DeviceとSwapChain作成
-DirectX11編-
概要
DirectX11の初期化ではいくつかのDeviceやViewの初期化が必要です。 その中で最初に行う初期化が「Device作成」「SwapChain作成」です。 DirectX9ではDeviceがSwapChainの内容も内包していましたが、 DirectX11ではDeviceとSwapChainが分離しています。 作成は「D3D11CreateDeviceAndSwapChain」で同時に行うか 「CreateDevice」「CreateSwapChain」で別々に行います。 今回のサンプルではD3D11CreateDeviceAndSwapChainを使用しています。
サンプル
サンプルはここからダウンロードできます。 環境は以下の通りです。
VSのバージョン | DirectXのバージョン |
---|---|
VisualStudio 2017 | DirectX11 |
DeviceとSwapChainの作成
Device、SwapChainの作成は事前に設定を行ったデータが必要です。 設定するデータの項目は「DXGI_SWAP_CHAIN_DESC」「FeatureLevel」「ビデオアダプタ」です。 Deviceの設定で必要となる「ドライバタイプ」の概要も下に書いてあります。
DXGI_SWAP_CHAIN_DESC
DXGI_SWAP_CHAIN_DESCはIDXGISwapChainの設定を行うための構造体で、 SwapChainを作成するために必要な設定を行います。
型 | メンバ名 | 説明 |
---|---|---|
DXGI_MODE_DESC | BufferDesc | バックバッファの設定 (ウィンドウのサイズやフォーマット)を行う |
DXGI_SAMPLE_DESC | BufferSampleDesc | マルチサンプリングの設定を行う |
DXGI_USAGE | BufferUsage | バッファの使用方法の指定 |
UINT | BufferCount | スワップチェインのバッファ数 |
HWND | OutputWindow | 出力先ウィンドウハンドル |
BOOL | Windowed | ウィンドウモード or フルスクリーンモード |
DXGI_SWAP_EFFECT | SwapEffect | スワップエフェクトの指定 |
UINT | Flags | スワップチェインの設定フラグの指定 |
DXGI_MODE_DESC
DXGI_MODE_DESC構造体ではバックバッファの設定ができます。
型 | メンバ名 | 説明 |
---|---|---|
UINT | Width | バッファの横幅 |
UINT | Height | バッファの縦幅 |
DXGI_RATIONAL | RefresRate | リフレッシュレートの設定 リフレッシュレートの分母(Numerator)と 分子(Denominator)の設定ができる |
DXGI_FORMAT | Format | バッファーのフォーマット指定 |
DXGI_MODE_SCANLINE_ORDER | ScanlineOrdering | スキャンライン(走査線)の指定 |
DXGI_MODE_SCALING | Scaling | ウィンドウ描画時のスケーリングの指定 バックバッファのサイズ通りに描画したり ウィンドウサイズに合わせるなど指定可能 |
DXGI_SAMPLE_DESC
DXGI_SAMPLE_DESC構造体ではバックバッファのマルチサンプリングに関する設定を行うことができます。
型 | メンバ名 | 説明 |
---|---|---|
UINT | Count | 1ピクセルの色を決めるサンプリング数 |
UINT | Quality | サンプリングの品質(精度) |
ビデオアダプタ
ビデオアダプタ(グラフィックアダプタ)は使用するアダプタを指定することができます。 特に指定しない場合、nullptrを指定することで既定のアダプタが設定されます。
FeatureLevel
FeatureLevelはドライバの機能レベルを指しており、初期化時にレベルを指定します。 例えばDirectX11の機能を求める場合、D3D_FEATURE_LEVEL_11_1やD3D_FEATURE_LEVEL_11_0を 指定するとドライバがそのレベルの処理を行えるかどうかが分かります。
ドライバタイプ
描画をハードウェアかソフトウェアのどちらで行うかを指定します。 通常はハードウェアを指定するので「D3D_DRIVER_TYPE_HARDWARE」が指定します。
関数内容
内容 | ID3D11DeviceとIDXGISwapChain作成する また、ID3D11DeviceContextも作成され、 適応されたFeatureLevelも取得できる |
|
---|---|---|
戻り値 | 初期化の成否(HRESULT)が返る | |
引数の型 | 説明 | |
IDXGIAdapter* | 使用するディスプレイアダプタの指定 nullptrの場合既定のアダプタを使用する |
|
D3D_DRIVER_TYPE | 描画を行うドライバの指定 基本はハードウェア(D3D11_DRIVER_TYPE_HARDWEAR)を指定 |
|
HMODULE | ドライバの指定をソフトウェアにした場合にのみ指定が必要 それ以外はnullptr |
|
UINT | ランタイムレイヤのフラグ指定 デバッグ出力、シングルスレッドなど指定できる |
|
D3D_FEATURE_LEVEL* | FeatureLevelの指定 配列で指定することができるので 試したいバージョンを複数指定できる |
|
UINT | D3D_FEATURE_LEVELを指定した場合の配列の要素数 | |
UINT | DirectSDKのバージョン 11ならD3D11_SDK_VERSIONを指定 |
|
DXGI_SWAP_CHAIN_DESC* | 設定を行ったDXGI_SWAP_CHAIN_DESCの アドレス |
|
IDXGISwapChain** | 初期化が完了したIDXGISwapChainを 受け取るためのIDXGISwapChainの ポインタのアドレス |
|
ID3D11Device** | 初期化が完了したID3D11Deviceを 受け取るためのID3D11Deviceの ポインタのアドレス |
|
D3D_FEATURE_LEVEL* | 最終的に決定したD3D_FEATURE_LEVELを 取得するためのD3D_FEATURE_LEVELの アドレス |
|
ID3D11DeviceContext** | 作成されたID3D11DeviceContextを 受け取るためのID3D11DeviceContextの ポインタのアドレス |
サンプルコード
以下はサンプルプロジェクトから今回の説明文を抜粋したコードです。
bool DirectX::Init()
{
HWND window_handle = FindWindow(Window::ClassName, nullptr);
RECT rect;
GetClientRect(window_handle, &rect);
/*
DirectX11版PresentationParameter
バッファの数やサイズ、カラーフォーマット等を設定する
*/
DXGI_SWAP_CHAIN_DESC dxgi;
ZeroMemory(&dxgi, sizeof(DXGI_SWAP_CHAIN_DESC));
dxgi.BufferCount = 1; // バッファの数
dxgi.BufferDesc.Width = (rect.right - rect.left); // バッファの横幅
dxgi.BufferDesc.Height = (rect.bottom - rect.top); // バッファの縦幅
dxgi.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // カラーフォーマット
dxgi.BufferDesc.RefreshRate.Numerator = 60; // リフレッシュレートの分母
dxgi.BufferDesc.RefreshRate.Denominator = 1; // リフレッシュレートの分子
dxgi.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // バッファの使い方 Usage => 使用方法
dxgi.OutputWindow = window_handle; // 出力対象のウィンドウハンドル
dxgi.SampleDesc.Count = 1; // マルチサンプリングのサンプル数(未使用は1)
dxgi.SampleDesc.Quality = 0; // マルチサンプリングの品質(未使用は0)
dxgi.Windowed = true; // ウィンドウモード指定
D3D_FEATURE_LEVEL level;
// デバイス生成とスワップチェーン作成を行う
if (FAILED(D3D11CreateDeviceAndSwapChain(
nullptr, // ビデオアダプタ指定(nullptrは既定)
D3D_DRIVER_TYPE_HARDWARE, // ドライバのタイプ
nullptr, // D3D_DRIVER_TYPE_SOFTWARE指定時に使用
0, // フラグ指定
nullptr, // D3D_FEATURE_LEVEL指定で自分で定義した配列を指定可能
0, // 上のD3D_FEATURE_LEVEL配列の要素数
D3D11_SDK_VERSION, // SDKバージョン
&dxgi, // DXGI_SWAP_CHAIN_DESC
&m_SwapChain, // 関数成功時のSwapChainの出力先
&m_Device, // 関数成功時のDeviceの出力先
&level, // 成功したD3D_FEATURE_LEVELの出力先
&m_Context))) // 関数成功時のContextの出力先
{
return false;
}
return true;
}
Context
D3D11CreateDeviceAndSwapChainを使用するとレンダリング用のContextが作成されます。 このContextは描画コマンドの追加、送信などの処理を扱っています。 CPU側で追加された描画コマンドをGPU側に送信するのが主な役目です。 このContextには「Immediate」と「Deferred」の2種類があります。
Immediate
Immediateは生成したコマンドを即時実行します。 D3D11CreateDeviceAndSwapChainで作成した場合、Immediateで作成されます。
Deferred
Deferredは生成した描画コマンドをバッファにためておきます。 そして、実行命令を受けたらたまっていたコマンドを実行します。 Deferredはマルチスレッドによる描画処理に有効とされています。