ID3D12GraphicsCommandList::ResourceBarrier メソッド (d3d12.h)

リソースへの複数のアクセスを同期する必要があることをドライバーに通知します。

構文

void ResourceBarrier(
  [in] UINT                         NumBarriers,
  [in] const D3D12_RESOURCE_BARRIER *pBarriers
);

パラメーター

[in] NumBarriers

型: UINT

送信されたバリアの説明の数。

[in] pBarriers

型: const D3D12_RESOURCE_BARRIER*

バリアの説明の配列へのポインター。

戻り値

なし

解説

Note

D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE状態に使用するリソースは、その状態で作成し、その状態から切り替える必要はありません。 また、その状態で作成されたリソースが移行されることもありません。 詳細については、GitHub の DirectX レイトレーシング (DXR) 機能仕様の 「アクセラレーション構造のメモリ制限 」を参照してください。

バリアの説明には、次の 3 種類があります。

  • D3D12_RESOURCE_TRANSITION_BARRIER - 遷移バリアは、一連のサブリソースが異なる使用法間で遷移することを示します。 呼び出し元は、サブリソースの使用の前後を指定する必要があります。 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES フラグは、リソース内のすべてのサブリソースを同時に移行するために使用されます。
  • D3D12_RESOURCE_ALIASING_BARRIER - エイリアシング バリアは、同じヒープにマッピングされている 2 つの異なるリソースの使用間の遷移を示します。 アプリケーションでは、before リソースと after リソースの両方を指定できます。 一方または両方のリソースが NULL である可能性があることに注意してください (タイル化されたリソースがエイリアスを引き起こす可能性があることを示します)。
  • D3D12_RESOURCE_UAV_BARRIER - 順序なしのアクセス ビュー バリアは、将来の UAV アクセス (読み取りまたは書き込み) を開始する前に、特定のリソースへのすべての UAV アクセス (読み取りまたは書き込み) を完了する必要があることを示します。 指定したリソースは NULL である可能性があります。 UAV のみを読み取る 2 つの描画呼び出しまたはディスパッチ呼び出しの間に UAV バリアを挿入する必要はありません。 さらに、2 つの描画呼び出しまたはディスパッチ呼び出しの間に UAV バリアを挿入する必要はありません。この呼び出しは、アプリケーションが UAV アクセスを任意の順序で実行しても安全であると認識している場合は、同じ UAV に書き込みます。 リソースには NULL を指定できます (すべての UAV アクセスでバリアが必要になる可能性があることを示します)。
ID3D12GraphicsCommandList::ResourceBarrier にリソース バリアの説明の配列が渡されると、API は指定された順序で N 回 (配列要素ごとに 1) 呼び出されたかのように動作します。 移行は、パフォーマンスの最適化として、可能な場合は 1 つの API 呼び出しにまとめる必要があります。

サブリソースに含めることができる使用状況の状態の説明については、「D3D12_RESOURCE_STATES列挙」および「リソース バリアを使用したリソース状態の同期」セクションDirect3D 12参照してください。

リソース内のすべてのサブリソースは、 ID3D12GraphicsCommandList::D iscardResource が呼び出されたときに、レンダー ターゲット/深度ステンシル リソースのRENDER_TARGET状態またはDEPTH_WRITE状態である必要があります。

バック バッファーが表示される場合は、D3D12_RESOURCE_STATE_PRESENT状態である必要があります。 PRESENT 状態ではないリソースで IDXGISwapChain1::P resent1 が呼び出されると、デバッグ レイヤーの警告が生成されます。

リソース使用量ビットは、読み取り専用と読み取り/書き込みの 2 つのカテゴリにグループ化されます。

次の使用ビットは読み取り専用です。

  • D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER
  • D3D12_RESOURCE_STATE_INDEX_BUFFER
  • D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
  • D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
  • D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT
  • D3D12_RESOURCE_STATE_COPY_SOURCE
  • D3D12_RESOURCE_STATE_DEPTH_READ
次の使用ビットは読み取り/書き込みです。
  • D3D12_RESOURCE_STATE_UNORDERED_ACCESS
  • D3D12_RESOURCE_STATE_DEPTH_WRITE
次の使用ビットは書き込み専用です。
  • D3D12_RESOURCE_STATE_COPY_DEST
  • D3D12_RESOURCE_STATE_RENDER_TARGET
  • D3D12_RESOURCE_STATE_STREAM_OUT
最大 1 つの書き込みビットを設定できます。 書き込みビットが設定されている場合は、読み取りビットを設定できません。 書き込みビットが設定されていない場合は、任意の数の読み取りビットを設定できます。

サブリソースは、いつでも 1 つの状態になります (フラグのセットによって決定されます)。 アプリケーションは、 ResourceBarrier 呼び出しのシーケンスを行うときに、状態が一致していることを確認する必要があります。 言い換えると、 ResourceBarrier への連続した呼び出しの before と after の状態は一致する必要があります。

リソース内のすべてのサブリソースを切り替えるために、アプリケーションはサブリソース インデックスを D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES に設定できます。これは、すべてのサブリソースが変更されることを意味します。

パフォーマンスを向上させるには、アプリケーションで分割バリアを使用する必要があります ( 「マルチエンジン同期」を参照)。 アプリケーションでは、可能な限り複数の遷移を 1 つの呼び出しにバッチ処理する必要もあります。

ランタイム検証

ランタイムは、バリア型の値が D3D12_RESOURCE_BARRIER_TYPE 列挙体の有効なメンバーであることを検証します。

さらに、ランタイムは次を確認します。

  • リソース ポインターが NULL 以外です。
  • サブリソース インデックスが有効です
  • 前後の状態は、リソースの D3D12_RESOURCE_BINDING_TIER フラグと D3D12_RESOURCE_FLAGS フラグでサポートされます。
  • 状態マスク内の予約済みビットが設定されていません。
  • before と after の状態は異なります。
  • before 状態と after 状態のビットセットが有効です。
  • D3D12_RESOURCE_STATE_RESOLVE_SOURCE ビットが設定されている場合、リソース サンプル数は 1 より大きい必要があります。
  • D3D12_RESOURCE_STATE_RESOLVE_DEST ビットが設定されている場合、リソース サンプル数は 1 に等しい必要があります。
エイリアス バリアの場合、ランタイムは、いずれかのリソース ポインターが NULL 以外の場合、タイル化されたリソースを参照することを検証します。

UAV バリアの場合、ランタイムは、リソースが NULL 以外の場合、リソースに D3D12_RESOURCE_STATE_UNORDERED_ACCESS バインド フラグが設定されていることを検証します。

検証エラーが発生すると、 ID3D12GraphicsCommandList::Close がE_INVALIDARGを返します。

デバッグ レイヤー

デバッグ レイヤーは通常、ランタイム検証が失敗するエラーを発行します。
  • コマンド リスト内のサブリソース遷移が、同じコマンド リスト内の以前の遷移と矛盾している場合。
  • ResourceBarrier を最初に呼び出さずにリソースを使用して、リソースを正しい状態にした場合。
  • リソースが同時に読み取りと書き込みに不正にバインドされている場合。
  • ResourceBarrier に渡される before 状態が、以前の ResourceBarrier 呼び出しの after 状態と一致しない場合 (別名の大文字と小文字を含む)。
デバッグ レイヤーはランタイム ルールの検証を試みますが、デバッグ 層のエラーが実際のエラーになるように保守的に動作し、場合によっては実際のエラーによってデバッグ レイヤー エラーが発生しない可能性があります。

デバッグ レイヤーでは、次の場合に警告が発行されます。

  • D3D12 デバッグ レイヤーが ID3D12GraphicsCommandList::ResourceBarrier の警告を発行するすべてのケース。
  • リソースにD3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE使用ビットが設定されている間に、深度バッファーが読み取り専用以外のモードで使用される場合。

D3D12HelloTriangle サンプルでは、次のように ID3D12GraphicsCommandList::ResourceBarrier を使用します。

D3D12_VIEWPORT m_viewport;
D3D12_RECT m_scissorRect;
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D12Device> m_device;
ComPtr<ID3D12Resource> m_renderTargets[FrameCount];
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
ComPtr<ID3D12CommandQueue> m_commandQueue;
ComPtr<ID3D12RootSignature> m_rootSignature;
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
UINT m_rtvDescriptorSize;

void D3D12HelloTriangle::PopulateCommandList()
{
    // Command list allocators can only be reset when the associated 
    // command lists have finished execution on the GPU; apps should use 
    // fences to determine GPU execution progress.
    ThrowIfFailed(m_commandAllocator->Reset());

    // However, when ExecuteCommandList() is called on a particular command 
    // list, that command list can then be reset at any time and must be before 
    // re-recording.
    ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), m_pipelineState.Get()));

    // Set necessary state.
    m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
    m_commandList->RSSetViewports(1, &m_viewport);
    m_commandList->RSSetScissorRects(1, &m_scissorRect);

    // Indicate that the back buffer will be used as a render target.
    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));

    CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
    m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);

    // Record commands.
    const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
    m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
    m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
    m_commandList->DrawInstanced(3, 1, 0, 0);

    // Indicate that the back buffer will now be used to present.
    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));

    ThrowIfFailed(m_commandList->Close());
}

「D3D12 リファレンス」のコード例を参照してください

要件

   
対象プラットフォーム Windows
ヘッダー d3d12.h
Library D3d12.lib
[DLL] D3d12.dll

関連項目

ID3D12GraphicsCommandList

リソース バリアを使用して、Direct3D 12 のリソースの状態を同期する