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);
    }
Example #2
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);
    }
        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);
        }
Example #4
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);
        }
Example #5
0
        /// <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);
                }
            }
        }