Partager via


ID3D12Resource ::Map, méthode (d3d12.h)

Obtient un pointeur processeur vers la sous-source spécifiée dans la ressource, mais peut ne pas divulguer la valeur du pointeur aux applications. Mappe également le cache du processeur, si nécessaire, afin que l’UC lise à cette adresse reflète toutes les modifications apportées par le GPU.

Syntaxe

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

Paramètres

Subresource

Type : UINT

Spécifie le numéro d’index de la sous-ressource.

[in, optional] pReadRange

Type : const D3D12_RANGE*

Pointeur vers une structure D3D12_RANGE qui décrit la plage de mémoire à accéder.

Cela indique la région que le processeur peut lire, et les coordonnées sont relatives aux sous-ressources. Un pointeur Null indique que la sous-ressource entière peut être lue par l’UC. Il est valide de spécifier que l’UC ne lit pas de données en passant une plage où La fin est inférieure ou égale à Begin.

[out, optional] ppData

Type : void**

Pointeur vers un bloc de mémoire qui reçoit un pointeur vers les données de ressource.

Un pointeur Null est valide et est utile pour mettre en cache une plage d’adresses virtuelles processeur pour les méthodes telles que WriteToSubresource. Lorsque ppData n’est pas NULL, le pointeur retourné n’est jamais décalé par des valeurs dans pReadRange.

Valeur retournée

Type : HRESULT

Cette méthode retourne l’un des codes de retour Direct3D 12.

Remarques

Map et Unmap peuvent être appelés par plusieurs threads en toute sécurité. Les appels map imbriqués sont pris en charge et sont comptabilisés dans la référence. Le premier appel à Map alloue une plage d’adresses virtuelles processeur pour la ressource. Le dernier appel à Unmap désalloue la plage d’adresses virtuelles du processeur. L’adresse virtuelle de l’UC est généralement retournée à l’application ; mais la manipulation du contenu des textures avec des dispositions inconnues empêche la divulgation de l’adresse virtuelle du processeur. Pour plus d’informations, consultez WriteToSubresource . Les applications ne peuvent pas s’appuyer sur l’adresse cohérente, sauf si map est imbriquée de manière permanente.

Les pointeurs retournés par Map ne sont pas garantis pour avoir toutes les fonctionnalités des pointeurs normaux, mais la plupart des applications ne remarqueront pas de différence dans l’utilisation normale. Par exemple, les pointeurs ayant un comportement WRITE_COMBINE ont des garanties d’ordre de mémoire processeur plus faibles que WRITE_BACK comportement. La mémoire accessible à la fois par l’UC et le GPU ne sont pas garanties pour partager les mêmes garanties de mémoire atomique que celle de l’UC, en raison des limitations pcIe. Utilisez des clôtures pour la synchronisation.

Il existe deux catégories de modèles d’utilisation pour Map, simple et avancé. Les modèles d’utilisation simples optimisent les performances des outils. Les applications sont donc recommandées pour respecter les modèles simples jusqu’à ce que les modèles avancés soient requis par l’application.

Modèles d’utilisation simples

Les applications doivent respecter les abstractions de type tas de UPLOAD, DEFAULT et READBACK, afin de prendre en charge toutes les architectures d’adaptateurs raisonnablement bien.

Les applications doivent éviter les lectures du processeur à partir de pointeurs vers des ressources sur des tas DE CHARGEMENT, même accidentellement. Les lectures de processeur fonctionnent, mais sont excessivement lentes sur de nombreuses architectures GPU courantes. Tenez donc compte des points suivants :

  • N’effectuez pas de lecture du processeur à partir de ressources associées aux tas D3D12_HEAP_TYPE_UPLOAD ou qui ont D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE.
  • Région de mémoire à laquelle les points pData peuvent être alloués avec PAGE_WRITECOMBINE, et votre application doit respecter toutes les restrictions associées à cette mémoire.
  • Même le code C++ suivant peut lire à partir de la mémoire et déclencher la pénalité de performances, car le code peut s’étendre au code d’assembly x86 suivant.

    Code C++ :

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

    Code d’assembly x86 :

    AND DWORD PTR [EAX],0
    
  • Utilisez les paramètres d’optimisation et les constructions de langage appropriés pour éviter cette pénalité de performances. Par exemple, vous pouvez éviter l’optimisation xor à l’aide d’un pointeur volatile ou en optimisant la vitesse du code au lieu de la taille du code.
Les applications sont encouragées à laisser les ressources non mappées alors que l’UC ne les modifie pas et qu’elles utilisent des plages étroites et précises à tout moment. Cela permet les modes les plus rapides pour les outils, tels que le débogage graphique et la couche de débogage. Ces outils doivent suivre toutes les modifications du processeur en mémoire que le GPU pourrait lire.

Modèles d’utilisation avancés

Les ressources sur les tas accessibles au processeur peuvent être mappées de manière permanente, ce qui signifie que map peut être appelée une seule fois, immédiatement après la création de ressources. Unmap n’a jamais besoin d’être appelé, mais l’adresse retournée par Map ne doit plus être utilisée après la dernière référence à la ressource. Lorsque vous utilisez la carte persistante, l’application doit s’assurer que l’UC termine l’écriture de données en mémoire avant que le GPU exécute une liste de commandes qui lit ou écrit la mémoire. Dans les scénarios courants, l’application doit simplement écrire en mémoire avant d’appeler ExecuteCommandLists ; mais l’utilisation d’une clôture pour retarder l’exécution de la liste de commandes fonctionne également.

Tous les types de mémoire accessibles au processeur prennent en charge l’utilisation du mappage persistant, où la ressource est mappée, mais jamais non mappée, à condition que l’application n’accède pas au pointeur une fois la ressource supprimée.

Examples

L’exemple D3D12Bundles utilise ID3D12Resource ::Map comme suit :

Copiez les données triangle dans la mémoire tampon de vertex.

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

Créez un tas de chargement pour les mémoires tampons 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)));

Reportez-vous à l’exemple de code dans la référence D3D12.

Spécifications

Requirement Valeur
plateforme cible Fenêtres
Header d3d12.h
Library D3D12.lib
DLL D3D12.dll

Voir aussi

ID3D12Resource

Sous-ressources

Annuler le mappage