Axiom.RenderSystems.DirectX9.D3DRenderSystem.UpdateRenderSystemCapabilities C# (CSharp) Метод

UpdateRenderSystemCapabilities() приватный метод

private UpdateRenderSystemCapabilities ( D3DRenderWindow renderWindow ) : RenderSystemCapabilities
renderWindow D3DRenderWindow
Результат RenderSystemCapabilities
        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;
        }
D3DRenderSystem