Synchronization with QVulkanWindow
-
Hello,
I'm working on a Vulkan-based application using QVulkanWindow, and I'm encountering some synchronization issues. I'm trying to implement custom command buffer submission with fence synchronization, but I'm running into conflicts with how QVulkanWindow manages command buffers.
Here's a simplified version of what I'm trying to do:void Renderer::startNextFrame() { VkCommandBuffer cb = p_window->currentCommandBuffer(); VkCommandBufferBeginInfo beginInfo = {}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; VkResult beginResult = p_instruments.devFuncs->vkBeginCommandBuffer(cb, &beginInfo); if (beginResult != VK_SUCCESS) { throw std::runtime_error("Failed to begin command buffer: " + std::to_string(beginResult)); } setClearColor(vt::VK_CLEAR_GREY); VkRenderPassBeginInfo p_rpBeginInfo = {}; p_rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; p_rpBeginInfo.renderPass = p_window->defaultRenderPass(); p_rpBeginInfo.framebuffer = p_window->currentFramebuffer(); p_rpBeginInfo.renderArea.extent.width = p_sz.width(); p_rpBeginInfo.renderArea.extent.height = p_sz.height(); p_rpBeginInfo.clearValueCount = p_window->sampleCountFlagBits() > VK_SAMPLE_COUNT_1_BIT ? 3 : 2; p_rpBeginInfo.pClearValues = p_clearValues; p_instruments.devFuncs->vkCmdBeginRenderPass(cb, &p_rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE); m_trianglePipeline.pushConstant(cb, 0, sizeof(QMatrix4x4), p_proj.data()); m_trianglePipeline.bind(cb); setViewport(cb); setScissors(cb); StopwatchCycle(); BaseGame::startNextFrame(); p_instruments.devFuncs->vkCmdEndRenderPass(cb); VkResult endResult = p_instruments.devFuncs->vkEndCommandBuffer(cb); if (endResult != VK_SUCCESS) { throw std::runtime_error("Failed to end command buffer: " + std::to_string(endResult)); } VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cb; VkResult submitResult = p_instruments.devFuncs->vkQueueSubmit(p_instruments.getDeviceQueue(), 1, &submitInfo, *p_fence); if (submitResult != VK_SUCCESS) { throw std::runtime_error("Failed to submit command buffer: " + std::to_string(submitResult)); } p_window->frameReady(); p_window->requestUpdate(); }
Error: vkDebug: Validation Error: [ VUID-vkBeginCommandBuffer-commandBuffer-00049 ] Object 0: handle = 0x4909430, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x84029a9f | vkBeginCommandBuffer(): Cannot call Begin on VkCommandBuffer 0x4909430[] in the RECORDING state. Must first call vkEndCommandBuffer(). The Vulkan spec states: commandBuffer must not be in the recording or pending state (https://vulkan.lunarg.com/doc/view/1.3.275.0/linux/1.3-extensions/vkspec.html#VUID-vkBeginCommandBuffer-commandBuffer-00049)
It seems that QVulkanWindow is handling commandBuffers itself(beginning cb, ending, subbmiting queue etc.), but how can i use it with fence?
My question is:
How can i implement my own fences with QVulkanWindow's command buffers, so i can synchronize cpu with gpu?
All the input will be appriciated. Thank you.
-
Hi,
I haven't used that class yet but based on its documentation, I think you are doing your modification in the wrong place. QVulkanWindowRenderer seems to be what you are after.
Hope it helps
-
Is your application using more than 1 thread? Can Renderer::startNextFrame() be called before the previous frame has finished?
-
Is your application using more than 1 thread? Can Renderer::startNextFrame() be called before the previous frame has finished?
@SimonSchroeder My application is using 1 thread.