Método ID3D12GraphicsCommandList::CopyTextureRegion (d3d12.h)

Esse método usa a GPU para copiar dados de textura entre dois locais. Tanto a origem quanto o destino podem referenciar dados de textura localizados em um recurso de buffer ou em um recurso de textura.

Sintaxe

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
);

Parâmetros

[in] pDst

Tipo: const D3D12_TEXTURE_COPY_LOCATION*

Especifica o D3D12_TEXTURE_COPY_LOCATION de destino. O sub-recurso referido deve estar no estado D3D12_RESOURCE_STATE_COPY_DEST.

DstX

Tipo: UINT

A coordenada x do canto superior esquerdo da região de destino.

DstY

Tipo: UINT

A coordenada y do canto superior esquerdo da região de destino. Para um sub-recurso 1D, isso deve ser zero.

DstZ

Tipo: UINT

A coordenada z do canto superior esquerdo da região de destino. Para um sub-recurso 1D ou 2D, isso deve ser zero.

[in] pSrc

Tipo: const D3D12_TEXTURE_COPY_LOCATION*

Especifica o D3D12_TEXTURE_COPY_LOCATION de origem. O sub-recurso referido deve estar no estado D3D12_RESOURCE_STATE_COPY_SOURCE.

[in, optional] pSrcBox

Tipo: const D3D12_BOX*

Especifica um D3D12_BOX opcional que define o tamanho da textura de origem a ser copiada.

Retornar valor

Nenhum

Comentários

A caixa de origem deve estar dentro do tamanho do recurso de origem. Os deslocamentos de destino , (x, y e z), permitem que a caixa de origem seja deslocada ao gravar no recurso de destino; no entanto, as dimensões da caixa de origem e os deslocamentos devem estar dentro do tamanho do recurso. Se você tentar copiar fora do recurso de destino ou especificar uma caixa de origem maior que o recurso de origem, o comportamento de CopyTextureRegion será indefinido. Se você criou um dispositivo que dá suporte à camada de depuração, a saída de depuração relatará um erro nesta chamada CopyTextureRegion inválida. Parâmetros inválidos para CopyTextureRegion causam comportamento indefinido e podem resultar em renderização incorreta, recorte, nenhuma cópia ou até mesmo a remoção do dispositivo de renderização.

Se os recursos forem buffers, todas as coordenadas estarão em bytes; se os recursos forem texturas, todas as coordenadas estarão em texels.

CopyTextureRegion executa a cópia na GPU (semelhante a uma memcpy da CPU). Como consequência, os recursos de origem e destino:

  • Devem ser sub-recursos diferentes (embora possam ser do mesmo recurso).
  • Deve ter DXGI_FORMATcompatíveis (idênticas ou do mesmo grupo de tipos). Por exemplo, uma textura DXGI_FORMAT_R32G32B32_FLOAT pode ser copiada para uma textura DXGI_FORMAT_R32G32B32_UINT, pois ambos os formatos estão no grupo DXGI_FORMAT_R32G32B32_TYPELESS. CopyTextureRegion pode copiar entre alguns tipos de formato. Para obter mais informações, consulte Conversão de formato usando o Direct3D 10.1.
CopyTextureRegion só dá suporte à cópia; ele não dá suporte a qualquer alongamento, chave de cor ou mesclagem. CopyTextureRegion pode reinterpretar os dados de recurso entre alguns tipos de formato.

Observe que, para um buffer de estêncil de profundidade, os planos de profundidade e estêncil são sub-recursos separados dentro do buffer.

Para copiar um recurso inteiro, em vez de apenas uma região de um sub-recurso, recomendamos usar CopyResource .

Nota Se você usar CopyTextureRegion com um buffer de estêncil de profundidade ou um recurso multisampled, você deverá copiar todo o retângulo de sub-fonte. Nessa situação, você deve passar 0 para os parâmetros DstX, DstY e DstZ e NULL para o parâmetro pSrcBox . Além disso, os recursos de origem e destino, que são representados pelos parâmetros pSrcResource e pDstResource , devem ter valores de contagem de exemplo idênticos.
 
CopyTextureRegion pode ser usado para inicializar recursos que alias a mesma memória de heap. Consulte CreatePlacedResource para obter mais detalhes.

Exemplo

O snippet de código a seguir copia a caixa (localizada em (120.100),(200.220)) de uma textura de origem para a região (10,20)(90.140) em uma textura de destino.
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);

Observe que, para uma textura 2D, front e back são definidos como 0 e 1, respectivamente.

Exemplos

O exemplo HelloTriangle usa ID3D12GraphicsCommandList::CopyTextureRegion da seguinte maneira:

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;
}

Consulte Código de exemplo na referência D3D12.

Requisitos

Requisito Valor
Plataforma de Destino Windows
Cabeçalho d3d12.h
Biblioteca D3d12.lib
DLL D3d12.dll

Confira também

CopyBufferRegion

ID3D12GraphicsCommandList