Share via


ID3D12Resource::Map 方法 (d3d12.h)

取得資源中指定子資源的CPU指標,但可能不會向應用程式揭露指標值。 對應 也會在必要時使CPU快取失效,讓CPU讀取至此位址時反映 GPU 所做的任何修改。

語法

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

參數

Subresource

類型: UINT

指定子資源的索引編號。

[in, optional] pReadRange

類型: const D3D12_RANGE*

描述要存取之內存範圍的 D3D12_RANGE 結構的指標。

這表示 CPU 可能讀取的區域,而且座標是子資源相對的。 Null 指標表示 CPU 可能會讀取整個子資源。 藉由傳遞 End 小於或等於 Begin 的範圍,指定 CPU 將不會讀取任何數據。

[out, optional] ppData

類型: void**

記憶體區塊的指標,可接收資源數據的指標。

Null 指標有效,而且對於 WriteToSubresource 之類的方法快取 CPU 虛擬位址範圍很有用。 當 ppData 不是 NULL 時,傳回的指標永遠不會由 pReadRange 中的任何值位移。

傳回值

類型: HRESULT

這個方法會傳回其中一個 Direct3D 12 傳回碼

備註

多個 線程可以安全地呼叫 Map 和 Unmap 。 支援巢狀 對應 呼叫,並且會計算 ref 計數。 對應的第一次呼叫 會配置資源的 CPU 虛擬位址範圍。 最後一次 呼叫 Unmap 會解除分配 CPU 虛擬位址範圍。 CPU 虛擬位址通常會傳回給應用程式;但操作具有未知版面配置之紋理的內容,會排除公開 CPU 虛擬位址。 如需詳細資訊 ,請參閱 WriteToSubresource 。 除非 Map 持續巢狀,否則應用程式無法依賴位址保持一致。

Map 傳回的指標不保證具有一般指標的所有功能,但大部分的應用程式都不會注意到一般使用方式的差異。 例如,具有WRITE_COMBINE行為的指標具有比WRITE_BACK行為更弱的CPU記憶體排序保證。 CPU 和 GPU 可存取的記憶體不保證會因為 PCIe 限制而共用相同的不可部分完成記憶體保證 CPU 具有。 使用柵欄進行同步處理。

地圖有兩個使用模型類別,簡單和進階。 簡單的使用模型會將工具效能最大化,因此建議應用程式使用簡單模型,直到應用程序證明需要進階模型為止。

簡單使用模型

應用程式應該保持上傳、DEFAULT 和 READBACK 的堆積類型抽象概念,才能合理地支援所有配接器架構。

應用程式應該避免 CPU 從 UPLOAD 堆積上的資源指標讀取,甚至不小心。 CPU 讀取將會運作,但在許多常見的 GPU 架構上非常緩慢,因此請考慮下列事項:

  • 請勿讓 CPU 從與D3D12_HEAP_TYPE_UPLOAD或具有D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE的堆積相關聯的資源讀取。
  • pData 點可使用PAGE_WRITECOMBINE配置至其中的記憶體區域,而且您的應用程式必須接受與這類記憶體相關聯的所有限制。
  • 即使下列 C++ 程式代碼可以從記憶體讀取並觸發效能負面影響,因為程式代碼可以擴充為下列 x86 元件程式代碼。

    C++ 程式代碼:

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

    x86 元件程式代碼:

    AND DWORD PTR [EAX],0
    
  • 使用適當的優化設定和語言建構來協助避免這種效能損失。 例如,您可以使用 變動 性指標或優化程式代碼速度,而不是程式代碼大小來避免 xor 優化。
建議應用程式在 CPU 不會修改資源時保持未對應的狀態,並隨時使用緊密、精確的範圍。 這可啟用工具的最快模式,例如 圖形偵錯 和偵錯層。 這類工具需要追蹤 GPU 可讀取之內存的所有 CPU 修改。

進階使用模型

CPU 可存取堆積上的資源可以持續對應,這表示在資源建立后立即呼叫 Map 一次。 Unmap 永遠不需要呼叫,但從 Map 傳回的地址在資源最後一次參考發行之後,就不能再使用。 使用永續性對應時,應用程式必須在 GPU 執行讀取或寫入記憶體的命令清單之前,確保 CPU 完成將數據寫入記憶體。 在常見的案例中,應用程式只需要寫入記憶體,才能呼叫 ExecuteCommandLists;但使用柵欄來延遲命令清單執行也正常運作。

所有可存取 CPU 的記憶體類型都支援持續性對應使用量,其中資源會對應,但永遠不會取消對應,前提是應用程式在處置資源之後不會存取指標。

範例

D3D12Bundles 範例使用 ID3D12Resource::Map,如下所示:

將三角形數據複製到頂點緩衝區。

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

建立常數緩衝區的上傳堆積。

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

請參閱 D3D12 參考中的範例程式代碼

規格需求

需求
目標平台 Windows
標頭 d3d12.h
程式庫 D3D12.lib
Dll D3D12.dll

另請參閱

ID3D12Resource

子資源

Unmap