vkAcquireNextImageKHR say that Semaphore must not have any pending operations
-
I had qvulkanwindow host my vulkan semaphores, and in fact, I never wrote any semaphores myself. When I move the windows, there will be this error:
——————————————————————————————
vkDebug: vkAcquireNextImageKHR(): Semaphore must not have any pending operations.
The Vulkan spec states: If semaphore is not VK_NULL_HANDLE, it must not have any uncompleted signal or wait operations pending (https://vulkan.lunarg.com/doc/view/1.4.313.2/windows/antora/spec/latest/chapters/VK_KHR_surface/wsi.html#VUID-vkAcquireNextImageKHR-semaphore-01779)
vkDebug: vkQueueSubmit(): pSubmits[0].pSignalSemaphores[0] (VkSemaphore 0x3f500000003f5) is being signaled by VkQueue 0x3a014e8, but it may still be in use by VkSwapchainKHR 0x3e300000003e3.
Here are the most recently acquired image indices: [0], 1, 2.
(brackets mark the last use of VkSemaphore 0x3f500000003f5 in a presentation operation)
Swapchain image 0 was presented but was not re-acquired, so VkSemaphore 0x3f500000003f5 may still be in use and cannot be safely reused with image index 2.
Vulkan insight: One solution is to assign each image its own semaphore. Here are some common methods to ensure that a semaphore passed to vkQueuePresentKHR is not in use and can be safely reused:
a) Use a separate semaphore per swapchain image. Index these semaphores using the index of the acquired image.
b) Consider the VK_EXT_swapchain_maintenance1 extension. It allows using a VkFence with the presentation operation.
The Vulkan spec states: Each binary semaphore element of the pSignalSemaphores member of any element of pSubmits must be unsignaled when the semaphore signal operation it defines is executed on the device (https://vulkan.lunarg.com/doc/view/1.4.313.2/windows/antora/spec/latest/chapters/cmdbuffers.html#VUID-vkQueueSubmit-pSignalSemaphores-00067)
——————————————————————————————
and when i resize the window,the warning will never happen.
this is my code in qvulkanwindowrender.cpp:#include "gui/PGVulkanWindowRender.h" PGVulkanwindowrender::PGVulkanwindowrender(QVulkanWindow* qvulkanwindow, QVulkanInstance* qvulkaninstance) { this->qvulkanwindow = qvulkanwindow; this->qvulkaninstance = qvulkaninstance; } void PGVulkanwindowrender::initResources() { this->device = this->qvulkanwindow->device(); this->df = qvulkaninstance->deviceFunctions(this->device); } void PGVulkanwindowrender::initSwapChainResources() { swapchainInfo.imageCount = this->qvulkanwindow->swapChainImageCount(); swapchainInfo.extent.setHeight(this->qvulkanwindow->swapChainImageSize().height()) .setWidth(this->qvulkanwindow->swapChainImageSize().width()); swapchainInfo.formart.format = static_cast<vk::Format>(this->qvulkanwindow->colorFormat()); initWindowHeight = this->qvulkanwindow->swapChainImageSize().height(); initWindowWidth = this->qvulkanwindow->swapChainImageSize().width(); this->pgrenderpass = new PGRenderPass(&this->device); this->pgpipeline = new PGPipeline(&this->device, &this->pgrenderpass->renderPass); vector<vk::ImageView> imageviews = {}; for (int i = 0; i < this->qvulkanwindow->swapChainImageCount(); i++) { imageviews.push_back(this->qvulkanwindow->swapChainImageView(i)); } this->pgframebuffers = new PGFrameBuffers(&this->device,this->pgrenderpass,imageviews); } void PGVulkanwindowrender::logicalDeviceLost() { throw std::runtime_error("逻辑设备丢失"); } void PGVulkanwindowrender::physicalDeviceLost() { throw std::runtime_error("物理设备丢失"); } void PGVulkanwindowrender::preInitResources() {} void PGVulkanwindowrender::releaseResources() { } void PGVulkanwindowrender::releaseSwapChainResources() { delete this->pgpipeline; delete this->pgrenderpass; delete this->pgframebuffers; } void PGVulkanwindowrender::startNextFrame() { vk::CommandBuffer commandbuffer = this->qvulkanwindow->currentCommandBuffer(); vk::CommandBufferBeginInfo begInfo = {}; // if (commandbuffer.begin(&begInfo) != vk::Result::eSuccess) { // throw std::runtime_error("命令缓存开始错误"); // } vk::RenderPassBeginInfo RenderPassBeginInfo = {}; vk::Rect2D area; area.setExtent({initWindowWidth,initWindowHeight}).setOffset({0, 0}); vk::ClearValue cv; cv.setColor({1.0f, 1.0f, 1.0f, 1.0f}); RenderPassBeginInfo.setRenderPass(this->pgrenderpass->renderPass) .setRenderArea(area) .setClearValueCount(1) .setPClearValues(&cv) .setFramebuffer(this->pgframebuffers->framebuffers[this->qvulkanwindow->currentSwapChainImageIndex()]); commandbuffer.beginRenderPass(&RenderPassBeginInfo, vk::SubpassContents::eInline); commandbuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, this->pgpipeline->pipeline); vk::DeviceSize offset = 0; //commandbuffer.bindVertexBuffers( //0, 1, &this->vertexBuffer->buffer, &offset); commandbuffer.draw(3, 1, 0, 0); commandbuffer.endRenderPass(); //commandbuffer.end(); this->qvulkanwindow->frameReady(); } // if ( != vk::Result::eSuccess) { // throw std::runtime_error("获取交换链图像错误"); //} // cout<<r1<<endl; PGVulkanwindowrender::~PGVulkanwindowrender() {}
and this is my code in the hearder file:
#pragma once #include "includes.h" #include "gui/PGShaderModule.h" #include "gui/PGPipeline.h" #include "gui/PGRenderPass.h" #include "gui/PGFrameBuffer.h" class PGVulkanwindowrender : public QVulkanWindowRenderer { private: void initResources() override; void initSwapChainResources() override; void logicalDeviceLost() override; void physicalDeviceLost() override; void preInitResources() override; void releaseResources() override; void releaseSwapChainResources() override; void startNextFrame() override; public: QVulkanWindow* qvulkanwindow; QVulkanInstance* qvulkaninstance; QVulkanDeviceFunctions *df; vk::Device device; //PGInstance* pginstance; // PGSurface* pgsurface; // PGPhyDevice* pgphydevice; // PGDevice* pgdevice; // PGQueue* geometryqueue; PGPipeline* pgpipeline; PGRenderPass* pgrenderpass; PGFrameBuffers* pgframebuffers; PGVulkanwindowrender(QVulkanWindow * qvulkanwindow,QVulkanInstance* qvulkaninstance); ~PGVulkanwindowrender(); };
-