Vulkan: Add platform hooks before presenting

This allows the Wayland plugin to circumvent the frame callback handling of the
driver (which blocks until the frame is presented, potentially forever, if the
window is minimized).

Task-number: QTBUG-78000
Change-Id: Ia7d347019dfeae3bfcfad3d0cca3f4fffdc8c7a9
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2019-10-04 14:49:30 +02:00
parent 1ed9cc2a93
commit 7a3d647bab
6 changed files with 29 additions and 0 deletions

View File

@ -1705,6 +1705,10 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
presInfo.waitSemaphoreCount = 1;
presInfo.pWaitSemaphores = &frame.drawSem; // gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
// Do platform-specific WM notification. F.ex. essential on Wayland in
// order to circumvent driver frame callbacks
inst->presentAboutToBeQueued(swapChainD->window);
VkResult err = vkQueuePresentKHR(gfxQueue, &presInfo);
if (err != VK_SUCCESS) {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {

View File

@ -80,6 +80,11 @@ QPlatformVulkanInstance::~QPlatformVulkanInstance()
{
}
void QPlatformVulkanInstance::presentAboutToBeQueued(QWindow *window)
{
Q_UNUSED(window);
}
void QPlatformVulkanInstance::presentQueued(QWindow *window)
{
Q_UNUSED(window);

View File

@ -77,6 +77,7 @@ public:
virtual QByteArrayList enabledExtensions() const = 0;
virtual PFN_vkVoidFunction getInstanceProcAddr(const char *name) = 0;
virtual bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) = 0;
virtual void presentAboutToBeQueued(QWindow *window);
virtual void presentQueued(QWindow *window);
virtual void setDebugFilters(const QVector<QVulkanInstance::DebugFilter> &filters);

View File

@ -774,6 +774,20 @@ bool QVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, uint32_t
return d_ptr->platformInst->supportsPresent(physicalDevice, queueFamilyIndex, window);
}
/*!
This function should be called by the application's renderer before queuing
a present operation for \a window.
While on some platforms this will be a no-op, some may perform windowing
system dependent synchronization. For example, on Wayland this will
add send a wl_surface.frame request in order to prevent the driver from
blocking for minimized windows.
*/
void QVulkanInstance::presentAboutToBeQueued(QWindow *window)
{
d_ptr->platformInst->presentAboutToBeQueued(window);
}
/*!
This function should be called by the application's renderer after queuing
a present operation for \a window.

View File

@ -186,6 +186,7 @@ public:
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window);
void presentAboutToBeQueued(QWindow *window);
void presentQueued(QWindow *window);
typedef bool (*DebugFilter)(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object,

View File

@ -2018,6 +2018,10 @@ void QVulkanWindowPrivate::endFrame()
presInfo.waitSemaphoreCount = 1;
presInfo.pWaitSemaphores = gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
// Do platform-specific WM notification. F.ex. essential on Wayland in
// order to circumvent driver frame callbacks
inst->presentAboutToBeQueued(q);
err = vkQueuePresentKHR(gfxQueue, &presInfo);
if (err != VK_SUCCESS) {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {