public D3D9Driver( int adapterNumber, D3D9.Capabilities deviceCaps, D3D9.AdapterDetails adapterIdentifier, D3D9.DisplayMode desktopDisplayMode ) : base() { this._adapterNumber = adapterNumber; this._d3D9DeviceCaps = deviceCaps; this._adapterIdentifier = adapterIdentifier; this._desktopDisplayMode = desktopDisplayMode; this._videoModeList = null; }
/// <summary> /// Internal constructor. /// </summary> /// <param name="graphicsDevice"></param> /// <param name="texture"></param> /// <param name="width"></param> /// <param name="height"></param> internal Texture(GraphicsDevice graphicsDevice, D3D.Texture texture, int width, int height) : base() { if (texture == null) throw new ArgumentNullException("texture"); graphicsDevice.EnsureDeviceCreated(); this.Width = width; this.Height = height; this.Usage = TextureUsage.None; this.CreateInternalTexture(graphicsDevice, texture); }
internal static D3D.Texture TextureFromStream(D3D.Device device, Stream stream, int width, int height, int colorKey) { return D3D.Texture.FromStream( device, stream, width, height, 1, D3D.Usage.None, D3D.Format.A8R8G8B8, D3D.Pool.Managed, D3D.Filter.Point, D3D.Filter.Point, colorKey); }
internal static D3D.Texture CreateTexture(D3D.Device device, int width, int height, TextureUsage usage) { D3D.Usage nativeUsage = D3D.Usage.None; D3D.Format nativeFormat = D3D.Format.A8R8G8B8; D3D.Pool nativePool = D3D.Pool.Managed; switch (usage) { case TextureUsage.RenderTarget: nativeUsage = D3D.Usage.RenderTarget; nativePool = D3D.Pool.Default; break; } return new D3D.Texture( device, width, height, 1, nativeUsage, nativeFormat, nativePool); }
public void NotifyOnDeviceReset( D3D9.Device d3d9Device ) { //Entering critical section this.LockDeviceAccess(); if ( this._d3dPool == D3D9.Pool.Default ) { CreateTextureResources( d3d9Device ); } //Leaving critical section this.UnlockDeviceAccess(); }
private void _createInternalResources( D3D9.Device d3d9Device ) { // Check if resources already exist. var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null && textureResources.BaseTexture != null ) { return; } // If SrcWidth and SrcHeight are zero, the requested extents have probably been set // through Width and Height. Take those values. if ( SrcWidth == 0 || SrcHeight == 0 ) { srcWidth = Width; srcHeight = Height; } // load based on tex.type switch ( TextureType ) { case TextureType.OneD: case TextureType.TwoD: _createNormalTexture( d3d9Device ); break; case TextureType.CubeMap: _createCubeTexture( d3d9Device ); break; case TextureType.ThreeD: _createVolumeTexture( d3d9Device ); break; default: FreeInternalResources(); throw new AxiomException( "Unknown texture type!" ); } }
public Stream Open( D3D9.IncludeType type, string fileName, Stream parentStream ) { return ResourceGroupManager.Instance.OpenResource( fileName, this.program.Group, true, this.program ); }
private void _freeTextureResources( D3D9.Device d3d9Device, TextureResources textureResources ) { //Entering critical section this.LockDeviceAccess(); // Release surfaces from each mip level. foreach ( var it in this._surfaceList ) { it.ReleaseSurfaces( d3d9Device ); } // Release the rest of the resources. textureResources.NormalTexture.SafeDispose(); textureResources.NormalTexture = null; textureResources.CubeTexture.SafeDispose(); textureResources.CubeTexture = null; textureResources.VolumeTexture.SafeDispose(); textureResources.VolumeTexture = null; textureResources.BaseTexture.SafeDispose(); textureResources.BaseTexture = null; textureResources.FSAASurface.SafeDispose(); textureResources.FSAASurface = null; //Leaving critical section this.UnlockDeviceAccess(); }
private void _loadNormalTexture( D3D9.Device d3d9Device, MemoryStream[] loadedStreams ) { Debug.Assert( TextureType == TextureType.OneD || TextureType == TextureType.TwoD ); // DDS load? if ( GetSourceFileType() == "dds" ) { // Use D3DX Debug.Assert( loadedStreams.Length == 1 ); var d3dUsage = D3D9.Usage.None; var numMips = 0; if ( requestedMipmapCount == (int)TextureMipmap.Unlimited ) { numMips = -1; } else if ( requestedMipmapCount == 0 ) { numMips = -3; } else { numMips = requestedMipmapCount + 1; } var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; // check if mip map volume textures are supported if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.MipCubeMap ) != D3D9.TextureCaps.MipCubeMap ) { // no mip map support for this kind of textures :( MipmapCount = 0; numMips = 1; } // Determine D3D pool to use var pool = UseDefaultPool() ? D3D9.Pool.Default : D3D9.Pool.Managed; // Get or create new texture resources structure. var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { _freeTextureResources( d3d9Device, textureResources ); } else { textureResources = _allocateTextureResources( d3d9Device ); } try { textureResources.NormalTexture = D3D9.Texture.FromMemory( d3d9Device, loadedStreams[ 0 ].GetBuffer(), -1, -1, // dims numMips, d3dUsage, D3D9.Format.Unknown, pool, D3D9.Filter.Default, D3D9.Filter.Default, 0 // colour key ); } catch ( Exception ex ) { // romeoxbm: this statement is not present in Ogre implementation, // but maybe it should be.. FreeInternalResources(); throw new AxiomException( "Can't create texture.", ex ); } textureResources.BaseTexture = textureResources.NormalTexture.QueryInterface<D3D9.BaseTexture>(); // set src and dest attributes to the same, we can't know var texDesc = textureResources.NormalTexture.GetLevelDescription( 0 ); this._d3dPool = texDesc.Pool; // set src and dest attributes to the same, we can't know _setSrcAttributes( texDesc.Width, texDesc.Height, 1, D3D9Helper.ConvertEnum( texDesc.Format ) ); _setFinalAttributes( d3d9Device, textureResources, texDesc.Width, texDesc.Height, 1, D3D9Helper.ConvertEnum( texDesc.Format ) ); if ( hwGamma ) { this._hwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, D3D9.ResourceType.Texture, texDesc.Format, false ); } internalResourcesCreated = true; } else { // find & load resource data intro stream to allow resource group changes if required Debug.Assert( loadedStreams.Length == 1 ); var pos = _name.LastIndexOf( "." ); var ext = string.Empty; if ( pos != -1 ) { ext = _name.Substring( pos + 1 ); } var img = Image.FromStream( loadedStreams[ 0 ], ext ); if ( img.Height == 0 ) { throw new AxiomException( "Image height == 0 in {0}", _name ); } if ( img.Width == 0 ) { throw new AxiomException( "Image width == 0 in {0}", _name ); } // Call internal _loadImages, not loadImage since that's external and // will determine load status etc again LoadImages( new Image[] { img } ); } }
private bool _canUseHardwareGammaCorrection( D3D9.Device d3d9Device, D3D9.Usage srcUsage, D3D9.ResourceType srcType, D3D9.Format srcFormat, bool forWriting ) { var d3d = d3d9Device.Direct3D; //TODO //if ( d3d != null ) // d3d.Release(); var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; var eBackBufferFormat = device.BackBufferFormat; // Always check 'read' capability here // We will check 'write' capability only in the context of a render target if ( forWriting ) { srcUsage |= D3D9.Usage.QuerySrgbWrite; } else { srcUsage |= D3D9.Usage.QuerySrgbRead; } // Check for sRGB support // check for auto gen. mip maps support var hr = d3d.CheckDeviceFormat( rkCurCaps.AdapterOrdinal, rkCurCaps.DeviceType, eBackBufferFormat, srcUsage, srcType, srcFormat ); return hr; }
private TextureResources _allocateTextureResources( D3D9.Device d3d9Device ) { Debug.Assert( !this._mapDeviceToTextureResources.ContainsKey( d3d9Device ) ); var textureResources = new TextureResources(); this._mapDeviceToTextureResources.Add( d3d9Device, textureResources ); return textureResources; }
private D3D9.TextureFilter _getBestFilterMethod( D3D9.Device d3d9Device ) { var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; var filterCaps = (D3D9.FilterCaps)0; // Minification filter is used for mipmap generation // Pick the best one supported for this tex type switch ( TextureType ) { case TextureType.OneD: // Same as 2D case TextureType.TwoD: filterCaps = rkCurCaps.TextureFilterCaps; break; case TextureType.ThreeD: filterCaps = rkCurCaps.VertexTextureFilterCaps; break; case TextureType.CubeMap: filterCaps = rkCurCaps.CubeTextureFilterCaps; break; default: return D3D9.TextureFilter.Point; } if ( ( filterCaps & D3D9.FilterCaps.MinGaussianQuad ) != 0 ) { return D3D9.TextureFilter.GaussianQuad; } if ( ( filterCaps & D3D9.FilterCaps.MinPyramidalQuad ) != 0 ) { return D3D9.TextureFilter.PyramidalQuad; } if ( ( filterCaps & D3D9.FilterCaps.MinAnisotropic ) != 0 ) { return D3D9.TextureFilter.Anisotropic; } if ( ( filterCaps & D3D9.FilterCaps.MinLinear ) != 0 ) { return D3D9.TextureFilter.Linear; } if ( ( filterCaps & D3D9.FilterCaps.MinPoint ) != 0 ) { return D3D9.TextureFilter.Point; } return D3D9.TextureFilter.Point; }
private bool _canUseDynamicTextures( D3D9.Device d3d9Device, D3D9.Usage srcUsage, D3D9.ResourceType srcType, D3D9.Format srcFormat ) { var d3d = d3d9Device.Direct3D; //TODO //if ( d3d != null ) // d3d.Release(); var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; var eBackBufferFormat = device.BackBufferFormat; // check for auto gen. mip maps support var hr = d3d.CheckDeviceFormat( rkCurCaps.AdapterOrdinal, rkCurCaps.DeviceType, eBackBufferFormat, srcUsage | D3D9.Usage.Dynamic, srcType, srcFormat ); return hr; }
private void _setFinalAttributes( D3D9.Device d3d9Device, TextureResources textureResources, int width, int height, int depth, PixelFormat format ) { // set target texture attributes Height = height; Width = width; Depth = depth; this.format = format; // Update size (the final size, not including temp space) // this is needed in Resource class Size = calculateSize(); // say to the world what we are doing if ( Width != SrcWidth || Height != SrcHeight ) { LogManager.Instance.Write( "D3D9 : ***** Dimensions altered by the render system" ); LogManager.Instance.Write( "D3D9 : ***** Source image dimensions : {0}x{1}", SrcWidth, SrcHeight ); LogManager.Instance.Write( "D3D9 : ***** Texture dimensions : {0}x{1}", Width, Height ); } // Create list of subsurfaces for getBuffer() _createSurfaceList( d3d9Device, textureResources ); }
private void _createVolumeTexture( D3D9.Device d3d9Device ) { Debug.Assert( Width > 0 && Height > 0 && Depth > 0 ); if ( ( Usage & TextureUsage.RenderTarget ) != 0 ) { throw new AxiomException( "D3D9 Volume texture can not be created as render target !!, SDXTexture.CreateVolumeTexture" ); } // determine which D3D9 pixel format we'll use var d3dPF = _chooseD3DFormat( d3d9Device ); // let's D3DX check the corrected pixel format var texRequires = D3D9.VolumeTexture.CheckRequirements( d3d9Device, 0, 0, 0, 0, 0, d3dPF, this._d3dPool ); d3dPF = texRequires.Format; // Use D3DX to help us create the texture, this way it can adjust any relevant sizes var d3dUsage = ( usage & TextureUsage.RenderTarget ) != 0 ? D3D9.Usage.RenderTarget : 0; var numMips = ( requestedMipmapCount == (int)TextureMipmap.Unlimited ) ? -1 : requestedMipmapCount + 1; // Check dynamic textures if ( ( Usage & TextureUsage.Dynamic ) != 0 ) { if ( _canUseDynamicTextures( d3d9Device, d3dUsage, D3D9.ResourceType.VolumeTexture, d3dPF ) ) { d3dUsage |= D3D9.Usage.Dynamic; this._dynamicTextures = true; } else { this._dynamicTextures = false; } } // Check sRGB support if ( hwGamma ) { this._hwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, d3dUsage, D3D9.ResourceType.VolumeTexture, d3dPF, false ); if ( ( usage & TextureUsage.RenderTarget ) != 0 ) { this._hwGammaWriteSupported = _canUseHardwareGammaCorrection( d3d9Device, d3dUsage, D3D9.ResourceType.VolumeTexture, d3dPF, true ); } } var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; // check if mip map volume textures are supported mipmapsHardwareGenerated = false; if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.MipVolumeMap ) != 0 ) { if ( ( Usage & TextureUsage.AutoMipMap ) != 0 && requestedMipmapCount != 0 ) { mipmapsHardwareGenerated = _canAutoGenMipMaps( d3d9Device, d3dUsage, D3D9.ResourceType.VolumeTexture, d3dPF ); if ( MipmapsHardwareGenerated ) { d3dUsage |= D3D9.Usage.AutoGenerateMipMap; numMips = 0; } } } else { // no mip map support for this kind of textures :( MipmapCount = 0; numMips = 1; } // derive the pool to use _determinePool(); // Get or create new texture resources structure. var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { _freeTextureResources( d3d9Device, textureResources ); } else { textureResources = _allocateTextureResources( d3d9Device ); } // create the texture textureResources.VolumeTexture = new D3D9.VolumeTexture( d3d9Device, Width, Height, Depth, numMips, d3dUsage, d3dPF, this._d3dPool ); // set the base texture we'll use in the render system textureResources.BaseTexture = textureResources.VolumeTexture.QueryInterface<D3D9.BaseTexture>(); // set final tex. attributes from tex. description // they may differ from the source image !!! var desc = textureResources.VolumeTexture.GetLevelDescription( 0 ); _setFinalAttributes( d3d9Device, textureResources, desc.Width, desc.Height, desc.Depth, D3D9Helper.ConvertEnum( desc.Format ) ); if ( mipmapsHardwareGenerated ) { textureResources.BaseTexture.AutoMipGenerationFilter = _getBestFilterMethod( d3d9Device ); } }
private void _createCubeTexture( D3D9.Device d3d9Device ) { // we must have those defined here Debug.Assert( SrcWidth > 0 || SrcHeight > 0 ); // determine wich D3D9 pixel format we'll use var d3dPF = _chooseD3DFormat( d3d9Device ); // let's D3DX check the corrected pixel format var texRequires = D3D9.CubeTexture.CheckRequirements( d3d9Device, 0, 0, 0, d3dPF, this._d3dPool ); d3dPF = texRequires.Format; // Use D3DX to help us create the texture, this way it can adjust any relevant sizes var d3dUsage = ( usage & TextureUsage.RenderTarget ) != 0 ? D3D9.Usage.RenderTarget : 0; var numMips = requestedMipmapCount == (int)TextureMipmap.Unlimited ? -1 : requestedMipmapCount + 1; // Check dynamic textures if ( ( usage & TextureUsage.Dynamic ) != 0 ) { if ( _canUseDynamicTextures( d3d9Device, d3dUsage, D3D9.ResourceType.CubeTexture, d3dPF ) ) { d3dUsage |= D3D9.Usage.Dynamic; this._dynamicTextures = true; } else { this._dynamicTextures = false; } } // Check sRGB support if ( hwGamma ) { this._hwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, d3dUsage, D3D9.ResourceType.CubeTexture, d3dPF, false ); if ( ( usage & TextureUsage.RenderTarget ) != 0 ) { this._hwGammaWriteSupported = _canUseHardwareGammaCorrection( d3d9Device, d3dUsage, D3D9.ResourceType.CubeTexture, d3dPF, true ); } } // Check FSAA level if ( ( usage & TextureUsage.RenderTarget ) != 0 ) { var rsys = (D3D9RenderSystem)Root.Instance.RenderSystem; rsys.DetermineFSAASettings( d3d9Device, fsaa, fsaaHint, d3dPF, false, out this._fsaaType, out this._fsaaQuality ); } else { this._fsaaType = D3D9.MultisampleType.None; this._fsaaQuality = 0; } var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; // check if mip map cube textures are supported mipmapsHardwareGenerated = false; if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.MipCubeMap ) != 0 ) { if ( ( usage & TextureUsage.AutoMipMap ) != 0 && requestedMipmapCount != 0 ) { // use auto.gen. if available; mipmapsHardwareGenerated = _canAutoGenMipMaps( d3d9Device, d3dUsage, D3D9.ResourceType.CubeTexture, d3dPF ); if ( mipmapsHardwareGenerated ) { d3dUsage |= D3D9.Usage.AutoGenerateMipMap; numMips = 0; } } } else { // no mip map support for this kind of texture :( MipmapCount = 0; numMips = 1; } // derive the pool to use _determinePool(); // Get or create new texture resources structure. var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { _freeTextureResources( d3d9Device, textureResources ); } else { textureResources = _allocateTextureResources( d3d9Device ); } // create the cube texture textureResources.CubeTexture = new D3D9.CubeTexture( d3d9Device, SrcWidth, numMips, d3dUsage, d3dPF, this._d3dPool ); // set the base texture we'll use in the render system textureResources.BaseTexture = textureResources.CubeTexture.QueryInterface<D3D9.BaseTexture>(); // set final tex. attributes from tex. description // they may differ from the source image !!! var desc = textureResources.CubeTexture.GetLevelDescription( 0 ); if ( this._fsaaType != 0 ) { // create AA surface textureResources.FSAASurface = D3D9.Surface.CreateRenderTarget( d3d9Device, desc.Width, desc.Height, d3dPF, this._fsaaType, this._fsaaQuality, false ); } _setFinalAttributes( d3d9Device, textureResources, desc.Width, desc.Height, 1, D3D9Helper.ConvertEnum( desc.Format ) ); // Set best filter type if ( mipmapsHardwareGenerated ) { textureResources.BaseTexture.AutoMipGenerationFilter = _getBestFilterMethod( d3d9Device ); } }
private void _load( D3D9.Device d3d9Device ) { if ( ( usage & TextureUsage.RenderTarget ) == TextureUsage.RenderTarget ) { _createInternalResources( d3d9Device ); return; } // Make sure streams prepared. if ( this._loadedStreams == null ) { prepare(); } // Set reading positions of loaded streams to the beginning. foreach ( var i in this._loadedStreams ) { i.Position = 0; } // only copy is on the stack so well-behaved if exception thrown var LoadedStreams = new MemoryStream[this._loadedStreams.Length]; Array.Copy( this._loadedStreams, LoadedStreams, this._loadedStreams.Length ); // load based on tex.type switch ( TextureType ) { case Graphics.TextureType.OneD: case Graphics.TextureType.TwoD: _loadNormalTexture( d3d9Device, LoadedStreams ); break; case Graphics.TextureType.ThreeD: _loadVolumeTexture( d3d9Device, LoadedStreams ); break; case Graphics.TextureType.CubeMap: _loadCubeTexture( d3d9Device, LoadedStreams ); break; default: throw new AxiomException( "Unknown texture type" ); } }
private bool _canAutoGenMipMaps( D3D9.Device d3d9Device, D3D9.Usage srcUsage, D3D9.ResourceType srcType, D3D9.Format srcFormat ) { var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; var eBackBufferFormat = device.BackBufferFormat; // Hacky override - many (all?) cards seem to not be able to autogen on // textures which are not a power of two // Can we even mipmap on 3D textures? Well if ( ( width & width - 1 ) != 0 || ( height & height - 1 ) != 0 || ( depth & depth - 1 ) != 0 ) { return false; } if ( ( rkCurCaps.Caps2 & D3D9.Caps2.CanAutoGenerateMipMap ) != 0 ) { var d3d = d3d9Device.Direct3D; // check for auto gen. mip maps support var hr = d3d.CheckDeviceFormat( rkCurCaps.AdapterOrdinal, rkCurCaps.DeviceType, eBackBufferFormat, srcUsage | D3D9.Usage.AutoGenerateMipMap, srcType, srcFormat ); d3d.Dispose(); // this HR could be a SUCCESS // but mip maps will not be generated return hr; } return false; }
private TextureResources _getTextureResources( D3D9.Device d3d9Device ) { if ( this._mapDeviceToTextureResources.ContainsKey( d3d9Device ) ) { return this._mapDeviceToTextureResources[ d3d9Device ]; } return null; }
private D3D9.Format _chooseD3DFormat( D3D9.Device d3d9Device ) { // Choose frame buffer pixel format in case PF_UNKNOWN was requested if ( Format == PixelFormat.Unknown ) { var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); return device.BackBufferFormat; } // Choose closest supported D3D format as a D3D format return D3D9Helper.ConvertEnum( D3D9Helper.GetClosestSupported( Format ) ); }
public void CreateTextureResources( D3D9.Device d3d9Device ) { //Entering critical section this.LockDeviceAccess(); if ( IsManuallyLoaded ) { preLoad(); // create the internal resources. _createInternalResources( d3d9Device ); // Load from manual loader if ( loader != null ) { loader.LoadResource( this ); } postLoad(); } else { prepare(); preLoad(); load(); postLoad(); } //Leaving critical section this.UnlockDeviceAccess(); }
private void _createSurfaceList( D3D9.Device d3d9Device, TextureResources textureResources ) { Debug.Assert( textureResources != null ); Debug.Assert( textureResources.BaseTexture != null ); // Make sure number of mips is right mipmapCount = textureResources.BaseTexture.LevelCount - 1; // Need to know static / dynamic BufferUsage bufusage; if ( ( ( Usage & TextureUsage.Dynamic ) != 0 ) && this._dynamicTextures ) { bufusage = BufferUsage.Dynamic; } else { bufusage = BufferUsage.Static; } if ( ( Usage & TextureUsage.RenderTarget ) != 0 ) { bufusage = (BufferUsage)( (int)bufusage | (int)TextureUsage.RenderTarget ); } var surfaceCount = FaceCount*( mipmapCount + 1 ); var updateOldList = this._surfaceList.Count == surfaceCount; if ( !updateOldList ) { // Create new list of surfaces _clearSurfaceList(); for ( var face = 0; face < FaceCount; ++face ) { for ( var mip = 0; mip <= MipmapCount; ++mip ) { var buffer = new D3D9HardwarePixelBuffer( bufusage, this ); this._surfaceList.Add( buffer ); } } } switch ( TextureType ) { case TextureType.OneD: case TextureType.TwoD: Debug.Assert( textureResources.NormalTexture != null ); // For all mipmaps, store surfaces as HardwarePixelBuffer for ( var mip = 0; mip <= MipmapCount; ++mip ) { var surface = textureResources.NormalTexture.GetSurfaceLevel( 0 ); var currPixelBuffer = _getSurfaceAtLevel( 0, mip ); if ( mip == 0 && requestedMipmapCount != 0 && ( usage & TextureUsage.AutoMipMap ) != 0 ) { currPixelBuffer.SetMipmapping( true, mipmapsHardwareGenerated ); } currPixelBuffer.Bind( d3d9Device, surface, textureResources.FSAASurface, this._hwGammaWriteSupported, fsaa, _name, textureResources.BaseTexture ); // decrement reference count, the GetSurfaceLevel call increments this // this is safe because the pixel buffer keeps a reference as well //TODO //surface.Release(); } break; case TextureType.CubeMap: Debug.Assert( textureResources.CubeTexture != null ); // For all faces and mipmaps, store surfaces as HardwarePixelBuffer for ( var face = 0; face < 6; ++face ) { for ( var mip = 0; mip <= MipmapCount; ++mip ) { var surface = textureResources.CubeTexture.GetCubeMapSurface( (D3D9.CubeMapFace)face, mip ); var currPixelBuffer = _getSurfaceAtLevel( face, mip ); if ( mip == 0 && requestedMipmapCount != 0 && ( usage & TextureUsage.AutoMipMap ) != 0 ) { currPixelBuffer.SetMipmapping( true, mipmapsHardwareGenerated ); } currPixelBuffer.Bind( d3d9Device, surface, textureResources.FSAASurface, this._hwGammaWriteSupported, fsaa, _name, textureResources.BaseTexture ); // decrement reference count, the GetSurfaceLevel call increments this // this is safe because the pixel buffer keeps a reference as well //TODO //surface.Release(); } } break; case TextureType.ThreeD: Debug.Assert( textureResources.VolumeTexture != null ); // For all mipmaps, store surfaces as HardwarePixelBuffer for ( var mip = 0; mip <= MipmapCount; ++mip ) { var volume = textureResources.VolumeTexture.GetVolumeLevel( mip ); var currPixelBuffer = _getSurfaceAtLevel( 0, mip ); currPixelBuffer.Bind( d3d9Device, volume, textureResources.BaseTexture ); if ( mip == 0 && requestedMipmapCount != 0 && ( usage & TextureUsage.AutoMipMap ) != 0 ) { currPixelBuffer.SetMipmapping( true, mipmapsHardwareGenerated ); } // decrement reference count, the GetSurfaceLevel call increments this // this is safe because the pixel buffer keeps a reference as well //TODO //volume.Release(); } break; } ; }
private void _loadCubeTexture( D3D9.Device d3d9Device, MemoryStream[] loadedStreams ) { Debug.Assert( TextureType == TextureType.CubeMap, "this.TextureType == TextureType.CubeMap" ); if ( GetSourceFileType() == "dds" ) { // find & load resource data Debug.Assert( this._loadedStreams.Length == 1 ); var d3dUsage = D3D9.Usage.None; var numMips = requestedMipmapCount == (int)TextureMipmap.Unlimited ? -1 : requestedMipmapCount + 1; var device = D3D9RenderSystem.DeviceManager.GetDeviceFromD3D9Device( d3d9Device ); var rkCurCaps = device.D3D9DeviceCaps; // check if mip map volume textures are supported if ( ( rkCurCaps.TextureCaps & D3D9.TextureCaps.MipCubeMap ) != D3D9.TextureCaps.MipCubeMap ) { // no mip map support for this kind of textures :( MipmapCount = 0; numMips = 1; } // Determine D3D pool to use var pool = UseDefaultPool() ? D3D9.Pool.Default : D3D9.Pool.Managed; // Get or create new texture resources structure. var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { _freeTextureResources( d3d9Device, textureResources ); } else { textureResources = _allocateTextureResources( d3d9Device ); } try { textureResources.CubeTexture = D3D9.CubeTexture.FromMemory( d3d9Device, loadedStreams[ 0 ].GetBuffer(), (int)loadedStreams[ 0 ].Length, numMips, d3dUsage, D3D9.Format.Unknown, pool, D3D9.Filter.Default, D3D9.Filter.Default, 0 // colour Key ); } catch ( Exception ex ) { freeInternalResources(); throw new AxiomException( "Can't create cube texture.", ex ); } textureResources.BaseTexture = textureResources.CubeTexture.QueryInterface<D3D9.BaseTexture>(); var texDesc = textureResources.CubeTexture.GetLevelDescription( 0 ); this._d3dPool = texDesc.Pool; // set src and dest attributes to the same, we can't know _setSrcAttributes( texDesc.Width, texDesc.Height, 1, D3D9Helper.ConvertEnum( texDesc.Format ) ); _setFinalAttributes( d3d9Device, textureResources, texDesc.Width, texDesc.Height, 1, D3D9Helper.ConvertEnum( texDesc.Format ) ); if ( hwGamma ) { this._hwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, D3D9.ResourceType.CubeTexture, texDesc.Format, false ); } internalResourcesCreated = true; } else { Debug.Assert( loadedStreams.Length == 6 ); var ext = string.Empty; var pos = _name.LastIndexOf( "." ); if ( pos != -1 ) { ext = _name.Substring( pos + 1 ); } var images = new List<Image>( 6 ); for ( var i = 0; i < 6; i++ ) { images.Add( Image.FromStream( loadedStreams[ i ], ext ) ); } LoadImages( images.ToArray() ); } }
public void NotifyOnDeviceCreate( D3D9.Device d3d9Device ) { //Entering critical section this.LockDeviceAccess(); if ( D3D9RenderSystem.ResourceManager.CreationPolicy == D3D9ResourceManager.ResourceCreationPolicy.CreateOnAllDevices ) { CreateTextureResources( d3d9Device ); } //Leaving critical section this.UnlockDeviceAccess(); }
private void CreateInternalTexture(GraphicsDevice graphicsDevice, D3D.Texture texture) { this.CalculateInternalSize(graphicsDevice); // Check if we need to resize if (this.InternalWidth == this.Width && this.InternalHeight == this.Height) { this.InternalTexture = texture; return; } this.InternalTexture = D3DHelper.CreateTexture(graphicsDevice.InternalDevice, this.InternalWidth, this.InternalHeight, TextureUsage.None); SharpDX.DataRectangle input = texture.LockRectangle(0, D3D.LockFlags.ReadOnly); SharpDX.DataStream inputStream = new SharpDX.DataStream(input.DataPointer, this.Height * input.Pitch, true, false); SharpDX.DataRectangle output = this.InternalTexture.LockRectangle(0, D3D.LockFlags.None); SharpDX.DataStream outputStream = new SharpDX.DataStream(output.DataPointer, this.InternalHeight * output.Pitch, true, true); byte[] buffer = new byte[4]; for (int y = 0; y < this.Height; y++) { for (int x = 0; x < this.Width; x++) { inputStream.Seek((y * input.Pitch) + (x * 4), SeekOrigin.Begin); inputStream.Read(buffer, 0, 4); outputStream.Seek((y * output.Pitch) + (x * 4), SeekOrigin.Begin); outputStream.Write(buffer, 0, 4); } } texture.UnlockRectangle(0); this.InternalTexture.UnlockRectangle(0); texture.Dispose(); // Get rid of old texture }
public void Open( D3D9.IncludeType type, string fileName, out Stream fileStream ) { fileStream = ResourceGroupManager.Instance.OpenResource( fileName, this.program.Group, true, this.program ); }
public void NotifyOnDeviceReset( D3D9.Device d3D9Device ) { lock ( _resourcesMutex ) { foreach ( var it in this.Resources ) { it.NotifyOnDeviceReset( d3D9Device ); } } }
public void NotifyOnDeviceLost( D3D9.Device d3d9Device ) { //Entering critical section this.LockDeviceAccess(); if ( this._d3dPool == D3D9.Pool.Default ) { var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { LogManager.Instance.Write( "D3D9 device: 0x[{0}] lost. Releasing D3D9 texture: {1}", d3d9Device.ToString(), _name ); // Just free any internal resources, don't call unload() here // because we want the un-touched resource to keep its unloaded status // after device reset. _freeTextureResources( d3d9Device, textureResources ); LogManager.Instance.Write( "Released D3D9 texture: {0}", _name ); } } //Leaving critical section this.UnlockDeviceAccess(); }
public void NotifyOnDeviceDestroy( D3D9.Device d3d9Device ) { //Entering critical section this.LockDeviceAccess(); var textureResources = _getTextureResources( d3d9Device ); if ( textureResources != null ) { LogManager.Instance.Write( "D3D9 device: 0x[{0}] destroy. Releasing D3D9 texture: {1}", d3d9Device.ToString(), _name ); // Destroy surfaces from each mip level. foreach ( var i in this._surfaceList ) { i.DestroyBufferResources( d3d9Device ); } // Just free any internal resources, don't call unload() here // because we want the un-touched resource to keep its unloaded status // after device reset. _freeTextureResources( d3d9Device, textureResources ); textureResources.SafeDispose(); this._mapDeviceToTextureResources.Remove( d3d9Device ); LogManager.Instance.Write( "Released D3D9 texture: {0}", _name ); } //Leaving critical section this.UnlockDeviceAccess(); }
public void BuildPresentParameters( ref D3D9.PresentParameters presentParams ) { // Set up the presentation parameters var pD3D = D3D9RenderSystem.Direct3D9; var devType = D3D9.DeviceType.Hardware; if ( this._device != null ) { devType = this._device.DeviceType; } presentParams.InitDefaults(); presentParams.Windowed = !isFullScreen; presentParams.SwapEffect = D3D9.SwapEffect.Discard; // triple buffer if VSync is on presentParams.BackBufferCount = this._vSync ? 2 : 1; presentParams.EnableAutoDepthStencil = isDepthBuffered; presentParams.DeviceWindowHandle = this._windowHandle.Handle; presentParams.BackBufferWidth = width; presentParams.BackBufferHeight = height; presentParams.FullScreenRefreshRateInHz = isFullScreen ? this._displayFrequency : 0; if ( presentParams.BackBufferWidth == 0 ) { presentParams.BackBufferWidth = 1; } if ( presentParams.BackBufferHeight == 0 ) { presentParams.BackBufferHeight = 1; } if ( this._vSync ) { // D3D9 only seems to support 2-4 presentation intervals in fullscreen if ( isFullScreen ) { switch ( this._vSyncInterval ) { case 1: default: presentParams.PresentationInterval = D3D9.PresentInterval.One; break; case 2: presentParams.PresentationInterval = D3D9.PresentInterval.Two; break; case 3: presentParams.PresentationInterval = D3D9.PresentInterval.Three; break; case 4: presentParams.PresentationInterval = D3D9.PresentInterval.Four; break; } ; // check that the interval was supported, revert to 1 to be safe otherwise var caps = pD3D.GetDeviceCaps( this._device.AdapterNumber, devType ); if ( ( caps.PresentationIntervals & presentParams.PresentationInterval ) == 0 ) { presentParams.PresentationInterval = D3D9.PresentInterval.One; } } else { presentParams.PresentationInterval = D3D9.PresentInterval.One; } } else { // NB not using vsync in windowed mode in D3D9 can cause jerking at low // frame rates no matter what buffering modes are used (odd - perhaps a // timer issue in D3D9 since GL doesn't suffer from this) // low is < 200fps in this context if ( !isFullScreen ) { LogManager.Instance.Write( "D3D9 : WARNING - " + "disabling VSync in windowed mode can cause timing issues at lower " + "frame rates, turn VSync on if you observe this problem." ); } presentParams.PresentationInterval = D3D9.PresentInterval.Immediate; } presentParams.BackBufferFormat = D3D9.Format.R5G6B5; if ( colorDepth > 16 ) { presentParams.BackBufferFormat = D3D9.Format.X8R8G8B8; } if ( colorDepth > 16 ) { // Try to create a 32-bit depth, 8-bit stencil if ( !pD3D.CheckDeviceFormat( this._device.AdapterNumber, devType, presentParams.BackBufferFormat, D3D9.Usage.DepthStencil, D3D9.ResourceType.Surface, D3D9.Format.D24S8 ) ) { // Bugger, no 8-bit hardware stencil, just try 32-bit zbuffer if ( !pD3D.CheckDeviceFormat( this._device.AdapterNumber, devType, presentParams.BackBufferFormat, D3D9.Usage.DepthStencil, D3D9.ResourceType.Surface, D3D9.Format.D32 ) ) { // Jeez, what a naff card. Fall back on 16-bit depth buffering presentParams.AutoDepthStencilFormat = D3D9.Format.D16; } else { presentParams.AutoDepthStencilFormat = D3D9.Format.D32; } } else { // Woohoo! if ( pD3D.CheckDepthStencilMatch( this._device.AdapterNumber, devType, presentParams.BackBufferFormat, presentParams.BackBufferFormat, D3D9.Format.D24S8 ) ) { presentParams.AutoDepthStencilFormat = D3D9.Format.D24S8; } else { presentParams.AutoDepthStencilFormat = D3D9.Format.D24X8; } } } else { // 16-bit depth, software stencil presentParams.AutoDepthStencilFormat = D3D9.Format.D16; } var rsys = (D3D9RenderSystem)Root.Instance.RenderSystem; rsys.DetermineFSAASettings( this._device.D3DDevice, fsaa, fsaaHint, presentParams.BackBufferFormat, isFullScreen, out this._fsaaType, out this._fsaaQuality ); presentParams.MultiSampleType = this._fsaaType; presentParams.MultiSampleQuality = ( this._fsaaQuality == 0 ) ? 0 : this._fsaaQuality; // Check sRGB if ( hwGamma ) { /* hmm, this never succeeds even when device does support?? if(FAILED(pD3D->CheckDeviceFormat(mDriver->getAdapterNumber(), devType, presentParams->BackBufferFormat, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_SURFACE, presentParams->BackBufferFormat ))) { // disable - not supported mHwGamma = false; } */ } }