次の方法で共有


ID3D12Resource::Map メソッド (d3d12.h)

リソース内の指定されたサブリソースへの CPU ポインターを取得しますが、ポインター値をアプリケーションに公開することはできません。 また、必要に応じて、このアドレスへの CPU 読み取りで GPU によって行われた変更が反映されるように、マップによって CPU キャッシュが無効になります。

構文

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 によって読み取られる可能性があることを示します。 EndBegin 以下の範囲を渡すことによって、CPU がデータを読み取らないことを指定することは有効です。

[out, optional] ppData

型: void**

リソース データへのポインターを受け取るメモリ ブロックへのポインター。

null ポインターは有効であり、 WriteToSubresource などのメソッドの CPU 仮想アドレス範囲をキャッシュするのに役立ちます。 ppData が NULL でない場合、返されるポインターは pReadRange 内の値によってオフセットされることはありません。

戻り値

型: HRESULT

このメソッドは、 Direct3D 12 リターン コードのいずれかを返します

注釈

マップマップ解除 は、複数のスレッドによって安全に呼び出すことができます。 入れ子になった マップ 呼び出しがサポートされ、参照カウントされます。 Map の最初の呼び出しでは、リソースの CPU 仮想アドレス範囲が割り当てられます。 Unmap の最後の呼び出しでは、CPU 仮想アドレス範囲の割り当てが解除されます。 CPU 仮想アドレスは通常、アプリケーションに返されます。しかし、不明なレイアウトでテクスチャの内容を操作すると、CPU 仮想アドレスが開示されません。 詳細については、 WriteToSubresource を参照してください。 Map が永続的に入れ子になっていない限り、アプリケーションはアドレスの一貫性に依存できません。

Map によって返されるポインターは、通常のポインターのすべての機能を備えているとは限りませんが、ほとんどのアプリケーションでは通常の使用の違いに気付くことはありません。 たとえば、WRITE_COMBINE動作を持つポインターの CPU メモリ順序の保証は、WRITE_BACK動作よりも低くなります。 CPU と GPU の両方からアクセスできるメモリは、PCIe の制限により、CPU が持つ同じアトミック メモリ保証を共有することは保証されません。 同期にはフェンスを使用します。

Map には、シンプルと高度の 2 つの使用モデル カテゴリがあります。 単純な使用モデルはツールのパフォーマンスを最大化するため、高度なモデルがアプリで必要であることが証明されるまで、アプリケーションは単純なモデルに従うことをお勧めします。

単純な使用モデル

アプリケーションは、すべてのアダプター アーキテクチャを適切にサポートするために、UPLOAD、DEFAULT、READBACK のヒープ型の抽象化を維持する必要があります。

アプリケーションは、誤ってアップロード ヒープ上のリソースへのポインターからの CPU 読み取りを回避する必要があります。 CPU 読み取りは機能しますが、多くの一般的な GPU アーキテクチャでは非常に遅いので、次の点を考慮してください。

  • D3D12_HEAP_TYPE_UPLOADまたはD3D12_CPU_PAGE_PROPERTY_WRITE_COMBINEを持つヒープに関連付けられているリソースから CPU を読み取らないでください。
  • pData ポイントがPAGE_WRITECOMBINEで割り当てることができるメモリ領域。アプリでは、そのようなメモリに関連付けられているすべての制限を遵守する必要があります。
  • 次の C++ コードでもメモリから読み取り、パフォーマンスの低下を引き起こす可能性があります。これは、コードが次の x86 アセンブリ コードに拡張される可能性があるためです。

    C++ コード:

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

    x86 アセンブリ コード:

    AND DWORD PTR [EAX],0
    
  • このパフォーマンスの低下を回避するには、適切な最適化設定と言語コンストラクトを使用します。 たとえば、 揮発性 ポインターを使用するか、コード サイズではなくコード速度を最適化することで、xor の最適化を回避できます。
アプリケーションは、CPU が変更せず、常に厳密で正確な範囲を使用する一方で、リソースをマップ解除しておくことを推奨します。 これにより、 グラフィックス デバッグ やデバッグ レイヤーなどのツールの最速モードが可能になります。 このようなツールでは、GPU が読み取ることができるメモリに対するすべての CPU 変更を追跡する必要があります。

高度な使用モデル

CPU アクセス可能なヒープ上のリソースは永続的にマップできます。つまり、 リソース の作成直後に Map を 1 回呼び出すことができます。 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 リファレンスのコード例を参照してください。

Requirements

Requirement 価値
ターゲット プラットフォーム ウィンドウズ
Header d3d12.h
Library D3D12.lib
DLL D3D12.dll

こちらも参照ください

ID3D12Resource

サブリソース

マップ解除