私の質問は2つの部分があります。バルカン:データの一貫性
- /見えメモリが利用可能であることの違いは何ですか?
このチュートリアル(https://vulkan-tutorial.com)からVulkanを学んで、デバイスのローカルメモリに一様なデータ(単純なモデル/ビュー/投影行列)をアップロードする別のアプローチを紹介しています。行列は頂点シェーダで使用されます。
このチュートリアルでは、マトリクスが更新され、ステージングバッファ(
vkMapMemory
など)にコピーされ、コマンドバッファを作成してvkCmdCopy
を記録し、バッファを破棄して最後のデバイスローカルバッファにコピーします。私は描画のために義務的なコマンドバッファ内で最後のステップを試みます。チュートリアルの方法は流暢なアニメーションにつながりますが、私の実験ではこの機能が欠けています。私は2つのbufferBarriersをインストールして、コピーが完了したことを確認しようとしましたが(これは問題のようです)、それは助けになりませんでした。リソースは適切に作成され、バインドされています。正常に動作しています。
namespace Tools { struct UniformBufferObject { glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; }; vk::Buffer uniformStagingBuffer; vk::DeviceMemory uniformStagingMemory; //dataBuffer also contains the vertex and index data, is device local vk::Buffer dataBuffer; vk::DeviceMemory dataBufferMemory; vk::vector<vk::DeviceSize> dataBufferOffsets; std::vector<vk::CommandBuffer> cmdBuffers;
vkcpp
を使用してIM(https://github.com/KhronosGroup/Vulkan-Hpp)と//update uniform buffer and copy it to the staging buffer //(called every frame) Tools::UniformBufferObject ubo; //set the matrices void* data; data = device.mapMemory(uniformStagingMemory, 0, sizeof(ubo), (vk::MemoryMapFlagBits) 0); memcpy(data, &ubo, sizeof(ubo)); device.unmapMemory(uniformStagingMemory); //once: create a command buffer for each framebuffer of the swapchain //queueFamily struct members set properly //1st barrier: make transfer from host memory to staging buffer available/visible vk::BufferMemoryBarrier bufMemBarrierStaging; bufMemBarrierStaging.srcAccessMask = vk::AccessFlagBits::eHostWrite; bufMemBarrierStaging.dstAccessMask = vk::AccessFlagBits::eTransferRead; bufMemBarrierStaging.buffer = uniformStagingBuffer; bufMemBarrierStaging.offset = 0; bufMemBarrierStaging.size = sizeof(Tools::UniformBufferObject); //2nd barrier: make transfer from staging buffer to device local buffer available/visible vk::BufferMemoryBarrier bufMemBarrier; bufMemBarrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; bufMemBarrier.dstAccessMask = vk::AccessFlagBits::eUniformRead | vk::AccessFlagBits::eShaderRead; bufMemBarrier.buffer = dataBuffer; bufMemBarrier.offset = dataBufferOffsets[2]; bufMemBarrier.size = sizeof(Tools::UniformBufferObject); for(size_t i = 0; i < cmdBuffers.size(); i++) { //begin command buffer cmdBuffers[i].pipelineBarrier( vk::PipelineStageFlagBits::eHost, //srcPipelineStage vk::PipelineStageFlagBits::eTransfer, //dstPipelineStage (vk::DependencyFlagBits) 0, nullptr, //memBarrier bufMemBarrierStaging, nullptr //imgBarrier ); vk::BufferCopy copyRegion; //filled appropriate cmdBuffers[i].copyBuffer(uniformStagingBuffer, dataBuffer, copyRegion); cmdBuffers[i].pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, //srcPipelineStage vk::PipelineStageFlagBits::eVertexShader, //dstPipelineStage (vk::DependencyFlagBits) 0, nullptr, //memBarrier bufMemBarrier, nullptr //imgBarrier ); //renderpass stuff and drawing etc. }
。
この非流動アニメーションがデータ一貫性を欠いている理由は、これを達成しようと間違っていましたか?
ありがとうございます!
編集:パート2の問題は同期が失われていました。ステージングバッファは、前にフレームをレンダリングする間に読み取られる前に部分的に更新されていました。 (使用可能/表示可能なメモリの違いを明確にしてくれてありがとう)。
"利用可能なメモリと表示されているメモリの違いは何ですか?" "利用可能であることを意味するものではありません。 "*とバッファを破壊する*"なぜあなたはバッファを破壊するだろうか?それはどういう意味ですか? –
ところで、最初のメモリバリアは必要ありません。メモリバリアHOST_WRITE_BIT/HOST_STAGEは、コマンドバッファの提出によって暗黙的に行われます。 –
@NicolBolas第1の質問は、仕様のセクション6.4、メモリ依存性に関する段落を参照しています。私は何の違いも見られませんでした。 Destory a bufferは、私は 'vkFreeCommandBuffers'を呼び出します。これはチュートリアルのコードなので、最も簡単な方法が選択されます。良い方法ではありません。 – camelCase