ユーザ用ツール

サイト用ツール


d3d:d3d12:descriptor

RootSignature と Descriptor

Descriptor

リソースの情報を格納した構造体です。 GPU メモリに確保され、GPU が直接リソースを参照するために用いられます。

Descriptor を格納するメモリは DescriptorHeap から確保されます。 DescriptorHeap は GPU Memory に確保すると同時に System Memory にもミラーが作られ、CPU と GPU 両方からアクセスできるようになっています。

  1. Descriptor の作成時 : CreateShaderResourceView 等 (CPU の Descriptor Address)
  2. 描画時 : SetGraphicsRootDescriptorTable (GPU の Descriptor Address)

Descriptor が必要なリソースは下記の通り

  • ConstantBufferView
  • ShaderResourceView (Texture)
  • UnorderedAccessView
  • Sampler
  • RenderTargetView
  • DepthStencilView

Descriptor が消費する Heap のメモリ量は GPU によって異なります。下記の表の単位は byte です。

GPU FeatureLevel CBV_SRV_UAV SAMPLER RTV DSV
RADEON GCN 1.0 11_1 32 16 32 144
RADEON GCN 1.1 12_0 32 16 32 144
GeForce Kepler 11_0 32 32 32 8
GeForce Maxwell GM1 11_0 32 32 32 8
GeForce Maxwell GM2 12_1 32 32 32 8
Intel HD Graphics Gen7.5 11_1 32 16 32 96
Intel HD Graphcis Gen8 11_1 64 16 32 128

古い D3D11 世代の GPU では Descriptor Handle が仮想的な実装になっている可能性があります。

Descriptor Heap

CBV, SRV, UAV の Descriptor Heap は共有されています。

Descriptor HeapType Descriptor
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ConstantBufferView, ShaderResourceView, UnorderedAccessView
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER Sampler
D3D12_DESCRIPTOR_HEAP_TYPE_RTV RenderTargetView
D3D12_DESCRIPTOR_HEAP_TYPE_DSV DepthStencilView

つまり Shader に渡すパラメータ CBV, SRV, UAV は同じ Heap (Table) 上に並べてまとめて管理することができます。描画時に API に渡す場合一度に設定することができます。 一度の描画で参照できる DescriptorHeap は、HeapType 毎に 1 つだけなので注意が必要です。

ID3D12RootSignature

リソースとシェーダーの対応付けを行うための API である Parameter Slot を定義します。 また Slot に指定した Descriptor と Shader Register の対応付けも行います。

パラメータのレイアウトはアプリケーション側で自由に設計することが可能です。 RootSignature はいわばシェーダーに渡すパラメータ API がプログラマブルになったものと言えます。

初期の Shader Program と同じように、RootSignature には Slot サイズの上限があります。 現状では最大 64エントリ のみとなります。 なお Descriptor 自体はテーブルとして先頭アドレスを Slot に設定するだけなので、Descriptor の最大数には上限がありません。

RootSignature の各 Slot は下記のように Type に応じた Cost が設けられています。

  • Cost 1 : DescriptorTable
  • Cost 2 : Root Descriptor 直接
  • Cost 1 : Root 32bit Constant (32bit 単位で1、float4 なら Cost4 になる)

例えば RootSignature を ConstantBuffer の 32bit 直値だけで埋めるなら最大で 64個まで入ります。つまり float4x4 を 4つ分。

RootSignature は PipelineState 作成時に必要で、また描画時にも CommandList に設定します。 RootSignature は定義内容が一致していれば同一とみなされます。 PipelineState と CommandList に異なる Object を与えても問題ありません。

RootSignature は Shader と同じように hlsl に記述することが可能で、fxc を使ってバイナリ化できます。

RootSignature と API

Shader にパラメータを渡す方法は複数存在しています。 下記はそのまとめです。

Type Descriptor Heap 設定 API 描画時に設定する内容 Reg 設定個数 消費Cost
CBV CBV_SRV_UAV Descriptor Table CommandList::SetGraphicsRootDescriptorTable() 先頭の GPU Descriptor Handle b 複数 1
CBV - Root Descriptor CommandList::SetGraphicsRootConstantBufferView() Resource GPU Address b 1 2
CBV - Root Constants CommandList::SetGraphicsRoot32BitConstants() Constant Value b 1 1x個数
SRV CBV_SRV_UAV Descriptor Table CommandList::SetGraphicsRootDescriptorTable() 先頭の GPU Descriptor Handle t 複数 1
SRV - Root Descriptor CommandList::SetGraphicsRootShaderResourceView() Resource GPU Address t 1 2 Raw/Structured のみ
UAV CBV_SRV_UAV Descriptor Table CommandList::SetGraphicsRootDescriptorTable() 先頭の GPU Descriptor Handle u 複数 1
UAV - Root Descriptor CommandList::SetGraphicsRootUnorderedAccessView() Resource GPU ADdress u 1 2 Raw/Structured のみ
Sampler SAMPLER Descriptor Table CommandList::SetGraphicsRootDescriptorTable() 先頭の GPU Descriptor Handle s 複数 1
Sampler - Static Sampler Device::CreateRootSignature() s 複数 - 動的に変更できない
RTV RTV Descriptor Table CommandList::OMSetRenderTargets() CPU Descriptor Handle 複数 -
DSV DSV Descriptor Table CommandList::OMSetRenderTargets() CPU Descriptor Handle 1 -

CBV, SRV, UAV, Sampler いずれも Descriptor Table を使う方法、使わない方法両方用意されています。 ただし SRV, UAV は Root Descriptor の場合 Sampler を使うことができません。 よって事実上 Texture Map として用いる場合は Descriptor Table を使う必要があります。

CBV は上記のように、DescriptorTable を使う場合、直接 Root Descriptor に設定する場合、値を RootSignature (Root 32bit Constant) に直接格納する場合の 3通りの手段があります。どの方法を用いても構いません。

API による速度の違い

RootSignature を使って Shader にパラメータを渡す方法は複数存在しています。 実際に RootSignature の設計によってどの程度パフォーマンスに差が生じるか調べてみました。

Core i7-4790K Jaguar N3150
Intel GCN 1.0 Kepler Maxwell1Maxwell2 GCN1.1 Gen8
const32bit 18.33 9.88 11.26 8.25 13.35 14.80 36.61
root desc 18.24 14.39 10.00 7.48 13.40 17.45 36.74
global handle 18.44 11.70 9.00 8.06 12.80 15.48 33.74
buf shared 18.25 11.69 9.90 7.44 13.31 14.72 35.53
cached 10.76 11.70 13.50 12.60 12.51 10.48 21.20
Dynamic Heap 25.66 35.54 15.96 15.00 15.18 133.73 79.77
Shared RS 17.45 11.72 14.88 14.87 14.88 13.08 33.14
Separate RS 18.25 11.70 10.25 9.50 12.20 13.25 33.66
Bundle const32bit 18.67 9.00 8.75 9.87 35.50
Bundle root desc 20.55 9.66 9.66 9.90 36.96
Bundle copy 42.62 34.47 17.11 15.00 67.93
Bundle cached 20.35 8.23 8.41 9.90 35.22
Bundle2 21.26 28.28 15.36 15.28 15.50 90.24 66.38
d3d/d3d12/descriptor.txt · 最終更新: 2015/09/22 17:19 by oga