首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >vkQueuePresentKHR做了什么?

vkQueuePresentKHR做了什么?
EN

Stack Overflow用户
提问于 2019-10-30 16:37:40
回答 1查看 1.4K关注 0票数 0
代码语言:javascript
运行
复制
void drawFrame() {

    vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());

    ...

    VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = signalSemaphores;

    vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame])

    ...

    VkSwapchainKHR swapChains[] = {swapChain};

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.waitSemaphoreCount = 1;
    presentInfo.pWaitSemaphores = signalSemaphores;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = swapChains;
    presentInfo.pImageIndices = &imageIndex;

    vkQueuePresentKHR(presentQueue, &presentInfo); // <- vkQueuePresentKHR
    ...

    currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}

在提交第一帧VkQueuePresentKHR后调用vkQueueSubmit,在第二帧中,调用vkWaitForFences等待前一帧的vkQueueSubmit结束,然后再次调用vkQueueSubmit提交,但此时vkQueuePresentKHR的第一帧可能在呈现中,它占据了第一帧的帧缓冲区。那么,第二帧的vkQueueSubmit会与第一帧的vkQueuePresentKHR冲突吗?

我想可能有两种情况:

1:第一帧和第二帧不占用相同的帧缓冲区,当第一帧vkQueueSubmit结束时,数据被复制到新的内存中。vkQueuePresentKHR在新内存中显示数据,因此将第二帧呈现给Framebuffer不会影响第一帧的内容。

2:第一帧和第二帧占用相同的帧缓冲区,当第一帧的vkQueuePresentKHR和第二帧的vkQueueSubmit同时使用帧缓冲区时,图像发生撕裂(我猜)。

我认为第二种可能性会更高。

我希望将结果呈现到我自己的内存中,而不是显示在屏幕上。我想弄清楚vkQueuePresentKHR是做什么的。

下面是一个向您自己的内存呈现的示例:https://github.com/SaschaWillems/Vulkan/blob/master/examples/renderheadless/renderheadless.cpp

在本例中,呈现的Framebuffer数据被传输到新内存。

在我设计的程序中,有一个二级线程负责等待栅栏的完成。一旦传输完成,就会使用这个内存。类似于下面的例子:

主线程:

代码语言:javascript
运行
复制
void drawFrame() {

    vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());

    ...

    VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = signalSemaphores;

    // VkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) cannot be executed before the execution of 
    // vkQueueSubmit(graphicsQueue, 1, &transferSubmitInfo, transferCompleteFences[currentFrame]) in the previous frame. Otherwise,
    // they will occupy the same FrameBuffer. I think it is not possible.
    transferCompleteMutexs[currentFrame].lock();                                                // <- lock transferCompleteMutexs

    vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame])

    ...

    VkSubmitInfo transferSubmitInfo = {};
    transferSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    transferSubmitInfo.commandBufferCount = 1;
    transferSubmitInfo.pCommandBuffers = &commandBuffer;
    transferSubmitInfo.waitSemaphoreCount = 1;
    transferSubmitInfo.pWaitSemaphores = signalSemaphores;
    vkQueueSubmit(graphicsQueue, 1, &transferSubmitInfo, transferCompleteFences[currentFrame]) // Signal <- transferCompleteFences
    ...
}

二次螺纹:

代码语言:javascript
运行
复制
while(true) {
    // Waiting for transfer to complete
    vkWaitForFences(logicalDevice_->vkLogicalDevice(),
                    1,
                    &transferCompleteFences[currentFrame],                         // Wait <- transferCompleteFences
                    VK_TRUE,
                    std::numeric_limits<uint64_t>::max());

    // using transfer completed data 
    ...

    // Secondary thread knows that the current frame is transmitted. The next Primary thread can be submitted.
    transferCompleteMutexs[currentFrame].unlock();                                // <- unlock transferCompleteMutexs
}

上面的代码使用transferCompleteMutexs来保护FrameBuffer,我认为这是必要的。但很明显,vkQueuePresentKHR不会这么做。我是否有更好的方法来模拟vkQueuePresentKHR,将数据呈现到我自己的内存中,还是我现在所做的是正确的?

EN

回答 1

Stack Overflow用户

发布于 2019-10-31 01:07:26

第二帧的vkQueueSubmit不能与第一帧的vkQueuePresent“冲突”。

在第二个框架中,您还将执行一个vkAcquireNextImage,它提供一个信号量。如果信号是信号,则表示引擎不再使用该图像(不管它是否与上一帧相同)。

vkQueueSubmit可以与之冲突的是以前的vkQueueSubmit和使用的各种资源。

vkQueuePresent所做的是提交您的信号量,等待它返回之前执行。在信号量发出信号之前,它不会访问该图像。它将从Vulkan队列异步地在Image外部显示图片。其他任何事情都没有具体说明。图像可以被复制、复制,或者直接使用,或者其他任何符合上述API协议的内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58630028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档