/// <summary> /// Copies the content of the specified texture. /// </summary> /// <param name="device">The Direct3D 11 device.</param> /// <param name="source">The source texture.</param> /// <param name="target">The target texture.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="device"/>, <paramref name="source"/> or <paramref name="target"/> is /// <see langword="null"/>. /// </exception> public static void Copy(Device device, Texture2D source, Texture2D target) { if (device == null) throw new ArgumentNullException("device"); if (source == null) throw new ArgumentNullException("source"); if (target == null) throw new ArgumentNullException("target"); int sourceWidth = source.Description.Width; int sourceHeight = source.Description.Height; int targetWidth = target.Description.Width; int targetHeight = target.Description.Height; if (sourceWidth == targetWidth && sourceHeight == targetHeight) { device.ImmediateContext.CopyResource(source, target); } else { int width = Math.Min(sourceWidth, targetWidth); int height = Math.Min(sourceHeight, targetHeight); var region = new ResourceRegion(0, 0, 0, width, height, 1); device.ImmediateContext.CopySubresourceRegion(source, 0, region, target, 0); } }
/// <summary> /// Sets 2D texture data, specifying a mipmap level, source rectangle, start index, and number of elements. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="level"></param> /// <param name="data"></param> /// <param name="startIndex"></param> /// <param name="elementCount"></param> public void SetData <T>(int level, Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct { var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); // Use try..finally to make sure dataHandle is freed in case of an error try { var startBytes = startIndex * elementSizeInByte; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); int x, y, w, h; if (rect.HasValue) { x = rect.Value.X; y = rect.Value.Y; w = rect.Value.Width; h = rect.Value.Height; } else { x = 0; y = 0; w = Math.Max(Width >> level, 1); h = Math.Max(Height >> level, 1); // For DXT textures the width and height of each level is a multiple of 4. if (format == ColorFormat.Dxt1 || format == ColorFormat.Dxt3 || format == ColorFormat.Dxt5) { w = (w + 3) & ~3; h = (h + 3) & ~3; } } var box = new SharpDX.DataBox(dataPtr, w * Converter.SizeOf(format), 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = y; region.Front = 0; region.Back = 1; region.Bottom = y + h; region.Left = x; region.Right = x + w; lock (device.DeviceContext) { device.DeviceContext.UpdateSubresource(box, tex2D, level, region); } } finally { dataHandle.Free(); } }
private void RenderFrame(BitmapFrame frame) { // Make sure there's a texture to render to // TODO: Can probably afford to remove width/height from frame, and just add the buffer name. this client code can then check that the buffer name matches what it expects, and noop if it doesn't if (texture == null) { BuildTexture(frame.Width, frame.Height); } // If the details don't match our expected sizes, noop the frame to avoid a CTD. // This may "stick" and cause no rendering at all, but can be fixed by jiggling the size a bit, or reloading. if ( texture.Description.Width != frame.Width || texture.Description.Height != frame.Height || bitmapBuffer.BufferSize != frame.Length ) { return; } // Calculate multipliers for the frame var depthPitch = frame.Length; var rowPitch = frame.Length / frame.Height; var bytesPerPixel = rowPitch / frame.Width; // Build the destination region for the dirty rect we're drawing var texDesc = texture.Description; var sourceRegionOffset = (frame.DirtyX * bytesPerPixel) + (frame.DirtyY * rowPitch); var destinationRegion = new D3D11.ResourceRegion() { Top = Math.Min(frame.DirtyY, texDesc.Height), Bottom = Math.Min(frame.DirtyY + frame.DirtyHeight, texDesc.Height), Left = Math.Min(frame.DirtyX, texDesc.Width), Right = Math.Min(frame.DirtyX + frame.DirtyWidth, texDesc.Width), Front = 0, Back = 1, }; // Write data from the buffer var context = DxHandler.Device.ImmediateContext; bitmapBuffer.Read(ptr => { context.UpdateSubresource(texture, 0, destinationRegion, ptr + sourceRegionOffset, rowPitch, depthPitch); }); }
private SurfaceWithInfo WaitForNewFrame() { _currentFrame?.Dispose(); _frameEvent.Reset();//获取新帧 var whiteRegion = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, 1920, 1080, 1); var signaledEvent = _events[WaitHandle.WaitAny(_events)]; if (signaledEvent == _closedEvent) { Cleanup(); return(null); } var result = new SurfaceWithInfo { SystemRelativeTime = _currentFrame.SystemRelativeTime }; using (var multithreadLock = new MultithreadLock(_multithread)) using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(_currentFrame.Surface)) { _d3dDevice.ImmediateContext.ClearRenderTargetView(_composeRenderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1)); var region = new SharpDX.Direct3D11.ResourceRegion(LocationX > 0?LocationX:0, LocationY > 0?LocationY:0, 0, (LocationX + 1920 > sourceTexture.Description.Width ? sourceTexture.Description.Width : LocationX + 1920), (LocationY + 1080 > sourceTexture.Description.Height ? sourceTexture.Description.Height : LocationY + 1080), 1); _d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, whiteRegion, _blankComposeTexture, 0); //覆盖掉原本区域 _d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, _tarComposeTexture, LocationX >= 0?0:(1920 + LocationX > 0? 1920 + LocationX - 1:0), LocationY >= 0?0:(1080 + LocationY - 1 > 0? 1080 + LocationY - 1:0), 0); //_targetTexture为剪切后的区域 //https://stackoverflow.com/questions/64130136/texture2d-from-byte-array-sharpdx //实现空白区域 var description = _tarComposeTexture.Description; description.Usage = SharpDX.Direct3D11.ResourceUsage.Default; description.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget; description.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; description.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; using (var copyTexture = new SharpDX.Direct3D11.Texture2D(_d3dDevice, description)) { _d3dDevice.ImmediateContext.CopyResource(_tarComposeTexture, copyTexture); result.Surface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(copyTexture); } } return(result); }
/// <summary> /// 原始思想:http://stackoverflow.com/questions/19364012/d3d11-creating-a-cube-map-from-6-images /// 上面的链接页面中,OptionFlags 的参数错误,后参考 http://www.gamedev.net/topic/647237-dx11-cube-texture-creation/ 做出修正。 /// </summary> /// <param name="device"></param> /// <param name="texture2Ds"></param> /// <returns></returns> public static ShaderResourceView CreateCubeMapFrom6Textures(Device device, Texture2D[] texture2Ds) { Debug.Assert(texture2Ds.Length == 6); var texElemDesc = texture2Ds[0].Description; var texArrayDesc = new Texture2DDescription() { Width = texElemDesc.Width, Height = texElemDesc.Height, MipLevels = texElemDesc.MipLevels, ArraySize = 6, Format = texElemDesc.Format, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.TextureCube }; var texArray = new Texture2D(device, texArrayDesc); var context = device.ImmediateContext; var sourceRegion = new ResourceRegion(); for (var i = 0; i < 6; ++i) { for (var mipLevel = 0; mipLevel < texArrayDesc.MipLevels; ++mipLevel) { sourceRegion.Left = 0; sourceRegion.Right = texArrayDesc.Width >> mipLevel; sourceRegion.Top = 0; sourceRegion.Bottom = texArrayDesc.Height >> mipLevel; sourceRegion.Front = 0; sourceRegion.Back = 1; if (sourceRegion.Bottom <= 0 || sourceRegion.Right <= 0) { break; } var n = Resource.CalculateSubResourceIndex(mipLevel, i, texArrayDesc.MipLevels); context.CopySubresourceRegion(texture2Ds[i], mipLevel, sourceRegion, texArray, n); } } var viewDesc = new ShaderResourceViewDescription() { Format = texArrayDesc.Format, Dimension = ShaderResourceViewDimension.TextureCube, TextureCube = new ShaderResourceViewDescription.TextureCubeResource() { MostDetailedMip = 0, MipLevels = texArrayDesc.MipLevels } }; return new ShaderResourceView(device, texArray, viewDesc); }
// Method to marshal from native to managed struct internal unsafe void __MarshalFrom(ref __Native @ref) { this.SourceRegionPointer = @ref.SourceRegionPointer; this.DestinationRegionPointer = @ref.DestinationRegionPointer; this.FirstSourceMip = @ref.FirstSourceMip; this.FirstDestinationMip = @ref.FirstDestinationMip; this.MipCount = @ref.MipCount; this.FirstSourceElement = @ref.FirstSourceElement; this.FirstDestinationElement = @ref.FirstDestinationElement; this.ElementCount = @ref.ElementCount; this.Filter = @ref.Filter; this.MipFilter = @ref.MipFilter; this.SourceRegion = new ResourceRegion(); if (@ref.SourceRegionPointer != IntPtr.Zero) Utilities.Read<ResourceRegion>(@ref.SourceRegionPointer, ref this.SourceRegion); this.DestinationRegion = new ResourceRegion(); if (@ref.DestinationRegionPointer != IntPtr.Zero) Utilities.Read<ResourceRegion>(@ref.DestinationRegionPointer, ref this.DestinationRegion); }
public SurfaceWithInfo WaitForNewFrame() { // Let's get a fresh one. _currentFrame?.Dispose(); _frameEvent.Reset(); var signaledEvent = _events[WaitHandle.WaitAny(_events)]; if (signaledEvent == _closedEvent) { Cleanup(); return(null); } var result = new SurfaceWithInfo(); result.SystemRelativeTime = _currentFrame.SystemRelativeTime; using (var multithreadLock = new MultithreadLock(_multithread)) using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(_currentFrame.Surface)) { _sharpDxD3dDevice.ImmediateContext.ClearRenderTargetView(_composeRenderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1)); var width = Math.Clamp(_currentFrame.ContentSize.Width, 0, _currentFrame.Surface.Description.Width); var height = Math.Clamp(_currentFrame.ContentSize.Height, 0, _currentFrame.Surface.Description.Height); var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1); _sharpDxD3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, _composeTexture, 0); var description = sourceTexture.Description; description.Usage = SharpDX.Direct3D11.ResourceUsage.Default; description.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget; description.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None; description.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; using (var copyTexture = new SharpDX.Direct3D11.Texture2D(_sharpDxD3dDevice, description)) { _sharpDxD3dDevice.ImmediateContext.CopyResource(_composeTexture, copyTexture); result.Surface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(copyTexture); } } return(result); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion?sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source == null) { throw new ArgumentNullException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?(); if (sourecRegion.HasValue) { var value = sourecRegion.Value; nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back); } NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ); }
internal unsafe void UpdateGeneric(List<MyInstanceData> instanceData, int capacity) { var instancesNum = instanceData.Count; if (m_capacity < instancesNum && VertexBuffer != VertexBufferId.NULL) { MyHwBuffers.Destroy(VertexBuffer); VertexBuffer = VertexBufferId.NULL; } if (m_capacity < instancesNum) { m_capacity = Math.Max(instancesNum, capacity); VertexBuffer = MyHwBuffers.CreateVertexBuffer(m_capacity, sizeof(MyVertexFormatGenericInstance), null, m_debugName + " instances buffer"); } fixed (MyInstanceData* dataPtr = instanceData.ToArray()) { DataBox srcBox = new DataBox(new IntPtr(dataPtr)); ResourceRegion dstRegion = new ResourceRegion(0, 0, 0, sizeof(MyVertexFormatGenericInstance) * instancesNum, 1, 1); MyRender11.ImmediateContext.UpdateSubresource(srcBox, VertexBuffer.Buffer, 0, dstRegion); } }
// Method to marshal from native to managed struct internal unsafe void __MarshalFrom(ref __Native @ref) { this.SourceRegionPointer = @ref.SourceRegionPointer; this.DestinationRegionPointer = @ref.DestinationRegionPointer; this.FirstSourceMip = @ref.FirstSourceMip; this.FirstDestinationMip = @ref.FirstDestinationMip; this.MipCount = @ref.MipCount; this.FirstSourceElement = @ref.FirstSourceElement; this.FirstDestinationElement = @ref.FirstDestinationElement; this.ElementCount = @ref.ElementCount; this.Filter = @ref.Filter; this.MipFilter = @ref.MipFilter; this.SourceRegion = new ResourceRegion(); if (@ref.SourceRegionPointer != IntPtr.Zero) { Utilities.Read <ResourceRegion>(@ref.SourceRegionPointer, ref this.SourceRegion); } this.DestinationRegion = new ResourceRegion(); if (@ref.DestinationRegionPointer != IntPtr.Zero) { Utilities.Read <ResourceRegion>(@ref.DestinationRegionPointer, ref this.DestinationRegion); } }
public override void OnPaint(PaintElementType type, Rect dirtyRect, IntPtr buffer, int width, int height) { var targetTexture = type switch { PaintElementType.View => texture, PaintElementType.Popup => popupTexture, _ => throw new Exception($"Unknown paint type {type}"), }; // Nasty hack; we're keeping a ref to the view buffer for pixel lookups without going through DX if (type == PaintElementType.View) { bufferPtr = buffer; bufferWidth = width; bufferHeight = height; } // Calculate offset multipliers for the current buffer var rowPitch = width * bytesPerPixel; var depthPitch = rowPitch * height; // Build the destination region for the dirty rect that we'll draw to var texDesc = targetTexture.Description; var sourceRegionPtr = buffer + (dirtyRect.X * bytesPerPixel) + (dirtyRect.Y * rowPitch); var destinationRegion = new D3D11.ResourceRegion() { Top = Math.Min(dirtyRect.Y, texDesc.Height), Bottom = Math.Min(dirtyRect.Y + dirtyRect.Height, texDesc.Height), Left = Math.Min(dirtyRect.X, texDesc.Width), Right = Math.Min(dirtyRect.X + dirtyRect.Width, texDesc.Width), Front = 0, Back = 1, }; // Draw to the target var context = targetTexture.Device.ImmediateContext; context.UpdateSubresource(targetTexture, 0, destinationRegion, sourceRegionPtr, rowPitch, depthPitch); // Only need to do composition + flush on primary texture if (type != PaintElementType.View) { return; } // Intersect with dirty? if (popupVisible) { context.CopySubresourceRegion(popupTexture, 0, null, targetTexture, 0, popupRect.X, popupRect.Y); } context.Flush(); // Rendering is complete, clean up any obsolete textures var textures = obsoluteTextures; obsoluteTextures = new ConcurrentBag <D3D11.Texture2D>(); foreach (var texture in textures) { texture.Dispose(); } }
public void Test1D() { var textureData = new byte[256]; for(int i = 0; i < textureData.Length; i++) textureData[i] = (byte)i; // ------------------------------------------------------- // General test for a Texture1D // ------------------------------------------------------- // Create Texture1D var texture = Texture1D.New(GraphicsDevice, textureData.Length, PixelFormat.R8.UNorm); // Check description against native description var d3d11Texture = (Direct3D11.Texture1D)texture; var d3d11SRV = (Direct3D11.ShaderResourceView)texture; Assert.AreEqual(d3d11Texture.Description, new Direct3D11.Texture1DDescription() { Width = textureData.Length, ArraySize = 1, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Format = DXGI.Format.R8_UNorm, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Default }); // Check shader resource view. var srvDescription = d3d11SRV.Description; // Clear those fields that are garbage returned from ShaderResourceView.Description. srvDescription.Texture2DArray.ArraySize = 0; srvDescription.Texture2DArray.FirstArraySlice = 0; Assert.AreEqual(srvDescription, new Direct3D11.ShaderResourceViewDescription() { Dimension = ShaderResourceViewDimension.Texture1D, Format = DXGI.Format.R8_UNorm, Texture1D = { MipLevels = 1, MostDetailedMip = 0 }, }); // Check mipmap description var mipmapDescription = texture.GetMipMapDescription(0); var rowStride = textureData.Length * sizeof(byte); var refMipmapDescription = new MipMapDescription(textureData.Length, 1, 1, rowStride, rowStride, textureData.Length, 1); Assert.AreEqual(mipmapDescription, refMipmapDescription); // Check that getting the default SRV is the same as getting the first mip/array Assert.AreEqual(texture.ShaderResourceView[ViewType.Full, 0, 0].View, d3d11SRV); // Check GraphicsDevice.GetData/SetData data // Upload the textureData to the GPU texture.SetData(GraphicsDevice, textureData); // Read back data from the GPU var readBackData = texture.GetData<byte>(); // Check that both content are equal Assert.True(Utilities.Compare(textureData, readBackData)); // ------------------------------------------------------- // Check with Texture1D.Clone and GraphicsDevice.Copy // ------------------------------------------------------- using (var texture2 = texture.Clone<Texture1D>()) { GraphicsDevice.Copy(texture, texture2); readBackData = texture2.GetData<byte>(); // Check that both content are equal Assert.True(Utilities.Compare(textureData, readBackData)); } // ------------------------------------------------------- // Test SetData using a ResourceRegion // ------------------------------------------------------- // Set the last 4 pixels in different orders var smallTextureDataRegion = new byte[] { 4, 3, 2, 1 }; var region = new ResourceRegion(textureData.Length - 4, 0, 0, textureData.Length, 1, 1); texture.SetData(GraphicsDevice, smallTextureDataRegion, 0, 0, region); readBackData = texture.GetData<byte>(); Array.Copy(smallTextureDataRegion, 0, textureData, textureData.Length - 4, 4); // Check that both content are equal Assert.True(Utilities.Compare(textureData, readBackData)); // ------------------------------------------------------- // Texture.Dispose() // ------------------------------------------------------- // TODO check that Dispose is implemented correctly texture.Dispose(); }
internal unsafe void UpdateCube(List<MyCubeInstanceData> instanceData, int capacity) { Debug.Assert(m_type == MyRenderInstanceBufferType.Cube); var instancesNum = instanceData.Count; if (m_capacity < instancesNum && VB != VertexBufferId.NULL) { MyHwBuffers.Destroy(VB); VB = VertexBufferId.NULL; } if (m_capacity < instancesNum) { m_capacity = Math.Max(instancesNum, capacity); VB = MyHwBuffers.CreateVertexBuffer(m_capacity, sizeof(MyVertexFormatCubeInstance), null, m_debugName + " instances buffer"); } var rawBuffer = new MyVertexFormatCubeInstance[m_capacity]; for (int i = 0; i < instancesNum; i++) { fixed (byte* pSource = instanceData[i].RawBones(), pTarget = rawBuffer[i].bones) { for (int j = 0; j < MyRender11Constants.CUBE_INSTANCE_BONES_NUM * 4; j++) pTarget[j] = pSource[j]; } rawBuffer[i].translationRotation = new HalfVector4(instanceData[i].m_translationAndRot); rawBuffer[i].colorMaskHSV = new HalfVector4(instanceData[i].ColorMaskHSV); } fixed (MyVertexFormatCubeInstance* dataPtr = rawBuffer) { DataBox srcBox = new DataBox(new IntPtr(dataPtr)); ResourceRegion dstRegion = new ResourceRegion(0, 0, 0, sizeof(MyVertexFormatCubeInstance) * instancesNum, 1, 1); MyRender11.ImmediateContext.UpdateSubresource(srcBox, VB.Buffer, 0, dstRegion); } BumpRenderable(); }
internal unsafe static void UpdateVertexBuffer(InstancingId id) { var info = id.Info; if (info.Capacity == 0) { return; } fixed (byte* ptr = info.Data) { if(Data[id.Index].VB == VertexBufferId.NULL) { Data[id.Index].VB = MyHwBuffers.CreateVertexBuffer(info.Capacity, info.Stride, new IntPtr(ptr), info.DebugName); } else { var vb = Data[id.Index].VB; MyHwBuffers.ResizeVertexBuffer(vb, info.Capacity); DataBox srcBox = new DataBox(new IntPtr(ptr)); ResourceRegion dstRegion = new ResourceRegion(0, 0, 0, info.Stride * info.Capacity, 1, 1); MyRender11.ImmediateContext.UpdateSubresource(srcBox, vb.Buffer, 0, dstRegion); } } }
public void UpdateMemory(int width, int height, Format format, uint[] data, int pitch) { using (var stream = new DataStream(data.Length * 4, true, true)) { stream.WriteRange(data); stream.Position = 0; var box = new DataBox(stream.DataPointer, pitch, 0); if (IsDirty(width, height, format, 1)) CreateNew(width, height, format, new[] { box }); else { var region = new ResourceRegion { Back = 1, Bottom = height, Front = 0, Left = 0, Right = width, Top = 0 }; mContext.Context.UpdateSubresource(mTexture, 0, region, box.DataPointer, width * 4, 0); } } }
/// <summary> /// Gets a copy of 2D texture data, specifying a mipmap level, source rectangle, start index, and number of elements. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="level"></param> /// <param name="rect"></param> /// <param name="data"></param> /// <param name="startIndex"></param> /// <param name="elementCount"></param> public void GetData <T>(int level, Rectangle?rect, 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."); } if (rect.HasValue) { throw new NotImplementedException("Set 'rect' parameter to null."); } var mipWidth = MathUtil.Clamp(Width >> level, 1, Width); var mipHeight = MathUtil.Clamp(Width >> level, 1, Height); // Create a temp staging resource for copying the data. // // TODO: We should probably be pooling these staging resources // and not creating a new one each time. // var desc = new SharpDX.Direct3D11.Texture2DDescription(); desc.Width = mipWidth; desc.Height = mipHeight; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = Converter.Convert(Format); desc.BindFlags = D3D.BindFlags.None; desc.CpuAccessFlags = D3D.CpuAccessFlags.Read; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = D3D.ResourceUsage.Staging; desc.OptionFlags = D3D.ResourceOptionFlags.None; var d3dContext = device.DeviceContext; using (var stagingTex = new D3D.Texture2D(device.Device, desc)) { lock (d3dContext) { // // Copy the data from the GPU to the staging texture. // int elementsInRow; int rows; if (rect.HasValue) { elementsInRow = rect.Value.Width; rows = rect.Value.Height; var region = new D3D.ResourceRegion(rect.Value.Left, rect.Value.Top, 0, rect.Value.Right, rect.Value.Bottom, 1); d3dContext.CopySubresourceRegion(tex2D, level, region, stagingTex, 0, 0, 0, 0); } else { elementsInRow = mipWidth; rows = mipHeight; d3dContext.CopySubresourceRegion(tex2D, level, null, stagingTex, 0, 0, 0, 0); } // Copy the data to the array : DataStream stream; var databox = d3dContext.MapSubresource(stagingTex, 0, D3D.MapMode.Read, D3D.MapFlags.None, out stream); // Some drivers may add pitch to rows. // We need to copy each row separatly and skip trailing zeros. var currentIndex = startIndex; var elementSize = Marshal.SizeOf(typeof(T)); for (var row = 0; row < rows; row++) { stream.ReadRange(data, currentIndex, elementsInRow); stream.Seek(databox.RowPitch - (elementSize * elementsInRow), SeekOrigin.Current); currentIndex += elementsInRow; } stream.Dispose(); } } }
/// <summary> /// Copies data from the CPU to to a non-mappable subresource region. /// </summary> /// <param name = "source">The source data.</param> /// <param name = "resource">The destination resource.</param> /// <param name="srcBytesPerElement">The size in bytes per pixel/block element.</param> /// <param name = "subresource">The destination subresource.</param> /// <param name = "region">The destination region within the resource.</param> /// <param name="isCompressedResource">if set to <c>true</c> the resource is a block/compressed resource</param> /// <remarks> /// This method is implementing the <a href="http://blogs.msdn.com/b/chuckw/archive/2010/07/28/known-issue-direct3d-11-updatesubresource-and-deferred-contexts.aspx">workaround for deferred context</a>. /// </remarks> /// <unmanaged>void ID3D11DeviceContext::UpdateSubresource([In] ID3D11Resource* pDstResource,[In] unsigned int DstSubresource,[In, Optional] const D3D11_BOX* pDstBox,[In] const void* pSrcData,[In] unsigned int SrcRowPitch,[In] unsigned int SrcDepthPitch)</unmanaged> public void UpdateSubresourceSafe(DataBox source, Resource resource, int srcBytesPerElement, int subresource, ResourceRegion region, bool isCompressedResource = false) { UpdateSubresourceSafe(resource, subresource, region, source.DataPointer, source.RowPitch, source.SlicePitch, srcBytesPerElement, isCompressedResource); }
/// <summary> /// Copies data from the CPU to to a non-mappable subresource region. /// </summary> /// <param name = "source">The source data.</param> /// <param name = "resource">The destination resource.</param> /// <param name = "subresource">The destination subresource.</param> /// <param name = "region">The destination region within the resource.</param> /// <remarks> /// This method is implementing the <a href="http://blogs.msdn.com/b/chuckw/archive/2010/07/28/known-issue-direct3d-11-updatesubresource-and-deferred-contexts.aspx">workaround for deferred context</a>. /// </remarks> /// <unmanaged>void ID3D11DeviceContext::UpdateSubresource([In] ID3D11Resource* pDstResource,[In] unsigned int DstSubresource,[In, Optional] const D3D11_BOX* pDstBox,[In] const void* pSrcData,[In] unsigned int SrcRowPitch,[In] unsigned int SrcDepthPitch)</unmanaged> public void UpdateSubresource(DataBox source, Resource resource, int subresource, ResourceRegion region) { UpdateSubresource(resource, subresource, region, source.DataPointer, source.RowPitch, source.SlicePitch); }
public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourecRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { if (source == null) throw new ArgumentNullException("source"); if (destination == null) throw new ArgumentNullException("destination"); var nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion?(); if (sourecRegion.HasValue) { var value = sourecRegion.Value; nullableSharpDxRegion = new SharpDX.Direct3D11.ResourceRegion(value.Left, value.Top, value.Front, value.Right, value.Bottom, value.Back); } NativeDeviceContext.CopySubresourceRegion(source.NativeResource, sourceSubresource, nullableSharpDxRegion, destination.NativeResource, destinationSubResource, dstX, dstY, dstZ); }
public void UpdateMemory(int width, int height, Format format, byte[] data, int pitch) { using (var stream = new DataStream(data.Length, true, true)) { stream.WriteRange(data); stream.Position = 0; var box = new DataBox(stream.DataPointer, pitch, 0); if (width != mTexture.Description.Width || height != mTexture.Description.Height || format != mTexture.Description.Format || mTexture.Description.MipLevels != 1 || mTexture == gDefaultTexture) { CreateNew(width, height, format, new[] { box }); } else { var region = new ResourceRegion { Back = 1, Bottom = height, Front = 0, Left = 0, Right = width, Top = 0 }; mContext.Context.UpdateSubresource(mTexture, 0, region, box.DataPointer, width * 4, 0); } } }
public MeshDeviceResources(Device device, SharpDX.WIC.ImagingFactory2 imagingFactory, Mesh mesh) { this.mesh = mesh; // create single vertex buffer var stream = new DataStream(mesh.vertices.Count * Mesh.VertexPositionNormalTexture.sizeInBytes, true, true); stream.WriteRange(mesh.vertices.ToArray()); stream.Position = 0; var vertexBufferDesc = new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default, SizeInBytes = mesh.vertices.Count * Mesh.VertexPositionNormalTexture.sizeInBytes, }; vertexBuffer = new SharpDX.Direct3D11.Buffer(device, stream, vertexBufferDesc); stream.Dispose(); vertexBufferBinding = new VertexBufferBinding(vertexBuffer, Mesh.VertexPositionNormalTexture.sizeInBytes, 0); foreach (var subset in mesh.subsets) { if (subset.material.textureFilename != null) { var decoder = new SharpDX.WIC.BitmapDecoder(imagingFactory, subset.material.textureFilename, SharpDX.WIC.DecodeOptions.CacheOnLoad); var bitmapFrameDecode = decoder.GetFrame(0); var stagingTextureDesc = new Texture2DDescription() { Width = bitmapFrameDecode.Size.Width, Height = bitmapFrameDecode.Size.Height, MipLevels = 1, ArraySize = 1, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.Write }; var stagingTexture = new Texture2D(device, stagingTextureDesc); var textureDesc = new Texture2DDescription() { Width = bitmapFrameDecode.Size.Width, Height = bitmapFrameDecode.Size.Height, MipLevels = 0, ArraySize = 1, Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.GenerateMipMaps }; var texture = new Texture2D(device, textureDesc); // convert to 32 bpp var formatConverter = new FormatConverter(imagingFactory); formatConverter.Initialize(bitmapFrameDecode, SharpDX.WIC.PixelFormat.Format32bppBGR); var dataBox = device.ImmediateContext.MapSubresource(stagingTexture, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None); formatConverter.CopyPixels(dataBox.RowPitch, dataBox.DataPointer, dataBox.RowPitch * bitmapFrameDecode.Size.Height); device.ImmediateContext.UnmapSubresource(stagingTexture, 0); var resourceRegion = new ResourceRegion() { Left = 0, Top = 0, Right = bitmapFrameDecode.Size.Width, Bottom = bitmapFrameDecode.Size.Height, Front = 0, Back = 1, }; device.ImmediateContext.CopySubresourceRegion(stagingTexture, 0, resourceRegion, texture, 0); var textureRV = new ShaderResourceView(device, texture); device.ImmediateContext.GenerateMips(textureRV); decoder.Dispose(); formatConverter.Dispose(); bitmapFrameDecode.Dispose(); textureRVs[subset] = textureRV; } } }