6

現在マイクロソフトの例を調べていると、コマンドリストごとに cbv_srv_uav ヒープが 1 つしか使用されていないことがわかります (+ 追加のサンプラー ヒープ上にある可能性があります)。

CommandList ごとに複数のヒープを使用することは可能ですか?

だから私はヒープと範囲をセットアップします

this->mRSVHeap = new urd::DescriptorHeap(
    *this->mDevice,
    urd::DescriptorHeapType::CBV_SRV_UAV,
    1, // shader visible
    2); // space for 2 descriptors (2 textures)

this->mConstHeap = new urd::DescriptorHeap(
    *this->mDevice,
    urd::DescriptorHeapType::CBV_SRV_UAV,
    1, // shader visible
    1); // space for 1 descriptor

urd::DescriptorRange ranges[3];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); // first and second descriptor in rsv heap (t0, t1)
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // first descriptor in cbv heap (b0)
ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2); // same texture used as first range (again first descriptor in rsv, accessable by t2)

その後、記述子テーブルを定義します

rootParam[0].InitDescTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
rootParam[1].InitDescTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
rootParam[2].InitDescTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);

そのため、rsv ヒープの cpu オフセット 0 と 1 でテクスチャ 1 と 2 の shaderResourceViews を作成し、cbv ヒープの cpu オフセット 0 で定数バッファーの constantbufferview を作成します。

このような:

D3D12_CPU_DESCRIPTOR_HANDLE handle = this->ConstHeap->GetCPUDescriptorHandleForHeapStart();
handle.ptr += index * SIZE_OF_ONE_DESCRIPTOR_CBV_SRV_UAV_TYPE;
CreateConstantBufferView(&desc, handle)

コマンドリストにこれらのヒープを参照するように指示する時が来ました

ID3D12DescriptorHeap* ppHeaps[] = { this->mRSVHeap.Get(), this->mConstHeap.Get() };
this->mCommandList->GetRef()->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);

この後、コマンドリストを閉じると常にスローされます。

ThrowIfFailed(this->mCommandList->Close());

どのテーブルのどのヒープをコマンドリストに伝えるかを次に示します。

this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(0, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(1, this->mConstHeap->GetGPUHeapAddressAtOffset(0));
this->mCommandList->GetRef()->SetGraphicsRootDescriptorTable(2, this->mRSVHeap->GetGPUHeapAddressAtOffset(0));

すべてのオブジェクトを 1 つの記述子ヒープ (例のように) に記述し、そのヒープの異なるオフセットを使用するだけで問題なく動作します。

デバッグ出力:

D3D12 エラー: ID3D12CommandList::SetDescriptorHeaps: pDescriptorHeaps[1] は、pDescriptorHeaps 配列の前の方にある記述子ヒープ タイプを設定します。一度に設定できる記述子ヒープの種類は 1 つだけです。[実行エラー #554: SET_DESCRIPTOR_HEAP_INVALID] D3D12 エラー: CCommandList::SetGraphicsRootDescriptorTable: 現在コマンド リストに CBV_SRV_UAV 記述子ヒープが設定されていないため、CBV_SRV_UAV ハンドルのルート記述子テーブルの設定は無効です。[実行エラー #708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 エラー: CCommandList::SetGraphicsRootDescriptorTable: 現在コマンド リストに CBV_SRV_UAV 記述子ヒープが設定されていないため、CBV_SRV_UAV ハンドルのルート記述子テーブルの設定は無効です。[実行エラー #708: SET_DESCRIPTOR_TABLE_INVALID] D3D12 エラー: CCommandList::SetGraphicsRootDescriptorTable: 現在、コマンド リストに CBV_SRV_UAV 記述子ヒープが設定されていないため、CBV_SRV_UAV ハンドルのルート記述子テーブルの設定は無効です。[実行エラー #708: SET_DESCRIPTOR_TABLE_INVALID]

4

1 に答える 1

10

制限は、各タイプ (CBV/SRV/UAV およびサンプラー) のヒープを一度に 1 つだけ設定できることです。したがって、一度に設定できる記述子ヒープは 2 つだけです。

ただし、ディスクリプタ ヒープ セットは、コマンド リスト中に異なる可能性があることに注意することが重要です。

于 2015-08-21T16:38:39.943 に答える