1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QVULKANWINDOW_P_H
41#define QVULKANWINDOW_P_H
42
43#include <QtGui/private/qtguiglobal_p.h>
44
45#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
46
47#include "qvulkanwindow.h"
48#include <QtCore/QHash>
49#include <private/qwindow_p.h>
50
51//
52// W A R N I N G
53// -------------
54//
55// This file is not part of the Qt API. It exists for the convenience
56// of a number of Qt sources files. This header file may change from
57// version to version without notice, or even be removed.
58//
59// We mean it.
60//
61
62QT_BEGIN_NAMESPACE
63
64class Q_GUI_EXPORT QVulkanWindowPrivate : public QWindowPrivate
65{
66 Q_DECLARE_PUBLIC(QVulkanWindow)
67
68public:
69 ~QVulkanWindowPrivate();
70
71 void ensureStarted();
72 void init();
73 void reset();
74 bool createDefaultRenderPass();
75 void recreateSwapChain();
76 uint32_t chooseTransientImageMemType(VkImage img, uint32_t startIndex);
77 bool createTransientImage(VkFormat format, VkImageUsageFlags usage, VkImageAspectFlags aspectMask,
78 VkImage *images, VkDeviceMemory *mem, VkImageView *views, int count);
79 void releaseSwapChain();
80 void beginFrame();
81 void endFrame();
82 bool checkDeviceLost(VkResult err);
83 void addReadback();
84 void finishBlockingReadback();
85
86 enum Status {
87 StatusUninitialized,
88 StatusFail,
89 StatusFailRetry,
90 StatusDeviceReady,
91 StatusReady
92 };
93 Status status = StatusUninitialized;
94 QVulkanWindowRenderer *renderer = nullptr;
95 QVulkanInstance *inst = nullptr;
96 VkSurfaceKHR surface = VK_NULL_HANDLE;
97 int physDevIndex = 0;
98 QList<VkPhysicalDevice> physDevs;
99 QList<VkPhysicalDeviceProperties> physDevProps;
100 QVulkanWindow::Flags flags;
101 QByteArrayList requestedDevExtensions;
102 QHash<VkPhysicalDevice, QVulkanInfoVector<QVulkanExtension> > supportedDevExtensions;
103 QList<VkFormat> requestedColorFormats;
104 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
105 QVulkanWindow::QueueCreateInfoModifier queueCreateInfoModifier;
106
107 VkDevice dev = VK_NULL_HANDLE;
108 QVulkanDeviceFunctions *devFuncs;
109 uint32_t gfxQueueFamilyIdx;
110 uint32_t presQueueFamilyIdx;
111 VkQueue gfxQueue;
112 VkQueue presQueue;
113 VkCommandPool cmdPool = VK_NULL_HANDLE;
114 VkCommandPool presCmdPool = VK_NULL_HANDLE;
115 uint32_t hostVisibleMemIndex;
116 uint32_t deviceLocalMemIndex;
117 VkFormat colorFormat;
118 VkColorSpaceKHR colorSpace;
119 VkFormat dsFormat = VK_FORMAT_D24_UNORM_S8_UINT;
120
121 PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
122 PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
123 PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
124 PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
125 PFN_vkQueuePresentKHR vkQueuePresentKHR;
126 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
127 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
128
129 static const int MAX_SWAPCHAIN_BUFFER_COUNT = 3;
130 static const int MAX_FRAME_LAG = QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT;
131 // QVulkanWindow only supports the always available FIFO mode. The
132 // rendering thread will get throttled to the presentation rate (vsync).
133 // This is in effect Example 5 from the VK_KHR_swapchain spec.
134 VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
135 int swapChainBufferCount = 2;
136 int frameLag = 2;
137
138 QSize swapChainImageSize;
139 VkSwapchainKHR swapChain = VK_NULL_HANDLE;
140 bool swapChainSupportsReadBack = false;
141
142 struct ImageResources {
143 VkImage image = VK_NULL_HANDLE;
144 VkImageView imageView = VK_NULL_HANDLE;
145 VkCommandBuffer cmdBuf = VK_NULL_HANDLE;
146 VkFence cmdFence = VK_NULL_HANDLE;
147 bool cmdFenceWaitable = false;
148 VkFramebuffer fb = VK_NULL_HANDLE;
149 VkCommandBuffer presTransCmdBuf = VK_NULL_HANDLE;
150 VkImage msaaImage = VK_NULL_HANDLE;
151 VkImageView msaaImageView = VK_NULL_HANDLE;
152 } imageRes[MAX_SWAPCHAIN_BUFFER_COUNT];
153
154 VkDeviceMemory msaaImageMem = VK_NULL_HANDLE;
155
156 uint32_t currentImage;
157
158 struct FrameResources {
159 VkFence fence = VK_NULL_HANDLE;
160 bool fenceWaitable = false;
161 VkSemaphore imageSem = VK_NULL_HANDLE;
162 VkSemaphore drawSem = VK_NULL_HANDLE;
163 VkSemaphore presTransSem = VK_NULL_HANDLE;
164 bool imageAcquired = false;
165 bool imageSemWaitable = false;
166 } frameRes[MAX_FRAME_LAG];
167
168 uint32_t currentFrame;
169
170 VkRenderPass defaultRenderPass = VK_NULL_HANDLE;
171
172 VkDeviceMemory dsMem = VK_NULL_HANDLE;
173 VkImage dsImage = VK_NULL_HANDLE;
174 VkImageView dsView = VK_NULL_HANDLE;
175
176 bool framePending = false;
177 bool frameGrabbing = false;
178 QImage frameGrabTargetImage;
179 VkImage frameGrabImage = VK_NULL_HANDLE;
180 VkDeviceMemory frameGrabImageMem = VK_NULL_HANDLE;
181
182 QMatrix4x4 m_clipCorrect;
183};
184
185QT_END_NAMESPACE
186
187#endif // QT_CONFIG(vulkan)
188
189#endif
190