【日本語訳】Direct3D 12 概要 Part3:リソースバインド

Intelのブログに”Direct3D 12 Overview Part 3: Resource Binding“という記事が上がっています。

Direct3D 12に関してはMicrosoftがPowerPointと動画を公開していますが、文章による詳細な解説はほとんど見られません。このブログの記事はDirect3D 12の前情報としては貴重なものなので、日本語訳に挑戦しました。

が、筆者の英語力が致命的に低いため、ほとんど意味不明です……雰囲気だけ読み取ってもらえれば幸いです。修正歓迎。

なお、図は元の記事を参照してください。また、Part1/2については図を見れば大体内容が理解できるので、訳しません。

—–

Part2では、我々はPSO(Pipeline State Object)とハードウェアミスマッチのオーバーヘッドを削減することの利益について議論しました。
これから我々はリソースのバインドとD3D 12チームがこの分野でCPUオーバーヘッドを削減する計画をどう立てたかに移る。
この議論をするために、我々はD3D 11で使われたリソースバインディングモデルを迅速に批評する必要がある。
下図は、左側がD3D 12のPSOによるレンダーコンテクストの図で、右側がD3D 11のリソースバインディングモデルの図である。

(Render Context: Pipeline State Object (PSO))

各シェーダの右側を見ると、明示的なバインドポイントが見られる。
明示的なバインドモデルは、パイプライン内の各ステージが参照できる明確なリソースを持っている。
それらのバインドポイントはGPUメモリの中のリソースを次々に参照する。
それらはテクスチャになれ、レンダーターゲット、バッファ、UAV等になれる。
リソースバインディングはずっと前から存在していたが、実際はD3Dより前に来る。
このアイデアは、シーンの裏で複数のプロパティを取り扱うこととゲームが効率的に描画コマンドをサブミットするのを助けることである。
しかし、システムは3つの鍵の領域で多くのバインドの精査をすることが必要になる。
それらの領域と、D3DチームがD3D 12をどう最適化したかを見ていこう。

リソースハザード:

ハザードは通常、遷移(トランシジョン)である。レンダーターゲットからテクスチャへの移動のように。
仮にゲームがあるフレームを描画していて、シーンを取り巻く環境マップになる予定である。
ゲームが環境マップを描画し終えてそれをテクスチャとして使いたい。
この仕事の間、何かがレンダーターゲットとテクスチャのどちらかとしてバインドされた時、ランタイムとドライバの両方が追跡している。
もしそれらが永久に何かへ(訳注:レンダーターゲットとテクスチャの)両方にバインドされているのが見られるなら、最も古い設定がアンバインドされ、最も新しいものを尊重するだろう。
この方法はゲームが必要なだけスイッチでき、またソフトウェアスタックがシーンの裏でそのスイッチを管理する。
加えて、ドライバはレンダーターゲットをテクスチャとして使うためにGPUパイプラインをフラッシュしなければならない。
そうでなければ、GPUでピクセルを読む前に(訳注:描画結果を)リタイアさせなければ、一貫した状態を手に入れられない。
本質的に、ハザードは一貫したデータを保証するためにGPUに余計な仕事を要求する。
これは一例にすぎず、もちろん沢山の考えられる例が存在する。
簡単のため、我々はただこの例を使う。

D3D 12での他の機能と強化と同様に、ここの解決法はゲームにより多くの制御を与えることである。
なぜAPIとドライバが全てのこの仕事をしたりフレーム内の1つのポイントがあるときに追跡したりすべきなのか?
我々は、1つのリソースから他のリソースへ切り替えるところのおおよそ1秒間の60番目について話している。
リソースの遷移をゲームが作りたいとき、制御をゲームに返すことにより、全てのあのオーバーヘッドが削減され、コストは一度だけ払われ払われなければならない。
下にD3D 12で追加された実際のリソースバリアAPIを示す。

D3D12_RESOURCE_BARRIER_DESC Desc;
Desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
Desc.Transition.pResource   = pRTTexture;
Desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
Desc.Transition.StateBefore = D3D12_RESOURCE_USAGE_RENDER_TARGET;
Desc.Transition.StateAfter  = D3D12_RESOURCE_USAGE_PIXEL_SHADER_RESOURCE;
pContext->ResourceBarrier( 1, &Desc );

このAPIはいくぶん率直で、リソースを宣言してそのソースとターゲットとして使う宣言をする。
遷移についてランタイムとドライバの問い合わせの呼び出しが続く。
たくさんの条件付きロジックで描画するフレーム間をまたいて追跡されるものの代わりに、それは明示的なものとなる。
いくぶんかのゲームは既に知っている。
すべての追加のロジックを引き出すことの追加の利益で。
フレームあたり1回、あるいは遷移するのが必要な任意の周期でそれをする。

リソースの生存時間:

D3D 11(とそれ以前のバージョン)は呼び出しがキューされるように振る舞う。
呼び出しが作られたとき、ゲームはAPIが即座にその呼び出しを実行すると信じている。
しかし、それは違う。
全てが遅延され、GPUにより後になって実行されるコマンドのキューがある。
GPUとCPUの間でより良い並列性と効率性を出せるが、たくさんリファレンスカウントしたり追跡したりする。
すべてのこのカウントと追跡はCPUの労力が必要である。

これを直すため、ゲームがリソースの生存時間について明示的な制御を得る。
D3D 12はキューされたGPUの性質をもはや隠しておらず、ゲームはそれがあとで実装されるであろうコマンドのリストをサブミットすることを知る。
GPUの進捗を追跡するためにFence APIが追加された。
ゲームは(多分1フレームに1回)与えられたポイントでチェックでき、どのリソースがもう必要ないか見ることができ、そしてそのメモリを解放することができる。
代わりに、解放するための追加のロジックを使い続ける限りリソースを追跡し、メモリが不要になったときに解放する。

リソース常在管理:

GPUは大量のビデオメモリを使うことを好み、実際よく手に入る。
これはメモリのある程度を持つ外付けGPUでより問題になる。
そこで我々はコマンドの流れとしてページイン・ページアウトするもののリソース常在管理を持つ。
それが本当に単なるメモリ管理のときは、ゲームにとってそれは無制限のメモリがあるように見える。
もう一度、これはリファレンスカウントと追跡のコストに来る。

リソースの生存時間と同様に、ゲームはリソースの常在を超えて厳密な制御を得る。
D3D 11はOSのなかで常在カウントとコントロールフローを追跡する。
一般にゲームはリソースの集合を指す描画コマンドのひとつながりをすでに知っている。
D3D 12では、メモリにそれらを移動するためにゲームがOSへ明示的に問い合わせることができる。
後ほどコマンドが実行されたときは、ゲームがメモリから取り除かれたリソースを持つことができる。

状態反映:

1度上の3つのエリアが最適化されたら、(小さなパフォーマンス増加ではあるが)より効率を生み出せる4つ目の箇所が姿を現す。
バインドポイントが設定されたとき、ランタイムはゲームがパイプラインに何がバインドされているか見つけ出すためにあとでGetを呼び出せるのを追跡する。
バインドポイントは反映されるかコピーされる。
ミドルウェアのために物事を簡単にする機能が設計された。
だから、コンポーネント化されたソフトウェアは描画コンテクストの現在の状態の外を知ることができる。
一度リソースのバインドが最適化されたら、反映された状態のコピーはもう不要である。
だから、前の3つのエリアから取り除かれたフロー制御に加えて、状態の反映のためのGetも同様に取り除かれる。

これは改善に当てはまり、D3D 12のリソースのバインドの中で効率的である。
たくさんの撹乳が取り除かれている。
前もって必要な制御フローや追跡のロジックを必要とするリソースのバインドや、ランタイムとドライバでのリソースのsetとget。
すべてのそれはゲームに制御を返すことに味方して取り除かれている。
GPUのキューされた性質を隠すつもりはD3Dにはもはやない。
リソース管理の全てのそれらの粒度はゲームの中でそのように発生し、ゲーム開発者は次々に必要と思うだろう。

—–

ここまで

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中