diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-01-17 15:06:47 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-01-22 22:46:51 +0100 |
commit | e0e7c42a19316c53fd3ab21133223b5ee788ba38 (patch) | |
tree | deb66ad7fded11f605aac833e88fe63e1b11ce15 /src/gui | |
parent | dd23313d66846022894b56ad25b6c2c0fdb54762 (diff) |
Introduce VK_KHR_display support for i.MX8 devices
The eglfs_viv backend has Vulkan support now. While the support code is
common (lives in api/vulkan), we will not expose this for any other integration
yet, without the appropriate testing.
While putting this to eglfs seems unintuitive at first, it turns out that
for Vivante in particular this is very useful, since we can rely on the existing
framebuffer device infrastructure to solve certain problems (like the lack of
vsync)
The VK_KHR_display implementation of Vivante currently exhibits all the known issues
of the old, fbdev-style EGL plumbing (presumably since it lives on top of that):
- No vsync. This can be fixed by setting QT_QPA_EGLFS_FORCEVSYNC.
- May need a manual call to fbset to set the correct resolution before
launching the Qt app.
- And of course it lacks all the multi-screen features provided by drm.
- Plus, it seems the swapchain only supports a min/max buffer count of 1. This
needs special handling in QRhi since until now we assumed that there was always
at least 2 buffers available.
[ChangeLog][Platform Specific Changes][Linux] Vulkan is now supported by eglfs
(eglfs_viv backend) on i.MX8 devices with the Vivante graphics stack. This is done
via VK_KHR_display so no windowing system is required.
Task-number: QTBUG-78754
Change-Id: I7530aa026d4b904b9de83f9bdbdc4897ae770e71
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index f4c72d2cca..e7faa0cadd 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -1351,8 +1351,8 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) quint32 actualSwapChainBufferCount = 0; err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, nullptr); - if (err != VK_SUCCESS || actualSwapChainBufferCount < 2) { - qWarning("Failed to get swapchain images: %d (count=%u)", err, actualSwapChainBufferCount); + if (err != VK_SUCCESS || actualSwapChainBufferCount == 0) { + qWarning("Failed to get swapchain images: %d", err); return false; } @@ -1528,7 +1528,8 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain) QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) { QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain); - QVkSwapChain::FrameResources &frame(swapChainD->frameRes[swapChainD->currentFrameSlot]); + const int frameResIndex = swapChainD->bufferCount > 1 ? swapChainD->currentFrameSlot : 0; + QVkSwapChain::FrameResources &frame(swapChainD->frameRes[frameResIndex]); QRhiProfilerPrivate *rhiP = profilerPrivateOrNull(); if (!frame.imageAcquired) { @@ -1571,7 +1572,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin // will make B wait for A's frame 0 commands, so if a resource is written // in B's frame or when B checks for pending resource releases, that won't // mess up A's in-flight commands (as they are not in flight anymore). - waitCommandCompletion(int(swapChainD->currentFrameSlot)); + waitCommandCompletion(frameResIndex); // Now is the time to read the timestamps for the previous frame for this slot. if (frame.timestampQueryIndex >= 0) { @@ -1606,7 +1607,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin // when profiling is enabled, pick a free query (pair) from the pool int timestampQueryIdx = -1; - if (profilerPrivateOrNull()) { + if (profilerPrivateOrNull() && swapChainD->bufferCount > 1) { // no timestamps if not having at least 2 frames in flight for (int i = 0; i < timestampQueryPoolMap.count(); ++i) { if (!timestampQueryPoolMap.testBit(i)) { timestampQueryPoolMap.setBit(i); @@ -1648,7 +1649,8 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram recordPrimaryCommandBuffer(&swapChainD->cbWrapper); - QVkSwapChain::FrameResources &frame(swapChainD->frameRes[swapChainD->currentFrameSlot]); + int frameResIndex = swapChainD->bufferCount > 1 ? swapChainD->currentFrameSlot : 0; + QVkSwapChain::FrameResources &frame(swapChainD->frameRes[frameResIndex]); QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImageIndex]); if (image.lastUse != QVkSwapChain::ImageResources::ScImageUseRender) { @@ -1860,7 +1862,8 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer void QRhiVulkan::waitCommandCompletion(int frameSlot) { for (QVkSwapChain *sc : qAsConst(swapchains)) { - QVkSwapChain::FrameResources &frame(sc->frameRes[frameSlot]); + const int frameResIndex = sc->bufferCount > 1 ? frameSlot : 0; + QVkSwapChain::FrameResources &frame(sc->frameRes[frameResIndex]); if (frame.cmdFenceWaitable) { df->vkWaitForFences(dev, 1, &frame.cmdFence, VK_TRUE, UINT64_MAX); df->vkResetFences(dev, 1, &frame.cmdFence); |