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); } }
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 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 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(); } }