Freigeben über


ID3D12Resource::Map-Methode (d3d12.h)

Ruft einen CPU-Zeiger auf die angegebene Unterressource in der Ressource ab, gibt den Zeigerwert jedoch möglicherweise nicht an Anwendungen weiter. Außerdem wird der CPU-Cache bei Bedarf ungültig, damit die CPU diese Adresse liest, alle Änderungen der GPU widerspiegeln.

Syntax

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

Die Parameter

Subresource

Typ: UINT

Gibt die Indexnummer der Unterressource an.

[in, optional] pReadRange

Typ: const D3D12_RANGE*

Ein Zeiger auf eine D3D12_RANGE-Struktur , die den Speicherbereich beschreibt, auf den zugegriffen werden kann.

Dies gibt an, welche Region die CPU lesen kann, und die Koordinaten sind unterresourcerelativ. Ein Nullzeiger gibt an, dass die gesamte Unterressource möglicherweise von der CPU gelesen wird. Es ist gültig, um anzugeben, dass die CPU keine Daten liest, indem ein Bereich übergeben wird, in dem End kleiner als oder gleich "Begin" ist.

[out, optional] ppData

Typ: void**

Ein Zeiger auf einen Speicherblock, der einen Zeiger auf die Ressourcendaten empfängt.

Ein Nullzeiger ist gültig und eignet sich zum Zwischenspeichern eines virtuellen CPU-Adressbereichs für Methoden wie WriteToSubresource. Wenn ppData nicht NULL ist, wird der zurückgegebene Zeiger niemals durch werte in pReadRange versetzt.

Rückgabewert

Typ: HRESULT

Diese Methode gibt einen der Direct3D 12-Rückgabecodes zurück.

Bemerkungen

Zuordnung und Unmap können von mehreren Threads sicher aufgerufen werden. Geschachtelte Kartenaufrufe werden unterstützt und werden gezählt. Der erste Aufruf von Map weist einen virtuellen CPU-Adressbereich für die Ressource zu. Der letzte Aufruf von "Unmap " ordnet den virtuellen CPU-Adressbereich zu. Die virtuelle CPU-Adresse wird häufig an die Anwendung zurückgegeben. die Bearbeitung des Inhalts von Texturen mit unbekannten Layouts schließt jedoch die Offenlegung der virtuellen CPU-Adresse aus. Weitere Details finden Sie unter WriteToSubresource . Anwendungen können sich nicht darauf verlassen, dass die Adresse konsistent ist, es sei denn, die Zuordnung ist dauerhaft geschachtelt.

Zeiger, die von Map zurückgegeben werden, sind nicht garantiert, dass alle Funktionen normaler Zeiger verfügbar sind, aber die meisten Anwendungen bemerken keinen Unterschied bei der normalen Verwendung. Zeiger mit WRITE_COMBINE Verhalten haben beispielsweise schwächere CPU-Speichersortierungsgarantien als WRITE_BACK Verhalten. Der von CPU und GPU zugängliche Speicher ist nicht garantiert, dass der gleiche atomische Speicher den cpu hat, aufgrund von PCIe-Einschränkungen. Verwenden Sie Zäune für die Synchronisierung.

Es gibt zwei Verwendungsmodellkategorien für Karten, einfach und erweitert. Die einfachen Verwendungsmodelle maximieren die Toolleistung, sodass Anwendungen empfohlen werden, mit den einfachen Modellen zu bleiben, bis die erweiterten Modelle nachweislich von der App benötigt werden.

Einfache Verwendungsmodelle

Anwendungen sollten sich an die Heap-Typenabstraktionen von UPLOAD, DEFAULT und READBACK halten, um alle Adapterarchitekturen angemessen zu unterstützen.

Anwendungen sollten CPU-Lesevorgänge von Zeigern auf Ressourcen auf UPLOAD-Heaps vermeiden, auch versehentlich. CPU-Lesevorgänge funktionieren zwar, sind aber bei vielen gängigen GPU-Architekturen unertraglich langsam. Beachten Sie daher Folgendes:

  • Sie können die CPU nicht aus Ressourcen lesen, die heaps zugeordnet sind, die D3D12_HEAP_TYPE_UPLOAD sind oder über D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE verfügen.
  • Der Speicherbereich, dem pData-Punktemit PAGE_WRITECOMBINE zugeordnet werden können, und Ihre App muss alle Einschränkungen berücksichtigen, die diesem Speicher zugeordnet sind.
  • Selbst der folgende C++-Code kann aus dem Arbeitsspeicher lesen und die Leistungseinbußen auslösen, da der Code auf den folgenden x86-Assemblycode erweitert werden kann.

    C++-Code:

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

    x86-Assemblycode:

    AND DWORD PTR [EAX],0
    
  • Verwenden Sie die entsprechenden Optimierungseinstellungen und Sprachkonstrukte, um diese Leistungseinbußen zu vermeiden. Beispielsweise können Sie die XOR-Optimierung vermeiden, indem Sie einen veränderliche Zeiger verwenden oder die Codegeschwindigkeit anstelle der Codegröße optimieren.
Anwendungen werden ermutigt, Ressourcen nicht zugeordnet zu lassen, während die CPU sie nicht ändert und immer enge, genaue Bereiche verwendet. Dies ermöglicht die schnellsten Modi für Tools, z. B. Grafikdebugging und Debugebene. Solche Tools müssen alle CPU-Änderungen im Arbeitsspeicher nachverfolgen, die die GPU lesen konnte.

Erweiterte Verwendungsmodelle

Ressourcen auf heaps mit CPU-Zugriff können dauerhaft zugeordnet werden, was bedeutet, dass die Zuordnung einmal aufgerufen werden kann, unmittelbar nach der Ressourcenerstellung. "Unmap " muss nie aufgerufen werden, aber die von Map zurückgegebene Adresse darf nach der Veröffentlichung des letzten Verweises auf die Ressource nicht mehr verwendet werden. Bei Verwendung der persistenten Zuordnung muss die Anwendung sicherstellen, dass die CPU das Schreiben von Daten in den Arbeitsspeicher beendet, bevor die GPU eine Befehlsliste ausführt, die den Speicher liest oder schreibt. In gängigen Szenarien muss die Anwendung lediglich in den Arbeitsspeicher schreiben, bevor ExecuteCommandLists aufgerufen wird. Die Ausführung von Befehlslisten funktioniert jedoch auch mit einem Zaun, um die Ausführung der Befehlsliste zu verzögern.

Alle cpu-zugänglichen Speichertypen unterstützen die beständige Zuordnungsauslastung, bei der die Ressource zugeordnet, aber dann nie nicht zugeordnet ist, vorausgesetzt, die Anwendung greift nicht auf den Zeiger zu, nachdem die Ressource gelöscht wurde.

Examples

Im Beispiel "D3D12Bundles " wird ID3D12Resource::Map wie folgt verwendet:

Kopieren Sie Dreiecksdaten in den Vertexpuffer.

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

Erstellen Sie einen Upload-Heap für die Konstantenpuffer.

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

Verweisen Sie auf den Beispielcode in der D3D12-Referenz.

Anforderungen

Anforderung Wert
Zielplattform Fenster
Header d3d12.h
Library D3D12.lib
DLL D3D12.dll

Siehe auch

ID3D12Resource

Unterressourcen

Aufheben der Zuordnung