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 进行格式转换。
请注意,对于深度模具缓冲区,深度平面和模具平面是缓冲区内的 单独子资源 。
若要复制整个资源,而不仅仅是子资源的区域,建议改用 CopyResource 。
示例
以下代码片段将位于 (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 |