Monday, February 27, 2017

[DX11] DXGI_FORMAT_R32_TYPELESSのTYPELESSとは?

CreateTexture2DでDXGI_FORMAT_D32_FLOAT型のデプスバッファを作る時に以下のようなエラーが発生する場合、DXGI_FORMAT_D32_FLOATの代わりにDXGI_FORMAT_R32_TYPELESSを指定してエラーを回避できます。

D3D11 ERROR: ID3D11Device::CreateTexture2D: The format (0x28, D32_FLOAT) cannot be bound as a ShaderResource or cast to a format that could be bound as a ShaderResource. Therefore this format cannot support D3D11_BIND_SHADER_RESOURCE.  Specifiying the format R32_TYPELESS instead would solve this issue.  [ STATE_CREATION ERROR #92: CREATETEXTURE2D_UNSUPPORTEDFORMAT]

つまり、デプスバッファとしてレンダリングに使った後、SRVとしてシェーダから参照させたいならCreateTexture2Dの時はDXGI_FORMAT_R32_TYPELESSにしなければいけません。そして、そのテクスチャからSRVとDSVを作る場合、CreateShaderResourceViewにはDXGI_FORMAT_R32_FLOAT、CreateDepthStencilViewにはDXGI_FORMAT_D32_FLOATをそれぞれ指定します。

おそらく、DSVとSRVをそれぞれD32、R32として作るのでCreateTexture2Dではテクスチャを型が未定のストレージと規定して齟齬が起こらないようにする意図と思われます。

Thursday, February 2, 2017

6年前のNVIDIA Direct3D SDK 11を今の環境でコンパイルする

NVIDIAの"Direct3D SDK 11"はIsland11を始めとした良質なサンプルのソースコードが入っているので時々いじってみたくなります。しかし古いサンプルなので、Visual Studio 2015とWindows 10でコンパイル+実行するには一手間掛ける必要があります。


ソリューション内の各プロジェクトに以下の変更を行います。

  • *.fx, *.hlslはプロジェクトから除外しておきます。(Removeで除外、あるいはExcluded From Build設定)VS2015はこれらがプロジェクトにあるとコンパイルしようとしますが、シェーダーバイナリを使うプロジェクトがないのでその必要はありません。
  • ConfigrationをDebugにするとd3dx11effectsd.libが無いと言われてビルドできません。'd'の無いd3dx11effects.libはNVIDIA Corporation\NVIDIA Direct3D SDK 11\Libの下にあり、Releaseにしておくとリンクできます。参考:https://www.gamedev.net/topic/602742-getting-nvidia-sdk-samples-to-compile/
  • Additional Include Directoriesに;%DXSDK_DIR%\Includeを追加
  • Additional Library Directoriesに;%DXSDK_DIR%\Lib\x86を追加
  • __vsnwprintfが無いと言われるので、Additional Dependenciesにlegacy_stdio_definitions.libを追加
  • Treat Warnings As ErrorsはNoにしておきます。DXGI_*系のマクロがWindowsSDKに取り込まれた結果、再定義されたと警告が出るようです。又は、C4005警告をDisable Specific Warningsに入れてもいいのですが、これ以外にも警告が多いので一括で許可したほうが簡単です。
  • TerrainTessellation.cppで、powfとstd::maxのコンパイルが出来ないので、#include <algorithm>を追加
ただ、プロジェクトの数が多いので、一つ一つ設定するのは大変です。そこで、少々乱暴ですが以下のようにします。

  • C:\ProgramData\NVIDIA Corporation\NVIDIA Direct3D SDK 11\Include\DXUT\Core にDirectX SDKのヘッダファイルを入れてしまう。
  • C:\ProgramData\NVIDIA Corporation\NVIDIA Direct3D SDK 11\Lib にも同様に C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86 からライブラリファイルを持ってくる。
  • NVIDIA Direct3D SDK 11\Include\DXUT\Core\DXUT.hに、以下の行を追加する。
    #pragma comment(lib,"legacy_stdio_definitions.lib")
    #pragma warning(disable:4005)
これで、大部分のプロジェクトはHLSLファイルを除外するだけでビルドに成功するようになります。

更に、Debugでビルドするには、d3dx11effectsd.lib、dxutd.lib、dxutoptd.libといった、いくつかのライブラリが存在しておらずリンクできません。これは、DirectX SDKのSamplesフォルダに含まれるいくつかのプロジェクトをDebugでビルドしたものです。ビルドしたlibファイルをNVIDIA SDKの下のLibフォルダに置けばリンクできるのですが、NVIDIAの開発者がファイル名をリネームして使っているようです。
  • Samples\C++\DXUT11\Core\DXUT_2010.slnからDXUT.libが出来ますが、DXUTd.libにリネームします。
  • Samples\C++\DXUT11\Core\DXUTOpt_2010.slnからDXUTOpt.libが出来ますが、DXUTOptd.libにリネームします。
  • Effects11_2010.slnをビルドしようとすると、static void* __cdecl operator new(size_t s, CDataBlockStore &pAllocator) という関数がERROR C2323"non-member operator new and delete functions may not be declared inline"というエラーになります。これは、staticをinlineに変更するとコンパイルできます。Effects11.libというファイルが出来ますが、d3dx11effectsd.libにリネームします。
これらのslnファイルはProgram Filesの下にあり、Windows10環境で開くと"Do you want to restart the application with elevated permissions?"と、Visual Studio 2015から権限上昇を求めるダイアログが開きます。"Restart this application under different credentials"を押してコンパイルするか、該当のプロジェクトをユーザー権限でコンパイル出来る場所にコピーしてからコンパイルします。