Skip to content

Commit f1a23a5

Browse files
committed
Basic Vulkan enablers
For Android, Windows and xcb. Verified on Win10 with NVIDIA, Win10 with AMD, Android with Tegra K1, Android aarch64 with Tegra X1, and Linux aarch64 with Tegra X1 (Jetson TX1, L4T). Introduce QPA-based Vulkan library loader, core function resolver, and instance creation support. In addition to creating a new VkInstance, adopting an existing one from an external engine is supported as well. The WSI specifics are hidden in the platform plugins. Vulkan-capable windows use the new surface type VulkanSurface and are associated with a QVulkanInstance. On Windows VULKAN_SDK is picked up automatically so finding vulkan.h needs no additional manual steps once the LunarG SDK is installed. [ChangeLog][QtGui] Added support for rendering to QWindow via the Vulkan graphics API. Task-number: QTBUG-55981 Change-Id: I50fa92d313fa440e0cc73939c6d7510ca317fbc9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
1 parent a512c9c commit f1a23a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+9981
-19
lines changed

config.tests/qpa/vulkan/vulkan.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 config.tests 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+
// This is a header-only test. Qt does not rely on linking to a Vulkan library directly.
41+
42+
#include <vulkan/vulkan.h>
43+
44+
// The pData parameter has changed from uint32_t* to void* at some point.
45+
// Ensure the headers have the updated one to prevent compile errors later on.
46+
PFN_vkCmdUpdateBuffer cmdUpdBuf;
47+
void testUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
48+
{
49+
cmdUpdBuf(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
50+
}
51+
52+
int main(int, char **)
53+
{
54+
VkInstanceCreateInfo info;
55+
testUpdateBuffer(0, 0, 0, 0, 0);
56+
57+
return 0;
58+
}

config.tests/qpa/vulkan/vulkan.pro

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SOURCES = vulkan.cpp

mkspecs/common/linux.conf

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ QMAKE_LIBS_OPENGL = -lGL
3535
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
3636
QMAKE_LIBS_OPENVG = -lOpenVG
3737
QMAKE_LIBS_THREAD = -lpthread
38+
QMAKE_LIBS_VULKAN =
3839

3940
QMAKE_INCDIR_WAYLAND =
4041
QMAKE_LIBS_WAYLAND_CLIENT = -lwayland-client

mkspecs/common/msvc-desktop.conf

+1
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,4 @@ VCSOLUTION_EXTENSION = .sln
106106
VCPROJ_KEYWORD = Qt4VSv1.0
107107

108108
include(windows-gles.conf)
109+
include(windows-vulkan.conf)

mkspecs/common/windows-vulkan.conf

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Pick up the VULKAN_SDK env var set by the LunarG SDK so that the Vulkan
2+
# headers are found out-of-the-box on typical Windows setups.
3+
4+
QMAKE_INCDIR_VULKAN = $(VULKAN_SDK)\\include
5+
QMAKE_LIBS_VULKAN =

mkspecs/win32-g++/qmake.conf

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
8080
QMAKE_NM = $${CROSS_COMPILE}nm -P
8181

8282
include(../common/windows-gles.conf)
83+
include(../common/windows-vulkan.conf)
8384
include(../common/gcc-base.conf)
8485

8586
load(qt_config)

mkspecs/win32-icc/qmake.conf

+1
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,6 @@ QMAKE_LIB = xilib /NOLOGO
5959
DSP_EXTENSION = .dsp
6060

6161
include(../common/windows-gles.conf)
62+
include(../common/windows-vulkan.conf)
6263

6364
load(qt_config)

src/gui/configure.json

+15
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"qpa-platform-guard": "boolean",
3939
"sm": { "type": "boolean", "name": "sessionmanager" },
4040
"tslib": "boolean",
41+
"vulkan": "boolean",
4142
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
4243
"xcb-xlib": "boolean",
4344
"xinput2": "boolean",
@@ -211,6 +212,14 @@
211212
"-lts"
212213
]
213214
},
215+
"vulkan": {
216+
"label": "Vulkan",
217+
"test": "qpa/vulkan",
218+
"sources": [
219+
{ "type": "pkgConfig", "args": "vulkan" },
220+
{ "type": "makeSpec", "spec": "VULKAN" }
221+
]
222+
},
214223
"wayland_server": {
215224
"label": "Wayland Server",
216225
"test": "qpa/wayland-server",
@@ -605,6 +614,11 @@
605614
"condition": "features.opengl-desktop || features.opengl-dynamic || features.opengles2",
606615
"output": [ "publicFeature", "feature" ]
607616
},
617+
"vulkan": {
618+
"label": "Vulkan",
619+
"condition": "libs.vulkan",
620+
"output": [ "publicFeature" ]
621+
},
608622
"openvg": {
609623
"label": "OpenVG",
610624
"condition": "libs.openvg",
@@ -1096,6 +1110,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
10961110
"opengles31"
10971111
]
10981112
},
1113+
"vulkan",
10991114
"sessionmanager"
11001115
]
11011116
},

src/gui/gui.pro

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ include(math3d/math3d.pri)
4646
include(opengl/opengl.pri)
4747
include(animation/animation.pri)
4848
include(itemmodels/itemmodels.pri)
49+
include(vulkan/vulkan.pri)
4950

5051
QMAKE_LIBS += $$QMAKE_LIBS_GUI
5152

src/gui/kernel/qplatformintegration.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -629,4 +629,26 @@ void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const
629629
Q_UNUSED(icon);
630630
}
631631

632+
#if QT_CONFIG(vulkan)
633+
634+
/*!
635+
Factory function for QPlatformVulkanInstance. The \a instance parameter is a
636+
pointer to the instance for which a platform-specific backend needs to be
637+
created.
638+
639+
Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could
640+
not be created.
641+
642+
\sa QVulkanInstance
643+
\since 5.10
644+
*/
645+
QPlatformVulkanInstance *QPlatformIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
646+
{
647+
Q_UNUSED(instance);
648+
qWarning("This plugin does not support createPlatformVulkanInstance");
649+
return nullptr;
650+
}
651+
652+
#endif // QT_CONFIG(vulkan)
653+
632654
QT_END_NAMESPACE

src/gui/kernel/qplatformintegration.h

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class QPlatformSessionManager;
7878
class QKeyEvent;
7979
class QPlatformOffscreenSurface;
8080
class QOffscreenSurface;
81+
class QPlatformVulkanInstance;
82+
class QVulkanInstance;
8183

8284
class Q_GUI_EXPORT QPlatformIntegration
8385
{
@@ -190,6 +192,10 @@ class Q_GUI_EXPORT QPlatformIntegration
190192

191193
virtual void beep() const;
192194

195+
#if QT_CONFIG(vulkan)
196+
virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const;
197+
#endif
198+
193199
protected:
194200
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
195201
void destroyScreen(QPlatformScreen *screen);

src/gui/kernel/qsurface.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ QT_BEGIN_NAMESPACE
7878
requires the use of private API.
7979
\value OpenVGSurface The surface is an OpenVG compatible surface and can be used
8080
in conjunction with OpenVG contexts.
81+
\value VulkanSurface The surface is a Vulkan compatible surface and can be used
82+
in conjunction with the Vulkan graphics API.
8183
*/
8284

8385

src/gui/kernel/qsurface.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class Q_GUI_EXPORT QSurface
6666
OpenGLSurface,
6767
RasterGLSurface,
6868
OpenVGSurface,
69+
VulkanSurface
6970
};
7071

7172
virtual ~QSurface();

src/gui/kernel/qwindow.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -2797,6 +2797,30 @@ QDebug operator<<(QDebug debug, const QWindow *window)
27972797
}
27982798
#endif // !QT_NO_DEBUG_STREAM
27992799

2800+
#if QT_CONFIG(vulkan)
2801+
2802+
/*!
2803+
Associates this window with the specified Vulkan \a instance.
2804+
2805+
\a instance must stay valid as long as this QWindow instance exists.
2806+
*/
2807+
void QWindow::setVulkanInstance(QVulkanInstance *instance)
2808+
{
2809+
Q_D(QWindow);
2810+
d->vulkanInstance = instance;
2811+
}
2812+
2813+
/*!
2814+
\return the associrated Vulkan instance or \c null if there is none.
2815+
*/
2816+
QVulkanInstance *QWindow::vulkanInstance() const
2817+
{
2818+
Q_D(const QWindow);
2819+
return d->vulkanInstance;
2820+
}
2821+
2822+
#endif // QT_CONFIG(vulkan)
2823+
28002824
QT_END_NAMESPACE
28012825

28022826
#include "moc_qwindow.cpp"

src/gui/kernel/qwindow.h

+8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class QWindowContainer;
8888
#ifndef QT_NO_DEBUG_STREAM
8989
class QDebug;
9090
#endif
91+
#if QT_CONFIG(vulkan)
92+
class QVulkanInstance;
93+
#endif
9194

9295
class Q_GUI_EXPORT QWindow : public QObject, public QSurface
9396
{
@@ -269,6 +272,11 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
269272

270273
static QWindow *fromWinId(WId id);
271274

275+
#if QT_CONFIG(vulkan)
276+
void setVulkanInstance(QVulkanInstance *instance);
277+
QVulkanInstance *vulkanInstance() const;
278+
#endif
279+
272280
public Q_SLOTS:
273281
Q_REVISION(1) void requestActivate();
274282

src/gui/kernel/qwindow_p.h

+7
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate
105105
, hasCursor(false)
106106
#endif
107107
, compositing(false)
108+
#if QT_CONFIG(vulkan)
109+
, vulkanInstance(nullptr)
110+
#endif
108111
{
109112
isWindow = true;
110113
}
@@ -196,6 +199,10 @@ class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate
196199

197200
bool compositing;
198201
QElapsedTimer lastComposeTime;
202+
203+
#if QT_CONFIG(vulkan)
204+
QVulkanInstance *vulkanInstance;
205+
#endif
199206
};
200207

201208

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
#include "qplatformvulkaninstance.h"
41+
42+
QT_BEGIN_NAMESPACE
43+
44+
/*!
45+
\class QPlatformVulkanInstance
46+
\since 5.10
47+
\internal
48+
\preliminary
49+
\ingroup qpa
50+
51+
\brief The QPlatformVulkanInstance class provides an abstraction for Vulkan instances.
52+
53+
The platform Vulkan instance is responsible for loading a Vulkan library,
54+
resolving the basic entry points for creating instances, providing support
55+
for creating new or adopting existing VkInstances, and abstracting some
56+
WSI-specifics like checking if a given queue family can be used to present
57+
using a given window.
58+
59+
\note platform plugins will typically subclass not this class, but rather
60+
QBasicVulkanPlatformInstance.
61+
62+
\note Vulkan instance creation is split into two phases: a new
63+
QPlatformVulkanInstance is expected to load the Vulkan library and do basic
64+
initialization, after which the supported layers and extensions can be
65+
queried. Everything else is deferred into createOrAdoptInstance().
66+
*/
67+
68+
class QPlatformVulkanInstancePrivate
69+
{
70+
public:
71+
QPlatformVulkanInstancePrivate() { }
72+
};
73+
74+
QPlatformVulkanInstance::QPlatformVulkanInstance()
75+
: d_ptr(new QPlatformVulkanInstancePrivate)
76+
{
77+
}
78+
79+
QPlatformVulkanInstance::~QPlatformVulkanInstance()
80+
{
81+
}
82+
83+
void QPlatformVulkanInstance::presentQueued(QWindow *window)
84+
{
85+
Q_UNUSED(window);
86+
}
87+
88+
QT_END_NAMESPACE

0 commit comments

Comments
 (0)