Поделиться через


Метод 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, который задает размер исходной текстуры для копирования.

Возвращаемое значение

None

Remarks

Поле источника должно быть в пределах размера исходного ресурса. Конечные смещения (x, y и z) позволяют смещению исходного поля при записи в целевой ресурс; Однако размеры исходного поля и смещения должны быть в пределах размера ресурса. Если попытаться скопировать за пределы целевого ресурса или указать поле источника, которое больше исходного ресурса, поведение CopyTextureRegion будет неопределенным. Если вы создали устройство, поддерживающее уровень отладки, выходные данные отладки сообщают об ошибке при этом недопустимом вызове CopyTextureRegion . Недопустимые параметры для CopyTextureRegion приводят к неопределенному поведению и могут привести к неправильной отрисовке, обрезке, без копирования или даже удалению устройства отрисовки.

Если ресурсы являются буферами, все координаты находятся в байтах; Если ресурсы являются текстурами, все координаты находятся в текселях.

CopyTextureRegion выполняет копирование на GPU (аналогично операции memcpy ЦП). Как следствие, исходные и целевые ресурсы:

  • Должны быть разными подресурсами (хотя они могут относиться к одному и тому же ресурсу).
  • Должны иметь совместимые DXGI_FORMAT(идентичные или из той же группы типов). Например, DXGI_FORMAT_R32G32B32_FLOAT текстуру можно скопировать в DXGI_FORMAT_R32G32B32_UINT текстуру, так как оба этих формата находятся в группе DXGI_FORMAT_R32G32B32_TYPELESS. CopyTextureRegion может копировать данные между несколькими типами форматов. Дополнительные сведения см. в разделе Преобразование формата с помощью Direct3D 10.1.
CopyTextureRegion поддерживает только копирование; он не поддерживает растяжение, цвет или смешения. CopyTextureRegion может переосмыслить данные ресурсов между несколькими типами форматов.

Обратите внимание, что для буфера трафарета глубины плоскости глубины и трафарета являются отдельными вложенными источниками в буфере.

Чтобы скопировать весь ресурс, а не только регион подресурса, рекомендуется использовать CopyResource .

Примечание При использовании CopyTextureRegion с буфером трафарета глубины или ресурсом с несколькими выборками необходимо скопировать весь прямоугольник подресурса. В этом случае необходимо передать 0 в параметры DstX, DstY и DstZ , а null — в параметр pSrcBox . Кроме того, исходные и целевые ресурсы, представленные параметрами pSrcResource и pDstResource , должны иметь одинаковые значения количества выборок.
 
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);

Обратите внимание, что для двухd-текстуры спереди и назад заданы значения 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
Header d3d12.h
Библиотека D3d12.lib
DLL D3d12.dll

См. также раздел

CopyBufferRegion

ID3D12GraphicsCommandList