* Vulkan [#rce4106a]
Vulkan に関する個人的なメモを書くページです。

#contents

** 17-02-12 Buffer BufferView Image ImageView [#i2c6c26f]
使い分けがイメージできないモヤっとを取り除いてみよう。

BufferとBufferViewの関係はぱっと想像できるんです。
大きなバッファ作って部分ごとに使い分けたいとか。

ImageとImageView。こちらがモヤっとしています。
同じメモリ領域を別の使い方をしたいときにViewを量産するんでしょうか?
%%例えば、MSAA用に大きいメモリ領域をImageに割り当てるが、状況によって小さなViewを使って描くとか?%%
違うか、その場合は同じメモリ領域を別のImageにバインドすることになりますね。

あ!例えばキューブマップの1面ずつをオフスクリーンレンダする場合、1面ずつをViewに割り当てて描画先に指定するのかな。
そんで、6面描画しおわったら、CUBEなViewをサンプラーとして使って描画する、とかでしょうか。
CUBEマップを指定する場合のImageとViewの設定がこちらに載っていました。
https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#resources-image-views-compatibility
View を作る際に指定する VkImageSubresourceRange に baseArrayLayer がある。
CUBEのときは各面が0〜5 に対応しているんですね。View の役割がイメージできました。
** 17-02-12 Fence Semaphore Event の違い [#q567df32]
分かりやすく解説されてました。ありがたい。
https://www.reddit.com/r/vulkan/comments/47tc3s/differences_between_vkfence_vkevent_and/

** 17-02-12 クイックリファレンス [#r12ea657]
クイックなんだけど、ページ数すごいですね。ココに出てくるものがざっくり理解できたら大枠は理解できたと考えてよさそうです。
https://www.khronos.org/files/vulkan10-reference-guide.pdf

** 17-02-08 だいたいハテナがとれたので [#td80489e]
CrossFrameworkにモジュールを作ってみよう。
その前に名前空間整理をやってしまおう。

** 17-02-07 SPIR-V から名前などの一覧はとれるのか [#hceae211]
デモのシェーダーを少し書き換えてSPVにしてみました。
#pre(){{
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 20
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %uFragColor %texcoord
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 400
               OpSourceExtension "GL_ARB_separate_shader_objects"
               OpSourceExtension "GL_ARB_shading_language_420pack"
               OpName %main "main"
               OpName %uFragColor "uFragColor"
               OpName %tex "tex"
               OpName %texcoord "texcoord"
               OpDecorate %uFragColor Location 0
               OpDecorate %tex DescriptorSet 0
               OpDecorate %tex Binding 0
               OpDecorate %texcoord Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
 %uFragColor = OpVariable %_ptr_Output_v4float Output
         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
         %11 = OpTypeSampledImage %10
%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
        %tex = OpVariable %_ptr_UniformConstant_11 UniformConstant
    %v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
   %texcoord = OpVariable %_ptr_Input_v2float Input
       %main = OpFunction %void None %3
          %5 = OpLabel
         %14 = OpLoad %11 %tex
         %18 = OpLoad %v2float %texcoord
         %19 = OpImageSampleImplicitLod %v4float %14 %18
               OpStore %uFragColor %19
               OpReturn
               OpFunctionEnd
}}
Uniformやサンプラーの名前はSPVから取得できるのかの件ですが、SPVを解析したら出せそうですね。
C++での解析ライブラリは見つけたのですがC#のはあるのかな?
そしたらバイナリコンバータで手軽に好きな形で情報をつっこめるんだけどねぇ。
** 17-02-06 Uniform と DescriptorSet [#r2af655e]
頭がこんがらがってきた。けどめげない。
Uniform まわりをすっきりさせよう。
日本語解説ページにお世話になります。ありがとうございます。
https://sites.google.com/site/monshonosuana/vulkan/vulkan_004

DescriptorSetLayoutBinding::descriptorCount は何に使うのか最初ハテナでしたが、どうやら配列を指定するときに使うようです。
https://vulkan.lunarg.com/doc/view/1.0.33.0/linux/vkspec.chunked/ch13s02.html

シェーダのユニフォーム値や頂点属性名はシェーダーバイナリ(SPIR-V)に含まれてるのかどうか気になりました。
次調べます。
** 17-02-05 Pipeline [#i35d7bf6]
レンダーパスと同じくなんじゃこりゃと思ったパイプライン。
コードを見る限り、マテリアルに関するRenderStateを集めたモノと考えてよさそう。
Blend、DepthStencilTest、Vertex&Fragmentシェーダの設定などなど。
頻繁に変える項目は DynamicState で指定できるようにすることも可能らしく、1項目の設定値が異なるマテリアルがあっても Pipeline をもう1つ作る必要はないみたい。

また、 uniform やリードするテクスチャは vkCmdBindDescriptorSets で Descriptor という概念で反映するらしく、Pipelineとは別らしい。
これはまた別で調べましょう。

** 17-02-05 テクスチャフォーマットで調べたこと [#b1edd176]
:USCALED SSCALED|
公式ドキュメントに書いてありました。
#pre(){{
USCALED
The components are unsigned integer values that get converted to floating-point in the range [0,2n-1]

SSCALED
The components are signed integer values that get converted to floating-point in the range [-2n-1,2n-1-1]
}}
floatに変換されますというだけなのかな?どういう使い方をするのかは分かりませんでした。

:E, X, S|
指数部(RGB共通にかかる指数)、未使用、ステンシルを示すものでした。


:linearTiling、optimalTiling、bufferFeatures|
公式ドキュメントより。
#pre(){{
    linearTilingFeatures describes the features supported by VK_IMAGE_TILING_LINEAR.

    optimalTilingFeatures describes the features supported by VK_IMAGE_TILING_OPTIMAL.

    bufferFeatures describes the features supported by buffers.
}}
タイリングはピクセルの並びのことです。
LINEARは1行ごとに(おそらく左端から右端の順で)ピクセルデータが並んでいるようです。
OPTIMALはGPUが処理しやすい並びの順でピクセルデータが並んでいるようです。
LINEARで使える用途、OPTIMALで使える用途、あとバッファ系で使える用途がここで列挙されているようです。
OPTIMALな並びはGPU依存ですけど、よく使うBCシリーズはそのものがOPTIMALな並びなのかどうかが気になりました。
ひとまずそれは置いておいて、先にチュートリアルページを読んでいくことにします。
** 17-02-05 ROデータのVRAMへの転送 [#mf268782]
RO = リードオンリーのこと。

昨日の VulkanInfo の結果を見たら DeviceLocal なメモリが明確に扱えることが分かりました。
これをいわゆるVRAM(GPUしかアクセスできないメモリで通常のメモリより高速)であると考えますと、
アセットとしてロードしたテクスチャや頂点属性は基本不変であるならばそこに突っ込んだほうが早くなりそうですね。
通常メモリからVRAMへコピーする方法はあるのかと思って検索したらあっさり出てきました。
https://vulkan-tutorial.com/Vertex_buffers/Staging_buffer

不変なものは基本VRAMへ。変更回数が少ないものも基本VRAMに載せたほうがいいのかもしれません。
ハードによっては通常メモリが超遅いものもあるので、もしかすると毎フレーム変わるようなものも毎フレームコピーしたほうが早い、なんてこともあるのかもしれませんね。

スマートデバイス系はVRAMがなく共有メモリで済ませているのがほとんどという印象なので、効果があるのはVRAMのあるハード(PCやコンシューマ機)となりそうです。
参考:Android 機の VulkanInfo
http://dench.flatlib.jp/vulkan/vulkaninfo
※いつも参考にさせていただいております&ありがとうございます!
** 17-02-05 RenderPass [#g148ba15]
解説ページを見ながらお勉強。ありがとうございます。
http://qiita.com/Pctg-x8/items/2b3d5c8a861f42aa533f

Subpass、Attachment、Dependencyの言葉が何を指すのかが分かり一気に理解が進みました。
GPUを少しでも暇させないための仕組みなんですね。すっきり!


** 17-02-05 VulkanInfo を見てぱっと分からなかったもの [#mc2f09fc]
FORMAT_R8_USCALED にある USCALED や SCALED ってどういうタイプなのか。
linearTiling、optimalTiling、bufferFeaturesとは。(想像通りかもしれないけど念のため)
VK_FORMAT_FEATURE_ 各種定数の意味は。
フォーマットのE,S,X,は何なのか。(Sはステンシル・・・?)

レンダーパス調べた後ぐらいに調べよう。
** 17-02-04 GTX680 で Vulkan [#n598825b]
GTX680が届いたので早速MacProさんに装着。Metalも動き、MoltenVkのサンプルも動きました。
BootcampのWin10でもVulkanInfoサンプルが動きました。
&attachref(./vulkaninfo-gtx680.txt);
昨日のメモリの話関連になりますが、↑を見るとビデオカードのメモリと通常メモリでヒープが分かれているのが分かりますね。
** 17-02-03 メモリあれこれ [#u14bbfbc]
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT と VK_MEMORY_PROPERTY_HOST_COHERENT_BIT はどっちのほうがパフォーマンスが良いのか気になったので調べました。
VkPhysicalDeviceMemoryProperties の公式の説明を読むと「パフォーマンスが同等もしくはそれより良いもの順に見つかるように memoryTypes は並んでいます」というようなことが書いてあります。
つまり、 HOST_VISIBLE_BIT だけで良い場合は HOST_COHERENT_BIT がたっていないメモリタイプのヒープからメモリを確保するほうがパフォーマンスが良くなる可能性がある、ということだと理解しました。

続いてHeap。
VkMemoryHeap.size はMoltenVk では 0 が格納されていました。
おそらく Metal からはその情報がとれないのか、もしくは未対応なのかと思われます。 
Apple系OS環境も考慮するならばサイズみてほにゃららするという処理は書かず、Allocを試してサイズを測る方が良さそうです。

最後にメモリアロケーションは少ない方がいいのかどうか。
[[NVIDIAさんの解説>https://developer.nvidia.com/vulkan-memory-management]]の最後の図を見る限り、1つのBufferでまとめられるならまとめたほうが良さそう。
ということはメモリブロックも少ないにこしたことはないということだと理解しました。
CPUからRead or Write するようなタイプのものは全部1つの VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT なメモリタイプ&ヒープから確保したメモリブロックからやりくりするのが一番良さそうです。
もちろんその場合、もちろんヒープ管理をこちらでする必要がでてくるため少し面倒ではありますがパフォーマンスを重要にするならやるっきゃない、ということですかね。
** 17-02-02 コードの解説 [#t31c9dd7]
http://qiita.com/Pctg-x8/items/6fd3ef76b58d98f26634

丁寧に書かれていて入門編としてとてもありがたかった。
レンダーパスとパイプライン、ぼんやりとしかまだ分かってないです。

** 17-02-01 オーバービューを読む [#g1448939]
https://vulkan-tutorial.com/Overview

わかりやすーい!だいたいイメージできた。
Render pass と Graphics pipeline は初めて見る概念な気がする。
そしてまだよく理解できてないので後で改めて読み直してみよー。

** 17-02-01 実行環境どうしようかな [#rc3e1c28]
Macで確認するならMetalをラップした MoltenVK を使用する必要あり。
MacBook 環境ではサンプルが動いた。
タワー型 MacPro は基本Metalをノンサポートのため動かない。
近日グラボを変えるのでそれで動くことを期待。(動いて欲しいなぁ)
試用は Windows 上のほうが安定してそうなので対応グラボをさした Bootcamp を使おう。

    ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS