Open1

C-WebGL: GPUへのデータ転送(Vulkan)

okuokuokuoku

ちょっと描画は悩みどころが多すぎるので、一旦データのアップロードから。。

手順

https://vulkan.lunarg.com/doc/view/1.2.170.0/windows/tutorial/html/07-init_uniform_buffer.html

チュートリアル通りにやるとして:

  1. vkCreateBuffer でバッファを用意する。バッファにはメモリ領域は付いてこないので、後でbindしてやる必要がある
  2. vkAllocateMemory で、 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT かつ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT なメモリを確保する
  3. vkMapMemory で、ホスト(CPU)側のメモリ空間にマップする
  4. memcpyなりなんなりで転送する
  5. vkUnmapMemory で、ホスト側のメモリ空間からアンマップする
  6. vkBindBufferMemory でバッファとメモリを関連づける

テクスチャ

テクスチャはさらに複雑で、

https://vulkan-tutorial.com/Texture_mapping/Images

のように、

  1. 通常のバッファと同様に、一旦LinearレイアウトのままGPUにアップロードする
  2. Imageを確保してメモリをbindしておく
  3. vkCmdCopyBufferToImage を実行してImage内にコピーする

と、一旦中間バッファを経由してやる必要がある。近代的なGPUはテクスチャを単純なビットマップ形式で扱うことは殆どなく、 Z階数曲線 のような空間局所性の良いアドレッシングを採用していることがある。Vulkan(を始め多くのグラフィックスAPIでは)GPU独自のアドレッシングルールは隠蔽されているため、CPU側でアドレス変換を行うのではなく、コピーの形でGPU(またはドライバ)側に変換を行わせている。

...更に悪いことにWebGLには UNPACK_FLIP_Y_WEBGL が有り、上下の反転も行える必要がある。これは流石にどうしようもないので、ホスト側で上下反転コピーすることになる。