NEUROMANTIC

自分でC/C++/UE4/Graphics/ゲームなどをやったことをメモするブログ

Primitive ShaderとかMesh Shaderとかを調べてみた。

今のGPUそしてグラフィックスで通用されているシェーダーレンダリングのパイプラインを纏めると以下になりそうです。

レンダリングパイプライン 独立パイプライン
~OpenGL 3.0 固定パイプライン なし
~OpenGL 4.0 VS > GS > FS なし
OpenGL 4.0~ VS > TCS > TES > GS > FS Compute
DX9 VS > FS (PS) なし
DX10 VS > GS > FS (PS) なし
DX11, 12 VS > HS > DS > GS > PS Compute

元々はVertex Shader(頂点シェーダー)とFragment (Pixel) Shaderしかなかったのですが、GSを始めラスタライズ以前に頂点をいじれるシェーダーステージが入りながらちょっとコントロールがしにくくなったそうです。

そしてこのTCS、GS、TES(HS、DS)の付加ステージはEarly Depth TestingみたいなGPUが素早くレンダリングするための最適化または技法を使えなくなる可能性を上げるそうです。 また、このステージ自体は無理やり入れ込んだものとしてGPUとは相性がうまく合わないらしいです。

GSを例として短く話せば、GPUのスレッドはWARPというものとして団体的に動くようになっていますね。 しかしこの3つのステージで何かを追加したり削除することにより、バッファを捨てられなくなるとか、スレッドグループをまた取り直さなければならなくなる、ということによって性能が落ちる恐れもあるということです。 (INTELではこういう性能落ちを防ぐようにハードウェアの最適化を行います。)

で、こういう問題を解決するためNVさんとAMDさんが最近(~3年)新しいシェーダーパイプラインを発表し始めました。こういうことを気付いたのは1ヶ月前からなんだったんですが、自分的にちょっとまとめて記事で上げたかったですので書いてみました。不正確であるかもしれませんが、ご了承ください

Primitive Shader

f:id:neuliliilli:20190425222225p:plain

AMDのVegaシリーズGPUから開発が始まったと言われる、Primitive Shaderという物があります。これを使用してレンダリングをすると、既存のシェーダーを使って頂点の深度テストかあらゆる作業を行うより最大2倍の性能が上がるそうです。

Primitive ShaderはVSはGSを合わせたものとして、VSとGSの機能を行うが複雑でなく性能が秀でるらしいです。ただしこのシェーダーを使うには既存のグラフィックスのAPIから支援しなければなりません。OpenGLでの支援は多分しないかもしれませんが、VulkanかD3D12のバージョンアップデートで支援出来ることがあるでしょうね。

  • Primitive Shaderを用いて、既存の非効率的なWorld-space pipelineを効率化していること。
  • ハードウェアからのPrimitiveのZテストをさせて、素早くレンダリング出来るようにしたこと。

Task Shader / Mesh Shader

f:id:neuliliilli:20190425225557p:plain

NVはTuringアーキテクチャから、Mesh Shaderという新たなグラフィックスシェーダーパイプラインを発表し、実装しました。Mesh Shaderというのは、既存では分離されていたCompute Shaderの仕組みを頂点レンダリングに溶け込んで、もっと素早くレンダリングさせるようにするものだそうです。

大きなメッシュをレンダリングする時に、一気にレンダリングせずにハードウェアから演算を行ってMeshletsというConvexな小さなメッシュを生成しレンダリングします。

...The mesh shader stage produces triangles for the rasterizer, but uses a cooperative thread model internally instead of using a single-thread program model, similar to compute shaders. Ahead of the mesh shader in the pipeline is the task shader. The task shader operates similarly to the control stage of tessellation, in that it is able to dynamically generate work. However, like the mesh shader, it uses a cooperative thread model and instead of having to take a patch as input and tessellation decisions as output, its input and output are user defined.

  • Task Shader:テセレーションのHSに似ているが、もっと動的に頂点をいじることが出来る。そしてInputとOutputはテセレーションで指定されたものだけを取って行うのではなく、ユーザーが指定できるそうだ。
  • Mesh Shader:実質的に三角形Primitiveを生成するステージ。
  • Mesh Shaderは従来のCompute Shaderのモデルを沿ってレンダリングをする。

参考

www.joshbarczak.com

m.blog.naver.com

www.pcper.com

devblogs.nvidia.com