private void CopyUnsafe(GraphicsTextureView destination, GraphicsBufferView source) { var d3d12DestinationTextureCopyLocation = new D3D12_TEXTURE_COPY_LOCATION(destination.Resource.D3D12Resource, Sub: destination.D3D12SubresourceIndex); var d3d12SourceTextureCopyLocation = new D3D12_TEXTURE_COPY_LOCATION(source.Resource.D3D12Resource, in destination.D3D12PlacedSubresourceFootprints[0]); d3d12SourceTextureCopyLocation.PlacedFootprint.Offset = source.ByteOffset; D3D12GraphicsCommandList->CopyTextureRegion(&d3d12DestinationTextureCopyLocation, DstX: 0, DstY: 0, DstZ: 0, &d3d12SourceTextureCopyLocation, pSrcBox: null); }
public static ulong UpdateSubresources(ID3D12GraphicsCommandList *pCmdList, ID3D12Resource *pDestinationResource, ID3D12Resource *pIntermediate, uint FirstSubresource, uint NumSubresources, [NativeTypeName("UINT64")] ulong RequiredSize, [NativeTypeName("const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *")] D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, [NativeTypeName("const UINT *")] uint *pNumRows, [NativeTypeName("const UINT64 *")] ulong *pRowSizesInBytes, [NativeTypeName("const D3D12_SUBRESOURCE_DATA *")] D3D12_SUBRESOURCE_DATA *pSrcData) { D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); if (unchecked (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || RequiredSize > (nuint)(-1)) || (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && (FirstSubresource != 0 || NumSubresources != 1))) { return(0); } byte * pData; HRESULT hr = pIntermediate->Map(0, null, (void **)(&pData)); if ((((HRESULT)(hr)) < 0)) { return(0); } for (uint i = 0; i < NumSubresources; ++i) { if (pRowSizesInBytes[i] > unchecked ((nuint)(-1))) { return(0); } D3D12_MEMCPY_DEST DestData = new D3D12_MEMCPY_DEST { pData = pData + pLayouts[i].Offset, RowPitch = pLayouts[i].Footprint.RowPitch, SlicePitch = unchecked ((nuint)(pLayouts[i].Footprint.RowPitch) * (nuint)(pNumRows[i])), }; MemcpySubresource(&DestData, &pSrcData[i], unchecked ((nuint)(pRowSizesInBytes[i])), pNumRows[i], pLayouts[i].Footprint.Depth); } pIntermediate->Unmap(0, null); if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { pCmdList->CopyBufferRegion(pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); } else { for (uint i = 0; i < NumSubresources; ++i) { D3D12_TEXTURE_COPY_LOCATION Dst = new D3D12_TEXTURE_COPY_LOCATION(pDestinationResource, i + FirstSubresource); D3D12_TEXTURE_COPY_LOCATION Src = new D3D12_TEXTURE_COPY_LOCATION(pIntermediate, pLayouts[i]); pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, null); } } return(RequiredSize); }
public virtual void CopyTextureRegion( ref D3D12_TEXTURE_COPY_LOCATION pDst, uint DstX, uint DstY, uint DstZ, ref D3D12_TEXTURE_COPY_LOCATION pSrc, ref D3D12_BOX pSrcBox ) { var fp = GetFunctionPointer(16); if (m_CopyTextureRegionFunc == null) { m_CopyTextureRegionFunc = (CopyTextureRegionFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(CopyTextureRegionFunc)); } m_CopyTextureRegionFunc(m_ptr, ref pDst, DstX, DstY, DstZ, ref pSrc, ref pSrcBox); }
public static ulong UpdateSubresources(ID3D12GraphicsCommandList *pCmdList, ID3D12Resource *pDestinationResource, ID3D12Resource *pIntermediate, uint FirstSubresource, uint NumSubresources, ulong RequiredSize, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, uint *pNumRows, ulong *pRowSizesInBytes, D3D12_SUBRESOURCE_DATA *pSrcData) { // Minor validation D3D12_RESOURCE_DESC IntermediateDesc; pIntermediate->GetDesc(&IntermediateDesc); D3D12_RESOURCE_DESC DestinationDesc; pDestinationResource->GetDesc(&DestinationDesc); if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || RequiredSize > ((IntPtr.Size == 4) ? uint.MaxValue : ulong.MaxValue) || (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && (FirstSubresource != 0 || NumSubresources != 1))) { return(0); } byte *pData; int hr = pIntermediate->Map(0, null, (void **)(&pData)); if (FAILED(hr)) { return(0); } for (var i = 0u; i < NumSubresources; ++i) { if (pRowSizesInBytes[i] > ((IntPtr.Size == 4) ? uint.MaxValue : ulong.MaxValue)) { return(0); } var DestData = new D3D12_MEMCPY_DEST { pData = pData + pLayouts[i].Offset, RowPitch = (UIntPtr)(pLayouts[i].Footprint.RowPitch), SlicePitch = (UIntPtr)(pLayouts[i].Footprint.RowPitch * pNumRows[i]) }; MemcpySubresource(&DestData, &pSrcData[i], (UIntPtr)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); } pIntermediate->Unmap(0, null); if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { var SrcBox = new D3D12_BOX { left = (uint)pLayouts[0].Offset, top = 0, front = 0, right = (uint)pLayouts[0].Offset + pLayouts[0].Footprint.Width, bottom = 1, back = 1 }; pCmdList->CopyBufferRegion( pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); } else { for (var i = 0u; i < NumSubresources; ++i) { var Dst = new D3D12_TEXTURE_COPY_LOCATION { pResource = pDestinationResource, Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, Anonymous = new D3D12_TEXTURE_COPY_LOCATION._Anonymous_e__Union { SubresourceIndex = i + FirstSubresource } }; var Src = new D3D12_TEXTURE_COPY_LOCATION { pResource = pIntermediate, Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, Anonymous = new D3D12_TEXTURE_COPY_LOCATION._Anonymous_e__Union { PlacedFootprint = pLayouts[i] } }; pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, null); } } return(RequiredSize); }
/// <inheritdoc cref="Copy(GraphicsTexture, GraphicsBuffer)" /> public void Copy(D3D12GraphicsTexture destination, D3D12GraphicsBuffer source) { ThrowIfNull(destination, nameof(destination)); ThrowIfNull(source, nameof(source)); var graphicsDevice = D3D12GraphicsDevice.D3D12Device; var graphicsCommandList = D3D12GraphicsCommandList; var destinationCpuAccess = destination.GraphicsHeap.CpuAccess; var sourceCpuAccess = source.GraphicsHeap.CpuAccess; var d3d12DestinationResource = destination.D3D12Resource; var d3d12SourceResource = source.D3D12Resource; var d3d12DestinationResourceState = destination.D3D12ResourceState; var d3d12SourceResourceState = source.D3D12ResourceState; BeginCopy(); D3D12_PLACED_SUBRESOURCE_FOOTPRINT sourceFootprint; var destinationDesc = d3d12DestinationResource->GetDesc(); graphicsDevice->GetCopyableFootprints(&destinationDesc, FirstSubresource: 0, NumSubresources: 1, BaseOffset: 0, &sourceFootprint, pNumRows: null, pRowSizeInBytes: null, pTotalBytes: null); var d3d12DestinationTextureCopyLocation = new D3D12_TEXTURE_COPY_LOCATION(d3d12DestinationResource, Sub: 0); var d3d12SourceTextureCopyLocation = new D3D12_TEXTURE_COPY_LOCATION(d3d12SourceResource, in sourceFootprint); graphicsCommandList->CopyTextureRegion(&d3d12DestinationTextureCopyLocation, DstX: 0, DstY: 0, DstZ: 0, &d3d12SourceTextureCopyLocation, pSrcBox: null); EndCopy(); void BeginCopy() { var resourceBarriers = stackalloc D3D12_RESOURCE_BARRIER[2]; var numResourceBarriers = 0u; if (destinationCpuAccess == GraphicsHeapCpuAccess.None) { resourceBarriers[numResourceBarriers] = D3D12_RESOURCE_BARRIER.InitTransition( d3d12DestinationResource, stateBefore: d3d12DestinationResourceState, stateAfter: D3D12_RESOURCE_STATE_COPY_DEST ); numResourceBarriers++; } if (sourceCpuAccess == GraphicsHeapCpuAccess.None) { resourceBarriers[numResourceBarriers] = D3D12_RESOURCE_BARRIER.InitTransition( d3d12SourceResource, stateBefore: d3d12SourceResourceState, stateAfter: D3D12_RESOURCE_STATE_COPY_SOURCE ); numResourceBarriers++; } if (numResourceBarriers != 0) { graphicsCommandList->ResourceBarrier(numResourceBarriers, resourceBarriers); } } void EndCopy() { var resourceBarriers = stackalloc D3D12_RESOURCE_BARRIER[2]; var numResourceBarriers = 0u; if (sourceCpuAccess == GraphicsHeapCpuAccess.None) { resourceBarriers[numResourceBarriers] = D3D12_RESOURCE_BARRIER.InitTransition( d3d12SourceResource, stateBefore: D3D12_RESOURCE_STATE_COPY_SOURCE, stateAfter: d3d12SourceResourceState ); numResourceBarriers++; } if (destinationCpuAccess == GraphicsHeapCpuAccess.None) { resourceBarriers[numResourceBarriers] = D3D12_RESOURCE_BARRIER.InitTransition( d3d12DestinationResource, stateBefore: D3D12_RESOURCE_STATE_COPY_DEST, stateAfter: d3d12DestinationResourceState ); numResourceBarriers++; } if (numResourceBarriers != 0) { graphicsCommandList->ResourceBarrier(numResourceBarriers, resourceBarriers); } } }