C-WebGL: DirectX11バックエンドの計画
あまりにもIntelのVulkanが言うことを聞いてくれないので、ちょっとデバッグを諦めてDirectX11をターゲットすることに。。Vulkanに比べてDirectX11はかなりハイレベルなAPIなのでトラブルも少いんじゃないかと期待している。
更に、VulkanはOpenGL ES2に比べて制約が多いが、その制約の大半はDirectX由来なのでVulkanのために書いた Depth範囲変換 のようなシェーダパッチはそのまま流用できる。
DirectX12にはDXILという専用の中間言語が存在するものの、これはDirectX11では使用できないので、(MetalやWebGPUと同様、)一旦システムのシェーダコンパイラ D3DCompiler_47.dll
が受け入れるHLSLに変換し、バイトコードにコンパイルしてから使うことになる。( D3DCompilerのバージョン自体は大量にあって 超ややこしい。特に、UWPをサポートしていないWindows7ではシステム標準では含まれないため手動でインストールするか再配布する必要がある。
資料あつめ
前書いた
みたいな表を書きたい。DirectX11とか最後に触ったのが昔過ぎてまったく覚えてないんで。。
Vulkan Decoder Ring とか MSDNの移植チャプタ が参考になる。
DirectXは COM 風 のAPIを伝統的に採用しているため、たとえばGLで言うところの glDrawElements
はデバイスのメソッド ID3D11DeviceContext::DrawIndexed
となる。
DirectX11 ドキュメンテーションの目次 。 Vulkanと違って仕様書PDFが一本あったりしないので。。 よく探したらあった https://microsoft.github.io/DirectX-Specs/
描画系コマンド
WebGL | DirectX11 |
---|---|
cwgl_drawArrays, cwgl_drawElements | Draw, DrawIndexed |
cwgl_clear | ClearRenderTargetView, ClearDepthStencilView |
cwgl_readPixels | CopySubresourceRegion してから Map してコピー |
cwgl_renderbufferStorage , cwgl_checkFramebufferStatus | ID3D11RenderTargetView や ID3D11DepthStencilView を用意して OMSetRenderTargets で設定 |
cwgl_finish | なし |
cwgl_flush | Flush |
cwgl_generateMipmap | GenerateMips |
Vulkan同様、Clearはscissorやviewportを処理しない(常に全面クリア)。
固定機能の殆どは廃止されているが、generateMipmapに相当するGenerateMipsはDirectX11でも残っている。これはDirectX12で廃止された。
オブジェクト
DirectX11はResourceとViewを分離している。このため多くのGet/Set系インターフェースはViewの方を取ることになる。
WebGL | DirectX11 |
---|---|
Buffer | ID3D11Buffer |
Shader | ID3D11VertexShader, ID3D11PixelShader |
Program | なし |
Texture | ID3D11Texture2D と ID3D11SamplerState |
Renderbuffer | ID3D11RenderTargetView や ID3D11DepthStencilView |
VertexArrayObject | (エミュレートする) |
DirectXでは、事前にBufferの用途を確定させてからバッファを作成する必要がある。 CreateBuffer, D3D11_BIND_FLAG, How to: Create a Vertex Buffer, Index, Constant 。また、Constant bufferはGLES2には無いがVulkanやDirectX11では逆にdefault uniform
が存在しないため必要になる。