Compartir a través de


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

Obtiene un puntero de CPU al subrecurso especificado en el recurso, pero puede no revelar el valor de puntero a las aplicaciones. El mapa también invalida la memoria caché de CPU, cuando sea necesario, para que la CPU lea esta dirección refleje las modificaciones realizadas por la GPU.

Syntax

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

Parámetros

Subresource

Tipo: UINT

Especifica el número de índice del subrecurso.

[in, optional] pReadRange

Tipo: const D3D12_RANGE*

Puntero a una estructura de D3D12_RANGE que describe el intervalo de memoria al que acceder.

Esto indica la región que la CPU podría leer y las coordenadas son subresource-relative. Un puntero nulo indica que la CPU podría leer todo el subrecurso. Es válido especificar que la CPU no leerá ningún dato pasando un intervalo en el que End sea menor o igual que Begin.

[out, optional] ppData

Tipo: void**

Puntero a un bloque de memoria que recibe un puntero a los datos del recurso.

Un puntero nulo es válido y es útil almacenar en caché un intervalo de direcciones virtuales de CPU para métodos como WriteToSubresource. Cuando ppData no es NULL, el puntero devuelto nunca se desplaza por ningún valor de pReadRange.

Valor devuelto

Tipo: HRESULT

Este método devuelve uno de los códigos de retorno de Direct3D 12.

Observaciones

Varios subprocesos pueden llamar a Map y Unmap de forma segura. Se admiten llamadas de mapa anidadas y se cuentan con referencias. La primera llamada a Map asigna un intervalo de direcciones virtuales de CPU para el recurso. La última llamada a Unmap desasigna el intervalo de direcciones virtuales de la CPU. La dirección virtual de CPU se devuelve normalmente a la aplicación; pero manipular el contenido de las texturas con diseños desconocidos impide que la dirección virtual de la CPU se diste. Consulte WriteToSubresource para obtener más detalles. Las aplicaciones no pueden confiar en que la dirección sea coherente, a menos que map esté anidada de forma persistente.

No se garantiza que los punteros devueltos por Map tengan todas las funcionalidades de punteros normales, pero la mayoría de las aplicaciones no observarán una diferencia en el uso normal. Por ejemplo, los punteros con WRITE_COMBINE comportamiento tienen garantías de ordenación de memoria de CPU más débiles que WRITE_BACK comportamiento. No se garantiza que la memoria accesible tanto por CPU como por GPU compartan la misma memoria atómica que la CPU tiene, debido a las limitaciones de PCIe. Use barreras para la sincronización.

Hay dos categorías de modelos de uso para Map, simple y avanzado. Los modelos de uso simple maximizan el rendimiento de las herramientas, por lo que las aplicaciones se recomiendan para seguir con los modelos simples hasta que la aplicación demuestre que los modelos avanzados son necesarios.

Modelos de uso simples

Las aplicaciones deben seguir las abstracciones de tipo montón de UPLOAD, DEFAULT y READBACK, con el fin de admitir todas las arquitecturas de adaptadores razonablemente bien.

Las aplicaciones deben evitar lecturas de CPU de punteros a recursos en montones de carga, incluso accidentalmente. Las lecturas de CPU funcionarán, pero son prohibitivamente lentas en muchas arquitecturas comunes de GPU, por lo que tenga en cuenta lo siguiente:

  • No haga que la CPU se lea de los recursos asociados a montones que se D3D12_HEAP_TYPE_UPLOAD o que tengan D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE.
  • La región de memoria a la que se pueden asignar puntos pData con PAGE_WRITECOMBINE y la aplicación debe respetar todas las restricciones asociadas a dicha memoria.
  • Incluso el siguiente código de C++ puede leer desde la memoria y desencadenar la penalización de rendimiento porque el código puede expandirse al siguiente código de ensamblado x86.

    Código de C++:

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

    Código de ensamblado x86:

    AND DWORD PTR [EAX],0
    
  • Use la configuración de optimización adecuada y las construcciones de lenguaje para ayudar a evitar esta penalización de rendimiento. Por ejemplo, puede evitar la optimización de xor mediante un puntero volátil o optimizando para la velocidad del código en lugar del tamaño del código.
Se recomienda que las aplicaciones abandonen los recursos sin asignar, mientras que la CPU no las modificará y usar intervalos estrictos y precisos en todo momento. Esto permite los modos más rápidos para las herramientas, como la depuración de gráficos y la capa de depuración. Estas herramientas deben realizar un seguimiento de todas las modificaciones de CPU en la memoria que la GPU podría leer.

Modelos de uso avanzado

Los recursos de los montones accesibles para cpu se pueden asignar de forma persistente, lo que significa que se puede llamar a Map una vez, inmediatamente después de la creación de recursos. No es necesario llamar a un mapa nunca, pero la dirección devuelta desde Map ya no debe usarse después de que se libere la última referencia al recurso. Cuando se usa la asignación persistente, la aplicación debe asegurarse de que la CPU termina de escribir datos en memoria antes de que la GPU ejecute una lista de comandos que lea o escriba la memoria. En escenarios comunes, la aplicación simplemente debe escribir en la memoria antes de llamar a ExecuteCommandLists; pero también funciona el uso de una barrera para retrasar la ejecución de la lista de comandos.

Todos los tipos de memoria accesibles para LA CPU admiten el uso de asignación persistente, donde el recurso se asigna pero, a continuación, nunca se desasigna, siempre que la aplicación no acceda al puntero después de eliminar el recurso.

Examples

El ejemplo D3D12Bundles usa ID3D12Resource::Map de la siguiente manera:

Copie los datos del triángulo en el búfer de vértices.

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

Cree un montón de carga para los búferes de 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 el código de ejemplo en la referencia D3D12.

Requisitos

Requirement Importancia
de la plataforma de destino de Windows
Header d3d12.h
Library D3D12.lib
DLL de D3D12.dll

Consulte también

ID3D12Resource

Subrecursos

Desasignación de mapa