protected void Blit(D3D9.Device d3d9Device, HardwarePixelBuffer rsrc, BasicBox srcBox, BasicBox dstBox, BufferResources srcBufferResources, BufferResources dstBufferResources) { if (dstBufferResources.Surface != null && srcBufferResources.Surface != null) { // Surface-to-surface var dsrcRect = ToD3DRectangle(srcBox); var ddestRect = ToD3DRectangle(dstBox); var srcDesc = srcBufferResources.Surface.Description; // If we're blitting from a RTT, try GetRenderTargetData // if we're going to try to use GetRenderTargetData, need to use system mem pool // romeoxbm: not used even in Ogre //var tryGetRenderTargetData = false; if ((srcDesc.Usage & D3D9.Usage.RenderTarget) != 0 && srcDesc.MultiSampleType == D3D9.MultisampleType.None) { // Temp texture var tmptex = new D3D9.Texture(d3d9Device, srcDesc.Width, srcDesc.Height, 1, // 1 mip level ie topmost, generate no mipmaps 0, srcDesc.Format, D3D9.Pool.SystemMemory); var tmpsurface = tmptex.GetSurfaceLevel(0); d3d9Device.GetRenderTargetData(srcBufferResources.Surface, tmpsurface); D3D9.Surface.FromSurface(dstBufferResources.Surface, tmpsurface, D3D9.Filter.Default, 0, dsrcRect, ddestRect); tmpsurface.SafeDispose(); tmptex.SafeDispose(); return; } // Otherwise, try the normal method D3D9.Surface.FromSurface(dstBufferResources.Surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, dsrcRect, ddestRect); } else if (dstBufferResources.Volume != null && srcBufferResources.Volume != null) { // Volume-to-volume var dsrcBox = ToD3DBox(srcBox); var ddestBox = ToD3DBox(dstBox); D3D9.Volume.FromVolume(dstBufferResources.Volume, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox); } else { // Software fallback base.Blit(rsrc, srcBox, dstBox); } }
public void CreateBuffer(D3D9.Device d3d9Device, D3D9.Pool ePool) { // Find the vertex buffer of this device. BufferResources bufferResources; if (this._mapDeviceToBufferResources.TryGetValue(d3d9Device, out bufferResources)) { bufferResources.VertexBuffer.SafeDispose(); } else { bufferResources = new BufferResources(); this._mapDeviceToBufferResources.Add(d3d9Device, bufferResources); } bufferResources.VertexBuffer = null; bufferResources.IsOutOfDate = true; bufferResources.LockOffset = 0; bufferResources.LockLength = sizeInBytes; bufferResources.LockOptions = BufferLocking.Normal; bufferResources.LastUsedFrame = Root.Instance.NextFrameNumber; // Create the vertex buffer try { bufferResources.VertexBuffer = new D3D9.VertexBuffer(d3d9Device, sizeInBytes, D3D9Helper.ConvertEnum(usage), 0, ePool); } catch (Exception ex) { throw new AxiomException("Cannot restore D3D9 vertex buffer", ex); } this._bufferDesc = bufferResources.VertexBuffer.Description; }
protected PixelBox LockBuffer(BufferResources bufferResources, BasicBox lockBox, D3D9.LockFlags flags) { // Set extents and format // Note that we do not carry over the left/top/front here, since the returned // PixelBox will be re-based from the locking point onwards var rval = new PixelBox(lockBox.Width, lockBox.Height, lockBox.Depth, Format); if (bufferResources.Surface != null) { //Surface DX.DataRectangle lrect; // Filled in by D3D if (lockBox.Left == 0 && lockBox.Top == 0 && lockBox.Right == Width && lockBox.Bottom == Height) { // Lock whole surface lrect = bufferResources.Surface.LockRectangle(flags); } else { var prect = ToD3DRectangle(lockBox); lrect = bufferResources.Surface.LockRectangle(prect, flags); } FromD3DLock(rval, lrect); } else if (bufferResources.Volume != null) { // Volume var pbox = ToD3DBox(lockBox); // specify range to lock var lbox = bufferResources.Volume.LockBox(pbox, flags); FromD3DLock(rval, lbox); } return(rval); }
public void Bind(D3D9.Device dev, D3D9.Volume volume, D3D9.BaseTexture mipTex) { //Entering critical section LockDeviceAccess(); var bufferResources = GetBufferResources(dev); var isNewBuffer = false; if (bufferResources == null) { bufferResources = new BufferResources(); this.mapDeviceToBufferResources.Add(dev, bufferResources); isNewBuffer = true; } bufferResources.MipTex = mipTex; bufferResources.Volume = volume; var desc = volume.Description; width = desc.Width; height = desc.Height; depth = desc.Depth; format = D3D9Helper.ConvertEnum(desc.Format); // Default rowPitch = Width; slicePitch = Height * Width; sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format); if (isNewBuffer && this.ownerTexture.IsManuallyLoaded) { foreach (var it in this.mapDeviceToBufferResources) { if (it.Value != bufferResources && it.Value.Volume != null && it.Key.TestCooperativeLevel().Success&& dev.TestCooperativeLevel().Success) { var fullBufferBox = new BasicBox(0, 0, 0, Width, Height, Depth); var dstBox = new PixelBox(fullBufferBox, Format); var data = new byte[sizeInBytes]; using (var d = BufferBase.Wrap(data)) { dstBox.Data = d; BlitToMemory(fullBufferBox, dstBox, it.Value, it.Key); BlitFromMemory(dstBox, fullBufferBox, bufferResources); Array.Clear(data, 0, sizeInBytes); } break; } } } //Leaving critical section UnlockDeviceAccess(); }
protected void UnlockBuffer(BufferResources bufferResources) { if (bufferResources.Surface != null) { // Surface bufferResources.Surface.UnlockRectangle(); } else if (bufferResources.Volume != null) { // Volume bufferResources.Volume.UnlockBox(); } }
/// <summary> /// Updates buffer resources from system memory buffer. /// </summary> private bool _updateBufferResources(BufferBase systemMemoryBuffer, ref BufferResources bufferResources) { Contract.RequiresNotNull(bufferResources, "Cannot update BufferResources in D3D9HardwareIndexBuffer!"); Contract.RequiresNotNull(bufferResources.IndexBuffer, "Cannot update BufferResources in D3D9HardwareIndexBuffer!"); Contract.Requires(bufferResources.IsOutOfDate); DX.DataStream dstBytes; // Lock the buffer try { dstBytes = bufferResources.IndexBuffer.Lock(bufferResources.LockOffset, bufferResources.LockLength, D3D9Helper.ConvertEnum(bufferResources.LockOptions, usage)); } catch (Exception ex) { throw new AxiomException("Cannot lock D3D9 index buffer!", ex); } using (var src = systemMemoryBuffer + bufferResources.LockOffset) { using (var dest = BufferBase.Wrap(dstBytes.DataPointer, (int)dstBytes.Length)) { Memory.Copy(src, dest, bufferResources.LockLength); } } // Unlock the buffer. var hr = bufferResources.IndexBuffer.Unlock(); if (hr.Failure) { throw new AxiomException("Cannot unlock D3D9 index buffer: {0}", hr.ToString()); } bufferResources.IsOutOfDate = false; bufferResources.LockOffset = sizeInBytes; bufferResources.LockLength = 0; bufferResources.LockOptions = BufferLocking.Normal; return(true); }
protected void Blit( D3D9.Device d3d9Device, HardwarePixelBuffer rsrc, BasicBox srcBox, BasicBox dstBox, BufferResources srcBufferResources, BufferResources dstBufferResources ) { if ( dstBufferResources.Surface != null && srcBufferResources.Surface != null ) { // Surface-to-surface var dsrcRect = ToD3DRectangle( srcBox ); var ddestRect = ToD3DRectangle( dstBox ); var srcDesc = srcBufferResources.Surface.Description; // If we're blitting from a RTT, try GetRenderTargetData // if we're going to try to use GetRenderTargetData, need to use system mem pool // romeoxbm: not used even in Ogre //var tryGetRenderTargetData = false; if ( ( srcDesc.Usage & D3D9.Usage.RenderTarget ) != 0 && srcDesc.MultiSampleType == D3D9.MultisampleType.None ) { // Temp texture var tmptex = new D3D9.Texture( d3d9Device, srcDesc.Width, srcDesc.Height, 1, // 1 mip level ie topmost, generate no mipmaps 0, srcDesc.Format, D3D9.Pool.SystemMemory ); var tmpsurface = tmptex.GetSurfaceLevel( 0 ); if ( d3d9Device.GetRenderTargetData( srcBufferResources.Surface, tmpsurface ).Success ) { // Hey, it worked // Copy from this surface instead var res = D3D9.Surface.FromSurface( dstBufferResources.Surface, tmpsurface, D3D9.Filter.Default, 0, dsrcRect, ddestRect ); if ( res.Failure ) { tmpsurface.SafeDispose(); tmptex.SafeDispose(); throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.Blit" ); } tmpsurface.SafeDispose(); tmptex.SafeDispose(); return; } } // Otherwise, try the normal method var res2 = D3D9.Surface.FromSurface( dstBufferResources.Surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, dsrcRect, ddestRect ); if ( res2.Failure ) { throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.Blit" ); } } else if ( dstBufferResources.Volume != null && srcBufferResources.Volume != null ) { // Volume-to-volume var dsrcBox = ToD3DBox( srcBox ); var ddestBox = ToD3DBox( dstBox ); var res = D3D9.Volume.FromVolume( dstBufferResources.Volume, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox ); if ( res.Failure ) { throw new AxiomException( "D3D9.Volume.FromVolume failed in D3D9HardwarePixelBuffer.Blit" ); } } else { // Software fallback base.Blit( rsrc, srcBox, dstBox ); } }
protected void UnlockBuffer( BufferResources bufferResources ) { if ( bufferResources.Surface != null ) { // Surface bufferResources.Surface.UnlockRectangle(); } else if ( bufferResources.Volume != null ) { // Volume bufferResources.Volume.UnlockBox(); } }
protected PixelBox LockBuffer( BufferResources bufferResources, BasicBox lockBox, D3D9.LockFlags flags ) { // Set extents and format // Note that we do not carry over the left/top/front here, since the returned // PixelBox will be re-based from the locking point onwards var rval = new PixelBox( lockBox.Width, lockBox.Height, lockBox.Depth, Format ); if ( bufferResources.Surface != null ) { //Surface DX.DataRectangle lrect; // Filled in by D3D if ( lockBox.Left == 0 && lockBox.Top == 0 && lockBox.Right == Width && lockBox.Bottom == Height ) { // Lock whole surface lrect = bufferResources.Surface.LockRectangle( flags ); } else { var prect = ToD3DRectangle( lockBox ); lrect = bufferResources.Surface.LockRectangle( prect, flags ); } FromD3DLock( rval, lrect ); } else if ( bufferResources.Volume != null ) { // Volume var pbox = ToD3DBox( lockBox ); // specify range to lock var lbox = bufferResources.Volume.LockBox( pbox, flags ); FromD3DLock( rval, lbox ); } return rval; }
public void Bind( D3D9.Device dev, D3D9.Volume volume, D3D9.BaseTexture mipTex ) { //Entering critical section LockDeviceAccess(); var bufferResources = GetBufferResources( dev ); var isNewBuffer = false; if ( bufferResources == null ) { bufferResources = new BufferResources(); this.mapDeviceToBufferResources.Add( dev, bufferResources ); isNewBuffer = true; } bufferResources.MipTex = mipTex; bufferResources.Volume = volume; var desc = volume.Description; width = desc.Width; height = desc.Height; depth = desc.Depth; format = D3D9Helper.ConvertEnum( desc.Format ); // Default rowPitch = Width; slicePitch = Height*Width; sizeInBytes = PixelUtil.GetMemorySize( Width, Height, Depth, Format ); if ( isNewBuffer && this.ownerTexture.IsManuallyLoaded ) { foreach ( var it in this.mapDeviceToBufferResources ) { if ( it.Value != bufferResources && it.Value.Volume != null && it.Key.TestCooperativeLevel().Success && dev.TestCooperativeLevel().Success ) { var fullBufferBox = new BasicBox( 0, 0, 0, Width, Height, Depth ); var dstBox = new PixelBox( fullBufferBox, Format ); var data = new byte[sizeInBytes]; using ( var d = BufferBase.Wrap( data ) ) { dstBox.Data = d; BlitToMemory( fullBufferBox, dstBox, it.Value, it.Key ); BlitFromMemory( dstBox, fullBufferBox, bufferResources ); Array.Clear( data, 0, sizeInBytes ); } break; } } } //Leaving critical section UnlockDeviceAccess(); }
/// <summary> /// Updates buffer resources from system memory buffer. /// </summary> private bool _updateBufferResources( BufferBase systemMemoryBuffer, ref BufferResources bufferResources ) { Contract.RequiresNotNull( bufferResources, "Cannot update BufferResources in D3D9HardwareIndexBuffer!" ); Contract.RequiresNotNull( bufferResources.IndexBuffer, "Cannot update BufferResources in D3D9HardwareIndexBuffer!" ); Contract.Requires( bufferResources.IsOutOfDate ); DX.DataStream dstBytes; // Lock the buffer try { dstBytes = bufferResources.IndexBuffer.Lock( bufferResources.LockOffset, bufferResources.LockLength, D3D9Helper.ConvertEnum( bufferResources.LockOptions, usage ) ); } catch ( Exception ex ) { throw new AxiomException( "Cannot lock D3D9 index buffer!", ex ); } using ( var src = systemMemoryBuffer + bufferResources.LockOffset ) { using ( var dest = BufferBase.Wrap( dstBytes.DataPointer, (int)dstBytes.Length ) ) { Memory.Copy( src, dest, bufferResources.LockLength ); } } // Unlock the buffer. var hr = bufferResources.IndexBuffer.Unlock(); if ( hr.Failure ) { throw new AxiomException( "Cannot unlock D3D9 index buffer: {0}", hr.ToString() ); } bufferResources.IsOutOfDate = false; bufferResources.LockOffset = sizeInBytes; bufferResources.LockLength = 0; bufferResources.LockOptions = BufferLocking.Normal; return true; }
protected void BlitToMemory(BasicBox srcBox, PixelBox dst, BufferResources srcBufferResources, D3D9.Device d3d9Device) { // Decide on pixel format of temp surface PixelFormat tmpFormat = Format; if (D3D9Helper.ConvertEnum(dst.Format) != D3D9.Format.Unknown) { tmpFormat = dst.Format; } if (srcBufferResources.Surface != null) { Debug.Assert(srcBox.Depth == 1 && dst.Depth == 1); var srcDesc = srcBufferResources.Surface.Description; var temppool = D3D9.Pool.Scratch; // if we're going to try to use GetRenderTargetData, need to use system mem pool var tryGetRenderTargetData = false; if (((srcDesc.Usage & D3D9.Usage.RenderTarget) != 0) && (srcBox.Width == dst.Width) && (srcBox.Height == dst.Height) && (srcBox.Width == Width) && (srcBox.Height == Height) && (Format == tmpFormat)) { tryGetRenderTargetData = true; temppool = D3D9.Pool.SystemMemory; } // Create temp texture var tmp = new D3D9.Texture(d3d9Device, dst.Width, dst.Height, 1, // 1 mip level ie topmost, generate no mipmaps 0, D3D9Helper.ConvertEnum(tmpFormat), temppool); var surface = tmp.GetSurfaceLevel(0); // Copy texture to this temp surface var srcRect = ToD3DRectangle(srcBox); var destRect = ToD3DRectangle(dst); // Get the real temp surface format var dstDesc = surface.Description; tmpFormat = D3D9Helper.ConvertEnum(dstDesc.Format); // Use fast GetRenderTargetData if we are in its usage conditions var fastLoadSuccess = false; if (tryGetRenderTargetData) { var result = d3d9Device.GetRenderTargetData(srcBufferResources.Surface, surface); fastLoadSuccess = result.Success; } if (!fastLoadSuccess) { var res = D3D9.Surface.FromSurface(surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, srcRect, destRect); if (res.Failure) { surface.SafeDispose(); tmp.SafeDispose(); throw new AxiomException("D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.BlitToMemory"); } } // Lock temp surface and copy it to memory var lrect = surface.LockRectangle(D3D9.LockFlags.ReadOnly); // Copy it var locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat); FromD3DLock(locked, lrect); PixelConverter.BulkPixelConversion(locked, dst); surface.UnlockRectangle(); // Release temporary surface and texture surface.SafeDispose(); tmp.SafeDispose(); } else if (srcBufferResources.Volume != null) { // Create temp texture var tmp = new D3D9.VolumeTexture(d3d9Device, dst.Width, dst.Height, dst.Depth, 0, 0, D3D9Helper.ConvertEnum(tmpFormat), D3D9.Pool.Scratch); var surface = tmp.GetVolumeLevel(0); // Volume var ddestBox = ToD3DBoxExtent(dst); var dsrcBox = ToD3DBox(srcBox); var res = D3D9.Volume.FromVolume(surface, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox); if (res.Failure) { surface.SafeDispose(); tmp.SafeDispose(); throw new AxiomException("D3D9.Surface.FromVolume failed in D3D9HardwarePixelBuffer.BlitToMemory"); } // Lock temp surface and copy it to memory var lbox = surface.LockBox(D3D9.LockFlags.ReadOnly); // Filled in by D3D // Copy it var locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat); FromD3DLock(locked, lbox); PixelConverter.BulkPixelConversion(locked, dst); surface.UnlockBox(); // Release temporary surface and texture surface.SafeDispose(); tmp.SafeDispose(); } }
protected void BlitFromMemory(PixelBox src, BasicBox dstBox, BufferResources dstBufferResources) { // for scoped deletion of conversion buffer var converted = src; var bufSize = 0; // convert to pixelbuffer's native format if necessary if (D3D9Helper.ConvertEnum(src.Format) == D3D9.Format.Unknown) { bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, Format); var newBuffer = new byte[bufSize]; using (var data = BufferBase.Wrap(newBuffer)) { converted = new PixelBox(src.Width, src.Height, src.Depth, Format, data); } PixelConverter.BulkPixelConversion(src, converted); } int rowWidth = 0; if (PixelUtil.IsCompressed(converted.Format)) { rowWidth = converted.RowPitch / 4; // D3D wants the width of one row of cells in bytes if (converted.Format == PixelFormat.DXT1) { // 64 bits (8 bytes) per 4x4 block rowWidth *= 8; } else { // 128 bits (16 bytes) per 4x4 block rowWidth *= 16; } } else { rowWidth = converted.RowPitch * PixelUtil.GetNumElemBytes(converted.Format); } if (dstBufferResources.Surface != null) { var srcRect = ToD3DRectangle(converted); var destRect = ToD3DRectangle(dstBox); bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format); var data = new byte[bufSize]; using (var dest = BufferBase.Wrap(data)) { Memory.Copy(converted.Data, dest, bufSize); } try { D3D9.Surface.FromMemory(dstBufferResources.Surface, data, D3D9.Filter.Default, 0, D3D9Helper.ConvertEnum(converted.Format), rowWidth, srcRect, destRect); } catch (Exception e) { throw new AxiomException("D3D9.Surface.FromMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e); } } else if (dstBufferResources.Volume != null) { var srcBox = ToD3DBox(converted); var destBox = ToD3DBox(dstBox); var sliceWidth = 0; if (PixelUtil.IsCompressed(converted.Format)) { sliceWidth = converted.SlicePitch / 16; // D3D wants the width of one slice of cells in bytes if (converted.Format == PixelFormat.DXT1) { // 64 bits (8 bytes) per 4x4 block sliceWidth *= 8; } else { // 128 bits (16 bytes) per 4x4 block sliceWidth *= 16; } } else { sliceWidth = converted.SlicePitch * PixelUtil.GetNumElemBytes(converted.Format); } bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format); var data = new byte[bufSize]; using (var dest = BufferBase.Wrap(data)) { Memory.Copy(converted.Data, dest, bufSize); } //TODO note sliceWidth and rowWidth are ignored.. D3D9.ImageInformation info; try { //D3D9.D3DX9.LoadVolumeFromMemory() not accessible 'cause D3D9.D3DX9 static class is not public D3D9.Volume.FromFileInMemory(dstBufferResources.Volume, data, D3D9.Filter.Default, 0, srcBox, destBox, null, out info); } catch (Exception e) { throw new AxiomException("D3D9.Volume.FromFileInMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e); } } if (this.doMipmapGen) { GenMipmaps(dstBufferResources.MipTex); } }
protected void BlitFromMemory( PixelBox src, BasicBox dstBox, BufferResources dstBufferResources ) { // for scoped deletion of conversion buffer var converted = src; var bufSize = 0; // convert to pixelbuffer's native format if necessary if ( D3D9Helper.ConvertEnum( src.Format ) == D3D9.Format.Unknown ) { bufSize = PixelUtil.GetMemorySize( src.Width, src.Height, src.Depth, Format ); var newBuffer = new byte[bufSize]; using ( var data = BufferBase.Wrap( newBuffer ) ) { converted = new PixelBox( src.Width, src.Height, src.Depth, Format, data ); } PixelConverter.BulkPixelConversion( src, converted ); } int rowWidth = 0; if ( PixelUtil.IsCompressed( converted.Format ) ) { rowWidth = converted.RowPitch/4; // D3D wants the width of one row of cells in bytes if ( converted.Format == PixelFormat.DXT1 ) { // 64 bits (8 bytes) per 4x4 block rowWidth *= 8; } else { // 128 bits (16 bytes) per 4x4 block rowWidth *= 16; } } else { rowWidth = converted.RowPitch*PixelUtil.GetNumElemBytes( converted.Format ); } if ( dstBufferResources.Surface != null ) { var srcRect = ToD3DRectangle( converted ); var destRect = ToD3DRectangle( dstBox ); bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format ); var data = new byte[bufSize]; using ( var dest = BufferBase.Wrap( data ) ) { Memory.Copy( converted.Data, dest, bufSize ); } try { D3D9.Surface.FromMemory( dstBufferResources.Surface, data, D3D9.Filter.Default, 0, D3D9Helper.ConvertEnum( converted.Format ), rowWidth, srcRect, destRect ); } catch ( Exception e ) { throw new AxiomException( "D3D9.Surface.FromMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e ); } } else if ( dstBufferResources.Volume != null ) { var srcBox = ToD3DBox( converted ); var destBox = ToD3DBox( dstBox ); var sliceWidth = 0; if ( PixelUtil.IsCompressed( converted.Format ) ) { sliceWidth = converted.SlicePitch/16; // D3D wants the width of one slice of cells in bytes if ( converted.Format == PixelFormat.DXT1 ) { // 64 bits (8 bytes) per 4x4 block sliceWidth *= 8; } else { // 128 bits (16 bytes) per 4x4 block sliceWidth *= 16; } } else { sliceWidth = converted.SlicePitch*PixelUtil.GetNumElemBytes( converted.Format ); } bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format ); var data = new byte[ bufSize ]; using ( var dest = BufferBase.Wrap( data ) ) { Memory.Copy( converted.Data, dest, bufSize ); } try { using ( var srcData = BufferBase.Wrap( data ) ) { var srcMemoryPtr = new IntPtr( srcData.Ptr ); dstBufferResources.Volume.LoadFromMemory( null, destBox, srcMemoryPtr, D3D9Helper.ConvertEnum( converted.Format ), rowWidth, slicePitch, null, srcBox, D3D9.Filter.Default, 0 ); } } catch ( Exception e ) { throw new AxiomException( "D3D9.Volume.FromFileInMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e ); } } if ( this.doMipmapGen ) { GenMipmaps( dstBufferResources.MipTex ); } }
public void CreateBuffer( D3D9.Device d3d9Device, D3D9.Pool ePool ) { //Entering critical section this.LockDeviceAccess(); BufferResources bufferResources; // Find the vertex buffer of this device. if ( this._mapDeviceToBufferResources.TryGetValue( d3d9Device, out bufferResources ) ) { bufferResources.IndexBuffer.SafeDispose(); } else { bufferResources = new BufferResources(); this._mapDeviceToBufferResources.Add( d3d9Device, bufferResources ); } bufferResources.IndexBuffer = null; bufferResources.IsOutOfDate = true; bufferResources.LockOffset = 0; bufferResources.LockLength = sizeInBytes; bufferResources.LockOptions = BufferLocking.Normal; bufferResources.LastUsedFrame = Root.Instance.NextFrameNumber; // Create the Index buffer try { bufferResources.IndexBuffer = new D3D9.IndexBuffer( d3d9Device, sizeInBytes, D3D9Helper.ConvertEnum( usage ), ePool, D3D9Helper.ConvertEnum( type ) ); } catch ( Exception ex ) { throw new AxiomException( "Cannot create D3D9 Index buffer", ex ); } this._bufferDesc = bufferResources.IndexBuffer.Description; //Leaving critical section this.UnlockDeviceAccess(); }
protected void BlitToMemory( BasicBox srcBox, PixelBox dst, BufferResources srcBufferResources, D3D9.Device d3d9Device ) { // Decide on pixel format of temp surface PixelFormat tmpFormat = Format; if ( D3D9Helper.ConvertEnum( dst.Format ) != D3D9.Format.Unknown ) { tmpFormat = dst.Format; } if ( srcBufferResources.Surface != null ) { Debug.Assert( srcBox.Depth == 1 && dst.Depth == 1 ); var srcDesc = srcBufferResources.Surface.Description; var temppool = D3D9.Pool.Scratch; // if we're going to try to use GetRenderTargetData, need to use system mem pool var tryGetRenderTargetData = false; if ( ( ( srcDesc.Usage & D3D9.Usage.RenderTarget ) != 0 ) && ( srcBox.Width == dst.Width ) && ( srcBox.Height == dst.Height ) && ( srcBox.Width == Width ) && ( srcBox.Height == Height ) && ( Format == tmpFormat ) ) { tryGetRenderTargetData = true; temppool = D3D9.Pool.SystemMemory; } // Create temp texture var tmp = new D3D9.Texture( d3d9Device, dst.Width, dst.Height, 1, // 1 mip level ie topmost, generate no mipmaps 0, D3D9Helper.ConvertEnum( tmpFormat ), temppool ); var surface = tmp.GetSurfaceLevel( 0 ); // Copy texture to this temp surface var srcRect = ToD3DRectangle( srcBox ); var destRect = ToD3DRectangle( dst ); // Get the real temp surface format var dstDesc = surface.Description; tmpFormat = D3D9Helper.ConvertEnum( dstDesc.Format ); // Use fast GetRenderTargetData if we are in its usage conditions var fastLoadSuccess = false; if ( tryGetRenderTargetData ) { var result = d3d9Device.GetRenderTargetData( srcBufferResources.Surface, surface ); fastLoadSuccess = result.Success; } if ( !fastLoadSuccess ) { var res = D3D9.Surface.FromSurface( surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, srcRect, destRect ); if ( res.Failure ) { surface.SafeDispose(); tmp.SafeDispose(); throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.BlitToMemory" ); } } // Lock temp surface and copy it to memory var lrect = surface.LockRectangle( D3D9.LockFlags.ReadOnly ); // Copy it var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat ); FromD3DLock( locked, lrect ); PixelConverter.BulkPixelConversion( locked, dst ); surface.UnlockRectangle(); // Release temporary surface and texture surface.SafeDispose(); tmp.SafeDispose(); } else if ( srcBufferResources.Volume != null ) { // Create temp texture var tmp = new D3D9.VolumeTexture( d3d9Device, dst.Width, dst.Height, dst.Depth, 0, 0, D3D9Helper.ConvertEnum( tmpFormat ), D3D9.Pool.Scratch ); var surface = tmp.GetVolumeLevel( 0 ); // Volume var ddestBox = ToD3DBoxExtent( dst ); var dsrcBox = ToD3DBox( srcBox ); var res = D3D9.Volume.FromVolume( surface, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox ); if ( res.Failure ) { surface.SafeDispose(); tmp.SafeDispose(); throw new AxiomException( "D3D9.Surface.FromVolume failed in D3D9HardwarePixelBuffer.BlitToMemory" ); } // Lock temp surface and copy it to memory var lbox = surface.LockBox( D3D9.LockFlags.ReadOnly ); // Filled in by D3D // Copy it var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat ); FromD3DLock( locked, lbox ); PixelConverter.BulkPixelConversion( locked, dst ); surface.UnlockBox(); // Release temporary surface and texture surface.SafeDispose(); tmp.SafeDispose(); } }
public void CreateBuffer( D3D9.Device d3d9Device, D3D9.Pool ePool ) { // Find the vertex buffer of this device. BufferResources bufferResources; if ( this._mapDeviceToBufferResources.TryGetValue( d3d9Device, out bufferResources ) ) { bufferResources.VertexBuffer.SafeDispose(); } else { bufferResources = new BufferResources(); this._mapDeviceToBufferResources.Add( d3d9Device, bufferResources ); } bufferResources.VertexBuffer = null; bufferResources.IsOutOfDate = true; bufferResources.LockOffset = 0; bufferResources.LockLength = sizeInBytes; bufferResources.LockOptions = BufferLocking.Normal; bufferResources.LastUsedFrame = Root.Instance.NextFrameNumber; // Create the vertex buffer try { bufferResources.VertexBuffer = new D3D9.VertexBuffer( d3d9Device, sizeInBytes, D3D9Helper.ConvertEnum( usage ), 0, // No FVF here, thank you. ePool ); } catch ( Exception ex ) { throw new AxiomException( "Cannot restore D3D9 vertex buffer", ex ); } this._bufferDesc = bufferResources.VertexBuffer.Description; }