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.
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 .
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 |