1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qxcbvulkaninstance.h"
5#include "qxcbwindow.h"
6#include "qxcbscreen.h"
7
8QT_BEGIN_NAMESPACE
9
10QXcbVulkanInstance::QXcbVulkanInstance(QVulkanInstance *instance)
11 : m_instance(instance),
12 m_getPhysDevPresSupport(nullptr),
13 m_createSurface(nullptr)
14{
15 loadVulkanLibrary(QStringLiteral("vulkan"), defaultLibraryVersion: 1);
16}
17
18QXcbVulkanInstance::~QXcbVulkanInstance()
19{
20}
21
22void QXcbVulkanInstance::createOrAdoptInstance()
23{
24 initInstance(instance: m_instance, extraExts: QByteArrayList() << QByteArrayLiteral("VK_KHR_xcb_surface"));
25
26 if (!m_vkInst)
27 return;
28
29 m_getPhysDevPresSupport = reinterpret_cast<PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR>(
30 m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
31 if (!m_getPhysDevPresSupport)
32 qWarning(msg: "Failed to find vkGetPhysicalDeviceXcbPresentationSupportKHR");
33}
34
35bool QXcbVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
36 uint32_t queueFamilyIndex,
37 QWindow *window)
38{
39 if (!m_getPhysDevPresSupport || !m_getPhysDevSurfaceSupport)
40 return true;
41
42 QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
43 if (!w) {
44 qWarning(msg: "Attempted to call supportsPresent() without a valid platform window");
45 return false;
46 }
47 xcb_connection_t *connection = w->xcbScreen()->xcb_connection();
48 bool ok = m_getPhysDevPresSupport(physicalDevice, queueFamilyIndex, connection, w->visualId());
49
50 VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
51 VkBool32 supported = false;
52 m_getPhysDevSurfaceSupport(physicalDevice, queueFamilyIndex, surface, &supported);
53 ok &= bool(supported);
54
55 return ok;
56}
57
58VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
59{
60 VkSurfaceKHR surface = VK_NULL_HANDLE;
61
62 if (!m_createSurface) {
63 m_createSurface = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(
64 m_vkGetInstanceProcAddr(m_vkInst, "vkCreateXcbSurfaceKHR"));
65 }
66 if (!m_createSurface) {
67 qWarning(msg: "Failed to find vkCreateXcbSurfaceKHR");
68 return surface;
69 }
70
71 VkXcbSurfaceCreateInfoKHR surfaceInfo;
72 memset(s: &surfaceInfo, c: 0, n: sizeof(surfaceInfo));
73 surfaceInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
74 surfaceInfo.connection = window->xcbScreen()->xcb_connection();
75 surfaceInfo.window = window->xcb_window();
76 VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
77 if (err != VK_SUCCESS)
78 qWarning(msg: "Failed to create Vulkan surface: %d", err);
79
80 return surface;
81}
82
83void QXcbVulkanInstance::presentQueued(QWindow *window)
84{
85 QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
86 if (!w) {
87 qWarning(msg: "Attempted to call presentQueued() without a valid platform window");
88 return;
89 }
90
91 if (w->needsSync())
92 w->postSyncWindowRequest();
93}
94
95QT_END_NAMESPACE
96

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