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 (上執行與 CPU) 類似的 memcpy 複本。 因此,來源和目的地資源:

  • 雖然子資源可以來自相同的資源) ,但必須是不同的子資源 (。
  • 必須有相容的 DXGI_FORMAT (相同或來自相同類型群組) 。 例如,DXGI_FORMAT_R32G32B32_FLOAT紋理可以複製到DXGI_FORMAT_R32G32B32_UINT紋理,因為這兩種格式都位於DXGI_FORMAT_R32G32B32_TYPELESS群組中。 CopyTextureRegion 可以在幾個格式類型之間複製。 如需詳細資訊,請參閱 使用 Direct3D 10.1 的格式轉換
CopyTextureRegion 僅支援 copy;它不支援任何延展、色彩索引鍵或混合。 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
程式庫 D3d12.lib
Dll D3d12.dll

另請參閱

CopyBufferRegion

ID3D12GraphicsCommandList