/// <summary> /// Creates texture /// </summary> /// <param name="device"></param> public VolumeRWTexture ( GraphicsDevice device, int width, int height, int depth, ColorFormat format, bool mips ) : base( device ) { this.Width = width; this.Height = height; this.Depth = depth; this.format = format; this.mipCount = mips ? ShaderResource.CalculateMipLevels(Width,Height,Depth) : 1; var texDesc = new Texture3DDescription(); texDesc.BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert( format ); texDesc.Height = Height; texDesc.MipLevels = mipCount; texDesc.OptionFlags = ResourceOptionFlags.None; texDesc.Usage = ResourceUsage.Default; texDesc.Width = Width; texDesc.Depth = Depth; var uavDesc = new UnorderedAccessViewDescription(); uavDesc.Format = Converter.Convert( format ); uavDesc.Dimension = UnorderedAccessViewDimension.Texture3D; uavDesc.Texture3D.FirstWSlice = 0; uavDesc.Texture3D.MipSlice = 0; uavDesc.Texture3D.WSize = depth; tex3D = new D3D.Texture3D( device.Device, texDesc ); SRV = new D3D.ShaderResourceView( device.Device, tex3D ); uav = new UnorderedAccessView( device.Device, tex3D, uavDesc ); }
protected override Resource GetStagingTexture(LayerMipmapSlice lm) { Debug.Assert(IO.SupportedFormats.Contains(Format) || Format == Format.R8_UInt); Debug.Assert(lm.Layer == 0); Debug.Assert(lm.IsIn(LayerMipmap)); var mipDim = Size.GetMip(lm.Mipmap); var desc = new Texture3DDescription { Width = mipDim.Width, Height = mipDim.Height, Depth = mipDim.Depth, Format = Format, MipLevels = 1, BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Staging }; // create staging texture var staging = new SharpDX.Direct3D11.Texture3D(Device.Get().Handle, desc); // copy data to staging texture Device.Get().CopySubresource(handle, staging, GetSubresourceIndex(lm), 0, mipDim); return(staging); }
/// <summary> /// Creates texture /// </summary> /// <param name="device"></param> public VolumeRWTexture(GraphicsDevice device, int width, int height, int depth, ColorFormat format, bool mips) : base(device) { this.Width = width; this.Height = height; this.Depth = depth; this.format = format; this.mipCount = mips ? ShaderResource.CalculateMipLevels(Width, Height, Depth) : 1; var texDesc = new Texture3DDescription(); texDesc.BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert(format); texDesc.Height = Height; texDesc.MipLevels = mipCount; texDesc.OptionFlags = ResourceOptionFlags.None; texDesc.Usage = ResourceUsage.Default; texDesc.Width = Width; texDesc.Depth = Depth; var uavDesc = new UnorderedAccessViewDescription(); uavDesc.Format = Converter.Convert(format); uavDesc.Dimension = UnorderedAccessViewDimension.Texture3D; uavDesc.Texture3D.FirstWSlice = 0; uavDesc.Texture3D.MipSlice = 0; uavDesc.Texture3D.WSize = depth; tex3D = new D3D.Texture3D(device.Device, texDesc); SRV = new D3D.ShaderResourceView(device.Device, tex3D); uav = new UnorderedAccessView(device.Device, tex3D, uavDesc); }
private void PlatformGetData <T>(int level, int left, int top, int right, int bottom, int front, int back, T[] data, int startIndex, int elementCount) where T : struct { // Create a temp staging resource for copying the data. // // TODO: Like in Texture2D, we should probably be pooling these staging resources // and not creating a new one each time. // var desc = new Texture3DDescription { Width = _width, Height = _height, Depth = _depth, MipLevels = 1, Format = SharpDXHelper.ToFormat(_format), BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, Usage = ResourceUsage.Staging, OptionFlags = ResourceOptionFlags.None, }; var d3dContext = GraphicsDevice._d3dContext; using (var stagingTex = new SharpDX.Direct3D11.Texture3D(GraphicsDevice._d3dDevice, desc)) { lock (d3dContext) { // Copy the data from the GPU to the staging texture. d3dContext.CopySubresourceRegion(GetTexture(), level, new ResourceRegion(left, top, front, right, bottom, back), stagingTex, 0); // Copy the data to the array. DataStream stream = null; try { var databox = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None, out stream); // Some drivers may add pitch to rows or slices. // We need to copy each row separatly and skip trailing zeros. var currentIndex = startIndex; var elementSize = _format.GetSize(); var elementsInRow = right - left; var rowsInSlice = bottom - top; for (var slice = front; slice < back; slice++) { for (var row = top; row < bottom; row++) { stream.ReadRange(data, currentIndex, elementsInRow); stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current); currentIndex += elementsInRow; } stream.Seek(databox.SlicePitch - (databox.RowPitch * rowsInSlice), SeekOrigin.Current); } } finally { SharpDX.Utilities.Dispose(ref stream); } } } }
/// <summary> /// Initializes a new instance of the <see cref="Texture3DBase" /> class. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/>.</param> /// <param name="description3D">The description.</param> /// <param name="dataRectangles">A variable-length parameters list containing data rectangles.</param> protected internal Texture3D(GraphicsDevice device, TextureDescription description3D, DataBox[] dataBoxes = null) : base(device, description3D, ViewType.Full, 0, 0) { NativeDescription = ConvertToNativeDescription(description3D); Resource = new SharpDX.Direct3D11.Texture3D(device.NativeDevice, NativeDescription, ConvertDataBoxes(dataBoxes)); NativeDeviceChild = Resource; NativeShaderResourceView = GetShaderResourceView(ViewType, ArraySlice, MipLevel); NativeUnorderedAccessView = GetUnorderedAccessView(ArraySlice, MipLevel); }
public Texture3D(int numMipmaps, Size3 size, Format format, bool createUav, bool createRt = true) { Size = size; LayerMipmap = new LayerMipmapCount(1, numMipmaps); Format = format; handle = new SharpDX.Direct3D11.Texture3D(Device.Get().Handle, CreateTextureDescription(createUav, createRt)); CreateTextureViews(createUav, createRt); }
/// <summary> /// Specialised constructor for use only by derived classes. /// </summary> /// <param name="device">The device.</param> /// <param name="texture">The texture.</param> protected internal Texture3D(GraphicsDevice device, Texture3D texture, ViewType viewType, int arraySlice, int mipMapSlice, PixelFormat viewFormat = PixelFormat.None) : base(device, texture, viewType, arraySlice, mipMapSlice, viewFormat) { // Copy the device child, but don't use NativeDeviceChild, as it is registering it for disposing. _nativeDeviceChild = texture._nativeDeviceChild; Resource = texture.Resource; NativeDescription = texture.NativeDescription; dxgiSurface = texture.dxgiSurface; NativeShaderResourceView = GetShaderResourceView(ViewType, ArraySlice, MipLevel); NativeUnorderedAccessView = GetUnorderedAccessView(ArraySlice, MipLevel); }
public Texture3D(int numMipmaps, Size3 size, Format format, bool createUav) { Size = size; NumLayers = 1; NumMipmaps = numMipmaps; Format = format; handle = new SharpDX.Direct3D11.Texture3D(Device.Get().Handle, CreateTextureDescription(createUav)); CreateTextureViews(createUav); }
public Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.width = width; this.height = height; this.depth = depth; this.levelCount = 1; #if OPENGL this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #elif DIRECTX if (mipMap) { this.levelCount = CalculateMipLevels(width, height, depth); } var description = new Texture3DDescription { Width = width, Height = height, Depth = depth, MipLevels = levelCount, Format = SharpDXHelper.ToFormat(format), BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.None, }; _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description); #endif }
public Texture3D(ImageLoader.Image image, int layer = 0) { Size = image.GetSize(0); LayerMipmap = image.LayerMipmap; Format = image.Format.DxgiFormat; var data = new DataBox[LayerMipmap.Mipmaps]; for (int curMipmap = 0; curMipmap < LayerMipmap.Mipmaps; ++curMipmap) { var mip = image.Layers[layer].Mipmaps[curMipmap]; var idx = curMipmap; data[idx].DataPointer = mip.Bytes; data[idx].SlicePitch = (int)(mip.Size / mip.Depth); data[idx].RowPitch = data[idx].SlicePitch / mip.Height; } handle = new SharpDX.Direct3D11.Texture3D(Device.Get().Handle, CreateTextureDescription(false, true), data); CreateTextureViews(false, true); }
/// <summary> /// Create texture inplace with new parameters. /// Old texture will be completely discarded /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> /// <param name="mips"></param> void CreateFromFile(byte[] fileInMemory, string name, bool forceSRgb) { IntPtr resource = new IntPtr(0); IntPtr resourceView = new IntPtr(0); var r = DdsLoader.CreateTextureFromMemory(device.Device.NativePointer, fileInMemory, forceSRgb, ref resource, ref resourceView); if (!r) { throw new GraphicsException("Failed to load texture: " + name); } tex3D = new D3D.Texture3D(resource); SRV = new D3D.ShaderResourceView(resourceView); Width = tex3D.Description.Width; Height = tex3D.Description.Height; Depth = tex3D.Description.Depth; mipCount = tex3D.Description.MipLevels; format = Converter.Convert(tex3D.Description.Format); }
/// <summary> /// Function to create an image with initial data. /// </summary> /// <param name="initialData">Data to use when creating the image.</param> /// <remarks> /// The <paramref name="initialData" /> can be NULL (Nothing in VB.Net) IF the texture is not created with an Immutable usage flag. /// <para>To initialize the texture, create a new <see cref="GorgonLibrary.Graphics.GorgonImageData">GorgonImageData</see> object and fill it with image information.</para> /// </remarks> protected override void OnInitialize(GorgonImageData initialData) { var desc = new D3D.Texture3DDescription { Format = (Format)Settings.Format, Width = Settings.Width, Height = Settings.Height, Depth = Settings.Depth, MipLevels = Settings.MipCount, BindFlags = GetBindFlags(false, false), Usage = (D3D.ResourceUsage)Settings.Usage, OptionFlags = D3D.ResourceOptionFlags.None }; switch (Settings.Usage) { case BufferUsage.Staging: desc.CpuAccessFlags = D3D.CpuAccessFlags.Read | D3D.CpuAccessFlags.Write; break; case BufferUsage.Dynamic: desc.CpuAccessFlags = D3D.CpuAccessFlags.Write; break; default: desc.CpuAccessFlags = D3D.CpuAccessFlags.None; break; } if ((initialData != null) && (initialData.Buffers.Count > 0)) { D3DResource = new D3D.Texture3D(Graphics.D3DDevice, desc, initialData.Buffers.DataBoxes); } else { D3DResource = new D3D.Texture3D(Graphics.D3DDevice, desc); } }
/// <summary> /// Creates texture /// </summary> /// <param name="device"></param> public Texture3D(GraphicsDevice device, int width, int height, int depth, ColorFormat format, bool mips, bool srgb = false) : base(device) { this.Width = width; this.Height = height; this.Depth = depth; this.format = format; this.mipCount = mips ? ShaderResource.CalculateMipLevels(Width, Height, Depth) : 1; var texDesc = new Texture3DDescription(); texDesc.BindFlags = BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.Convert(format); texDesc.Height = Height; texDesc.MipLevels = mipCount; texDesc.OptionFlags = ResourceOptionFlags.None; texDesc.Usage = ResourceUsage.Default; texDesc.Width = Width; texDesc.Depth = Depth; tex3D = new D3D.Texture3D(device.Device, texDesc); SRV = new D3D.ShaderResourceView(device.Device, tex3D); }
protected Texture3D(GraphicsDevice graphicsDevice, int width, int height, int depth, bool mipMap, SurfaceFormat format, bool renderTarget) { if (graphicsDevice == null) { throw new ArgumentNullException("graphicsDevice"); } this.GraphicsDevice = graphicsDevice; this.width = width; this.height = height; this.depth = depth; this._levelCount = 1; this._format = format; #if OPENGL this.glTarget = TextureTarget.Texture3D; GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); format.GetGLFormat(out glInternalFormat, out glFormat, out glType); GL.TexImage3D(glTarget, 0, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); if (mipMap) { throw new NotImplementedException("Texture3D does not yet support mipmaps."); } #elif DIRECTX if (mipMap) { this._levelCount = CalculateMipLevels(width, height, depth); } var description = new Texture3DDescription { Width = width, Height = height, Depth = depth, MipLevels = _levelCount, Format = SharpDXHelper.ToFormat(format), BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.None, }; if (renderTarget) { description.BindFlags |= BindFlags.RenderTarget; if (mipMap) { // Note: XNA 4 does not have a method Texture.GenerateMipMaps() // because generation of mipmaps is not supported on the Xbox 360. // TODO: New method Texture.GenerateMipMaps() required. description.OptionFlags |= ResourceOptionFlags.GenerateMipMaps; } } _texture = new SharpDX.Direct3D11.Texture3D(graphicsDevice._d3dDevice, description); #endif }
/// <summary> /// Initializes a new instance of the <see cref="Texture3DBase" /> class. /// </summary> /// <param name="device">The <see cref="DirectXDevice"/>.</param> /// <param name="description3D">The description.</param> /// <msdn-id>ff476522</msdn-id> /// <unmanaged>HRESULT ID3D11Device::CreateTexture3D([In] const D3D11_TEXTURE3D_DESC* pDesc,[In, Buffer, Optional] const D3D11_SUBRESOURCE_DATA* pInitialData,[Out, Fast] ID3D11Texture3D** ppTexture3D)</unmanaged> /// <unmanaged-short>ID3D11Device::CreateTexture3D</unmanaged-short> protected internal Texture3DBase(DirectXDevice device, Texture3DDescription description3D) : base(device, description3D) { Resource = new SharpDX.Direct3D11.Texture3D(device, description3D); }
/// <summary> /// Initializes a new instance of the <see cref="Texture3DBase" /> class. /// </summary> /// <param name="device">The <see cref="DirectXDevice"/>.</param> /// <param name="description3D">The description.</param> /// <param name="dataRectangles">A variable-length parameters list containing data rectangles.</param> /// <msdn-id>ff476522</msdn-id> /// <unmanaged>HRESULT ID3D11Device::CreateTexture3D([In] const D3D11_TEXTURE3D_DESC* pDesc,[In, Buffer, Optional] const D3D11_SUBRESOURCE_DATA* pInitialData,[Out, Fast] ID3D11Texture3D** ppTexture3D)</unmanaged> /// <unmanaged-short>ID3D11Device::CreateTexture3D</unmanaged-short> protected internal Texture3DBase(DirectXDevice device, Texture3DDescription description3D, DataBox[] dataRectangles) : base(device, description3D) { Resource = new SharpDX.Direct3D11.Texture3D(device, description3D, dataRectangles); }
/// <summary> /// Specialised constructor for use only by derived classes. /// </summary> /// <param name="device">The device.</param> /// <param name="texture">The texture.</param> /// <msdn-id>ff476522</msdn-id> /// <unmanaged>HRESULT ID3D11Device::CreateTexture3D([In] const D3D11_TEXTURE3D_DESC* pDesc,[In, Buffer, Optional] const D3D11_SUBRESOURCE_DATA* pInitialData,[Out, Fast] ID3D11Texture3D** ppTexture3D)</unmanaged> /// <unmanaged-short>ID3D11Device::CreateTexture3D</unmanaged-short> protected internal Texture3DBase(DirectXDevice device, SharpDX.Direct3D11.Texture3D texture) : base(device, texture.Description) { Resource = texture; }
internal RenderTarget3D(DirectXDevice device, SharpDX.Direct3D11.Texture3D texture) : base(device, texture) { }
// Simple DDS loader ported from http://msdn.microsoft.com/en-us/library/windows/apps/jj651550.aspx static void CreateD3DResources( SharpDX.Direct3D11.Device d3dDevice, TextureDimension resDim, int width, int height, int depth, int mipCount, int arraySize, Format format, bool isCubeMap, DataBox[] initData, //_In_reads_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData, out SharpDX.Direct3D11.Resource texture, out SharpDX.Direct3D11.ShaderResourceView textureView //_Out_opt_ ID3D11Resource** texture, //_Out_opt_ ID3D11ShaderResourceView** textureView ) { texture = null; textureView = null; if (d3dDevice == null || initData == null) { return; } switch (resDim) { case TextureDimension.Texture1D:// D3D11_RESOURCE_DIMENSION_TEXTURE1D: { Texture1DDescription desc = new Texture1DDescription(); //D3D11_TEXTURE1D_DESC desc; desc.Width = width; desc.MipLevels = mipCount; desc.ArraySize = arraySize; desc.Format = format; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource;// D3D11_BIND_SHADER_RESOURCE; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; Texture1D tex = null; //ID3D11Texture1D* tex = nullptr; tex = new Texture1D(d3dDevice, desc, initData); //hr = d3dDevice->CreateTexture1D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); //D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; //memset(&SRVDesc, 0, sizeof(SRVDesc)); SRVDesc.Format = format; if (arraySize > 1) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture1DArray;// D3D_SRV_DIMENSION_TEXTURE1DARRAY; SRVDesc.Texture1DArray.MipLevels = desc.MipLevels; SRVDesc.Texture1DArray.ArraySize = arraySize; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture1D;// D3D_SRV_DIMENSION_TEXTURE1D; SRVDesc.Texture1D.MipLevels = desc.MipLevels; } textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); //hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView); if (textureView == null) { tex.Dispose(); return; } texture = tex; } } break; case TextureDimension.TextureCube: case TextureDimension.Texture2D:// D3D11_RESOURCE_DIMENSION_TEXTURE2D: { Texture2DDescription desc = new Texture2DDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = mipCount; desc.ArraySize = arraySize; desc.Format = format; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = (isCubeMap) ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None; Texture2D tex = null; tex = new Texture2D(d3dDevice, desc, initData); tex.DebugName = "Test"; //hr = d3dDevice->CreateTexture2D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); SRVDesc.Format = format; if (isCubeMap) { if (arraySize > 6) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCubeArray; SRVDesc.TextureCubeArray.MipLevels = desc.MipLevels; // Earlier we set arraySize to (NumCubes * 6) SRVDesc.TextureCubeArray.CubeCount = arraySize / 6; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCube; SRVDesc.TextureCube.MipLevels = desc.MipLevels; } } else if (arraySize > 1) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DArray; SRVDesc.Texture2DArray.MipLevels = desc.MipLevels; SRVDesc.Texture2DArray.ArraySize = arraySize; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D; SRVDesc.Texture2D.MipLevels = desc.MipLevels; } textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); //hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView); texture = tex; } } break; case TextureDimension.Texture3D: { Texture3DDescription desc = new Texture3DDescription(); desc.Width = width; desc.Height = height; desc.Depth = depth; desc.MipLevels = mipCount; desc.Format = format; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; Texture3D tex = null; tex = new Texture3D(d3dDevice, desc, initData); //hr = d3dDevice->CreateTexture3D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); SRVDesc.Format = format; SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture3D; SRVDesc.Texture3D.MipLevels = desc.MipLevels; textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); texture = tex; } } break; } }
/// <summary> /// Gets a copy of 3D texture data, specifying a mipmap level, source box, start index, and number of elements. /// </summary> /// <typeparam name="T">The type of the elements in the array.</typeparam> /// <param name="level">Mipmap level.</param> /// <param name="left">Position of the left side of the box on the x-axis.</param> /// <param name="top">Position of the top of the box on the y-axis.</param> /// <param name="right">Position of the right side of the box on the x-axis.</param> /// <param name="bottom">Position of the bottom of the box on the y-axis.</param> /// <param name="front">Position of the front of the box on the z-axis.</param> /// <param name="back">Position of the back of the box on the z-axis.</param> /// <param name="data">Array of data.</param> /// <param name="startIndex">Index of the first element to get.</param> /// <param name="elementCount">Number of elements to get.</param> public void GetData <T>(int level, int left, int top, int right, int bottom, int front, int back, T[] data, int startIndex, int elementCount) where T : struct { if (data == null || data.Length == 0) { throw new ArgumentException("data cannot be null"); } if (data.Length < startIndex + elementCount) { throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested."); } // Disallow negative box size if ((left < 0 || left >= right) || (top < 0 || top >= bottom) || (front < 0 || front >= back)) { throw new ArgumentException("Neither box size nor box position can be negative"); } #if IOS // Reading back a texture from GPU memory is unsupported // in OpenGL ES 2.0 and no work around has been implemented. throw new NotSupportedException("OpenGL ES 2.0 does not support texture reads."); #elif ANDROID throw new NotImplementedException(); #elif PSM throw new NotImplementedException(); #elif DIRECTX // Create a temp staging resource for copying the data. // // TODO: Like in Texture2D, we should probably be pooling these staging resources // and not creating a new one each time. // var desc = new Texture3DDescription { Width = width, Height = height, Depth = depth, MipLevels = 1, Format = SharpDXHelper.ToFormat(_format), BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, Usage = ResourceUsage.Staging, OptionFlags = ResourceOptionFlags.None, }; var d3dContext = GraphicsDevice._d3dContext; using (var stagingTex = new SharpDX.Direct3D11.Texture3D(GraphicsDevice._d3dDevice, desc)) { lock (d3dContext) { // Copy the data from the GPU to the staging texture. d3dContext.CopySubresourceRegion(GetTexture(), level, new ResourceRegion(left, top, front, right, bottom, back), stagingTex, 0); // Copy the data to the array. DataStream stream; var databox = d3dContext.MapSubresource(stagingTex, 0, MapMode.Read, MapFlags.None, out stream); // Some drivers may add pitch to rows or slices. // We need to copy each row separatly and skip trailing zeros. var currentIndex = startIndex; var elementSize = SharpDX.Utilities.SizeOf <T>(); var elementsInRow = right - left; var rowsInSlice = bottom - top; for (var slice = front; slice < back; slice++) { for (var row = top; row < bottom; row++) { stream.ReadRange(data, currentIndex, elementsInRow); stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current); currentIndex += elementsInRow; } stream.Seek(databox.SlicePitch - (databox.RowPitch * rowsInSlice), SeekOrigin.Current); } stream.Dispose(); } } #else throw new NotImplementedException(); #endif }
/// <summary> /// Creates a new <see cref="RenderTarget3D"/> from a <see cref="SharpDX.Direct3D11.Texture3D"/>. /// </summary> /// <param name="device">The <see cref="DirectXDevice"/>.</param> /// <param name="texture">The native texture <see cref="SharpDX.Direct3D11.Texture3D"/>.</param> /// <returns> /// A new instance of <see cref="RenderTarget3D"/> class. /// </returns> /// <msdn-id>ff476521</msdn-id> /// <unmanaged>HRESULT ID3D11Device::CreateTexture3D([In] const D3D11_TEXTURE3D_DESC* pDesc,[In, Buffer, Optional] const D3D11_SUBRESOURCE_DATA* pInitialData,[Out, Fast] ID3D11Texture3D** ppTexture3D)</unmanaged> /// <unmanaged-short>ID3D11Device::CreateTexture3D</unmanaged-short> public static RenderTarget3D New(DirectXDevice device, SharpDX.Direct3D11.Texture3D texture) { return(new RenderTarget3D(device, texture)); }