Compartilhar via


Método ID3D12Resource::Map (d3d12.h)

Obtém um ponteiro de CPU para o sub-recurso especificado no recurso, mas pode não divulgar o valor do ponteiro para aplicativos. O mapa também invalida o cache de CPU, quando necessário, para que as leituras da CPU nesse endereço reflitam as modificações feitas pela GPU.

Sintaxe

HRESULT Map(
                  UINT              Subresource,
  [in, optional]  const D3D12_RANGE *pReadRange,
  [out, optional] void              **ppData
);

Parâmetros

Subresource

Tipo: UINT

Especifica o número de índice do sub-recurso.

[in, optional] pReadRange

Tipo: const D3D12_RANGE*

Um ponteiro para uma estrutura D3D12_RANGE que descreve o intervalo de memória a ser acessado.

Isso indica a região que a CPU pode ler e as coordenadas são relativas a sub-recursos. Um ponteiro nulo indica que todo o sub-recurso pode ser lido pela CPU. É válido especificar que a CPU não lerá nenhum dado passando um intervalo em que End é menor ou igual a Begin.

[out, optional] ppData

Tipo: void**

Um ponteiro para um bloco de memória que recebe um ponteiro para os dados do recurso.

Um ponteiro nulo é válido e é útil para armazenar em cache um intervalo de endereços virtuais da CPU para métodos como WriteToSubresource. Quando ppData não é NULL, o ponteiro retornado nunca é deslocado por nenhum valor em pReadRange.

Retornar valor

Tipo: HRESULT

Esse método retorna um dos códigos de retorno do Direct3D 12.

Comentários

Map e Unmap podem ser chamados por vários threads com segurança. Há suporte para chamadas aninhadas do Mapa e são contadas novamente. A primeira chamada para Mapa aloca um intervalo de endereços virtuais da CPU para o recurso. A última chamada para Desalocar desaloca o intervalo de endereços virtuais da CPU. O endereço virtual da CPU normalmente é retornado ao aplicativo; mas manipular o conteúdo de texturas com layouts desconhecidos impede a divulgação do endereço virtual da CPU. Consulte WriteToSubresource para obter mais detalhes. Os aplicativos não podem depender do endereço ser consistente, a menos que o Mapa seja persistentemente aninhado.

Os ponteiros retornados pelo Mapa não têm garantia de ter todos os recursos de ponteiros normais, mas a maioria dos aplicativos não observará uma diferença no uso normal. Por exemplo, ponteiros com WRITE_COMBINE comportamento têm garantias de ordenação de memória de CPU mais fracas do que WRITE_BACK comportamento. A memória acessível pela CPU e pela GPU não tem garantia de compartilhar as mesmas garantias de memória atômica que a CPU tem, devido a limitações de PCIe. Use cercas para sincronização.

Há duas categorias de modelo de uso para Mapa, simples e avançado. Os modelos de uso simples maximizam o desempenho da ferramenta, portanto, é recomendável que os aplicativos fiquem com os modelos simples até que os modelos avançados sejam comprovados como exigidos pelo aplicativo.

Modelos de uso simples

Os aplicativos devem se ater às abstrações de tipo heap de UPLOAD, DEFAULT e READBACK, a fim de dar suporte a todas as arquiteturas do adaptador razoavelmente bem.

Os aplicativos devem evitar leituras de CPU de ponteiros para recursos em heaps upload, mesmo acidentalmente. As leituras de CPU funcionarão, mas são proibitivamente lentas em muitas arquiteturas comuns de GPU, portanto, considere o seguinte:

  • Não faça a CPU ler de recursos associados a heaps D3D12_HEAP_TYPE_UPLOAD ou que tenham D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE.
  • A região de memória à qual os pontos pData podem ser alocados com PAGE_WRITECOMBINE e seu aplicativo deve respeitar todas as restrições associadas a essa memória.
  • Até mesmo o código C++ a seguir pode ler da memória e disparar a penalidade de desempenho porque o código pode expandir para o código de assembly x86 a seguir.

    Código C++:

    *((int*)MappedResource.pData) = 0;
    

    Código do assembly x86:

    AND DWORD PTR [EAX],0
    
  • Use as configurações de otimização apropriadas e os constructos de linguagem para ajudar a evitar essa penalidade de desempenho. Por exemplo, você pode evitar a otimização xor usando um ponteiro volátil ou otimizando para velocidade de código em vez do tamanho do código.
Os aplicativos são incentivados a deixar os recursos não mapeados, enquanto a CPU não os modificará e usará intervalos apertados e precisos o tempo todo. Isso habilita os modos mais rápidos para ferramentas, como a Depuração de Gráficos e a camada de depuração. Essas ferramentas precisam acompanhar todas as modificações de CPU na memória que a GPU pode ler.

Modelos de uso avançados

Os recursos em heaps acessíveis à CPU podem ser mapeados persistentemente, o que significa que o Mapa pode ser chamado uma vez, imediatamente após a criação do recurso. O unmap nunca precisa ser chamado, mas o endereço retornado do Mapa não deve mais ser usado depois que a última referência ao recurso for lançada. Ao usar o mapa persistente, o aplicativo deve garantir que a CPU termine de gravar dados na memória antes que a GPU execute uma lista de comandos que leia ou grave a memória. Em cenários comuns, o aplicativo deve apenas gravar na memória antes de chamar ExecuteCommandLists; mas usar uma cerca para atrasar a execução da lista de comandos também funciona.

Todos os tipos de memória acessíveis à CPU dão suporte ao uso de mapeamento persistente, em que o recurso é mapeado, mas nunca não mapeado, desde que o aplicativo não acesse o ponteiro após o recurso ter sido descartado.

Exemplos

O exemplo D3D12Bundles usa ID3D12Resource::Map da seguinte maneira:

Copie dados de triângulo para o buffer de vértice.

// Copy the triangle data to the vertex buffer.
UINT8* pVertexDataBegin;
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
m_vertexBuffer->Unmap(0, nullptr);

Crie um heap de upload para os buffers constantes.

// Create an upload heap for the constant buffers.
ThrowIfFailed(pDevice->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
    D3D12_HEAP_FLAG_NONE,
    &CD3DX12_RESOURCE_DESC::Buffer(sizeof(ConstantBuffer) * m_cityRowCount * m_cityColumnCount),
    D3D12_RESOURCE_STATE_GENERIC_READ,
    nullptr,
    IID_PPV_ARGS(&m_cbvUploadHeap)));

// Map the constant buffers. Note that unlike D3D11, the resource 
// does not need to be unmapped for use by the GPU. In this sample, 
// the resource stays 'permanently' mapped to avoid overhead with 
// mapping/unmapping each frame.
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_cbvUploadHeap->Map(0, &readRange, reinterpret_cast<void**>(&m_pConstantBuffers)));

Consulte o 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

ID3D12Resource

Sub-recursos

Desmapear