ID3D12GraphicsCommandList::CopyTextureRegion 方法 (d3d12.h)

此方法使用 GPU 在两个位置之间复制纹理数据。 源和目标都可以引用位于缓冲区资源或纹理资源中的纹理数据。

语法

void CopyTextureRegion(
  [in]           const D3D12_TEXTURE_COPY_LOCATION *pDst,
                 UINT                              DstX,
                 UINT                              DstY,
                 UINT                              DstZ,
  [in]           const D3D12_TEXTURE_COPY_LOCATION *pSrc,
  [in, optional] const D3D12_BOX                   *pSrcBox
);

参数

[in] pDst

类型: const D3D12_TEXTURE_COPY_LOCATION*

指定目标 D3D12_TEXTURE_COPY_LOCATION。 引用的子资源必须处于D3D12_RESOURCE_STATE_COPY_DEST状态。

DstX

类型: UINT

目标区域左上角的 x 坐标。

DstY

类型: UINT

目标区域左上角的 y 坐标。 对于 1D 子资源,这必须为零。

DstZ

类型: UINT

目标区域左上角的 z 坐标。 对于 1D 或 2D 子资源,这必须为零。

[in] pSrc

类型: const D3D12_TEXTURE_COPY_LOCATION*

指定源 D3D12_TEXTURE_COPY_LOCATION。 引用的子资源必须处于D3D12_RESOURCE_STATE_COPY_SOURCE状态。

[in, optional] pSrcBox

类型: const D3D12_BOX*

指定可选D3D12_BOX,用于设置要复制的源纹理的大小。

返回值

备注

源框必须在源资源的大小范围内。 目标偏移量( (x、y 和 z) )允许源框在写入目标资源时偏移;但是,源框的尺寸和偏移量必须在资源的大小范围内。 如果尝试在目标资源外部复制或指定大于源资源的源框,则 CopyTextureRegion 的行为未定义。 如果创建了支持 调试层的设备,则调试输出将报告此无效 CopyTextureRegion 调用的错误。 CopyTextureRegion 的参数无效会导致未定义的行为,并可能导致不正确的呈现、剪裁、无副本甚至删除呈现设备。

如果资源是缓冲区,则所有坐标都以字节为单位;如果资源是纹理,则所有坐标都以纹素表示。

CopyTextureRegion 在 GPU (上执行复制,类似于 memcpy CPU) 。 因此,源和目标资源:

  • 必须是不同的子资源 (,尽管它们可以来自同一资源) 。
  • 必须具有兼容的 DXGI_FORMAT (相同或来自同一类型组) 。 例如,可以将DXGI_FORMAT_R32G32B32_FLOAT纹理复制到DXGI_FORMAT_R32G32B32_UINT纹理,因为这两种格式都位于DXGI_FORMAT_R32G32B32_TYPELESS组中。 CopyTextureRegion 可以在几种格式类型之间复制。 有关详细信息,请参阅 使用 Direct3D 10.1 进行格式转换
CopyTextureRegion 仅支持复制;它不支持任何拉伸、颜色键或混合。 CopyTextureRegion 可以在几种格式类型之间重新解释资源数据。

请注意,对于深度模具缓冲区,深度平面和模具平面是缓冲区内的 单独子资源

若要复制整个资源,而不仅仅是子资源的区域,建议改用 CopyResource

注意 如果将 CopyTextureRegion 与深度模具缓冲区或多重采样资源一起使用,则必须复制整个子资源矩形。 在这种情况下,必须将 0 传递给 DstXDstYDstZ 参数,将 NULL 传递给 pSrcBox 参数。 此外,源和目标资源(由 pSrcResourcepDstResource 参数表示)应具有相同的样本计数值。
 
CopyTextureRegion 可用于初始化同一堆内存别名的资源。 有关更多详细信息 ,请参阅 CreatePlacedResource

示例

以下代码片段将位于 (120,100) , (200,220) ) 的框 (从源纹理复制到目标纹理中 (10,20) , (90,140) 的区域。
D3D12_BOX sourceRegion;
sourceRegion.left = 120;
sourceRegion.top = 100;
sourceRegion.right = 200;
sourceRegion.bottom = 220;
sourceRegion.front = 0;
sourceRegion.back = 1;

pCmdList -> CopyTextureRegion(pDestTexture, 10, 20, 0, pSourceTexture, &sourceRegion);

请注意,对于 2D 纹理,正面和背面分别设置为 0 和 1。

示例

HelloTriangle 示例使用 ID3D12GraphicsCommandList::CopyTextureRegion,如下所示:

inline UINT64 UpdateSubresources(
    _In_ ID3D12GraphicsCommandList* pCmdList,
    _In_ ID3D12Resource* pDestinationResource,
    _In_ ID3D12Resource* pIntermediate,
    _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
    _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
    UINT64 RequiredSize,
    _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
    _In_reads_(NumSubresources) const UINT* pNumRows,
    _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
    _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData)
{
    // Minor validation
    D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc();
    D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc();
    if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || 
        IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || 
        RequiredSize > (SIZE_T)-1 || 
        (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && 
            (FirstSubresource != 0 || NumSubresources != 1)))
    {
        return 0;
    }
    
    BYTE* pData;
    HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData));
    if (FAILED(hr))
    {
        return 0;
    }
    
    for (UINT i = 0; i < NumSubresources; ++i)
    {
        if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0;
        D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] };
        MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth);
    }
    pIntermediate->Unmap(0, NULL);
    
    if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
    {
        CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( 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)
        {
            CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
            CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
            pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
        }
    }
    return RequiredSize;
}

请参阅 D3D12 参考中的示例代码

要求

要求
目标平台 Windows
标头 d3d12.h
Library D3d12.lib
DLL D3d12.dll

另请参阅

CopyBufferRegion

ID3D12GraphicsCommandList