public override RenderWindow CreateRenderWindow( string name, int width, int height, bool isFullScreen, NamedParameterList miscParams ) { LogManager.Instance.Write("D3D9RenderSystem::createRenderWindow \"{0}\", {1}x{2} {3} ", name, width, height, isFullScreen ? "fullscreen" : "windowed"); LogManager.Instance.Write( "miscParams: {0}", miscParams.Aggregate( new StringBuilder(), ( s, kv ) => s.AppendFormat( "{0} = {1};", kv.Key, kv.Value ).AppendLine() ).ToString() ); // Make sure we don't already have a render target of the // same name as the one supplied if (renderTargets.ContainsKey(name)) { throw new Exception(String.Format("A render target of the same name '{0}' already exists." + "You cannot create a new window with this name.", name)); } var window = new D3DRenderWindow(_activeD3DDriver, null); window.Create(name, width, height, isFullScreen, miscParams); _resourceManager.LockDeviceAccess(); _deviceManager.LinkRenderWindow( window ); _resourceManager.UnlockDeviceAccess(); _renderWindows.Add( window ); UpdateRenderSystemCapabilities( window ); AttachRenderTarget( window ); return window; }
private bool CheckVertexTextureFormats(D3DRenderWindow renderWindow) { var anySupported = false; var bbSurf = (Surface[])renderWindow[ "DDBACKBUFFER" ]; var bbSurfDesc = bbSurf[0].Description; for (var pf = PixelFormat.L8; pf < PixelFormat.Count; pf++) { var fmt = D3DHelper.ConvertEnum( pf ); if ( !_pD3D.CheckDeviceFormat( _activeD3DDriver.AdapterNumber, DeviceType.Hardware, bbSurfDesc.Format, Usage.QueryVertexTexture, ResourceType.Texture, fmt ) ) continue; // cool, at least one supported anySupported = true; LogManager.Instance.Write( "D3D9: Vertex texture format supported - {0}", PixelUtil.GetFormatName( pf ) ); } return anySupported; }
public override void DestroyRenderTarget(string name) { // Check in specialised lists if (primaryWindow.Name == name) { // We're destroying the primary window, so reset device and window primaryWindow = null; } else { // Check secondary windows foreach (RenderWindow window in secondaryWindows) { if (window.Name == name) { secondaryWindows.Remove(window); break; } } } // Do the real removal base.DestroyRenderTarget(name); // Did we destroy the primary? if (primaryWindow == null) { // device is no longer valid, so free it all up FreeDevice(); } }
private RenderSystemCapabilities UpdateRenderSystemCapabilities(D3DRenderWindow renderWindow) { var rsc = realCapabilities ?? new RenderSystemCapabilities(); rsc.SetCategoryRelevant(CapabilitiesCategory.D3D9, true); rsc.DriverVersion = driverVersion; rsc.DeviceName = _activeD3DDriver.DriverDescription; rsc.RendersystemName = Name; // Init caps to maximum. rsc.TextureUnitCount = 1024; rsc.SetCapability(Graphics.Capabilities.AnisotropicFiltering); rsc.SetCapability(Graphics.Capabilities.HardwareMipMaps); rsc.SetCapability(Graphics.Capabilities.Dot3); rsc.SetCapability(Graphics.Capabilities.CubeMapping); rsc.SetCapability(Graphics.Capabilities.ScissorTest); rsc.SetCapability(Graphics.Capabilities.TwoSidedStencil); rsc.SetCapability(Graphics.Capabilities.StencilWrap); rsc.SetCapability(Graphics.Capabilities.HardwareOcculusion); rsc.SetCapability(Graphics.Capabilities.UserClipPlanes); rsc.SetCapability(Graphics.Capabilities.VertexFormatUByte4); rsc.SetCapability(Graphics.Capabilities.Texture3D); rsc.SetCapability(Graphics.Capabilities.NonPowerOf2Textures); rsc.NonPOW2TexturesLimited = false; rsc.MultiRenderTargetCount = Config.MaxMultipleRenderTargets; rsc.SetCapability(Graphics.Capabilities.MRTDifferentBitDepths); rsc.SetCapability(Graphics.Capabilities.PointSprites); rsc.SetCapability(Graphics.Capabilities.PointExtendedParameters); rsc.MaxPointSize = 2.19902e+012f; rsc.SetCapability(Graphics.Capabilities.MipmapLODBias); rsc.SetCapability(Graphics.Capabilities.PerStageConstant); rsc.SetCapability(Graphics.Capabilities.StencilBuffer); rsc.StencilBufferBitCount = 8; rsc.SetCapability(Graphics.Capabilities.AdvancedBlendOperations); rsc.SetCapability(Graphics.Capabilities.RTTSerperateDepthBuffer); rsc.SetCapability(Graphics.Capabilities.RTTMainDepthbufferAttachable); rsc.SetCapability(Graphics.Capabilities.RTTDepthbufferResolutionLessEqual); rsc.SetCapability(Graphics.Capabilities.VertexBufferInstanceData); rsc.SetCapability(Graphics.Capabilities.CanGetCompiledShaderBuffer); foreach (var dev in _deviceManager) { var d3D9Device = dev.D3DDevice; // Check for hardware stencil support var pSurf = d3D9Device.DepthStencilSurface; if (pSurf != null) { var surfDesc = pSurf.Description; if (surfDesc.Format != Format.D15S1 && surfDesc.Format != Format.D24S8 && surfDesc.Format != Format.D24X4S4 && surfDesc.Format != Format.D24SingleS8) rsc.UnsetCapability( Graphics.Capabilities.StencilBuffer ); } // Check for hardware occlusion support //HRESULT hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); try { new Query(d3D9Device, QueryType.Occlusion); } catch (Direct3D9Exception) { rsc.UnsetCapability( Graphics.Capabilities.HardwareOcculusion ); } } // Update RS caps using the minimum value found in adapter list. foreach (var pCurDriver in _driverList) { var rkCurCaps = pCurDriver.D3D9DeviceCaps; if (rkCurCaps.MaxSimultaneousTextures < rsc.TextureUnitCount) { rsc.TextureUnitCount = rkCurCaps.MaxSimultaneousTextures; } // Check for Anisotropy. if (rkCurCaps.MaxAnisotropy <= 1) rsc.UnsetCapability( Graphics.Capabilities.AnisotropicFiltering ); // Check automatic mipmap generation. if ((rkCurCaps.Caps2 & Caps2.CanAutoGenerateMipMap) == 0) rsc.UnsetCapability( Graphics.Capabilities.HardwareMipMaps ); // Check Dot product 3. if ((rkCurCaps.TextureOperationCaps & TextureOperationCaps.DotProduct3) == 0) rsc.UnsetCapability( Graphics.Capabilities.Dot3 ); // Check cube map support. if ((rkCurCaps.TextureCaps & TextureCaps.CubeMap) == 0) rsc.UnsetCapability(Graphics.Capabilities.CubeMapping); // Scissor test if ((rkCurCaps.RasterCaps & RasterCaps.ScissorTest) == 0) rsc.UnsetCapability(Graphics.Capabilities.ScissorTest); // Two-sided stencil if ((rkCurCaps.StencilCaps & StencilCaps.TwoSided) == 0) rsc.UnsetCapability(Graphics.Capabilities.TwoSidedStencil); // stencil wrap if ((rkCurCaps.StencilCaps & StencilCaps.Increment) == 0 || (rkCurCaps.StencilCaps & StencilCaps.Decrement) == 0) rsc.UnsetCapability(Graphics.Capabilities.StencilWrap); // User clip planes if (rkCurCaps.MaxUserClipPlanes == 0) rsc.UnsetCapability(Graphics.Capabilities.UserClipPlanes); // UBYTE4 type? if ((rkCurCaps.DeclarationTypes & DeclarationTypeCaps.UByte4) == 0) rsc.UnsetCapability(Graphics.Capabilities.VertexFormatUByte4); // 3D textures? if ((rkCurCaps.TextureCaps & TextureCaps.VolumeMap) == 0) rsc.UnsetCapability(Graphics.Capabilities.Texture3D); if ((rkCurCaps.TextureCaps & TextureCaps.Pow2) != 0) { // Conditional support for non POW2 if ((rkCurCaps.TextureCaps & TextureCaps.NonPow2Conditional) != 0) rsc.NonPOW2TexturesLimited = true; // Only power of 2 supported. else rsc.UnsetCapability(Graphics.Capabilities.NonPowerOf2Textures); } // Number of render targets if (rkCurCaps.SimultaneousRTCount < rsc.MultiRenderTargetCount) { rsc.MultiRenderTargetCount = Utility.Min( rkCurCaps.SimultaneousRTCount, Config.MaxMultipleRenderTargets ); } if((rkCurCaps.PrimitiveMiscCaps & PrimitiveMiscCaps.MrtIndependentBitDepths) == 0) { rsc.UnsetCapability(Graphics.Capabilities.MRTDifferentBitDepths); } // Point sprites if (rkCurCaps.MaxPointSize <= 1.0f) { rsc.UnsetCapability(Graphics.Capabilities.PointSprites); // sprites and extended parameters go together in D3D rsc.UnsetCapability(Graphics.Capabilities.PointExtendedParameters); } // Take the minimum point size. if (rkCurCaps.MaxPointSize < rsc.MaxPointSize) rsc.MaxPointSize = rkCurCaps.MaxPointSize; // Mipmap LOD biasing? if ((rkCurCaps.RasterCaps & RasterCaps.MipMapLodBias) == 0) rsc.UnsetCapability(Graphics.Capabilities.MipmapLODBias); // Do we support per-stage src_manual constants? // HACK - ATI drivers seem to be buggy and don't support per-stage constants properly? // TODO: move this to RSC if((rkCurCaps.PrimitiveMiscCaps & PrimitiveMiscCaps.PerStageConstant) == 0) rsc.UnsetCapability(Graphics.Capabilities.PerStageConstant); // Advanced blend operations? min max subtract rev if ((rkCurCaps.PrimitiveMiscCaps & PrimitiveMiscCaps.BlendOperation) == 0) rsc.UnsetCapability(Graphics.Capabilities.AdvancedBlendOperations); } // Blending between stages supported rsc.SetCapability(Graphics.Capabilities.Blending); // We always support compression, D3DX will decompress if device does not support rsc.SetCapability(Graphics.Capabilities.TextureCompression); rsc.SetCapability(Graphics.Capabilities.TextureCompressionDXT); // We always support VBOs rsc.SetCapability(Graphics.Capabilities.VertexBuffer); ConvertVertexShaderCaps(rsc); ConvertPixelShaderCaps(rsc); // Adapter details var adapterId = _activeD3DDriver.AdapterIdentifier; // determine vendor // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id switch (adapterId.VendorId) { case 0x10DE: rsc.Vendor = GPUVendor.Nvidia; break; case 0x1002: rsc.Vendor = GPUVendor.Ati; break; case 0x163C: case 0x8086: rsc.Vendor = GPUVendor.Intel; break; case 0x5333: rsc.Vendor = GPUVendor.S3; break; case 0x3D3D: rsc.Vendor = GPUVendor._3DLabs; break; case 0x102B: rsc.Vendor = GPUVendor.Matrox; break; case 0x1039: rsc.Vendor = GPUVendor.Sis; break; default: rsc.Vendor = GPUVendor.Unknown; break; } // Infinite projection? // We have no capability for this, so we have to base this on our // experience and reports from users // Non-vertex program capable hardware does not appear to support it if (rsc.HasCapability(Graphics.Capabilities.VertexPrograms)) { // GeForce4 Ti (and presumably GeForce3) does not // render infinite projection properly, even though it does in GL // So exclude all cards prior to the FX range from doing infinite if (rsc.Vendor != GPUVendor.Nvidia || // not nVidia !((adapterId.DeviceId >= 0x200 && adapterId.DeviceId <= 0x20F) || //gf3 (adapterId.DeviceId >= 0x250 && adapterId.DeviceId <= 0x25F) || //gf4ti (adapterId.DeviceId >= 0x280 && adapterId.DeviceId <= 0x28F) || //gf4ti (adapterId.DeviceId >= 0x170 && adapterId.DeviceId <= 0x18F) || //gf4 go (adapterId.DeviceId >= 0x280 && adapterId.DeviceId <= 0x28F))) //gf4ti go { rsc.SetCapability( Graphics.Capabilities.InfiniteFarPlane ); } } // We always support rendertextures bigger than the frame buffer rsc.SetCapability( Graphics.Capabilities.HardwareRenderToTexture ); // Determine if any floating point texture format is supported var floatFormats = new[] {Format.R16F, Format.G16R16F, Format.A16B16G16R16F, Format.R32F, Format.G32R32F, Format.A32B32G32R32F}; var bbSurf = (Surface[])renderWindow[ "DDBACKBUFFER" ]; var bbSurfDesc = bbSurf[0].Description; for (var i = 0; i < 6; ++i) { if (!_pD3D.CheckDeviceFormat(_activeD3DDriver.AdapterNumber, DeviceType.Hardware, bbSurfDesc.Format, 0, ResourceType.Texture, floatFormats[i])) continue; rsc.SetCapability( Graphics.Capabilities.TextureFloat ); break; } // TODO: make convertVertex/Fragment fill in rsc // TODO: update the below line to use rsc // Vertex textures if (rsc.IsShaderProfileSupported("vs_3_0")) { // Run through all the texture formats looking for any which support // vertex texture fetching. Must have at least one! // All ATI Radeon up to X1n00 say they support vs_3_0, // but they support no texture formats for vertex texture fetch (cheaters!) if (CheckVertexTextureFormats(renderWindow)) { rsc.SetCapability( Graphics.Capabilities.VertexTextureFetch ); // always 4 vertex texture units in vs_3_0, and never shared rsc.TextureUnitCount = 4; rsc.VertexTextureUnitsShared = false; } } else { //True HW Instancing is supported since Shader model 3.0 ATI has a nasty //hack for enabling it in their SM 2.0 cards, but we don't (and won't) support it rsc.UnsetCapability( Graphics.Capabilities.VertexBufferInstanceData ); } // Check alpha to coverage support // this varies per vendor! But at least SM3 is required if (rsc.IsShaderProfileSupported("ps_3_0")) { // NVIDIA needs a separate check switch ( rsc.Vendor ) { case GPUVendor.Nvidia: if (_pD3D.CheckDeviceFormat(0, DeviceType.Hardware, Format.X8R8G8B8, 0, ResourceType.Surface, (Format)( 'A' | ( 'T' ) << 8 | ( 'O' ) << 16 | ( 'C' ) << 24 ) )) { rsc.SetCapability( Graphics.Capabilities.AlphaToCoverage ); } break; case GPUVendor.Ati: rsc.SetCapability( Graphics.Capabilities.AlphaToCoverage ); break; } // no other cards have Dx9 hacks for alpha to coverage, as far as I know } if (realCapabilities == null) { realCapabilities = rsc; realCapabilities.AddShaderProfile("hlsl"); // if we are using custom capabilities, then // mCurrentCapabilities has already been loaded if(!useCustomCapabilities) currentCapabilities = realCapabilities; FireEvent("RenderSystemCapabilitiesCreated"); InitializeFromRenderSystemCapabilities(currentCapabilities, renderWindow); } return rsc; }
public override RenderWindow CreateRenderWindow(string name, int width, int height, bool isFullscreen, params object[] miscParams) { // Check we're not creating a secondary window when the primary // was fullscreen if (primaryWindow != null && primaryWindow.IsFullScreen) { throw new Exception("Cannot create secondary windows when the primary is full screen"); } else if (primaryWindow != null && isFullscreen) { throw new Exception("Cannot create full screen secondary windows"); } // Make sure we don't already have a render target of the // same name as the one supplied foreach (RenderTarget x in renderTargets) { if (x.Name == name) throw new Exception("A render target of the same name '" + name + "' already exists. You cannot create a new window with this name."); } RenderWindow win = new D3DRenderWindow(activeD3DDriver, primaryWindow != null); // create the window win.Create(name, width, height, isFullscreen, miscParams); // add the new render target AttachRenderTarget(win); // If this is the first window, get the D3D device and create the texture manager if (primaryWindow == null) { primaryWindow = (D3DRenderWindow)win; device = (Device)win.GetCustomAttribute("D3DDEVICE"); // by creating our texture manager, singleton TextureManager will hold our implementation textureManager = new D3DTextureManager(device); // by creating our Gpu program manager, singleton GpuProgramManager will hold our implementation gpuProgramMgr = new D3DGpuProgramManager(device); // intializes the HardwareBufferManager singleton hardwareBufferManager = new D3DHardwareBufferManager(device); // Initialise the capabilities structures InitCapabilities(); CreateAndApplyCache(); } else { secondaryWindows.Add(win); } return win; }