はじめに
前にも書いたように中古だがGeforce 650GTX Ti Boostにビデオカードをアップデートした。DirectX11.1対応をうたっているけどもDxDiagで調べると機能レベルは「11.0」までと表示される。
なんか11.1サポートしているかしていないかのかいまいちよくわからないのでID3D11Device::CheckFeatureSupport メソッドで調べてみた。ついでに11.2も調べてみた。
ID3D11Device::CheckFeatureSupport
Direct3DではGPUの能力を調べるためにCAPSビットを細かく調べる必要があったのだが、DX10からだったと思うがCAPSビットで能力を調べる方法は廃止になり、機能レベル「Feature Level」を調べるだけでよくなったのだが、DX11からだったと思うがID3D11Device::CheckFeatureSupportによりまた細かく機能が調査できるようになった。今回はこれを使って機能サポート具合を調べてみる。
調査するのに書いたコードは下記のとおりである。なおピクセルフォーマットのサポートチェックは行っていない。
void GameRenderer::DisplaySupportFeatures()
{
OutputDebugStringW(L"########## Support Features ##########\n");
D3D11_FEATURE_DATA_THREADING threading;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_THREADING, &threading, sizeof(D3D11_FEATURE_DATA_THREADING));
DOUT2((boost::wformat(L"DriverConcurrentCreates:描画中も継続的して複数のスレッドでリソースを作成できるかどうか。: %s \n") % (threading.DriverConcurrentCreates ? L"True" : L"False")));
DOUT2((boost::wformat(L"DriverCommandLists:コマンドリストが利用可能であるか。遅延レンダリングが可能かどうか。: %s \n") % (threading.DriverCommandLists ? L"True" : L"False")));
D3D11_FEATURE_DATA_DOUBLES doubles;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_DOUBLES, &doubles, sizeof(D3D11_FEATURE_DATA_DOUBLES));
DOUT2((boost::wformat(L"DoublePrecisionFloatShaderOps:double型が利用できるかどうか: %s \n") % (doubles.DoublePrecisionFloatShaderOps ? L"True" : L"False")));
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS d3d10_x_hardware_options;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &d3d10_x_hardware_options, sizeof(D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS));
DOUT2((boost::wformat(L"ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x:生バッファかつ構造化バッファをサポートしているか: %s \n") % (d3d10_x_hardware_options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ? L"True" : L"False")));
OutputDebugStringW(L"########## 11.1 ##########\n");
D3D11_FEATURE_DATA_D3D11_OPTIONS options;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
DOUT2((boost::wformat(L"ClearView:: %s \n") % (options.ClearView ? L"True" : L"False")));
DOUT2((boost::wformat(L"ConstantBufferOffsetting:: %s \n") % (options.ConstantBufferOffsetting ? L"True" : L"False")));
DOUT2((boost::wformat(L"ConstantBufferPartialUpdate:: %s \n") % (options.ConstantBufferPartialUpdate ? L"True" : L"False")));
DOUT2((boost::wformat(L"CopyWithOverlap:: %s \n") % (options.CopyWithOverlap ? L"True" : L"False")));
DOUT2((boost::wformat(L"DiscardAPIsSeenByDriver:: %s \n") % (options.DiscardAPIsSeenByDriver ? L"True" : L"False")));
DOUT2((boost::wformat(L"ExtendedDoublesShaderInstructions:: %s \n") % (options.ExtendedDoublesShaderInstructions ? L"True" : L"False")));
DOUT2((boost::wformat(L"ExtendedResourceSharing:: %s \n") % (options.ExtendedResourceSharing ? L"True" : L"False")));
DOUT2((boost::wformat(L"FlagsForUpdateAndCopySeenByDriver:: %s \n") % (options.FlagsForUpdateAndCopySeenByDriver ? L"True" : L"False")));
DOUT2((boost::wformat(L"MapNoOverwriteOnDynamicBufferSRV:: %s \n") % (options.MapNoOverwriteOnDynamicBufferSRV ? L"True" : L"False")));
DOUT2((boost::wformat(L"MapNoOverwriteOnDynamicConstantBuffer:: %s \n") % (options.MapNoOverwriteOnDynamicConstantBuffer ? L"True" : L"False")));
DOUT2((boost::wformat(L"MultisampleRTVWithForcedSampleCountOne:: %s \n") % (options.MultisampleRTVWithForcedSampleCountOne ? L"True" : L"False")));
DOUT2((boost::wformat(L"OutputMergerLogicOp:出力マージャーで論理演算が可能かどうか: %s \n") % (options.OutputMergerLogicOp ? L"True" : L"False")));
DOUT2((boost::wformat(L"SAD4ShaderInstructions:: %s \n") % (options.SAD4ShaderInstructions ? L"True" : L"False")));
DOUT2((boost::wformat(L"UAVOnlyRenderingForcedSampleCount:: %s \n") % (options.UAVOnlyRenderingForcedSampleCount ? L"True" : L"False")));
D3D11_FEATURE_DATA_ARCHITECTURE_INFO architecture;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_ARCHITECTURE_INFO, &architecture, sizeof(D3D11_FEATURE_DATA_ARCHITECTURE_INFO));
DOUT2((boost::wformat(L"TileBasedDeferredRenderer:: %s \n") % (architecture.TileBasedDeferredRenderer ? L"True" : L"False")));
D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT min_precision;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, &min_precision, sizeof(D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT));
DOUT2((boost::wformat(L"AllOtherShaderStagesMinPrecision:: %s \n") % (min_precision.AllOtherShaderStagesMinPrecision ? L"True" : L"False")));
DOUT2((boost::wformat(L"PixelShaderMinPrecision:: %s \n") % (min_precision.PixelShaderMinPrecision ? L"True" : L"False")));
D3D11_FEATURE_DATA_D3D9_OPTIONS d3d9_options;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D9_OPTIONS, &d3d9_options, sizeof(D3D11_FEATURE_DATA_D3D9_OPTIONS));
DOUT2((boost::wformat(L"FullNonPow2TextureSupport:: %s \n") % (d3d9_options.FullNonPow2TextureSupport ? L"True" : L"False")));
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT d3d9_shadow;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D9_SHADOW_SUPPORT, &d3d9_shadow, sizeof(D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT));
DOUT2((boost::wformat(L"SupportsDepthAsTextureWithLessEqualComparisonFilter:: %s \n") % (d3d9_shadow.SupportsDepthAsTextureWithLessEqualComparisonFilter ? L"True" : L"False")));
OutputDebugStringW(L"########## 11.2 ##########\n");
D3D11_FEATURE_DATA_D3D11_OPTIONS1 d3d11_options1;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS1, &d3d11_options1, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS1));
DOUT2((boost::wformat(L"ClearViewAlsoSupportsDepthOnlyFormats:: %s \n") % (d3d11_options1.ClearViewAlsoSupportsDepthOnlyFormats ? L"True" : L"False")));
DOUT2((boost::wformat(L"MapOnDefaultBuffers:: %s \n") % (d3d11_options1.MapOnDefaultBuffers ? L"True" : L"False")));
DOUT2((boost::wformat(L"MinMaxFiltering:: %s \n") % (d3d11_options1.MinMaxFiltering ? L"True" : L"False")));
DOUT2((boost::wformat(L"TiledResourcesTier:: %s \n") % (d3d11_options1.TiledResourcesTier ? L"True" : L"False")));
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT d3d9_simple_instancing;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT, &d3d9_simple_instancing, sizeof(D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT));
DOUT2((boost::wformat(L"SimpleInstancingSupported:: %s \n") % (d3d9_simple_instancing.SimpleInstancingSupported ? L"True" : L"False")));
D3D11_FEATURE_DATA_MARKER_SUPPORT marker;
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_MARKER_SUPPORT, &marker, sizeof(D3D11_FEATURE_DATA_MARKER_SUPPORT));
DOUT2((boost::wformat(L"Profile:: %s \n") % (marker.Profile ? L"True" : L"False")));
}
実行結果は下記のとおりである。
########## Support Features ########## DriverConcurrentCreates:描画中も継続的して複数のスレッドでリソースを作成できるかどうか。: True DriverCommandLists:コマンドリストが利用可能であるか。遅延レンダリングが可能かどうか。: True DoublePrecisionFloatShaderOps:double型が利用できるかどうか: True ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x:生バッファかつ構造化バッファをサポートしているか: True ########## 11.1 ########## ClearView:: True ConstantBufferOffsetting:: True ConstantBufferPartialUpdate:: True CopyWithOverlap:: True DiscardAPIsSeenByDriver:: True ExtendedDoublesShaderInstructions:: True ExtendedResourceSharing:: True FlagsForUpdateAndCopySeenByDriver:: True MapNoOverwriteOnDynamicBufferSRV:: True MapNoOverwriteOnDynamicConstantBuffer:: True MultisampleRTVWithForcedSampleCountOne:: True OutputMergerLogicOp:出力マージャーで論理演算が可能かどうか: True SAD4ShaderInstructions:: True UAVOnlyRenderingForcedSampleCount:: True TileBasedDeferredRenderer:: False AllOtherShaderStagesMinPrecision:: False PixelShaderMinPrecision:: False FullNonPow2TextureSupport:: True SupportsDepthAsTextureWithLessEqualComparisonFilter:: True ########## 11.2 ########## ClearViewAlsoSupportsDepthOnlyFormats:: False MapOnDefaultBuffers:: False MinMaxFiltering:: False TiledResourcesTier:: False SimpleInstancingSupported:: True Profile:: False
まあおおむねサポートしているようだ。さすがに11.2の機能はサポートしていないようだが。
Fermi and Kepler DirectX API Support
NVIDIAサポートページの記事「Fermi and Kepler DirectX API Support」にDirectX11.1のサポート状況について書いてあった。ここにまさに知りたいことが書いてあった。 KeplerGPU世代はDirectX11.1 が必要とされる機能をサポートしていなので、「D3D_FEATURE_LEVEL_11_1」を満たせず、「D3D_FEATURE_LEVEL_11_0」となってしまうとのことだ。 その機能とは何かというと
- UAVOnlyRenderingForcedSampleCount supports 16x raster coverage sampling
- TIR - aliased color-only rendering with up to 16x raster coverage sampling
である。これらの2つの機能はDirect2Dの描画をアクセラレーションするための機能で、NVIDIAとしては3Dの機能に注力したかったのでこの2つの機能は見送ったとのこと。あと11.1の目玉ともいえる「UAVを頂点・ジオメトリ・テッセレーションステージでも利用可能にする」という機能はサポートしているけれども、この機能はD3D_FEATURE_LEVEL_11_1で公開される機能のため、D3D_FEATURE_LEVEL_11_0となってしまう現在は利用できないとのこと。将来的にはアプリ固有機能として利用可能にするそうである。「アプリ固有機能」とは何のことかよくわからないけれども、残念ながらGeforce6XX世代はDirectX11.1をサポートしているとは言えない状況にあることがわかった。残念。。。