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_SWAP_CHAIN_DESC構造体メンバ
メンバ名 説明
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構造体ではバックバッファの設定ができます。

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構造体ではバックバッファのマルチサンプリングに関する設定を行うことができます。

DXGI_MODE_DESC構造体メンバ
メンバ名 説明
UINT Count 1ピクセルの色を決めるサンプリング数
UINT Quality サンプリングの品質(精度)
もし、マルチサンプリングを使用しない場合は、Countに1、Qualityに0を指定します。

ビデオアダプタ

ビデオアダプタ(グラフィックアダプタ)は使用するアダプタを指定することができます。
特に指定しない場合、nullptrを指定することで既定のアダプタが設定されます。

FeatureLevel

FeatureLevelはドライバの機能レベルを指しており、初期化時にレベルを指定します。
例えばDirectX11の機能を求める場合、D3D_FEATURE_LEVEL_11_1やD3D_FEATURE_LEVEL_11_0を
指定するとドライバがそのレベルの処理を行えるかどうかが分かります。

ドライバタイプ

描画をハードウェアかソフトウェアのどちらで行うかを指定します。
通常はハードウェアを指定するので「D3D_DRIVER_TYPE_HARDWARE」が指定します。

関数内容

D3D11CreateDeviceAndSwapChain
内容 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はマルチスレッドによる描画処理に有効とされています。