コード例 #1
0
    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);
    }
コード例 #2
0
        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);
        }