public static void MemcpySubresource(D3D12_MEMCPY_DEST *pDest, D3D12_SUBRESOURCE_DATA *pSrc, UIntPtr RowSizeInBytes, uint NumRows, uint NumSlices) { for (var z = 0u; z < NumSlices; ++z) { byte *pDestSlice = (byte *)(pDest->pData); byte *pSrcSlice = (byte *)(pSrc->pData); if (IntPtr.Size == 4) { pDestSlice += (uint)pDest->SlicePitch * z; pSrcSlice += (uint)pSrc->SlicePitch * z; } else { pDestSlice += (ulong)pDest->SlicePitch * z; pSrcSlice += (ulong)pSrc->SlicePitch * z; } for (var y = 0u; y < NumRows; ++y) { byte *pTempDest = pDestSlice; byte *pTempSrc = pSrcSlice; if (IntPtr.Size == 4) { pDestSlice += (uint)pDest->RowPitch * y; pSrcSlice += (uint)pDest->RowPitch * y; } else { pDestSlice += (ulong)pDest->RowPitch * y; pSrcSlice += (ulong)pDest->RowPitch * y; } Buffer.MemoryCopy(pTempSrc, pTempDest, (long)RowSizeInBytes, (long)RowSizeInBytes); } } }
public static void MemcpySubresource([NativeTypeName("const D3D12_MEMCPY_DEST *")] D3D12_MEMCPY_DEST *pDest, [NativeTypeName("const D3D12_SUBRESOURCE_DATA *")] D3D12_SUBRESOURCE_DATA *pSrc, [NativeTypeName("SIZE_T")] nuint RowSizeInBytes, [NativeTypeName("UINT")] uint NumRows, [NativeTypeName("UINT")] uint NumSlices) { for (var z = 0u; z < NumSlices; ++z) { var pDestSlice = (byte *)pDest->pData + pDest->SlicePitch * z; var pSrcSlice = (byte *)pSrc->pData + pSrc->SlicePitch * (nint)z; for (var y = 0u; y < NumRows; ++y) { Buffer.MemoryCopy( pSrcSlice + pSrc->RowPitch * (nint)y, pDestSlice + pDest->RowPitch * y, (ulong)RowSizeInBytes, (ulong)RowSizeInBytes ); } } }
public static ulong UpdateSubresources([NativeTypeName("UINT")] uint MaxSubresources, [NativeTypeName("ID3D12GraphicsCommandList *")] ID3D12GraphicsCommandList *pCmdList, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pDestinationResource, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pIntermediate, [NativeTypeName("UINT64")] ulong IntermediateOffset, [NativeTypeName("UINT")] uint FirstSubresource, [NativeTypeName("UINT")] uint NumSubresources, [NativeTypeName("D3D12_SUBRESOURCE_DATA *")] D3D12_SUBRESOURCE_DATA *pSrcData) { ulong RequiredSize = 0; D3D12_PLACED_SUBRESOURCE_FOOTPRINT *Layouts = stackalloc D3D12_PLACED_SUBRESOURCE_FOOTPRINT[(int)MaxSubresources]; uint * NumRows = stackalloc uint[(int)MaxSubresources]; ulong *RowSizesInBytes = stackalloc ulong[(int)MaxSubresources]; var Desc = pDestinationResource->GetDesc(); ID3D12Device *pDevice = null; var iid = IID_ID3D12Device; pDestinationResource->GetDevice(&iid, (void **)&pDevice); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); pDevice->Release(); return(UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData)); }
public static ulong UpdateSubresources([NativeTypeName("ID3D12GraphicsCommandList *")] ID3D12GraphicsCommandList *pCmdList, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pDestinationResource, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pIntermediate, [NativeTypeName("UINT64")] ulong IntermediateOffset, [NativeTypeName("UINT")] uint FirstSubresource, [NativeTypeName("UINT")] uint NumSubresources, [NativeTypeName("D3D12_SUBRESOURCE_DATA *")] D3D12_SUBRESOURCE_DATA *pSrcData) { ulong RequiredSize = 0; ulong MemToAlloc = (ulong)(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint) + sizeof(ulong)) * NumSubresources; if (MemToAlloc > unchecked ((nuint)(-1))) { return(0); } var pMem = HeapAlloc(GetProcessHeap(), 0, (nuint)MemToAlloc); if (pMem == null) { return(0); } var pLayouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT *)pMem; ulong *pRowSizesInBytes = (ulong *)(pLayouts + NumSubresources); uint * pNumRows = (uint *)(pRowSizesInBytes + NumSubresources); var Desc = pDestinationResource->GetDesc(); ID3D12Device *pDevice = null; var iid = IID_ID3D12Device; pDestinationResource->GetDevice(&iid, (void **)&pDevice); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); pDevice->Release(); ulong Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); HeapFree(GetProcessHeap(), 0, pMem); return(Result); }
public static ulong UpdateSubresources([NativeTypeName("ID3D12GraphicsCommandList *")] ID3D12GraphicsCommandList *pCmdList, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pDestinationResource, [NativeTypeName("ID3D12Resource *")] ID3D12Resource *pIntermediate, [NativeTypeName("UINT")] uint FirstSubresource, [NativeTypeName("UINT")] 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) { var IntermediateDesc = pIntermediate->GetDesc(); var DestinationDesc = pDestinationResource->GetDesc(); if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || RequiredSize > unchecked ((nuint)(-1)) || (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] > unchecked ((nuint)(-1))) { return(0); } D3D12_MEMCPY_DEST DestData = new D3D12_MEMCPY_DEST { pData = pData + pLayouts[i].Offset, RowPitch = (nuint)pLayouts[i].Footprint.RowPitch, SlicePitch = (nuint)(pLayouts[i].Footprint.RowPitch * pNumRows[i]) }; MemcpySubresource(&DestData, &pSrcData[i], (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 (var i = 0u; 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 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); }
//public static ulong UpdateSubresources( // [In] ID3D12GraphicsCommandList* pCmdList, // [In] ID3D12Resource* pDestinationResource, // [In] ID3D12Resource* pIntermediate, // ulong IntermediateOffset, // [In] uint FirstSubresource, // [In] uint NumSubresources, // [In] D3D12_SUBRESOURCE_DATA* pSrcData) //{ // ulong RequiredSize = 0; // ulong MemToAlloc = (ulong) (sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint) + sizeof(ulong)) * // NumSubresources; // if (MemToAlloc > (ulong)(void*)-1) // new // { // return 0; // } // void* pMem = UnsafeNativeMethods.HeapAlloc(UnsafeNativeMethods.GetProcessHeap(), 0, (IntPtr)MemToAlloc); // if (pMem == null) // { // return 0; // } // D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT*) pMem; // ulong* pRowSizesInBytes = (ulong*) (pLayouts + NumSubresources); // uint* pNumRows = (uint*) (pRowSizesInBytes + NumSubresources); // D3D12_RESOURCE_DESC Desc; // pDestinationResource->GetDesc(&Desc); // ID3D12Device* pDevice; // Guid iid = D3D12.IID_ID3D12Device; // pDestinationResource->GetDevice(&iid, (void**) &pDevice); // pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, // pNumRows, pRowSizesInBytes, &RequiredSize); // pDevice->Release(); // ulong Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, // NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); // UnsafeNativeMethods.HeapFree(UnsafeNativeMethods.GetProcessHeap(), 0, pMem); // return Result; //} //public static ulong UpdateSubresources( // uint MaxSubresources, // [In] ID3D12GraphicsCommandList* pCmdList, // [In] ID3D12Resource* pDestinationResource, // [In] ID3D12Resource* pIntermediate, // ulong IntermediateOffset, // [In] uint FirstSubresource, // [In] uint NumSubresources, // [In] D3D12_SUBRESOURCE_DATA* pSrcData) //{ // ulong RequiredSize = 0; // D3D12_PLACED_SUBRESOURCE_FOOTPRINT* Layouts // = stackalloc D3D12_PLACED_SUBRESOURCE_FOOTPRINT[(int) MaxSubresources]; // uint* NumRows = stackalloc uint[(int) MaxSubresources]; // ulong* RowSizesInBytes = stackalloc ulong[(int) MaxSubresources]; // D3D12_RESOURCE_DESC Desc; // pDestinationResource->GetDesc(&Desc); // ID3D12Device* pDevice; // Guid iid = D3D12.IID_ID3D12Device; // pDestinationResource->GetDevice(&iid, (void**) &pDevice); // pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, // NumRows, RowSizesInBytes, &RequiredSize); // pDevice->Release(); // return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, // RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); //} //public static ulong UpdateSubresources( // [In] ID3D12GraphicsCommandList* pCmdList, // [In] ID3D12Resource* pDestinationResource, // [In] ID3D12Resource* pIntermediate, // [In] uint FirstSubresource, // [In] uint NumSubresources, // ulong RequiredSize, // [In] D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, // [In] uint* pNumRows, // [In] ulong* pRowSizesInBytes, // [In] 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 > (ulong)(void*)(-1) || // (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && // (FirstSubresource != 0 || NumSubresources != 1))) // { // return 0; // } // byte* pData; // HRESULT hr = pIntermediate->Map(0, null, (void**) &pData); // if (FAILED(hr)) // { // return 0; // } // for (uint i = 0; i < NumSubresources; ++i) // { // /* // void *pData; // SIZE_T RowPitch; // SIZE_T SlicePitch; // */ // if (pRowSizesInBytes[i] > (ulong)(void*)-1) return 0; // D3D12_MEMCPY_DEST 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) // { // D3D12_BOX SrcBox = CD3DX12_BOX.Create((int) pLayouts[0].Offset, // (int) (pLayouts[0].Offset + pLayouts[0].Footprint.Width)); // 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 = // CD3DX12_TEXTURE_COPY_LOCATION.Create(pDestinationResource, i + FirstSubresource); // D3D12_TEXTURE_COPY_LOCATION Src = CD3DX12_TEXTURE_COPY_LOCATION.Create(pIntermediate, pLayouts[i]); // pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, null); // } // } // return RequiredSize; //} //public static void MemcpySubresource( // [In] D3D12_MEMCPY_DEST* pDest, // [In] D3D12_SUBRESOURCE_DATA* pSrc, // UIntPtr RowSizeInBytes, // uint NumRows, // uint NumSlices) //{ // for (uint z = 0; z < NumSlices; ++z) // { // byte* pDestSlice = (byte*)(pDest->pData); // byte* pSrcSlice = (byte*)(pSrc->pData); // if (IntPtr.Size == 4) // { // pDestSlice += (uint)pDest->SlicePitch * z; // pSrcSlice += (uint)pSrc->SlicePitch * z; // } // else // { // pDestSlice += (ulong)pDest->SlicePitch * z; // pSrcSlice += (ulong)pSrc->SlicePitch * z; // } // for (var y = 0u; y < NumRows; ++y) // { // byte* pTempDest = pDestSlice; // byte* pTempSrc = pSrcSlice; // if (IntPtr.Size == 4) // { // pDestSlice += (uint)pDest->RowPitch * y; // pSrcSlice += (uint)pDest->RowPitch * y; // } // else // { // pDestSlice += (ulong)pDest->RowPitch * y; // pSrcSlice += (ulong)pDest->RowPitch * y; // } // Buffer.MemoryCopy(pTempSrc, pTempDest, (long)RowSizeInBytes, (long)RowSizeInBytes); // } // } //} public static ulong UpdateSubresources(ID3D12GraphicsCommandList *pCmdList, ID3D12Resource *pDestinationResource, ID3D12Resource *pIntermediate, ulong IntermediateOffset, uint FirstSubresource, uint NumSubresources, D3D12_SUBRESOURCE_DATA *pSrcData) { ulong RequiredSize = 0; ulong MemToAlloc = (ulong)(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint) + sizeof(ulong)) * NumSubresources; if (MemToAlloc > ((IntPtr.Size == 4) ? uint.MaxValue : ulong.MaxValue)) { return(0); } void *pMem = Marshal.AllocHGlobal((IntPtr)MemToAlloc).ToPointer(); if (pMem == null) { return(0); } D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT *)(pMem); ulong *pRowSizesInBytes = (ulong *)(pLayouts + NumSubresources); uint * pNumRows = (uint *)(pRowSizesInBytes + NumSubresources); D3D12_RESOURCE_DESC Desc; pDestinationResource->GetDesc(&Desc); ID3D12Device *pDevice; var iid = IID_ID3D12Device; pDestinationResource->GetDevice(&iid, (void **)(&pDevice)); pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); pDevice->Release(); ulong Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); Marshal.FreeHGlobal((IntPtr)pMem); return(Result); }