S.F. Page

Programming,Music,etc...

Geforce 650 Ti Boostの DirectX11.1サポート度合を調べる

はじめに

前にも書いたように中古だが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をサポートしているとは言えない状況にあることがわかった。残念。。。