Exemplo n.º 1
0
        public void LinkRenderWindow(D3D9RenderWindow renderWindow)
        {
            // Detach from previous device.
            var renderDevice = renderWindow.Device;

            if (renderDevice != null)
            {
                renderDevice.DetachRenderWindow(renderWindow);
            }

            var renderWindowsGroup = new D3D9RenderWindowList();

            // Select new device for this window.
            renderDevice = _selectDevice(renderWindow, renderWindowsGroup);

            // Link the windows group to the new device.
            for (var i = 0; i < renderWindowsGroup.Count; ++i)
            {
                var currWindow = renderWindowsGroup[i];

                currWindow.Device = renderDevice;
                renderDevice.AttachRenderWindow(currWindow);
                renderDevice.SetAdapterOrdinalIndex(currWindow, i);
            }

            renderDevice.Acquire();
            if (this._activeDevice == null)
            {
                ActiveDevice = renderDevice;
            }
        }
Exemplo n.º 2
0
        private D3D9Driver _findDriver(D3D9RenderWindow renderWindow)
        {
            var renderSystem = D3D9RenderSystem.Instance;
            var direct3D9    = D3D9RenderSystem.Direct3D9;
            var driverList   = renderSystem.Direct3DDrivers;

            // Find the monitor this render window belongs to.
            var hRenderWindowMonitor = ScreenHelper.GetHandle(renderWindow.WindowHandle);

            // Find the matching driver using window monitor handle.
            foreach (var currDriver in driverList)
            {
                var hCurrAdpaterMonitor = direct3D9.GetAdapterMonitor(currDriver.AdapterNumber);

                if (hCurrAdpaterMonitor == hRenderWindowMonitor)
                {
                    return(currDriver);
                }
            }

            return(null);
        }
        private bool _checkVertexTextureFormats(D3D9RenderWindow renderWindow)
        {
            var anySupported = false;

            var bbSurf     = (D3D9.Surface[])renderWindow["DDBACKBUFFER"];
            var bbSurfDesc = bbSurf[0].Description;

            for (var pf = PixelFormat.L8; pf < PixelFormat.Count; ++pf)
            {
                var fmt = D3D9Helper.ConvertEnum(D3D9Helper.GetClosestSupported(pf));
                if (
                    !this._pD3D.CheckDeviceFormat(this._activeD3DDriver.AdapterNumber, D3D9.DeviceType.Hardware, bbSurfDesc.Format,
                                                  D3D9.Usage.QueryVertexTexture, D3D9.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);
        }
Exemplo n.º 4
0
		public void DetachRenderWindow( D3D9RenderWindow renderWindow )
		{
			RenderWindowResources renderWindowResources;
			if ( this._mapRenderWindowToResources.TryGetValue( renderWindow, out renderWindowResources ) )
			{
				// The focus window in which the d3d9 device created on is detached.
				// resources must be acquired again.
				if ( this._focusWindow == renderWindow.WindowHandle )
				{
					this._focusWindow = IntPtr.Zero;
				}

				// Case this is the shared focus window.
				if ( renderWindow.WindowHandle == SharedFocusWindow )
				{
					SharedWindowHandle = IntPtr.Zero;
				}

				ReleaseRenderWindowResources( renderWindowResources );

				renderWindowResources.SafeDispose();

				this._mapRenderWindowToResources.Remove( renderWindow );
			}
			UpdateRenderWindowsIndices();
		}
Exemplo n.º 5
0
		public void AttachRenderWindow( D3D9RenderWindow renderWindow )
		{
			if ( !this._mapRenderWindowToResources.ContainsKey( renderWindow ) )
			{
				var renderWindowResources = new RenderWindowResources();

				renderWindowResources.AdapterOrdinalInGroupIndex = 0;
				renderWindowResources.Acquired = false;
				this._mapRenderWindowToResources.Add( renderWindow, renderWindowResources );
			}
			UpdateRenderWindowsIndices();
		}
Exemplo n.º 6
0
		protected KeyValuePair<D3D9RenderWindow, RenderWindowResources> GetRenderWindowIterator( D3D9RenderWindow renderWindow )
		{
			if ( !this._mapRenderWindowToResources.ContainsKey( renderWindow ) )
			{
				throw new AxiomException( "Render window was not attached to this device !!" );
			}

			return new KeyValuePair<D3D9RenderWindow, RenderWindowResources>( renderWindow,
			                                                                  this._mapRenderWindowToResources[ renderWindow ] );
		}
Exemplo n.º 7
0
		public void CopyContentsToMemory( D3D9RenderWindow renderWindow, PixelBox dst, RenderTarget.FrameBuffer buffer )
		{
			var resources = this._mapRenderWindowToResources[ renderWindow ];
			var swapChain = IsSwapChainWindow( renderWindow );

			if ( ( dst.Left < 0 ) || ( dst.Right > renderWindow.Width ) || ( dst.Top < 0 ) ||
			     ( dst.Bottom > renderWindow.Height ) || ( dst.Front != 0 ) || ( dst.Back != 1 ) )
			{
				throw new AxiomException( "Invalid box." );
			}

			var desc = new D3D9.SurfaceDescription();
			DX.DataRectangle lockedRect;
			D3D9.Surface pTempSurf = null, pSurf = null;

			if ( buffer == RenderTarget.FrameBuffer.Auto )
			{
				buffer = RenderTarget.FrameBuffer.Front;
			}

			if ( buffer == RenderTarget.FrameBuffer.Front )
			{
				var dm = this.pDevice.GetDisplayMode( 0 );

				desc.Width = dm.Width;
				desc.Height = dm.Height;
				desc.Format = D3D9.Format.A8R8G8B8;

				pTempSurf = D3D9.Surface.CreateOffscreenPlain( this.pDevice, desc.Width, desc.Height, desc.Format,
				                                               D3D9.Pool.SystemMemory );

				try
				{
					if ( swapChain )
					{
						resources.SwapChain.GetFrontBufferData( pTempSurf );
					}
					else
					{
						pTempSurf = this.pDevice.GetFrontBufferData( 0 );
					}
				}
				catch ( DX.SharpDXException ex )
				{
					pTempSurf.SafeDispose();
					throw new AxiomException( "Can't get front buffer: {0}", ex.Message );
				}

				if ( renderWindow.IsFullScreen )
				{
					try
					{
						if ( ( dst.Left == 0 ) && ( dst.Right == renderWindow.Width ) && ( dst.Top == 0 ) &&
						     ( dst.Bottom == renderWindow.Height ) )
						{
							lockedRect = pTempSurf.LockRectangle( D3D9.LockFlags.ReadOnly | D3D9.LockFlags.NoSystemLock );
						}
						else
						{
							var rect = new System.Drawing.Rectangle( dst.Left, dst.Top, dst.Right - dst.Left, dst.Bottom - dst.Top );
							lockedRect = pTempSurf.LockRectangle( rect, D3D9.LockFlags.ReadOnly | D3D9.LockFlags.NoSystemLock );
						}
					}
					catch
					{
						pTempSurf.SafeDispose();
						throw new AxiomException( "Can't lock rect" );
					}
				}
				else
				{
					//GetClientRect(mHWnd, &srcRect);
					var srcRect = new System.Drawing.Rectangle( dst.Left, dst.Top, dst.Right - dst.Left, dst.Bottom - dst.Top );
					var point = new System.Drawing.Point( srcRect.Left, srcRect.Top );

					point = System.Windows.Forms.Control.FromHandle( renderWindow.WindowHandle ).PointToScreen( point );

					srcRect = new System.Drawing.Rectangle( point.X, point.Y, srcRect.Right + point.X - srcRect.Left,
					                                        srcRect.Bottom + point.Y - dst.Top );

					desc.Width = srcRect.Right - srcRect.Left;
					desc.Height = srcRect.Bottom - srcRect.Top;

					try
					{
						lockedRect = pTempSurf.LockRectangle( srcRect, D3D9.LockFlags.ReadOnly | D3D9.LockFlags.NoSystemLock );
					}
					catch
					{
						pTempSurf.SafeDispose();
						throw new AxiomException( "Can't lock rect" );
					}
				}
			}
			else
			{
				pSurf.SafeDispose();
				pSurf = swapChain ? resources.SwapChain.GetBackBuffer( 0 ) : this.pDevice.GetBackBuffer( 0, 0 );
				desc = pSurf.Description;

				pTempSurf = D3D9.Surface.CreateOffscreenPlain( this.pDevice, desc.Width, desc.Height, desc.Format,
				                                               D3D9.Pool.SystemMemory );

				if ( desc.MultiSampleType == D3D9.MultisampleType.None )
				{
					var hr = this.pDevice.GetRenderTargetData( pSurf, pTempSurf );
					if ( hr.Failure )
					{
						pTempSurf.SafeDispose();
						throw new AxiomException( "Can't get render target data" );
					}
				}
				else
				{
					var pStretchSurf = D3D9.Surface.CreateRenderTarget( this.pDevice, desc.Width, desc.Height, desc.Format,
					                                                    D3D9.MultisampleType.None, 0, false );
					var hr = this.pDevice.StretchRectangle( pSurf, pStretchSurf, D3D9.TextureFilter.None );
					if ( hr.Failure )
					{
						pTempSurf.SafeDispose();
						pStretchSurf.SafeDispose();
						throw new AxiomException( "Can't stretch rect" );
					}

					hr = this.pDevice.GetRenderTargetData( pStretchSurf, pTempSurf );
					if ( hr.Failure )
					{
						pTempSurf.SafeDispose();
						pStretchSurf.SafeDispose();
						throw new AxiomException( "Can't get render target data" );
					}

					pStretchSurf.SafeDispose();
				}

				try
				{
					if ( ( dst.Left == 0 ) && ( dst.Right == renderWindow.Width ) && ( dst.Top == 0 ) &&
					     ( dst.Bottom == renderWindow.Height ) )
					{
						lockedRect = pTempSurf.LockRectangle( D3D9.LockFlags.ReadOnly | D3D9.LockFlags.NoSystemLock );
					}
					else
					{
						var rect = new System.Drawing.Rectangle( dst.Left, dst.Top, dst.Right - dst.Left, dst.Bottom - dst.Top );
						lockedRect = pTempSurf.LockRectangle( rect, D3D9.LockFlags.ReadOnly | D3D9.LockFlags.NoSystemLock );
					}
				}
				catch
				{
					pTempSurf.SafeDispose();
					throw new AxiomException( "Can't lock rect" );
				}
			}

			var format = D3D9Helper.ConvertEnum( desc.Format );

			if ( format == PixelFormat.Unknown )
			{
				pTempSurf.SafeDispose();
				throw new AxiomException( "Unsupported format" );
			}

			using ( var data = BufferBase.Wrap( lockedRect.DataPointer, lockedRect.Pitch*dst.Height ) )
			{
				var src = new PixelBox( dst.Width, dst.Height, 1, format, data );
				src.RowPitch = lockedRect.Pitch/PixelUtil.GetNumElemBytes( format );
				src.SlicePitch = desc.Height*src.RowPitch;

				PixelConverter.BulkPixelConversion( src, dst );
			}

			pTempSurf.SafeDispose();
			pSurf.SafeDispose();
		}
        private RenderSystemCapabilities _updateRenderSystemCapabilities(D3D9RenderWindow renderWindow)
        {
            var rsc = realCapabilities ?? new RenderSystemCapabilities();

            rsc.SetCategoryRelevant(CapabilitiesCategory.D3D9, true);
            rsc.DriverVersion    = driverVersion;
            rsc.DeviceName       = this._activeD3DDriver.DriverDescription;
            rsc.RendersystemName = Name;

            // Supports fixed-function
            rsc.SetCapability(Graphics.Capabilities.FixedFunction);

            // 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 = 10.0f;
            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 device in this._deviceManager)
            {
                var d3D9Device = device.D3DDevice;

                // Check for hardware stencil support
                var pSurf = d3D9Device.DepthStencilSurface;
                if (pSurf != null)
                {
                    var surfDesc = pSurf.Description;
                    //TODO
                    //pSurf.Release();

                    if (surfDesc.Format != D3D9.Format.D15S1 && surfDesc.Format != D3D9.Format.D24S8 &&
                        surfDesc.Format != D3D9.Format.D24X4S4 && surfDesc.Format != D3D9.Format.D24SingleS8)
                    {
                        rsc.UnsetCapability(Graphics.Capabilities.StencilBuffer);
                    }
                }

                // Check for hardware occlusion support
                try
                {
                    new D3D9.Query(d3D9Device, D3D9.QueryType.Occlusion);
                }
                catch (DX.SharpDXException)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.HardwareOcculusion);
                }
            }

            // Update RS caps using the minimum value found in adapter list.
            foreach (var pCurDriver in this._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 & D3D9.Caps2.CanAutoGenerateMipMap) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.HardwareMipMaps);
                }

                // Check Dot product 3.
                if ((rkCurCaps.TextureOperationCaps & D3D9.TextureOperationCaps.DotProduct3) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.Dot3);
                }

                // Check cube map support.
                if ((rkCurCaps.TextureCaps & D3D9.TextureCaps.CubeMap) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.CubeMapping);
                }

                // Scissor test
                if ((rkCurCaps.RasterCaps & D3D9.RasterCaps.ScissorTest) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.ScissorTest);
                }

                // Two-sided stencil
                if ((rkCurCaps.StencilCaps & D3D9.StencilCaps.TwoSided) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.TwoSidedStencil);
                }

                // stencil wrap
                if ((rkCurCaps.StencilCaps & D3D9.StencilCaps.Increment) == 0 ||
                    (rkCurCaps.StencilCaps & D3D9.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 & D3D9.DeclarationTypeCaps.UByte4) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.VertexFormatUByte4);
                }

                // 3D textures?
                if ((rkCurCaps.TextureCaps & D3D9.TextureCaps.VolumeMap) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.Texture3D);
                }

                if ((rkCurCaps.TextureCaps & D3D9.TextureCaps.Pow2) != 0)
                {
                    // Conditional support for non POW2
                    if ((rkCurCaps.TextureCaps & D3D9.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 & D3D9.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 & D3D9.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 & D3D9.PrimitiveMiscCaps.PerStageConstant) == 0)
                {
                    rsc.UnsetCapability(Graphics.Capabilities.PerStageConstant);
                }

                // Advanced blend operations? min max subtract rev
                if ((rkCurCaps.PrimitiveMiscCaps & D3D9.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 = this._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[]
            {
                D3D9.Format.R16F, D3D9.Format.G16R16F, D3D9.Format.A16B16G16R16F, D3D9.Format.R32F,
                D3D9.Format.G32R32F, D3D9.Format.A32B32G32R32F
            };

            var bbSurf     = (D3D9.Surface[])renderWindow["DDBACKBUFFER"];
            var bbSurfDesc = bbSurf[0].Description;

            for (var i = 0; i < 6; ++i)
            {
                if (
                    !this._pD3D.CheckDeviceFormat(this._activeD3DDriver.AdapterNumber, D3D9.DeviceType.Hardware, bbSurfDesc.Format, 0,
                                                  D3D9.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.VertexTextureUnitCount   = 4;
                    rsc.VertexTextureUnitsShared = false;
                }
            }

            // 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 (this._pD3D.CheckDeviceFormat(0, D3D9.DeviceType.Hardware, D3D9.Format.X8R8G8B8, 0, D3D9.ResourceType.Surface,
                                                     (D3D9.Format)('A' | ('T') << 8 | ('O') << 16 | ('C') << 24)))
                    {
                        rsc.SetCapability(Graphics.Capabilities.AlphaToCoverage);
                    }
                    break;

                case GPUVendor.Ati:
                    // There is no check on ATI, we have to assume SM3 == support
                    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;
                }

                InitializeFromRenderSystemCapabilities(currentCapabilities, renderWindow);
            }

            return(rsc);
        }
Exemplo n.º 9
0
		public bool Validate( D3D9RenderWindow renderWindow )
		{
			// Validate that the render window should run on this device.
			if ( !ValidateDisplayMonitor( renderWindow ) )
			{
				return false;
			}

			// Validate that this device created on the correct target focus window handle        
			ValidateFocusWindow();

			// Validate that the render window dimensions matches to back buffer dimensions.
			ValidateBackBufferSize( renderWindow );

			// Validate that this device is in valid rendering state.
			return ValidateDeviceState( renderWindow );
		}
Exemplo n.º 10
0
		public void SetAdapterOrdinalIndex( D3D9RenderWindow renderWindow, int adapterOrdinalInGroupIndex )
		{
			var it = this._mapRenderWindowToResources[ renderWindow ];
			it.AdapterOrdinalInGroupIndex = adapterOrdinalInGroupIndex;
			UpdateRenderWindowsIndices();
		}
Exemplo n.º 11
0
		protected void ValidateBackBufferSize( D3D9RenderWindow renderWindow )
		{
			var renderWindowResources = this._mapRenderWindowToResources[ renderWindow ];

			// Case size has been changed.
			if ( renderWindow.Width != renderWindowResources.PresentParameters.BackBufferWidth ||
			     renderWindow.Height != renderWindowResources.PresentParameters.BackBufferHeight )
			{
				if ( renderWindow.Width > 0 )
				{
					renderWindowResources.PresentParameters.BackBufferWidth = renderWindow.Width;
				}

				if ( renderWindow.Height > 0 )
				{
					renderWindowResources.PresentParameters.BackBufferHeight = renderWindow.Height;
				}

				Invalidate( renderWindow );
			}
		}
Exemplo n.º 12
0
        private D3D9Device _selectDevice(D3D9RenderWindow renderWindow, D3D9RenderWindowList renderWindowsGroup)
        {
            var        renderSystem    = D3D9RenderSystem.Instance;
            D3D9Device renderDevice    = null;
            var        direct3D9       = D3D9RenderSystem.Direct3D9;
            var        nAdapterOrdinal = 0; // D3DADAPTER_DEFAULT
            var        devType         = D3D9.DeviceType.Hardware;

            D3D9.CreateFlags extraFlags = 0;
            var driverList     = renderSystem.Direct3DDrivers;
            var nvAdapterFound = false;

            // Default group includes at least the given render window.
            renderWindowsGroup.Add(renderWindow);

            // Case we use nvidia performance HUD, override the device settings.
            if (renderWindow.IsNvPerfHUDEnable)
            {
                // Look for 'NVIDIA NVPerfHUD' adapter (<= v4)
                // or 'NVIDIA PerfHUD' (v5)
                // If it is present, override default settings
                for (var adapter = 0; adapter < direct3D9.AdapterCount; ++adapter)
                {
                    var currDriver = driverList[adapter];

                    if (!currDriver.DriverDescription.Contains("PerfHUD"))
                    {
                        continue;
                    }

                    // renderDevice = null;
                    nAdapterOrdinal = adapter;
                    renderSystem._activeD3DDriver = currDriver;
                    devType        = D3D9.DeviceType.Reference;
                    nvAdapterFound = true;
                    break;
                }
            }

            // No special adapter should be used.
            if (nvAdapterFound == false)
            {
                renderSystem._activeD3DDriver = _findDriver(renderWindow);
                nAdapterOrdinal = renderSystem._activeD3DDriver.AdapterNumber;

                var bTryUsingMultiheadDevice = false;

                if (renderWindow.IsFullScreen)
                {
                    bTryUsingMultiheadDevice = true;
                    var osVersionInfo = System.Environment.OSVersion;

                    // XP and below - multi-head will cause artifacts when vsync is on.
                    if (osVersionInfo.Version.Major <= 5 && renderWindow.IsVSync)
                    {
                        bTryUsingMultiheadDevice = false;
                        LogManager.Instance.Write(
                            "D3D9 : Multi head disabled. It causes horizontal line when used in XP + VSync combination");
                    }

                    // Vista and SP1 or SP2 - multi-head device can not be reset - it causes memory corruption.
                    if (osVersionInfo.Version.Major == 6 &&
                        (osVersionInfo.ServicePack.Contains("Service Pack 1") ||
                         osVersionInfo.ServicePack.Contains("Service Pack 2")))
                    {
                        bTryUsingMultiheadDevice = false;
                        LogManager.Instance.Write(
                            "D3D9 : Multi head disabled. It causes application run time crashes when used in Vista + SP 1 or 2 combination");
                    }
                }

                // Check if we can create a group of render windows
                // on the same device using the multi-head feature.
                if (bTryUsingMultiheadDevice)
                {
                    var targetAdapterCaps = renderSystem._activeD3DDriver.D3D9DeviceCaps;
                    var masterAdapterCaps = new Capabilities();

                    // Find the master device caps.
                    if (targetAdapterCaps.MasterAdapterOrdinal == targetAdapterCaps.AdapterOrdinal)
                    {
                        masterAdapterCaps = targetAdapterCaps;
                    }
                    else
                    {
                        foreach (var currDriver in driverList)
                        {
                            var currDeviceCaps = currDriver.D3D9DeviceCaps;

                            if (currDeviceCaps.AdapterOrdinal != targetAdapterCaps.MasterAdapterOrdinal)
                            {
                                continue;
                            }

                            masterAdapterCaps = currDeviceCaps;
                            break;
                        }
                    }

                    // Case the master adapter can handle multiple adapters.
                    if (masterAdapterCaps.NumberOfAdaptersInGroup > 1)
                    {
                        // Create empty list of render windows composing this group.
                        renderWindowsGroup.Clear();
                        while (renderWindowsGroup.Count < masterAdapterCaps.NumberOfAdaptersInGroup)
                        {
                            renderWindowsGroup.Add(null);
                        }

                        // Assign the current render window to it's place in the group.
                        renderWindowsGroup[targetAdapterCaps.AdapterOrdinalInGroup] = renderWindow;


                        // For each existing window - check if it belongs to the group.
                        foreach (var currRenderWindow in renderSystem.RenderWindows)
                        {
                            if (!currRenderWindow.IsFullScreen)
                            {
                                continue;
                            }

                            var currDriver     = _findDriver((D3D9RenderWindow)currRenderWindow);
                            var currDeviceCaps = currDriver.D3D9DeviceCaps;

                            if (currDeviceCaps.MasterAdapterOrdinal != masterAdapterCaps.AdapterOrdinal)
                            {
                                continue;
                            }

                            renderWindowsGroup[currDeviceCaps.AdapterOrdinalInGroup] = (D3D9RenderWindow)currRenderWindow;
                            break;
                        }

                        var bDeviceGroupFull = true;


                        // Check if render windows group is full and ready to be driven by
                        // the master device.
                        for (var i = 0; i < renderWindowsGroup.Count; ++i)
                        {
                            // This group misses required window -> go back to default.
                            if (renderWindowsGroup[i] != null)
                            {
                                continue;
                            }

                            bDeviceGroupFull = false;
                            renderWindowsGroup.Clear();
                            renderWindowsGroup.Add(renderWindow);
                            break;
                        }

                        // Case device group is full -> we can use multi head device.
                        if (bDeviceGroupFull)
                        {
                            var validateAllDevices = false;

                            for (var i = 0; i < renderWindowsGroup.Count; ++i)
                            {
                                var currRenderWindow = renderWindowsGroup[i];
                                var currDevice       = currRenderWindow.Device;

                                // This is the master window
                                if (i == 0)
                                {
                                    // If master device exists - just release it.
                                    if (currDevice != null)
                                    {
                                        renderDevice = currDevice;
                                        renderDevice.Release();
                                    }
                                }

                                // This is subordinate window.
                                else
                                {
                                    // If subordinate device exists - destroy it.
                                    if (currDevice != null)
                                    {
                                        currDevice.Destroy();
                                        validateAllDevices = true;
                                    }
                                }
                            }

                            // In case some device was destroyed - make sure all other devices are valid.
                            // A possible scenario is that full screen window has been destroyed and it's handle
                            // was used and the shared focus handle. All other devices used this handle and must be
                            // recreated using other handles otherwise create device will fail.
                            if (validateAllDevices)
                            {
                                foreach (var dev in this._renderDevices)
                                {
                                    dev.ValidateFocusWindow();
                                }
                            }
                        }
                    }
                }
            }


            // Do we want to preserve the FPU mode? Might be useful for scientific apps
            var options = renderSystem.ConfigOptions;

            ConfigOption opti;

            if (options.TryGetValue("Floating-point mode", out opti) && opti.Value == "Consistent")
            {
                extraFlags |= D3D9.CreateFlags.FpuPreserve;
            }

#if AXIOM_THREAD_SUPPORT
            if (Configuration.Config.AxiomThreadLevel == 1)
            {
                extraFlags |= D3D9.CreateFlags.Multithreaded;
            }
#endif

            // Try to find a matching device from current device list.
            if (renderDevice == null)
            {
                foreach (var currDevice in this._renderDevices)
                {
                    if (currDevice.AdapterNumber != nAdapterOrdinal || currDevice.DeviceType != devType)
                    {
                        continue;
                    }

                    renderDevice = currDevice;
                    break;
                }
            }

            // No matching device found -> try reference device type (might have been
            // previously created as a fallback, but don't change devType because HAL
            // should be preferred on creation)
            if (renderDevice == null)
            {
                foreach (var currDevice in this._renderDevices)
                {
                    if (currDevice.AdapterNumber != nAdapterOrdinal || currDevice.DeviceType != D3D9.DeviceType.Reference)
                    {
                        continue;
                    }

                    renderDevice = currDevice;
                    break;
                }
            }

            // No matching device found -> create new one.
            if (renderDevice == null)
            {
                renderDevice = new D3D9Device(this, nAdapterOrdinal, direct3D9.GetAdapterMonitor(nAdapterOrdinal), devType,
                                              extraFlags);
                this._renderDevices.Add(renderDevice);
                if (this._activeDevice == null)
                {
                    ActiveDevice = renderDevice;
                }
            }

            return(renderDevice);
        }
		private RenderSystemCapabilities _updateRenderSystemCapabilities( D3D9RenderWindow renderWindow )
		{
			var rsc = realCapabilities ?? new RenderSystemCapabilities();

			rsc.SetCategoryRelevant( CapabilitiesCategory.D3D9, true );
			rsc.DriverVersion = driverVersion;
			rsc.DeviceName = this._activeD3DDriver.DriverDescription;
			rsc.RendersystemName = Name;

			// Supports fixed-function
			rsc.SetCapability( Graphics.Capabilities.FixedFunction );

			// 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 = 10.0f;
			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 device in this._deviceManager )
			{
				var d3D9Device = device.D3DDevice;

				// Check for hardware stencil support
				var pSurf = d3D9Device.DepthStencilSurface;
				if ( pSurf != null )
				{
					var surfDesc = pSurf.Description;
					//TODO
					//pSurf.Release();

					if ( surfDesc.Format != D3D9.Format.D15S1 && surfDesc.Format != D3D9.Format.D24S8 &&
					     surfDesc.Format != D3D9.Format.D24X4S4 && surfDesc.Format != D3D9.Format.D24SingleS8 )
					{
						rsc.UnsetCapability( Graphics.Capabilities.StencilBuffer );
					}
				}

				// Check for hardware occlusion support
				try
				{
					new D3D9.Query( d3D9Device, D3D9.QueryType.Occlusion );
				}
				catch ( DX.SharpDXException )
				{
					rsc.UnsetCapability( Graphics.Capabilities.HardwareOcculusion );
				}
			}

			// Update RS caps using the minimum value found in adapter list.
			foreach ( var pCurDriver in this._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 & D3D9.Caps2.CanAutoGenerateMipMap ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.HardwareMipMaps );
				}

				// Check Dot product 3.
				if ( ( rkCurCaps.TextureOperationCaps & D3D9.TextureOperationCaps.DotProduct3 ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.Dot3 );
				}

				// Check cube map support.
				if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.CubeMap ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.CubeMapping );
				}

				// Scissor test
				if ( ( rkCurCaps.RasterCaps & D3D9.RasterCaps.ScissorTest ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.ScissorTest );
				}

				// Two-sided stencil
				if ( ( rkCurCaps.StencilCaps & D3D9.StencilCaps.TwoSided ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.TwoSidedStencil );
				}

				// stencil wrap
				if ( ( rkCurCaps.StencilCaps & D3D9.StencilCaps.Increment ) == 0 ||
				     ( rkCurCaps.StencilCaps & D3D9.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 & D3D9.DeclarationTypeCaps.UByte4 ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.VertexFormatUByte4 );
				}

				// 3D textures?
				if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.VolumeMap ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.Texture3D );
				}

				if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.Pow2 ) != 0 )
				{
					// Conditional support for non POW2
					if ( ( rkCurCaps.TextureCaps & D3D9.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 & D3D9.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 & D3D9.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 & D3D9.PrimitiveMiscCaps.PerStageConstant ) == 0 )
				{
					rsc.UnsetCapability( Graphics.Capabilities.PerStageConstant );
				}

				// Advanced blend operations? min max subtract rev 
				if ( ( rkCurCaps.PrimitiveMiscCaps & D3D9.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 = this._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[]
			                   {
			                   	D3D9.Format.R16F, D3D9.Format.G16R16F, D3D9.Format.A16B16G16R16F, D3D9.Format.R32F,
			                   	D3D9.Format.G32R32F, D3D9.Format.A32B32G32R32F
			                   };

			var bbSurf = (D3D9.Surface[])renderWindow[ "DDBACKBUFFER" ];
			var bbSurfDesc = bbSurf[ 0 ].Description;

			for ( var i = 0; i < 6; ++i )
			{
				if (
					!this._pD3D.CheckDeviceFormat( this._activeD3DDriver.AdapterNumber, D3D9.DeviceType.Hardware, bbSurfDesc.Format, 0,
					                               D3D9.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.VertexTextureUnitCount = 4;
					rsc.VertexTextureUnitsShared = false;
				}
			}

			// 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 ( this._pD3D.CheckDeviceFormat( 0, D3D9.DeviceType.Hardware, D3D9.Format.X8R8G8B8, 0, D3D9.ResourceType.Surface,
						                                   (D3D9.Format)( 'A' | ( 'T' ) << 8 | ( 'O' ) << 16 | ( 'C' ) << 24 ) ) )
						{
							rsc.SetCapability( Graphics.Capabilities.AlphaToCoverage );
						}
						break;

					case GPUVendor.Ati:
						// There is no check on ATI, we have to assume SM3 == support
						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;
				}

				InitializeFromRenderSystemCapabilities( currentCapabilities, renderWindow );
			}

			return rsc;
		}
		private bool _checkVertexTextureFormats( D3D9RenderWindow renderWindow )
		{
			var anySupported = false;

			var bbSurf = (D3D9.Surface[])renderWindow[ "DDBACKBUFFER" ];
			var bbSurfDesc = bbSurf[ 0 ].Description;

			for ( var pf = PixelFormat.L8; pf < PixelFormat.Count; ++pf )
			{
				var fmt = D3D9Helper.ConvertEnum( D3D9Helper.GetClosestSupported( pf ) );
				if (
					!this._pD3D.CheckDeviceFormat( this._activeD3DDriver.AdapterNumber, D3D9.DeviceType.Hardware, bbSurfDesc.Format,
					                               D3D9.Usage.QueryVertexTexture, D3D9.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;
		}
Exemplo n.º 15
0
		protected bool Acquire( D3D9RenderWindow renderWindow )
		{
			var it = GetRenderWindowIterator( renderWindow );
			AcquireRenderWindowResources( it );
			return true;
		}
Exemplo n.º 16
0
		public D3D9.Surface GetBackBuffer( D3D9RenderWindow renderWindow )
		{
			var it = this._mapRenderWindowToResources[ renderWindow ];
			return it.BackBuffer;
		}
Exemplo n.º 17
0
		protected bool ValidateDisplayMonitor( D3D9RenderWindow renderWindow )
		{
			// Ignore full screen since it doesn't really move and it is possible 
			// that it created using multi-head adapter so for a subordinate the
			// native monitor handle and this device handle will be different.
			if ( renderWindow.IsFullScreen )
			{
				return true;
			}

			// Find the monitor this render window belongs to.
			// Note: In Ogre, there was MONITOR_DEFAULTTONULL as flag of the MonitorFromWindow method,
			// while Screen.FromHandle method always use MONITOR_DEFAULTTONEAREST flag.
			var hRenderWindowMonitor = ScreenHelper.GetHandle( renderWindow.WindowHandle );

			// This window doesn't intersect with any of the display monitor
			if ( hRenderWindowMonitor == IntPtr.Zero )
			{
				return false;
			}

			// Case this window changed monitor.
			if ( hRenderWindowMonitor != this._monitor )
			{
				// Lock access to rendering device.
				D3D9RenderSystem.ResourceManager.LockDeviceAccess();

				this.pDeviceManager.LinkRenderWindow( renderWindow );

				// UnLock access to rendering device.
				D3D9RenderSystem.ResourceManager.UnlockDeviceAccess();

				return false;
			}

			return true;
		}
Exemplo n.º 18
0
		public void Invalidate( D3D9RenderWindow renderWindow )
		{
			this._mapRenderWindowToResources[ renderWindow ].Acquired = false;
		}
Exemplo n.º 19
0
		public void Present( D3D9RenderWindow renderWindow )
		{
			var renderWindowResources = this._mapRenderWindowToResources[ renderWindow ];

			// Skip present while current device state is invalid.
			if ( this.DeviceLost || renderWindowResources.Acquired == false || IsDeviceLost )
			{
				return;
			}

			try
			{
				if ( IsMultihead )
				{
					// Only the master will call present method results in synchronized
					// buffer swap for the rest of the implicit swap chain.
					if ( PrimaryWindow == renderWindow )
					{
						this.pDevice.Present();
					}
				}
				else
				{
					renderWindowResources.SwapChain.Present( 0 );
				}

				LastPresentFrame = Root.Instance.NextFrameNumber;
			}
			catch ( DX.SharpDXException ex )
			{
				if ( ex.ResultCode == D3D9.ResultCode.DeviceLost )
				{
					ReleaseRenderWindowResources( renderWindowResources );
					NotifyDeviceLost();
				}
				else
				{
					throw new AxiomException( "Error Presenting surfaces", ex );
				}
			}
		}
Exemplo n.º 20
0
		protected bool ValidateDeviceState( D3D9RenderWindow renderWindow )
		{
			var renderWindowResources = this._mapRenderWindowToResources[ renderWindow ];

			var hr = this.pDevice.TestCooperativeLevel();

			// Case device is not valid for rendering. 
			if ( hr.Failure )
			{
				// device lost, and we can't reset
				// can't do anything about it here, wait until we get 
				// D3DERR_DEVICENOTRESET; rendering calls will silently fail until 
				// then (except Present, but we ignore device lost there too)
				if ( hr == D3D9.ResultCode.DeviceLost )
				{
					ReleaseRenderWindowResources( renderWindowResources );
					NotifyDeviceLost();
					return false;
				}

				// device lost, and we can reset
				/*else*/
				if ( hr == D3D9.ResultCode.DeviceNotReset )
				{
					var deviceRestored = Reset();

					// Device was not restored yet.
					if ( deviceRestored == false )
					{
						// Wait a while
						Thread.Sleep( 50 );
						return false;
					}
				}
			}

			// Render window resources explicitly invalidated. (Resize or window mode switch) 
			if ( renderWindowResources.Acquired == false )
			{
				if ( PrimaryWindow == renderWindow )
				{
					var deviceRestored = Reset();

					// Device was not restored yet.
					if ( deviceRestored == false )
					{
						// Wait a while
						Thread.Sleep( 50 );
						return false;
					}
				}
				else
				{
					Acquire( renderWindow );
				}
			}

			return true;
		}
Exemplo n.º 21
0
		protected bool IsSwapChainWindow( D3D9RenderWindow renderWindow )
		{
			var it = this._mapRenderWindowToResources[ renderWindow ];
			return it.PresentParametersIndex != 0 && !renderWindow.IsFullScreen;
		}