Compartilhar via


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

Obtém um ponteiro de CPU para a sub-fonte especificada 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 da sub-fonte.

[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 à sub-fonte. Um ponteiro nulo indica que toda a sub-fonte pode ser lida 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 no pReadRange.

Valor de retorno

Tipo: HRESULT

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

Observações

O mapa e o unmap podem ser chamados por vários threads com segurança. Há suporte para chamadas de mapa aninhadas 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 Desmapear desaloca o intervalo de endereços virtuais da CPU. O endereço virtual da CPU geralmente é retornado para o 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 contar com o endereço sendo consistente, a menos que o Mapa esteja 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 a 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 comprovadamente 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 que são D3D12_HEAP_TYPE_UPLOAD ou têm 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 a velocidade do 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çado

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 conclua a gravação de 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.

Requirements

Requirement Value
da Plataforma de Destino Windows
Header d3d12.h
Library D3D12.lib
de DLL D3D12.dll

Consulte também

ID3D12Resource

Sub-recursos

Cancelar o mapa