Condividi tramite


Metodo ID3D12Resource::Map (d3d12.h)

Ottiene un puntatore della CPU alla sottoresource specificata nella risorsa, ma potrebbe non divulgare il valore del puntatore alle applicazioni. Il mapping invalida anche la cache della CPU, se necessario, in modo che la CPU venga letto in questo indirizzo rifletta tutte le modifiche apportate dalla GPU.

Sintassi

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

Parametri

Subresource

Tipo: UINT

Specifica il numero di indice della sottoresource.

[in, optional] pReadRange

Tipo: const D3D12_RANGE*

Puntatore a una struttura D3D12_RANGE che descrive l'intervallo di memoria da accedere.

Ciò indica che l'area della CPU potrebbe leggere e le coordinate sono sottoresource-relative. Un puntatore Null indica che l'intera sottoresource potrebbe essere letto dalla CPU. È valido specificare che la CPU non legge i dati passando un intervallo in cui End è minore o uguale a Begin.

[out, optional] ppData

Tipo: void**

Puntatore a un blocco di memoria che riceve un puntatore ai dati della risorsa.

Un puntatore Null è valido ed è utile memorizzare nella cache un intervallo di indirizzi virtuali della CPU per metodi come WriteToSubresource. Quando ppData non è NULL, il puntatore restituito non viene mai offset da alcun valore in pReadRange.

Valore restituito

Tipo: HRESULT

Questo metodo restituisce uno dei codici restituiti Direct3D 12.

Commenti

La mappa e Unmap possono essere chiamate da più thread in modo sicuro. Le chiamate mappa annidate sono supportate e vengono conteggiate. La prima chiamata a Map alloca un intervallo di indirizzi virtuali della CPU per la risorsa. L'ultima chiamata a Unmap dealloca l'intervallo di indirizzi virtuali della CPU. L'indirizzo virtuale della CPU viene comunemente restituito all'applicazione; ma la modifica del contenuto delle trame con layout sconosciuti impedisce di divulgare l'indirizzo virtuale della CPU. Per altre informazioni, vedere WriteToSubresource . Le applicazioni non possono basarsi sull'indirizzo coerente, a meno che Map non sia annidato in modo permanente.

I puntatori restituiti da Map non sono garantiti per avere tutte le funzionalità dei normali puntatori, ma la maggior parte delle applicazioni non noterà una differenza nell'utilizzo normale. Ad esempio, i puntatori con WRITE_COMBINE comportamento hanno garanzie di ordinamento della memoria CPU più deboli rispetto al comportamento WRITE_BACK. La memoria accessibile sia dalla CPU che dalla GPU non è garantita per condividere le stesse garanzie di memoria atomiche che la CPU ha, a causa delle limitazioni del PCIe. Usare le recinzioni per la sincronizzazione.

Esistono due categorie di modelli di utilizzo per Map, semplici e avanzate. I modelli di utilizzo semplici ottimizzano le prestazioni degli strumenti, pertanto è consigliabile che le applicazioni siano conformi ai modelli semplici fino a quando i modelli avanzati non vengono dimostrati necessari dall'app.

Modelli di utilizzo semplice

Le applicazioni devono attenersi alle astrazioni di tipo heap di UPLOAD, DEFAULT e READBACK, per supportare tutte le architetture dell'adattatore ragionevolmente bene.

Le applicazioni devono evitare le letture della CPU dai puntatori alle risorse sugli heaps DI CARICAMENTo, anche accidentalmente. Le letture della CPU funzioneranno, ma sono eccessivamente lente su molte architetture GPU comuni, quindi prendere in considerazione quanto segue:

  • Non eseguire la lettura della CPU dalle risorse associate agli heaps D3D12_HEAP_TYPE_UPLOAD o avere D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE.
  • L'area di memoria a cui possono essere allocati punti pData con PAGE_WRITECOMBINE e l'app deve rispettare tutte le restrizioni associate a tale memoria.
  • Anche il codice C++ seguente può leggere dalla memoria e attivare la penalità delle prestazioni perché il codice può espandersi al codice dell'assembly x86 seguente.

    Codice C++:

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

    Codice assembly x86:

    AND DWORD PTR [EAX],0
    
  • Usare le impostazioni di ottimizzazione e i costrutti linguistici appropriati per evitare questa penalità delle prestazioni. Ad esempio, è possibile evitare l'ottimizzazione xor usando un puntatore volatile o ottimizzando la velocità del codice anziché le dimensioni del codice.
Le applicazioni sono incoraggiate a lasciare invariate le risorse mentre la CPU non li modifica e usa intervalli stretti e accurati in ogni momento. Ciò consente le modalità più veloci per gli strumenti, ad esempio Debug grafico e livello di debug. Tali strumenti devono tenere traccia di tutte le modifiche della CPU alla memoria che la GPU potrebbe leggere.

Modelli di utilizzo avanzati

Le risorse sugli heaps accessibili dalla CPU possono essere mappate in modo permanente, il che significa che la mappa può essere chiamata una sola volta, immediatamente dopo la creazione di risorse. Unmap non deve mai essere chiamato, ma l'indirizzo restituito da Map non deve più essere usato dopo il rilascio dell'ultimo riferimento alla risorsa. Quando si usa una mappa persistente, l'applicazione deve assicurarsi che la CPU finisca la scrittura dei dati in memoria prima che la GPU esegga un elenco di comandi che legge o scrive la memoria. Negli scenari comuni, l'applicazione deve semplicemente scrivere in memoria prima di chiamare ExecuteCommandLists; ma l'uso di un recinto per ritardare l'esecuzione dell'elenco di comandi funziona anche.

Tutti i tipi di memoria accessibili dalla CPU supportano l'utilizzo persistente del mapping, in cui la risorsa viene mappata, ma non viene mai annullata, se l'applicazione non accede al puntatore dopo l'eliminazione della risorsa.

Esempio

L'esempio D3D12Bundles usa ID3D12Resource::Map come indicato di seguito:

Copiare i dati del triangolo nel buffer del vertice.

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

Creare un heap di caricamento per i buffer costanti.

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

Fare riferimento al codice di esempio nel riferimento D3D12.

Requisiti

Requisito Valore
Piattaforma di destinazione Windows
Intestazione d3d12.h
Libreria D3D12.lib
DLL D3D12.dll

Vedi anche

ID3D12Resource

Sottorisorse

Unmap