1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of plugins 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#include "qxcbvulkaninstance.h"
41#include "qxcbwindow.h"
42#include "qxcbscreen.h"
43
44QT_BEGIN_NAMESPACE
45
46QXcbVulkanInstance::QXcbVulkanInstance(QVulkanInstance *instance)
47 : m_instance(instance),
48 m_getPhysDevPresSupport(nullptr),
49 m_createSurface(nullptr)
50{
51 loadVulkanLibrary(QStringLiteral("vulkan"));
52}
53
54QXcbVulkanInstance::~QXcbVulkanInstance()
55{
56}
57
58void QXcbVulkanInstance::createOrAdoptInstance()
59{
60 initInstance(instance: m_instance, extraExts: QByteArrayList() << QByteArrayLiteral("VK_KHR_xcb_surface"));
61
62 if (!m_vkInst)
63 return;
64
65 m_getPhysDevPresSupport = reinterpret_cast<PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR>(
66 m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
67 if (!m_getPhysDevPresSupport)
68 qWarning(msg: "Failed to find vkGetPhysicalDeviceXcbPresentationSupportKHR");
69}
70
71bool QXcbVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
72 uint32_t queueFamilyIndex,
73 QWindow *window)
74{
75 if (!m_getPhysDevPresSupport || !m_getPhysDevSurfaceSupport)
76 return true;
77
78 QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
79 if (!w) {
80 qWarning(msg: "Attempted to call supportsPresent() without a valid platform window");
81 return false;
82 }
83 xcb_connection_t *connection = w->xcbScreen()->xcb_connection();
84 bool ok = m_getPhysDevPresSupport(physicalDevice, queueFamilyIndex, connection, w->visualId());
85
86 VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
87 VkBool32 supported = false;
88 m_getPhysDevSurfaceSupport(physicalDevice, queueFamilyIndex, surface, &supported);
89 ok &= bool(supported);
90
91 return ok;
92}
93
94VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
95{
96 VkSurfaceKHR surface = VK_NULL_HANDLE;
97
98 if (!m_createSurface) {
99 m_createSurface = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(
100 m_vkGetInstanceProcAddr(m_vkInst, "vkCreateXcbSurfaceKHR"));
101 }
102 if (!m_createSurface) {
103 qWarning(msg: "Failed to find vkCreateXcbSurfaceKHR");
104 return surface;
105 }
106
107 VkXcbSurfaceCreateInfoKHR surfaceInfo;
108 memset(s: &surfaceInfo, c: 0, n: sizeof(surfaceInfo));
109 surfaceInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
110 surfaceInfo.connection = window->xcbScreen()->xcb_connection();
111 surfaceInfo.window = window->xcb_window();
112 VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
113 if (err != VK_SUCCESS)
114 qWarning(msg: "Failed to create Vulkan surface: %d", err);
115
116 return surface;
117}
118
119void QXcbVulkanInstance::presentQueued(QWindow *window)
120{
121 QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
122 if (!w) {
123 qWarning(msg: "Attempted to call presentQueued() without a valid platform window");
124 return;
125 }
126
127 if (w->needsSync())
128 w->postSyncWindowRequest();
129}
130
131QT_END_NAMESPACE
132

source code of qtbase/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp