我的問題有兩個部分:福爾康:vkCmdPipelineBarrier數據一致性
- 是什麼可用的內存/可見的區別?
我從本教程中學習Vulkan(https://vulkan-tutorial.com),並且目前偷偷摸摸尋找將統一數據(簡單模型/視圖/投影矩陣)上傳到設備本地內存的不同方法。矩陣用在頂點着色器中。
在教程矩陣得到更新和被複制到一個臨時緩衝器(
vkMapMemory
等)和通過創建一個命令緩衝區,記錄vkCmdCopy
,submiting它並破壞緩衝器之後複製到最終設備本地緩衝器。我嘗試在繪圖的強制命令緩衝區內完成最後一步。雖然教程方式導致流暢的動畫,但我的實驗忽略了此功能。我試圖安裝2個bufferBarriers,以確保副本完成(這似乎是問題),但這沒有幫助。資源被正確創建和綁定 - 工作正常。
//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. }
使用
vkcpp
(https://github.com/KhronosGroup/Vulkan-Hpp)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;
林。
這是非流體動畫缺少數據一致性的原因 - 我是否試圖實現這個目標?
在此先感謝!
編輯:第2部分的問題是缺少syncronisation;在渲染幀之前,暫存緩衝區在被讀取之前(部分)被更新。 (感謝您澄清內存可用/可見之間的差異)。
「*可用內存/可見內容之間的區別是什麼?*」目前尚不清楚「可用內存」的含義。 「*並銷燬緩衝區*」爲什麼要銷燬緩衝區?你究竟是什麼意思? –
順便說一句,你不需要第一個內存屏障。內存屏障HOST_WRITE_BIT/HOST_STAGE通過提交命令緩衝區隱式完成。 –
@NicolBolas第一個問題涉及規範的第6.4節,關於內存依賴關係的段落。我看不出有什麼區別。 Destory是一個緩衝區,我稱之爲'vkFreeCommandBuffers'。由於這是來自教程的代碼,所以選擇了最簡單的方法,而不是一個好的方法。 – camelCase