ここぷろ!

私がプログラミングで学んだこと、行き詰った事などを書いていきます。たまに個人的なことも載せるかも

【DirectX12】コマンドアロケータの作成【初期化】


 こんにちは、ここあです。
 今回はコマンドアロケータの作成と、コマンドアロケータで使うことの出来るBundleについて解説をしていきます。

Library & Includes

#include <d3dx12.h>
#pragma comment(lib, "d3d12.lib")
#include <dxgi1_4.h>
#pragma comment(lib, "dxgi.lib")
#include <D3Dcompiler.h>
#pragma comment(lib, "d3dcompiler.lib")
#include <DirectXMath.h>

using Microsoft::WRL::ComPtr;
using namespace DirectX;

コマンドアロケータの作成

コマンドアロケータとは

 コマンドアロケータは、コマンドリストに格納する命令の為のメモリを管理するオブジェクトです。
 
 命令の割り当てられたメモリは、その命令の実行が終わるまで開放することが出来ません
 コマンドリスト単位で見ると「命令の実行が終わる」のは、基本的に「フレームバッファへの描画が完了」したことを指します。
 つまり描画中のメモリは、命令の実行が終わっていない為、コマンドリストの作成に使えません
 なので通常は、最低でもフレームバッファと同じ数だけ、コマンドアロケータの作成をします。

CreateCommandAllocator関数

 コマンドアロケータの作成には、ID3D12Device::CreateCommandAllocator関数を使います。

ID3D12Device::CreateCommandAllocator method | Microsoft Docs

  • CreateCommandAllocator関数
    • 第1引数:コマンドアロケータの種類
    • 第2引数:各インタフェース固有のGUID
    • 第3引数:ID3D12CommandAllocatorインタフェースのポインタを格納する変数のアドレス
  • 補足説明
    • 第1引数:コマンドリストと違い、BUNDLEを含めた全ての種類を指定可能

第2、第3引数は、IID_PPV_ARGSマクロを使うことで簡易的に受け渡しが可能。
 

事前定義
const UINT FRAME_COUNT = 2;

ComPtr<ID3D12Device> g_device;
ComPtr<ID3D12CommandAllocator> g_commandAllocator[FRAME_COUNT]
実装
for (int i = 0; i < FRAME_COUNT ; ++i) {
    if (FAILED(g_device->CreateCommandAllocator(
        D3D12_COMMAND_LIST_TYPE_DIRECT,
        IID_PPV_ARGS(&g_commandAllocator[i])))) {
        return false;
    }
}

D3D12_COMMAND_LIST_TYPE_BUNDLE

Bundleとは

 日本語で言うと、束。
 その名の通り、これは小さなコマンドリストを表します。
 Bundleには、事前にコマンドを積んでおくことが出来て、コマンドリストから何度も使用可能です。

Bundleを使う際の注意点

  • Bundleによって参照されるすべてのパイプラインステートオブジェクトは、以下のそれぞれが同一でなければならない
    • レンダーターゲットのフォーマット
    • 深度バッファのフォーマット
    • サンプル
  • D3D12_COMMAND_LIST_TYPE_BUNDLE で生成されたコマンドリスト上で、以下のコマンドリストAPIの呼び出しは許可されない
    • すべての Clear メソッド
    • すべての Copy メソッド
    • DiscardResource
    • ExecuteBundle
    • ReosolveSubresource
    • SetPredication
    • BeginQuery
    • EndQuery
    • SOSetTargets
    • OMSetRenderTargets
    • RSSetViewports
    • RSSetScissorRects
  • SetDescriptorHeap は、Bundle上で呼び出し可能だが、バンドルディスクリプタヒープ呼び出し元のコマンドリストディスクリプタヒープと一致する必要がある。


 これらのAPIがコールされた場合、ランタイムはコールを取りやめるらしいので、使う際は注意しましょう。


終わりに

 お疲れ様でした。
 コマンドアロケータで使用できるBundleについても、少し詳しく解説をしました。
 DirectX12で新しく追加された機能なので、私も勉強してちゃんと使えるようになる予定です。

 解説が間違っていたり、より良い方法などがあった場合は教えて頂けるとありがたいです。

 次回はコマンドリストの作成について解説していきます。


 それでは、今回はこの辺りで。

github.com