summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/configure.json37
-rw-r--r--src/gui/doc/qtgui.qdocconf1
-rw-r--r--src/gui/doc/src/external-resources.qdoc10
-rw-r--r--src/gui/doc/src/qtgui.qdoc35
-rw-r--r--src/gui/gui.pro1
-rw-r--r--src/gui/image/qiconloader.cpp14
-rw-r--r--src/gui/image/qiconloader_p.h3
-rw-r--r--src/gui/image/qimagereader.cpp11
-rw-r--r--src/gui/image/qimagewriter.cpp10
-rw-r--r--src/gui/image/qimagewriter.h3
-rw-r--r--src/gui/image/qmovie.cpp48
-rw-r--r--src/gui/image/qmovie.h2
-rw-r--r--src/gui/image/qpixmap.cpp71
-rw-r--r--src/gui/image/qplatformpixmap.cpp76
-rw-r--r--src/gui/image/qplatformpixmap.h8
-rw-r--r--src/gui/image/qxpmhandler.cpp5
-rw-r--r--src/gui/kernel/qclipboard.cpp2
-rw-r--r--src/gui/kernel/qcursor.cpp48
-rw-r--r--src/gui/kernel/qcursor.h4
-rw-r--r--src/gui/kernel/qdnd.cpp5
-rw-r--r--src/gui/kernel/qdnd_p.h1
-rw-r--r--src/gui/kernel/qguiapplication.cpp31
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qkeysequence.cpp8
-rw-r--r--src/gui/kernel/qoffscreensurface.cpp20
-rw-r--r--src/gui/kernel/qoffscreensurface.h3
-rw-r--r--src/gui/kernel/qpalette.cpp8
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp26
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h5
-rw-r--r--src/gui/kernel/qplatformdrag.h1
-rw-r--r--src/gui/kernel/qplatformintegration.cpp31
-rw-r--r--src/gui/kernel/qplatformintegration.h10
-rw-r--r--src/gui/kernel/qplatformmenu.cpp31
-rw-r--r--src/gui/kernel/qplatformmenu.h18
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.cpp11
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h2
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qplatformtheme.h3
-rw-r--r--src/gui/kernel/qplatformwindow.cpp2
-rw-r--r--src/gui/kernel/qplatformwindow.h2
-rw-r--r--src/gui/kernel/qsimpledrag.cpp7
-rw-r--r--src/gui/kernel/qsimpledrag_p.h1
-rw-r--r--src/gui/kernel/qstylehints.cpp11
-rw-r--r--src/gui/kernel/qstylehints.h2
-rw-r--r--src/gui/kernel/qsurface.cpp2
-rw-r--r--src/gui/kernel/qsurface.h1
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp69
-rw-r--r--src/gui/kernel/qsurfaceformat.h9
-rw-r--r--src/gui/kernel/qwindow.cpp146
-rw-r--r--src/gui/kernel/qwindow.h10
-rw-r--r--src/gui/kernel/qwindow_p.h11
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp10
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h6
-rw-r--r--src/gui/painting/painting.pri3
-rw-r--r--src/gui/painting/qbrush.cpp2
-rw-r--r--src/gui/painting/qcolor.cpp33
-rw-r--r--src/gui/painting/qcolor.h16
-rw-r--r--src/gui/painting/qdrawhelper.cpp645
-rw-r--r--src/gui/painting/qgrayraster.c809
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp12
-rw-r--r--src/gui/painting/qpagedpaintdevice.h2
-rw-r--r--src/gui/painting/qpaintengine.cpp8
-rw-r--r--src/gui/painting/qpaintengine_p.h25
-rw-r--r--src/gui/painting/qpdf.cpp305
-rw-r--r--src/gui/painting/qpdf.qrc7
-rw-r--r--src/gui/painting/qpdf_p.h11
-rw-r--r--src/gui/painting/qpdfa_metadata.xml16
-rw-r--r--src/gui/painting/qpdfwriter.cpp31
-rw-r--r--src/gui/painting/qpdfwriter.h3
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp34
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/text/qdistancefield.cpp10
-rw-r--r--src/gui/text/qfontsubset.cpp8
-rw-r--r--src/gui/text/qstatictext.h2
-rw-r--r--src/gui/text/qtextdocument.cpp2
-rw-r--r--src/gui/text/qtextengine_p.h17
-rw-r--r--src/gui/text/qtexthtmlparser.cpp14
-rw-r--r--src/gui/text/qtexthtmlparser_p.h1
-rw-r--r--src/gui/text/qtextlayout.cpp58
-rw-r--r--src/gui/util/qvalidator.cpp12
-rw-r--r--src/gui/vulkan/KHRONOS_LICENSE.txt20
-rw-r--r--src/gui/vulkan/qplatformvulkaninstance.cpp88
-rw-r--r--src/gui/vulkan/qplatformvulkaninstance.h91
-rw-r--r--src/gui/vulkan/qt_attribution.json17
-rw-r--r--src/gui/vulkan/qvulkanfunctions.cpp177
-rw-r--r--src/gui/vulkan/qvulkaninstance.cpp894
-rw-r--r--src/gui/vulkan/qvulkaninstance.h198
-rw-r--r--src/gui/vulkan/qvulkanwindow.cpp2719
-rw-r--r--src/gui/vulkan/qvulkanwindow.h161
-rw-r--r--src/gui/vulkan/qvulkanwindow_p.h188
-rw-r--r--src/gui/vulkan/vk.xml5269
-rw-r--r--src/gui/vulkan/vulkan.pri52
93 files changed, 11841 insertions, 1021 deletions
diff --git a/src/gui/configure.json b/src/gui/configure.json
index f8cee387b8..672128a789 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -38,7 +38,9 @@
"qpa-platform-guard": "boolean",
"sm": { "type": "boolean", "name": "sessionmanager" },
"tslib": "boolean",
+ "vulkan": "boolean",
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
+ "xcb-native-painting": "boolean",
"xcb-xlib": "boolean",
"xinput2": "boolean",
"xkb": "boolean",
@@ -212,6 +214,14 @@
"-lts"
]
},
+ "vulkan": {
+ "label": "Vulkan",
+ "test": "qpa/vulkan",
+ "sources": [
+ { "type": "pkgConfig", "args": "vulkan" },
+ { "type": "makeSpec", "spec": "VULKAN" }
+ ]
+ },
"wayland_server": {
"label": "Wayland Server",
"test": "qpa/wayland-server",
@@ -296,6 +306,13 @@
"sources": [
{ "type": "pkgConfig", "args": "xkbcommon xkbcommon-x11 >= 0.4.1" }
]
+ },
+ "xrender": {
+ "label": "XRender for native painting",
+ "test": "x11/xrender",
+ "sources": [
+ "-lXrender"
+ ]
}
},
@@ -599,6 +616,11 @@
"condition": "features.opengl-desktop || features.opengl-dynamic || features.opengles2",
"output": [ "publicFeature", "feature" ]
},
+ "vulkan": {
+ "label": "Vulkan",
+ "condition": "libs.vulkan",
+ "output": [ "publicFeature" ]
+ },
"openvg": {
"label": "OpenVG",
"condition": "libs.openvg",
@@ -741,6 +763,18 @@
"condition": "libs.xcb_glx",
"output": [ "privateFeature" ]
},
+ "xcb-native-painting": {
+ "label": "Native painting (experimental)",
+ "emitIf": "features.xcb",
+ "condition": "features.xcb-xlib && libs.xrender",
+ "output": [ "privateFeature" ]
+ },
+ "xrender": {
+ "label": "XRender for native painting",
+ "emitIf": "features.xcb && features.xcb-native-painting",
+ "condition": "features.xcb-native-painting",
+ "output": [ "privateFeature" ]
+ },
"xcb-render": {
"label": "XCB render",
"emitIf": "features.xcb",
@@ -1088,6 +1122,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
"opengles31"
]
},
+ "vulkan",
"sessionmanager"
]
},
@@ -1130,7 +1165,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
"section": "X11",
"condition": "features.xcb",
"entries": [
- "system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system"
+ "system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
]
},
{
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index bac93af775..3b3ebafc2d 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -49,6 +49,7 @@ sourcedirs += .. \
src/includes
exampledirs += ../../../examples/gui \
+ ../../../examples/vulkan \
snippets
imagedirs += images \
diff --git a/src/gui/doc/src/external-resources.qdoc b/src/gui/doc/src/external-resources.qdoc
index 480a4057be..0addbb21cd 100644
--- a/src/gui/doc/src/external-resources.qdoc
+++ b/src/gui/doc/src/external-resources.qdoc
@@ -60,3 +60,13 @@
\externalpage https://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#directory_layout
\title Icon Theme Specification - Directory Layout
*/
+
+/*!
+ \externalpage https://www.khronos.org/vulkan/
+ \title Vulkan
+*/
+
+/*!
+ \externalpage https://www.lunarg.com/vulkan-sdk/
+ \title LunarG Vulkan SDK
+*/
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index a9fe520d5e..da3d419735 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -35,11 +35,11 @@
applications written with Qt.
The Qt GUI module provides classes for windowing system
- integration, event handling, OpenGL and OpenGL ES integration, 2D
- graphics, imaging, fonts and typography. These classes are used
- internally by Qt's user interface technologies and can also be
- used directly, for instance to write applications using low-level
- OpenGL ES graphics APIs.
+ integration, event handling, OpenGL and OpenGL ES integration,
+ Vulkan integration, 2D graphics, imaging, fonts and typography.
+ These classes are used internally by Qt's user interface technologies
+ and can also be used directly, for instance to write applications using
+ low-level OpenGL ES graphics APIs.
To include the definitions of the module's classes, use the
following directive:
@@ -170,6 +170,31 @@
+ \section1 Vulkan Integration
+
+ Qt 5.10 added support for \l {Vulkan}. This requires
+ the presence of the \l{LunarG Vulkan SDK}.
+
+ On Windows, the SDK sets the environment variable \c {VULKAN_SDK},
+ which will be detected by the \c {configure} script.
+
+ On Android, Vulkan headers were added in API level 24 of the NDK.
+
+ Relevant classes:
+
+ \list
+ \li QVulkanDeviceFunctions
+ \li QVulkanExtension
+ \li QVulkanFunctions
+ \li QVulkanInfoVector
+ \li QVulkanInstance
+ \li QVulkanWindow
+ \li QVulkanWindowRenderer
+ \endlist
+
+ For more information, see the \l{Hello Vulkan Widget Example}
+ and the \l {Hello Vulkan Window Example}.
+
\section1 Qt GUI Prior to Qt 5.0
Prior to Qt 5.0, the Qt GUI module was the monolithic container
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index cfdb5e889b..02983123b1 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -46,6 +46,7 @@ include(math3d/math3d.pri)
include(opengl/opengl.pri)
include(animation/animation.pri)
include(itemmodels/itemmodels.pri)
+include(vulkan/vulkan.pri)
QMAKE_LIBS += $$QMAKE_LIBS_GUI
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 349e0dfbe3..3cb6f46bd6 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -609,18 +609,18 @@ static int directorySizeDistance(const QIconDirInfo &dir, int iconsize, int icon
return INT_MAX;
}
-QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size, int scale)
+QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QThemeIconInfo &info, const QSize &size, int scale)
{
int iconsize = qMin(size.width(), size.height());
// Note that m_info.entries are sorted so that png-files
// come first
- const int numEntries = m_info.entries.size();
+ const int numEntries = info.entries.size();
// Search for exact matches first
for (int i = 0; i < numEntries; ++i) {
- QIconLoaderEngineEntry *entry = m_info.entries.at(i);
+ QIconLoaderEngineEntry *entry = info.entries.at(i);
if (directoryMatchesSize(entry->dir, iconsize, scale)) {
return entry;
}
@@ -630,7 +630,7 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size, int s
int minimalSize = INT_MAX;
QIconLoaderEngineEntry *closestMatch = 0;
for (int i = 0; i < numEntries; ++i) {
- QIconLoaderEngineEntry *entry = m_info.entries.at(i);
+ QIconLoaderEngineEntry *entry = info.entries.at(i);
int distance = directorySizeDistance(entry->dir, iconsize, scale);
if (distance < minimalSize) {
minimalSize = distance;
@@ -654,7 +654,7 @@ QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode,
ensureLoaded();
- QIconLoaderEngineEntry *entry = entryForSize(size);
+ QIconLoaderEngineEntry *entry = entryForSize(m_info, size);
if (entry) {
const QIconDirInfo &dir = entry->dir;
if (dir.type == QIconDirInfo::Scalable)
@@ -718,7 +718,7 @@ QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode,
{
ensureLoaded();
- QIconLoaderEngineEntry *entry = entryForSize(size);
+ QIconLoaderEngineEntry *entry = entryForSize(m_info, size);
if (entry)
return entry->pixmap(size, mode, state);
@@ -767,7 +767,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
QIconEngine::ScaledPixmapArgument &arg = *reinterpret_cast<QIconEngine::ScaledPixmapArgument*>(data);
// QIcon::pixmap() multiplies size by the device pixel ratio.
const int integerScale = qCeil(arg.scale);
- QIconLoaderEngineEntry *entry = entryForSize(arg.size / integerScale, integerScale);
+ QIconLoaderEngineEntry *entry = entryForSize(m_info, arg.size / integerScale, integerScale);
arg.pixmap = entry ? entry->pixmap(arg.size, arg.mode, arg.state) : QPixmap();
}
break;
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index 5f3a3ef948..9398bca585 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -132,12 +132,13 @@ public:
bool read(QDataStream &in) Q_DECL_OVERRIDE;
bool write(QDataStream &out) const Q_DECL_OVERRIDE;
+ Q_GUI_EXPORT static QIconLoaderEngineEntry *entryForSize(const QThemeIconInfo &info, const QSize &size, int scale = 1);
+
private:
QString key() const Q_DECL_OVERRIDE;
bool hasIcon() const;
void ensureLoaded();
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
- QIconLoaderEngineEntry *entryForSize(const QSize &size, int scale = 1);
QIconLoaderEngine(const QIconLoaderEngine &other);
QThemeIconInfo m_info;
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index d01f0d640b..cd7c95b166 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -565,6 +565,16 @@ bool QImageReaderPrivate::initHandler()
// probe the file extension
if (deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly) && autoDetectImageFormat) {
+ Q_ASSERT(qobject_cast<QFile*>(device) != 0); // future-proofing; for now this should always be the case, so...
+ QFile *file = static_cast<QFile *>(device);
+
+ if (file->error() == QFileDevice::ResourceError) {
+ // this is bad. we should abort the open attempt and note the failure.
+ imageReaderError = QImageReader::DeviceError;
+ errorString = file->errorString();
+ return false;
+ }
+
QList<QByteArray> extensions = QImageReader::supportedImageFormats();
if (!format.isEmpty()) {
// Try the most probable extension first
@@ -575,7 +585,6 @@ bool QImageReaderPrivate::initHandler()
int currentExtension = 0;
- QFile *file = static_cast<QFile *>(device);
QString fileName = file->fileName();
do {
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index ab15d8ee29..a39d204677 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -87,6 +87,9 @@
\value UnsupportedFormatError Qt does not support the requested
image format.
+ \value InvalidImageError An attempt was made to write an invalid QImage. An
+ example of an invalid image would be a null QImage.
+
\value UnknownError An unknown error occurred. If you get this
value after calling write(), it is most likely caused by a bug in
QImageWriter.
@@ -736,6 +739,13 @@ extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orie
*/
bool QImageWriter::write(const QImage &image)
{
+ // Do this before canWrite, so it doesn't create a file if this fails.
+ if (Q_UNLIKELY(image.isNull())) {
+ d->imageWriterError = QImageWriter::InvalidImageError;
+ d->errorString = QImageWriter::tr("Image is empty");
+ return false;
+ }
+
if (!canWrite())
return false;
diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h
index 58f8c51472..fd1fdd07e8 100644
--- a/src/gui/image/qimagewriter.h
+++ b/src/gui/image/qimagewriter.h
@@ -60,7 +60,8 @@ public:
enum ImageWriterError {
UnknownError,
DeviceError,
- UnsupportedFormatError
+ UnsupportedFormatError,
+ InvalidImageError
};
QImageWriter();
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index 55ddd839b7..3889b747db 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -161,6 +161,8 @@
This signal is emitted by QMovie when the error \a error occurred during
playback. QMovie will stop the movie, and enter QMovie::NotRunning state.
+
+ \sa lastError(), lastErrorString()
*/
/*! \fn void QMovie::finished()
@@ -330,6 +332,8 @@ int QMoviePrivate::speedAdjustedDelay(int delay) const
*/
QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
{
+ Q_Q(QMovie);
+
if (frameNumber < 0)
return QFrameInfo(); // Invalid
@@ -358,7 +362,8 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
reader = new QImageReader(device, format);
else
reader = new QImageReader(absoluteFilePath, format);
- (void)reader->canRead(); // Provoke a device->open() call
+ if (!reader->canRead()) // Provoke a device->open() call
+ emit q->error(reader->error());
reader->device()->seek(initialDevicePos);
reader->setBackgroundColor(bgColor);
reader->setScaledSize(scaledSize);
@@ -525,8 +530,20 @@ void QMoviePrivate::_q_loadNextFrame(bool starting)
*/
bool QMoviePrivate::isValid() const
{
- return (greatestFrameNumber >= 0) // have we seen valid data
- || reader->canRead(); // or does the reader see valid data
+ Q_Q(const QMovie);
+
+ if (greatestFrameNumber >= 0)
+ return true; // have we seen valid data
+ bool canRead = reader->canRead();
+ if (!canRead) {
+ // let the consumer know it's broken
+ //
+ // ### the const_cast here is ugly, but 'const' of this method is
+ // technically wrong right now, since it may cause the underlying device
+ // to open.
+ emit const_cast<QMovie*>(q)->error(reader->error());
+ }
+ return canRead;
}
/*!
@@ -777,6 +794,8 @@ QImage QMovie::currentImage() const
/*!
Returns \c true if the movie is valid (e.g., the image data is readable and
the image format is supported); otherwise returns \c false.
+
+ For information about why the movie is not valid, see lastError().
*/
bool QMovie::isValid() const
{
@@ -785,6 +804,29 @@ bool QMovie::isValid() const
}
/*!
+ Returns the most recent error that occurred while attempting to read image data.
+
+ \sa lastErrorString()
+*/
+QImageReader::ImageReaderError QMovie::lastError() const
+{
+ Q_D(const QMovie);
+ return d->reader->error();
+}
+
+/*!
+ Returns a human-readable representation of the most recent error that occurred
+ while attempting to read image data.
+
+ \sa lastError()
+*/
+QString QMovie::lastErrorString() const
+{
+ Q_D(const QMovie);
+ return d->reader->errorString();
+}
+
+/*!
Returns the number of frames in the movie.
Certain animation formats do not support this feature, in which
diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h
index 2b41e07dba..ab8ef82aa0 100644
--- a/src/gui/image/qmovie.h
+++ b/src/gui/image/qmovie.h
@@ -106,6 +106,8 @@ public:
QPixmap currentPixmap() const;
bool isValid() const;
+ QImageReader::ImageReaderError lastError() const;
+ QString lastErrorString() const;
bool jumpToFrame(int frameNumber);
int loopCount() const;
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 0aa05a04e2..5b3e3985a7 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -596,44 +596,7 @@ void QPixmap::setMask(const QBitmap &mask)
return;
detach();
-
- QImage image = data->toImage();
- if (mask.size().isEmpty()) {
- if (image.depth() != 1) { // hw: ????
- image = image.convertToFormat(QImage::Format_RGB32);
- }
- } else {
- const int w = image.width();
- const int h = image.height();
-
- switch (image.depth()) {
- case 1: {
- const QImage imageMask = mask.toImage().convertToFormat(image.format());
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- uchar *tscan = image.scanLine(y);
- int bytesPerLine = image.bytesPerLine();
- for (int i = 0; i < bytesPerLine; ++i)
- tscan[i] &= mscan[i];
- }
- break;
- }
- default: {
- const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
- image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- QRgb *tscan = (QRgb *)image.scanLine(y);
- for (int x = 0; x < w; ++x) {
- if (!(mscan[x>>3] & (1 << (x&7))))
- tscan[x] = 0;
- }
- }
- break;
- }
- }
- }
- data->fromImage(image, Qt::AutoColor);
+ data->setMask(mask);
}
/*!
@@ -1496,37 +1459,7 @@ QPaintEngine *QPixmap::paintEngine() const
*/
QBitmap QPixmap::mask() const
{
- if (!data || !hasAlphaChannel())
- return QBitmap();
-
- const QImage img = toImage();
- bool shouldConvert = (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied);
- const QImage image = (shouldConvert ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img);
- const int w = image.width();
- const int h = image.height();
-
- QImage mask(w, h, QImage::Format_MonoLSB);
- if (mask.isNull()) // allocation failed
- return QBitmap();
-
- mask.setColorCount(2);
- mask.setColor(0, QColor(Qt::color0).rgba());
- mask.setColor(1, QColor(Qt::color1).rgba());
-
- const int bpl = mask.bytesPerLine();
-
- for (int y = 0; y < h; ++y) {
- const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y));
- uchar *dest = mask.scanLine(y);
- memset(dest, 0, bpl);
- for (int x = 0; x < w; ++x) {
- if (qAlpha(*src) > 0)
- dest[x >> 3] |= (1 << (x & 7));
- ++src;
- }
- }
-
- return QBitmap::fromImage(mask);
+ return data ? data->mask() : QBitmap();
}
/*!
diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp
index 00c21a5f54..b123afb4db 100644
--- a/src/gui/image/qplatformpixmap.cpp
+++ b/src/gui/image/qplatformpixmap.cpp
@@ -160,6 +160,82 @@ bool QPlatformPixmap::scroll(int dx, int dy, const QRect &rect)
return false;
}
+QBitmap QPlatformPixmap::mask() const
+{
+ if (!hasAlphaChannel())
+ return QBitmap();
+
+ const QImage img = toImage();
+ bool shouldConvert = (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied);
+ const QImage image = (shouldConvert ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img);
+ const int w = image.width();
+ const int h = image.height();
+
+ QImage mask(w, h, QImage::Format_MonoLSB);
+ if (mask.isNull()) // allocation failed
+ return QBitmap();
+
+ mask.setColorCount(2);
+ mask.setColor(0, QColor(Qt::color0).rgba());
+ mask.setColor(1, QColor(Qt::color1).rgba());
+
+ const int bpl = mask.bytesPerLine();
+
+ for (int y = 0; y < h; ++y) {
+ const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y));
+ uchar *dest = mask.scanLine(y);
+ memset(dest, 0, bpl);
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(*src) > 0)
+ dest[x >> 3] |= (1 << (x & 7));
+ ++src;
+ }
+ }
+
+ return QBitmap::fromImage(mask);
+}
+
+void QPlatformPixmap::setMask(const QBitmap &mask)
+{
+ QImage image = toImage();
+ if (mask.size().isEmpty()) {
+ if (image.depth() != 1) { // hw: ????
+ image = image.convertToFormat(QImage::Format_RGB32);
+ }
+ } else {
+ const int w = image.width();
+ const int h = image.height();
+
+ switch (image.depth()) {
+ case 1: {
+ const QImage imageMask = mask.toImage().convertToFormat(image.format());
+ for (int y = 0; y < h; ++y) {
+ const uchar *mscan = imageMask.scanLine(y);
+ uchar *tscan = image.scanLine(y);
+ int bytesPerLine = image.bytesPerLine();
+ for (int i = 0; i < bytesPerLine; ++i)
+ tscan[i] &= mscan[i];
+ }
+ break;
+ }
+ default: {
+ const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
+ image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ for (int y = 0; y < h; ++y) {
+ const uchar *mscan = imageMask.scanLine(y);
+ QRgb *tscan = (QRgb *)image.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ if (!(mscan[x>>3] & (1 << (x&7))))
+ tscan[x] = 0;
+ }
+ }
+ break;
+ }
+ }
+ }
+ fromImage(image, Qt::AutoColor);
+}
+
QPixmap QPlatformPixmap::transformed(const QTransform &matrix,
Qt::TransformationMode mode) const
{
diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h
index 8513755cca..7635ac2949 100644
--- a/src/gui/image/qplatformpixmap.h
+++ b/src/gui/image/qplatformpixmap.h
@@ -69,7 +69,7 @@ public:
enum ClassId { RasterClass, DirectFBClass,
BlitterClass, Direct2DClass,
- CustomClass = 1024 };
+ X11Class, CustomClass = 1024 };
QPlatformPixmap(PixelType pixelType, int classId);
virtual ~QPlatformPixmap();
@@ -99,6 +99,9 @@ public:
virtual int metric(QPaintDevice::PaintDeviceMetric metric) const = 0;
virtual void fill(const QColor &color) = 0;
+ virtual QBitmap mask() const;
+ virtual void setMask(const QBitmap &mask);
+
virtual bool hasAlphaChannel() const = 0;
virtual QPixmap transformed(const QTransform &matrix,
Qt::TransformationMode mode) const;
@@ -144,6 +147,7 @@ protected:
private:
friend class QPixmap;
+ friend class QX11PlatformPixmap;
friend class QImagePixmapCleanupHooks; // Needs to set is_cached
friend class QOpenGLTextureCache; //Needs to check the reference count
friend class QExplicitlySharedDataPointer<QPlatformPixmap>;
@@ -159,7 +163,7 @@ private:
# define QT_XFORM_TYPE_MSBFIRST 0
# define QT_XFORM_TYPE_LSBFIRST 1
-extern bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
+Q_GUI_EXPORT bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
QT_END_NAMESPACE
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index ce7f7b8a0f..9c54b9ada4 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -42,6 +42,7 @@
#ifndef QT_NO_IMAGEFORMAT_XPM
#include <private/qcolor_p.h>
+#include <qbytearraymatcher.h>
#include <qimage.h>
#include <qmap.h>
#include <qtextstream.h>
@@ -1041,7 +1042,9 @@ bool qt_read_xpm_image_or_array(QIODevice *device, const char * const * source,
if ((readBytes = device->readLine(buf.data(), buf.size())) < 0)
return false;
- if (buf.indexOf("/* XPM") != 0) {
+ static Q_RELAXED_CONSTEXPR auto matcher = qMakeStaticByteArrayMatcher("/* XPM");
+
+ if (matcher.indexIn(buf) != 0) {
while (readBytes > 0) {
device->ungetChar(buf.at(readBytes - 1));
--readBytes;
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index f14355bc01..399216d27c 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -476,7 +476,7 @@ void QClipboard::setMimeData(QMimeData* src, Mode mode)
QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
if (!clipboard->supportsMode(mode)) {
if (src != 0) {
- qWarning("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
+ qDebug("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
src->deleteLater();
}
} else {
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index b7035d47c4..8ae9085d9f 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -471,6 +471,54 @@ QCursor::QCursor(Qt::CursorShape shape)
setShape(shape);
}
+/*!
+ \fn bool operator==(const QCursor &lhs, const QCursor &rhs)
+ \relates QCursor
+ \since 5.10
+
+ Equality operator. Returns \c true if \a lhs and \a rhs
+ have the same \l{QCursor::}{shape()} and, in the case of
+ \l{Qt::BitmapCursor}{bitmap cursors}, the same \l{QCursor::}{hotSpot()}
+ and either the same \l{QCursor::}{pixmap()} or the same
+ \l{QCursor::}{bitmap()} and \l{QCursor::}{mask()}.
+
+ \note When comparing bitmap cursors, this function only
+ compares the bitmaps' \l{QPixmap::cacheKey()}{cache keys},
+ not each pixel.
+
+ \sa operator!=(const QCursor &lhs, const QCursor &rhs)
+*/
+bool operator==(const QCursor &lhs, const QCursor &rhs) Q_DECL_NOTHROW
+{
+ if (lhs.d == rhs.d)
+ return true; // Copy or same shape
+
+ // Check pixmaps or bitmaps cache keys. Notice that having BitmapCursor
+ // shape implies either non-null pixmap or non-null bitmap and mask
+ if (lhs.shape() == Qt::BitmapCursor && rhs.shape() == Qt::BitmapCursor
+ && lhs.hotSpot() == rhs.hotSpot()) {
+ if (!lhs.d->pixmap.isNull())
+ return lhs.d->pixmap.cacheKey() == rhs.d->pixmap.cacheKey();
+
+ if (!rhs.d->pixmap.isNull())
+ return false;
+
+ return lhs.d->bm->cacheKey() == rhs.d->bm->cacheKey()
+ && lhs.d->bmm->cacheKey() == rhs.d->bmm->cacheKey();
+ }
+
+ return false;
+}
+
+/*!
+ \fn bool operator!=(const QCursor &lhs, const QCursor &rhs)
+ \relates QCursor
+ \since 5.10
+
+ Inequality operator. Returns the equivalent of !(\a lhs == \a rhs).
+
+ \sa operator==(const QCursor &lhs, const QCursor &rhs)
+*/
/*!
Returns the cursor shape identifier. The return value is one of
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index c7e9188e5b..ccce3d84ef 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -112,10 +112,14 @@ public:
inline static void setPos(QScreen *screen, const QPoint &p) { setPos(screen, p.x(), p.y()); }
private:
+ friend Q_GUI_EXPORT bool operator==(const QCursor &lhs, const QCursor &rhs) Q_DECL_NOTHROW;
QCursorData *d;
};
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QCursor)
+Q_GUI_EXPORT bool operator==(const QCursor &lhs, const QCursor &rhs) Q_DECL_NOTHROW;
+inline bool operator!=(const QCursor &lhs, const QCursor &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); }
+
/*****************************************************************************
QCursor stream functions
*****************************************************************************/
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index a59612474b..3af7f5c181 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -71,14 +71,11 @@ QDragManager *QDragManager::m_instance = 0;
QDragManager::QDragManager()
- : QObject(qApp), m_platformDropData(0), m_currentDropTarget(0),
+ : QObject(qApp), m_currentDropTarget(0),
m_platformDrag(QGuiApplicationPrivate::platformIntegration()->drag()),
m_object(0)
{
Q_ASSERT(!m_instance);
-
- if (m_platformDrag)
- m_platformDropData = m_platformDrag->platformDropData();
}
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 6f2ec46252..eaf6c74fd4 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -134,7 +134,6 @@ public:
QObject *source() const;
private:
- QMimeData *m_platformDropData;
QObject *m_currentDropTarget;
QPlatformDrag *m_platformDrag;
QDrag *m_object;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 1dd019cd55..808f3ad166 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -164,8 +164,6 @@ QString *QGuiApplicationPrivate::desktopFileName = 0;
QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
-Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
-
ulong QGuiApplicationPrivate::mousePressTime = 0;
Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
int QGuiApplicationPrivate::mousePressX = 0;
@@ -570,6 +568,15 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and
\c none disables them.
\li \c {fontengine=freetype}, uses the FreeType font engine.
+ \li \c {menus=[native|none]}, controls the use of native menus.
+
+ Native menus are implemented using Win32 API and are simpler than
+ QMenu-based menus in for example that they do allow for placing
+ widgets on them or changing properties like fonts and do not
+ provide hover signals. They are mainly intended for Qt Quick.
+ By default, they will be used if the application is not an
+ instance of QApplication or for Qt Quick Controls 2
+ applications.
\endlist
For more information about the platform-specific arguments available for
@@ -1825,7 +1832,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
{
QEvent::Type type;
- Qt::MouseButtons stateChange = e->buttons ^ buttons;
+ Qt::MouseButtons stateChange = e->buttons ^ mouse_buttons;
if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
// A mouse event should not change both position and buttons at the same time. Instead we
// should first send a move event followed by a button changed event. Since this is not the case
@@ -1834,7 +1841,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers, e->source);
if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic)
mouseButtonEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
- e->buttons = buttons;
+ e->buttons = mouse_buttons;
processMouseEvent(e);
processMouseEvent(&mouseButtonEvent);
return;
@@ -1888,7 +1895,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
// Ignore mouse events that don't change the current state.
return;
}
- mouse_buttons = buttons = e->buttons;
+ mouse_buttons = e->buttons;
if (button & e->buttons) {
ulong doubleClickInterval = static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
doubleClick = e->timestamp - mousePressTime < doubleClickInterval && button == mousePressButton;
@@ -1913,14 +1920,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
- button, buttons, e->modifiers, e->source);
+ button, mouse_buttons, e->modifiers, e->source);
ev.setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
}
}
#endif
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, mouse_buttons, e->modifiers, e->source);
ev.setTimestamp(e->timestamp);
if (window->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {
@@ -1954,7 +1961,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
point.state = Qt::TouchPointPressed;
} else if (type == QEvent::MouseButtonRelease && button == Qt::LeftButton) {
point.state = Qt::TouchPointReleased;
- } else if (type == QEvent::MouseMove && (buttons & Qt::LeftButton)) {
+ } else if (type == QEvent::MouseMove && (mouse_buttons & Qt::LeftButton)) {
point.state = Qt::TouchPointMoved;
} else {
return;
@@ -1975,7 +1982,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press
const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
- button, buttons, e->modifiers, e->source);
+ button, mouse_buttons, e->modifiers, e->source);
dblClickEvent.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
}
@@ -2009,7 +2016,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
}
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation,
- buttons, e->modifiers, e->phase, e->source, e->inverted);
+ mouse_buttons, e->modifiers, e->phase, e->source, e->inverted);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
#else
@@ -2466,7 +2473,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
e->timestamp,
synthIt->pos,
synthIt->screenPos,
- buttons & ~Qt::LeftButton,
+ mouse_buttons & ~Qt::LeftButton,
e->modifiers,
Qt::MouseEventSynthesizedByQt);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@@ -2681,7 +2688,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp,
touchPoint.pos(),
touchPoint.screenPos(),
- b | (buttons & ~Qt::LeftButton),
+ b | (mouse_buttons & ~Qt::LeftButton),
e->modifiers,
Qt::MouseEventSynthesizedByQt);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 3804667ef3..014ed861df 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -201,7 +201,6 @@ public:
virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const;
virtual bool popupActive() { return false; }
- static Qt::MouseButtons buttons;
static ulong mousePressTime;
static Qt::MouseButton mousePressButton;
static int mousePressX;
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 20eac2ed15..9905caa92a 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -56,7 +56,6 @@
#if defined(Q_OS_MACX)
#include <QtCore/private/qcore_mac_p.h>
-#include <Carbon/Carbon.h>
#endif
#include <algorithm>
@@ -70,6 +69,13 @@ struct MacSpecialKey {
ushort macSymbol;
};
+// Unicode code points for the glyphs associated with these keys
+// Defined by Carbon headers but not anywhere in Cocoa
+static const int kShiftUnicode = 0x21E7;
+static const int kControlUnicode = 0x2303;
+static const int kOptionUnicode = 0x2325;
+static const int kCommandUnicode = 0x2318;
+
static const int NumEntries = 21;
static const MacSpecialKey entries[NumEntries] = {
{ Qt::Key_Escape, 0x238B },
diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp
index 307bc5e62f..4f8276aa87 100644
--- a/src/gui/kernel/qoffscreensurface.cpp
+++ b/src/gui/kernel/qoffscreensurface.cpp
@@ -121,14 +121,16 @@ public:
/*!
- Creates an offscreen surface for the \a targetScreen.
+ \since 5.10
+
+ Creates an offscreen surface for the \a targetScreen with the given \a parent.
The underlying platform surface is not created until create() is called.
\sa setScreen(), create()
*/
-QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen)
- : QObject(*new QOffscreenSurfacePrivate(), 0)
+QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen, QObject *parent)
+ : QObject(*new QOffscreenSurfacePrivate(), parent)
, QSurface(Offscreen)
{
Q_D(QOffscreenSurface);
@@ -143,6 +145,18 @@ QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen)
connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
}
+/*!
+ Creates an offscreen surface for the \a targetScreen.
+
+ The underlying platform surface is not created until create() is called.
+
+ \sa setScreen(), create()
+*/
+QOffscreenSurface::QOffscreenSurface(QScreen *targetScreen)
+ : QOffscreenSurface(targetScreen, nullptr)
+{
+}
+
/*!
Destroys the offscreen surface.
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 35c498c89a..3295ae0d40 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -57,7 +57,8 @@ class Q_GUI_EXPORT QOffscreenSurface : public QObject, public QSurface
Q_DECLARE_PRIVATE(QOffscreenSurface)
public:
-
+ // ### Qt 6: merge overloads
+ explicit QOffscreenSurface(QScreen *screen, QObject *parent);
explicit QOffscreenSurface(QScreen *screen = Q_NULLPTR);
virtual ~QOffscreenSurface();
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index a992793246..665cc430cc 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -388,7 +388,7 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
\warning Some styles do not use the palette for all drawing, for
instance, if they make use of native theme engines. This is the
- case for both the Windows XP, Windows Vista, and the \macos
+ case for both the Windows Vista and the \macos
styles.
\sa QApplication::setPalette(), QWidget::setPalette(), QColor
@@ -1115,14 +1115,14 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBru
Q_GUI_EXPORT QPalette qt_fusionPalette()
{
- QColor backGround(239, 235, 231);
+ QColor backGround(239, 239, 239);
QColor light = backGround.lighter(150);
QColor mid(backGround.darker(130));
QColor midLight = mid.lighter(110);
QColor base = Qt::white;
QColor disabledBase(backGround);
QColor dark = backGround.darker(150);
- QColor darkDisabled = QColor(209, 200, 191).darker(110);
+ QColor darkDisabled = QColor(209, 209, 209).darker(110);
QColor text = Qt::black;
QColor hightlightedText = Qt::white;
QColor disabledText = QColor(190, 190, 190);
@@ -1145,7 +1145,7 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198));
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 141, 126));
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
return fusionPalette;
}
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 01cf98c7c9..ad134ebe7f 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
*/
-static const int buttonRoleLayouts[2][5][14] =
+static const int buttonRoleLayouts[2][6][14] =
{
// Qt::Horizontal
{
@@ -92,7 +92,15 @@ static const int buttonRoleLayouts[2][5][14] =
// MacModelessLayout
{ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
- QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // AndroidLayout (neutral, stretch, dismissive, affirmative)
+ // https://material.io/guidelines/components/dialogs.html#dialogs-specs
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::Stretch, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
},
// Qt::Vertical
@@ -120,10 +128,20 @@ static const int buttonRoleLayouts[2][5][14] =
// MacModelessLayout
{ QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch,
QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
- QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // AndroidLayout
+ // (affirmative
+ // dismissive
+ // neutral)
+ // https://material.io/guidelines/components/dialogs.html#dialogs-specs
+ { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole,
+ QPlatformDialogHelper::NoRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole,
+ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
}
};
+
QPlatformDialogHelper::QPlatformDialogHelper()
{
qRegisterMetaType<StandardButton>();
@@ -917,6 +935,8 @@ const int *QPlatformDialogHelper::buttonLayout(Qt::Orientation orientation, Butt
policy = MacLayout;
#elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX)
policy = KdeLayout;
+#elif defined (Q_OS_ANDROID)
+ policy = AndroidLayout;
#else
policy = WinLayout;
#endif
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index ed88c19c84..f58dcf17f0 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -141,13 +141,14 @@ public:
Q_ENUM(ButtonRole)
enum ButtonLayout {
- // keep this in sync with QDialogButtonBox::ButtonLayout and QMessageBox::ButtonLayout
+ // keep this in sync with QDialogButtonBox::ButtonLayout
UnknownLayout = -1,
WinLayout,
MacLayout,
KdeLayout,
GnomeLayout,
- MacModelessLayout
+ MacModelessLayout,
+ AndroidLayout
};
QPlatformDialogHelper();
diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h
index 560f984a5b..54e6a667fe 100644
--- a/src/gui/kernel/qplatformdrag.h
+++ b/src/gui/kernel/qplatformdrag.h
@@ -95,7 +95,6 @@ public:
virtual ~QPlatformDrag();
QDrag *currentDrag() const;
- virtual QMimeData *platformDropData() = 0;
virtual Qt::DropAction drag(QDrag *m_drag) = 0;
virtual void cancelDrag();
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index fe1861e08b..873ec3a33b 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -237,6 +237,10 @@ QPlatformServices *QPlatformIntegration::services() const
is required to have this capability.
\value ApplicationIcon The platform supports setting the application icon. (since 5.5)
+
+ \value TopStackedNativeChildWindows The platform supports native child windows via
+ QWindowContainer without having to punch a transparent hole in the
+ backingstore. (since 5.10)
*/
/*!
@@ -260,7 +264,8 @@ QPlatformServices *QPlatformIntegration::services() const
bool QPlatformIntegration::hasCapability(Capability cap) const
{
- return cap == NonFullScreenWindows || cap == NativeWidgets || cap == WindowManagement;
+ return cap == NonFullScreenWindows || cap == NativeWidgets || cap == WindowManagement
+ || cap == TopStackedNativeChildWindows;
}
QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
@@ -387,6 +392,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return false;
case ShowIsMaximized:
return false;
+ case ShowShortcutsInContextMenus:
+ return QPlatformTheme::defaultThemeHint(QPlatformTheme::ShowShortcutsInContextMenus);
case PasswordMaskDelay:
return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskDelay);
case PasswordMaskCharacter:
@@ -622,4 +629,26 @@ void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const
Q_UNUSED(icon);
}
+#if QT_CONFIG(vulkan)
+
+/*!
+ Factory function for QPlatformVulkanInstance. The \a instance parameter is a
+ pointer to the instance for which a platform-specific backend needs to be
+ created.
+
+ Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could
+ not be created.
+
+ \sa QVulkanInstance
+ \since 5.10
+*/
+QPlatformVulkanInstance *QPlatformIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ Q_UNUSED(instance);
+ qWarning("This plugin does not support createPlatformVulkanInstance");
+ return nullptr;
+}
+
+#endif // QT_CONFIG(vulkan)
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 0449e0b4c8..eeaa7574f7 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -78,6 +78,8 @@ class QPlatformSessionManager;
class QKeyEvent;
class QPlatformOffscreenSurface;
class QOffscreenSurface;
+class QPlatformVulkanInstance;
+class QVulkanInstance;
class Q_GUI_EXPORT QPlatformIntegration
{
@@ -99,7 +101,8 @@ public:
RasterGLSurface,
AllGLFunctionsQueryable,
ApplicationIcon,
- SwitchableWidgetComposition
+ SwitchableWidgetComposition,
+ TopStackedNativeChildWindows
};
virtual ~QPlatformIntegration() { }
@@ -160,6 +163,7 @@ public:
ItemViewActivateItemOnSingleClick,
UiEffects,
WheelScrollLines,
+ ShowShortcutsInContextMenus,
};
virtual QVariant styleHint(StyleHint hint) const;
@@ -188,6 +192,10 @@ public:
virtual void beep() const;
+#if QT_CONFIG(vulkan)
+ virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const;
+#endif
+
protected:
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
void destroyScreen(QPlatformScreen *screen);
diff --git a/src/gui/kernel/qplatformmenu.cpp b/src/gui/kernel/qplatformmenu.cpp
index 1eb146dd0f..0d76f2039d 100644
--- a/src/gui/kernel/qplatformmenu.cpp
+++ b/src/gui/kernel/qplatformmenu.cpp
@@ -45,6 +45,37 @@
QT_BEGIN_NAMESPACE
+QPlatformMenuItem::QPlatformMenuItem()
+{
+ m_tag = reinterpret_cast<quintptr>(this);
+}
+
+void QPlatformMenuItem::setTag(quintptr tag)
+{
+ m_tag = tag;
+}
+
+quintptr QPlatformMenuItem::tag() const
+{
+ return m_tag;
+}
+
+QPlatformMenu::QPlatformMenu()
+{
+ m_tag = reinterpret_cast<quintptr>(this);
+}
+
+void QPlatformMenu::setTag(quintptr tag)
+{
+ m_tag = tag;
+}
+
+quintptr QPlatformMenu::tag() const
+{
+ return m_tag;
+
+}
+
QPlatformMenuItem *QPlatformMenu::createMenuItem() const
{
return QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index f8561445b1..e3fa5c71b1 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -62,6 +62,8 @@ class Q_GUI_EXPORT QPlatformMenuItem : public QObject
{
Q_OBJECT
public:
+ QPlatformMenuItem();
+
// copied from, and must stay in sync with, QAction menu roles.
enum MenuRole { NoRole = 0, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole,
AboutRole, PreferencesRole, QuitRole,
@@ -71,8 +73,8 @@ public:
RoleCount };
Q_ENUM(MenuRole)
- virtual void setTag(quintptr tag) = 0;
- virtual quintptr tag()const = 0;
+ virtual void setTag(quintptr tag);
+ virtual quintptr tag() const;
virtual void setText(const QString &text) = 0;
virtual void setIcon(const QIcon &icon) = 0;
@@ -94,12 +96,17 @@ public:
Q_SIGNALS:
void activated();
void hovered();
+
+private:
+ quintptr m_tag;
};
class Q_GUI_EXPORT QPlatformMenu : public QObject
{
Q_OBJECT
public:
+ QPlatformMenu();
+
enum MenuType { DefaultMenu = 0, EditMenu };
Q_ENUM(MenuType)
@@ -108,8 +115,8 @@ public:
virtual void syncMenuItem(QPlatformMenuItem *menuItem) = 0;
virtual void syncSeparatorsCollapsible(bool enable) = 0;
- virtual void setTag(quintptr tag) = 0;
- virtual quintptr tag()const = 0;
+ virtual void setTag(quintptr tag);
+ virtual quintptr tag() const;
virtual void setText(const QString &text) = 0;
virtual void setIcon(const QIcon &icon) = 0;
@@ -138,6 +145,9 @@ public:
Q_SIGNALS:
void aboutToShow();
void aboutToHide();
+
+private:
+ quintptr m_tag;
};
class Q_GUI_EXPORT QPlatformMenuBar : public QObject
diff --git a/src/gui/kernel/qplatformsystemtrayicon.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp
index 5481997b3c..296beda0f9 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.cpp
+++ b/src/gui/kernel/qplatformsystemtrayicon.cpp
@@ -140,10 +140,19 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon()
*/
/*!
+ \fn void QPlatformSystemTrayIcon::contextMenuRequested(QPoint globalPos, const QPlatformScreen *screen)
+ This signal is emitted when the context menu is requested.
+ In particular, on platforms where createMenu() returns nullptr,
+ its emission will cause QSystemTrayIcon to show a QMenu-based menu.
+ \sa activated()
+ \since 5.10
+*/
+
+/*!
\fn void QPlatformSystemTrayIcon::activated(QPlatformSystemTrayIcon::ActivationReason reason)
This signal is emitted when the user activates the system tray icon.
\a reason specifies the reason for activation.
- \sa QSystemTrayIcon::ActivationReason
+ \sa QSystemTrayIcon::ActivationReason, contextMenuRequested()
*/
/*!
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index c52dbfbd78..948a6c099d 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QPlatformMenu;
+class QPlatformScreen;
class QIcon;
class QString;
class QRect;
@@ -88,6 +89,7 @@ public:
Q_SIGNALS:
void activated(QPlatformSystemTrayIcon::ActivationReason reason);
+ void contextMenuRequested(QPoint globalPos, const QPlatformScreen *screen);
void messageClicked();
};
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 878f656f2e..ebf65eda12 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -161,6 +161,8 @@ QT_BEGIN_NAMESPACE
The default value is double the MouseDoubleClickDistance, or 10 logical pixels
if that is not specified.
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
\sa themeHint(), QStyle::pixelMetric()
*/
@@ -516,6 +518,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
return QVariant(QStringList());
case QPlatformTheme::StyleNames:
return QVariant(QStringList());
+ case QPlatformTheme::ShowShortcutsInContextMenus:
+ return QVariant(false);
case TextCursorWidth:
return QVariant(1);
case DropShadow:
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 2ba2f8669f..f4ff418db6 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -115,7 +115,8 @@ public:
MousePressAndHoldInterval,
MouseDoubleClickDistance,
WheelScrollLines,
- TouchDoubleTapDistance
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus
};
enum DialogType {
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 5062bd1e77..dda7cc94fe 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -261,7 +261,7 @@ QPoint QPlatformWindow::mapFromGlobal(const QPoint &pos) const
Qt::WindowActive can be ignored.
*/
-void QPlatformWindow::setWindowState(Qt::WindowState)
+void QPlatformWindow::setWindowState(Qt::WindowStates)
{
}
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 8af8791bb4..eead96f2d1 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -89,7 +89,7 @@ public:
virtual void setVisible(bool visible);
virtual void setWindowFlags(Qt::WindowFlags flags);
- virtual void setWindowState(Qt::WindowState state);
+ virtual void setWindowState(Qt::WindowStates state);
virtual WId winId() const;
virtual void setParent(const QPlatformWindow *window);
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index fc62273325..481971f21a 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -353,13 +353,6 @@ QSimpleDrag::QSimpleDrag() : m_current_window(0)
{
}
-QMimeData *QSimpleDrag::platformDropData()
-{
- if (drag())
- return drag()->mimeData();
- return 0;
-}
-
void QSimpleDrag::startDrag()
{
QBasicDrag::startDrag();
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 0b8a0bc703..45c13e43b2 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -125,7 +125,6 @@ class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
{
public:
QSimpleDrag();
- virtual QMimeData *platformDropData() Q_DECL_OVERRIDE;
protected:
virtual void startDrag() Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 85c0768e35..0850228ee5 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -365,6 +365,17 @@ bool QStyleHints::showIsMaximized() const
}
/*!
+ \property QStyleHints::showShortcutsInContextMenus
+ \since 5.10
+ \brief \c true if the platform normally shows shortcut key sequences in
+ context menus, otherwise \c false.
+*/
+bool QStyleHints::showShortcutsInContextMenus() const
+{
+ return themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool();
+}
+
+/*!
\property QStyleHints::passwordMaskDelay
\brief the time, in milliseconds, a typed letter is displayed unshrouded
in a text input field in password mode.
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index b9bf428edd..2c2e048b15 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -64,6 +64,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsMaximized READ showIsMaximized STORED false CONSTANT FINAL)
+ Q_PROPERTY(bool showShortcutsInContextMenus READ showShortcutsInContextMenus STORED false CONSTANT FINAL)
Q_PROPERTY(int startDragDistance READ startDragDistance NOTIFY startDragDistanceChanged FINAL)
Q_PROPERTY(int startDragTime READ startDragTime NOTIFY startDragTimeChanged FINAL)
Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL)
@@ -90,6 +91,7 @@ public:
int cursorFlashTime() const;
bool showIsFullScreen() const;
bool showIsMaximized() const;
+ bool showShortcutsInContextMenus() const;
int passwordMaskDelay() const;
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index 3cdd11de8c..63651ee822 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -78,6 +78,8 @@ QT_BEGIN_NAMESPACE
requires the use of private API.
\value OpenVGSurface The surface is an OpenVG compatible surface and can be used
in conjunction with OpenVG contexts.
+ \value VulkanSurface The surface is a Vulkan compatible surface and can be used
+ in conjunction with the Vulkan graphics API.
*/
diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h
index a96b7a6422..7e09449d12 100644
--- a/src/gui/kernel/qsurface.h
+++ b/src/gui/kernel/qsurface.h
@@ -66,6 +66,7 @@ public:
OpenGLSurface,
RasterGLSurface,
OpenVGSurface,
+ VulkanSurface
};
virtual ~QSurface();
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 000d727380..574310f554 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -73,6 +73,7 @@ public:
, major(2)
, minor(0)
, swapInterval(1) // default to vsync
+ , colorSpace(QSurfaceFormat::DefaultColorSpace)
{
}
@@ -91,7 +92,8 @@ public:
profile(other->profile),
major(other->major),
minor(other->minor),
- swapInterval(other->swapInterval)
+ swapInterval(other->swapInterval),
+ colorSpace(other->colorSpace)
{
}
@@ -110,6 +112,7 @@ public:
int major;
int minor;
int swapInterval;
+ QSurfaceFormat::ColorSpace colorSpace;
};
/*!
@@ -124,6 +127,12 @@ public:
contains surface configuration parameters such as OpenGL profile and
version for rendering, whether or not to enable stereo buffers, and swap
behaviour.
+
+ \note When troubleshooting context or window format issues, it can be
+ helpful to enable the logging category \c{qt.qpa.gl}. Depending on the
+ platform, this may print useful debug information when it comes to OpenGL
+ initialization and the native visual or framebuffer configurations which
+ QSurfaceFormat gets mapped to.
*/
/*!
@@ -199,6 +208,22 @@ public:
*/
/*!
+ \enum QSurfaceFormat::ColorSpace
+
+ This enum is used to specify the preferred color space, controlling if the
+ window's associated default framebuffer is able to do updates and blending
+ in a given encoding instead of the standard linear operations.
+
+ \value DefaultColorSpace The default, unspecified color space.
+
+ \value sRGBColorSpace When \c{GL_ARB_framebuffer_sRGB} or
+ \c{GL_EXT_framebuffer_sRGB} is supported by the platform and this value is
+ set, the window will be created with an sRGB-capable default
+ framebuffer. Note that some platforms may return windows with a sRGB-capable
+ default framebuffer even when not requested explicitly.
+ */
+
+/*!
Constructs a default initialized QSurfaceFormat.
\note By default OpenGL 2.0 is requested since this provides the highest
@@ -736,6 +761,47 @@ int QSurfaceFormat::swapInterval() const
return d->swapInterval;
}
+/*!
+ Sets the preferred \a colorSpace.
+
+ For example, this allows requesting windows with default framebuffers that
+ are sRGB-capable on platforms that support it.
+
+ \note When the requested color space is not supported by the platform, the
+ request is ignored. Query the QSurfaceFormat after window creation to verify
+ if the color space request could be honored or not.
+
+ \note This setting controls if the default framebuffer of the window is
+ capable of updates and blending in a given color space. It does not change
+ applications' output by itself. The applications' rendering code will still
+ have to opt in via the appropriate OpenGL calls to enable updates and
+ blending to be performed in the given color space instead of using the
+ standard linear operations.
+
+ \since 5.10
+
+ \sa colorSpace()
+ */
+void QSurfaceFormat::setColorSpace(ColorSpace colorSpace)
+{
+ if (d->colorSpace != colorSpace) {
+ detach();
+ d->colorSpace = colorSpace;
+ }
+}
+
+/*!
+ \return the color space.
+
+ \since 5.10
+
+ \sa setColorSpace()
+*/
+QSurfaceFormat::ColorSpace QSurfaceFormat::colorSpace() const
+{
+ return d->colorSpace;
+}
+
Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
/*!
@@ -841,6 +907,7 @@ QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
<< ", samples " << d->numSamples
<< ", swapBehavior " << d->swapBehavior
<< ", swapInterval " << d->swapInterval
+ << ", colorSpace " << d->colorSpace
<< ", profile " << d->profile
<< ')';
diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h
index 246163609e..ed63eb8bbf 100644
--- a/src/gui/kernel/qsurfaceformat.h
+++ b/src/gui/kernel/qsurfaceformat.h
@@ -85,6 +85,12 @@ public:
};
Q_ENUM(OpenGLContextProfile)
+ enum ColorSpace {
+ DefaultColorSpace,
+ sRGBColorSpace
+ };
+ Q_ENUM(ColorSpace)
+
QSurfaceFormat();
/*implicit*/ QSurfaceFormat(FormatOptions options);
QSurfaceFormat(const QSurfaceFormat &other);
@@ -145,6 +151,9 @@ public:
int swapInterval() const;
void setSwapInterval(int interval);
+ ColorSpace colorSpace() const;
+ void setColorSpace(ColorSpace colorSpace);
+
static void setDefaultFormat(const QSurfaceFormat &format);
static QSurfaceFormat defaultFormat();
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 519d749b8a..796a552bcb 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE
application, isExposed() will simply return the same value as isVisible().
QWindow::Visibility queried through visibility() is a convenience API
- combining the functions of visible() and windowState().
+ combining the functions of visible() and windowStates().
\section1 Rendering
@@ -323,27 +323,16 @@ void QWindowPrivate::updateVisibility()
QWindow::Visibility old = visibility;
- if (visible) {
- switch (windowState) {
- case Qt::WindowMinimized:
- visibility = QWindow::Minimized;
- break;
- case Qt::WindowMaximized:
- visibility = QWindow::Maximized;
- break;
- case Qt::WindowFullScreen:
- visibility = QWindow::FullScreen;
- break;
- case Qt::WindowNoState:
- visibility = QWindow::Windowed;
- break;
- default:
- Q_ASSERT(false);
- break;
- }
- } else {
+ if (!visible)
visibility = QWindow::Hidden;
- }
+ else if (windowState & Qt::WindowMinimized)
+ visibility = QWindow::Minimized;
+ else if (windowState & Qt::WindowFullScreen)
+ visibility = QWindow::FullScreen;
+ else if (windowState & Qt::WindowMaximized)
+ visibility = QWindow::Maximized;
+ else
+ visibility = QWindow::Windowed;
if (visibility != old)
emit q->visibilityChanged(visibility);
@@ -1215,6 +1204,17 @@ qreal QWindow::devicePixelRatio() const
return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
}
+Qt::WindowState QWindowPrivate::effectiveState(Qt::WindowStates state)
+{
+ if (state & Qt::WindowMinimized)
+ return Qt::WindowMinimized;
+ else if (state & Qt::WindowFullScreen)
+ return Qt::WindowFullScreen;
+ else if (state & Qt::WindowMaximized)
+ return Qt::WindowMaximized;
+ return Qt::WindowNoState;
+}
+
/*!
\brief set the screen-occupation state of the window
@@ -1223,31 +1223,69 @@ qreal QWindow::devicePixelRatio() const
The enum value Qt::WindowActive is not an accepted parameter.
- \sa showNormal(), showFullScreen(), showMinimized(), showMaximized()
+ \sa showNormal(), showFullScreen(), showMinimized(), showMaximized(), setWindowStates()
*/
void QWindow::setWindowState(Qt::WindowState state)
{
- if (state == Qt::WindowActive) {
- qWarning("QWindow::setWindowState does not accept Qt::WindowActive");
- return;
- }
+ setWindowStates(state);
+}
+/*!
+ \brief set the screen-occupation state of the window
+ \since 5.10
+
+ The window \a state represents whether the window appears in the
+ windowing system as maximized, minimized and/or fullscreen.
+
+ The window can be in a combination of several states. For example, if
+ the window is both minimized and maximized, the window will appear
+ minimized, but clicking on the task bar entry will restore it to the
+ maximized state.
+
+ The enum value Qt::WindowActive should not be set.
+
+ \sa showNormal(), showFullScreen(), showMinimized(), showMaximized()
+ */
+void QWindow::setWindowStates(Qt::WindowStates state)
+{
Q_D(QWindow);
+ if (state & Qt::WindowActive) {
+ qWarning("QWindow::setWindowStates does not accept Qt::WindowActive");
+ state &= ~Qt::WindowActive;
+ }
+
if (d->platformWindow)
d->platformWindow->setWindowState(state);
d->windowState = state;
- emit windowStateChanged(d->windowState);
+ emit windowStateChanged(QWindowPrivate::effectiveState(d->windowState));
d->updateVisibility();
}
/*!
\brief the screen-occupation state of the window
- \sa setWindowState()
+ \sa setWindowState(), windowStates()
*/
Qt::WindowState QWindow::windowState() const
{
Q_D(const QWindow);
+ return QWindowPrivate::effectiveState(d->windowState);
+}
+
+/*!
+ \brief the screen-occupation state of the window
+ \since 5.10
+
+ The window can be in a combination of several states. For example, if
+ the window is both minimized and maximized, the window will appear
+ minimized, but clicking on the task bar entry will restore it to
+ the maximized state.
+
+ \sa setWindowStates()
+*/
+Qt::WindowStates QWindow::windowStates() const
+{
+ Q_D(const QWindow);
return d->windowState;
}
@@ -1255,7 +1293,7 @@ Qt::WindowState QWindow::windowState() const
\fn QWindow::windowStateChanged(Qt::WindowState windowState)
This signal is emitted when the \a windowState changes, either
- by being set explicitly with setWindowState(), or automatically when
+ by being set explicitly with setWindowStates(), or automatically when
the user clicks one of the titlebar buttons or by other means.
*/
@@ -2000,42 +2038,42 @@ void QWindow::hide()
/*!
Shows the window as minimized.
- Equivalent to calling setWindowState(Qt::WindowMinimized) and then
+ Equivalent to calling setWindowStates(Qt::WindowMinimized) and then
setVisible(true).
- \sa setWindowState(), setVisible()
+ \sa setWindowStates(), setVisible()
*/
void QWindow::showMinimized()
{
- setWindowState(Qt::WindowMinimized);
+ setWindowStates(Qt::WindowMinimized);
setVisible(true);
}
/*!
Shows the window as maximized.
- Equivalent to calling setWindowState(Qt::WindowMaximized) and then
+ Equivalent to calling setWindowStates(Qt::WindowMaximized) and then
setVisible(true).
- \sa setWindowState(), setVisible()
+ \sa setWindowStates(), setVisible()
*/
void QWindow::showMaximized()
{
- setWindowState(Qt::WindowMaximized);
+ setWindowStates(Qt::WindowMaximized);
setVisible(true);
}
/*!
Shows the window as fullscreen.
- Equivalent to calling setWindowState(Qt::WindowFullScreen) and then
+ Equivalent to calling setWindowStates(Qt::WindowFullScreen) and then
setVisible(true).
- \sa setWindowState(), setVisible()
+ \sa setWindowStates(), setVisible()
*/
void QWindow::showFullScreen()
{
- setWindowState(Qt::WindowFullScreen);
+ setWindowStates(Qt::WindowFullScreen);
setVisible(true);
#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
// activating it here before libscreen activates it causes problems
@@ -2046,14 +2084,14 @@ void QWindow::showFullScreen()
/*!
Shows the window as normal, i.e. neither maximized, minimized, nor fullscreen.
- Equivalent to calling setWindowState(Qt::WindowNoState) and then
+ Equivalent to calling setWindowStates(Qt::WindowNoState) and then
setVisible(true).
- \sa setWindowState(), setVisible()
+ \sa setWindowStates(), setVisible()
*/
void QWindow::showNormal()
{
- setWindowState(Qt::WindowNoState);
+ setWindowStates(Qt::WindowNoState);
setVisible(true);
}
@@ -2249,7 +2287,7 @@ bool QWindow::event(QEvent *ev)
case QEvent::WindowStateChange: {
Q_D(QWindow);
- emit windowStateChanged(d->windowState);
+ emit windowStateChanged(QWindowPrivate::effectiveState(d->windowState));
d->updateVisibility();
break;
}
@@ -2765,6 +2803,30 @@ QDebug operator<<(QDebug debug, const QWindow *window)
}
#endif // !QT_NO_DEBUG_STREAM
+#if QT_CONFIG(vulkan)
+
+/*!
+ Associates this window with the specified Vulkan \a instance.
+
+ \a instance must stay valid as long as this QWindow instance exists.
+ */
+void QWindow::setVulkanInstance(QVulkanInstance *instance)
+{
+ Q_D(QWindow);
+ d->vulkanInstance = instance;
+}
+
+/*!
+ \return the associrated Vulkan instance or \c null if there is none.
+ */
+QVulkanInstance *QWindow::vulkanInstance() const
+{
+ Q_D(const QWindow);
+ return d->vulkanInstance;
+}
+
+#endif // QT_CONFIG(vulkan)
+
QT_END_NAMESPACE
#include "moc_qwindow.cpp"
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 2883749d2e..529589e67b 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -88,6 +88,9 @@ class QWindowContainer;
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
#endif
+#if QT_CONFIG(vulkan)
+class QVulkanInstance;
+#endif
class Q_GUI_EXPORT QWindow : public QObject, public QSurface
{
@@ -189,7 +192,9 @@ public:
qreal devicePixelRatio() const;
Qt::WindowState windowState() const;
+ Qt::WindowStates windowStates() const;
void setWindowState(Qt::WindowState state);
+ void setWindowStates(Qt::WindowStates states);
void setTransientParent(QWindow *parent);
QWindow *transientParent() const;
@@ -267,6 +272,11 @@ public:
static QWindow *fromWinId(WId id);
+#if QT_CONFIG(vulkan)
+ void setVulkanInstance(QVulkanInstance *instance);
+ QVulkanInstance *vulkanInstance() const;
+#endif
+
public Q_SLOTS:
Q_REVISION(1) void requestActivate();
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index dd282a671d..cffe5b4125 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -105,6 +105,9 @@ public:
, hasCursor(false)
#endif
, compositing(false)
+#if QT_CONFIG(vulkan)
+ , vulkanInstance(nullptr)
+#endif
{
isWindow = true;
}
@@ -151,6 +154,8 @@ public:
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
+ static Qt::WindowState effectiveState(Qt::WindowStates);
+
QWindow::SurfaceType surfaceType;
Qt::WindowFlags windowFlags;
QWindow *parentWindow;
@@ -163,7 +168,7 @@ public:
QString windowFilePath;
QIcon windowIcon;
QRect geometry;
- Qt::WindowState windowState;
+ Qt::WindowStates windowState;
QWindow::Visibility visibility;
bool resizeEventPending;
bool receivedExpose;
@@ -194,6 +199,10 @@ public:
bool compositing;
QElapsedTimer lastComposeTime;
+
+#if QT_CONFIG(vulkan)
+ QVulkanInstance *vulkanInstance;
+#endif
};
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 7f25ed76c3..974391d3a4 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -66,7 +66,7 @@ extern QPointer<QWindow> qt_last_mouse_receiver;
// ------------------- QWindowSystemInterfacePrivate -------------------
-/*!
+/*
Handles a window system event asynchronously by posting the event to Qt Gui.
This function posts the event on the window system event queue and wakes the
@@ -82,7 +82,7 @@ bool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterfa
return true;
}
-/*!
+/*
Handles a window system event synchronously.
Qt Gui will process the event immediately. The return value indicates if Qt
@@ -112,7 +112,7 @@ bool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterfa
return accepted;
}
-/*!
+/*
Handles a window system event.
By default this function posts the event on the window system event queue and
@@ -246,14 +246,14 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::Fo
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
-QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowState newState, int oldState)
+QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState)
{
Q_ASSERT(window);
if (oldState < Qt::WindowNoState)
oldState = window->windowState();
QWindowSystemInterfacePrivate::WindowStateChangedEvent *e =
- new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowState(oldState));
+ new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowStates(oldState));
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index aadf63782f..d3dd5ac2e9 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -176,7 +176,7 @@ public:
static void handleWindowActivated(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
- static void handleWindowStateChanged(QWindow *window, Qt::WindowState newState, int oldState = -1);
+ static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState = -1);
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen);
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 0f350fb2d2..55aafc4d15 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -168,13 +168,13 @@ public:
class WindowStateChangedEvent : public WindowSystemEvent {
public:
- WindowStateChangedEvent(QWindow *_window, Qt::WindowState _newState, Qt::WindowState _oldState)
+ WindowStateChangedEvent(QWindow *_window, Qt::WindowStates _newState, Qt::WindowStates _oldState)
: WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState), oldState(_oldState)
{ }
QPointer<QWindow> window;
- Qt::WindowState newState;
- Qt::WindowState oldState;
+ Qt::WindowStates newState;
+ Qt::WindowStates oldState;
};
class WindowScreenChangedEvent : public WindowSystemEvent {
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 63e345545c..9ff0b5f5e5 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -99,6 +99,9 @@ SOURCES += \
painting/qplatformbackingstore.cpp \
painting/qpathsimplifier.cpp
+RESOURCES += \
+ painting/qpdf.qrc
+
darwin {
HEADERS += painting/qcoregraphics_p.h
SOURCES += painting/qcoregraphics.mm
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index cc3ee76f0d..5c13308d94 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -100,7 +100,7 @@ const uchar *qt_patternForBrush(int brushStyle, bool invert)
return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
}
-QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
+Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
{
QPixmap pm;
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 9e1785c11d..855f245396 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -79,7 +79,7 @@ static inline int hex2int(char s)
return h < 0 ? h : (h << 4) | h;
}
-static bool get_hex_rgb(const char *name, int len, QRgb *rgb)
+static bool get_hex_rgb(const char *name, size_t len, QRgb *rgb)
{
if (name[0] != '#')
return false;
@@ -124,12 +124,12 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
return get_hex_rgb(name, qstrlen(name), rgb);
}
-static bool get_hex_rgb(const QChar *str, int len, QRgb *rgb)
+static bool get_hex_rgb(const QChar *str, size_t len, QRgb *rgb)
{
if (len > 13)
return false;
char tmp[16];
- for (int i = 0; i < len; ++i)
+ for (size_t i = 0; i < len; ++i)
tmp[i] = str[i].toLatin1();
tmp[len] = 0;
return get_hex_rgb(tmp, len, rgb);
@@ -858,6 +858,7 @@ QString QColor::name(NameFormat format) const
return QString();
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
Sets the RGB value of this QColor to \a name, which may be in one
of these formats:
@@ -883,6 +884,17 @@ QString QColor::name(NameFormat format) const
void QColor::setNamedColor(const QString &name)
{
+ setColorFromString(qToStringViewIgnoringNull(name));
+}
+#endif
+
+/*!
+ \overload
+ \since 5.10
+*/
+
+void QColor::setNamedColor(QStringView name)
+{
setColorFromString(name);
}
@@ -896,6 +908,7 @@ void QColor::setNamedColor(QLatin1String name)
setColorFromString(name);
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\since 4.7
@@ -909,7 +922,17 @@ void QColor::setNamedColor(QLatin1String name)
*/
bool QColor::isValidColor(const QString &name)
{
- return !name.isEmpty() && QColor().setColorFromString(name);
+ return isValidColor(qToStringViewIgnoringNull(name));
+}
+#endif
+
+/*!
+ \overload
+ \since 5.10
+*/
+bool QColor::isValidColor(QStringView name) Q_DECL_NOTHROW
+{
+ return name.size() && QColor().setColorFromString(name);
}
/*!
@@ -922,7 +945,7 @@ bool QColor::isValidColor(QLatin1String name) Q_DECL_NOTHROW
}
template <typename String>
-bool QColor::setColorFromString(const String &name)
+bool QColor::setColorFromString(String name)
{
if (!name.size()) {
invalidate();
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index 83a93e25ea..0c5ebcbda9 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -72,7 +72,10 @@ public:
inline QColor(int r, int g, int b, int a = 255);
QColor(QRgb rgb) Q_DECL_NOTHROW;
QColor(QRgba64 rgba64) Q_DECL_NOTHROW;
+#if QT_STRINGVIEW_LEVEL < 2
inline QColor(const QString& name);
+#endif
+ explicit inline QColor(QStringView name);
inline QColor(const char *aname) : QColor(QLatin1String(aname)) {}
inline QColor(QLatin1String name);
QColor(Spec spec) Q_DECL_NOTHROW;
@@ -95,7 +98,10 @@ public:
QString name() const;
QString name(NameFormat format) const;
+#if QT_STRINGVIEW_LEVEL < 2
void setNamedColor(const QString& name);
+#endif
+ void setNamedColor(QStringView name);
void setNamedColor(QLatin1String name);
static QStringList colorNames();
@@ -221,14 +227,17 @@ public:
operator QVariant() const;
+#if QT_STRINGVIEW_LEVEL < 2
static bool isValidColor(const QString &name);
+#endif
+ static bool isValidColor(QStringView) Q_DECL_NOTHROW;
static bool isValidColor(QLatin1String) Q_DECL_NOTHROW;
private:
void invalidate() Q_DECL_NOTHROW;
template <typename String>
- bool setColorFromString(const String &name);
+ bool setColorFromString(String name);
Spec cspec;
union {
@@ -280,8 +289,13 @@ inline QColor::QColor(int r, int g, int b, int a)
inline QColor::QColor(QLatin1String aname)
{ setNamedColor(aname); }
+inline QColor::QColor(QStringView aname)
+{ setNamedColor(aname); }
+
+#if QT_STRINGVIEW_LEVEL < 2
inline QColor::QColor(const QString& aname)
{ setNamedColor(aname); }
+#endif
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
inline QColor::QColor(const QColor &acolor) Q_DECL_NOTHROW
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index b2e762a391..3aa7accef6 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2657,6 +2657,241 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
return buffer;
}
+template<TextureBlendType blendType, QPixelLayout::BPP bpp>
+static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b, uint *end, const QTextureData &image,
+ int &fx, int &fy, int fdx, int /*fdy*/)
+{
+ const QPixelLayout *layout = &qPixelLayouts[image.format];
+ const QVector<QRgb> *clut = image.colorTable;
+ Q_ASSERT(bpp == QPixelLayout::BPPNone || bpp == layout->bpp);
+ // When templated 'fetch' should be inlined at compile time:
+ const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels<bpp>;
+ const ConvertFunc convertToARGB32PM = layout->convertToARGB32PM;
+
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
+ const uchar *s1 = image.scanLine(y1);
+ const uchar *s2 = image.scanLine(y2);
+
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idisty = 256 - disty;
+ int x = fx >> 16;
+ int length = end - b;
+
+ // The idea is first to do the interpolation between the row s1 and the row s2
+ // into an intermediate buffer, then we interpolate between two pixel of this buffer.
+ // +1 for the last pixel to interpolate with, and +1 for rounding errors.
+ uint buf1[buffer_size + 2];
+ uint buf2[buffer_size + 2];
+ const uint *ptr1;
+ const uint *ptr2;
+
+ int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2;
+ Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+
+ if (blendType == BlendTransformedBilinearTiled) {
+ x %= image.width;
+ if (x < 0)
+ x += image.width;
+ int len1 = qMin(count, image.width - x);
+ int len2 = qMin(x, count - len1);
+
+ ptr1 = fetch(buf1, s1, x, len1);
+ ptr1 = convertToARGB32PM(buf1, ptr1, len1, clut, 0);
+ ptr2 = fetch(buf2, s2, x, len1);
+ ptr2 = convertToARGB32PM(buf2, ptr2, len1, clut, 0);
+ for (int i = 0; i < len1; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+
+ if (len2) {
+ ptr1 = fetch(buf1 + len1, s1, 0, len2);
+ ptr1 = convertToARGB32PM(buf1 + len1, ptr1, len2, clut, 0);
+ ptr2 = fetch(buf2 + len1, s2, 0, len2);
+ ptr2 = convertToARGB32PM(buf2 + len1, ptr2, len2, clut, 0);
+ for (int i = 0; i < len2; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+ }
+ for (int i = image.width; i < count; ++i) {
+ buf1[i] = buf1[i - image.width];
+ buf2[i] = buf2[i - image.width];
+ }
+ } else {
+ int start = qMax(x, image.x1);
+ int end = qMin(x + count, image.x2);
+ int len = qMax(1, end - start);
+ int leading = start - x;
+
+ ptr1 = fetch(buf1 + leading, s1, start, len);
+ ptr1 = convertToARGB32PM(buf1 + leading, ptr1, len, clut, 0);
+ ptr2 = fetch(buf2 + leading, s2, start, len);
+ ptr2 = convertToARGB32PM(buf2 + leading, ptr2, len, clut, 0);
+
+ for (int i = 0; i < len; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+
+ for (int i = 0; i < leading; ++i) {
+ buf1[i] = buf1[leading];
+ buf2[i] = buf2[leading];
+ }
+ for (int i = leading + len; i < count; ++i) {
+ buf1[i] = buf1[i - 1];
+ buf2[i] = buf2[i - 1];
+ }
+ }
+
+ // Now interpolate the values from the intermediate_buffer to get the final result.
+ fx &= fixed_scale - 1;
+ Q_ASSERT((fx >> 16) == 0);
+ while (b < end) {
+ int x1 = (fx >> 16);
+ int x2 = x1 + 1;
+ Q_ASSERT(x1 >= 0);
+ Q_ASSERT(x2 < count);
+
+ int distx = (fx & 0x0000ffff) >> 8;
+ int idistx = 256 - distx;
+ int rb = ((buf1[x1] * idistx + buf1[x2] * distx) >> 8) & 0xff00ff;
+ int ag = (buf2[x1] * idistx + buf2[x2] * distx) & 0xff00ff00;
+ *b++ = rb | ag;
+ fx += fdx;
+ }
+}
+
+
+typedef void (QT_FASTCALL *BilinearFastTransformFetcher)(uint *buf1, uint *buf2, const int len, const QTextureData &image,
+ int fx, int fy, const int fdx, const int fdy);
+
+template<TextureBlendType blendType, QPixelLayout::BPP bpp>
+static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2, const int len, const QTextureData &image,
+ int fx, int fy, const int fdx, const int fdy)
+{
+ const QPixelLayout &layout = qPixelLayouts[image.format];
+ Q_ASSERT(bpp == QPixelLayout::BPPNone || bpp == layout.bpp);
+ // When templated 'fetch1' should be inlined at compile time:
+ const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout.bpp] : fetchPixel<bpp>;
+ if (fdy == 0) {
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
+ const uchar *s1 = image.scanLine(y1);
+ const uchar *s2 = image.scanLine(y2);
+
+ int i = 0;
+ if (blendType == BlendTransformedBilinear) {
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ if (x1 != x2)
+ break;
+ buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
+ buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
+ fx += fdx;
+ }
+ int fastLen = len;
+ if (fdx > 0)
+ fastLen = qMin(fastLen, int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
+ else if (fdx < 0)
+ fastLen = qMin(fastLen, int((qint64(image.x1) * fixed_scale - fx) / fdx));
+
+ for (; i < fastLen; ++i) {
+ int x = (fx >> 16);
+ buf1[i * 2 + 0] = fetch1(s1, x);
+ buf1[i * 2 + 1] = fetch1(s1, x + 1);
+ buf2[i * 2 + 0] = fetch1(s2, x);
+ buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ fx += fdx;
+ }
+ }
+
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ fx += fdx;
+ }
+ } else {
+ int i = 0;
+ if (blendType == BlendTransformedBilinear) {
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
+ if (x1 != x2 && y1 != y2)
+ break;
+ const uchar *s1 = image.scanLine(y1);
+ const uchar *s2 = image.scanLine(y2);
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ fx += fdx;
+ fy += fdy;
+ }
+ int fastLen = len;
+ if (fdx > 0)
+ fastLen = qMin(fastLen, int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
+ else if (fdx < 0)
+ fastLen = qMin(fastLen, int((qint64(image.x1) * fixed_scale - fx) / fdx));
+ if (fdy > 0)
+ fastLen = qMin(fastLen, int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
+ else if (fdy < 0)
+ fastLen = qMin(fastLen, int((qint64(image.y1) * fixed_scale - fy) / fdy));
+
+ for (; i < fastLen; ++i) {
+ int x = (fx >> 16);
+ int y = (fy >> 16);
+ const uchar *s1 = image.scanLine(y);
+ const uchar *s2 = s1 + image.bytesPerLine;
+ buf1[i * 2 + 0] = fetch1(s1, x);
+ buf1[i * 2 + 1] = fetch1(s1, x + 1);
+ buf2[i * 2 + 0] = fetch1(s2, x);
+ buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ fx += fdx;
+ fy += fdy;
+ }
+ }
+
+ for (; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
+
+ const uchar *s1 = image.scanLine(y1);
+ const uchar *s2 = image.scanLine(y2);
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ fx += fdx;
+ fy += fdy;
+ }
+ }
+}
+
// blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled
template<TextureBlendType blendType, QPixelLayout::BPP bpp>
static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *,
@@ -2664,19 +2899,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
{
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
const QVector<QRgb> *clut = data->texture.colorTable;
- if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
- Q_ASSERT(layout->bpp == bpp);
- // When templated 'fetch' should be inlined at compile time:
- const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : FetchPixelsFunc(fetchPixels<bpp>);
- const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
-
- int image_width = data->texture.width;
- int image_height = data->texture.height;
-
- int image_x1 = data->texture.x1;
- int image_y1 = data->texture.y1;
- int image_x2 = data->texture.x2 - 1;
- int image_y2 = data->texture.y2 - 1;
+ Q_ASSERT(bpp == QPixelLayout::BPPNone || layout->bpp == bpp);
const qreal cx = x + qreal(0.5);
const qreal cy = y + qreal(0.5);
@@ -2692,203 +2915,80 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
fx -= half_point;
fy -= half_point;
- if (fdy == 0) { //simple scale, no rotation
- int y1 = (fy >> 16);
- int y2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
-
+ if (fdy == 0) { // simple scale, no rotation or shear
if (fdx <= fixed_scale && fdx > 0) { // scale up on X
- int disty = (fy & 0x0000ffff) >> 8;
- int idisty = 256 - disty;
- int x = fx >> 16;
-
- // The idea is first to do the interpolation between the row s1 and the row s2
- // into an intermediate buffer, then we interpolate between two pixel of this buffer.
- // +1 for the last pixel to interpolate with, and +1 for rounding errors.
- uint buf1[buffer_size + 2];
- uint buf2[buffer_size + 2];
- const uint *ptr1;
- const uint *ptr2;
-
- int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2;
- Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
-
- if (blendType == BlendTransformedBilinearTiled) {
- x %= image_width;
- if (x < 0)
- x += image_width;
- int len1 = qMin(count, image_width - x);
- int len2 = qMin(x, count - len1);
-
- ptr1 = fetch(buf1, s1, x, len1);
- ptr1 = layout->convertToARGB32PM(buf1, ptr1, len1, clut, 0);
- ptr2 = fetch(buf2, s2, x, len1);
- ptr2 = layout->convertToARGB32PM(buf2, ptr2, len1, clut, 0);
- for (int i = 0; i < len1; ++i) {
- uint t = ptr1[i];
- uint b = ptr2[i];
- buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
- buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
- }
-
- if (len2) {
- ptr1 = fetch(buf1 + len1, s1, 0, len2);
- ptr1 = layout->convertToARGB32PM(buf1 + len1, ptr1, len2, clut, 0);
- ptr2 = fetch(buf2 + len1, s2, 0, len2);
- ptr2 = layout->convertToARGB32PM(buf2 + len1, ptr2, len2, clut, 0);
- for (int i = 0; i < len2; ++i) {
- uint t = ptr1[i];
- uint b = ptr2[i];
- buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
- buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
- }
- }
- for (int i = image_width; i < count; ++i) {
- buf1[i] = buf1[i - image_width];
- buf2[i] = buf2[i - image_width];
- }
- } else {
- int start = qMax(x, image_x1);
- int end = qMin(x + count, image_x2 + 1);
- int len = qMax(1, end - start);
- int leading = start - x;
-
- ptr1 = fetch(buf1 + leading, s1, start, len);
- ptr1 = layout->convertToARGB32PM(buf1 + leading, ptr1, len, clut, 0);
- ptr2 = fetch(buf2 + leading, s2, start, len);
- ptr2 = layout->convertToARGB32PM(buf2 + leading, ptr2, len, clut, 0);
-
- for (int i = 0; i < len; ++i) {
- uint t = ptr1[i];
- uint b = ptr2[i];
- buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
- buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
- }
-
- for (int i = 0; i < leading; ++i) {
- buf1[i] = buf1[leading];
- buf2[i] = buf2[leading];
- }
- for (int i = leading + len; i < count; ++i) {
- buf1[i] = buf1[i - 1];
- buf2[i] = buf2[i - 1];
- }
- }
-
- // Now interpolate the values from the intermediate_buffer to get the final result.
- fx &= fixed_scale - 1;
- Q_ASSERT((fx >> 16) == 0);
- for (int i = 0; i < length; ++i) {
- int x1 = (fx >> 16);
- int x2 = x1 + 1;
- Q_ASSERT(x1 >= 0);
- Q_ASSERT(x2 < count);
-
- int distx = (fx & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int rb = ((buf1[x1] * idistx + buf1[x2] * distx) >> 8) & 0xff00ff;
- int ag = (buf2[x1] * idistx + buf2[x2] * distx) & 0xff00ff00;
- buffer[i] = rb | ag;
- fx += fdx;
- }
+ fetchTransformedBilinear_simple_upscale_helper<blendType, bpp>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
} else {
+ const BilinearFastTransformFetcher fetcher = fetchTransformedBilinear_fetcher<blendType,bpp>;
+
uint buf1[buffer_size];
uint buf2[buffer_size];
uint *b = buffer;
while (length) {
int len = qMin(length, buffer_size / 2);
- int fracX = fx;
- for (int i = 0; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- buf1[i * 2 + 0] = fetch1(s1, x1);
- buf1[i * 2 + 1] = fetch1(s1, x2);
- buf2[i * 2 + 0] = fetch1(s2, x1);
- buf2[i * 2 + 1] = fetch1(s2, x2);
- fx += fdx;
- }
+ fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
if ((fdx < 0 && fdx > -(fixed_scale / 8)) || qAbs(data->m22) < qreal(1./8.)) { // scale up more than 8x
int disty = (fy & 0x0000ffff) >> 8;
for (int i = 0; i < len; ++i) {
- int distx = (fracX & 0x0000ffff) >> 8;
+ int distx = (fx & 0x0000ffff) >> 8;
b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
- fracX += fdx;
+ fx += fdx;
}
- } else { //scale down
+ } else {
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
for (int i = 0; i < len; ++i) {
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
- int distx = ((fracX & 0x0000ffff) + 0x0800) >> 12;
+ int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
- fracX += fdx;
+ fx += fdx;
}
}
length -= len;
b += len;
}
}
- } else { //rotation
+ } else { // rotation or shear
+ const BilinearFastTransformFetcher fetcher = fetchTransformedBilinear_fetcher<blendType,bpp>;
+
uint buf1[buffer_size];
uint buf2[buffer_size];
uint *b = buffer;
-
while (length) {
int len = qMin(length, buffer_size / 2);
- int fracX = fx;
- int fracY = fy;
- for (int i = 0; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- int y1 = (fy >> 16);
- int y2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
-
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
- buf1[i * 2 + 0] = fetch1(s1, x1);
- buf1[i * 2 + 1] = fetch1(s1, x2);
- buf2[i * 2 + 0] = fetch1(s2, x1);
- buf2[i * 2 + 1] = fetch1(s2, x2);
- fx += fdx;
- fy += fdy;
- }
+ fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
- if (qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.) ) {
- //if we are zooming more than 8 times, we use 8bit precision for the position.
+ if (qAbs(data->m11) < qreal(1./8.)|| qAbs(data->m22) < qreal(1./8.)) {
+ // If we are zooming more than 8 times, we use 8bit precision for the position.
for (int i = 0; i < len; ++i) {
- int distx = (fracX & 0x0000ffff) >> 8;
- int disty = (fracY & 0x0000ffff) >> 8;
+ int distx = (fx & 0x0000ffff) >> 8;
+ int disty = (fy & 0x0000ffff) >> 8;
b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
- fracX += fdx;
- fracY += fdy;
+ fx += fdx;
+ fy += fdy;
}
} else {
- //we are zooming less than 8x, use 4bit precision
+ // We are zooming less than 8x, use 4bit precision
for (int i = 0; i < len; ++i) {
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
- int distx = ((fracX & 0x0000ffff) + 0x0800) >> 12;
- int disty = ((fracY & 0x0000ffff) + 0x0800) >> 12;
+ int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
+ int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
- fracX += fdx;
- fracY += fdy;
+ fx += fdx;
+ fy += fdy;
}
}
@@ -2897,6 +2997,11 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
}
}
} else {
+ // When templated 'fetch' should be inlined at compile time:
+ const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel<bpp>;
+
+ const QTextureData &image = data->texture;
+
const qreal fdx = data->m11;
const qreal fdy = data->m12;
const qreal fdw = data->m13;
@@ -2927,8 +3032,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
distxs[i] = int((px - x1) * 256);
distys[i] = int((py - y1) * 256);
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
const uchar *s1 = data->texture.scanLine(y1);
const uchar *s2 = data->texture.scanLine(y2);
@@ -2969,21 +3074,9 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
const QVector<QRgb> *clut = data->texture.colorTable;
- int image_width = data->texture.width;
- int image_height = data->texture.height;
-
- int image_x1 = data->texture.x1;
- int image_y1 = data->texture.y1;
- int image_x2 = data->texture.x2 - 1;
- int image_y2 = data->texture.y2 - 1;
-
const qreal cx = x + qreal(0.5);
const qreal cy = y + qreal(0.5);
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
if (data->fast_matrix) {
// The increment pr x in the scanline
int fdx = (int)(data->m11 * fixed_scale);
@@ -2995,14 +3088,13 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
fx -= half_point;
fy -= half_point;
+ const BilinearFastTransformFetcher fetcher =
+ (layout->bpp == QPixelLayout::BPP32)
+ ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32>
+ : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone>;
+
if (fdy == 0) { //simple scale, no rotation
- int y1 = (fy >> 16);
- int y2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
- FetchPixelFunc fetch = qFetchPixel[layout->bpp];
uint sbuf1[buffer_size];
uint sbuf2[buffer_size];
quint64 buf1[buffer_size];
@@ -3010,84 +3102,19 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
QRgba64 *b = buffer;
while (length) {
int len = qMin(length, buffer_size / 2);
- int fracX = fx;
- int i = 0;
int disty = (fy & 0x0000ffff);
#if defined(__SSE2__)
const __m128i vdy = _mm_set1_epi16(disty);
const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
- if (blendType != BlendTransformedBilinearTiled && layout->bpp == QPixelLayout::BPP32) {
- for (; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- if (x1 != x2)
- break;
- sbuf1[i * 2 + 0] = sbuf1[i * 2 + 1] = ((const uint*)s1)[x1];
- sbuf2[i * 2 + 0] = sbuf2[i * 2 + 1] = ((const uint*)s2)[x1];
- fx += fdx;
- }
- int fastLen;
- if (fdx > 0)
- fastLen = qMin(len, int((image_x2 - (fx >> 16)) / data->m11));
- else
- fastLen = qMin(len, int((image_x1 - (fx >> 16)) / data->m11));
- fastLen -= 3;
-
- const __m128i v_fdx = _mm_set1_epi32(fdx*4);
- __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
- for (; i < fastLen; i += 4) {
- int offset = _mm_extract_epi16(v_fx, 1);
- sbuf1[i * 2 + 0] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[offset + 1];
- offset = _mm_extract_epi16(v_fx, 3);
- sbuf1[i * 2 + 2] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 3] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 2] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 3] = ((const uint*)s2)[offset + 1];
- offset = _mm_extract_epi16(v_fx, 5);
- sbuf1[i * 2 + 4] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 5] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 4] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 5] = ((const uint*)s2)[offset + 1];
- offset = _mm_extract_epi16(v_fx, 7);
- sbuf1[i * 2 + 6] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 7] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 6] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 7] = ((const uint*)s2)[offset + 1];
- v_fx = _mm_add_epi32(v_fx, v_fdx);
- }
- fx = _mm_cvtsi128_si32(v_fx);
- }
#endif
- for (; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
-
- if (layout->bpp == QPixelLayout::BPP32) {
- sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
-
- } else {
- sbuf1[i * 2 + 0] = fetch(s1, x1);
- sbuf1[i * 2 + 1] = fetch(s1, x2);
- sbuf2[i * 2 + 0] = fetch(s2, x1);
- sbuf2[i * 2 + 1] = fetch(s2, x2);
- }
+ fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
- fx += fdx;
- }
layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0);
if (disty)
layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0);
for (int i = 0; i < len; ++i) {
- int distx = (fracX & 0x0000ffff);
+ int distx = (fx & 0x0000ffff);
#if defined(__SSE2__)
const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
@@ -3104,13 +3131,12 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
#else
b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty);
#endif
- fracX += fdx;
+ fx += fdx;
}
length -= len;
b += len;
}
} else { //rotation
- FetchPixelFunc fetch = qFetchPixel[layout->bpp];
uint sbuf1[buffer_size];
uint sbuf2[buffer_size];
quint64 buf1[buffer_size];
@@ -3120,117 +3146,18 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
while (b < end) {
int len = qMin(length, buffer_size / 2);
- int fracX = fx;
- int fracY = fy;
- int i = 0;
-#if defined(__SSE2__)
- if (blendType != BlendTransformedBilinearTiled && layout->bpp == QPixelLayout::BPP32) {
- for (; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- int y1 = (fy >> 16);
- int y2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- if (x1 != x2 && y1 != y2)
- break;
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
- sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
- fx += fdx;
- fy += fdy;
- }
- int fastLen = len;
- if (fdx > 0)
- fastLen = qMin(fastLen, int((qint64(image_x2) * fixed_scale - fx) / fdx));
- else if (fdx < 0)
- fastLen = qMin(fastLen, int((qint64(image_x1) * fixed_scale - fx) / fdx));
- if (fdy > 0)
- fastLen = qMin(fastLen, int((qint64(image_y2) * fixed_scale - fy) / fdy));
- else if (fdy < 0)
- fastLen = qMin(fastLen, int((qint64(image_y1) * fixed_scale - fy) / fdy));
- fastLen -= 3;
-
- const __m128i v_fdx = _mm_set1_epi32(fdx*4);
- const __m128i v_fdy = _mm_set1_epi32(fdy*4);
- __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
- __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
- const int bytesPerLine = data->texture.bytesPerLine;
- const uchar *s1 = data->texture.imageData;
- const uchar *s2 = s1 + bytesPerLine;
- const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
- for (; i < fastLen; i += 4) {
- const __m128i vy = _mm_packs_epi32(_mm_srai_epi32(v_fy, 16), _mm_setzero_si128());
- __m128i voffset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epu16(vy, vbpl));
- voffset = _mm_add_epi32(voffset, _mm_srli_epi32(v_fx, 16));
-
- int offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
- sbuf1[i * 2 + 0] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[offset + 1];
- offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
- sbuf1[i * 2 + 2] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 3] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 2] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 3] = ((const uint*)s2)[offset + 1];
- offset = _mm_cvtsi128_si32(voffset); voffset = _mm_srli_si128(voffset, 4);
- sbuf1[i * 2 + 4] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 5] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 4] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 5] = ((const uint*)s2)[offset + 1];
- offset = _mm_cvtsi128_si32(voffset);
- sbuf1[i * 2 + 6] = ((const uint*)s1)[offset];
- sbuf1[i * 2 + 7] = ((const uint*)s1)[offset + 1];
- sbuf2[i * 2 + 6] = ((const uint*)s2)[offset];
- sbuf2[i * 2 + 7] = ((const uint*)s2)[offset + 1];
-
- v_fx = _mm_add_epi32(v_fx, v_fdx);
- v_fy = _mm_add_epi32(v_fy, v_fdy);
- }
- fx = _mm_cvtsi128_si32(v_fx);
- fy = _mm_cvtsi128_si32(v_fy);
- }
-#endif
- for (; i < len; ++i) {
- int x1 = (fx >> 16);
- int x2;
- int y1 = (fy >> 16);
- int y2;
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
-
- if (layout->bpp == QPixelLayout::BPP32) {
- sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
-
- } else {
- sbuf1[i * 2 + 0] = fetch(s1, x1);
- sbuf1[i * 2 + 1] = fetch(s1, x2);
- sbuf2[i * 2 + 0] = fetch(s2, x1);
- sbuf2[i * 2 + 1] = fetch(s2, x2);
- }
+ fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
- fx += fdx;
- fy += fdy;
- }
layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0);
layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0);
for (int i = 0; i < len; ++i) {
- int distx = (fracX & 0x0000ffff);
- int disty = (fracY & 0x0000ffff);
+ int distx = (fx & 0x0000ffff);
+ int disty = (fy & 0x0000ffff);
b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty);
- fracX += fdx;
- fracY += fdy;
+ fx += fdx;
+ fy += fdy;
}
length -= len;
@@ -3238,6 +3165,12 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
}
}
} else {
+ const QTextureData &image = data->texture;
+
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+
qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
@@ -3267,8 +3200,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
distxs[i] = int((px - x1) * (1<<16));
distys[i] = int((py - y1) * (1<<16));
- fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
const uchar *s1 = data->texture.scanLine(y1);
const uchar *s2 = data->texture.scanLine(y2);
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c
index 4a135e25d8..0143e9b602 100644
--- a/src/gui/painting/qgrayraster.c
+++ b/src/gui/painting/qgrayraster.c
@@ -43,7 +43,7 @@
/* */
/* A new `perfect' anti-aliasing renderer (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003 by */
+/* Copyright 2000-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -119,10 +119,6 @@
/* */
/*************************************************************************/
-/* experimental support for gamma correction within the rasterizer */
-#define xxxGRAYS_USE_GAMMA
-
-
/*************************************************************************/
/* */
/* The macro QT_FT_COMPONENT is used in trace mode. It is an implicit */
@@ -133,6 +129,28 @@
#define QT_FT_COMPONENT trace_smooth
+/* Auxiliary macros for token concatenation. */
+#define QT_FT_ERR_XCAT( x, y ) x ## y
+#define QT_FT_ERR_CAT( x, y ) QT_FT_ERR_XCAT( x, y )
+
+#define QT_FT_BEGIN_STMNT do {
+#define QT_FT_END_STMNT } while ( 0 )
+
+#define QT_FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
+#define QT_FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
+
+
+/*
+ * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
+ * algorithm. We use alpha = 1, beta = 3/8, giving us results with a
+ * largest error less than 7% compared to the exact value.
+ */
+#define QT_FT_HYPOT( x, y ) \
+ ( x = QT_FT_ABS( x ), \
+ y = QT_FT_ABS( y ), \
+ x > y ? x + ( 3 * y >> 3 ) \
+ : y + ( 3 * x >> 3 ) )
+
#define ErrRaster_MemoryOverflow -4
#if defined(VXWORKS)
@@ -150,6 +168,9 @@
#define qt_ft_longjmp longjmp
#define qt_ft_jmp_buf jmp_buf
+#include <stddef.h>
+typedef ptrdiff_t QT_FT_PtrDist;
+
#define ErrRaster_Invalid_Mode -2
#define ErrRaster_Invalid_Outline -1
#define ErrRaster_Invalid_Argument -3
@@ -169,15 +190,10 @@
#define QT_FT_UNUSED( x ) (void) x
- /* Disable the tracing mechanism for simplicity -- developers can */
- /* activate it easily by redefining these two macros. */
-#ifndef QT_FT_ERROR
-#define QT_FT_ERROR( x ) do ; while ( 0 ) /* nothing */
-#endif
-
-#ifndef QT_FT_TRACE
-#define QT_FT_TRACE( x ) do ; while ( 0 ) /* nothing */
-#endif
+#define QT_FT_TRACE5( x ) do { } while ( 0 ) /* nothing */
+#define QT_FT_TRACE7( x ) do { } while ( 0 ) /* nothing */
+#define QT_FT_ERROR( x ) do { } while ( 0 ) /* nothing */
+#define QT_FT_THROW( e ) QT_FT_ERR_CAT( ErrRaster_, e )
#ifndef QT_FT_MEM_SET
#define QT_FT_MEM_SET( d, s, c ) qt_ft_memset( d, s, c )
@@ -187,9 +203,6 @@
#define QT_FT_MEM_ZERO( dest, count ) QT_FT_MEM_SET( dest, 0, count )
#endif
- /* define this to dump debugging information */
-#define xxxDEBUG_GRAYS
-
#define RAS_ARG PWorker worker
#define RAS_ARG_ PWorker worker,
@@ -199,26 +212,47 @@
#define ras (*worker)
-
/* must be at least 6 bits! */
#define PIXEL_BITS 8
#define ONE_PIXEL ( 1L << PIXEL_BITS )
-#define PIXEL_MASK ( -1L << PIXEL_BITS )
#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) )
-#define SUBPIXELS( x ) ( (TPos)(x) * ( 1 << PIXEL_BITS ) )
+#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL )
#define FLOOR( x ) ( (x) & -ONE_PIXEL )
#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
#if PIXEL_BITS >= 6
-#define UPSCALE( x ) ( (x) * ( 1 << ( PIXEL_BITS - 6 ) ) )
+#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) )
#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) )
#else
#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) )
-#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) )
+#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) )
#endif
+/* Compute `dividend / divisor' and return both its quotient and */
+/* remainder, cast to a specific type. This macro also ensures that */
+/* the remainder is always positive. */
+#define QT_FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
+QT_FT_BEGIN_STMNT \
+ (quotient) = (type)( (dividend) / (divisor) ); \
+ (remainder) = (type)( (dividend) % (divisor) ); \
+ if ( (remainder) < 0 ) \
+ { \
+ (quotient)--; \
+ (remainder) += (type)(divisor); \
+ } \
+QT_FT_END_STMNT
+
+ /* These macros speed up repetitive divisions by replacing them */
+ /* with multiplications and right shifts. */
+#define QT_FT_UDIVPREP( b ) \
+ long b ## _r = (long)( ULONG_MAX >> PIXEL_BITS ) / ( b )
+#define QT_FT_UDIV( a, b ) \
+ ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \
+ ( sizeof( long ) * CHAR_BIT - PIXEL_BITS ) )
+
+
/*************************************************************************/
/* */
/* TYPE DEFINITIONS */
@@ -228,28 +262,9 @@
/* need to define them to "float" or "double" when experimenting with */
/* new algorithms */
- typedef int TCoord; /* integer scanline/pixel coordinate */
- typedef int TPos; /* sub-pixel coordinate */
-
- /* determine the type used to store cell areas. This normally takes at */
- /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */
- /* `long' instead of `int', otherwise bad things happen */
-
-#if PIXEL_BITS <= 7
-
- typedef int TArea;
-
-#else /* PIXEL_BITS >= 8 */
-
- /* approximately determine the size of integers using an ANSI-C header */
-#if QT_FT_UINT_MAX == 0xFFFFU
- typedef long TArea;
-#else
- typedef int TArea;
-#endif
-
-#endif /* PIXEL_BITS >= 8 */
-
+ typedef long TCoord; /* integer scanline/pixel coordinate */
+ typedef long TPos; /* sub-pixel coordinate */
+ typedef long TArea ; /* cell areas, coordinate products */
/* maximal number of gray spans in a call to the span callback */
#define QT_FT_MAX_GRAY_SPANS 256
@@ -279,17 +294,11 @@
int invalid;
PCell cells;
- int max_cells;
- int num_cells;
+ QT_FT_PtrDist max_cells;
+ QT_FT_PtrDist num_cells;
- TCoord cx, cy;
TPos x, y;
- TPos last_ey;
-
- QT_FT_Vector bez_stack[32 * 3 + 1];
- int lev_stack[32];
-
QT_FT_Outline outline;
QT_FT_Bitmap target;
QT_FT_BBox clip_box;
@@ -302,8 +311,6 @@
int band_size;
int band_shoot;
- int conic_level;
- int cubic_level;
qt_ft_jmp_buf jump_buffer;
@@ -311,7 +318,7 @@
long buffer_size;
PCell* ycells;
- int ycount;
+ TPos ycount;
int skip_spans;
} TWorker, *PWorker;
@@ -341,7 +348,7 @@
/* */
static void
gray_init_cells( RAS_ARG_ void* buffer,
- long byte_size )
+ long byte_size )
{
ras.buffer = buffer;
ras.buffer_size = byte_size;
@@ -404,31 +411,25 @@
/* */
/* Record the current cell in the table. */
/* */
- static void
- gray_record_cell( RAS_ARG )
+ static PCell
+ gray_find_cell( RAS_ARG )
{
PCell *pcell, cell;
- int x = ras.ex;
+ TPos x = ras.ex;
- if ( ras.invalid || !( ras.area | ras.cover ) )
- return;
- if ( x > ras.max_ex )
- x = ras.max_ex;
+ if ( x > ras.count_ex )
+ x = ras.count_ex;
pcell = &ras.ycells[ras.ey];
-
for (;;)
{
cell = *pcell;
if ( cell == NULL || cell->x > x )
break;
- if ( cell->x == x ) {
- cell->area += ras.area;
- cell->cover += ras.cover;
- return;
- }
+ if ( cell->x == x )
+ goto Exit;
pcell = &cell->next;
}
@@ -438,11 +439,28 @@
cell = ras.cells + ras.num_cells++;
cell->x = x;
- cell->area = ras.area;
- cell->cover = ras.cover;
+ cell->area = 0;
+ cell->cover = 0;
cell->next = *pcell;
*pcell = cell;
+
+ Exit:
+ return cell;
+ }
+
+
+ static void
+ gray_record_cell( RAS_ARG )
+ {
+ if ( ras.area | ras.cover )
+ {
+ PCell cell = gray_find_cell( RAS_VAR );
+
+
+ cell->area += ras.area;
+ cell->cover += ras.cover;
+ }
}
@@ -488,8 +506,8 @@
ras.ey = ey;
}
- ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
- ex >= ras.count_ex );
+ ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey ||
+ ex >= ras.count_ex );
}
@@ -511,12 +529,13 @@
ras.cover = 0;
ras.ex = ex - ras.min_ex;
ras.ey = ey - ras.min_ey;
- ras.last_ey = SUBPIXELS( ey );
ras.invalid = 0;
gray_set_cell( RAS_VAR_ ex, ey );
}
+// The new render-line implementation is not yet used
+#if 1
/*************************************************************************/
/* */
@@ -529,9 +548,9 @@
TPos x2,
TCoord y2 )
{
- TCoord ex1, ex2, fx1, fx2, delta;
+ TCoord ex1, ex2, fx1, fx2, delta, mod;
int p, first, dx;
- int incr, lift, mod, rem;
+ int incr;
dx = x2 - x1;
@@ -573,13 +592,7 @@
dx = -dx;
}
- delta = (TCoord)( p / dx );
- mod = (TCoord)( p % dx );
- if ( mod < 0 )
- {
- delta--;
- mod += (TCoord)dx;
- }
+ QT_FT_DIV_MOD( TCoord, p, dx, delta, mod );
ras.area += (TArea)( fx1 + first ) * delta;
ras.cover += delta;
@@ -590,14 +603,11 @@
if ( ex1 != ex2 )
{
- p = ONE_PIXEL * ( y2 - y1 + delta );
- lift = (TCoord)( p / dx );
- rem = (TCoord)( p % dx );
- if ( rem < 0 )
- {
- lift--;
- rem += (TCoord)dx;
- }
+ TCoord lift, rem;
+
+
+ p = ONE_PIXEL * ( y2 - y1 + delta );
+ QT_FT_DIV_MOD( TCoord, p, dx, lift, rem );
mod -= (int)dx;
@@ -633,38 +643,24 @@
gray_render_line( RAS_ARG_ TPos to_x,
TPos to_y )
{
- TCoord ey1, ey2, fy1, fy2;
+ TCoord ey1, ey2, fy1, fy2, mod;
TPos dx, dy, x, x2;
int p, first;
- int delta, rem, mod, lift, incr;
+ int delta, rem, lift, incr;
- ey1 = TRUNC( ras.last_ey );
+ ey1 = TRUNC( ras.y );
ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
- fy1 = (TCoord)( ras.y - ras.last_ey );
+ fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
dx = to_x - ras.x;
dy = to_y - ras.y;
- /* XXX: we should do something about the trivial case where dx == 0, */
- /* as it happens very often! */
-
/* perform vertical clipping */
- {
- TCoord min, max;
-
-
- min = ey1;
- max = ey2;
- if ( ey1 > ey2 )
- {
- min = ey2;
- max = ey1;
- }
- if ( min >= ras.max_ey || max < ras.min_ey )
- goto End;
- }
+ if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
+ ( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
+ goto End;
/* everything is on a single scanline */
if ( ey1 == ey2 )
@@ -771,13 +767,7 @@
if ( ey1 != ey2 )
{
p = ONE_PIXEL * dx;
- lift = (int)( p / dy );
- rem = (int)( p % dy );
- if ( rem < 0 )
- {
- lift--;
- rem += (int)dy;
- }
+ QT_FT_DIV_MOD( int, p, dy, lift, rem );
mod -= (int)dy;
while ( ey1 != ey2 )
@@ -808,10 +798,147 @@
End:
ras.x = to_x;
ras.y = to_y;
- ras.last_ey = SUBPIXELS( ey2 );
}
+#else
+
+ /*************************************************************************/
+ /* */
+ /* Render a straight line across multiple cells in any direction. */
+ /* */
+ static void
+ gray_render_line( RAS_ARG_ TPos to_x,
+ TPos to_y )
+ {
+ TPos dx, dy, fx1, fy1, fx2, fy2;
+ TCoord ex1, ex2, ey1, ey2;
+
+
+ ex1 = TRUNC( ras.x );
+ ex2 = TRUNC( to_x );
+ ey1 = TRUNC( ras.y );
+ ey2 = TRUNC( to_y );
+
+ /* perform vertical clipping */
+ if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
+ ( ey1 < ras.min_ey && ey2 < ras.min_ey ) )
+ goto End;
+
+ dx = to_x - ras.x;
+ dy = to_y - ras.y;
+
+ fx1 = ras.x - SUBPIXELS( ex1 );
+ fy1 = ras.y - SUBPIXELS( ey1 );
+
+ if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */
+ ;
+ else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */
+ {
+ ex1 = ex2;
+ gray_set_cell( RAS_VAR_ ex1, ey1 );
+ }
+ else if ( dx == 0 )
+ {
+ if ( dy > 0 ) /* vertical line up */
+ do
+ {
+ fy2 = ONE_PIXEL;
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * fx1 * 2;
+ fy1 = 0;
+ ey1++;
+ gray_set_cell( RAS_VAR_ ex1, ey1 );
+ } while ( ey1 != ey2 );
+ else /* vertical line down */
+ do
+ {
+ fy2 = 0;
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * fx1 * 2;
+ fy1 = ONE_PIXEL;
+ ey1--;
+ gray_set_cell( RAS_VAR_ ex1, ey1 );
+ } while ( ey1 != ey2 );
+ }
+ else /* any other line */
+ {
+ TArea prod = dx * fy1 - dy * fx1;
+ QT_FT_UDIVPREP( dx );
+ QT_FT_UDIVPREP( dy );
+
+
+ /* The fundamental value `prod' determines which side and the */
+ /* exact coordinate where the line exits current cell. It is */
+ /* also easily updated when moving from one cell to the next. */
+ do
+ {
+ if ( prod <= 0 &&
+ prod - dx * ONE_PIXEL > 0 ) /* left */
+ {
+ fx2 = 0;
+ fy2 = (TPos)QT_FT_UDIV( -prod, -dx );
+ prod -= dy * ONE_PIXEL;
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
+ fx1 = ONE_PIXEL;
+ fy1 = fy2;
+ ex1--;
+ }
+ else if ( prod - dx * ONE_PIXEL <= 0 &&
+ prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */
+ {
+ prod -= dx * ONE_PIXEL;
+ fx2 = (TPos)QT_FT_UDIV( -prod, dy );
+ fy2 = ONE_PIXEL;
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
+ fx1 = fx2;
+ fy1 = 0;
+ ey1++;
+ }
+ else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 &&
+ prod + dy * ONE_PIXEL >= 0 ) /* right */
+ {
+ prod += dy * ONE_PIXEL;
+ fx2 = ONE_PIXEL;
+ fy2 = (TPos)QT_FT_UDIV( prod, dx );
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
+ fx1 = 0;
+ fy1 = fy2;
+ ex1++;
+ }
+ else /* ( prod + dy * ONE_PIXEL < 0 &&
+ prod > 0 ) down */
+ {
+ fx2 = (TPos)QT_FT_UDIV( prod, -dy );
+ fy2 = 0;
+ prod += dx * ONE_PIXEL;
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
+ fx1 = fx2;
+ fy1 = ONE_PIXEL;
+ ey1--;
+ }
+
+ gray_set_cell( RAS_VAR_ ex1, ey1 );
+ } while ( ex1 != ex2 || ey1 != ey2 );
+ }
+
+ fx2 = to_x - SUBPIXELS( ex2 );
+ fy2 = to_y - SUBPIXELS( ey2 );
+
+ ras.cover += ( fy2 - fy1 );
+ ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 );
+
+ End:
+ ras.x = to_x;
+ ras.y = to_y;
+ }
+
+#endif
+
static void
gray_split_conic( QT_FT_Vector* base )
{
@@ -836,52 +963,11 @@
gray_render_conic( RAS_ARG_ const QT_FT_Vector* control,
const QT_FT_Vector* to )
{
+ QT_FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */
+ QT_FT_Vector* arc = bez_stack;
TPos dx, dy;
- int top, level;
- int* levels;
- QT_FT_Vector* arc;
-
-
- dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
-
- level = 1;
- dx = dx / ras.conic_level;
- while ( dx > 0 )
- {
- dx >>= 2;
- level++;
- }
+ int draw, split;
- /* a shortcut to speed things up */
- if ( level <= 1 )
- {
- /* we compute the mid-point directly in order to avoid */
- /* calling gray_split_conic() */
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = UPSCALE( to->x );
- to_y = UPSCALE( to->y );
- mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
- mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
-
- return;
- }
-
- arc = ras.bez_stack;
- levels = ras.lev_stack;
- top = 0;
- levels[0] = level;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
@@ -890,54 +976,51 @@
arc[2].x = ras.x;
arc[2].y = ras.y;
- while ( top >= 0 )
+ /* short-cut the arc that crosses the current band */
+ if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+ TRUNC( arc[1].y ) >= ras.max_ey &&
+ TRUNC( arc[2].y ) >= ras.max_ey ) ||
+ ( TRUNC( arc[0].y ) < ras.min_ey &&
+ TRUNC( arc[1].y ) < ras.min_ey &&
+ TRUNC( arc[2].y ) < ras.min_ey ) )
{
- level = levels[top];
- if ( level > 1 )
- {
- /* check that the arc crosses the current band */
- TPos min, max, y;
-
-
- min = max = arc[0].y;
-
- y = arc[1].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
+ ras.x = arc[0].x;
+ ras.y = arc[0].y;
+ return;
+ }
- y = arc[2].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
+ dx = QT_FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
+ dy = QT_FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
+ if ( dx < dy )
+ dx = dy;
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
- goto Draw;
+ /* We can calculate the number of necessary bisections because */
+ /* each bisection predictably reduces deviation exactly 4-fold. */
+ /* Even 32-bit deviation would vanish after 16 bisections. */
+ draw = 1;
+ while ( dx > ONE_PIXEL / 4 )
+ {
+ dx >>= 2;
+ draw <<= 1;
+ }
+ /* We use decrement counter to count the total number of segments */
+ /* to draw starting from 2^level. Before each draw we split as */
+ /* many times as there are trailing zeros in the counter. */
+ do
+ {
+ split = 1;
+ while ( ( draw & split ) == 0 )
+ {
gray_split_conic( arc );
arc += 2;
- top++;
- levels[top] = levels[top - 1] = level - 1;
- continue;
+ split <<= 1;
}
- Draw:
- {
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = arc[0].x;
- to_y = arc[0].y;
- mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
- mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
-
- top--;
- arc -= 2;
- }
- }
+ gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
+ arc -= 2;
- return;
+ } while ( --draw );
}
@@ -974,60 +1057,13 @@
const QT_FT_Vector* control2,
const QT_FT_Vector* to )
{
- TPos dx, dy, da, db;
- int top, level;
- int* levels;
- QT_FT_Vector* arc;
+ QT_FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */
+ QT_FT_Vector* arc = bez_stack;
+ TPos dx, dy, dx_, dy_;
+ TPos dx1, dy1, dx2, dy2;
+ TPos L, s, s_limit;
- dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
- da = dx;
-
- dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->y + control2->y );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
- db = dx;
-
- level = 1;
- da = da / ras.cubic_level;
- db = db / ras.conic_level;
- while ( da > 0 || db > 0 )
- {
- da >>= 2;
- db >>= 3;
- level++;
- }
-
- if ( level <= 1 )
- {
- TPos to_x, to_y, mid_x, mid_y;
-
-
- to_x = UPSCALE( to->x );
- to_y = UPSCALE( to->y );
- mid_x = ( ras.x + to_x +
- 3 * UPSCALE( control1->x + control2->x ) ) / 8;
- mid_y = ( ras.y + to_y +
- 3 * UPSCALE( control1->y + control2->y ) ) / 8;
-
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
- return;
- }
-
- arc = ras.bez_stack;
arc[0].x = UPSCALE( to->x );
arc[0].y = UPSCALE( to->y );
arc[1].x = UPSCALE( control2->x );
@@ -1037,56 +1073,77 @@
arc[3].x = ras.x;
arc[3].y = ras.y;
- levels = ras.lev_stack;
- top = 0;
- levels[0] = level;
+ /* short-cut the arc that crosses the current band */
+ if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+ TRUNC( arc[1].y ) >= ras.max_ey &&
+ TRUNC( arc[2].y ) >= ras.max_ey &&
+ TRUNC( arc[3].y ) >= ras.max_ey ) ||
+ ( TRUNC( arc[0].y ) < ras.min_ey &&
+ TRUNC( arc[1].y ) < ras.min_ey &&
+ TRUNC( arc[2].y ) < ras.min_ey &&
+ TRUNC( arc[3].y ) < ras.min_ey ) )
+ {
+ ras.x = arc[0].x;
+ ras.y = arc[0].y;
+ return;
+ }
- while ( top >= 0 )
+ for (;;)
{
- level = levels[top];
- if ( level > 1 )
- {
- /* check that the arc crosses the current band */
- TPos min, max, y;
-
-
- min = max = arc[0].y;
- y = arc[1].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
- y = arc[2].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
- y = arc[3].y;
- if ( y < min ) min = y;
- if ( y > max ) max = y;
- if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
- goto Draw;
- gray_split_cubic( arc );
- arc += 3;
- top ++;
- levels[top] = levels[top - 1] = level - 1;
- continue;
- }
+ /* Decide whether to split or draw. See `Rapid Termination */
+ /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
+ /* F. Hain, at */
+ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
- Draw:
- {
- TPos to_x, to_y, mid_x, mid_y;
+ /* dx and dy are x and y components of the P0-P3 chord vector. */
+ dx = dx_ = arc[3].x - arc[0].x;
+ dy = dy_ = arc[3].y - arc[0].y;
- to_x = arc[0].x;
- to_y = arc[0].y;
- mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
- mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
+ L = QT_FT_HYPOT( dx_, dy_ );
- gray_render_line( RAS_VAR_ mid_x, mid_y );
- gray_render_line( RAS_VAR_ to_x, to_y );
- top --;
- arc -= 3;
- }
- }
+ /* Avoid possible arithmetic overflow below by splitting. */
+ if ( L > 32767 )
+ goto Split;
+
+ /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
+ s_limit = L * (TPos)( ONE_PIXEL / 6 );
+
+ /* s is L * the perpendicular distance from P1 to the line P0-P3. */
+ dx1 = arc[1].x - arc[0].x;
+ dy1 = arc[1].y - arc[0].y;
+ s = QT_FT_ABS( dy * dx1 - dx * dy1 );
+
+ if ( s > s_limit )
+ goto Split;
+
+ /* s is L * the perpendicular distance from P2 to the line P0-P3. */
+ dx2 = arc[2].x - arc[0].x;
+ dy2 = arc[2].y - arc[0].y;
+ s = QT_FT_ABS( dy * dx2 - dx * dy2 );
+
+ if ( s > s_limit )
+ goto Split;
+
+ /* Split super curvy segments where the off points are so far
+ from the chord that the angles P0-P1-P3 or P0-P2-P3 become
+ acute as detected by appropriate dot products. */
+ if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
+ dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+ goto Split;
- return;
+ gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
+
+ if ( arc == bez_stack )
+ return;
+
+ arc -= 3;
+ continue;
+
+ Split:
+ gray_split_cubic( arc );
+ arc += 3;
+ }
}
@@ -1099,7 +1156,8 @@
/* record current cell, if any */
- gray_record_cell( worker );
+ if ( !ras.invalid )
+ gray_record_cell( worker );
/* start to a new position */
x = UPSCALE( to->x );
@@ -1107,15 +1165,15 @@
gray_start_cell( worker, TRUNC( x ), TRUNC( y ) );
- worker->x = x;
- worker->y = y;
+ ras.x = x;
+ ras.y = y;
return 0;
}
static void
- gray_render_span( int count,
+ gray_render_span( int count,
const QT_FT_Span* spans,
- PWorker worker )
+ PWorker worker )
{
unsigned char* p;
QT_FT_Bitmap* map = &worker->target;
@@ -1127,34 +1185,30 @@
/* first of all, compute the scanline offset */
p = (unsigned char*)map->buffer - spans->y * map->pitch;
if ( map->pitch >= 0 )
- p += ( map->rows - 1 ) * map->pitch;
+ p += ( map->rows - 1 ) * (unsigned int)map->pitch;
if ( coverage )
{
+ unsigned char* q = p + spans->x;
+
+
/* For small-spans it is faster to do it by ourselves than
* calling `memset'. This is mainly due to the cost of the
* function call.
*/
- if ( spans->len >= 8 )
- QT_FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
- else
+ switch ( spans->len )
{
- unsigned char* q = p + spans->x;
-
-
- switch ( spans->len )
- {
- case 7: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 6: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 5: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 4: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 3: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 2: *q++ = (unsigned char)coverage; Q_FALLTHROUGH();
- case 1: *q = (unsigned char)coverage;
- default:
- ;
- }
+ case 7: *q++ = coverage; Q_FALLTHROUGH();
+ case 6: *q++ = coverage; Q_FALLTHROUGH();
+ case 5: *q++ = coverage; Q_FALLTHROUGH();
+ case 4: *q++ = coverage; Q_FALLTHROUGH();
+ case 3: *q++ = coverage; Q_FALLTHROUGH();
+ case 2: *q++ = coverage; Q_FALLTHROUGH();
+ case 1: *q = coverage; Q_FALLTHROUGH();
+ case 0: break;
+ default:
+ QT_FT_MEM_SET( q, coverage, spans->len );
}
}
}
@@ -1167,9 +1221,7 @@
TPos area,
int acount )
{
- QT_FT_Span* span;
- int coverage;
- int skip;
+ int coverage;
/* compute the coverage line's coverage, depending on the */
@@ -1202,14 +1254,24 @@
x += (TCoord)ras.min_ex;
/* QT_FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
- if ( x >= 32768 )
+ if ( x >= 32767 )
x = 32767;
+ /* QT_FT_Span.y is a 16-bit short, so limit our coordinates appropriately */
+ if ( y >= 32767 )
+ y = 32767;
+
if ( coverage )
{
+ QT_FT_Span* span;
+ int count;
+ int skip;
+
+
/* see whether we can add this span to the current list */
- span = ras.gray_spans + ras.num_gray_spans - 1;
- if ( ras.num_gray_spans > 0 &&
+ count = ras.num_gray_spans;
+ span = ras.gray_spans + count - 1;
+ if ( count > 0 &&
span->y == y &&
(int)span->x + span->len == (int)x &&
span->coverage == coverage )
@@ -1218,9 +1280,9 @@
return;
}
- if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS )
+ if ( count >= QT_FT_MAX_GRAY_SPANS )
{
- if ( ras.render_span && ras.num_gray_spans > ras.skip_spans )
+ if ( ras.render_span && count > ras.skip_spans )
{
skip = ras.skip_spans > 0 ? ras.skip_spans : 0;
ras.render_span( ras.num_gray_spans - skip,
@@ -1302,6 +1364,8 @@
if ( ras.num_cells == 0 )
return;
+ QT_FT_TRACE7(( "gray_sweep: start\n" ));
+
for ( yindex = 0; yindex < ras.ycount; yindex++ )
{
PCell cell = ras.ycells[yindex];
@@ -1331,6 +1395,8 @@
gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
ras.count_ex - x );
}
+
+ QT_FT_TRACE7(( "gray_sweep: end\n" ));
}
/*************************************************************************/
@@ -1364,7 +1430,7 @@
/* */
static
int QT_FT_Outline_Decompose( const QT_FT_Outline* outline,
- void* user )
+ void* user )
{
#undef SCALED
#define SCALED( x ) (x)
@@ -1382,6 +1448,9 @@
int error;
char tag; /* current point's state */
+ if ( !outline )
+ return ErrRaster_Invalid_Outline;
+
first = 0;
for ( n = 0; n < outline->n_contours; n++ )
@@ -1390,16 +1459,17 @@
last = outline->contours[n];
+ if ( last < 0 )
+ goto Invalid_Outline;
limit = outline->points + last;
- v_start = outline->points[first];
- v_last = outline->points[last];
-
+ v_start = outline->points[first];
v_start.x = SCALED( v_start.x );
v_start.y = SCALED( v_start.y );
- v_last.x = SCALED( v_last.x );
- v_last.y = SCALED( v_last.y );
+ v_last = outline->points[last];
+ v_last.x = SCALED( v_last.x );
+ v_last.y = SCALED( v_last.y );
v_control = v_start;
@@ -1435,6 +1505,8 @@
tags--;
}
+ QT_FT_TRACE5(( " move to (%.2f, %.2f)\n",
+ v_start.x / 64.0, v_start.y / 64.0 ));
error = gray_move_to( &v_start, user );
if ( error )
goto Exit;
@@ -1455,6 +1527,8 @@
vec.x = SCALED( point->x );
vec.y = SCALED( point->y );
+ QT_FT_TRACE5(( " line to (%.2f, %.2f)\n",
+ vec.x / 64.0, vec.y / 64.0 ));
gray_render_line(user, UPSCALE(vec.x), UPSCALE(vec.y));
continue;
}
@@ -1480,6 +1554,10 @@
if ( tag == QT_FT_CURVE_TAG_ON )
{
+ QT_FT_TRACE5(( " conic to (%.2f, %.2f)"
+ " with control (%.2f, %.2f)\n",
+ vec.x / 64.0, vec.y / 64.0,
+ v_control.x / 64.0, v_control.y / 64.0 ));
gray_render_conic(user, &v_control, &vec);
continue;
}
@@ -1490,11 +1568,20 @@
v_middle.x = ( v_control.x + vec.x ) / 2;
v_middle.y = ( v_control.y + vec.y ) / 2;
+ QT_FT_TRACE5(( " conic to (%.2f, %.2f)"
+ " with control (%.2f, %.2f)\n",
+ v_middle.x / 64.0, v_middle.y / 64.0,
+ v_control.x / 64.0, v_control.y / 64.0 ));
gray_render_conic(user, &v_control, &v_middle);
+
v_control = vec;
goto Do_Conic;
}
+ QT_FT_TRACE5(( " conic to (%.2f, %.2f)"
+ " with control (%.2f, %.2f)\n",
+ v_start.x / 64.0, v_start.y / 64.0,
+ v_control.x / 64.0, v_control.y / 64.0 ));
gray_render_conic(user, &v_control, &v_start);
goto Close;
}
@@ -1525,10 +1612,20 @@
vec.x = SCALED( point->x );
vec.y = SCALED( point->y );
+ QT_FT_TRACE5(( " cubic to (%.2f, %.2f)"
+ " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
+ vec.x / 64.0, vec.y / 64.0,
+ vec1.x / 64.0, vec1.y / 64.0,
+ vec2.x / 64.0, vec2.y / 64.0 ));
gray_render_cubic(user, &vec1, &vec2, &vec);
continue;
}
+ QT_FT_TRACE5(( " cubic to (%.2f, %.2f)"
+ " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
+ v_start.x / 64.0, v_start.y / 64.0,
+ vec1.x / 64.0, vec1.y / 64.0,
+ vec2.x / 64.0, vec2.y / 64.0 ));
gray_render_cubic(user, &vec1, &vec2, &v_start);
goto Close;
}
@@ -1536,15 +1633,19 @@
}
/* close the contour with a line segment */
+ QT_FT_TRACE5(( " line to (%.2f, %.2f)\n",
+ v_start.x / 64.0, v_start.y / 64.0 ));
gray_render_line(user, UPSCALE(v_start.x), UPSCALE(v_start.y));
Close:
first = last + 1;
}
+ QT_FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
return 0;
Exit:
+ QT_FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
return error;
Invalid_Outline:
@@ -1557,7 +1658,6 @@
} TBand;
-
static int
gray_convert_glyph_inner( RAS_ARG )
{
@@ -1566,7 +1666,8 @@
if ( qt_ft_setjmp( ras.jump_buffer ) == 0 )
{
error = QT_FT_Outline_Decompose( &ras.outline, &ras );
- gray_record_cell( RAS_VAR );
+ if ( !ras.invalid )
+ gray_record_cell( RAS_VAR );
}
else
{
@@ -1608,29 +1709,12 @@
ras.count_ex = ras.max_ex - ras.min_ex;
ras.count_ey = ras.max_ey - ras.min_ey;
- /* simple heuristic used to speed-up the bezier decomposition -- see */
- /* the code in gray_render_conic() and gray_render_cubic() for more */
- /* details */
- ras.conic_level = 32;
- ras.cubic_level = 16;
-
- {
- int level = 0;
-
-
- if ( ras.count_ex > 24 || ras.count_ey > 24 )
- level++;
- if ( ras.count_ex > 120 || ras.count_ey > 120 )
- level++;
-
- ras.conic_level <<= level;
- ras.cubic_level <<= level;
- }
-
- /* setup vertical bands */
+ /* set up vertical bands */
num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
- if ( num_bands == 0 ) num_bands = 1;
- if ( num_bands >= 39 ) num_bands = 39;
+ if ( num_bands == 0 )
+ num_bands = 1;
+ if ( num_bands >= 39 )
+ num_bands = 39;
ras.band_shoot = 0;
@@ -1764,11 +1848,14 @@
if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE )
return ErrRaster_OutOfMemory;
+ if ( !outline )
+ return ErrRaster_Invalid_Outline;
+
/* return immediately if the outline is empty */
if ( outline->n_points == 0 || outline->n_contours <= 0 )
return 0;
- if ( !outline || !outline->contours || !outline->points )
+ if ( !outline->contours || !outline->points )
return ErrRaster_Invalid_Outline;
if ( outline->n_points !=
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 22ec981134..1c7d6471b6 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -243,6 +243,18 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd()
Starts a new page. Returns \c true on success.
*/
+/*!
+ \enum QPagedPaintDevice::PdfVersion
+
+ The PdfVersion enum describes the version of the PDF file that
+ is produced by QPrinter or QPdfWriter.
+
+ \value PdfVersion_1_4 A PDF 1.4 compatible document is produced.
+
+ \value PdfVersion_A1b A PDF/A-1b compatible document is produced.
+
+ \since 5.10
+*/
/*!
Sets the size of the a page to \a size.
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index c516f6a963..66dd6fa8cf 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -213,6 +213,8 @@ public:
Envelope10 = Comm10E
};
+ enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b };
+
// ### Qt6 Make these virtual
bool setPageLayout(const QPageLayout &pageLayout);
bool setPageSize(const QPageSize &pageSize);
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index ddea168e72..f42fd4ff87 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -547,8 +547,8 @@ void qt_fill_tile(QPixmap *tile, const QPixmap &pixmap)
}
}
-void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
- const QPixmap &pixmap, qreal xOffset, qreal yOffset)
+Q_GUI_EXPORT void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
+ const QPixmap &pixmap, qreal xOffset, qreal yOffset)
{
qreal yPos, xPos, drawH, drawW, yOff, xOff;
yPos = y;
@@ -929,11 +929,11 @@ QPoint QPaintEngine::coordinateOffset() const
void QPaintEngine::setSystemClip(const QRegion &region)
{
Q_D(QPaintEngine);
- d->systemClip = region;
+ d->baseSystemClip = region;
// Be backward compatible and only call d->systemStateChanged()
// if we currently have a system transform/viewport set.
+ d->updateSystemClip();
if (d->hasSystemTransform || d->hasSystemViewport) {
- d->transformSystemClip();
d->systemStateChanged();
}
}
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index 9d511f9bad..8ac3fcff5c 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -71,6 +71,7 @@ public:
QPaintDevice *pdev;
QPaintEngine *q_ptr;
+ QRegion baseSystemClip;
QRegion systemClip;
QRect systemRect;
QRegion systemViewport;
@@ -79,8 +80,9 @@ public:
uint hasSystemTransform : 1;
uint hasSystemViewport : 1;
- inline void transformSystemClip()
+ inline void updateSystemClip()
{
+ systemClip = baseSystemClip;
if (systemClip.isEmpty())
return;
@@ -104,15 +106,30 @@ public:
inline void setSystemTransform(const QTransform &xform)
{
systemTransform = xform;
- if ((hasSystemTransform = !xform.isIdentity()) || hasSystemViewport)
- transformSystemClip();
- systemStateChanged();
+ hasSystemTransform = !xform.isIdentity();
+ updateSystemClip();
+ if (q_ptr->state)
+ systemStateChanged();
}
inline void setSystemViewport(const QRegion &region)
{
systemViewport = region;
hasSystemViewport = !systemViewport.isEmpty();
+ updateSystemClip();
+ if (q_ptr->state)
+ systemStateChanged();
+ }
+
+ inline void setSystemTransformAndViewport(const QTransform &xform, const QRegion &region)
+ {
+ systemTransform = xform;
+ hasSystemTransform = !xform.isIdentity();
+ systemViewport = region;
+ hasSystemViewport = !systemViewport.isEmpty();
+ updateSystemClip();
+ if (q_ptr->state)
+ systemStateChanged();
}
virtual void systemStateChanged() { }
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index afeb198953..2b892159c5 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -42,16 +42,20 @@
#ifndef QT_NO_PDF
#include "qplatformdefs.h"
-#include <qdebug.h>
-#include <qfile.h>
-#include <qtemporaryfile.h>
+
+#include <private/qfont_p.h>
#include <private/qmath_p.h>
#include <private/qpainter_p.h>
-#include <qnumeric.h>
-#include "private/qfont_p.h"
+
+#include <qbuffer.h>
+#include <qcryptographichash.h>
+#include <qdatetime.h>
+#include <qdebug.h>
+#include <qfile.h>
#include <qimagewriter.h>
-#include "qbuffer.h"
-#include "QtCore/qdatetime.h"
+#include <qnumeric.h>
+#include <qtemporaryfile.h>
+#include <quuid.h>
#ifndef QT_NO_COMPRESS
#include <zlib.h>
@@ -79,6 +83,45 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
return f;
}
+extern bool qt_isExtendedRadialGradient(const QBrush &brush);
+
+// helper function to remove transparency from brush in PDF/A-1b mode
+static void removeTransparencyFromBrush(QBrush &brush)
+{
+ if (brush.style() == Qt::SolidPattern) {
+ QColor color = brush.color();
+ if (color.alpha() != 255) {
+ color.setAlpha(255);
+ brush.setColor(color);
+ }
+
+ return;
+ }
+
+ if (qt_isExtendedRadialGradient(brush)) {
+ brush = QBrush(Qt::black); // the safest we can do so far...
+ return;
+ }
+
+ if (brush.style() == Qt::LinearGradientPattern
+ || brush.style() == Qt::RadialGradientPattern
+ || brush.style() == Qt::ConicalGradientPattern) {
+
+ QGradientStops stops = brush.gradient()->stops();
+ for (int i = 0; i < stops.size(); ++i) {
+ if (stops[i].second.alpha() != 255)
+ stops[i].second.setAlpha(255);
+ }
+
+ const_cast<QGradient*>(brush.gradient())->setStops(stops);
+ return;
+ }
+
+ if (brush.style() == Qt::TexturePattern) {
+ // handled inside QPdfEnginePrivate::addImage() already
+ return;
+ }
+}
/* also adds a space at the end of the number */
@@ -1042,7 +1085,22 @@ void QPdfEngine::updateState(const QPaintEngineState &state)
d->stroker.matrix = state.transform();
if (flags & DirtyPen) {
- d->pen = state.pen();
+ if (d->pdfVersion == QPdfEngine::Version_A1b) {
+ QPen pen = state.pen();
+
+ QColor penColor = pen.color();
+ if (penColor.alpha() != 255)
+ penColor.setAlpha(255);
+ pen.setColor(penColor);
+
+ QBrush penBrush = pen.brush();
+ removeTransparencyFromBrush(penBrush);
+ pen.setBrush(penBrush);
+
+ d->pen = pen;
+ } else {
+ d->pen = state.pen();
+ }
d->hasPen = d->pen.style() != Qt::NoPen;
d->stroker.setPen(d->pen, state.renderHints());
QBrush penBrush = d->pen.brush();
@@ -1054,7 +1112,13 @@ void QPdfEngine::updateState(const QPaintEngineState &state)
d->stroker.setPen(d->pen, state.renderHints());
}
if (flags & DirtyBrush) {
- d->brush = state.brush();
+ if (d->pdfVersion == QPdfEngine::Version_A1b) {
+ QBrush brush = state.brush();
+ removeTransparencyFromBrush(brush);
+ d->brush = brush;
+ } else {
+ d->brush = state.brush();
+ }
if (d->brush.color().alpha() == 0 && d->brush.style() == Qt::SolidPattern)
d->brush.setStyle(Qt::NoBrush);
d->hasBrush = d->brush.style() != Qt::NoBrush;
@@ -1286,6 +1350,12 @@ int QPdfEngine::resolution() const
return d->resolution;
}
+void QPdfEngine::setPdfVersion(PdfVersion version)
+{
+ Q_D(QPdfEngine);
+ d->pdfVersion = version;
+}
+
void QPdfEngine::setPageLayout(const QPageLayout &pageLayout)
{
Q_D(QPdfEngine);
@@ -1364,6 +1434,7 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
QPdfEnginePrivate::QPdfEnginePrivate()
: clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),
+ pdfVersion(QPdfEngine::Version_1_4),
outDevice(0), ownsDevice(false),
embedFonts(true),
grayscale(false),
@@ -1465,16 +1536,38 @@ void QPdfEnginePrivate::writeHeader()
addXrefEntry(0,false);
xprintf("%%PDF-1.4\n");
+ xprintf("%%\303\242\303\243\n");
writeInfo();
+ int metaDataObj = -1;
+ int outputIntentObj = -1;
+ if (pdfVersion == QPdfEngine::Version_A1b) {
+ metaDataObj = writeXmpMetaData();
+ outputIntentObj = writeOutputIntent();
+ }
+
catalog = addXrefEntry(-1);
pageRoot = requestObject();
- xprintf("<<\n"
- "/Type /Catalog\n"
- "/Pages %d 0 R\n"
- ">>\n"
- "endobj\n", pageRoot);
+
+ // catalog
+ {
+ QByteArray catalog;
+ QPdf::ByteStream s(&catalog);
+ s << "<<\n"
+ << "/Type /Catalog\n"
+ << "/Pages " << pageRoot << "0 R\n";
+
+ if (pdfVersion == QPdfEngine::Version_A1b) {
+ s << "/OutputIntents [" << outputIntentObj << "0 R]\n";
+ s << "/Metadata " << metaDataObj << "0 R\n";
+ }
+
+ s << ">>\n"
+ << "endobj\n";
+
+ write(catalog);
+ }
// graphics state
graphicsState = addXrefEntry(-1);
@@ -1527,6 +1620,95 @@ void QPdfEnginePrivate::writeInfo()
"endobj\n");
}
+int QPdfEnginePrivate::writeXmpMetaData()
+{
+ const int metaDataObj = addXrefEntry(-1);
+
+ const QString producer(QString::fromLatin1("Qt " QT_VERSION_STR));
+
+ const QDateTime now = QDateTime::currentDateTime();
+ const QDate date = now.date();
+ const QTime time = now.time();
+
+ QString timeStr;
+ timeStr.sprintf("%d-%02d-%02dT%02d:%02d:%02d", date.year(), date.month(), date.day(),
+ time.hour(), time.minute(), time.second());
+
+ const int offset = now.offsetFromUtc();
+ const int hours = (offset / 60) / 60;
+ const int mins = (offset / 60) % 60;
+ QString tzStr;
+ if (offset < 0)
+ tzStr.sprintf("-%02d:%02d", -hours, -mins);
+ else if (offset > 0)
+ tzStr.sprintf("+%02d:%02d", hours , mins);
+ else
+ tzStr = QLatin1String("Z");
+
+ const QString metaDataDate = timeStr + tzStr;
+
+ QFile metaDataFile(QLatin1String(":/qpdf/qpdfa_metadata.xml"));
+ metaDataFile.open(QIODevice::ReadOnly);
+ const QByteArray metaDataContent = QString::fromUtf8(metaDataFile.readAll()).arg(producer.toHtmlEscaped(),
+ title.toHtmlEscaped(),
+ creator.toHtmlEscaped(),
+ metaDataDate).toUtf8();
+ xprintf("<<\n"
+ "/Type /Metadata /Subtype /XML\n"
+ "/Length %d\n"
+ ">>\n"
+ "stream\n", metaDataContent.size());
+ write(metaDataContent);
+ xprintf("\nendstream\n"
+ "endobj\n");
+
+ return metaDataObj;
+}
+
+int QPdfEnginePrivate::writeOutputIntent()
+{
+ const int colorProfile = addXrefEntry(-1);
+ {
+ QFile colorProfileFile(QLatin1String(":/qpdf/sRGB2014.icc"));
+ colorProfileFile.open(QIODevice::ReadOnly);
+ const QByteArray colorProfileData = colorProfileFile.readAll();
+
+ QByteArray data;
+ QPdf::ByteStream s(&data);
+ int length_object = requestObject();
+
+ s << "<<\n";
+ s << "/N 3\n";
+ s << "/Alternate /DeviceRGB\n";
+ s << "/Length " << length_object << "0 R\n";
+ s << "/Filter /FlateDecode\n";
+ s << ">>\n";
+ s << "stream\n";
+ write(data);
+ const int len = writeCompressed(colorProfileData);
+ write("\nendstream\n"
+ "endobj\n");
+ addXrefEntry(length_object);
+ xprintf("%d\n"
+ "endobj\n", len);
+ }
+
+ const int outputIntent = addXrefEntry(-1);
+ {
+ xprintf("<<\n");
+ xprintf("/Type /OutputIntent\n");
+ xprintf("/S/GTS_PDFA1\n");
+ xprintf("/OutputConditionIdentifier (sRGB_IEC61966-2-1_black_scaled)\n");
+ xprintf("/DestOutputProfile %d 0 R\n", colorProfile);
+ xprintf("/Info(sRGB IEC61966 v2.1 with black scaling)\n");
+ xprintf("/RegistryName(http://www.color.org)\n");
+ xprintf(">>\n");
+ xprintf("endobj\n");
+ }
+
+ return outputIntent;
+}
+
void QPdfEnginePrivate::writePageRoot()
{
addXrefEntry(pageRoot);
@@ -1568,6 +1750,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
int fontstream = requestObject();
int cidfont = requestObject();
int toUnicode = requestObject();
+ int cidset = requestObject();
QFontEngine::Properties properties = font->fontEngine->properties();
QByteArray postscriptName = properties.postscriptName.replace(' ', '_');
@@ -1597,7 +1780,8 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
"/CapHeight " << properties.capHeight.toReal()*scale << "\n"
"/StemV " << properties.lineWidth.toReal()*scale << "\n"
"/FontFile2 " << fontstream << "0 R\n"
- ">> endobj\n";
+ "/CIDSet " << cidset << "0 R\n"
+ ">>\nendobj\n";
write(descriptor);
}
{
@@ -1615,7 +1799,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
"stream\n";
write(header);
int len = writeCompressed(fontData);
- write("endstream\n"
+ write("\nendstream\n"
"endobj\n");
addXrefEntry(length_object);
xprintf("%d\n"
@@ -1642,7 +1826,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
xprintf("<< /Length %d >>\n"
"stream\n", touc.length());
write(touc);
- write("endstream\n"
+ write("\nendstream\n"
"endobj\n");
}
{
@@ -1659,6 +1843,29 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font)
"endobj\n";
write(font);
}
+ {
+ QByteArray cidSetStream(font->nGlyphs() / 8 + 1, 0);
+ int byteCounter = 0;
+ int bitCounter = 0;
+ for (int i = 0; i < font->nGlyphs(); ++i) {
+ cidSetStream.data()[byteCounter] |= (1 << (7 - bitCounter));
+
+ bitCounter++;
+ if (bitCounter == 8) {
+ bitCounter = 0;
+ byteCounter++;
+ }
+ }
+
+ addXrefEntry(cidset);
+ xprintf("<<\n");
+ xprintf("/Length %d\n", cidSetStream.size());
+ xprintf(">>\n");
+ xprintf("stream\n");
+ write(cidSetStream);
+ xprintf("\nendstream\n");
+ xprintf("endobj\n");
+ }
}
@@ -1748,7 +1955,7 @@ void QPdfEnginePrivate::writePage()
xprintf("stream\n");
QIODevice *content = currentPage->stream();
int len = writeCompressed(content);
- xprintf("endstream\n"
+ xprintf("\nendstream\n"
"endobj\n");
addXrefEntry(pageStreamLength);
@@ -1768,15 +1975,28 @@ void QPdfEnginePrivate::writeTail()
for (int i = 1; i < xrefPositions.size()-1; ++i)
xprintf("%010d 00000 n \n", xrefPositions[i]);
- xprintf("trailer\n"
- "<<\n"
- "/Size %d\n"
- "/Info %d 0 R\n"
- "/Root %d 0 R\n"
- ">>\n"
- "startxref\n%d\n"
- "%%%%EOF\n",
- xrefPositions.size()-1, info, catalog, xrefPositions.constLast());
+ {
+ QByteArray trailer;
+ QPdf::ByteStream s(&trailer);
+
+ s << "trailer\n"
+ << "<<\n"
+ << "/Size " << xrefPositions.size() - 1 << "\n"
+ << "/Info " << info << "0 R\n"
+ << "/Root " << catalog << "0 R\n";
+
+ if (pdfVersion == QPdfEngine::Version_A1b) {
+ const QString uniqueId = QUuid::createUuid().toString();
+ const QByteArray fileIdentifier = QCryptographicHash::hash(uniqueId.toLatin1(), QCryptographicHash::Md5).toHex();
+ s << "/ID [ <" << fileIdentifier << "> <" << fileIdentifier << "> ]\n";
+ }
+
+ s << ">>\n"
+ << "startxref\n" << xrefPositions.constLast() << "\n"
+ << "%%EOF\n";
+
+ write(trailer);
+ }
}
int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)
@@ -1794,7 +2014,13 @@ int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)
return object;
}
-void QPdfEnginePrivate::printString(const QString &string) {
+void QPdfEnginePrivate::printString(const QString &string)
+{
+ if (string.isEmpty()) {
+ write("()");
+ return;
+ }
+
// The 'text string' type in PDF is encoded either as PDFDocEncoding, or
// Unicode UTF-16 with a Unicode byte order mark as the first character
// (0xfeff), with the high-order byte first.
@@ -1976,7 +2202,7 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height,
xprintf(">>\nstream\n");
len = writeCompressed(data);
}
- xprintf("endstream\n"
+ xprintf("\nendstream\n"
"endobj\n");
addXrefEntry(lenobj);
xprintf("%d\n"
@@ -2303,7 +2529,7 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QTransform &matrix,
">>\n"
"stream\n"
<< content
- << "endstream\n"
+ << "\nendstream\n"
"endobj\n";
int softMaskFormObject = addXrefEntry(-1);
@@ -2412,7 +2638,7 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
">>\n"
"stream\n"
<< pattern
- << "endstream\n"
+ << "\nendstream\n"
"endobj\n";
int patternObj = addXrefEntry(-1);
@@ -2443,6 +2669,23 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
QImage image = img;
QImage::Format format = image.format();
+
+ if (pdfVersion == QPdfEngine::Version_A1b) {
+ if (image.hasAlphaChannel()) {
+ // transparent images are not allowed in PDF/A-1b, so we convert it to
+ // a format without alpha channel first
+
+ QImage alphaLessImage(image.width(), image.height(), QImage::Format_RGB32);
+ alphaLessImage.fill(Qt::white);
+
+ QPainter p(&alphaLessImage);
+ p.drawImage(0, 0, image);
+
+ image = alphaLessImage;
+ format = image.format();
+ }
+ }
+
if (image.depth() == 1 && *bitmap && is_monochrome(img.colorTable())) {
if (format == QImage::Format_MonoLSB)
image = image.convertToFormat(QImage::Format_Mono);
diff --git a/src/gui/painting/qpdf.qrc b/src/gui/painting/qpdf.qrc
new file mode 100644
index 0000000000..56359c775b
--- /dev/null
+++ b/src/gui/painting/qpdf.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource prefix="qpdf/">
+ <file>qpdfa_metadata.xml</file>
+ <file alias="sRGB2014.icc">../../3rdparty/icc/sRGB2014.icc</file>
+ </qresource>
+</RCC>
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index a6aa2940c8..f5bb4e17a8 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -168,6 +168,12 @@ class Q_GUI_EXPORT QPdfEngine : public QPaintEngine
Q_DECLARE_PRIVATE(QPdfEngine)
friend class QPdfWriter;
public:
+ enum PdfVersion
+ {
+ Version_1_4,
+ Version_A1b
+ };
+
QPdfEngine();
QPdfEngine(QPdfEnginePrivate &d);
~QPdfEngine() {}
@@ -177,6 +183,8 @@ public:
void setResolution(int resolution);
int resolution() const;
+ void setPdfVersion(PdfVersion version);
+
// reimplementations QPaintEngine
bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
bool end() Q_DECL_OVERRIDE;
@@ -258,6 +266,7 @@ public:
bool hasBrush;
bool simplePen;
qreal opacity;
+ QPdfEngine::PdfVersion pdfVersion;
QHash<QFontEngine::FaceId, QFontSubset *> fonts;
@@ -286,6 +295,8 @@ private:
int createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha);
void writeInfo();
+ int writeXmpMetaData();
+ int writeOutputIntent();
void writePageRoot();
void writeFonts();
void embedFont(QFontSubset *font);
diff --git a/src/gui/painting/qpdfa_metadata.xml b/src/gui/painting/qpdfa_metadata.xml
new file mode 100644
index 0000000000..5e5c57f1c6
--- /dev/null
+++ b/src/gui/painting/qpdfa_metadata.xml
@@ -0,0 +1,16 @@
+<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/" rdf:about="">
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">%2</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ </rdf:Description>
+ <rdf:Description xmlns:xmp="http://ns.adobe.com/xap/1.0/" rdf:about="" xmp:CreatorTool="%3" xmp:CreateDate="%4" xmp:ModifyDate="%4"/>
+ <rdf:Description xmlns:pdf="http://ns.adobe.com/pdf/1.3/" rdf:about="" pdf:Producer="%1"/>
+ <rdf:Description xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" rdf:about="" pdfaid:part="1" pdfaid:conformance="B"/>
+ </rdf:RDF>
+</x:xmpmeta>
+<?xpacket end='w'?>
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index edf2950a67..5af465edeb 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -56,6 +56,7 @@ public:
{
engine = new QPdfEngine();
output = 0;
+ pdfVersion = QPdfWriter::PdfVersion_1_4;
}
~QPdfWriterPrivate()
{
@@ -65,6 +66,7 @@ public:
QPdfEngine *engine;
QFile *output;
+ QPdfWriter::PdfVersion pdfVersion;
};
class QPdfPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
@@ -177,6 +179,35 @@ QPdfWriter::~QPdfWriter()
}
/*!
+ \since 5.10
+
+ Sets the PDF version for this writer to \a version.
+
+ If \a version is the same value as currently set then no change will be made.
+*/
+void QPdfWriter::setPdfVersion(PdfVersion version)
+{
+ Q_D(QPdfWriter);
+
+ if (d->pdfVersion == version)
+ return;
+
+ d->pdfVersion = version;
+ d->engine->setPdfVersion(d->pdfVersion == QPdfWriter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b);
+}
+
+/*!
+ \since 5.10
+
+ Returns the PDF version for this writer. The default is \c PdfVersion_1_4.
+*/
+QPdfWriter::PdfVersion QPdfWriter::pdfVersion() const
+{
+ Q_D(const QPdfWriter);
+ return d->pdfVersion;
+}
+
+/*!
Returns the title of the document.
*/
QString QPdfWriter::title() const
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
index 17c73dd480..b260805b2b 100644
--- a/src/gui/painting/qpdfwriter.h
+++ b/src/gui/painting/qpdfwriter.h
@@ -61,6 +61,9 @@ public:
explicit QPdfWriter(QIODevice *device);
~QPdfWriter();
+ void setPdfVersion(PdfVersion version);
+ PdfVersion pdfVersion() const;
+
QString title() const;
void setTitle(const QString &title);
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index b8bbdefa37..e006fad437 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -70,6 +70,13 @@
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
+#ifndef GL_FRAMEBUFFER_SRB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE
+#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -269,7 +276,7 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
}
static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
- QOpenGLTextureBlitter *blitter, const QPoint &offset)
+ QOpenGLTextureBlitter *blitter, const QPoint &offset, bool canUseSrgb)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
@@ -289,7 +296,15 @@ static void blitTextureForWidget(const QPlatformTextureList *textures, int idx,
deviceRect(rectInWindow, window).size(),
QOpenGLTextureBlitter::OriginBottomLeft);
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ const bool srgb = textures->flags(idx).testFlag(QPlatformTextureList::TextureIsSrgb);
+ if (srgb && canUseSrgb)
+ funcs->glEnable(GL_FRAMEBUFFER_SRGB);
+
blitter->blit(textures->textureId(idx), target, source);
+
+ if (srgb && canUseSrgb)
+ funcs->glDisable(GL_FRAMEBUFFER_SRGB);
}
/*!
@@ -334,10 +349,23 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window);
+ bool canUseSrgb = false;
+ // If there are any sRGB textures in the list, check if the destination
+ // framebuffer is sRGB capable.
+ for (int i = 0; i < textures->count(); ++i) {
+ if (textures->flags(i).testFlag(QPlatformTextureList::TextureIsSrgb)) {
+ GLint cap = 0;
+ funcs->glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &cap);
+ if (cap)
+ canUseSrgb = true;
+ break;
+ }
+ }
+
// Textures for renderToTexture widgets.
for (int i = 0; i < textures->count(); ++i) {
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
// Backingstore texture with the normal widgets.
@@ -406,7 +434,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
funcs->glDisable(GL_BLEND);
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index ec56aaa002..d1ce67a65d 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -78,7 +78,8 @@ class Q_GUI_EXPORT QPlatformTextureList : public QObject
Q_DECLARE_PRIVATE(QPlatformTextureList)
public:
enum Flag {
- StacksOnTop = 0x01
+ StacksOnTop = 0x01,
+ TextureIsSrgb = 0x02
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index 064c2aca7f..746200fd9c 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -436,7 +436,7 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
const quint32 *indices, int indexCount, qint32 value)
{
Q_ASSERT(indexCount != 0);
- typedef QVarLengthArray<quint8, 16> ScanLine;
+ typedef QVarLengthArray<quint16, 16> ScanLine;
QVarLengthArray<ScanLine, 128> scans(height);
int first = 0;
for (int i = 1; i < indexCount; ++i) {
@@ -461,16 +461,16 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
for (int y = fromY; y < toY; ++y) {
quint32 c = quint32(x >> 8);
if (c < quint32(width))
- scans[y].append(quint8(c));
+ scans[y].append(quint16(c));
x += dx;
}
}
for (int i = 0; i < height; ++i) {
- quint8 *scanline = scans[i].data();
+ quint16 *scanline = scans[i].data();
int size = scans[i].size();
for (int j = 1; j < size; ++j) {
int k = j;
- quint8 value = scanline[k];
+ quint16 value = scanline[k];
for (; k != 0 && value < scanline[k - 1]; --k)
scanline[k] = scanline[k - 1];
scanline[k] = value;
@@ -478,7 +478,7 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
qint32 *line = bits + i * width;
int j = 0;
for (; j + 1 < size; j += 2) {
- for (quint8 x = scanline[j]; x < scanline[j + 1]; ++x)
+ for (quint16 x = scanline[j]; x < scanline[j + 1]; ++x)
line[x] = value;
}
if (j < size) {
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 92eeaf7919..f5fc562e13 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -136,7 +136,7 @@ QByteArray QFontSubset::widthArray() const
QByteArray width;
QPdf::ByteStream s(&width);
- QFixed scale = QFixed(1000)/emSquare;
+ const qreal scale = 1000.0/emSquare.toInt();
QFixed defWidth = widths[0];
//qDebug("defWidth=%d, scale=%f", defWidth.toInt(), scale.toReal());
@@ -145,7 +145,7 @@ QByteArray QFontSubset::widthArray() const
defWidth = 0;
}
if (defWidth > 0) {
- s << "/DW " << (defWidth*scale).toInt();
+ s << "/DW " << qRound(defWidth.toInt() * scale);
} else {
s << "/W [";
for (int g = 0; g < nGlyphs();) {
@@ -174,11 +174,11 @@ QByteArray QFontSubset::widthArray() const
if (endnonlinear > start) {
s << start << '[';
for (int i = start; i < endnonlinear; ++i)
- s << (widths[i]*scale).toInt();
+ s << qRound(widths[i].toInt() * scale);
s << "]\n";
}
if (startLinear)
- s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << '\n';
+ s << startLinear << g - 1 << qRound(widths[startLinear].toInt() * scale) << '\n';
}
s << "]\n";
}
diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h
index 00dfccc144..e6a196d865 100644
--- a/src/gui/text/qstatictext.h
+++ b/src/gui/text/qstatictext.h
@@ -62,7 +62,7 @@ public:
};
QStaticText();
- QStaticText(const QString &text);
+ explicit QStaticText(const QString &text);
QStaticText(const QStaticText &other);
#ifdef Q_COMPILER_RVALUE_REFS
QStaticText &operator=(QStaticText &&other) Q_DECL_NOTHROW { swap(other); return *this; }
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index f8215f92e9..db0650d154 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -71,7 +71,7 @@
QT_BEGIN_NAMESPACE
-Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n);
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n);
/*!
Returns \c true if the string \a text is likely to be rich text;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index f49e2638f5..89f1328241 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -323,13 +323,9 @@ public:
QFontEngine *fontEngine;
};
-struct Q_AUTOTEST_EXPORT QScriptItem
+struct QScriptItem
{
- inline QScriptItem()
- : position(0),
- num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
- glyph_data_offset(0) {}
- inline QScriptItem(int p, const QScriptAnalysis &a)
+ Q_DECL_CONSTEXPR QScriptItem(int p, QScriptAnalysis a) Q_DECL_NOTHROW
: position(p), analysis(a),
num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
glyph_data_offset(0) {}
@@ -342,11 +338,12 @@ struct Q_AUTOTEST_EXPORT QScriptItem
QFixed leading;
QFixed width;
int glyph_data_offset;
- QFixed height() const { return ascent + descent; }
+ Q_DECL_CONSTEXPR QFixed height() const Q_DECL_NOTHROW { return ascent + descent; }
+private:
+ friend class QVector<QScriptItem>;
+ QScriptItem() {}; // for QVector, don't use
};
-
-
-Q_DECLARE_TYPEINFO(QScriptItem, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QScriptItem, Q_PRIMITIVE_TYPE);
typedef QVector<QScriptItem> QScriptItemArray;
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index da4e21728f..be10efad8d 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -493,7 +493,7 @@ static QString quoteNewline(const QString &s)
QTextHtmlParserNode::QTextHtmlParserNode()
: parent(0), id(Html_unknown),
- cssFloat(QTextFrameFormat::InFlow), hasOwnListStyle(false), hasOwnLineHeightType(false),
+ cssFloat(QTextFrameFormat::InFlow), hasOwnListStyle(false), hasOwnLineHeightType(false), hasLineHeightMultiplier(false),
hasCssListIndent(false), isEmptyParagraph(false), isTextFrame(false), isRootFrame(false),
displayMode(QTextHtmlElement::DisplayInline), hasHref(false),
listStyle(QTextListFormat::ListStyleUndefined), imageWidth(-1), imageHeight(-1), tableBorder(0),
@@ -1216,6 +1216,11 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
else
lineHeightType = QTextBlockFormat::SingleHeight;
+ if (hasLineHeightMultiplier) {
+ qreal lineHeight = blockFormat.lineHeight() / 100.0;
+ blockFormat.setProperty(QTextBlockFormat::LineHeight, lineHeight);
+ }
+
blockFormat.setProperty(QTextBlockFormat::LineHeightType, lineHeightType);
hasOwnLineHeightType = true;
}
@@ -1227,9 +1232,14 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
lineHeightType = QTextBlockFormat::MinimumHeight;
} else {
bool ok;
- QString value = decl.d->values.first().toString();
+ QCss::Value cssValue = decl.d->values.first();
+ QString value = cssValue.toString();
lineHeight = value.toDouble(&ok);
if (ok) {
+ if (!hasOwnLineHeightType && cssValue.type == QCss::Value::Number) {
+ lineHeight *= 100.0;
+ hasLineHeightMultiplier = true;
+ }
lineHeightType = QTextBlockFormat::ProportionalHeight;
} else {
lineHeight = 0.0;
diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h
index 77bfa685c0..73dac38b82 100644
--- a/src/gui/text/qtexthtmlparser_p.h
+++ b/src/gui/text/qtexthtmlparser_p.h
@@ -173,6 +173,7 @@ struct QTextHtmlParserNode {
uint cssFloat : 2;
uint hasOwnListStyle : 1;
uint hasOwnLineHeightType : 1;
+ uint hasLineHeightMultiplier : 1;
uint hasCssListIndent : 1;
uint isEmptyParagraph : 1;
uint isTextFrame : 1;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 023a1b7f52..2848d55fef 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -167,7 +167,7 @@ QRectF QTextInlineObject::rect() const
*/
qreal QTextInlineObject::width() const
{
- return eng->layoutData->items[itm].width.toReal();
+ return eng->layoutData->items.at(itm).width.toReal();
}
/*!
@@ -177,7 +177,7 @@ qreal QTextInlineObject::width() const
*/
qreal QTextInlineObject::ascent() const
{
- return eng->layoutData->items[itm].ascent.toReal();
+ return eng->layoutData->items.at(itm).ascent.toReal();
}
/*!
@@ -187,7 +187,7 @@ qreal QTextInlineObject::ascent() const
*/
qreal QTextInlineObject::descent() const
{
- return eng->layoutData->items[itm].descent.toReal();
+ return eng->layoutData->items.at(itm).descent.toReal();
}
/*!
@@ -198,7 +198,7 @@ qreal QTextInlineObject::descent() const
*/
qreal QTextInlineObject::height() const
{
- return eng->layoutData->items[itm].height().toReal();
+ return eng->layoutData->items.at(itm).height().toReal();
}
/*!
@@ -918,7 +918,7 @@ QRectF QTextLayout::boundingRect() const
QFixed ymin = d->lines.at(0).y;
for (int i = 0; i < d->lines.size(); ++i) {
- const QScriptLine &si = d->lines[i];
+ const QScriptLine &si = d->lines.at(i);
xmin = qMin(xmin, si.x);
ymin = qMin(ymin, si.y);
QFixed lineWidth = si.width < QFIXED_MAX ? qMax(si.width, si.textWidth) : si.textWidth;
@@ -1046,9 +1046,9 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const
QHash<QPair<QFontEngine *, int>, QGlyphRun> glyphRunHash;
for (int i=0; i<d->lines.size(); ++i) {
- if (d->lines[i].from > from + length)
+ if (d->lines.at(i).from > from + length)
break;
- else if (d->lines[i].from + d->lines[i].length >= from) {
+ else if (d->lines.at(i).from + d->lines[i].length >= from) {
QList<QGlyphRun> glyphRuns = QTextLine(i, d).glyphRuns(from, length);
for (int j = 0; j < glyphRuns.size(); j++) {
@@ -1109,7 +1109,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
int lastLine = d->lines.size();
for (int i = 0; i < d->lines.size(); ++i) {
QTextLine l(i, d);
- const QScriptLine &sl = d->lines[i];
+ const QScriptLine &sl = d->lines.at(i);
if (sl.y > clipe) {
lastLine = i;
@@ -1131,7 +1131,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
region.setFillRule(Qt::WindingFill);
for (int line = firstLine; line < lastLine; ++line) {
- const QScriptLine &sl = d->lines[line];
+ const QScriptLine &sl = d->lines.at(line);
QTextLine tl(line, d);
QRectF lineRect(tl.naturalTextRect());
@@ -1296,7 +1296,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
return;
QTextLine l(line, d);
- const QScriptLine &sl = d->lines[line];
+ const QScriptLine &sl = d->lines.at(line);
qreal x = position.x() + l.cursorToX(cursorPosition);
@@ -1409,7 +1409,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
*/
QRectF QTextLine::rect() const
{
- const QScriptLine& sl = eng->lines[index];
+ const QScriptLine& sl = eng->lines.at(index);
return QRectF(sl.x.toReal(), sl.y.toReal(), sl.width.toReal(), sl.height().toReal());
}
@@ -1418,7 +1418,7 @@ QRectF QTextLine::rect() const
*/
QRectF QTextLine::naturalTextRect() const
{
- const QScriptLine& sl = eng->lines[index];
+ const QScriptLine& sl = eng->lines.at(index);
QFixed x = sl.x + eng->alignLine(sl);
QFixed width = sl.textWidth;
@@ -1435,7 +1435,7 @@ QRectF QTextLine::naturalTextRect() const
*/
qreal QTextLine::x() const
{
- return eng->lines[index].x.toReal();
+ return eng->lines.at(index).x.toReal();
}
/*!
@@ -1445,7 +1445,7 @@ qreal QTextLine::x() const
*/
qreal QTextLine::y() const
{
- return eng->lines[index].y.toReal();
+ return eng->lines.at(index).y.toReal();
}
/*!
@@ -1455,7 +1455,7 @@ qreal QTextLine::y() const
*/
qreal QTextLine::width() const
{
- return eng->lines[index].width.toReal();
+ return eng->lines.at(index).width.toReal();
}
@@ -1466,7 +1466,7 @@ qreal QTextLine::width() const
*/
qreal QTextLine::ascent() const
{
- return eng->lines[index].ascent.toReal();
+ return eng->lines.at(index).ascent.toReal();
}
/*!
@@ -1476,7 +1476,7 @@ qreal QTextLine::ascent() const
*/
qreal QTextLine::descent() const
{
- return eng->lines[index].descent.toReal();
+ return eng->lines.at(index).descent.toReal();
}
/*!
@@ -1488,7 +1488,7 @@ qreal QTextLine::descent() const
*/
qreal QTextLine::height() const
{
- return eng->lines[index].height().ceil().toReal();
+ return eng->lines.at(index).height().ceil().toReal();
}
/*!
@@ -1500,7 +1500,7 @@ qreal QTextLine::height() const
*/
qreal QTextLine::leading() const
{
- return eng->lines[index].leading.toReal();
+ return eng->lines.at(index).leading.toReal();
}
/*!
@@ -1535,7 +1535,7 @@ void QTextLine::setLeadingIncluded(bool included)
*/
bool QTextLine::leadingIncluded() const
{
- return eng->lines[index].leadingIncluded;
+ return eng->lines.at(index).leadingIncluded;
}
/*!
@@ -1545,7 +1545,7 @@ bool QTextLine::leadingIncluded() const
*/
qreal QTextLine::naturalTextWidth() const
{
- return eng->lines[index].textWidth.toReal();
+ return eng->lines.at(index).textWidth.toReal();
}
/*!
@@ -1560,7 +1560,7 @@ qreal QTextLine::naturalTextWidth() const
*/
qreal QTextLine::horizontalAdvance() const
{
- return eng->lines[index].textAdvance.toReal();
+ return eng->lines.at(index).textAdvance.toReal();
}
/*!
@@ -1826,7 +1826,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.softHyphenWidth = 0;
if (newItem != item) {
item = newItem;
- const QScriptItem &current = eng->layoutData->items[item];
+ const QScriptItem &current = eng->layoutData->items.at(item);
if (!current.num_glyphs) {
eng->shape(item);
attributes = eng->attributes();
@@ -1844,7 +1844,7 @@ void QTextLine::layout_helper(int maxGlyphs)
QFixed::fromReal(fontEngine->minRightBearing()));
}
}
- const QScriptItem &current = eng->layoutData->items[item];
+ const QScriptItem &current = eng->layoutData->items.at(item);
lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
@@ -2087,7 +2087,7 @@ void QTextLine::setPosition(const QPointF &pos)
*/
QPointF QTextLine::position() const
{
- return QPointF(eng->lines[index].x.toReal(), eng->lines[index].y.toReal());
+ return QPointF(eng->lines.at(index).x.toReal(), eng->lines.at(index).y.toReal());
}
// ### DOC: I have no idea what this means/does.
@@ -2103,7 +2103,7 @@ QPointF QTextLine::position() const
*/
int QTextLine::textStart() const
{
- return eng->lines[index].from;
+ return eng->lines.at(index).from;
}
/*!
@@ -2115,9 +2115,9 @@ int QTextLine::textLength() const
{
if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators
&& eng->block.isValid() && index == eng->lines.count()-1) {
- return eng->lines[index].length - 1;
+ return eng->lines.at(index).length - 1;
}
- return eng->lines[index].length + eng->lines[index].trailingSpaces;
+ return eng->lines.at(index).length + eng->lines.at(index).trailingSpaces;
}
static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r)
@@ -2241,7 +2241,7 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine,
*/
QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
{
- const QScriptLine &line = eng->lines[index];
+ const QScriptLine &line = eng->lines.at(index);
if (line.length == 0)
return QList<QGlyphRun>();
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index fb9dfc9f69..1709012291 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -420,9 +420,9 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
if (buff.size() == 1 && (buff.at(0) == '+' || buff.at(0) == '-'))
return Intermediate;
- bool ok, overflow;
- qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
- if (overflow || !ok)
+ bool ok;
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
+ if (!ok)
return Invalid;
if (entered >= b && entered <= t) {
@@ -447,9 +447,9 @@ void QIntValidator::fixup(QString &input) const
locale().numberOptions())) {
return;
}
- bool ok, overflow;
- qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
- if (ok && !overflow)
+ bool ok;
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok);
+ if (ok)
input = locale().toString(entered);
}
diff --git a/src/gui/vulkan/KHRONOS_LICENSE.txt b/src/gui/vulkan/KHRONOS_LICENSE.txt
new file mode 100644
index 0000000000..7f6672d50e
--- /dev/null
+++ b/src/gui/vulkan/KHRONOS_LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2015-2017 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/src/gui/vulkan/qplatformvulkaninstance.cpp b/src/gui/vulkan/qplatformvulkaninstance.cpp
new file mode 100644
index 0000000000..6201d3ec11
--- /dev/null
+++ b/src/gui/vulkan/qplatformvulkaninstance.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformvulkaninstance.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPlatformVulkanInstance
+ \since 5.10
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief The QPlatformVulkanInstance class provides an abstraction for Vulkan instances.
+
+ The platform Vulkan instance is responsible for loading a Vulkan library,
+ resolving the basic entry points for creating instances, providing support
+ for creating new or adopting existing VkInstances, and abstracting some
+ WSI-specifics like checking if a given queue family can be used to present
+ using a given window.
+
+ \note platform plugins will typically subclass not this class, but rather
+ QBasicVulkanPlatformInstance.
+
+ \note Vulkan instance creation is split into two phases: a new
+ QPlatformVulkanInstance is expected to load the Vulkan library and do basic
+ initialization, after which the supported layers and extensions can be
+ queried. Everything else is deferred into createOrAdoptInstance().
+*/
+
+class QPlatformVulkanInstancePrivate
+{
+public:
+ QPlatformVulkanInstancePrivate() { }
+};
+
+QPlatformVulkanInstance::QPlatformVulkanInstance()
+ : d_ptr(new QPlatformVulkanInstancePrivate)
+{
+}
+
+QPlatformVulkanInstance::~QPlatformVulkanInstance()
+{
+}
+
+void QPlatformVulkanInstance::presentQueued(QWindow *window)
+{
+ Q_UNUSED(window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/vulkan/qplatformvulkaninstance.h b/src/gui/vulkan/qplatformvulkaninstance.h
new file mode 100644
index 0000000000..9470e2d0b4
--- /dev/null
+++ b/src/gui/vulkan/qplatformvulkaninstance.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMVULKANINSTANCE_H
+#define QPLATFORMVULKANINSTANCE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#include <QtGui/qtguiglobal.h>
+
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+
+#include <qvulkaninstance.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformVulkanInstancePrivate;
+
+class Q_GUI_EXPORT QPlatformVulkanInstance
+{
+ Q_DECLARE_PRIVATE(QPlatformVulkanInstance)
+
+public:
+ QPlatformVulkanInstance();
+ virtual ~QPlatformVulkanInstance();
+
+ virtual QVulkanInfoVector<QVulkanLayer> supportedLayers() const = 0;
+ virtual QVulkanInfoVector<QVulkanExtension> supportedExtensions() const = 0;
+ virtual void createOrAdoptInstance() = 0;
+ virtual bool isValid() const = 0;
+ virtual VkResult errorCode() const = 0;
+ virtual VkInstance vkInstance() const = 0;
+ virtual QByteArrayList enabledLayers() const = 0;
+ virtual QByteArrayList enabledExtensions() const = 0;
+ virtual PFN_vkVoidFunction getInstanceProcAddr(const char *name) = 0;
+ virtual bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) = 0;
+ virtual void presentQueued(QWindow *window);
+
+private:
+ QScopedPointer<QPlatformVulkanInstancePrivate> d_ptr;
+ Q_DISABLE_COPY(QPlatformVulkanInstance)
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(vulkan)
+
+#endif // QPLATFORMVULKANINSTANCE_H
diff --git a/src/gui/vulkan/qt_attribution.json b/src/gui/vulkan/qt_attribution.json
new file mode 100644
index 0000000000..3c09e9f498
--- /dev/null
+++ b/src/gui/vulkan/qt_attribution.json
@@ -0,0 +1,17 @@
+[
+ {
+ "Id": "vulkan-xml-spec",
+ "Name": "Vulkan API Registry",
+ "QDocModule": "qtgui",
+ "Description": "Vulkan XML API Registry.",
+ "QtUsage": "Used to dynamically generate the sources for the QVulkan(Device)Functions classes.",
+ "Path": "vk.xml",
+
+ "Homepage": "https://www.khronos.org/",
+ "Version": "1.0.39",
+ "License": "MIT License",
+ "LicenseId": "MIT",
+ "LicenseFile": "KHRONOS_LICENSE.txt",
+ "Copyright": "Copyright (c) 2015-2017 The Khronos Group Inc."
+ }
+]
diff --git a/src/gui/vulkan/qvulkanfunctions.cpp b/src/gui/vulkan/qvulkanfunctions.cpp
new file mode 100644
index 0000000000..c5f9616d20
--- /dev/null
+++ b/src/gui/vulkan/qvulkanfunctions.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qvulkanfunctions_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVulkanFunctions
+ \since 5.10
+ \ingroup painting-3D
+ \inmodule QtGui
+ \wrapper
+
+ \brief The QVulkanFunctions class provides cross-platform access to the
+ instance level core Vulkan 1.0 API.
+
+ Qt and Qt applications do not link to any Vulkan libraries by default.
+ Instead, all functions are resolved dynamically at run time. Each
+ QVulkanInstance provides a QVulkanFunctions object retrievable via
+ QVulkanInstance::functions(). This does not contain device level functions
+ in order to avoid the potential overhead of an internal dispatching.
+ Instead, functions that rely on a device, or a dispatchable child object of
+ a device, are exposed via QVulkanDeviceFunctions and
+ QVulkanInstance::deviceFunctions(). QVulkanFunctions and
+ QVulkanDeviceFunctions together provides access to the full core Vulkan
+ API, excluding any extensions.
+
+ \note QVulkanFunctions instances cannot be constructed directly.
+
+ The typical usage is the following:
+
+ \code
+ void Window::render()
+ {
+ QVulkanInstance *inst = vulkanInstance();
+ QVulkanFunctions *f = inst->functions();
+ ...
+ VkResult err = f->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf);
+ ...
+ }
+ \endcode
+
+ \note Windowing system interface (WSI) specifics and extensions are
+ excluded. This class only covers core Vulkan commands, with the exception
+ of instance creation, destruction, and function resolving, since such
+ functionality is covered by QVulkanInstance itself.
+
+ To access additional functions, applications can use
+ QVulkanInstance::getInstanceProcAddr() and vkGetDeviceProcAddr().
+ Applications can also decide to link to a Vulkan library directly, as
+ platforms with an appropriate loader will typically export function symbols
+ for the core commands. See
+ \l{https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkGetInstanceProcAddr.html}{the
+ man page for vkGetInstanceProcAddr} for more information.
+
+ \sa QVulkanInstance, QVulkanDeviceFunctions, QWindow::setVulkanInstance(), QWindow::setSurfaceType()
+*/
+
+/*!
+ \class QVulkanDeviceFunctions
+ \since 5.10
+ \ingroup painting-3D
+ \inmodule QtGui
+ \wrapper
+
+ \brief The QVulkanDeviceFunctions class provides cross-platform access to
+ the device level core Vulkan 1.0 API.
+
+ Qt and Qt applications do not link to any Vulkan libraries by default.
+ Instead, all functions are resolved dynamically at run time. Each
+ QVulkanInstance provides a QVulkanFunctions object retrievable via
+ QVulkanInstance::functions(). This does not contain device level functions
+ in order to avoid the potential overhead of an internal dispatching.
+ Instead, functions that rely on a device, or a dispatchable child object of
+ a device, are exposed via QVulkanDeviceFunctions and
+ QVulkanInstance::deviceFunctions(). QVulkanFunctions and
+ QVulkanDeviceFunctions together provides access to the full core Vulkan
+ API, excluding any extensions.
+
+ \note QVulkanDeviceFunctions instances cannot be constructed directly.
+
+ The typical usage is the following:
+
+ \code
+ void Window::render()
+ {
+ QVulkanInstance *inst = vulkanInstance();
+ QVulkanDeviceFunctions *df = inst->deviceFunctions(device);
+ VkResult err = df->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf);
+ ...
+ }
+ \endcode
+
+ The QVulkanDeviceFunctions object specific to the provided VkDevice is
+ created when QVulkanInstance::deviceFunctions() is first called with the
+ device in question. The object is then cached internally.
+
+ To access additional functions, applications can use
+ QVulkanInstance::getInstanceProcAddr() and vkGetDeviceProcAddr().
+ Applications can also decide to link to a Vulkan library directly, as many
+ implementations export function symbols for the core commands. See
+ \l{https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkGetInstanceProcAddr.html}{the
+ man page for vkGetInstanceProcAddr} for more information.
+
+ \sa QVulkanInstance, QVulkanFunctions, QWindow::setVulkanInstance(), QWindow::setSurfaceType()
+*/
+
+/*
+ Constructs a new QVulkanFunctions for \a inst.
+ \internal
+ */
+QVulkanFunctions::QVulkanFunctions(QVulkanInstance *inst)
+ : d_ptr(new QVulkanFunctionsPrivate(inst))
+{
+}
+
+/*
+ Destructor.
+ */
+QVulkanFunctions::~QVulkanFunctions()
+{
+}
+
+/*
+ Constructs a new QVulkanDeviceFunctions for \a inst and the given \a device.
+ \internal
+ */
+QVulkanDeviceFunctions::QVulkanDeviceFunctions(QVulkanInstance *inst, VkDevice device)
+ : d_ptr(new QVulkanDeviceFunctionsPrivate(inst, device))
+{
+}
+
+/*
+ Destructor.
+ */
+QVulkanDeviceFunctions::~QVulkanDeviceFunctions()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp
new file mode 100644
index 0000000000..8f364328d6
--- /dev/null
+++ b/src/gui/vulkan/qvulkaninstance.cpp
@@ -0,0 +1,894 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvulkaninstance.h"
+#include <private/qvulkanfunctions_p.h>
+#include <qpa/qplatformvulkaninstance.h>
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <QtGui/private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVulkanInstance
+ \since 5.10
+ \inmodule QtGui
+
+ \brief The QVulkanInstance class represents a native Vulkan instance, enabling
+ Vulkan rendering onto a QSurface.
+
+ \l{https://www.khronos.org/vulkan/}{Vulkan} is a cross-platform, explicit
+ graphics and compute API. This class provides support for loading a Vulkan
+ library and creating an \c instance in a cross-platform manner. For an
+ introduction on Vulkan instances, refer
+ \l{https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#initialization-instances}{to
+ section 3.2 of the specification}.
+
+ \note Platform-specific support for Vulkan instances and windows with
+ Vulkan-capable surfaces is provided by the various platform plugins. Not
+ all of them will support Vulkan, however. When running on such a platform,
+ create() will fail and always return \c false.
+
+ \note Vulkan support may get automatically disabled for a given Qt build due
+ to not having the necessary Vulkan headers available at build time. When
+ this is the case, and the output of \c configure indicates Vulkan support is
+ disabled, the QVulkan* classes will be unavailable.
+
+ \note Some functions changed their signature between the various Vulkan
+ header revisions. When building Qt and only headers with the old,
+ conflicting signatures are present in a system, Vulkan support will get
+ disabled. It is recommended to use headers from Vulkan 1.0.39 or newer.
+
+ \section1 Initialization
+
+ Similarly to QOpenGLContext, any actual Vulkan instance creation happens
+ only when calling create(). This allows using QVulkanInstance as a plain
+ member variable while retaining control over when to perform
+ initialization.
+
+ Querying the supported instance-level layers and extensions is possible by
+ calling supportedLayers() and supportedExtensions(). These ensure the
+ Vulkan library is loaded, and can therefore be called safely before
+ create() as well.
+
+ Instances store per-application Vulkan state and creating a \c VkInstance
+ object initializes the Vulkan library. In practice there will typically be
+ a single instance constructed early on in main(). The object then stays
+ alive until exiting the application.
+
+ Every Vulkan-based QWindow must be associated with a QVulkanInstance by
+ calling QWindow::setVulkanInstance(). Thus a typical application pattern is
+ the following:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ QGuiApplication app(argc, argv);
+
+ QVulkanInstance inst;
+ if (!inst.create())
+ return 1;
+
+ ...
+ window->setVulkanInstance(&inst);
+ window->show();
+
+ return app.exec();
+ }
+ \endcode
+
+ \section1 Configuration
+
+ QVulkanInstance automatically enables the minimum set of extensions it
+ needs on the newly created instance. In practice this means the
+ \c{VK_KHR_*_surface} family of extensions.
+
+ By default Vulkan debug output, for example messages from the validation
+ layers, is routed to qDebug(). This can be disabled by passing the flag
+ \c NoDebugOutputRedirect to setFlags() \e before invoking create().
+
+ To enable additional layers and extensions, provide the list via
+ setLayers() and setExtensions() \e before invoking create(). When a
+ given layer or extension is not reported as available from the instance,
+ the request is ignored. After a successful call to create(), the values
+ returned from functions like layers() and extensions() reflect the actual
+ enabled layers and extensions. When necessary, for example to avoid
+ requesting extensions that conflict and thus would fail the Vulkan instance
+ creation, the list of actually supported layers and extensions can be
+ examined via supportedLayers() and supportedExtensions() before calling
+ create().
+
+ For example, to enable the standard validation layers, one could do the
+ following:
+
+ \code
+ QVulkanInstance inst;
+
+ // Enable validation layer, if supported. Messages go to qDebug by default.
+ inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
+
+ bool ok = inst.create();
+ if (!ok)
+ ... // Vulkan not available
+ if (!inst.layers().contains("VK_LAYER_LUNARG_standard_validation"))
+ ... // validation layer not available
+ \endcode
+
+ Or, alternatively, to make decisions before attempting to create a Vulkan
+ instance:
+
+ \code
+ QVulkanInstance inst;
+
+ if (inst.supportedLayers().contains("VK_LAYER_LUNARG_standard_validation"))
+ ...
+
+ bool ok = inst.create();
+ ...
+ \endcode
+
+ \section1 Adopting an Existing Instance
+
+ By default QVulkanInstance creates a new Vulkan instance. When working with
+ external engines and renderers, this may sometimes not be desirable. When
+ there is a \c VkInstance handle already available, call setVkInstance()
+ before invoking create(). This way no additional instances will get
+ created, and QVulkanInstance will not own the handle.
+
+ \note It is up to the component creating the external instance to ensure
+ the necessary extensions are enabled on it. These are: \c{VK_KHR_surface},
+ the WSI-specific \c{VK_KHR_*_surface} that is appropriate for the platform
+ in question, and \c{VK_EXT_debug_report} in case QVulkanInstance's debug
+ output redirection is desired.
+
+ \section1 Accessing Core Vulkan Commands
+
+ To access the \c VkInstance handle the QVulkanInstance wraps, call
+ vkInstance(). To resolve Vulkan functions, call getInstanceProcAddr(). For
+ core Vulkan commands manual resolving is not necessary as they are provided
+ via the QVulkanFunctions and QVulkanDeviceFunctions objects accessible via
+ functions() and deviceFunctions().
+
+ \note QVulkanFunctions and QVulkanDeviceFunctions are generated from the
+ Vulkan API XML specifications when building the Qt libraries. Therefore no
+ documentation is provided for them. They contain the Vulkan 1.0 functions
+ with the same signatures as described in the
+ \l{https://www.khronos.org/registry/vulkan/specs/1.0/html/}{Vulkan API
+ documentation}.
+
+ \section1 Getting a Native Vulkan Surface for a Window
+
+ The two common windowing system specific operations are getting a surface
+ (a \c{VkSurfaceKHR} handle) for a window, and querying if a given queue
+ family supports presenting to a given surface. To avoid WSI-specific bits
+ in the applications, these are abstracted by QVulkanInstance and the
+ underlying QPA layers.
+
+ To create a Vulkan surface for a window, or retrieve an existing one,
+ call surfaceForWindow(). Most platforms will only create the surface via
+ \c{VK_KHR_*_surface} when first calling surfaceForWindow(), but there may be
+ platform-specific variations in the internal behavior. Once created,
+ subsequent calls to surfaceForWindow() just return the same handle. This
+ fits the structure of typical Vulkan-enabled QWindow subclasses well.
+
+ To query if a given queue family within a physical device can be used to
+ perform presentation to a given surface, call supportsPresent(). This
+ encapsulates both the generic \c vkGetPhysicalDeviceSurfaceSupportKHR and
+ the WSI-specific \c{vkGetPhysicalDevice*PresentationSupportKHR} checks.
+
+ \section1 Troubleshooting
+
+ Besides returning \c false from create() or \c 0 from surfaceForWindow(),
+ critical errors will also get printed to the debug output via qWarning().
+ Additional logging can be requested by enabling debug output for the
+ logging category \c{qt.vulkan}. The actual Vulkan error code from instance
+ creation can be retrieved by calling errorCode() after a failing create().
+
+ In some special cases it may be necessary to override the Vulkan
+ library name. This can be achieved by setting the \c{QT_VULKAN_LIB}
+ environment variable.
+
+ \section1 Example
+
+ The following is the basic outline of creating a Vulkan-capable QWindow:
+
+ \code
+ class VulkanWindow : public QWindow
+ {
+ public:
+ VulkanWindow() {
+ setSurfaceType(VulkanSurface);
+ }
+
+ void exposeEvent(QExposeEvent *) {
+ if (isExposed()) {
+ if (!m_initialized) {
+ m_initialized = true;
+ // initialize device, swapchain, etc.
+ QVulkanInstance *inst = vulkanInstance();
+ QVulkanFunctions *f = inst->functions();
+ uint32_t devCount = 0;
+ f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr);
+ ...
+ // build the first frame
+ render();
+ }
+ }
+ }
+
+ bool event(QEvent *e) {
+ if (e->type == QEvent::UpdateRequest)
+ render();
+ return QWindow::event(e);
+ }
+
+ void render() {
+ ...
+ requestUpdate(); // render continuously
+ }
+
+ private:
+ bool m_initialized = false;
+ };
+
+ int main(int argc, char **argv)
+ {
+ QGuiApplication app(argc, argv);
+
+ QVulkanInstance inst;
+ if (!inst.create()) {
+ qWarning("Vulkan not available");
+ return 1;
+ }
+
+ VulkanWindow window;
+ window.showMaximized();
+
+ return app.exec();
+
+ }
+ \endcode
+
+ \note In addition to expose, a well-behaving window implementation will
+ also have to take care of additional events like resize and
+ QPlatformSurfaceEvent in order to ensure proper management of the
+ swap chain. Additionally, some platforms may require releasing resources
+ when not being exposed anymore.
+
+ \section1 Using C++ Bindings for Vulkan
+
+ Combining Qt's Vulkan enablers with a C++ Vulkan wrapper, for example
+ \l{https://github.com/KhronosGroup/Vulkan-Hpp}{Vulkan-Hpp}, is possible as
+ well. The pre-requisite here is that the C++ layer must be able to adopt
+ native handles (VkInstance, VkSurfaceKHR) in its classes without taking
+ ownership (since the ownership stays with QVulkanInstance and QWindow).
+ Consider also the following:
+
+ \list
+
+ \li Some wrappers require exception support to be enabled. Qt does not use
+ exceptions. To enable exceptions for the application, add \c{CONFIG += exceptions}
+ to the \c{.pro} file.
+
+ \li Some wrappers call Vulkan functions directly, assuming \c{vulkan.h}
+ provides prototypes and the application links to a Vulkan library exporting
+ all necessary symbols. Qt may not directly link to a Vulkan library.
+ Therefore, on some platforms it may be necessary to add
+ \c{LIBS += -lvulkan} or similar in the application's \c{.pro} file.
+
+ \li The headers for the QVulkan classes may include \c{vulkan.h} with
+ \c{VK_NO_PROTOTYPES} enabled. This can cause issues in C++ wrapper headers
+ that rely on the prototypes. Hence in application code it may be
+ necessary to include \c{vulkan.hpp} or similar before any of the QVulkan
+ headers.
+
+ \endlist
+
+ \sa QVulkanFunctions, QSurface::SurfaceType
+*/
+
+/*!
+ \enum QVulkanInstance::Flag
+ \since 5.10
+
+ This enum describes the flags that can be passed to setFlags(). These control
+ the behavior of create().
+
+ \value NoDebugOutputRedirect Disables Vulkan debug output (\c{VK_EXT_debug_report}) redirection to qDebug.
+*/
+
+class QVulkanInstancePrivate
+{
+public:
+ QVulkanInstancePrivate(QVulkanInstance *q)
+ : q_ptr(q),
+ vkInst(VK_NULL_HANDLE),
+ flags(0),
+ errorCode(VK_SUCCESS)
+ { }
+ ~QVulkanInstancePrivate() { reset(); }
+
+ bool ensureVulkan();
+ void reset();
+
+ QVulkanInstance *q_ptr;
+ QScopedPointer<QPlatformVulkanInstance> platformInst;
+ VkInstance vkInst;
+ QVulkanInstance::Flags flags;
+ QByteArrayList layers;
+ QByteArrayList extensions;
+ QVersionNumber apiVersion;
+ VkResult errorCode;
+ QScopedPointer<QVulkanFunctions> funcs;
+ QHash<VkDevice, QVulkanDeviceFunctions *> deviceFuncs;
+};
+
+bool QVulkanInstancePrivate::ensureVulkan()
+{
+ if (!platformInst) {
+ platformInst.reset(QGuiApplicationPrivate::platformIntegration()->createPlatformVulkanInstance(q_ptr));
+ if (!platformInst) {
+ qWarning("QVulkanInstance: Failed to initialize Vulkan");
+ return false;
+ }
+ }
+ return true;
+}
+
+void QVulkanInstancePrivate::reset()
+{
+ qDeleteAll(deviceFuncs);
+ deviceFuncs.clear();
+ funcs.reset();
+ platformInst.reset();
+ vkInst = VK_NULL_HANDLE;
+ errorCode = VK_SUCCESS;
+}
+
+/*!
+ Constructs a new instance.
+
+ \note No Vulkan initialization is performed in the constructor.
+ */
+QVulkanInstance::QVulkanInstance()
+ : d_ptr(new QVulkanInstancePrivate(this))
+{
+}
+
+/*!
+ Destructor.
+
+ \note current() will return \c nullptr once the instance is destroyed.
+ */
+QVulkanInstance::~QVulkanInstance()
+{
+ destroy();
+}
+
+/*!
+ \class QVulkanLayer
+ \brief Represents information about a Vulkan layer.
+ */
+
+/*!
+ \variable QVulkanLayer::name
+ \brief The name of the layer.
+ */
+
+/*!
+ \variable QVulkanLayer::version
+ \brief The version of the layer. This is an integer, increasing with each backward
+ compatible change.
+ */
+
+/*!
+ \variable QVulkanLayer::specVersion
+ \brief The Vulkan version the layer was written against.
+ */
+
+/*!
+ \variable QVulkanLayer::description
+ \brief The description of the layer.
+ */
+
+/*!
+ \fn bool operator==(const QVulkanLayer &lhs, const QVulkanLayer &rhs)
+ \since 5.10
+ \relates QVulkanLayer
+
+ Returns \c true if Vulkan layers \a lhs and \a rhs have
+ the same name, version, and spec version.
+*/
+
+/*!
+ \fn bool operator!=(const QVulkanLayer &lhs, const QVulkanLayer &rhs)
+ \since 5.10
+ \relates QVulkanLayer
+
+ Returns \c true if Vulkan layers \a lhs and \a rhs have
+ different name, version, or spec version.
+*/
+
+/*!
+ \fn uint qHash(const QVulkanLayer &key, uint seed)
+ \since 5.10
+ \relates QVulkanLayer
+
+ Returns the hash value for the \a key, using \a seed to seed the
+ calculation.
+*/
+
+/*!
+ \class QVulkanExtension
+ \brief Represents information about a Vulkan extension.
+ */
+
+/*!
+ \variable QVulkanExtension::name
+ \brief The name of the extension.
+ */
+
+/*!
+ \variable QVulkanExtension::version
+ \brief The version of the extension. This is an integer, increasing with each backward
+ compatible change.
+ */
+
+/*!
+ \fn bool operator==(const QVulkanExtension &lhs, const QVulkanExtension &rhs)
+ \since 5.10
+ \relates QVulkanExtension
+
+ Returns \c true if Vulkan extensions \a lhs and \a rhs are have the
+ same name and version.
+*/
+
+/*!
+ \fn bool operator!=(const QVulkanExtension &lhs, const QVulkanExtension &rhs)
+ \since 5.10
+ \relates QVulkanExtension
+
+ Returns \c true if Vulkan extensions \a lhs and \a rhs are have different
+ name or version.
+*/
+
+/*!
+ \fn uint qHash(const QVulkanExtension &key, uint seed)
+ \since 5.10
+ \relates QVulkanExtension
+
+ Returns the hash value for the \a key, using \a seed to seed the
+ calculation.
+*/
+
+/*!
+ \class QVulkanInfoVector
+ \brief A specialized QVector for QVulkanLayer and QVulkanExtension.
+ */
+
+/*!
+ \fn bool QVulkanInfoVector::contains(const QByteArray &name) const
+
+ \return true if the vector contains a layer or extension with the given \a name.
+ */
+
+/*!
+ \fn bool QVulkanInfoVector::contains(const QByteArray &name, int minVersion) const
+
+ \return true if the vector contains a layer or extension with the given
+ \a name and a version same as or newer than \a minVersion.
+ */
+
+/*!
+ \return the list of supported instance-level layers.
+
+ \note This function can be called before create().
+ */
+QVulkanInfoVector<QVulkanLayer> QVulkanInstance::supportedLayers()
+{
+ return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedLayers() : QVulkanInfoVector<QVulkanLayer>();
+}
+
+/*!
+ \return the list of supported instance-level extensions.
+
+ \note This function can be called before create().
+ */
+QVulkanInfoVector<QVulkanExtension> QVulkanInstance::supportedExtensions()
+{
+ return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedExtensions() : QVulkanInfoVector<QVulkanExtension>();
+}
+
+/*!
+ Makes QVulkanInstance adopt an existing VkInstance handle instead of
+ creating a new one.
+
+ \note \a existingVkInstance must have at least \c{VK_KHR_surface} and the
+ appropriate WSI-specific \c{VK_KHR_*_surface} extensions enabled. To ensure
+ debug output redirection is functional, \c{VK_EXT_debug_report} is needed as
+ well.
+
+ \note This function can only be called before create() and has no effect if
+ called afterwards.
+ */
+void QVulkanInstance::setVkInstance(VkInstance existingVkInstance)
+{
+ if (isValid()) {
+ qWarning("QVulkanInstance already created; setVkInstance() has no effect");
+ return;
+ }
+
+ d_ptr->vkInst = existingVkInstance;
+}
+
+/*!
+ Configures the behavior of create() based on the provided \a flags.
+
+ \note This function can only be called before create() and has no effect if
+ called afterwards.
+ */
+void QVulkanInstance::setFlags(Flags flags)
+{
+ if (isValid()) {
+ qWarning("QVulkanInstance already created; setFlags() has no effect");
+ return;
+ }
+
+ d_ptr->flags = flags;
+}
+
+/*!
+ Specifies the list of instance \a layers to enable. It is safe to specify
+ unsupported layers as well because these get ignored when not supported at
+ run time.
+
+ \note This function can only be called before create() and has no effect if
+ called afterwards.
+ */
+void QVulkanInstance::setLayers(const QByteArrayList &layers)
+{
+ if (isValid()) {
+ qWarning("QVulkanInstance already created; setLayers() has no effect");
+ return;
+ }
+
+ d_ptr->layers = layers;
+}
+
+/*!
+ Specifies the list of additional instance \a extensions to enable. It is
+ safe to specify unsupported extensions as well because these get ignored
+ when not supported at run time. The surface-related extensions required by
+ Qt will always be added automatically, no need to include them in this
+ list.
+
+ \note This function can only be called before create() and has no effect if
+ called afterwards.
+ */
+void QVulkanInstance::setExtensions(const QByteArrayList &extensions)
+{
+ if (isValid()) {
+ qWarning("QVulkanInstance already created; setExtensions() has no effect");
+ return;
+ }
+
+ d_ptr->extensions = extensions;
+}
+
+/*!
+ Specifies the Vulkan API against which the application expects to run.
+
+ By default no \a vulkanVersion is specified, and so no version check is performed
+ during Vulkan instance creation.
+
+ \note This function can only be called before create() and has no effect if
+ called afterwards.
+ */
+void QVulkanInstance::setApiVersion(const QVersionNumber &vulkanVersion)
+{
+ if (isValid()) {
+ qWarning("QVulkanInstance already created; setApiVersion() has no effect");
+ return;
+ }
+
+ d_ptr->apiVersion = vulkanVersion;
+}
+
+/*!
+ Initializes the Vulkan library and creates a new or adopts and existing
+ Vulkan instance.
+
+ \return true if successful, false on error or when Vulkan is not supported.
+
+ When successful, the pointer to this QVulkanInstance is retrievable via the
+ static function current().
+
+ The Vulkan instance and library is available as long as this
+ QVulkanInstance exists, or until destroy() is called.
+ */
+bool QVulkanInstance::create()
+{
+ if (isValid())
+ destroy();
+
+ if (!d_ptr->ensureVulkan())
+ return false;
+
+ d_ptr->platformInst->createOrAdoptInstance();
+
+ if (d_ptr->platformInst->isValid()) {
+ d_ptr->vkInst = d_ptr->platformInst->vkInstance();
+ d_ptr->layers = d_ptr->platformInst->enabledLayers();
+ d_ptr->extensions = d_ptr->platformInst->enabledExtensions();
+ d_ptr->errorCode = VK_SUCCESS;
+ d_ptr->funcs.reset(new QVulkanFunctions(this));
+ return true;
+ }
+
+ qWarning("Failed to create platform Vulkan instance");
+ if (d_ptr->platformInst) {
+ d_ptr->errorCode = d_ptr->platformInst->errorCode();
+ d_ptr->platformInst.reset();
+ } else {
+ d_ptr->errorCode = VK_NOT_READY;
+ }
+ return false;
+}
+
+/*!
+ Destroys the underlying platform instance, thus destroying the VkInstance
+ (when owned). The QVulkanInstance object is still reusable by calling
+ create() again.
+ */
+void QVulkanInstance::destroy()
+{
+ d_ptr->reset();
+}
+
+/*!
+ \return true if create() was successful and the instance is valid.
+ */
+bool QVulkanInstance::isValid() const
+{
+ return d_ptr->platformInst && d_ptr->platformInst->isValid();
+}
+
+/*!
+ \return the Vulkan error code after an unsuccessful create(), \c VK_SUCCESS otherwise.
+
+ The value is typically the return value from vkCreateInstance() (when
+ creating a new Vulkan instance instead of adopting an existing one), but
+ may also be \c VK_NOT_READY if the platform plugin does not support Vulkan.
+ */
+VkResult QVulkanInstance::errorCode() const
+{
+ return d_ptr->errorCode;
+}
+
+/*!
+ \return the VkInstance handle this QVulkanInstance wraps, or \c null if
+ create() has not yet been successfully called and no existing instance has
+ been provided via setVkInstance().
+ */
+VkInstance QVulkanInstance::vkInstance() const
+{
+ return d_ptr->vkInst;
+}
+
+/*!
+ \return the requested flags.
+ */
+QVulkanInstance::Flags QVulkanInstance::flags() const
+{
+ return d_ptr->flags;
+}
+
+/*!
+ \return the enabled instance layers, if create() was called and was successful. The
+ requested layers otherwise.
+ */
+QByteArrayList QVulkanInstance::layers() const
+{
+ return d_ptr->layers;
+}
+
+/*!
+ \return the enabled instance extensions, if create() was called and was
+ successful. The requested extensions otherwise.
+ */
+QByteArrayList QVulkanInstance::extensions() const
+{
+ return d_ptr->extensions;
+}
+
+/*!
+ \return the requested Vulkan API version against which the application
+ expects to run, or a null version number if setApiVersion() was not called
+ before create().
+ */
+QVersionNumber QVulkanInstance::apiVersion() const
+{
+ return d_ptr->apiVersion;
+}
+
+/*!
+ Resolves the Vulkan function with the given \a name.
+
+ For core Vulkan commands prefer using the function wrappers retrievable from
+ functions() and deviceFunctions() instead.
+ */
+PFN_vkVoidFunction QVulkanInstance::getInstanceProcAddr(const char *name)
+{
+ // The return value is PFN_vkVoidFunction instead of QFunctionPointer or
+ // similar because on some platforms honoring VKAPI_PTR is important.
+ return d_ptr->platformInst->getInstanceProcAddr(name);
+}
+
+/*!
+ \return the platform Vulkan instance corresponding to this QVulkanInstance.
+
+ \internal
+ */
+QPlatformVulkanInstance *QVulkanInstance::handle() const
+{
+ return d_ptr->platformInst.data();
+}
+
+/*!
+ \return the corresponding QVulkanFunctions object that exposes the core
+ Vulkan command set, excluding device level functions, and is guaranteed to
+ be functional cross-platform.
+
+ \note The returned object is owned and managed by the QVulkanInstance. Do
+ not destroy or alter it.
+
+ \sa deviceFunctions()
+ */
+QVulkanFunctions *QVulkanInstance::functions() const
+{
+ return d_ptr->funcs.data();
+}
+
+/*!
+ \return the QVulkanDeviceFunctions object that exposes the device level
+ core Vulkan command set and is guaranteed to be functional cross-platform.
+
+ \note The Vulkan functions in the returned object must only be called with
+ \a device or a child object (VkQueue, VkCommandBuffer) of \a device as
+ their first parameter. This is because these functions are resolved via
+ \l{https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkGetDeviceProcAddr.html}{vkGetDeviceProcAddr}
+ in order to avoid the potential overhead of internal dispatching.
+
+ \note The returned object is owned and managed by the QVulkanInstance. Do
+ not destroy or alter it.
+
+ \note The object is cached so calling this function with the same \a device
+ again is a cheap operation. However, when the device gets destroyed, it is up
+ to the application to notify the QVulkanInstance by calling
+ resetDeviceFunctions().
+
+ \sa functions(), resetDeviceFunctions()
+ */
+QVulkanDeviceFunctions *QVulkanInstance::deviceFunctions(VkDevice device)
+{
+ QVulkanDeviceFunctions *&f(d_ptr->deviceFuncs[device]);
+ if (!f)
+ f = new QVulkanDeviceFunctions(this, device);
+ return f;
+}
+
+/*!
+ Invalidates and destroys the QVulkanDeviceFunctions object for the given
+ \a device.
+
+ This function must be called when a VkDevice, for which deviceFunctions()
+ was called, gets destroyed while the application intends to continue
+ running, possibly creating a new logical Vulkan device later on.
+
+ There is no need to call this before destroying the QVulkanInstance since
+ clean up is then performed automatically.
+
+ \sa deviceFunctions()
+ */
+void QVulkanInstance::resetDeviceFunctions(VkDevice device)
+{
+ QVulkanDeviceFunctions *&f(d_ptr->deviceFuncs[device]);
+ delete f;
+ f = nullptr;
+}
+
+/*!
+ Creates or retrieves the already existing \c{VkSurfaceKHR} handle for the
+ given \a window.
+
+ \return the Vulkan surface handle or 0 when failed.
+ */
+VkSurfaceKHR QVulkanInstance::surfaceForWindow(QWindow *window)
+{
+ QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface();
+ // VkSurfaceKHR is non-dispatchable and maps to a pointer on x64 and a uint64 on x86.
+ // Therefore a pointer is returned from the platform plugin, not the value itself.
+ void *p = nativeInterface->nativeResourceForWindow(QByteArrayLiteral("vkSurface"), window);
+ return p ? *static_cast<VkSurfaceKHR *>(p) : 0;
+}
+
+/*!
+ \return true if the queue family with \a queueFamilyIndex within the
+ \a physicalDevice supports presenting to \a window.
+
+ Call this function when examining the queues of a given Vulkan device, in
+ order to decide which queue can be used for performing presentation.
+ */
+bool QVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window)
+{
+ return d_ptr->platformInst->supportsPresent(physicalDevice, queueFamilyIndex, window);
+}
+
+/*!
+ This function should be called by the application's renderer after queuing
+ a present operation for \a window.
+
+ While on some platforms this will be a no-op, some may perform windowing
+ system dependent synchronization. For example, on X11 this will update
+ \c{_NET_WM_SYNC_REQUEST_COUNTER}.
+ */
+void QVulkanInstance::presentQueued(QWindow *window)
+{
+ d_ptr->platformInst->presentQueued(window);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QVulkanLayer &layer)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QVulkanLayer(" << layer.name << " " << layer.version
+ << " " << layer.specVersion << " " << layer.description << ")";
+ return dbg;
+}
+
+QDebug operator<<(QDebug dbg, const QVulkanExtension &extension)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QVulkanExtension(" << extension.name << " " << extension.version << ")";
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/vulkan/qvulkaninstance.h b/src/gui/vulkan/qvulkaninstance.h
new file mode 100644
index 0000000000..ada297be43
--- /dev/null
+++ b/src/gui/vulkan/qvulkaninstance.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVULKANINSTANCE_H
+#define QVULKANINSTANCE_H
+
+#include <QtGui/qtguiglobal.h>
+
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+
+#ifndef VK_NO_PROTOTYPES
+#define VK_NO_PROTOTYPES
+#endif
+#ifndef Q_CLANG_QDOC
+#include <vulkan/vulkan.h>
+#else
+typedef void* PFN_vkVoidFunction;
+typedef unsigned long VkSurfaceKHR;
+typedef unsigned long VkImage;
+typedef unsigned long VkImageView;
+#endif
+
+#include <QtCore/qhashfunctions.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qbytearraylist.h>
+#include <QtCore/qversionnumber.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVulkanInstancePrivate;
+class QPlatformVulkanInstance;
+class QVulkanFunctions;
+class QVulkanDeviceFunctions;
+class QWindow;
+
+struct QVulkanLayer
+{
+ QByteArray name;
+ uint32_t version;
+ QVersionNumber specVersion;
+ QByteArray description;
+};
+Q_DECLARE_TYPEINFO(QVulkanLayer, Q_MOVABLE_TYPE);
+
+inline bool operator==(const QVulkanLayer &lhs, const QVulkanLayer &rhs) Q_DECL_NOTHROW
+{
+ return lhs.name == rhs.name && lhs.version == rhs.version && lhs.specVersion == rhs.specVersion;
+}
+inline bool operator!=(const QVulkanLayer &lhs, const QVulkanLayer &rhs) Q_DECL_NOTHROW
+{ return !(lhs == rhs); }
+
+inline uint qHash(const QVulkanLayer &key, uint seed = 0) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.name);
+ seed = hash(seed, key.version);
+ seed = hash(seed, key.specVersion);
+ return seed;
+}
+
+struct QVulkanExtension
+{
+ QByteArray name;
+ uint32_t version;
+};
+Q_DECLARE_TYPEINFO(QVulkanExtension, Q_MOVABLE_TYPE);
+
+inline bool operator==(const QVulkanExtension &lhs, const QVulkanExtension &rhs) Q_DECL_NOTHROW
+{
+ return lhs.name == rhs.name && lhs.version == rhs.version;
+}
+inline bool operator!=(const QVulkanExtension &lhs, const QVulkanExtension &rhs) Q_DECL_NOTHROW
+{ return !(lhs == rhs); }
+
+inline uint qHash(const QVulkanExtension &key, uint seed = 0) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.name);
+ seed = hash(seed, key.version);
+ return seed;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QVulkanLayer &);
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QVulkanExtension &);
+#endif
+
+template<typename T>
+class QVulkanInfoVector : public QVector<T>
+{
+public:
+ bool contains(const QByteArray &name) const {
+ return std::any_of(this->cbegin(), this->cend(), [&](const T &entry) {
+ return entry.name == name; });
+ }
+ bool contains(const QByteArray &name, int minVersion) const {
+ return std::any_of(this->cbegin(), this->cend(), [&](const T &entry) {
+ return entry.name == name && entry.version >= minVersion; });
+ }
+};
+
+class Q_GUI_EXPORT QVulkanInstance
+{
+public:
+ QVulkanInstance();
+ ~QVulkanInstance();
+
+ enum Flag {
+ NoDebugOutputRedirect = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ QVulkanInfoVector<QVulkanLayer> supportedLayers();
+ QVulkanInfoVector<QVulkanExtension> supportedExtensions();
+
+ void setVkInstance(VkInstance existingVkInstance);
+
+ void setFlags(Flags flags);
+ void setLayers(const QByteArrayList &layers);
+ void setExtensions(const QByteArrayList &extensions);
+ void setApiVersion(const QVersionNumber &vulkanVersion);
+
+ bool create();
+ void destroy();
+ bool isValid() const;
+ VkResult errorCode() const;
+
+ VkInstance vkInstance() const;
+
+ Flags flags() const;
+ QByteArrayList layers() const;
+ QByteArrayList extensions() const;
+ QVersionNumber apiVersion() const;
+
+ PFN_vkVoidFunction getInstanceProcAddr(const char *name);
+
+ QPlatformVulkanInstance *handle() const;
+
+ QVulkanFunctions *functions() const;
+ QVulkanDeviceFunctions *deviceFunctions(VkDevice device);
+ void resetDeviceFunctions(VkDevice device);
+
+ static VkSurfaceKHR surfaceForWindow(QWindow *window);
+
+ bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window);
+
+ void presentQueued(QWindow *window);
+
+private:
+ QScopedPointer<QVulkanInstancePrivate> d_ptr;
+ Q_DISABLE_COPY(QVulkanInstance)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QVulkanInstance::Flags)
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(vulkan)
+
+#endif // QVULKANINSTANCE_H
diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp
new file mode 100644
index 0000000000..82c157147c
--- /dev/null
+++ b/src/gui/vulkan/qvulkanwindow.cpp
@@ -0,0 +1,2719 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvulkanwindow_p.h"
+#include "qvulkanfunctions.h"
+#include <QLoggingCategory>
+#include <QTimer>
+#include <QThread>
+#include <QCoreApplication>
+#include <qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcVk, "qt.vulkan")
+
+/*!
+ \class QVulkanWindow
+ \inmodule QtGui
+ \since 5.10
+ \brief The QVulkanWindow class is a convenience subclass of QWindow to perform Vulkan rendering.
+
+ QVulkanWindow is a Vulkan-capable QWindow that manages a Vulkan device, a
+ graphics queue, a command pool and buffer, a depth-stencil image and a
+ double-buffered FIFO swapchain, while taking care of correct behavior when it
+ comes to events like resize, special situations like not having a device
+ queue supporting both graphics and presentation, device lost scenarios, and
+ additional functionality like reading the rendered content back. Conceptually
+ it is the counterpart of QOpenGLWindow in the Vulkan world.
+
+ \note QVulkanWindow does not always eliminate the need to implement a fully
+ custom QWindow subclass as it will not necessarily be sufficient in advanced
+ use cases.
+
+ QVulkanWindow can be embedded into QWidget-based user interfaces via
+ QWidget::createWindowContainer(). This approach has a number of limitations,
+ however. Make sure to study the
+ \l{QWidget::createWindowContainer()}{documentation} first.
+
+ A typical application using QVulkanWindow may look like the following:
+
+ \code
+ class VulkanRenderer : public QVulkanWindowRenderer
+ {
+ public:
+ VulkanRenderer(QVulkanWindow *w) : m_window(w) { }
+
+ void initResources() override
+ {
+ m_devFuncs = m_window->vulkanInstance()->deviceFunctions(m_window->device());
+ ...
+ }
+ void initSwapChainResources() override { ... }
+ void releaseSwapChainResources() override { ... }
+ void releaseResources() override { ... }
+
+ void startNextFrame() override
+ {
+ VkCommandBuffer cmdBuf = m_window->currentCommandBuffer();
+ ...
+ m_devFuncs->vkCmdBeginRenderPass(...);
+ ...
+ m_window->frameReady();
+ }
+
+ private:
+ QVulkanWindow *m_window;
+ QVulkanDeviceFunctions *m_devFuncs;
+ };
+
+ class VulkanWindow : public QVulkanWindow
+ {
+ public:
+ QVulkanWindowRenderer *createRenderer() override {
+ return new VulkanRenderer(this);
+ }
+ };
+
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+
+ QVulkanInstance inst;
+ // enable the standard validation layers, when available
+ inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
+ if (!inst.create())
+ qFatal("Failed to create Vulkan instance: %d", inst.errorCode());
+
+ VulkanWindow w;
+ w.setVulkanInstance(&inst);
+ w.showMaximized();
+
+ return app.exec();
+ }
+ \endcode
+
+ As it can be seen in the example, the main patterns in QVulkanWindow usage are:
+
+ \list
+
+ \li The QVulkanInstance is associated via QWindow::setVulkanInstance(). It is
+ then retrievable via QWindow::vulkanInstance() from everywhere, on any
+ thread.
+
+ \li Similarly to QVulkanInstance, device extensions can be queried via
+ supportedDeviceExtensions() before the actual initialization. Requesting an
+ extension to be enabled is done via setDeviceExtensions(). Such calls must be
+ made before the window becomes visible, that is, before calling show() or
+ similar functions. Unsupported extension requests are gracefully ignored.
+
+ \li The renderer is implemented in a QVulkanWindowRenderer subclass, an
+ instance of which is created in the createRenderer() factory function.
+
+ \li The core Vulkan commands are exposed via the QVulkanFunctions object,
+ retrievable by calling QVulkanInstance::functions(). Device level functions
+ are available after creating a VkDevice by calling
+ QVulkanInstance::deviceFunctions().
+
+ \li The building of the draw calls for the next frame happens in
+ QVulkanWindowRenderer::startNextFrame(). The implementation is expected to
+ add commands to the command buffer returned from currentCommandBuffer().
+ Returning from the function does not indicate that the commands are ready for
+ submission. Rather, an explicit call to frameReady() is required. This allows
+ asynchronous generation of commands, possibly on multiple threads. Simple
+ implementations will simply call frameReady() at the end of their
+ QVulkanWindowRenderer::startNextFrame().
+
+ \li The basic Vulkan resources (physical device, graphics queue, a command
+ pool, the window's main command buffer, image formats, etc.) are exposed on
+ the QVulkanWindow via lightweight getter functions. Some of these are for
+ convenience only, and applications are always free to query, create and
+ manage additional resources directly via the Vulkan API.
+
+ \li The renderer lives in the gui/main thread, like the window itself. This
+ thread is then throttled to the presentation rate, similarly to how OpenGL
+ with a swap interval of 1 would behave. However, the renderer implementation
+ is free to utilize multiple threads in any way it sees fit. The accessors
+ like vulkanInstance(), currentCommandBuffer(), etc. can be called from any
+ thread. The submission of the main command buffer, the queueing of present,
+ and the building of the next frame do not start until frameReady() is
+ invoked on the gui/main thread.
+
+ \li When the window is made visible, the content is updated automatically.
+ Further updates can be requested by calling QWindow::requestUpdate(). To
+ render continuously, call requestUpdate() after frameReady().
+
+ \endlist
+
+ For troubleshooting, enable the logging category \c{qt.vulkan}. Critical
+ errors are printed via qWarning() automatically.
+
+ \section1 Coordinate system differences between OpenGL and Vulkan
+
+ There are two notable differences to be aware of: First, with Vulkan Y points
+ down the screen in clip space, while OpenGL uses an upwards pointing Y axis.
+ Second, the standard OpenGL projection matrix assume a near and far plane
+ values of -1 and 1, while Vulkan prefers 0 and 1.
+
+ In order to help applications migrate from OpenGL-based code without having
+ to flip Y coordinates in the vertex data, and to allow using QMatrix4x4
+ functions like QMatrix4x4::perspective() while keeping the Vulkan viewport's
+ minDepth and maxDepth set to 0 and 1, QVulkanWindow provides a correction
+ matrix retrievable by calling clipCorrectionMatrix().
+
+ \section1 Multisampling
+
+ While disabled by default, multisample antialiasing is fully supported by
+ QVulkanWindow. Additional color buffers and resolving into the swapchain's
+ non-multisample buffers are all managed automatically.
+
+ To query the supported sample counts, call supportedSampleCounts(). When the
+ returned set contains 4, 8, ..., passing one of those values to setSampleCount()
+ requests multisample rendering.
+
+ \note unlike QSurfaceFormat::setSamples(), the list of supported sample
+ counts are exposed to the applications in advance and there is no automatic
+ falling back to lower sample counts in setSampleCount(). If the requested value
+ is not supported, a warning is shown and a no multisampling will be used.
+
+ \section1 Reading images back
+
+ When supportsGrab() returns true, QVulkanWindow can perform readbacks from
+ the color buffer into a QImage. grab() is a slow and inefficient operation,
+ so frequent usage should be avoided. It is nonetheless valuable since it
+ allows applications to take screenshots, or tools and tests to process and
+ verify the output of the GPU rendering.
+
+ \section1 sRGB support
+
+ While many applications will be fine with the default behavior of
+ QVulkanWindow when it comes to swapchain image formats,
+ setPreferredColorFormats() allows requesting a pre-defined format. This is
+ useful most notably when working in the sRGB color space. Passing a format
+ like \c{VK_FORMAT_B8G8R8A8_SRGB} results in choosing an sRGB format, when
+ available.
+
+ \section1 Validation layers
+
+ During application development it can be extremely valuable to have the
+ Vulkan validation layers enabled. As shown in the example code above, calling
+ QVulkanInstance::setLayers() on the QVulkanInstance before
+ QVulkanInstance::create() enables validation, assuming the Vulkan driver
+ stack in the system contains the necessary layers.
+
+ \note Be aware of platform-specific differences. On desktop platforms
+ installing the \l{https://www.lunarg.com/vulkan-sdk/}{Vulkan SDK} is
+ typically sufficient. However, Android for example requires deploying
+ additional shared libraries together with the application, and also mandates
+ a different list of validation layer names. See
+ \l{https://developer.android.com/ndk/guides/graphics/validation-layer.html}{the
+ Android Vulkan development pages} for more information.
+
+ \note QVulkanWindow does not expose device layers since this functionality
+ has been deprecated since version 1.0.13 of the Vulkan API.
+
+ \sa QVulkanInstance, QWindow
+ */
+
+/*!
+ \class QVulkanWindowRenderer
+ \inmodule QtGui
+ \since 5.10
+
+ \brief The QVulkanWindowRenderer class is used to implement the
+ application-specific rendering logic for a QVulkanWindow.
+
+ Applications typically subclass both QVulkanWindow and QVulkanWindowRenderer.
+ The former allows handling events, for example, input, while the latter allows
+ implementing the Vulkan resource management and command buffer building that
+ make up the application's rendering.
+
+ In addition to event handling, the QVulkanWindow subclass is responsible for
+ providing an implementation for QVulkanWindow::createRenderer() as well. This
+ is where the window and renderer get connected. A typical implementation will
+ simply create a new instance of a subclass of QVulkanWindowRenderer.
+ */
+
+/*!
+ Constructs a new QVulkanWindow with the given \a parent.
+
+ The surface type is set to QSurface::VulkanSurface.
+ */
+QVulkanWindow::QVulkanWindow(QWindow *parent)
+ : QWindow(*(new QVulkanWindowPrivate), parent)
+{
+ setSurfaceType(QSurface::VulkanSurface);
+}
+
+/*!
+ Destructor.
+*/
+QVulkanWindow::~QVulkanWindow()
+{
+}
+
+QVulkanWindowPrivate::~QVulkanWindowPrivate()
+{
+ // graphics resource cleanup is already done at this point due to
+ // QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed
+
+ delete renderer;
+}
+
+/*!
+ \enum QVulkanWindow::Flag
+
+ This enum describes the flags that can be passed to setFlags().
+
+ \value PersistentResources Ensures no graphics resources are released when
+ the window becomes unexposed. The default behavior is to release
+ everything, and reinitialize later when becoming visible again.
+ */
+
+/*!
+ Configures the behavior based on the provided \a flags.
+
+ \note This function must be called before the window is made visible or at
+ latest in QVulkanWindowRenderer::preInitResources(), and has no effect if
+ called afterwards.
+ */
+void QVulkanWindow::setFlags(Flags flags)
+{
+ Q_D(QVulkanWindow);
+ if (d->status != QVulkanWindowPrivate::StatusUninitialized) {
+ qWarning("QVulkanWindow: Attempted to set flags when already initialized");
+ return;
+ }
+ d->flags = flags;
+}
+
+/*!
+ Return the requested flags.
+ */
+QVulkanWindow::Flags QVulkanWindow::flags() const
+{
+ Q_D(const QVulkanWindow);
+ return d->flags;
+}
+
+/*!
+ Returns the list of properties for the supported physical devices in the system.
+
+ \note This function can be called before making the window visible.
+ */
+QVector<VkPhysicalDeviceProperties> QVulkanWindow::availablePhysicalDevices()
+{
+ Q_D(QVulkanWindow);
+ if (!d->physDevs.isEmpty() && !d->physDevProps.isEmpty())
+ return d->physDevProps;
+
+ QVulkanInstance *inst = vulkanInstance();
+ if (!inst) {
+ qWarning("QVulkanWindow: Attempted to call availablePhysicalDevices() without a QVulkanInstance");
+ return d->physDevProps;
+ }
+
+ QVulkanFunctions *f = inst->functions();
+ uint32_t count = 1;
+ VkResult err = f->vkEnumeratePhysicalDevices(inst->vkInstance(), &count, nullptr);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to get physical device count: %d", err);
+ return d->physDevProps;
+ }
+
+ qCDebug(lcVk, "%d physical devices", count);
+ if (!count)
+ return d->physDevProps;
+
+ QVector<VkPhysicalDevice> devs(count);
+ err = f->vkEnumeratePhysicalDevices(inst->vkInstance(), &count, devs.data());
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to enumerate physical devices: %d", err);
+ return d->physDevProps;
+ }
+
+ d->physDevs = devs;
+ d->physDevProps.resize(count);
+ for (uint32_t i = 0; i < count; ++i) {
+ VkPhysicalDeviceProperties *p = &d->physDevProps[i];
+ f->vkGetPhysicalDeviceProperties(d->physDevs.at(i), p);
+ qCDebug(lcVk, "Physical device [%d]: name '%s' version %d.%d.%d", i, p->deviceName,
+ VK_VERSION_MAJOR(p->driverVersion), VK_VERSION_MINOR(p->driverVersion),
+ VK_VERSION_PATCH(p->driverVersion));
+ }
+
+ return d->physDevProps;
+}
+
+/*!
+ Requests the usage of the physical device with index \a idx. The index
+ corresponds to the list returned from availablePhysicalDevices().
+
+ By default the first physical device is used.
+
+ \note This function must be called before the window is made visible or at
+ latest in QVulkanWindowRenderer::preInitResources(), and has no effect if
+ called afterwards.
+ */
+void QVulkanWindow::setPhysicalDeviceIndex(int idx)
+{
+ Q_D(QVulkanWindow);
+ if (d->status != QVulkanWindowPrivate::StatusUninitialized) {
+ qWarning("QVulkanWindow: Attempted to set physical device when already initialized");
+ return;
+ }
+ const int count = availablePhysicalDevices().count();
+ if (idx < 0 || idx >= count) {
+ qWarning("QVulkanWindow: Invalid physical device index %d (total physical devices: %d)", idx, count);
+ return;
+ }
+ d->physDevIndex = idx;
+}
+
+/*!
+ Returns the list of the extensions that are supported by logical devices
+ created from the physical device selected by setPhysicalDeviceIndex().
+
+ \note This function can be called before making the window visible.
+ */
+QVulkanInfoVector<QVulkanExtension> QVulkanWindow::supportedDeviceExtensions()
+{
+ Q_D(QVulkanWindow);
+
+ availablePhysicalDevices();
+
+ if (d->physDevs.isEmpty()) {
+ qWarning("QVulkanWindow: No physical devices found");
+ return QVulkanInfoVector<QVulkanExtension>();
+ }
+
+ VkPhysicalDevice physDev = d->physDevs.at(d->physDevIndex);
+ if (d->supportedDevExtensions.contains(physDev))
+ return d->supportedDevExtensions.value(physDev);
+
+ QVulkanFunctions *f = vulkanInstance()->functions();
+ uint32_t count = 0;
+ VkResult err = f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &count, nullptr);
+ if (err == VK_SUCCESS) {
+ QVector<VkExtensionProperties> extProps(count);
+ err = f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &count, extProps.data());
+ if (err == VK_SUCCESS) {
+ QVulkanInfoVector<QVulkanExtension> exts;
+ for (const VkExtensionProperties &prop : extProps) {
+ QVulkanExtension ext;
+ ext.name = prop.extensionName;
+ ext.version = prop.specVersion;
+ exts.append(ext);
+ }
+ d->supportedDevExtensions.insert(physDev, exts);
+ qDebug(lcVk) << "Supported device extensions:" << exts;
+ return exts;
+ }
+ }
+
+ qWarning("QVulkanWindow: Failed to query device extension count: %d", err);
+ return QVulkanInfoVector<QVulkanExtension>();
+}
+
+/*!
+ Sets the list of device \a extensions to be enabled.
+
+ Unsupported extensions are ignored.
+
+ The swapchain extension will always be added automatically, no need to
+ include it in this list.
+
+ \note This function must be called before the window is made visible or at
+ latest in QVulkanWindowRenderer::preInitResources(), and has no effect if
+ called afterwards.
+ */
+void QVulkanWindow::setDeviceExtensions(const QByteArrayList &extensions)
+{
+ Q_D(QVulkanWindow);
+ if (d->status != QVulkanWindowPrivate::StatusUninitialized) {
+ qWarning("QVulkanWindow: Attempted to set device extensions when already initialized");
+ return;
+ }
+ d->requestedDevExtensions = extensions;
+}
+
+/*!
+ Sets the preferred \a formats of the swapchain.
+
+ By default no application-preferred format is set. In this case the
+ surface's preferred format will be used or, in absence of that,
+ \c{VK_FORMAT_B8G8R8A8_UNORM}.
+
+ The list in \a formats is ordered. If the first format is not supported,
+ the second will be considered, and so on. When no formats in the list are
+ supported, the behavior is the same as in the default case.
+
+ To query the actual format after initialization, call colorFormat().
+
+ \note This function must be called before the window is made visible or at
+ latest in QVulkanWindowRenderer::preInitResources(), and has no effect if
+ called afterwards.
+
+ \note Reimplementing QVulkanWindowRenderer::preInitResources() allows
+ dynamically examining the list of supported formats, should that be
+ desired. There the surface is retrievable via
+ QVulkanInstace::surfaceForWindow(), while this function can still safely be
+ called to affect the later stages of initialization.
+
+ \sa colorFormat()
+ */
+void QVulkanWindow::setPreferredColorFormats(const QVector<VkFormat> &formats)
+{
+ Q_D(QVulkanWindow);
+ if (d->status != QVulkanWindowPrivate::StatusUninitialized) {
+ qWarning("QVulkanWindow: Attempted to set preferred color format when already initialized");
+ return;
+ }
+ d->requestedColorFormats = formats;
+}
+
+static struct {
+ VkSampleCountFlagBits mask;
+ int count;
+} qvk_sampleCounts[] = {
+ { VK_SAMPLE_COUNT_1_BIT, 1 },
+ { VK_SAMPLE_COUNT_2_BIT, 2 },
+ { VK_SAMPLE_COUNT_4_BIT, 4 },
+ { VK_SAMPLE_COUNT_8_BIT, 8 },
+ { VK_SAMPLE_COUNT_16_BIT, 16 },
+ { VK_SAMPLE_COUNT_32_BIT, 32 },
+ { VK_SAMPLE_COUNT_64_BIT, 64 }
+};
+
+/*!
+ Returns the set of supported sample counts when using the physical device
+ selected by setPhysicalDeviceIndex().
+
+ By default QVulkanWindow uses a sample count of 1. By calling setSampleCount()
+ with a different value (2, 4, 8, ...) from the set returned by this
+ function, multisample anti-aliasing can be requested.
+
+ \note This function can be called before making the window visible.
+
+ \sa setSampleCount()
+ */
+QSet<int> QVulkanWindow::supportedSampleCounts()
+{
+ Q_D(const QVulkanWindow);
+ QSet<int> result;
+
+ availablePhysicalDevices();
+
+ if (d->physDevs.isEmpty()) {
+ qWarning("QVulkanWindow: No physical devices found");
+ return result;
+ }
+
+ const VkPhysicalDeviceLimits *limits = &d->physDevProps[d->physDevIndex].limits;
+ VkSampleCountFlags color = limits->framebufferColorSampleCounts;
+ VkSampleCountFlags depth = limits->framebufferDepthSampleCounts;
+ VkSampleCountFlags stencil = limits->framebufferStencilSampleCounts;
+
+ for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
+ if ((color & qvk_sampleCounts[i].mask)
+ && (depth & qvk_sampleCounts[i].mask)
+ && (stencil & qvk_sampleCounts[i].mask))
+ {
+ result.insert(qvk_sampleCounts[i].count);
+ }
+ }
+
+ return result;
+}
+
+/*!
+ Requests multisample antialiasing with the given \a sampleCount. The valid
+ values are 1, 2, 4, 8, ... up until the maximum value supported by the
+ physical device.
+
+ When the sample count is greater than 1, QVulkanWindow will create a
+ multisample color buffer instead of simply targeting the swapchain's
+ images. The rendering in the multisample buffer will get resolved into the
+ non-multisample buffers at the end of each frame.
+
+ To examine the list of supported sample counts, call supportedSampleCounts().
+
+ When setting up the rendering pipeline, call sampleCountFlagBits() to query the
+ active sample count as a \c VkSampleCountFlagBits value.
+
+ \note This function must be called before the window is made visible or at
+ latest in QVulkanWindowRenderer::preInitResources(), and has no effect if
+ called afterwards.
+
+ \sa supportedSampleCounts(), sampleCountFlagBits()
+ */
+void QVulkanWindow::setSampleCount(int sampleCount)
+{
+ Q_D(QVulkanWindow);
+ if (d->status != QVulkanWindowPrivate::StatusUninitialized) {
+ qWarning("QVulkanWindow: Attempted to set sample count when already initialized");
+ return;
+ }
+
+ // Stay compatible with QSurfaceFormat and friends where samples == 0 means the same as 1.
+ sampleCount = qBound(1, sampleCount, 64);
+
+ if (!supportedSampleCounts().contains(sampleCount)) {
+ qWarning("QVulkanWindow: Attempted to set unsupported sample count %d", sampleCount);
+ return;
+ }
+
+ for (size_t i = 0; i < sizeof(qvk_sampleCounts) / sizeof(qvk_sampleCounts[0]); ++i) {
+ if (qvk_sampleCounts[i].count == sampleCount) {
+ d->sampleCount = qvk_sampleCounts[i].mask;
+ return;
+ }
+ }
+
+ Q_UNREACHABLE();
+}
+
+void QVulkanWindowPrivate::init()
+{
+ Q_Q(QVulkanWindow);
+ Q_ASSERT(status == StatusUninitialized);
+
+ qCDebug(lcVk, "QVulkanWindow init");
+
+ inst = q->vulkanInstance();
+ if (!inst) {
+ qWarning("QVulkanWindow: Attempted to initialize without a QVulkanInstance");
+ // This is a simple user error, recheck on the next expose instead of
+ // going into the permanent failure state.
+ status = StatusFailRetry;
+ return;
+ }
+
+ if (!renderer)
+ renderer = q->createRenderer();
+
+ surface = QVulkanInstance::surfaceForWindow(q);
+ if (surface == VK_NULL_HANDLE) {
+ qWarning("QVulkanWindow: Failed to retrieve Vulkan surface for window");
+ status = StatusFailRetry;
+ return;
+ }
+
+ q->availablePhysicalDevices();
+
+ if (physDevs.isEmpty()) {
+ qWarning("QVulkanWindow: No physical devices found");
+ status = StatusFail;
+ return;
+ }
+
+ if (physDevIndex < 0 || physDevIndex >= physDevs.count()) {
+ qWarning("QVulkanWindow: Invalid physical device index; defaulting to 0");
+ physDevIndex = 0;
+ }
+ qCDebug(lcVk, "Using physical device [%d]", physDevIndex);
+
+ // Give a last chance to do decisions based on the physical device and the surface.
+ if (renderer)
+ renderer->preInitResources();
+
+ VkPhysicalDevice physDev = physDevs.at(physDevIndex);
+ QVulkanFunctions *f = inst->functions();
+
+ uint32_t queueCount = 0;
+ f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
+ QVector<VkQueueFamilyProperties> queueFamilyProps(queueCount);
+ f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueFamilyProps.data());
+ gfxQueueFamilyIdx = uint32_t(-1);
+ presQueueFamilyIdx = uint32_t(-1);
+ for (int i = 0; i < queueFamilyProps.count(); ++i) {
+ const bool supportsPresent = inst->supportsPresent(physDev, i, q);
+ qCDebug(lcVk, "queue family %d: flags=0x%x count=%d supportsPresent=%d", i,
+ queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount, supportsPresent);
+ if (gfxQueueFamilyIdx == uint32_t(-1)
+ && (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+ && supportsPresent)
+ gfxQueueFamilyIdx = i;
+ }
+ if (gfxQueueFamilyIdx != uint32_t(-1)) {
+ presQueueFamilyIdx = gfxQueueFamilyIdx;
+ } else {
+ qCDebug(lcVk, "No queue with graphics+present; trying separate queues");
+ for (int i = 0; i < queueFamilyProps.count(); ++i) {
+ if (gfxQueueFamilyIdx == uint32_t(-1) && (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
+ gfxQueueFamilyIdx = i;
+ if (presQueueFamilyIdx == uint32_t(-1) && inst->supportsPresent(physDev, i, q))
+ presQueueFamilyIdx = i;
+ }
+ }
+ if (gfxQueueFamilyIdx == uint32_t(-1)) {
+ qWarning("QVulkanWindow: No graphics queue family found");
+ status = StatusFail;
+ return;
+ }
+ if (presQueueFamilyIdx == uint32_t(-1)) {
+ qWarning("QVulkanWindow: No present queue family found");
+ status = StatusFail;
+ return;
+ }
+#ifdef QT_DEBUG
+ // allow testing the separate present queue case in debug builds on AMD cards
+ if (qEnvironmentVariableIsSet("QT_VK_PRESENT_QUEUE_INDEX"))
+ presQueueFamilyIdx = qEnvironmentVariableIntValue("QT_VK_PRESENT_QUEUE_INDEX");
+#endif
+ qCDebug(lcVk, "Using queue families: graphics = %u present = %u", gfxQueueFamilyIdx, presQueueFamilyIdx);
+
+ VkDeviceQueueCreateInfo queueInfo[2];
+ const float prio[] = { 0 };
+ memset(queueInfo, 0, sizeof(queueInfo));
+ queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queueInfo[0].queueFamilyIndex = gfxQueueFamilyIdx;
+ queueInfo[0].queueCount = 1;
+ queueInfo[0].pQueuePriorities = prio;
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx) {
+ queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queueInfo[1].queueFamilyIndex = presQueueFamilyIdx;
+ queueInfo[1].queueCount = 1;
+ queueInfo[1].pQueuePriorities = prio;
+ }
+
+ // Filter out unsupported extensions in order to keep symmetry
+ // with how QVulkanInstance behaves. Add the swapchain extension.
+ QVector<const char *> devExts;
+ QVulkanInfoVector<QVulkanExtension> supportedExtensions = q->supportedDeviceExtensions();
+ QByteArrayList reqExts = requestedDevExtensions;
+ reqExts.append("VK_KHR_swapchain");
+ for (const QByteArray &ext : reqExts) {
+ if (supportedExtensions.contains(ext))
+ devExts.append(ext.constData());
+ }
+ qCDebug(lcVk) << "Enabling device extensions:" << devExts;
+
+ VkDeviceCreateInfo devInfo;
+ memset(&devInfo, 0, sizeof(devInfo));
+ devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+ devInfo.queueCreateInfoCount = gfxQueueFamilyIdx == presQueueFamilyIdx ? 1 : 2;
+ devInfo.pQueueCreateInfos = queueInfo;
+ devInfo.enabledExtensionCount = devExts.count();
+ devInfo.ppEnabledExtensionNames = devExts.constData();
+
+ // Device layers are not supported by QVulkanWindow since that's an already deprecated
+ // API. However, have a workaround for systems with older API and layers (f.ex. L4T
+ // 24.2 for the Jetson TX1 provides API 1.0.13 and crashes when the validation layer
+ // is enabled for the instance but not the device).
+ uint32_t apiVersion = physDevProps[physDevIndex].apiVersion;
+ if (VK_VERSION_MAJOR(apiVersion) == 1
+ && VK_VERSION_MINOR(apiVersion) == 0
+ && VK_VERSION_PATCH(apiVersion) <= 13)
+ {
+ // Make standard validation work at least.
+ const QByteArray stdValName = QByteArrayLiteral("VK_LAYER_LUNARG_standard_validation");
+ const char *stdValNamePtr = stdValName.constData();
+ if (inst->layers().contains(stdValName)) {
+ uint32_t count = 0;
+ VkResult err = f->vkEnumerateDeviceLayerProperties(physDev, &count, nullptr);
+ if (err == VK_SUCCESS) {
+ QVector<VkLayerProperties> layerProps(count);
+ err = f->vkEnumerateDeviceLayerProperties(physDev, &count, layerProps.data());
+ if (err == VK_SUCCESS) {
+ for (const VkLayerProperties &prop : layerProps) {
+ if (!strncmp(prop.layerName, stdValNamePtr, stdValName.count())) {
+ devInfo.enabledLayerCount = 1;
+ devInfo.ppEnabledLayerNames = &stdValNamePtr;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ VkResult err = f->vkCreateDevice(physDev, &devInfo, nullptr, &dev);
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("QVulkanWindow: Physical device lost");
+ if (renderer)
+ renderer->physicalDeviceLost();
+ // clear the caches so the list of physical devices is re-queried
+ physDevs.clear();
+ physDevProps.clear();
+ status = StatusUninitialized;
+ qCDebug(lcVk, "Attempting to restart in 2 seconds");
+ QTimer::singleShot(2000, q, [this]() { ensureStarted(); });
+ return;
+ }
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create device: %d", err);
+ status = StatusFail;
+ return;
+ }
+
+ devFuncs = inst->deviceFunctions(dev);
+ Q_ASSERT(devFuncs);
+
+ devFuncs->vkGetDeviceQueue(dev, gfxQueueFamilyIdx, 0, &gfxQueue);
+ if (gfxQueueFamilyIdx == presQueueFamilyIdx)
+ presQueue = gfxQueue;
+ else
+ devFuncs->vkGetDeviceQueue(dev, presQueueFamilyIdx, 0, &presQueue);
+
+ VkCommandPoolCreateInfo poolInfo;
+ memset(&poolInfo, 0, sizeof(poolInfo));
+ poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ poolInfo.queueFamilyIndex = gfxQueueFamilyIdx;
+ err = devFuncs->vkCreateCommandPool(dev, &poolInfo, nullptr, &cmdPool);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create command pool: %d", err);
+ status = StatusFail;
+ return;
+ }
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx) {
+ poolInfo.queueFamilyIndex = presQueueFamilyIdx;
+ err = devFuncs->vkCreateCommandPool(dev, &poolInfo, nullptr, &presCmdPool);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create command pool for present queue: %d", err);
+ status = StatusFail;
+ return;
+ }
+ }
+
+ hostVisibleMemIndex = 0;
+ VkPhysicalDeviceMemoryProperties physDevMemProps;
+ bool hostVisibleMemIndexSet = false;
+ f->vkGetPhysicalDeviceMemoryProperties(physDev, &physDevMemProps);
+ for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) {
+ const VkMemoryType *memType = physDevMemProps.memoryTypes;
+ qCDebug(lcVk, "memtype %d: flags=0x%x", i, memType[i].propertyFlags);
+ // Find a host visible, host coherent memtype. If there is one that is
+ // cached as well (in addition to being coherent), prefer that.
+ const int hostVisibleAndCoherent = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+ if ((memType[i].propertyFlags & hostVisibleAndCoherent) == hostVisibleAndCoherent) {
+ if (!hostVisibleMemIndexSet
+ || (memType[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)) {
+ hostVisibleMemIndexSet = true;
+ hostVisibleMemIndex = i;
+ }
+ }
+ }
+ qCDebug(lcVk, "Picked memtype %d for host visible memory", hostVisibleMemIndex);
+ deviceLocalMemIndex = 0;
+ for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) {
+ const VkMemoryType *memType = physDevMemProps.memoryTypes;
+ // Just pick the first device local memtype.
+ if (memType[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+ deviceLocalMemIndex = i;
+ break;
+ }
+ }
+ qCDebug(lcVk, "Picked memtype %d for device local memory", deviceLocalMemIndex);
+
+ if (!vkGetPhysicalDeviceSurfaceCapabilitiesKHR || !vkGetPhysicalDeviceSurfaceFormatsKHR) {
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(
+ inst->getInstanceProcAddr("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
+ vkGetPhysicalDeviceSurfaceFormatsKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(
+ inst->getInstanceProcAddr("vkGetPhysicalDeviceSurfaceFormatsKHR"));
+ if (!vkGetPhysicalDeviceSurfaceCapabilitiesKHR || !vkGetPhysicalDeviceSurfaceFormatsKHR) {
+ qWarning("QVulkanWindow: Physical device surface queries not available");
+ status = StatusFail;
+ return;
+ }
+ }
+
+ // Figure out the color format here. Must not wait until recreateSwapChain()
+ // because the renderpass should be available already from initResources (so
+ // that apps do not have to defer pipeline creation to
+ // initSwapChainResources), but the renderpass needs the final color format.
+
+ uint32_t formatCount = 0;
+ vkGetPhysicalDeviceSurfaceFormatsKHR(physDev, surface, &formatCount, nullptr);
+ QVector<VkSurfaceFormatKHR> formats(formatCount);
+ if (formatCount)
+ vkGetPhysicalDeviceSurfaceFormatsKHR(physDev, surface, &formatCount, formats.data());
+
+ colorFormat = VK_FORMAT_B8G8R8A8_UNORM; // our documented default if all else fails
+ colorSpace = VkColorSpaceKHR(0); // this is in fact VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
+
+ // Pick the preferred format, if there is one.
+ if (!formats.isEmpty() && formats[0].format != VK_FORMAT_UNDEFINED) {
+ colorFormat = formats[0].format;
+ colorSpace = formats[0].colorSpace;
+ }
+
+ // Try to honor the user request.
+ if (!formats.isEmpty() && !requestedColorFormats.isEmpty()) {
+ for (VkFormat reqFmt : qAsConst(requestedColorFormats)) {
+ auto r = std::find_if(formats.cbegin(), formats.cend(),
+ [reqFmt](const VkSurfaceFormatKHR &sfmt) { return sfmt.format == reqFmt; });
+ if (r != formats.cend()) {
+ colorFormat = r->format;
+ colorSpace = r->colorSpace;
+ break;
+ }
+ }
+ }
+
+ const VkFormat dsFormatCandidates[] = {
+ VK_FORMAT_D24_UNORM_S8_UINT,
+ VK_FORMAT_D32_SFLOAT_S8_UINT,
+ VK_FORMAT_D16_UNORM_S8_UINT
+ };
+ const int dsFormatCandidateCount = sizeof(dsFormatCandidates) / sizeof(VkFormat);
+ int dsFormatIdx = 0;
+ while (dsFormatIdx < dsFormatCandidateCount) {
+ dsFormat = dsFormatCandidates[dsFormatIdx];
+ VkFormatProperties fmtProp;
+ f->vkGetPhysicalDeviceFormatProperties(physDev, dsFormat, &fmtProp);
+ if (fmtProp.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
+ break;
+ ++dsFormatIdx;
+ }
+ if (dsFormatIdx == dsFormatCandidateCount)
+ qWarning("QVulkanWindow: Failed to find an optimal depth-stencil format");
+
+ qCDebug(lcVk, "Color format: %d Depth-stencil format: %d", colorFormat, dsFormat);
+
+ if (!createDefaultRenderPass())
+ return;
+
+ if (renderer)
+ renderer->initResources();
+
+ status = StatusDeviceReady;
+}
+
+void QVulkanWindowPrivate::reset()
+{
+ if (!dev) // do not rely on 'status', a half done init must be cleaned properly too
+ return;
+
+ qCDebug(lcVk, "QVulkanWindow reset");
+
+ devFuncs->vkDeviceWaitIdle(dev);
+
+ if (renderer) {
+ renderer->releaseResources();
+ devFuncs->vkDeviceWaitIdle(dev);
+ }
+
+ if (defaultRenderPass) {
+ devFuncs->vkDestroyRenderPass(dev, defaultRenderPass, nullptr);
+ defaultRenderPass = VK_NULL_HANDLE;
+ }
+
+ if (cmdPool) {
+ devFuncs->vkDestroyCommandPool(dev, cmdPool, nullptr);
+ cmdPool = VK_NULL_HANDLE;
+ }
+
+ if (presCmdPool) {
+ devFuncs->vkDestroyCommandPool(dev, presCmdPool, nullptr);
+ presCmdPool = VK_NULL_HANDLE;
+ }
+
+ if (frameGrabImage) {
+ devFuncs->vkDestroyImage(dev, frameGrabImage, nullptr);
+ frameGrabImage = VK_NULL_HANDLE;
+ }
+
+ if (frameGrabImageMem) {
+ devFuncs->vkFreeMemory(dev, frameGrabImageMem, nullptr);
+ frameGrabImageMem = VK_NULL_HANDLE;
+ }
+
+ if (dev) {
+ devFuncs->vkDestroyDevice(dev, nullptr);
+ inst->resetDeviceFunctions(dev);
+ dev = VK_NULL_HANDLE;
+ vkCreateSwapchainKHR = nullptr; // re-resolve swapchain funcs later on since some come via the device
+ }
+
+ surface = VK_NULL_HANDLE;
+
+ status = StatusUninitialized;
+}
+
+bool QVulkanWindowPrivate::createDefaultRenderPass()
+{
+ VkAttachmentDescription attDesc[3];
+ memset(attDesc, 0, sizeof(attDesc));
+
+ const bool msaa = sampleCount > VK_SAMPLE_COUNT_1_BIT;
+
+ // This is either the non-msaa render target or the resolve target.
+ attDesc[0].format = colorFormat;
+ attDesc[0].samples = VK_SAMPLE_COUNT_1_BIT;
+ attDesc[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // ignored when msaa
+ attDesc[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ attDesc[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attDesc[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ attDesc[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+ attDesc[1].format = dsFormat;
+ attDesc[1].samples = sampleCount;
+ attDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attDesc[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attDesc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ attDesc[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ if (msaa) {
+ // msaa render target
+ attDesc[2].format = colorFormat;
+ attDesc[2].samples = sampleCount;
+ attDesc[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attDesc[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ attDesc[2].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ }
+
+ VkAttachmentReference colorRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+ VkAttachmentReference resolveRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+ VkAttachmentReference dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
+
+ VkSubpassDescription subPassDesc;
+ memset(&subPassDesc, 0, sizeof(subPassDesc));
+ subPassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subPassDesc.colorAttachmentCount = 1;
+ subPassDesc.pColorAttachments = &colorRef;
+ subPassDesc.pDepthStencilAttachment = &dsRef;
+
+ VkRenderPassCreateInfo rpInfo;
+ memset(&rpInfo, 0, sizeof(rpInfo));
+ rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ rpInfo.attachmentCount = 2;
+ rpInfo.pAttachments = attDesc;
+ rpInfo.subpassCount = 1;
+ rpInfo.pSubpasses = &subPassDesc;
+
+ if (msaa) {
+ colorRef.attachment = 2;
+ subPassDesc.pResolveAttachments = &resolveRef;
+ rpInfo.attachmentCount = 3;
+ }
+
+ VkResult err = devFuncs->vkCreateRenderPass(dev, &rpInfo, nullptr, &defaultRenderPass);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create renderpass: %d", err);
+ return false;
+ }
+
+ return true;
+}
+
+void QVulkanWindowPrivate::recreateSwapChain()
+{
+ Q_Q(QVulkanWindow);
+ Q_ASSERT(status >= StatusDeviceReady);
+
+ swapChainImageSize = q->size() * q->devicePixelRatio(); // note: may change below due to surfaceCaps
+
+ if (swapChainImageSize.isEmpty()) // handle null window size gracefully
+ return;
+
+ QVulkanInstance *inst = q->vulkanInstance();
+ QVulkanFunctions *f = inst->functions();
+ devFuncs->vkDeviceWaitIdle(dev);
+
+ if (!vkCreateSwapchainKHR) {
+ vkCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(f->vkGetDeviceProcAddr(dev, "vkCreateSwapchainKHR"));
+ vkDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(f->vkGetDeviceProcAddr(dev, "vkDestroySwapchainKHR"));
+ vkGetSwapchainImagesKHR = reinterpret_cast<PFN_vkGetSwapchainImagesKHR>(f->vkGetDeviceProcAddr(dev, "vkGetSwapchainImagesKHR"));
+ vkAcquireNextImageKHR = reinterpret_cast<PFN_vkAcquireNextImageKHR>(f->vkGetDeviceProcAddr(dev, "vkAcquireNextImageKHR"));
+ vkQueuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(f->vkGetDeviceProcAddr(dev, "vkQueuePresentKHR"));
+ }
+
+ VkPhysicalDevice physDev = physDevs.at(physDevIndex);
+ VkSurfaceCapabilitiesKHR surfaceCaps;
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDev, surface, &surfaceCaps);
+ uint32_t reqBufferCount = swapChainBufferCount;
+ if (surfaceCaps.maxImageCount)
+ reqBufferCount = qBound(surfaceCaps.minImageCount, reqBufferCount, surfaceCaps.maxImageCount);
+
+ VkExtent2D bufferSize = surfaceCaps.currentExtent;
+ if (bufferSize.width == uint32_t(-1)) {
+ Q_ASSERT(bufferSize.height == uint32_t(-1));
+ bufferSize.width = swapChainImageSize.width();
+ bufferSize.height = swapChainImageSize.height();
+ } else {
+ swapChainImageSize = QSize(bufferSize.width, bufferSize.height);
+ }
+
+ VkSurfaceTransformFlagBitsKHR preTransform =
+ (surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
+ ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
+ : surfaceCaps.currentTransform;
+
+ VkCompositeAlphaFlagBitsKHR compositeAlpha =
+ (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
+ ? VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
+ : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+
+ if (q->requestedFormat().hasAlpha()) {
+ if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
+ compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
+ else if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
+ compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
+ }
+
+ VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ swapChainSupportsReadBack = (surfaceCaps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+ if (swapChainSupportsReadBack)
+ usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+
+ VkSwapchainKHR oldSwapChain = swapChain;
+ VkSwapchainCreateInfoKHR swapChainInfo;
+ memset(&swapChainInfo, 0, sizeof(swapChainInfo));
+ swapChainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ swapChainInfo.surface = surface;
+ swapChainInfo.minImageCount = reqBufferCount;
+ swapChainInfo.imageFormat = colorFormat;
+ swapChainInfo.imageColorSpace = colorSpace;
+ swapChainInfo.imageExtent = bufferSize;
+ swapChainInfo.imageArrayLayers = 1;
+ swapChainInfo.imageUsage = usage;
+ swapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ swapChainInfo.preTransform = preTransform;
+ swapChainInfo.compositeAlpha = compositeAlpha;
+ swapChainInfo.presentMode = presentMode;
+ swapChainInfo.clipped = true;
+ swapChainInfo.oldSwapchain = oldSwapChain;
+
+ qCDebug(lcVk, "Creating new swap chain of %d buffers, size %dx%d", reqBufferCount, bufferSize.width, bufferSize.height);
+
+ VkSwapchainKHR newSwapChain;
+ VkResult err = vkCreateSwapchainKHR(dev, &swapChainInfo, nullptr, &newSwapChain);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create swap chain: %d", err);
+ return;
+ }
+
+ if (oldSwapChain)
+ releaseSwapChain();
+
+ swapChain = newSwapChain;
+
+ uint32_t actualSwapChainBufferCount = 0;
+ err = vkGetSwapchainImagesKHR(dev, swapChain, &actualSwapChainBufferCount, nullptr);
+ if (err != VK_SUCCESS || actualSwapChainBufferCount < 2) {
+ qWarning("QVulkanWindow: Failed to get swapchain images: %d (count=%d)", err, actualSwapChainBufferCount);
+ return;
+ }
+
+ qCDebug(lcVk, "Actual swap chain buffer count: %d (supportsReadback=%d)",
+ actualSwapChainBufferCount, swapChainSupportsReadBack);
+ if (actualSwapChainBufferCount > MAX_SWAPCHAIN_BUFFER_COUNT) {
+ qWarning("QVulkanWindow: Too many swapchain buffers (%d)", actualSwapChainBufferCount);
+ return;
+ }
+ swapChainBufferCount = actualSwapChainBufferCount;
+
+ VkImage swapChainImages[MAX_SWAPCHAIN_BUFFER_COUNT];
+ err = vkGetSwapchainImagesKHR(dev, swapChain, &actualSwapChainBufferCount, swapChainImages);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to get swapchain images: %d", err);
+ return;
+ }
+
+ if (!createTransientImage(dsFormat,
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+ VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
+ &dsImage,
+ &dsMem,
+ &dsView,
+ 1))
+ {
+ return;
+ }
+
+ const bool msaa = sampleCount > VK_SAMPLE_COUNT_1_BIT;
+ VkImage msaaImages[MAX_SWAPCHAIN_BUFFER_COUNT];
+ VkImageView msaaViews[MAX_SWAPCHAIN_BUFFER_COUNT];
+
+ if (msaa) {
+ if (!createTransientImage(colorFormat,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ msaaImages,
+ &msaaImageMem,
+ msaaViews,
+ swapChainBufferCount))
+ {
+ return;
+ }
+ }
+
+ VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
+
+ for (int i = 0; i < swapChainBufferCount; ++i) {
+ ImageResources &image(imageRes[i]);
+ image.image = swapChainImages[i];
+
+ if (msaa) {
+ image.msaaImage = msaaImages[i];
+ image.msaaImageView = msaaViews[i];
+ }
+
+ VkImageViewCreateInfo imgViewInfo;
+ memset(&imgViewInfo, 0, sizeof(imgViewInfo));
+ imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ imgViewInfo.image = swapChainImages[i];
+ imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ imgViewInfo.format = colorFormat;
+ imgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
+ imgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
+ imgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
+ imgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
+ imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ imgViewInfo.subresourceRange.levelCount = imgViewInfo.subresourceRange.layerCount = 1;
+ err = devFuncs->vkCreateImageView(dev, &imgViewInfo, nullptr, &image.imageView);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create swapchain image view %d: %d", i, err);
+ return;
+ }
+
+ err = devFuncs->vkCreateFence(dev, &fenceInfo, nullptr, &image.cmdFence);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create command buffer fence: %d", err);
+ return;
+ }
+ image.cmdFenceWaitable = true; // fence was created in signaled state
+
+ VkImageView views[3] = { image.imageView,
+ dsView,
+ msaa ? image.msaaImageView : VK_NULL_HANDLE };
+ VkFramebufferCreateInfo fbInfo;
+ memset(&fbInfo, 0, sizeof(fbInfo));
+ fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ fbInfo.renderPass = defaultRenderPass;
+ fbInfo.attachmentCount = msaa ? 3 : 2;
+ fbInfo.pAttachments = views;
+ fbInfo.width = swapChainImageSize.width();
+ fbInfo.height = swapChainImageSize.height();
+ fbInfo.layers = 1;
+ VkResult err = devFuncs->vkCreateFramebuffer(dev, &fbInfo, nullptr, &image.fb);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create framebuffer: %d", err);
+ return;
+ }
+
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx) {
+ // pre-build the static image-acquire-on-present-queue command buffer
+ VkCommandBufferAllocateInfo cmdBufInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, presCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 };
+ err = devFuncs->vkAllocateCommandBuffers(dev, &cmdBufInfo, &image.presTransCmdBuf);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to allocate acquire-on-present-queue command buffer: %d", err);
+ return;
+ }
+ VkCommandBufferBeginInfo cmdBufBeginInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
+ VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr };
+ err = devFuncs->vkBeginCommandBuffer(image.presTransCmdBuf, &cmdBufBeginInfo);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to begin acquire-on-present-queue command buffer: %d", err);
+ return;
+ }
+ VkImageMemoryBarrier presTrans;
+ memset(&presTrans, 0, sizeof(presTrans));
+ presTrans.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ presTrans.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ presTrans.oldLayout = presTrans.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ presTrans.srcQueueFamilyIndex = gfxQueueFamilyIdx;
+ presTrans.dstQueueFamilyIndex = presQueueFamilyIdx;
+ presTrans.image = image.image;
+ presTrans.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ presTrans.subresourceRange.levelCount = presTrans.subresourceRange.layerCount = 1;
+ devFuncs->vkCmdPipelineBarrier(image.presTransCmdBuf,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ 0, 0, nullptr, 0, nullptr,
+ 1, &presTrans);
+ err = devFuncs->vkEndCommandBuffer(image.presTransCmdBuf);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to end acquire-on-present-queue command buffer: %d", err);
+ return;
+ }
+ }
+ }
+
+ currentImage = 0;
+
+ VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
+ for (int i = 0; i < frameLag; ++i) {
+ FrameResources &frame(frameRes[i]);
+
+ frame.imageAcquired = false;
+ frame.imageSemWaitable = false;
+
+ devFuncs->vkCreateFence(dev, &fenceInfo, nullptr, &frame.fence);
+ frame.fenceWaitable = true; // fence was created in signaled state
+
+ devFuncs->vkCreateSemaphore(dev, &semInfo, nullptr, &frame.imageSem);
+ devFuncs->vkCreateSemaphore(dev, &semInfo, nullptr, &frame.drawSem);
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx)
+ devFuncs->vkCreateSemaphore(dev, &semInfo, nullptr, &frame.presTransSem);
+ }
+
+ currentFrame = 0;
+
+ if (renderer)
+ renderer->initSwapChainResources();
+
+ status = StatusReady;
+}
+
+uint32_t QVulkanWindowPrivate::chooseTransientImageMemType(VkImage img, uint32_t startIndex)
+{
+ VkPhysicalDeviceMemoryProperties physDevMemProps;
+ inst->functions()->vkGetPhysicalDeviceMemoryProperties(physDevs[physDevIndex], &physDevMemProps);
+
+ VkMemoryRequirements memReq;
+ devFuncs->vkGetImageMemoryRequirements(dev, img, &memReq);
+ uint32_t memTypeIndex = uint32_t(-1);
+
+ if (memReq.memoryTypeBits) {
+ // Find a device local + lazily allocated, or at least device local memtype.
+ const VkMemoryType *memType = physDevMemProps.memoryTypes;
+ bool foundDevLocal = false;
+ for (uint32_t i = startIndex; i < physDevMemProps.memoryTypeCount; ++i) {
+ if (memReq.memoryTypeBits & (1 << i)) {
+ if (memType[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+ if (!foundDevLocal) {
+ foundDevLocal = true;
+ memTypeIndex = i;
+ }
+ if (memType[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
+ memTypeIndex = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return memTypeIndex;
+}
+
+static inline VkDeviceSize aligned(VkDeviceSize v, VkDeviceSize byteAlign)
+{
+ return (v + byteAlign - 1) & ~(byteAlign - 1);
+}
+
+bool QVulkanWindowPrivate::createTransientImage(VkFormat format,
+ VkImageUsageFlags usage,
+ VkImageAspectFlags aspectMask,
+ VkImage *images,
+ VkDeviceMemory *mem,
+ VkImageView *views,
+ int count)
+{
+ VkMemoryRequirements memReq;
+ VkResult err;
+
+ for (int i = 0; i < count; ++i) {
+ VkImageCreateInfo imgInfo;
+ memset(&imgInfo, 0, sizeof(imgInfo));
+ imgInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ imgInfo.imageType = VK_IMAGE_TYPE_2D;
+ imgInfo.format = format;
+ imgInfo.extent.width = swapChainImageSize.width();
+ imgInfo.extent.height = swapChainImageSize.height();
+ imgInfo.extent.depth = 1;
+ imgInfo.mipLevels = imgInfo.arrayLayers = 1;
+ imgInfo.samples = sampleCount;
+ imgInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imgInfo.usage = usage | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
+
+ err = devFuncs->vkCreateImage(dev, &imgInfo, nullptr, images + i);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create image: %d", err);
+ return false;
+ }
+
+ // Assume the reqs are the same since the images are same in every way.
+ // Still, call GetImageMemReq for every image, in order to prevent the
+ // validation layer from complaining.
+ devFuncs->vkGetImageMemoryRequirements(dev, images[i], &memReq);
+ }
+
+ VkMemoryAllocateInfo memInfo;
+ memset(&memInfo, 0, sizeof(memInfo));
+ memInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ memInfo.allocationSize = aligned(memReq.size, memReq.alignment) * count;
+
+ uint32_t startIndex = 0;
+ do {
+ memInfo.memoryTypeIndex = chooseTransientImageMemType(images[0], startIndex);
+ if (memInfo.memoryTypeIndex == uint32_t(-1)) {
+ qWarning("QVulkanWindow: No suitable memory type found");
+ return false;
+ }
+ startIndex = memInfo.memoryTypeIndex + 1;
+ qCDebug(lcVk, "Allocating %u bytes for transient image (memtype %u)",
+ uint32_t(memInfo.allocationSize), memInfo.memoryTypeIndex);
+ err = devFuncs->vkAllocateMemory(dev, &memInfo, nullptr, mem);
+ if (err != VK_SUCCESS && err != VK_ERROR_OUT_OF_DEVICE_MEMORY) {
+ qWarning("QVulkanWindow: Failed to allocate image memory: %d", err);
+ return false;
+ }
+ } while (err != VK_SUCCESS);
+
+ VkDeviceSize ofs = 0;
+ for (int i = 0; i < count; ++i) {
+ err = devFuncs->vkBindImageMemory(dev, images[i], *mem, ofs);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to bind image memory: %d", err);
+ return false;
+ }
+ ofs += aligned(memReq.size, memReq.alignment);
+
+ VkImageViewCreateInfo imgViewInfo;
+ memset(&imgViewInfo, 0, sizeof(imgViewInfo));
+ imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ imgViewInfo.image = images[i];
+ imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ imgViewInfo.format = format;
+ imgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
+ imgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
+ imgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
+ imgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
+ imgViewInfo.subresourceRange.aspectMask = aspectMask;
+ imgViewInfo.subresourceRange.levelCount = imgViewInfo.subresourceRange.layerCount = 1;
+
+ err = devFuncs->vkCreateImageView(dev, &imgViewInfo, nullptr, views + i);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create image view: %d", err);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void QVulkanWindowPrivate::releaseSwapChain()
+{
+ if (!dev || !swapChain) // do not rely on 'status', a half done init must be cleaned properly too
+ return;
+
+ qCDebug(lcVk, "Releasing swapchain");
+
+ devFuncs->vkDeviceWaitIdle(dev);
+
+ if (renderer) {
+ renderer->releaseSwapChainResources();
+ devFuncs->vkDeviceWaitIdle(dev);
+ }
+
+ for (int i = 0; i < frameLag; ++i) {
+ FrameResources &frame(frameRes[i]);
+ if (frame.fence) {
+ if (frame.fenceWaitable)
+ devFuncs->vkWaitForFences(dev, 1, &frame.fence, VK_TRUE, UINT64_MAX);
+ devFuncs->vkDestroyFence(dev, frame.fence, nullptr);
+ frame.fence = VK_NULL_HANDLE;
+ frame.fenceWaitable = false;
+ }
+ if (frame.imageSem) {
+ devFuncs->vkDestroySemaphore(dev, frame.imageSem, nullptr);
+ frame.imageSem = VK_NULL_HANDLE;
+ }
+ if (frame.drawSem) {
+ devFuncs->vkDestroySemaphore(dev, frame.drawSem, nullptr);
+ frame.drawSem = VK_NULL_HANDLE;
+ }
+ if (frame.presTransSem) {
+ devFuncs->vkDestroySemaphore(dev, frame.presTransSem, nullptr);
+ frame.presTransSem = VK_NULL_HANDLE;
+ }
+ }
+
+ for (int i = 0; i < swapChainBufferCount; ++i) {
+ ImageResources &image(imageRes[i]);
+ if (image.cmdFence) {
+ if (image.cmdFenceWaitable)
+ devFuncs->vkWaitForFences(dev, 1, &image.cmdFence, VK_TRUE, UINT64_MAX);
+ devFuncs->vkDestroyFence(dev, image.cmdFence, nullptr);
+ image.cmdFence = VK_NULL_HANDLE;
+ image.cmdFenceWaitable = false;
+ }
+ if (image.fb) {
+ devFuncs->vkDestroyFramebuffer(dev, image.fb, nullptr);
+ image.fb = VK_NULL_HANDLE;
+ }
+ if (image.imageView) {
+ devFuncs->vkDestroyImageView(dev, image.imageView, nullptr);
+ image.imageView = VK_NULL_HANDLE;
+ }
+ if (image.cmdBuf) {
+ devFuncs->vkFreeCommandBuffers(dev, cmdPool, 1, &image.cmdBuf);
+ image.cmdBuf = VK_NULL_HANDLE;
+ }
+ if (image.presTransCmdBuf) {
+ devFuncs->vkFreeCommandBuffers(dev, presCmdPool, 1, &image.presTransCmdBuf);
+ image.presTransCmdBuf = VK_NULL_HANDLE;
+ }
+ if (image.msaaImageView) {
+ devFuncs->vkDestroyImageView(dev, image.msaaImageView, nullptr);
+ image.msaaImageView = VK_NULL_HANDLE;
+ }
+ if (image.msaaImage) {
+ devFuncs->vkDestroyImage(dev, image.msaaImage, nullptr);
+ image.msaaImage = VK_NULL_HANDLE;
+ }
+ }
+
+ if (msaaImageMem) {
+ devFuncs->vkFreeMemory(dev, msaaImageMem, nullptr);
+ msaaImageMem = VK_NULL_HANDLE;
+ }
+
+ if (dsView) {
+ devFuncs->vkDestroyImageView(dev, dsView, nullptr);
+ dsView = VK_NULL_HANDLE;
+ }
+ if (dsImage) {
+ devFuncs->vkDestroyImage(dev, dsImage, nullptr);
+ dsImage = VK_NULL_HANDLE;
+ }
+ if (dsMem) {
+ devFuncs->vkFreeMemory(dev, dsMem, nullptr);
+ dsMem = VK_NULL_HANDLE;
+ }
+
+ if (swapChain) {
+ vkDestroySwapchainKHR(dev, swapChain, nullptr);
+ swapChain = VK_NULL_HANDLE;
+ }
+
+ if (status == StatusReady)
+ status = StatusDeviceReady;
+}
+
+/*!
+ \internal
+ */
+void QVulkanWindow::exposeEvent(QExposeEvent *)
+{
+ Q_D(QVulkanWindow);
+
+ if (isExposed()) {
+ d->ensureStarted();
+ } else {
+ if (!d->flags.testFlag(PersistentResources)) {
+ d->releaseSwapChain();
+ d->reset();
+ }
+ }
+}
+
+void QVulkanWindowPrivate::ensureStarted()
+{
+ Q_Q(QVulkanWindow);
+ if (status == QVulkanWindowPrivate::StatusFailRetry)
+ status = QVulkanWindowPrivate::StatusUninitialized;
+ if (status == QVulkanWindowPrivate::StatusUninitialized) {
+ init();
+ if (status == QVulkanWindowPrivate::StatusDeviceReady)
+ recreateSwapChain();
+ }
+ if (status == QVulkanWindowPrivate::StatusReady)
+ q->requestUpdate();
+}
+
+/*!
+ \internal
+ */
+void QVulkanWindow::resizeEvent(QResizeEvent *)
+{
+ // Nothing to do here - recreating the swapchain is handled when building the next frame.
+}
+
+/*!
+ \internal
+ */
+bool QVulkanWindow::event(QEvent *e)
+{
+ Q_D(QVulkanWindow);
+
+ switch (e->type()) {
+ case QEvent::UpdateRequest:
+ d->beginFrame();
+ break;
+
+ // The swapchain must be destroyed before the surface as per spec. This is
+ // not ideal for us because the surface is managed by the QPlatformWindow
+ // which may be gone already when the unexpose comes, making the validation
+ // layer scream. The solution is to listen to the PlatformSurface events.
+ case QEvent::PlatformSurface:
+ if (static_cast<QPlatformSurfaceEvent *>(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
+ d->releaseSwapChain();
+ d->reset();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return QWindow::event(e);
+}
+
+/*!
+ Returns true if this window has successfully initialized all Vulkan
+ resources, including the swapchain.
+
+ \note Initialization happens on the first expose event after the window is
+ made visible.
+ */
+bool QVulkanWindow::isValid() const
+{
+ Q_D(const QVulkanWindow);
+ return d->status == QVulkanWindowPrivate::StatusReady;
+}
+
+/*!
+ Returns a new instance of QVulkanWindowRenderer.
+
+ This virtual function is called once during the lifetime of the window, at
+ some point after making it visible for the first time.
+
+ The default implementation returns null and so no rendering will be
+ performed apart from clearing the buffers.
+
+ The window takes ownership of the returned renderer object.
+ */
+QVulkanWindowRenderer *QVulkanWindow::createRenderer()
+{
+ return nullptr;
+}
+
+/*!
+ Virtual destructor.
+ */
+QVulkanWindowRenderer::~QVulkanWindowRenderer()
+{
+}
+
+/*!
+ This virtual function is called right before graphics initialization, that
+ ends up in calling initResources(), is about to begin.
+
+ Normally there is no need to reimplement this function. However, there are
+ cases that involve decisions based on both the physical device and the
+ surface. These cannot normally be performed before making the QVulkanWindow
+ visible since the Vulkan surface is not retrievable at that stage.
+
+ Instead, applications can reimplement this function. Here both
+ QVulkanWindow::physicalDevice() and QVulkanInstance::surfaceForWindow() are
+ functional, but no further logical device initialization has taken place
+ yet.
+
+ The default implementation is empty.
+ */
+void QVulkanWindowRenderer::preInitResources()
+{
+}
+
+/*!
+ This virtual function is called when it is time to create the renderer's
+ graphics resources.
+
+ Depending on the QVulkanWindow::PersistentResources flag, device lost
+ situations, etc. this function may be called more than once during the
+ lifetime of a QVulkanWindow. However, subsequent invocations are always
+ preceded by a call to releaseResources().
+
+ Accessors like device(), graphicsQueue() and graphicsCommandPool() are only
+ guaranteed to return valid values inside this function and afterwards, up
+ until releaseResources() is called.
+
+ The default implementation is empty.
+ */
+void QVulkanWindowRenderer::initResources()
+{
+}
+
+/*!
+ This virtual function is called when swapchain, framebuffer or renderpass
+ related initialization can be performed. Swapchain and related resources
+ are reset and then recreated in response to window resize events, and
+ therefore a pair of calls to initResources() and releaseResources() can
+ have multiple calls to initSwapChainResources() and
+ releaseSwapChainResources() calls in-between.
+
+ Accessors like QVulkanWindow::swapChainImageSize() are only guaranteed to
+ return valid values inside this function and afterwards, up until
+ releaseSwapChainResources() is called.
+
+ This is also the place where size-dependent calculations (for example, the
+ projection matrix) should be made since this function is called effectively
+ on every resize.
+
+ The default implementation is empty.
+ */
+void QVulkanWindowRenderer::initSwapChainResources()
+{
+}
+
+/*!
+ This virtual function is called when swapchain, framebuffer or renderpass
+ related resources must be released.
+
+ The implementation must be prepared that a call to this function may be
+ followed by a new call to initSwapChainResources() at a later point.
+
+ QVulkanWindow takes care of waiting for the device to become idle before
+ and after invoking this function.
+
+ The default implementation is empty.
+
+ \note This is the last place to act with all graphics resources intact
+ before QVulkanWindow starts releasing them. It is therefore essential that
+ implementations with an asynchronous, potentially multi-threaded
+ startNextFrame() perform a blocking wait and call
+ QVulkanWindow::frameReady() before returning from this function in case
+ there is a pending frame submission.
+ */
+void QVulkanWindowRenderer::releaseSwapChainResources()
+{
+}
+
+/*!
+ This virtual function is called when the renderer's graphics resources must be
+ released.
+
+ The implementation must be prepared that a call to this function may be
+ followed by an initResources() at a later point.
+
+ QVulkanWindow takes care of waiting for the device to become idle before
+ and after invoking this function.
+
+ The default implementation is empty.
+ */
+void QVulkanWindowRenderer::releaseResources()
+{
+}
+
+/*!
+ \fn QVulkanWindowRenderer::startNextFrame()
+
+ This virtual function is called when the draw calls for the next frame are
+ to be added to the command buffer.
+
+ Each call to this function must be followed by a call to
+ QVulkanWindow::frameReady(). Failing to do so will stall the rendering
+ loop. The call can also be made at a later time, after returning from this
+ function. This means that it is possible to kick off asynchronous work, and
+ only update the command buffer and notify QVulkanWindow when that work has
+ finished.
+
+ All Vulkan resources are initialized and ready when this function is
+ invoked. The current framebuffer and main command buffer can be retrieved
+ via QVulkanWindow::currentFramebuffer() and
+ QVulkanWindow::currentCommandBuffer(). The logical device and the active
+ graphics queue are available via QVulkanWindow::device() and
+ QVulkanWindow::graphicsQueue(). Implementations can create additional
+ command buffers from the pool returned by
+ QVulkanWindow::graphicsCommandPool(). For convenience, the index of a host
+ visible and device local memory type index are exposed via
+ QVulkanWindow::hostVisibleMemoryIndex() and
+ QVulkanWindow::deviceLocalMemoryIndex(). All these accessors are safe to be
+ called from any thread.
+
+ \sa QVulkanWindow::frameReady(), QVulkanWindow
+ */
+
+/*!
+ This virtual function is called when the physical device is lost, meaning
+ the creation of the logical device fails with \c{VK_ERROR_DEVICE_LOST}.
+
+ The default implementation is empty.
+
+ There is typically no need to perform anything special in this function
+ because QVulkanWindow will automatically retry to initialize itself after a
+ certain amount of time.
+
+ \sa logicalDeviceLost()
+ */
+void QVulkanWindowRenderer::physicalDeviceLost()
+{
+}
+
+/*!
+ This virtual function is called when the logical device (VkDevice) is lost,
+ meaning some operation failed with \c{VK_ERROR_DEVICE_LOST}.
+
+ The default implementation is empty.
+
+ There is typically no need to perform anything special in this function.
+ QVulkanWindow will automatically release all resources (invoking
+ releaseSwapChainResources() and releaseResources() as necessary) and will
+ attempt to reinitialize, acquiring a new device. When the physical device
+ was also lost, this reinitialization attempt may then result in
+ physicalDeviceLost().
+
+ \sa physicalDeviceLost()
+ */
+void QVulkanWindowRenderer::logicalDeviceLost()
+{
+}
+
+void QVulkanWindowPrivate::beginFrame()
+{
+ if (!swapChain || framePending)
+ return;
+
+ Q_Q(QVulkanWindow);
+ if (q->size() * q->devicePixelRatio() != swapChainImageSize) {
+ recreateSwapChain();
+ if (!swapChain)
+ return;
+ }
+
+ FrameResources &frame(frameRes[currentFrame]);
+
+ if (!frame.imageAcquired) {
+ // Wait if we are too far ahead, i.e. the thread gets throttled based on the presentation rate
+ // (note that we are using FIFO mode -> vsync)
+ if (frame.fenceWaitable) {
+ devFuncs->vkWaitForFences(dev, 1, &frame.fence, VK_TRUE, UINT64_MAX);
+ devFuncs->vkResetFences(dev, 1, &frame.fence);
+ frame.fenceWaitable = false;
+ }
+
+ // move on to next swapchain image
+ VkResult err = vkAcquireNextImageKHR(dev, swapChain, UINT64_MAX,
+ frame.imageSem, frame.fence, &currentImage);
+ if (err == VK_SUCCESS || err == VK_SUBOPTIMAL_KHR) {
+ frame.imageSemWaitable = true;
+ frame.imageAcquired = true;
+ frame.fenceWaitable = true;
+ } else if (err == VK_ERROR_OUT_OF_DATE_KHR) {
+ recreateSwapChain();
+ q->requestUpdate();
+ return;
+ } else {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to acquire next swapchain image: %d", err);
+ q->requestUpdate();
+ return;
+ }
+ }
+
+ // make sure the previous draw for the same image has finished
+ ImageResources &image(imageRes[currentImage]);
+ if (image.cmdFenceWaitable) {
+ devFuncs->vkWaitForFences(dev, 1, &image.cmdFence, VK_TRUE, UINT64_MAX);
+ devFuncs->vkResetFences(dev, 1, &image.cmdFence);
+ image.cmdFenceWaitable = false;
+ }
+
+ // build new draw command buffer
+ if (image.cmdBuf) {
+ devFuncs->vkFreeCommandBuffers(dev, cmdPool, 1, &image.cmdBuf);
+ image.cmdBuf = 0;
+ }
+
+ VkCommandBufferAllocateInfo cmdBufInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 };
+ VkResult err = devFuncs->vkAllocateCommandBuffers(dev, &cmdBufInfo, &image.cmdBuf);
+ if (err != VK_SUCCESS) {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to allocate frame command buffer: %d", err);
+ return;
+ }
+
+ VkCommandBufferBeginInfo cmdBufBeginInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr };
+ err = devFuncs->vkBeginCommandBuffer(image.cmdBuf, &cmdBufBeginInfo);
+ if (err != VK_SUCCESS) {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to begin frame command buffer: %d", err);
+ return;
+ }
+
+ if (frameGrabbing)
+ frameGrabTargetImage = QImage(swapChainImageSize, QImage::Format_RGBA8888);
+
+ if (renderer) {
+ framePending = true;
+ renderer->startNextFrame();
+ // done for now - endFrame() will get invoked when frameReady() is called back
+ } else {
+ VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+ VkClearDepthStencilValue clearDS = { 1.0f, 0 };
+ VkClearValue clearValues[3];
+ memset(clearValues, 0, sizeof(clearValues));
+ clearValues[0].color = clearValues[2].color = clearColor;
+ clearValues[1].depthStencil = clearDS;
+
+ VkRenderPassBeginInfo rpBeginInfo;
+ memset(&rpBeginInfo, 0, sizeof(rpBeginInfo));
+ rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+ rpBeginInfo.renderPass = defaultRenderPass;
+ rpBeginInfo.framebuffer = image.fb;
+ rpBeginInfo.renderArea.extent.width = swapChainImageSize.width();
+ rpBeginInfo.renderArea.extent.height = swapChainImageSize.height();
+ rpBeginInfo.clearValueCount = sampleCount > VK_SAMPLE_COUNT_1_BIT ? 3 : 2;
+ rpBeginInfo.pClearValues = clearValues;
+ devFuncs->vkCmdBeginRenderPass(image.cmdBuf, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+ devFuncs->vkCmdEndRenderPass(image.cmdBuf);
+
+ endFrame();
+ }
+}
+
+void QVulkanWindowPrivate::endFrame()
+{
+ Q_Q(QVulkanWindow);
+
+ FrameResources &frame(frameRes[currentFrame]);
+ ImageResources &image(imageRes[currentImage]);
+
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx && !frameGrabbing) {
+ // Add the swapchain image release to the command buffer that will be
+ // submitted to the graphics queue.
+ VkImageMemoryBarrier presTrans;
+ memset(&presTrans, 0, sizeof(presTrans));
+ presTrans.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ presTrans.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ presTrans.oldLayout = presTrans.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ presTrans.srcQueueFamilyIndex = gfxQueueFamilyIdx;
+ presTrans.dstQueueFamilyIndex = presQueueFamilyIdx;
+ presTrans.image = image.image;
+ presTrans.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ presTrans.subresourceRange.levelCount = presTrans.subresourceRange.layerCount = 1;
+ devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ 0, 0, nullptr, 0, nullptr,
+ 1, &presTrans);
+ }
+
+ // When grabbing a frame, add a readback at the end and skip presenting.
+ if (frameGrabbing)
+ addReadback();
+
+ VkResult err = devFuncs->vkEndCommandBuffer(image.cmdBuf);
+ if (err != VK_SUCCESS) {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to end frame command buffer: %d", err);
+ return;
+ }
+
+ // submit draw calls
+ VkSubmitInfo submitInfo;
+ memset(&submitInfo, 0, sizeof(submitInfo));
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &image.cmdBuf;
+ if (frame.imageSemWaitable) {
+ submitInfo.waitSemaphoreCount = 1;
+ submitInfo.pWaitSemaphores = &frame.imageSem;
+ }
+ if (!frameGrabbing) {
+ submitInfo.signalSemaphoreCount = 1;
+ submitInfo.pSignalSemaphores = &frame.drawSem;
+ }
+ VkPipelineStageFlags psf = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ submitInfo.pWaitDstStageMask = &psf;
+
+ Q_ASSERT(!image.cmdFenceWaitable);
+
+ err = devFuncs->vkQueueSubmit(gfxQueue, 1, &submitInfo, image.cmdFence);
+ if (err == VK_SUCCESS) {
+ frame.imageSemWaitable = false;
+ image.cmdFenceWaitable = true;
+ } else {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to submit to graphics queue: %d", err);
+ return;
+ }
+
+ // block and then bail out when grabbing
+ if (frameGrabbing) {
+ finishBlockingReadback();
+ frameGrabbing = false;
+ // Leave frame.imageAcquired set to true.
+ // Do not change currentFrame.
+ emit q->frameGrabbed(frameGrabTargetImage);
+ return;
+ }
+
+ if (gfxQueueFamilyIdx != presQueueFamilyIdx) {
+ // Submit the swapchain image acquire to the present queue.
+ submitInfo.pWaitSemaphores = &frame.drawSem;
+ submitInfo.pSignalSemaphores = &frame.presTransSem;
+ submitInfo.pCommandBuffers = &image.presTransCmdBuf; // must be USAGE_SIMULTANEOUS
+ err = devFuncs->vkQueueSubmit(presQueue, 1, &submitInfo, VK_NULL_HANDLE);
+ if (err != VK_SUCCESS) {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to submit to present queue: %d", err);
+ return;
+ }
+ }
+
+ // queue present
+ VkPresentInfoKHR presInfo;
+ memset(&presInfo, 0, sizeof(presInfo));
+ presInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
+ presInfo.swapchainCount = 1;
+ presInfo.pSwapchains = &swapChain;
+ presInfo.pImageIndices = &currentImage;
+ presInfo.waitSemaphoreCount = 1;
+ presInfo.pWaitSemaphores = gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
+
+ err = vkQueuePresentKHR(gfxQueue, &presInfo);
+ if (err != VK_SUCCESS) {
+ if (err == VK_ERROR_OUT_OF_DATE_KHR) {
+ recreateSwapChain();
+ q->requestUpdate();
+ return;
+ } else if (err != VK_SUBOPTIMAL_KHR) {
+ if (!checkDeviceLost(err))
+ qWarning("QVulkanWindow: Failed to present: %d", err);
+ return;
+ }
+ }
+
+ frame.imageAcquired = false;
+
+ inst->presentQueued(q);
+
+ currentFrame = (currentFrame + 1) % frameLag;
+}
+
+/*!
+ This function must be called exactly once in response to each invocation of
+ the QVulkanWindowRenderer::startNextFrame() implementation. At the time of
+ this call, the main command buffer, exposed via currentCommandBuffer(),
+ must have all necessary rendering commands added to it since this function
+ will trigger submitting the commands and queuing the present command.
+
+ \note This function must only be called from the gui/main thread, which is
+ where QVulkanWindowRenderer's functions are invoked and where the
+ QVulkanWindow instance lives.
+
+ \sa QVulkanWindowRenderer::startNextFrame()
+ */
+void QVulkanWindow::frameReady()
+{
+ Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread(),
+ "QVulkanWindow", "frameReady() can only be called from the GUI (main) thread");
+
+ Q_D(QVulkanWindow);
+
+ if (!d->framePending) {
+ qWarning("QVulkanWindow: frameReady() called without a corresponding startNextFrame()");
+ return;
+ }
+
+ d->framePending = false;
+
+ d->endFrame();
+}
+
+bool QVulkanWindowPrivate::checkDeviceLost(VkResult err)
+{
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("QVulkanWindow: Device lost");
+ if (renderer)
+ renderer->logicalDeviceLost();
+ qCDebug(lcVk, "Releasing all resources due to device lost");
+ releaseSwapChain();
+ reset();
+ qCDebug(lcVk, "Restarting");
+ ensureStarted();
+ return true;
+ }
+ return false;
+}
+
+void QVulkanWindowPrivate::addReadback()
+{
+ VkImageCreateInfo imageInfo;
+ memset(&imageInfo, 0, sizeof(imageInfo));
+ imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ imageInfo.imageType = VK_IMAGE_TYPE_2D;
+ imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
+ imageInfo.extent.width = frameGrabTargetImage.width();
+ imageInfo.extent.height = frameGrabTargetImage.height();
+ imageInfo.extent.depth = 1;
+ imageInfo.mipLevels = 1;
+ imageInfo.arrayLayers = 1;
+ imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
+ imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+
+ VkResult err = devFuncs->vkCreateImage(dev, &imageInfo, nullptr, &frameGrabImage);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to create image for readback: %d", err);
+ return;
+ }
+
+ VkMemoryRequirements memReq;
+ devFuncs->vkGetImageMemoryRequirements(dev, frameGrabImage, &memReq);
+
+ VkMemoryAllocateInfo allocInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ nullptr,
+ memReq.size,
+ hostVisibleMemIndex
+ };
+
+ err = devFuncs->vkAllocateMemory(dev, &allocInfo, nullptr, &frameGrabImageMem);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to allocate memory for readback image: %d", err);
+ return;
+ }
+
+ err = devFuncs->vkBindImageMemory(dev, frameGrabImage, frameGrabImageMem, 0);
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to bind readback image memory: %d", err);
+ return;
+ }
+
+ ImageResources &image(imageRes[currentImage]);
+
+ VkImageMemoryBarrier barrier;
+ memset(&barrier, 0, sizeof(barrier));
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ barrier.subresourceRange.levelCount = barrier.subresourceRange.layerCount = 1;
+
+ barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ barrier.image = image.image;
+
+ devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0, 0, nullptr, 0, nullptr,
+ 1, &barrier);
+
+ barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ barrier.srcAccessMask = 0;
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ barrier.image = frameGrabImage;
+
+ devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0, 0, nullptr, 0, nullptr,
+ 1, &barrier);
+
+ VkImageCopy copyInfo;
+ memset(&copyInfo, 0, sizeof(copyInfo));
+ copyInfo.srcSubresource.aspectMask = copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ copyInfo.srcSubresource.layerCount = copyInfo.dstSubresource.layerCount = 1;
+ copyInfo.extent.width = frameGrabTargetImage.width();
+ copyInfo.extent.height = frameGrabTargetImage.height();
+ copyInfo.extent.depth = 1;
+
+ devFuncs->vkCmdCopyImage(image.cmdBuf, image.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ frameGrabImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copyInfo);
+
+ barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
+ barrier.image = frameGrabImage;
+
+ devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0, 0, nullptr, 0, nullptr,
+ 1, &barrier);
+}
+
+void QVulkanWindowPrivate::finishBlockingReadback()
+{
+ ImageResources &image(imageRes[currentImage]);
+
+ // Block until the current frame is done. Normally this wait would only be
+ // done in current + concurrentFrameCount().
+ devFuncs->vkWaitForFences(dev, 1, &image.cmdFence, VK_TRUE, UINT64_MAX);
+ devFuncs->vkResetFences(dev, 1, &image.cmdFence);
+ // will reuse the same image for the next "real" frame, do not wait then
+ image.cmdFenceWaitable = false;
+
+ VkImageSubresource subres = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
+ VkSubresourceLayout layout;
+ devFuncs->vkGetImageSubresourceLayout(dev, frameGrabImage, &subres, &layout);
+
+ uchar *p;
+ VkResult err = devFuncs->vkMapMemory(dev, frameGrabImageMem, layout.offset, layout.size, 0, reinterpret_cast<void **>(&p));
+ if (err != VK_SUCCESS) {
+ qWarning("QVulkanWindow: Failed to map readback image memory after transfer: %d", err);
+ return;
+ }
+
+ for (int y = 0; y < frameGrabTargetImage.height(); ++y) {
+ memcpy(frameGrabTargetImage.scanLine(y), p, frameGrabTargetImage.width() * 4);
+ p += layout.rowPitch;
+ }
+
+ devFuncs->vkUnmapMemory(dev, frameGrabImageMem);
+
+ devFuncs->vkDestroyImage(dev, frameGrabImage, nullptr);
+ frameGrabImage = VK_NULL_HANDLE;
+ devFuncs->vkFreeMemory(dev, frameGrabImageMem, nullptr);
+ frameGrabImageMem = VK_NULL_HANDLE;
+}
+
+/*!
+ Returns the active physical device.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::preInitResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+VkPhysicalDevice QVulkanWindow::physicalDevice() const
+{
+ Q_D(const QVulkanWindow);
+ if (d->physDevIndex < d->physDevs.count())
+ return d->physDevs[d->physDevIndex];
+ qWarning("QVulkanWindow: Physical device not available");
+ return VK_NULL_HANDLE;
+}
+
+/*!
+ Returns a pointer to the properties for the active physical device.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::preInitResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+const VkPhysicalDeviceProperties *QVulkanWindow::physicalDeviceProperties() const
+{
+ Q_D(const QVulkanWindow);
+ if (d->physDevIndex < d->physDevProps.count())
+ return &d->physDevProps[d->physDevIndex];
+ qWarning("QVulkanWindow: Physical device properties not available");
+ return nullptr;
+}
+
+/*!
+ Returns the active logical device.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+VkDevice QVulkanWindow::device() const
+{
+ Q_D(const QVulkanWindow);
+ return d->dev;
+}
+
+/*!
+ Returns the active graphics queue.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+VkQueue QVulkanWindow::graphicsQueue() const
+{
+ Q_D(const QVulkanWindow);
+ return d->gfxQueue;
+}
+
+/*!
+ Returns the active graphics command pool.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+VkCommandPool QVulkanWindow::graphicsCommandPool() const
+{
+ Q_D(const QVulkanWindow);
+ return d->cmdPool;
+}
+
+/*!
+ Returns a host visible memory type index suitable for general use.
+
+ The returned memory type will be both host visible and coherent. In
+ addition, it will also be cached, if possible.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+uint32_t QVulkanWindow::hostVisibleMemoryIndex() const
+{
+ Q_D(const QVulkanWindow);
+ return d->hostVisibleMemIndex;
+}
+
+/*!
+ Returns a device local memory type index suitable for general use.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+uint32_t QVulkanWindow::deviceLocalMemoryIndex() const
+{
+ Q_D(const QVulkanWindow);
+ return d->deviceLocalMemIndex;
+}
+
+/*!
+ Returns a typical render pass with one sub-pass.
+
+ \note Applications are not required to use this render pass. However, they
+ are then responsible for ensuring the current swap chain and depth-stencil
+ images get transitioned from \c{VK_IMAGE_LAYOUT_UNDEFINED} to
+ \c{VK_IMAGE_LAYOUT_PRESENT_SRC_KHR} and
+ \c{VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL} either via the
+ application's custom render pass or by other means.
+
+ \note Stencil read/write is not enabled in this render pass.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+
+ \sa currentFramebuffer()
+ */
+VkRenderPass QVulkanWindow::defaultRenderPass() const
+{
+ Q_D(const QVulkanWindow);
+ return d->defaultRenderPass;
+}
+
+/*!
+ Returns the color buffer format used by the swapchain.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+
+ \sa setPreferredColorFormats()
+ */
+VkFormat QVulkanWindow::colorFormat() const
+{
+ Q_D(const QVulkanWindow);
+ return d->colorFormat;
+}
+
+/*!
+ Returns the format used by the depth-stencil buffer(s).
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initResources() up until
+ QVulkanWindowRenderer::releaseResources().
+ */
+VkFormat QVulkanWindow::depthStencilFormat() const
+{
+ Q_D(const QVulkanWindow);
+ return d->dsFormat;
+}
+
+/*!
+ Returns the image size of the swapchain.
+
+ This usually matches the size of the window, but may also differ in case
+ \c vkGetPhysicalDeviceSurfaceCapabilitiesKHR reports a fixed size.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+QSize QVulkanWindow::swapChainImageSize() const
+{
+ Q_D(const QVulkanWindow);
+ return d->swapChainImageSize;
+}
+
+/*!
+ Returns The active command buffer for the current swap chain image.
+ Implementations of QVulkanWindowRenderer::startNextFrame() are expected to
+ add commands to this command buffer.
+
+ \note This function must only be called from within startNextFrame() and, in
+ case of asynchronous command generation, up until the call to frameReady().
+ */
+VkCommandBuffer QVulkanWindow::currentCommandBuffer() const
+{
+ Q_D(const QVulkanWindow);
+ if (!d->framePending) {
+ qWarning("QVulkanWindow: Attempted to call currentCommandBuffer() without an active frame");
+ return VK_NULL_HANDLE;
+ }
+ return d->imageRes[d->currentImage].cmdBuf;
+}
+
+/*!
+ Returns a VkFramebuffer for the current swapchain image using the default
+ render pass.
+
+ The framebuffer has two attachments (color, depth-stencil) when
+ multisampling is not in use, and three (color resolve, depth-stencil,
+ multisample color) when sampleCountFlagBits() is greater than
+ \c{VK_SAMPLE_COUNT_1_BIT}. Renderers must take this into account, for
+ example when providing clear values.
+
+ \note Applications are not required to use this framebuffer in case they
+ provide their own render pass instead of using the one returned from
+ defaultRenderPass().
+
+ \note This function must only be called from within startNextFrame() and, in
+ case of asynchronous command generation, up until the call to frameReady().
+
+ \sa defaultRenderPass()
+ */
+VkFramebuffer QVulkanWindow::currentFramebuffer() const
+{
+ Q_D(const QVulkanWindow);
+ if (!d->framePending) {
+ qWarning("QVulkanWindow: Attempted to call currentFramebuffer() without an active frame");
+ return VK_NULL_HANDLE;
+ }
+ return d->imageRes[d->currentImage].fb;
+}
+
+/*!
+ Returns the current frame index in the range [0, concurrentFrameCount() - 1].
+
+ Renderer implementations will have to ensure that uniform data and other
+ dynamic resources exist in multiple copies, in order to prevent frame N
+ altering the data used by the still-active frames N - 1, N - 2, ... N -
+ concurrentFrameCount() + 1.
+
+ To avoid relying on dynamic array sizes, applications can use
+ MAX_CONCURRENT_FRAME_COUNT when declaring arrays. This is guaranteed to be
+ always equal to or greater than the value returned from
+ concurrentFrameCount(). Such arrays can then be indexed by the value
+ returned from this function.
+
+ \code
+ class Renderer {
+ ...
+ VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
+ };
+
+ void Renderer::startNextFrame()
+ {
+ VkDescriptorBufferInfo &uniformBufInfo(m_uniformBufInfo[m_window->currentFrame()]);
+ ...
+ }
+ \endcode
+
+ \note This function must only be called from within startNextFrame() and, in
+ case of asynchronous command generation, up until the call to frameReady().
+
+ \sa concurrentFrameCount()
+ */
+int QVulkanWindow::currentFrame() const
+{
+ Q_D(const QVulkanWindow);
+ if (!d->framePending)
+ qWarning("QVulkanWindow: Attempted to call currentFrame() without an active frame");
+ return d->currentFrame;
+}
+
+/*!
+ \variable QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT
+
+ \brief A constant value that is always equal to or greater than the maximum value
+ of concurrentFrameCount().
+ */
+
+/*!
+ Returns the number of frames that can be potentially active at the same time.
+
+ \note The value is constant for the entire lifetime of the QVulkanWindow.
+
+ \code
+ class Renderer {
+ ...
+ VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
+ };
+
+ void Renderer::startNextFrame()
+ {
+ const int count = m_window->concurrentFrameCount();
+ for (int i = 0; i < count; ++i)
+ m_uniformBufInfo[i] = ...
+ ...
+ }
+ \endcode
+
+ \sa currentFrame()
+ */
+int QVulkanWindow::concurrentFrameCount() const
+{
+ Q_D(const QVulkanWindow);
+ return d->frameLag;
+}
+
+/*!
+ Returns the number of images in the swap chain.
+
+ \note Accessing this is necessary when providing a custom render pass and
+ framebuffer. The framebuffer is specific to the current swapchain image and
+ hence the application must provide multiple framebuffers.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+int QVulkanWindow::swapChainImageCount() const
+{
+ Q_D(const QVulkanWindow);
+ return d->swapChainBufferCount;
+}
+
+/*!
+ Returns the current swap chain image index in the range [0, swapChainImageCount() - 1].
+
+ \note This function must only be called from within startNextFrame() and, in
+ case of asynchronous command generation, up until the call to frameReady().
+ */
+int QVulkanWindow::currentSwapChainImageIndex() const
+{
+ Q_D(const QVulkanWindow);
+ if (!d->framePending)
+ qWarning("QVulkanWindow: Attempted to call currentSwapChainImageIndex() without an active frame");
+ return d->currentImage;
+}
+
+/*!
+ Returns the specified swap chain image.
+
+ \a idx must be in the range [0, swapChainImageCount() - 1].
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImage QVulkanWindow::swapChainImage(int idx) const
+{
+ Q_D(const QVulkanWindow);
+ return idx >= 0 && idx < d->swapChainBufferCount ? d->imageRes[idx].image : VK_NULL_HANDLE;
+}
+
+/*!
+ Returns the specified swap chain image view.
+
+ \a idx must be in the range [0, swapChainImageCount() - 1].
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImageView QVulkanWindow::swapChainImageView(int idx) const
+{
+ Q_D(const QVulkanWindow);
+ return idx >= 0 && idx < d->swapChainBufferCount ? d->imageRes[idx].imageView : VK_NULL_HANDLE;
+}
+
+/*!
+ Returns the depth-stencil image.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImage QVulkanWindow::depthStencilImage() const
+{
+ Q_D(const QVulkanWindow);
+ return d->dsImage;
+}
+
+/*!
+ Returns the depth-stencil image view.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImageView QVulkanWindow::depthStencilImageView() const
+{
+ Q_D(const QVulkanWindow);
+ return d->dsView;
+}
+
+/*!
+ Returns the current sample count as a \c VkSampleCountFlagBits value.
+
+ When targeting the default render target, the \c rasterizationSamples field
+ of \c VkPipelineMultisampleStateCreateInfo must be set to this value.
+
+ \sa setSampleCount(), supportedSampleCounts()
+ */
+VkSampleCountFlagBits QVulkanWindow::sampleCountFlagBits() const
+{
+ Q_D(const QVulkanWindow);
+ return d->sampleCount;
+}
+
+/*!
+ Returns the specified multisample color image, or \c{VK_NULL_HANDLE} if
+ multisampling is not in use.
+
+ \a idx must be in the range [0, swapChainImageCount() - 1].
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImage QVulkanWindow::msaaColorImage(int idx) const
+{
+ Q_D(const QVulkanWindow);
+ return idx >= 0 && idx < d->swapChainBufferCount ? d->imageRes[idx].msaaImage : VK_NULL_HANDLE;
+}
+
+/*!
+ Returns the specified multisample color image view, or \c{VK_NULL_HANDLE} if
+ multisampling is not in use.
+
+ \a idx must be in the range [0, swapChainImageCount() - 1].
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+VkImageView QVulkanWindow::msaaColorImageView(int idx) const
+{
+ Q_D(const QVulkanWindow);
+ return idx >= 0 && idx < d->swapChainBufferCount ? d->imageRes[idx].msaaImageView : VK_NULL_HANDLE;
+}
+
+/*!
+ Returns true if the swapchain supports usage as transfer source, meaning
+ grab() is functional.
+
+ \note Calling this function is only valid from the invocation of
+ QVulkanWindowRenderer::initSwapChainResources() up until
+ QVulkanWindowRenderer::releaseSwapChainResources().
+ */
+bool QVulkanWindow::supportsGrab() const
+{
+ Q_D(const QVulkanWindow);
+ return d->swapChainSupportsReadBack;
+}
+
+/*!
+ \fn void QVulkanWindow::frameGrabbed(const QImage &image)
+
+ This signal is emitted when the \a image is ready.
+*/
+
+/*!
+ Builds and renders the next frame without presenting it, then performs a
+ blocking readback of the image content.
+
+ Returns the image if the renderer's
+ \l{QVulkanWindowRenderer::startNextFrame()}{startNextFrame()}
+ implementation calls back frameReady() directly. Otherwise, returns an
+ incomplete image, that has the correct size but not the content yet. The
+ content will be delivered via the frameGrabbed() signal in the latter case.
+
+ \note This function should not be called when a frame is in progress
+ (that is, frameReady() has not yet been called back by the application).
+
+ \note This function is potentially expensive due to the additional,
+ blocking readback.
+
+ \note This function currently requires that the swapchain supports usage as
+ a transfer source (\c{VK_IMAGE_USAGE_TRANSFER_SRC_BIT}), and will fail otherwise.
+ */
+QImage QVulkanWindow::grab()
+{
+ Q_D(QVulkanWindow);
+ if (!d->swapChain) {
+ qWarning("QVulkanWindow: Attempted to call grab() without a swapchain");
+ return QImage();
+ }
+ if (d->framePending) {
+ qWarning("QVulkanWindow: Attempted to call grab() while a frame is still pending");
+ return QImage();
+ }
+ if (!d->swapChainSupportsReadBack) {
+ qWarning("QVulkanWindow: Attempted to call grab() with a swapchain that does not support usage as transfer source");
+ return QImage();
+ }
+
+ d->frameGrabbing = true;
+ d->beginFrame();
+
+ return d->frameGrabTargetImage;
+}
+
+/*!
+ Returns a pointer to a QMatrix4x4 that can be used to correct for coordinate
+ system differences between OpenGL and Vulkan.
+
+ By pre-multiplying the projection matrix with this matrix, applications can
+ continue to assume OpenGL-style Y coordinates in clip space (i.e. Y pointing
+ upwards), and can set minDepth and maxDepth to 0 and 1, respectively,
+ without any further corrections to the vertex Z positions, while using the
+ projection matrices retrieved from the QMatrix4x4 functions, such as
+ QMatrix4x4::perspective(), as-is.
+
+ \note With vertex data following the default OpenGL rules (that is, the
+ front face being CCW), the correct winding order in the rasterization state
+ after applying this matrix is clockwise (\c{VK_FRONT_FACE_CLOCKWISE}).
+ */
+const QMatrix4x4 *QVulkanWindow::clipCorrectionMatrix()
+{
+ Q_D(QVulkanWindow);
+ if (d->m_clipCorrect.isIdentity()) {
+ // NB the ctor takes row-major
+ d->m_clipCorrect = QMatrix4x4(1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.5f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ }
+ return &d->m_clipCorrect;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/vulkan/qvulkanwindow.h b/src/gui/vulkan/qvulkanwindow.h
new file mode 100644
index 0000000000..c32c40d459
--- /dev/null
+++ b/src/gui/vulkan/qvulkanwindow.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVULKANWINDOW_H
+#define QVULKANWINDOW_H
+
+#include <QtGui/qtguiglobal.h>
+
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+
+#include <QtGui/qvulkaninstance.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qimage.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtCore/qset.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVulkanWindowPrivate;
+
+class Q_GUI_EXPORT QVulkanWindowRenderer
+{
+public:
+ virtual ~QVulkanWindowRenderer();
+
+ virtual void preInitResources();
+ virtual void initResources();
+ virtual void initSwapChainResources();
+ virtual void releaseSwapChainResources();
+ virtual void releaseResources();
+
+ virtual void startNextFrame() = 0;
+
+ virtual void physicalDeviceLost();
+ virtual void logicalDeviceLost();
+};
+
+class Q_GUI_EXPORT QVulkanWindow : public QWindow
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QVulkanWindow)
+
+public:
+ enum Flag {
+ PersistentResources = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ explicit QVulkanWindow(QWindow *parent = nullptr);
+ ~QVulkanWindow();
+
+ void setFlags(Flags flags);
+ Flags flags() const;
+
+ QVector<VkPhysicalDeviceProperties> availablePhysicalDevices();
+ void setPhysicalDeviceIndex(int idx);
+
+ QVulkanInfoVector<QVulkanExtension> supportedDeviceExtensions();
+ void setDeviceExtensions(const QByteArrayList &extensions);
+
+ void setPreferredColorFormats(const QVector<VkFormat> &formats);
+
+ QSet<int> supportedSampleCounts();
+ void setSampleCount(int sampleCount);
+
+ bool isValid() const;
+
+ virtual QVulkanWindowRenderer *createRenderer();
+ void frameReady();
+
+ VkPhysicalDevice physicalDevice() const;
+ const VkPhysicalDeviceProperties *physicalDeviceProperties() const;
+ VkDevice device() const;
+ VkQueue graphicsQueue() const;
+ VkCommandPool graphicsCommandPool() const;
+ uint32_t hostVisibleMemoryIndex() const;
+ uint32_t deviceLocalMemoryIndex() const;
+ VkRenderPass defaultRenderPass() const;
+
+ VkFormat colorFormat() const;
+ VkFormat depthStencilFormat() const;
+ QSize swapChainImageSize() const;
+
+ VkCommandBuffer currentCommandBuffer() const;
+ VkFramebuffer currentFramebuffer() const;
+ int currentFrame() const;
+
+ static const int MAX_CONCURRENT_FRAME_COUNT = 3;
+ int concurrentFrameCount() const;
+
+ int swapChainImageCount() const;
+ int currentSwapChainImageIndex() const;
+ VkImage swapChainImage(int idx) const;
+ VkImageView swapChainImageView(int idx) const;
+ VkImage depthStencilImage() const;
+ VkImageView depthStencilImageView() const;
+
+ VkSampleCountFlagBits sampleCountFlagBits() const;
+ VkImage msaaColorImage(int idx) const;
+ VkImageView msaaColorImageView(int idx) const;
+
+ bool supportsGrab() const;
+ QImage grab();
+
+ const QMatrix4x4 *clipCorrectionMatrix();
+
+Q_SIGNALS:
+ void frameGrabbed(const QImage &image);
+
+protected:
+ void exposeEvent(QExposeEvent *) override;
+ void resizeEvent(QResizeEvent *) override;
+ bool event(QEvent *) override;
+
+private:
+ Q_DISABLE_COPY(QVulkanWindow)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QVulkanWindow::Flags)
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(vulkan)
+
+#endif
diff --git a/src/gui/vulkan/qvulkanwindow_p.h b/src/gui/vulkan/qvulkanwindow_p.h
new file mode 100644
index 0000000000..c6a772bc31
--- /dev/null
+++ b/src/gui/vulkan/qvulkanwindow_p.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVULKANWINDOW_P_H
+#define QVULKANWINDOW_P_H
+
+#include <QtGui/private/qtguiglobal_p.h>
+
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+
+#include "qvulkanwindow.h"
+#include <QtCore/QHash>
+#include <private/qwindow_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QVulkanWindowPrivate : public QWindowPrivate
+{
+ Q_DECLARE_PUBLIC(QVulkanWindow)
+
+public:
+ ~QVulkanWindowPrivate();
+
+ void ensureStarted();
+ void init();
+ void reset();
+ bool createDefaultRenderPass();
+ void recreateSwapChain();
+ uint32_t chooseTransientImageMemType(VkImage img, uint32_t startIndex);
+ bool createTransientImage(VkFormat format, VkImageUsageFlags usage, VkImageAspectFlags aspectMask,
+ VkImage *images, VkDeviceMemory *mem, VkImageView *views, int count);
+ void releaseSwapChain();
+ void beginFrame();
+ void endFrame();
+ bool checkDeviceLost(VkResult err);
+ void addReadback();
+ void finishBlockingReadback();
+
+ enum Status {
+ StatusUninitialized,
+ StatusFail,
+ StatusFailRetry,
+ StatusDeviceReady,
+ StatusReady
+ };
+ Status status = StatusUninitialized;
+ QVulkanWindowRenderer *renderer = nullptr;
+ QVulkanInstance *inst = nullptr;
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
+ int physDevIndex = 0;
+ QVector<VkPhysicalDevice> physDevs;
+ QVector<VkPhysicalDeviceProperties> physDevProps;
+ QVulkanWindow::Flags flags = 0;
+ QByteArrayList requestedDevExtensions;
+ QHash<VkPhysicalDevice, QVulkanInfoVector<QVulkanExtension> > supportedDevExtensions;
+ QVector<VkFormat> requestedColorFormats;
+ VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
+
+ VkDevice dev = VK_NULL_HANDLE;
+ QVulkanDeviceFunctions *devFuncs;
+ uint32_t gfxQueueFamilyIdx;
+ uint32_t presQueueFamilyIdx;
+ VkQueue gfxQueue;
+ VkQueue presQueue;
+ VkCommandPool cmdPool = VK_NULL_HANDLE;
+ VkCommandPool presCmdPool = VK_NULL_HANDLE;
+ uint32_t hostVisibleMemIndex;
+ uint32_t deviceLocalMemIndex;
+ VkFormat colorFormat;
+ VkColorSpaceKHR colorSpace;
+ VkFormat dsFormat = VK_FORMAT_D24_UNORM_S8_UINT;
+
+ PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
+ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+ PFN_vkQueuePresentKHR vkQueuePresentKHR;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
+
+ static const int MAX_SWAPCHAIN_BUFFER_COUNT = 3;
+ static const int MAX_FRAME_LAG = QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT;
+ // QVulkanWindow only supports the always available FIFO mode. The
+ // rendering thread will get throttled to the presentation rate (vsync).
+ // This is in effect Example 5 from the VK_KHR_swapchain spec.
+ VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ int swapChainBufferCount = 2;
+ int frameLag = 2;
+
+ QSize swapChainImageSize;
+ VkSwapchainKHR swapChain = VK_NULL_HANDLE;
+ bool swapChainSupportsReadBack = false;
+
+ struct ImageResources {
+ VkImage image = VK_NULL_HANDLE;
+ VkImageView imageView = VK_NULL_HANDLE;
+ VkCommandBuffer cmdBuf = VK_NULL_HANDLE;
+ VkFence cmdFence = VK_NULL_HANDLE;
+ bool cmdFenceWaitable = false;
+ VkFramebuffer fb = VK_NULL_HANDLE;
+ VkCommandBuffer presTransCmdBuf = VK_NULL_HANDLE;
+ VkImage msaaImage = VK_NULL_HANDLE;
+ VkImageView msaaImageView = VK_NULL_HANDLE;
+ } imageRes[MAX_SWAPCHAIN_BUFFER_COUNT];
+
+ VkDeviceMemory msaaImageMem = VK_NULL_HANDLE;
+
+ uint32_t currentImage;
+
+ struct FrameResources {
+ VkFence fence = VK_NULL_HANDLE;
+ bool fenceWaitable = false;
+ VkSemaphore imageSem = VK_NULL_HANDLE;
+ VkSemaphore drawSem = VK_NULL_HANDLE;
+ VkSemaphore presTransSem = VK_NULL_HANDLE;
+ bool imageAcquired = false;
+ bool imageSemWaitable = false;
+ } frameRes[MAX_FRAME_LAG];
+
+ uint32_t currentFrame;
+
+ VkRenderPass defaultRenderPass = VK_NULL_HANDLE;
+
+ VkDeviceMemory dsMem = VK_NULL_HANDLE;
+ VkImage dsImage = VK_NULL_HANDLE;
+ VkImageView dsView = VK_NULL_HANDLE;
+
+ bool framePending = false;
+ bool frameGrabbing = false;
+ QImage frameGrabTargetImage;
+ VkImage frameGrabImage = VK_NULL_HANDLE;
+ VkDeviceMemory frameGrabImageMem = VK_NULL_HANDLE;
+
+ QMatrix4x4 m_clipCorrect;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(vulkan)
+
+#endif
diff --git a/src/gui/vulkan/vk.xml b/src/gui/vulkan/vk.xml
new file mode 100644
index 0000000000..779875b819
--- /dev/null
+++ b/src/gui/vulkan/vk.xml
@@ -0,0 +1,5269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<registry>
+ <comment>
+Copyright (c) 2015-2017 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+------------------------------------------------------------------------
+
+This file, vk.xml, is the Vulkan API Registry. It is a critically important
+and normative part of the Vulkan Specification, including a canonical
+machine-readable definition of the API, parameter and member validation
+language incorporated into the Specification and reference pages, and other
+material which is registered by Khronos, such as tags used by extension and
+layer authors. The only authoritative version of vk.xml is the one
+maintained in the master branch of the Khronos Vulkan GitHub project.
+ </comment>
+
+ <!-- SECTION: Vulkan vendor IDs for physical devices without PCI vendor IDs -->
+ <vendorids>
+ <vendorid name="KHR" id="0x10000" comment="This is the next available Khronos vendor ID"/>
+ <vendorid name="VIV" id="0x10001" comment="Vivante vendor ID"/>
+ <vendorid name="VSI" id="0x10002" comment="VeriSilicon vendor ID"/>
+ </vendorids>
+
+ <!-- SECTION: Vulkan vendor/author tags for extensions and layers -->
+ <tags>
+ <tag name="IMG" author="Imagination Technologies" contact="Michael Worcester @michaelworcester"/>
+ <tag name="AMD" author="Advanced Micro Devices, Inc." contact="Daniel Rakos @aqnuep"/>
+ <tag name="ARM" author="ARM Limited" contact="Jan-Harald Fredriksen @janharald"/>
+ <tag name="FSL" author="Freescale Semiconductor, Inc." contact="Norbert Nopper @FslNopper"/>
+ <tag name="BRCM" author="Broadcom Corporation" contact="Graeme Leese @gnl21"/>
+ <tag name="NXP" author="NXP Semiconductors N.V." contact="Norbert Nopper @FslNopper"/>
+ <tag name="NV" author="NVIDIA Corporation" contact="Daniel Koch @dgkoch"/>
+ <tag name="NVX" author="NVIDIA Corporation" contact="Daniel Koch @dgkoch"/>
+ <tag name="VIV" author="Vivante Corporation" contact="Yanjun Zhang @yanjunzhang"/>
+ <tag name="VSI" author="VeriSilicon Holdings Co., Ltd." contact="Yanjun Zhang @yanjunzhang"/>
+ <tag name="KDAB" author="KDAB" contact="Sean Harmer @seanharmer"/>
+ <tag name="ANDROID" author="Google, Inc." contact="Jesse Hall @jessehall"/>
+ <tag name="CHROMIUM" author="Google, Inc." contact="Jesse Hall @jessehall"/>
+ <tag name="GOOGLE" author="Google, Inc." contact="Jesse Hall @jessehall"/>
+ <tag name="QCOM" author="Qualcomm Technologies, Inc." contact="Maurice Ribble @mribble"/>
+ <tag name="LUNARG" author="LunarG, Inc." contact="Karen Ghavam @KarenGhavam"/>
+ <tag name="SAMSUNG" author="Samsung Electronics Co., Ltd." contact="Alon Or-bach @alonorbach"/>
+ <tag name="SEC" author="Samsung Electronics Co., Ltd." contact="Alon Or-bach @alonorbach"/>
+ <tag name="TIZEN" author="Samsung Electronics Co., Ltd." contact="Alon Or-bach @alonorbach"/>
+ <tag name="RENDERDOC" author="RenderDoc (renderdoc.org)" contact="baldurk@baldurk.org"/>
+ <tag name="NN" author="Nintendo Co., Ltd." contact="Yasuhiro Yoshioka @yoshioka_yasuhiro"/>
+ </tags>
+
+ <!-- SECTION: Vulkan type definitions -->
+ <types>
+ <type name="vk_platform" category="include">#include "vk_platform.h"</type>
+ <!-- WSI extensions -->
+ <type category="include">#include "<name>vulkan.h</name>"</type>
+ <type category="include">#include &lt;<name>X11/Xlib.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>X11/extensions/Xrandr.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>android/native_window.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>mir_toolkit/client_types.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>wayland-client.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>windows.h</name>&gt;</type>
+ <type category="include">#include &lt;<name>xcb/xcb.h</name>&gt;</type>
+
+ <type requires="X11/Xlib.h" name="Display"/>
+ <type requires="X11/Xlib.h" name="VisualID"/>
+ <type requires="X11/Xlib.h" name="Window"/>
+ <type requires="X11/extensions/Xrandr.h" name="RROutput"/>
+ <type requires="android/native_window.h" name="ANativeWindow"/>
+ <type requires="mir_toolkit/client_types.h" name="MirConnection"/>
+ <type requires="mir_toolkit/client_types.h" name="MirSurface"/>
+ <type requires="wayland-client.h" name="wl_display"/>
+ <type requires="wayland-client.h" name="wl_surface"/>
+ <type requires="windows.h" name="HINSTANCE"/>
+ <type requires="windows.h" name="HWND"/>
+ <type requires="windows.h" name="HANDLE"/>
+ <type requires="windows.h" name="SECURITY_ATTRIBUTES"/>
+ <type requires="windows.h" name="DWORD"/>
+ <type requires="xcb/xcb.h" name="xcb_connection_t"/>
+ <type requires="xcb/xcb.h" name="xcb_visualid_t"/>
+ <type requires="xcb/xcb.h" name="xcb_window_t"/>
+
+ <type category="define">#define <name>VK_MAKE_VERSION</name>(major, minor, patch) \
+ (((major) &lt;&lt; 22) | ((minor) &lt;&lt; 12) | (patch))</type>
+ <type category="define">#define <name>VK_VERSION_MAJOR</name>(version) ((uint32_t)(version) &gt;&gt; 22)</type>
+ <type category="define">#define <name>VK_VERSION_MINOR</name>(version) (((uint32_t)(version) &gt;&gt; 12) &amp; 0x3ff)</type>
+ <type category="define">#define <name>VK_VERSION_PATCH</name>(version) ((uint32_t)(version) &amp; 0xfff)</type>
+
+ <type category="define">// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead.
+//#define <name>VK_API_VERSION</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type> <!-- The patch version here should never be set to anything other than 0 -->
+ <type category="define">// Vulkan 1.0 version number
+#define <name>VK_API_VERSION_1_0</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type> <!-- The patch version here should never be set to anything other than 0 -->
+ <type category="define">// Version of this file
+#define <name>VK_HEADER_VERSION</name> 39</type>
+
+ <type category="define">
+#define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type>
+
+ <type category="define" name="VK_DEFINE_NON_DISPATCHABLE_HANDLE">
+#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
+#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) &amp;&amp; !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+#endif
+ </type>
+
+ <type category="define">
+#define <name>VK_NULL_HANDLE</name> 0
+ </type>
+
+ <type category="basetype">typedef <type>uint32_t</type> <name>VkSampleMask</name>;</type>
+ <type category="basetype">typedef <type>uint32_t</type> <name>VkBool32</name>;</type>
+ <type category="basetype">typedef <type>uint32_t</type> <name>VkFlags</name>;</type>
+ <type category="basetype">typedef <type>uint64_t</type> <name>VkDeviceSize</name>;</type>
+ <!-- Basic C types, pulled in via vk_platform.h -->
+ <type requires="vk_platform" name="void"/>
+ <type requires="vk_platform" name="char"/>
+ <type requires="vk_platform" name="float"/>
+ <type requires="vk_platform" name="uint8_t"/>
+ <type requires="vk_platform" name="uint32_t"/>
+ <type requires="vk_platform" name="uint64_t"/>
+ <type requires="vk_platform" name="int32_t"/>
+ <type requires="vk_platform" name="size_t"/>
+ <!-- Bitmask types -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkFramebufferCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkQueryPoolCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkRenderPassCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkSamplerCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineLayoutCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineCacheCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineDepthStencilStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineDynamicStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineColorBlendStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineMultisampleStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineRasterizationStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineViewportStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineTessellationStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineInputAssemblyStateCreateFlags</name>;</type><!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineVertexInputStateCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineShaderStageCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDescriptorSetLayoutCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkBufferViewCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkInstanceCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDeviceCreateFlags</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDeviceQueueCreateFlags</name>;</type> <!-- creation flags -->
+ <type requires="VkQueueFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueueFlags</name>;</type> <!-- Queue capabilities -->
+ <type requires="VkMemoryPropertyFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryPropertyFlags</name>;</type> <!-- Memory properties passed into vkAllocateMemory(). -->
+ <type requires="VkMemoryHeapFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryHeapFlags</name>;</type> <!-- Memory heap flags -->
+ <type requires="VkAccessFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkAccessFlags</name>;</type> <!-- Memory access flags passed to barrier/dependency operations -->
+ <type requires="VkBufferUsageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkBufferUsageFlags</name>;</type> <!-- Buffer usage flags -->
+ <type requires="VkBufferCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkBufferCreateFlags</name>;</type> <!-- Buffer creation flags -->
+ <type requires="VkShaderStageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkShaderStageFlags</name>;</type> <!-- Shader stage flags -->
+ <type requires="VkImageUsageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkImageUsageFlags</name>;</type> <!-- Image usage flags -->
+ <type requires="VkImageCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkImageCreateFlags</name>;</type> <!-- Image creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkImageViewCreateFlags</name>;</type> <!-- Image view creation flags (no bits yet) -->
+ <type requires="VkPipelineCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineCreateFlags</name>;</type> <!-- Pipeline creation flags -->
+ <type requires="VkColorComponentFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkColorComponentFlags</name>;</type> <!-- Color component flags -->
+ <type requires="VkFenceCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkFenceCreateFlags</name>;</type> <!-- Fence creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkSemaphoreCreateFlags</name>;</type> <!-- Semaphore creation flags -->
+ <type requires="VkFormatFeatureFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkFormatFeatureFlags</name>;</type> <!-- Format capability flags -->
+ <type requires="VkQueryControlFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueryControlFlags</name>;</type> <!-- Query control flags -->
+ <type requires="VkQueryResultFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueryResultFlags</name>;</type> <!-- Query result flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkShaderModuleCreateFlags</name>;</type> <!-- Shader module creation flags (no bits yet) -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkEventCreateFlags</name>;</type> <!-- Event creation flags (no bits yet) -->
+ <type requires="VkCommandPoolCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandPoolCreateFlags</name>;</type> <!-- Command pool creation flags -->
+ <type requires="VkCommandPoolResetFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandPoolResetFlags</name>;</type> <!-- Command pool reset flags -->
+ <type requires="VkCommandBufferResetFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandBufferResetFlags</name>;</type> <!-- Command buffer reset flags -->
+ <type requires="VkCommandBufferUsageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCommandBufferUsageFlags</name>;</type> <!-- Command buffer usage flags -->
+ <type requires="VkQueryPipelineStatisticFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueryPipelineStatisticFlags</name>;</type> <!-- Pipeline statistics flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryMapFlags</name>;</type> <!-- Memory mapping flags (no bits yet) -->
+ <type requires="VkImageAspectFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkImageAspectFlags</name>;</type> <!-- Bitmask of image aspects -->
+ <type requires="VkSparseMemoryBindFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkSparseMemoryBindFlags</name>;</type> <!-- Sparse memory bind flags -->
+ <type requires="VkSparseImageFormatFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkSparseImageFormatFlags</name>;</type> <!-- Sparse image memory requirements flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkSubpassDescriptionFlags</name>;</type> <!-- Subpass description flags -->
+ <type requires="VkPipelineStageFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineStageFlags</name>;</type> <!-- Pipeline stages -->
+ <type requires="VkSampleCountFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkSampleCountFlags</name>;</type> <!-- Pipeline stages -->
+ <type requires="VkAttachmentDescriptionFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkAttachmentDescriptionFlags</name>;</type> <!-- Render pass attachment description flags -->
+ <type requires="VkStencilFaceFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkStencilFaceFlags</name>;</type> <!-- Stencil face flags -->
+ <type requires="VkCullModeFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkCullModeFlags</name>;</type> <!-- Cull mode flags -->
+ <type requires="VkDescriptorPoolCreateFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkDescriptorPoolCreateFlags</name>;</type> <!-- Descriptor pool creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDescriptorPoolResetFlags</name>;</type> <!-- Descriptor pool reset flags -->
+ <type requires="VkDependencyFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkDependencyFlags</name>;</type> <!-- Pipeline barrier and subpass dependency flags -->
+
+ <type requires="VkIndirectCommandsLayoutUsageFlagBitsNVX" category="bitmask">typedef <type>VkFlags</type> <name>VkIndirectCommandsLayoutUsageFlagsNVX</name>;</type> <!-- Device generated commands usage flags -->
+ <type requires="VkObjectEntryUsageFlagBitsNVX" category="bitmask">typedef <type>VkFlags</type> <name>VkObjectEntryUsageFlagsNVX</name>;</type> <!-- Object usage flags -->
+
+ <!-- WSI extensions -->
+ <type requires="VkCompositeAlphaFlagBitsKHR" category="bitmask">typedef <type>VkFlags</type> <name>VkCompositeAlphaFlagsKHR</name>;</type>
+ <type requires="VkDisplayPlaneAlphaFlagBitsKHR" category="bitmask">typedef <type>VkFlags</type> <name>VkDisplayPlaneAlphaFlagsKHR</name>;</type>
+ <type requires="VkSurfaceTransformFlagBitsKHR" category="bitmask">typedef <type>VkFlags</type> <name>VkSurfaceTransformFlagsKHR</name>;</type>
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkSwapchainCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDisplayModeCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkDisplaySurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkAndroidSurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkMirSurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkViSurfaceCreateFlagsNN</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkWaylandSurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkWin32SurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkXlibSurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkXcbSurfaceCreateFlagsKHR</name>;</type> <!-- creation flags -->
+
+ <type requires="VkDebugReportFlagBitsEXT" category="bitmask">typedef <type>VkFlags</type> <name>VkDebugReportFlagsEXT</name>;</type>
+ <type category="bitmask">typedef <type>VkFlags</type> <name>VkCommandPoolTrimFlagsKHR</name>;</type>
+ <type requires="VkExternalMemoryHandleTypeFlagBitsNV" category="bitmask">typedef <type>VkFlags</type> <name>VkExternalMemoryHandleTypeFlagsNV</name>;</type>
+ <type requires="VkExternalMemoryFeatureFlagBitsNV" category="bitmask">typedef <type>VkFlags</type> <name>VkExternalMemoryFeatureFlagsNV</name>;</type>
+ <type requires="VkSurfaceCounterFlagBitsEXT" category="bitmask">typedef <type>VkFlags</type> <name>VkSurfaceCounterFlagsEXT</name>;</type>
+
+ <!-- Types which can be void pointers or class pointers, selected at compile time -->
+ <type category="handle"><type>VK_DEFINE_HANDLE</type>(<name>VkInstance</name>)</type>
+ <type category="handle" parent="VkInstance"><type>VK_DEFINE_HANDLE</type>(<name>VkPhysicalDevice</name>)</type>
+ <type category="handle" parent="VkPhysicalDevice"><type>VK_DEFINE_HANDLE</type>(<name>VkDevice</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_HANDLE</type>(<name>VkQueue</name>)</type>
+ <type category="handle" parent="VkCommandPool"><type>VK_DEFINE_HANDLE</type>(<name>VkCommandBuffer</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDeviceMemory</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkCommandPool</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkBuffer</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkBufferView</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkImage</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkImageView</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkShaderModule</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkPipeline</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkPipelineLayout</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkSampler</name>)</type>
+ <type category="handle" parent="VkDescriptorPool"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDescriptorSet</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDescriptorSetLayout</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDescriptorPool</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkFence</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkSemaphore</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkEvent</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkQueryPool</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkFramebuffer</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkRenderPass</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkPipelineCache</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkObjectTableNVX</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkIndirectCommandsLayoutNVX</name>)</type>
+
+ <!-- WSI extensions -->
+ <type category="handle"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDisplayKHR</name>)</type>
+ <type category="handle" parent="VkPhysicalDevice,VkDisplayKHR"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDisplayModeKHR</name>)</type>
+ <type category="handle" parent="VkInstance"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkSurfaceKHR</name>)</type>
+ <type category="handle" parent="VkSurfaceKHR"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkSwapchainKHR</name>)</type>
+ <type category="handle" parent="VkInstance"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDebugReportCallbackEXT</name>)</type>
+
+ <!-- Types generated from corresponding <enums> tags below -->
+ <type name="VkAttachmentLoadOp" category="enum"/>
+ <type name="VkAttachmentStoreOp" category="enum"/>
+ <type name="VkBlendFactor" category="enum"/>
+ <type name="VkBlendOp" category="enum"/>
+ <type name="VkBorderColor" category="enum"/>
+ <type name="VkFramebufferCreateFlagBits" category="enum"/>
+ <type name="VkQueryPoolCreateFlagBits" category="enum"/>
+ <type name="VkRenderPassCreateFlagBits" category="enum"/>
+ <type name="VkSamplerCreateFlagBits" category="enum"/>
+ <type name="VkPipelineCacheHeaderVersion" category="enum"/>
+ <type name="VkPipelineLayoutCreateFlagBits" category="enum"/>
+ <type name="VkPipelineCacheCreateFlagBits" category="enum"/>
+ <type name="VkPipelineDepthStencilStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineDynamicStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineColorBlendStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineMultisampleStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineRasterizationStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineViewportStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineTessellationStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineInputAssemblyStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineVertexInputStateCreateFlagBits" category="enum"/>
+ <type name="VkPipelineShaderStageCreateFlagBits" category="enum"/>
+ <type name="VkDescriptorSetLayoutCreateFlagBits" category="enum"/>
+ <type name="VkBufferViewCreateFlagBits" category="enum"/>
+ <type name="VkInstanceCreateFlagBits" category="enum"/>
+ <type name="VkDeviceQueueCreateFlagBits" category="enum"/>
+ <type name="VkBufferCreateFlagBits" category="enum"/>
+ <type name="VkBufferUsageFlagBits" category="enum"/>
+ <type name="VkColorComponentFlagBits" category="enum"/>
+ <type name="VkComponentSwizzle" category="enum"/>
+ <type name="VkCommandPoolCreateFlagBits" category="enum"/>
+ <type name="VkCommandPoolResetFlagBits" category="enum"/>
+ <type name="VkCommandBufferResetFlagBits" category="enum"/>
+ <type name="VkCommandBufferLevel" category="enum"/>
+ <type name="VkCommandBufferUsageFlagBits" category="enum"/>
+ <type name="VkCompareOp" category="enum"/>
+ <type name="VkCullModeFlagBits" category="enum"/>
+ <type name="VkDescriptorType" category="enum"/>
+ <type name="VkDeviceCreateFlagBits" category="enum"/>
+ <type name="VkDynamicState" category="enum"/>
+ <type name="VkFenceCreateFlagBits" category="enum"/>
+ <type name="VkPolygonMode" category="enum"/>
+ <type name="VkFormat" category="enum"/>
+ <type name="VkFormatFeatureFlagBits" category="enum"/>
+ <type name="VkFrontFace" category="enum"/>
+ <type name="VkImageAspectFlagBits" category="enum"/>
+ <type name="VkImageCreateFlagBits" category="enum"/>
+ <type name="VkImageLayout" category="enum"/>
+ <type name="VkImageTiling" category="enum"/>
+ <type name="VkImageType" category="enum"/>
+ <type name="VkImageUsageFlagBits" category="enum"/>
+ <type name="VkImageViewType" category="enum"/>
+ <type name="VkSharingMode" category="enum"/>
+ <type name="VkIndexType" category="enum"/>
+ <type name="VkLogicOp" category="enum"/>
+ <type name="VkMemoryHeapFlagBits" category="enum"/>
+ <type name="VkAccessFlagBits" category="enum"/>
+ <type name="VkMemoryPropertyFlagBits" category="enum"/>
+ <type name="VkPhysicalDeviceType" category="enum"/>
+ <type name="VkPipelineBindPoint" category="enum"/>
+ <type name="VkPipelineCreateFlagBits" category="enum"/>
+ <type name="VkPrimitiveTopology" category="enum"/>
+ <type name="VkQueryControlFlagBits" category="enum"/>
+ <type name="VkQueryPipelineStatisticFlagBits" category="enum"/>
+ <type name="VkQueryResultFlagBits" category="enum"/>
+ <type name="VkQueryType" category="enum"/>
+ <type name="VkQueueFlagBits" category="enum"/>
+ <type name="VkSubpassContents" category="enum"/>
+ <type name="VkResult" category="enum"/>
+ <type name="VkShaderStageFlagBits" category="enum"/>
+ <type name="VkSparseMemoryBindFlagBits" category="enum"/>
+ <type name="VkStencilFaceFlagBits" category="enum"/>
+ <type name="VkStencilOp" category="enum"/>
+ <type name="VkStructureType" category="enum"/>
+ <type name="VkSystemAllocationScope" category="enum"/>
+ <type name="VkInternalAllocationType" category="enum"/>
+ <type name="VkSamplerAddressMode" category="enum"/>
+ <type name="VkFilter" category="enum"/>
+ <type name="VkSamplerMipmapMode" category="enum"/>
+ <type name="VkVertexInputRate" category="enum"/>
+ <type name="VkPipelineStageFlagBits" category="enum"/>
+ <type name="VkSparseImageFormatFlagBits" category="enum"/>
+ <type name="VkSampleCountFlagBits" category="enum"/>
+ <type name="VkAttachmentDescriptionFlagBits" category="enum"/>
+ <type name="VkDescriptorPoolCreateFlagBits" category="enum"/>
+ <type name="VkDependencyFlagBits" category="enum"/>
+ <type name="VkIndirectCommandsLayoutUsageFlagBitsNVX" category="enum"/>
+ <type name="VkIndirectCommandsTokenTypeNVX" category="enum"/>
+ <type name="VkObjectEntryUsageFlagBitsNVX" category="enum"/>
+ <type name="VkObjectEntryTypeNVX" category="enum"/>
+ <!-- WSI extensions -->
+ <type name="VkColorSpaceKHR" category="enum"/>
+ <type name="VkCompositeAlphaFlagBitsKHR" category="enum"/>
+ <type name="VkDisplayPlaneAlphaFlagBitsKHR" category="enum"/>
+ <type name="VkPresentModeKHR" category="enum"/>
+ <type name="VkSurfaceTransformFlagBitsKHR" category="enum"/>
+ <type name="VkDebugReportFlagBitsEXT" category="enum"/>
+ <type name="VkDebugReportObjectTypeEXT" category="enum"/>
+ <type name="VkDebugReportErrorEXT" category="enum"/>
+ <type name="VkRasterizationOrderAMD" category="enum"/>
+ <type name="VkExternalMemoryHandleTypeFlagBitsNV" category="enum"/>
+ <type name="VkExternalMemoryFeatureFlagBitsNV" category="enum"/>
+ <type name="VkValidationCheckEXT" category="enum"/>
+ <type name="VkSurfaceCounterFlagBitsEXT" category="enum"/>
+ <type name="VkDisplayPowerStateEXT" category="enum"/>
+ <type name="VkDeviceEventTypeEXT" category="enum"/>
+ <type name="VkDisplayEventTypeEXT" category="enum"/>
+
+ <!-- The PFN_vk*Function types are used by VkAllocationCallbacks below -->
+ <type category="funcpointer">typedef void (VKAPI_PTR *<name>PFN_vkInternalAllocationNotification</name>)(
+ <type>void</type>* pUserData,
+ <type>size_t</type> size,
+ <type>VkInternalAllocationType</type> allocationType,
+ <type>VkSystemAllocationScope</type> allocationScope);</type>
+ <type category="funcpointer">typedef void (VKAPI_PTR *<name>PFN_vkInternalFreeNotification</name>)(
+ <type>void</type>* pUserData,
+ <type>size_t</type> size,
+ <type>VkInternalAllocationType</type> allocationType,
+ <type>VkSystemAllocationScope</type> allocationScope);</type>
+ <type category="funcpointer">typedef void* (VKAPI_PTR *<name>PFN_vkReallocationFunction</name>)(
+ <type>void</type>* pUserData,
+ <type>void</type>* pOriginal,
+ <type>size_t</type> size,
+ <type>size_t</type> alignment,
+ <type>VkSystemAllocationScope</type> allocationScope);</type>
+ <type category="funcpointer">typedef void* (VKAPI_PTR *<name>PFN_vkAllocationFunction</name>)(
+ <type>void</type>* pUserData,
+ <type>size_t</type> size,
+ <type>size_t</type> alignment,
+ <type>VkSystemAllocationScope</type> allocationScope);</type>
+ <type category="funcpointer">typedef void (VKAPI_PTR *<name>PFN_vkFreeFunction</name>)(
+ <type>void</type>* pUserData,
+ <type>void</type>* pMemory);</type>
+
+ <!-- The PFN_vkVoidFunction type are used by VkGet*ProcAddr below -->
+ <type category="funcpointer">typedef void (VKAPI_PTR *<name>PFN_vkVoidFunction</name>)(void);</type>
+
+ <!-- The PFN_vkDebugReportCallbackEXT type are used by the DEBUG_REPORT extension-->
+ <type category="funcpointer">typedef VkBool32 (VKAPI_PTR *<name>PFN_vkDebugReportCallbackEXT</name>)(
+ <type>VkDebugReportFlagsEXT</type> flags,
+ <type>VkDebugReportObjectTypeEXT</type> objectType,
+ <type>uint64_t</type> object,
+ <type>size_t</type> location,
+ <type>int32_t</type> messageCode,
+ const <type>char</type>* pLayerPrefix,
+ const <type>char</type>* pMessage,
+ <type>void</type>* pUserData);</type>
+
+ <!-- Struct types -->
+ <type category="struct" name="VkOffset2D">
+ <member><type>int32_t</type> <name>x</name></member>
+ <member><type>int32_t</type> <name>y</name></member>
+ </type>
+ <type category="struct" name="VkOffset3D">
+ <member><type>int32_t</type> <name>x</name></member>
+ <member><type>int32_t</type> <name>y</name></member>
+ <member><type>int32_t</type> <name>z</name></member>
+ </type>
+ <type category="struct" name="VkExtent2D">
+ <member><type>uint32_t</type> <name>width</name></member>
+ <member><type>uint32_t</type> <name>height</name></member>
+ </type>
+ <type category="struct" name="VkExtent3D">
+ <member><type>uint32_t</type> <name>width</name></member>
+ <member><type>uint32_t</type> <name>height</name></member>
+ <member><type>uint32_t</type> <name>depth</name></member>
+ </type>
+ <type category="struct" name="VkViewport">
+ <member><type>float</type> <name>x</name></member>
+ <member><type>float</type> <name>y</name></member>
+ <member><type>float</type> <name>width</name></member>
+ <member><type>float</type> <name>height</name></member>
+ <member><type>float</type> <name>minDepth</name></member>
+ <member><type>float</type> <name>maxDepth</name></member>
+ </type>
+ <type category="struct" name="VkRect2D">
+ <member><type>VkOffset2D</type> <name>offset</name></member>
+ <member><type>VkExtent2D</type> <name>extent</name></member>
+ </type>
+ <type category="struct" name="VkRect3D">
+ <member><type>VkOffset3D</type> <name>offset</name></member>
+ <member><type>VkExtent3D</type> <name>extent</name></member>
+ </type>
+ <type category="struct" name="VkClearRect">
+ <member><type>VkRect2D</type> <name>rect</name></member>
+ <member><type>uint32_t</type> <name>baseArrayLayer</name></member>
+ <member><type>uint32_t</type> <name>layerCount</name></member>
+ </type>
+ <type category="struct" name="VkComponentMapping">
+ <member><type>VkComponentSwizzle</type> <name>r</name></member>
+ <member><type>VkComponentSwizzle</type> <name>g</name></member>
+ <member><type>VkComponentSwizzle</type> <name>b</name></member>
+ <member><type>VkComponentSwizzle</type> <name>a</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceProperties" returnedonly="true">
+ <member><type>uint32_t</type> <name>apiVersion</name></member>
+ <member><type>uint32_t</type> <name>driverVersion</name></member>
+ <member><type>uint32_t</type> <name>vendorID</name></member>
+ <member><type>uint32_t</type> <name>deviceID</name></member>
+ <member><type>VkPhysicalDeviceType</type> <name>deviceType</name></member>
+ <member><type>char</type> <name>deviceName</name>[<enum>VK_MAX_PHYSICAL_DEVICE_NAME_SIZE</enum>]</member>
+ <member><type>uint8_t</type> <name>pipelineCacheUUID</name>[<enum>VK_UUID_SIZE</enum>]</member>
+ <member><type>VkPhysicalDeviceLimits</type> <name>limits</name></member>
+ <member><type>VkPhysicalDeviceSparseProperties</type> <name>sparseProperties</name></member>
+ </type>
+ <type category="struct" name="VkExtensionProperties" returnedonly="true">
+ <member><type>char</type> <name>extensionName</name>[<enum>VK_MAX_EXTENSION_NAME_SIZE</enum>]</member> <!-- extension name -->
+ <member><type>uint32_t</type> <name>specVersion</name></member> <!-- version of the extension specification implemented -->
+ </type>
+ <type category="struct" name="VkLayerProperties" returnedonly="true">
+ <member><type>char</type> <name>layerName</name>[<enum>VK_MAX_EXTENSION_NAME_SIZE</enum>]</member> <!-- layer name -->
+ <member><type>uint32_t</type> <name>specVersion</name></member> <!-- version of the layer specification implemented -->
+ <member><type>uint32_t</type> <name>implementationVersion</name></member> <!-- build or release version of the layer's library -->
+ <member><type>char</type> <name>description</name>[<enum>VK_MAX_DESCRIPTION_SIZE</enum>]</member> <!-- Free-form description of the layer -->
+ </type>
+ <type category="struct" name="VkApplicationInfo">
+ <member values="VK_STRUCTURE_TYPE_APPLICATION_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true" len="null-terminated">const <type>char</type>* <name>pApplicationName</name></member>
+ <member><type>uint32_t</type> <name>applicationVersion</name></member>
+ <member optional="true" len="null-terminated">const <type>char</type>* <name>pEngineName</name></member>
+ <member><type>uint32_t</type> <name>engineVersion</name></member>
+ <member><type>uint32_t</type> <name>apiVersion</name></member>
+ </type>
+ <type category="struct" name="VkAllocationCallbacks">
+ <member optional="true"><type>void</type>* <name>pUserData</name></member>
+ <member><type>PFN_vkAllocationFunction</type> <name>pfnAllocation</name></member>
+ <member><type>PFN_vkReallocationFunction</type> <name>pfnReallocation</name></member>
+ <member><type>PFN_vkFreeFunction</type> <name>pfnFree</name></member>
+ <member optional="true"><type>PFN_vkInternalAllocationNotification</type> <name>pfnInternalAllocation</name></member>
+ <member optional="true"><type>PFN_vkInternalFreeNotification</type> <name>pfnInternalFree</name></member>
+ </type>
+ <type category="struct" name="VkDeviceQueueCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDeviceQueueCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>uint32_t</type> <name>queueFamilyIndex</name></member>
+ <member><type>uint32_t</type> <name>queueCount</name></member>
+ <member len="queueCount">const <type>float</type>* <name>pQueuePriorities</name></member>
+ </type>
+ <type category="struct" name="VkDeviceCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkPhysicalDeviceFeatures2KHR">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDeviceCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>uint32_t</type> <name>queueCreateInfoCount</name></member>
+ <member len="queueCreateInfoCount">const <type>VkDeviceQueueCreateInfo</type>* <name>pQueueCreateInfos</name></member>
+ <member optional="true"><type>uint32_t</type> <name>enabledLayerCount</name></member>
+ <member len="enabledLayerCount,null-terminated">const <type>char</type>* const* <name>ppEnabledLayerNames</name></member> <!-- Ordered list of layer names to be enabled -->
+ <member optional="true"><type>uint32_t</type> <name>enabledExtensionCount</name></member>
+ <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const* <name>ppEnabledExtensionNames</name></member>
+ <member optional="true">const <type>VkPhysicalDeviceFeatures</type>* <name>pEnabledFeatures</name></member>
+ </type>
+ <type category="struct" name="VkInstanceCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkInstanceCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true">const <type>VkApplicationInfo</type>* <name>pApplicationInfo</name></member>
+ <member optional="true"><type>uint32_t</type> <name>enabledLayerCount</name></member>
+ <member len="enabledLayerCount,null-terminated">const <type>char</type>* const* <name>ppEnabledLayerNames</name></member> <!-- Ordered list of layer names to be enabled -->
+ <member optional="true"><type>uint32_t</type> <name>enabledExtensionCount</name></member>
+ <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const* <name>ppEnabledExtensionNames</name></member> <!-- Extension names to be enabled -->
+ </type>
+ <type category="struct" name="VkQueueFamilyProperties" returnedonly="true">
+ <member optional="true"><type>VkQueueFlags</type> <name>queueFlags</name></member> <!-- Queue flags -->
+ <member><type>uint32_t</type> <name>queueCount</name></member>
+ <member><type>uint32_t</type> <name>timestampValidBits</name></member>
+ <member><type>VkExtent3D</type> <name>minImageTransferGranularity</name></member> <!-- Minimum alignment requirement for image transfers -->
+ </type>
+ <type category="struct" name="VkPhysicalDeviceMemoryProperties" returnedonly="true">
+ <member><type>uint32_t</type> <name>memoryTypeCount</name></member>
+ <member><type>VkMemoryType</type> <name>memoryTypes</name>[<enum>VK_MAX_MEMORY_TYPES</enum>]</member>
+ <member><type>uint32_t</type> <name>memoryHeapCount</name></member>
+ <member><type>VkMemoryHeap</type> <name>memoryHeaps</name>[<enum>VK_MAX_MEMORY_HEAPS</enum>]</member>
+ </type>
+ <type category="struct" name="VkMemoryAllocateInfo">
+ <member values="VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkDedicatedAllocationMemoryAllocateInfoNV">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDeviceSize</type> <name>allocationSize</name></member> <!-- Size of memory allocation -->
+ <member><type>uint32_t</type> <name>memoryTypeIndex</name></member> <!-- Index of the of the memory type to allocate from -->
+ </type>
+ <type category="struct" name="VkMemoryRequirements" returnedonly="true">
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>alignment</name></member> <!-- Specified in bytes -->
+ <member><type>uint32_t</type> <name>memoryTypeBits</name></member> <!-- Bitmask of the allowed memory type indices into memoryTypes[] for this object -->
+ </type>
+ <type category="struct" name="VkSparseImageFormatProperties" returnedonly="true">
+ <member optional="true"><type>VkImageAspectFlags</type> <name>aspectMask</name></member>
+ <member><type>VkExtent3D</type> <name>imageGranularity</name></member>
+ <member optional="true"><type>VkSparseImageFormatFlags</type> <name>flags</name></member>
+ </type>
+ <type category="struct" name="VkSparseImageMemoryRequirements" returnedonly="true">
+ <member><type>VkSparseImageFormatProperties</type> <name>formatProperties</name></member>
+ <member><type>uint32_t</type> <name>imageMipTailFirstLod</name></member>
+ <member><type>VkDeviceSize</type> <name>imageMipTailSize</name></member> <!-- Specified in bytes, must be a multiple of sparse block size in bytes / alignment -->
+ <member><type>VkDeviceSize</type> <name>imageMipTailOffset</name></member> <!-- Specified in bytes, must be a multiple of sparse block size in bytes / alignment -->
+ <member><type>VkDeviceSize</type> <name>imageMipTailStride</name></member> <!-- Specified in bytes, must be a multiple of sparse block size in bytes / alignment -->
+ </type>
+ <type category="struct" name="VkMemoryType" returnedonly="true">
+ <member optional="true"><type>VkMemoryPropertyFlags</type> <name>propertyFlags</name></member> <!-- Memory properties of this memory type -->
+ <member><type>uint32_t</type> <name>heapIndex</name></member> <!-- Index of the memory heap allocations of this memory type are taken from -->
+ </type>
+ <type category="struct" name="VkMemoryHeap" returnedonly="true">
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Available memory in the heap-->
+ <member optional="true"><type>VkMemoryHeapFlags</type> <name>flags</name></member> <!-- Flags for the heap-->
+ </type>
+ <type category="struct" name="VkMappedMemoryRange">
+ <member values="VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDeviceMemory</type> <name>memory</name></member> <!-- Mapped memory object -->
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- Offset within the memory object where the range starts -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Size of the range within the memory object -->
+ </type>
+ <type category="struct" name="VkFormatProperties" returnedonly="true">
+ <member optional="true"><type>VkFormatFeatureFlags</type> <name>linearTilingFeatures</name></member> <!-- Format features in case of linear tiling -->
+ <member optional="true"><type>VkFormatFeatureFlags</type> <name>optimalTilingFeatures</name></member> <!-- Format features in case of optimal tiling -->
+ <member optional="true"><type>VkFormatFeatureFlags</type> <name>bufferFeatures</name></member> <!-- Format features supported by buffers -->
+ </type>
+ <type category="struct" name="VkImageFormatProperties" returnedonly="true">
+ <member><type>VkExtent3D</type> <name>maxExtent</name></member> <!-- max image dimensions for this resource type -->
+ <member><type>uint32_t</type> <name>maxMipLevels</name></member> <!-- max number of mipmap levels for this resource type -->
+ <member><type>uint32_t</type> <name>maxArrayLayers</name></member> <!-- max array size for this resource type -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>sampleCounts</name></member> <!-- supported sample counts for this resource type -->
+ <member><type>VkDeviceSize</type> <name>maxResourceSize</name></member> <!-- max size (in bytes) of this resource type -->
+ </type>
+ <type category="struct" name="VkDescriptorBufferInfo">
+ <member><type>VkBuffer</type> <name>buffer</name></member> <!-- Buffer used for this descriptor slot when the descriptor is UNIFORM_BUFFER[_DYNAMIC] or STORAGE_BUFFER[_DYNAMIC]. VK_NULL_HANDLE otherwise. -->
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- Base offset from buffer start in bytes to update in the descriptor set. -->
+ <member><type>VkDeviceSize</type> <name>range</name></member> <!-- Size in bytes of the buffer resource for this descriptor update. -->
+ </type>
+ <type category="struct" name="VkDescriptorImageInfo">
+ <member noautovalidity="true"><type>VkSampler</type> <name>sampler</name></member> <!-- Sampler to write to the descriptor in case it is a SAMPLER or COMBINED_IMAGE_SAMPLER descriptor. Ignored otherwise. -->
+ <member noautovalidity="true"><type>VkImageView</type> <name>imageView</name></member> <!-- Image view to write to the descriptor in case it is a SAMPLED_IMAGE, STORAGE_IMAGE, COMBINED_IMAGE_SAMPLER, or INPUT_ATTACHMENT descriptor. Ignored otherwise. -->
+ <member noautovalidity="true"><type>VkImageLayout</type> <name>imageLayout</name></member> <!-- Layout the image is expected to be in when accessed using this descriptor (only used if imageView is not VK_NULL_HANDLE). -->
+ </type>
+ <type category="struct" name="VkWriteDescriptorSet">
+ <member values="VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDescriptorSet</type> <name>dstSet</name></member> <!-- Destination descriptor set -->
+ <member><type>uint32_t</type> <name>dstBinding</name></member> <!-- Binding within the destination descriptor set to write -->
+ <member><type>uint32_t</type> <name>dstArrayElement</name></member> <!-- Array element within the destination binding to write -->
+ <member><type>uint32_t</type> <name>descriptorCount</name></member> <!-- Number of descriptors to write (determines the size of the array pointed by pDescriptors) -->
+ <member><type>VkDescriptorType</type> <name>descriptorType</name></member> <!-- Descriptor type to write (determines which members of the array pointed by pDescriptors are going to be used) -->
+ <member noautovalidity="true" len="descriptorCount">const <type>VkDescriptorImageInfo</type>* <name>pImageInfo</name></member> <!-- Sampler, image view, and layout for SAMPLER, COMBINED_IMAGE_SAMPLER, {SAMPLED,STORAGE}_IMAGE, and INPUT_ATTACHMENT descriptor types. -->
+ <member noautovalidity="true" len="descriptorCount">const <type>VkDescriptorBufferInfo</type>* <name>pBufferInfo</name></member> <!-- Raw buffer, size, and offset for {UNIFORM,STORAGE}_BUFFER[_DYNAMIC] descriptor types. -->
+ <member noautovalidity="true" len="descriptorCount">const <type>VkBufferView</type>* <name>pTexelBufferView</name></member> <!-- Buffer view to write to the descriptor for {UNIFORM,STORAGE}_TEXEL_BUFFER descriptor types. -->
+ </type>
+ <type category="struct" name="VkCopyDescriptorSet">
+ <member values="VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDescriptorSet</type> <name>srcSet</name></member> <!-- Source descriptor set -->
+ <member><type>uint32_t</type> <name>srcBinding</name></member> <!-- Binding within the source descriptor set to copy from -->
+ <member><type>uint32_t</type> <name>srcArrayElement</name></member> <!-- Array element within the source binding to copy from -->
+ <member><type>VkDescriptorSet</type> <name>dstSet</name></member> <!-- Destination descriptor set -->
+ <member><type>uint32_t</type> <name>dstBinding</name></member> <!-- Binding within the destination descriptor set to copy to -->
+ <member><type>uint32_t</type> <name>dstArrayElement</name></member> <!-- Array element within the destination binding to copy to -->
+ <member><type>uint32_t</type> <name>descriptorCount</name></member> <!-- Number of descriptors to write (determines the size of the array pointed by pDescriptors) -->
+ </type>
+ <type category="struct" name="VkBufferCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkDedicatedAllocationBufferCreateInfoNV">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkBufferCreateFlags</type> <name>flags</name></member> <!-- Buffer creation flags -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Specified in bytes -->
+ <member><type>VkBufferUsageFlags</type> <name>usage</name></member> <!-- Buffer usage flags -->
+ <member><type>VkSharingMode</type> <name>sharingMode</name></member>
+ <member optional="true"><type>uint32_t</type> <name>queueFamilyIndexCount</name></member>
+ <member noautovalidity="true" len="queueFamilyIndexCount">const <type>uint32_t</type>* <name>pQueueFamilyIndices</name></member>
+ </type>
+ <type category="struct" name="VkBufferViewCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkBufferViewCreateFlags</type><name>flags</name></member> <!-- Reserved -->
+ <member><type>VkBuffer</type> <name>buffer</name></member>
+ <member><type>VkFormat</type> <name>format</name></member> <!-- Optionally specifies format of elements -->
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>range</name></member> <!-- View size specified in bytes -->
+ </type>
+ <type category="struct" name="VkImageSubresource">
+ <member><type>VkImageAspectFlags</type> <name>aspectMask</name></member>
+ <member><type>uint32_t</type> <name>mipLevel</name></member>
+ <member><type>uint32_t</type> <name>arrayLayer</name></member>
+ </type>
+ <type category="struct" name="VkImageSubresourceLayers">
+ <member><type>VkImageAspectFlags</type> <name>aspectMask</name></member>
+ <member><type>uint32_t</type> <name>mipLevel</name></member>
+ <member><type>uint32_t</type> <name>baseArrayLayer</name></member>
+ <member><type>uint32_t</type> <name>layerCount</name></member>
+ </type>
+ <type category="struct" name="VkImageSubresourceRange">
+ <member><type>VkImageAspectFlags</type> <name>aspectMask</name></member>
+ <member><type>uint32_t</type> <name>baseMipLevel</name></member>
+ <member><type>uint32_t</type> <name>levelCount</name></member>
+ <member><type>uint32_t</type> <name>baseArrayLayer</name></member>
+ <member><type>uint32_t</type> <name>layerCount</name></member>
+ </type>
+ <type category="struct" name="VkMemoryBarrier">
+ <member values="VK_STRUCTURE_TYPE_MEMORY_BARRIER"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkAccessFlags</type> <name>srcAccessMask</name></member> <!-- Memory accesses from the source of the dependency to synchronize -->
+ <member optional="true"><type>VkAccessFlags</type> <name>dstAccessMask</name></member> <!-- Memory accesses from the destination of the dependency to synchronize -->
+ </type>
+ <type category="struct" name="VkBufferMemoryBarrier">
+ <member values="VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkAccessFlags</type> <name>srcAccessMask</name></member> <!-- Memory accesses from the source of the dependency to synchronize -->
+ <member optional="true"><type>VkAccessFlags</type> <name>dstAccessMask</name></member> <!-- Memory accesses from the destination of the dependency to synchronize -->
+ <member><type>uint32_t</type> <name>srcQueueFamilyIndex</name></member> <!-- Queue family to transition ownership from -->
+ <member><type>uint32_t</type> <name>dstQueueFamilyIndex</name></member> <!-- Queue family to transition ownership to -->
+ <member><type>VkBuffer</type> <name>buffer</name></member> <!-- Buffer to sync -->
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- Offset within the buffer to sync -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Amount of bytes to sync -->
+ </type>
+ <type category="struct" name="VkImageMemoryBarrier">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkAccessFlags</type> <name>srcAccessMask</name></member> <!-- Memory accesses from the source of the dependency to synchronize -->
+ <member optional="true"><type>VkAccessFlags</type> <name>dstAccessMask</name></member> <!-- Memory accesses from the destination of the dependency to synchronize -->
+ <member><type>VkImageLayout</type> <name>oldLayout</name></member> <!-- Current layout of the image -->
+ <member><type>VkImageLayout</type> <name>newLayout</name></member> <!-- New layout to transition the image to -->
+ <member><type>uint32_t</type> <name>srcQueueFamilyIndex</name></member> <!-- Queue family to transition ownership from -->
+ <member><type>uint32_t</type> <name>dstQueueFamilyIndex</name></member> <!-- Queue family to transition ownership to -->
+ <member><type>VkImage</type> <name>image</name></member> <!-- Image to sync -->
+ <member><type>VkImageSubresourceRange</type> <name>subresourceRange</name></member> <!-- Subresource range to sync -->
+ </type>
+ <type category="struct" name="VkImageCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkDedicatedAllocationImageCreateInfoNV">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>VkImageCreateFlags</type> <name>flags</name></member> <!-- Image creation flags -->
+ <member><type>VkImageType</type> <name>imageType</name></member>
+ <member><type>VkFormat</type> <name>format</name></member>
+ <member><type>VkExtent3D</type> <name>extent</name></member>
+ <member><type>uint32_t</type> <name>mipLevels</name></member>
+ <member><type>uint32_t</type> <name>arrayLayers</name></member>
+ <member><type>VkSampleCountFlagBits</type> <name>samples</name></member>
+ <member><type>VkImageTiling</type> <name>tiling</name></member>
+ <member><type>VkImageUsageFlags</type> <name>usage</name></member> <!-- Image usage flags -->
+ <member><type>VkSharingMode</type> <name>sharingMode</name></member> <!-- Cross-queue-family sharing mode -->
+ <member optional="true"><type>uint32_t</type> <name>queueFamilyIndexCount</name></member> <!-- Number of queue families to share across -->
+ <member noautovalidity="true" len="queueFamilyIndexCount">const <type>uint32_t</type>* <name>pQueueFamilyIndices</name></member> <!-- Array of queue family indices to share across -->
+ <member><type>VkImageLayout</type> <name>initialLayout</name></member> <!-- Initial image layout for all subresources -->
+ </type>
+ <type category="struct" name="VkSubresourceLayout" returnedonly="true">
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>rowPitch</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>arrayPitch</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>depthPitch</name></member> <!-- Specified in bytes -->
+ </type>
+ <type category="struct" name="VkImageViewCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkImageViewCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkImage</type> <name>image</name></member>
+ <member><type>VkImageViewType</type> <name>viewType</name></member>
+ <member><type>VkFormat</type> <name>format</name></member>
+ <member><type>VkComponentMapping</type> <name>components</name></member>
+ <member><type>VkImageSubresourceRange</type> <name>subresourceRange</name></member>
+ </type>
+ <type category="struct" name="VkBufferCopy">
+ <member><type>VkDeviceSize</type> <name>srcOffset</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>dstOffset</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Specified in bytes -->
+ </type>
+ <type category="struct" name="VkSparseMemoryBind">
+ <member><type>VkDeviceSize</type> <name>resourceOffset</name></member> <!-- Specified in bytes -->
+ <member><type>VkDeviceSize</type> <name>size</name></member> <!-- Specified in bytes -->
+ <member optional="true"><type>VkDeviceMemory</type> <name>memory</name></member>
+ <member><type>VkDeviceSize</type> <name>memoryOffset</name></member> <!-- Specified in bytes -->
+ <member optional="true"><type>VkSparseMemoryBindFlags</type><name>flags</name></member> <!-- Reserved for future -->
+ </type>
+ <type category="struct" name="VkSparseImageMemoryBind">
+ <member><type>VkImageSubresource</type> <name>subresource</name></member>
+ <member><type>VkOffset3D</type> <name>offset</name></member>
+ <member><type>VkExtent3D</type> <name>extent</name></member>
+ <member optional="true"><type>VkDeviceMemory</type> <name>memory</name></member>
+ <member><type>VkDeviceSize</type> <name>memoryOffset</name></member> <!-- Specified in bytes -->
+ <member optional="true"><type>VkSparseMemoryBindFlags</type><name>flags</name></member> <!-- Reserved for future -->
+ </type>
+ <type category="struct" name="VkSparseBufferMemoryBindInfo">
+ <member><type>VkBuffer</type> <name>buffer</name></member>
+ <member><type>uint32_t</type> <name>bindCount</name></member>
+ <member len="bindCount">const <type>VkSparseMemoryBind</type>* <name>pBinds</name></member>
+ </type>
+ <type category="struct" name="VkSparseImageOpaqueMemoryBindInfo">
+ <member><type>VkImage</type> <name>image</name></member>
+ <member><type>uint32_t</type> <name>bindCount</name></member>
+ <member len="bindCount">const <type>VkSparseMemoryBind</type>* <name>pBinds</name></member>
+ </type>
+ <type category="struct" name="VkSparseImageMemoryBindInfo">
+ <member><type>VkImage</type> <name>image</name></member>
+ <member><type>uint32_t</type> <name>bindCount</name></member>
+ <member len="bindCount">const <type>VkSparseImageMemoryBind</type>* <name>pBinds</name></member>
+ </type>
+ <type category="struct" name="VkBindSparseInfo">
+ <member values="VK_STRUCTURE_TYPE_BIND_SPARSE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure. -->
+ <member optional="true"><type>uint32_t</type> <name>waitSemaphoreCount</name></member>
+ <member len="waitSemaphoreCount">const <type>VkSemaphore</type>* <name>pWaitSemaphores</name></member>
+ <member optional="true"><type>uint32_t</type> <name>bufferBindCount</name></member>
+ <member len="bufferBindCount">const <type>VkSparseBufferMemoryBindInfo</type>* <name>pBufferBinds</name></member>
+ <member optional="true"><type>uint32_t</type> <name>imageOpaqueBindCount</name></member>
+ <member len="imageOpaqueBindCount">const <type>VkSparseImageOpaqueMemoryBindInfo</type>* <name>pImageOpaqueBinds</name></member>
+ <member optional="true"><type>uint32_t</type> <name>imageBindCount</name></member>
+ <member len="imageBindCount">const <type>VkSparseImageMemoryBindInfo</type>* <name>pImageBinds</name></member>
+ <member optional="true"><type>uint32_t</type> <name>signalSemaphoreCount</name></member>
+ <member len="signalSemaphoreCount">const <type>VkSemaphore</type>* <name>pSignalSemaphores</name></member>
+ </type>
+ <type category="struct" name="VkImageCopy">
+ <member><type>VkImageSubresourceLayers</type> <name>srcSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>srcOffset</name></member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ <member><type>VkImageSubresourceLayers</type> <name>dstSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>dstOffset</name></member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ <member><type>VkExtent3D</type> <name>extent</name></member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ </type>
+ <type category="struct" name="VkImageBlit">
+ <member><type>VkImageSubresourceLayers</type> <name>srcSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>srcOffsets</name>[2]</member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ <member><type>VkImageSubresourceLayers</type> <name>dstSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>dstOffsets</name>[2]</member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ </type>
+ <type category="struct" name="VkBufferImageCopy">
+ <member><type>VkDeviceSize</type> <name>bufferOffset</name></member> <!-- Specified in bytes -->
+ <member><type>uint32_t</type> <name>bufferRowLength</name></member> <!-- Specified in texels -->
+ <member><type>uint32_t</type> <name>bufferImageHeight</name></member>
+ <member><type>VkImageSubresourceLayers</type> <name>imageSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>imageOffset</name></member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ <member><type>VkExtent3D</type> <name>imageExtent</name></member> <!-- Specified in pixels for both compressed and uncompressed images -->
+ </type>
+ <type category="struct" name="VkImageResolve">
+ <member><type>VkImageSubresourceLayers</type> <name>srcSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>srcOffset</name></member>
+ <member><type>VkImageSubresourceLayers</type> <name>dstSubresource</name></member>
+ <member><type>VkOffset3D</type> <name>dstOffset</name></member>
+ <member><type>VkExtent3D</type> <name>extent</name></member>
+ </type>
+ <type category="struct" name="VkShaderModuleCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkShaderModuleCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>size_t</type> <name>codeSize</name></member> <!-- Specified in bytes -->
+ <member len="latexmath:[$codeSize \over 4$]">const <type>uint32_t</type>* <name>pCode</name></member> <!-- Binary code of size codeSize -->
+ </type>
+ <type category="struct" name="VkDescriptorSetLayoutBinding">
+ <member><type>uint32_t</type> <name>binding</name></member> <!-- Binding number for this entry -->
+ <member><type>VkDescriptorType</type> <name>descriptorType</name></member> <!-- Type of the descriptors in this binding -->
+ <member optional="true"><type>uint32_t</type> <name>descriptorCount</name></member> <!-- Number of descriptors in this binding -->
+ <member noautovalidity="true"><type>VkShaderStageFlags</type> <name>stageFlags</name></member> <!-- Shader stages this binding is visible to -->
+ <member noautovalidity="true" optional="true" len="descriptorCount">const <type>VkSampler</type>* <name>pImmutableSamplers</name></member> <!-- Immutable samplers (used if descriptor type is SAMPLER or COMBINED_IMAGE_SAMPLER, is either NULL or contains count number of elements) -->
+ </type>
+ <type category="struct" name="VkDescriptorSetLayoutCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDescriptorSetLayoutCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true"><type>uint32_t</type> <name>bindingCount</name></member> <!-- Number of bindings in the descriptor set layout -->
+ <member len="bindingCount">const <type>VkDescriptorSetLayoutBinding</type>* <name>pBindings</name></member> <!-- Array of descriptor set layout bindings -->
+ </type>
+ <type category="struct" name="VkDescriptorPoolSize">
+ <member><type>VkDescriptorType</type> <name>type</name></member>
+ <member><type>uint32_t</type> <name>descriptorCount</name></member>
+ </type>
+ <type category="struct" name="VkDescriptorPoolCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDescriptorPoolCreateFlags</type> <name>flags</name></member>
+ <member><type>uint32_t</type> <name>maxSets</name></member>
+ <member><type>uint32_t</type> <name>poolSizeCount</name></member>
+ <member len="poolSizeCount">const <type>VkDescriptorPoolSize</type>* <name>pPoolSizes</name></member>
+ </type>
+ <type category="struct" name="VkDescriptorSetAllocateInfo">
+ <member values="VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDescriptorPool</type> <name>descriptorPool</name></member>
+ <member><type>uint32_t</type> <name>descriptorSetCount</name></member>
+ <member len="descriptorSetCount">const <type>VkDescriptorSetLayout</type>* <name>pSetLayouts</name></member>
+ </type>
+ <type category="struct" name="VkSpecializationMapEntry">
+ <member><type>uint32_t</type> <name>constantID</name></member> <!-- The SpecConstant ID specified in the BIL -->
+ <member><type>uint32_t</type> <name>offset</name></member> <!-- Offset of the value in the data block -->
+ <member><type>size_t</type> <name>size</name></member> <!-- Size in bytes of the SpecConstant -->
+ </type>
+ <type category="struct" name="VkSpecializationInfo">
+ <member optional="true"><type>uint32_t</type> <name>mapEntryCount</name></member> <!-- Number of entries in the map -->
+ <member len="mapEntryCount" noautovalidity="true">const <type>VkSpecializationMapEntry</type>* <name>pMapEntries</name></member> <!-- Array of map entries -->
+ <member optional="true"><type>size_t</type> <name>dataSize</name></member> <!-- Size in bytes of pData -->
+ <member len="dataSize">const <type>void</type>* <name>pData</name></member> <!-- Pointer to SpecConstant data -->
+ </type>
+ <type category="struct" name="VkPipelineShaderStageCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineShaderStageCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkShaderStageFlagBits</type> <name>stage</name></member> <!-- Shader stage -->
+ <member><type>VkShaderModule</type> <name>module</name></member> <!-- Module containing entry point -->
+ <member len="null-terminated">const <type>char</type>* <name>pName</name></member> <!-- Null-terminated entry point name -->
+ <member optional="true">const <type>VkSpecializationInfo</type>* <name>pSpecializationInfo</name></member>
+ </type>
+ <type category="struct" name="VkComputePipelineCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineCreateFlags</type> <name>flags</name></member> <!-- Pipeline creation flags -->
+ <member><type>VkPipelineShaderStageCreateInfo</type> <name>stage</name></member>
+ <member><type>VkPipelineLayout</type> <name>layout</name></member> <!-- Interface layout of the pipeline -->
+ <member noautovalidity="true" optional="true"><type>VkPipeline</type> <name>basePipelineHandle</name></member> <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
+ <member><type>int32_t</type> <name>basePipelineIndex</name></member> <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
+ </type>
+ <type category="struct" name="VkVertexInputBindingDescription">
+ <member><type>uint32_t</type> <name>binding</name></member> <!-- Vertex buffer binding id -->
+ <member><type>uint32_t</type> <name>stride</name></member> <!-- Distance between vertices in bytes (0 = no advancement) -->
+ <member><type>VkVertexInputRate</type> <name>inputRate</name></member> <!-- The rate at which the vertex data is consumed -->
+ </type>
+ <type category="struct" name="VkVertexInputAttributeDescription">
+ <member><type>uint32_t</type> <name>location</name></member> <!-- location of the shader vertex attrib -->
+ <member><type>uint32_t</type> <name>binding</name></member> <!-- Vertex buffer binding id -->
+ <member><type>VkFormat</type> <name>format</name></member> <!-- format of source data -->
+ <member><type>uint32_t</type> <name>offset</name></member> <!-- Offset of first element in bytes from base of vertex -->
+ </type>
+ <type category="struct" name="VkPipelineVertexInputStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineVertexInputStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true"><type>uint32_t</type> <name>vertexBindingDescriptionCount</name></member> <!-- number of bindings -->
+ <member len="vertexBindingDescriptionCount">const <type>VkVertexInputBindingDescription</type>* <name>pVertexBindingDescriptions</name></member>
+ <member optional="true"><type>uint32_t</type> <name>vertexAttributeDescriptionCount</name></member> <!-- number of attributes -->
+ <member len="vertexAttributeDescriptionCount">const <type>VkVertexInputAttributeDescription</type>* <name>pVertexAttributeDescriptions</name></member>
+ </type>
+ <type category="struct" name="VkPipelineInputAssemblyStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineInputAssemblyStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkPrimitiveTopology</type> <name>topology</name></member>
+ <member><type>VkBool32</type> <name>primitiveRestartEnable</name></member>
+ </type>
+ <type category="struct" name="VkPipelineTessellationStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineTessellationStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>uint32_t</type> <name>patchControlPoints</name></member>
+ </type>
+ <type category="struct" name="VkPipelineViewportStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineViewportStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>uint32_t</type> <name>viewportCount</name></member>
+ <member noautovalidity="true" optional="true" len="viewportCount">const <type>VkViewport</type>* <name>pViewports</name></member>
+ <member><type>uint32_t</type> <name>scissorCount</name></member>
+ <member noautovalidity="true" optional="true" len="scissorCount">const <type>VkRect2D</type>* <name>pScissors</name></member>
+ </type>
+ <type category="struct" name="VkPipelineRasterizationStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkPipelineRasterizationStateRasterizationOrderAMD">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineRasterizationStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkBool32</type> <name>depthClampEnable</name></member>
+ <member><type>VkBool32</type> <name>rasterizerDiscardEnable</name></member>
+ <member><type>VkPolygonMode</type> <name>polygonMode</name></member> <!-- optional (GL45) -->
+ <member optional="true"><type>VkCullModeFlags</type> <name>cullMode</name></member>
+ <member><type>VkFrontFace</type> <name>frontFace</name></member>
+ <member><type>VkBool32</type> <name>depthBiasEnable</name></member>
+ <member><type>float</type> <name>depthBiasConstantFactor</name></member>
+ <member><type>float</type> <name>depthBiasClamp</name></member>
+ <member><type>float</type> <name>depthBiasSlopeFactor</name></member>
+ <member><type>float</type> <name>lineWidth</name></member>
+ </type>
+ <type category="struct" name="VkPipelineMultisampleStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineMultisampleStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkSampleCountFlagBits</type> <name>rasterizationSamples</name></member> <!-- Number of samples used for rasterization -->
+ <member><type>VkBool32</type> <name>sampleShadingEnable</name></member> <!-- optional (GL45) -->
+ <member><type>float</type> <name>minSampleShading</name></member> <!-- optional (GL45) -->
+ <member optional="true" len="latexmath:[$\lceil{\mathit{rasterizationSamples} \over 32}\rceil$]">const <type>VkSampleMask</type>* <name>pSampleMask</name></member> <!-- Array of sampleMask words -->
+ <member><type>VkBool32</type> <name>alphaToCoverageEnable</name></member>
+ <member><type>VkBool32</type> <name>alphaToOneEnable</name></member>
+ </type>
+ <type category="struct" name="VkPipelineColorBlendAttachmentState">
+ <member><type>VkBool32</type> <name>blendEnable</name></member>
+ <member><type>VkBlendFactor</type> <name>srcColorBlendFactor</name></member>
+ <member><type>VkBlendFactor</type> <name>dstColorBlendFactor</name></member>
+ <member><type>VkBlendOp</type> <name>colorBlendOp</name></member>
+ <member><type>VkBlendFactor</type> <name>srcAlphaBlendFactor</name></member>
+ <member><type>VkBlendFactor</type> <name>dstAlphaBlendFactor</name></member>
+ <member><type>VkBlendOp</type> <name>alphaBlendOp</name></member>
+ <member optional="true"><type>VkColorComponentFlags</type> <name>colorWriteMask</name></member>
+ </type>
+ <type category="struct" name="VkPipelineColorBlendStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineColorBlendStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkBool32</type> <name>logicOpEnable</name></member>
+ <member noautovalidity="true"><type>VkLogicOp</type> <name>logicOp</name></member>
+ <member optional="true"><type>uint32_t</type> <name>attachmentCount</name></member> <!-- # of pAttachments -->
+ <member len="attachmentCount">const <type>VkPipelineColorBlendAttachmentState</type>* <name>pAttachments</name></member>
+ <member><type>float</type> <name>blendConstants</name>[4]</member>
+ </type>
+ <type category="struct" name="VkPipelineDynamicStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineDynamicStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>uint32_t</type> <name>dynamicStateCount</name></member>
+ <member len="dynamicStateCount">const <type>VkDynamicState</type>* <name>pDynamicStates</name></member>
+ </type>
+ <type category="struct" name="VkStencilOpState">
+ <member><type>VkStencilOp</type> <name>failOp</name></member>
+ <member><type>VkStencilOp</type> <name>passOp</name></member>
+ <member><type>VkStencilOp</type> <name>depthFailOp</name></member>
+ <member><type>VkCompareOp</type> <name>compareOp</name></member>
+ <member><type>uint32_t</type> <name>compareMask</name></member>
+ <member><type>uint32_t</type> <name>writeMask</name></member>
+ <member><type>uint32_t</type> <name>reference</name></member>
+ </type>
+ <type category="struct" name="VkPipelineDepthStencilStateCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineDepthStencilStateCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkBool32</type> <name>depthTestEnable</name></member>
+ <member><type>VkBool32</type> <name>depthWriteEnable</name></member>
+ <member><type>VkCompareOp</type> <name>depthCompareOp</name></member>
+ <member><type>VkBool32</type> <name>depthBoundsTestEnable</name></member> <!-- optional (depth_bounds_test) -->
+ <member><type>VkBool32</type> <name>stencilTestEnable</name></member>
+ <member><type>VkStencilOpState</type> <name>front</name></member>
+ <member><type>VkStencilOpState</type> <name>back</name></member>
+ <member><type>float</type> <name>minDepthBounds</name></member>
+ <member><type>float</type> <name>maxDepthBounds</name></member>
+ </type>
+ <type category="struct" name="VkGraphicsPipelineCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineCreateFlags</type> <name>flags</name></member> <!-- Pipeline creation flags -->
+ <member><type>uint32_t</type> <name>stageCount</name></member>
+ <member len="stageCount">const <type>VkPipelineShaderStageCreateInfo</type>* <name>pStages</name></member> <!-- One entry for each active shader stage -->
+ <member>const <type>VkPipelineVertexInputStateCreateInfo</type>* <name>pVertexInputState</name></member>
+ <member>const <type>VkPipelineInputAssemblyStateCreateInfo</type>* <name>pInputAssemblyState</name></member>
+ <member noautovalidity="true" optional="true">const <type>VkPipelineTessellationStateCreateInfo</type>* <name>pTessellationState</name></member>
+ <member noautovalidity="true" optional="true">const <type>VkPipelineViewportStateCreateInfo</type>* <name>pViewportState</name></member>
+ <member>const <type>VkPipelineRasterizationStateCreateInfo</type>* <name>pRasterizationState</name></member>
+ <member noautovalidity="true" optional="true">const <type>VkPipelineMultisampleStateCreateInfo</type>* <name>pMultisampleState</name></member>
+ <member noautovalidity="true" optional="true">const <type>VkPipelineDepthStencilStateCreateInfo</type>* <name>pDepthStencilState</name></member>
+ <member noautovalidity="true" optional="true">const <type>VkPipelineColorBlendStateCreateInfo</type>* <name>pColorBlendState</name></member>
+ <member optional="true">const <type>VkPipelineDynamicStateCreateInfo</type>* <name>pDynamicState</name></member>
+ <member><type>VkPipelineLayout</type> <name>layout</name></member> <!-- Interface layout of the pipeline -->
+ <member><type>VkRenderPass</type> <name>renderPass</name></member>
+ <member><type>uint32_t</type> <name>subpass</name></member>
+ <member noautovalidity="true" optional="true"><type>VkPipeline</type> <name>basePipelineHandle</name></member> <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
+ <member><type>int32_t</type> <name>basePipelineIndex</name></member> <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
+ </type>
+ <type category="struct" name="VkPipelineCacheCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineCacheCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true"><type>size_t</type> <name>initialDataSize</name></member> <!-- Size of initial data to populate cache, in bytes -->
+ <member len="initialDataSize">const <type>void</type>* <name>pInitialData</name></member> <!-- Initial data to populate cache -->
+ </type>
+ <type category="struct" name="VkPushConstantRange">
+ <member><type>VkShaderStageFlags</type> <name>stageFlags</name></member> <!-- Which stages use the range -->
+ <member><type>uint32_t</type> <name>offset</name></member> <!-- Start of the range, in bytes -->
+ <member><type>uint32_t</type> <name>size</name></member> <!-- Size of the range, in bytes -->
+ </type>
+ <type category="struct" name="VkPipelineLayoutCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkPipelineLayoutCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true"><type>uint32_t</type> <name>setLayoutCount</name></member> <!-- Number of descriptor sets interfaced by the pipeline -->
+ <member len="setLayoutCount">const <type>VkDescriptorSetLayout</type>* <name>pSetLayouts</name></member> <!-- Array of setCount number of descriptor set layout objects defining the layout of the -->
+ <member optional="true"><type>uint32_t</type> <name>pushConstantRangeCount</name></member> <!-- Number of push-constant ranges used by the pipeline -->
+ <member len="pushConstantRangeCount">const <type>VkPushConstantRange</type>* <name>pPushConstantRanges</name></member> <!-- Array of pushConstantRangeCount number of ranges used by various shader stages -->
+ </type>
+ <type category="struct" name="VkSamplerCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkSamplerCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkFilter</type> <name>magFilter</name></member> <!-- Filter mode for magnification -->
+ <member><type>VkFilter</type> <name>minFilter</name></member> <!-- Filter mode for minifiation -->
+ <member><type>VkSamplerMipmapMode</type> <name>mipmapMode</name></member> <!-- Mipmap selection mode -->
+ <member><type>VkSamplerAddressMode</type> <name>addressModeU</name></member>
+ <member><type>VkSamplerAddressMode</type> <name>addressModeV</name></member>
+ <member><type>VkSamplerAddressMode</type> <name>addressModeW</name></member>
+ <member><type>float</type> <name>mipLodBias</name></member>
+ <member><type>VkBool32</type> <name>anisotropyEnable</name></member>
+ <member><type>float</type> <name>maxAnisotropy</name></member>
+ <member><type>VkBool32</type> <name>compareEnable</name></member>
+ <member noautovalidity="true"><type>VkCompareOp</type> <name>compareOp</name></member>
+ <member><type>float</type> <name>minLod</name></member>
+ <member><type>float</type> <name>maxLod</name></member>
+ <member noautovalidity="true"><type>VkBorderColor</type> <name>borderColor</name></member>
+ <member><type>VkBool32</type> <name>unnormalizedCoordinates</name></member>
+ </type>
+ <type category="struct" name="VkCommandPoolCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkCommandPoolCreateFlags</type> <name>flags</name></member> <!-- Command pool creation flags -->
+ <member><type>uint32_t</type> <name>queueFamilyIndex</name></member>
+ </type>
+ <type category="struct" name="VkCommandBufferAllocateInfo">
+ <member values="VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkCommandPool</type> <name>commandPool</name></member>
+ <member><type>VkCommandBufferLevel</type> <name>level</name></member>
+ <member><type>uint32_t</type> <name>commandBufferCount</name></member>
+ </type>
+ <type category="struct" name="VkCommandBufferInheritanceInfo">
+ <member values="VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true" noautovalidity="true"><type>VkRenderPass</type> <name>renderPass</name></member> <!-- Render pass for secondary command buffers -->
+ <member><type>uint32_t</type> <name>subpass</name></member>
+ <member optional="true" noautovalidity="true"><type>VkFramebuffer</type> <name>framebuffer</name></member> <!-- Framebuffer for secondary command buffers -->
+ <member><type>VkBool32</type> <name>occlusionQueryEnable</name></member> <!-- Whether this secondary command buffer may be executed during an occlusion query -->
+ <member optional="true" noautovalidity="true"><type>VkQueryControlFlags</type> <name>queryFlags</name></member> <!-- Query flags used by this secondary command buffer, if executed during an occlusion query -->
+ <member optional="true" noautovalidity="true"><type>VkQueryPipelineStatisticFlags</type> <name>pipelineStatistics</name></member> <!-- Pipeline statistics that may be counted for this secondary command buffer -->
+ </type>
+ <type category="struct" name="VkCommandBufferBeginInfo">
+ <member values="VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkCommandBufferUsageFlags</type> <name>flags</name></member> <!-- Command buffer usage flags -->
+ <member optional="true" noautovalidity="true">const <type>VkCommandBufferInheritanceInfo</type>* <name>pInheritanceInfo</name></member> <!-- Pointer to inheritance info for secondary command buffers -->
+ </type>
+ <type category="struct" name="VkRenderPassBeginInfo">
+ <member values="VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkRenderPass</type> <name>renderPass</name></member>
+ <member><type>VkFramebuffer</type> <name>framebuffer</name></member>
+ <member><type>VkRect2D</type> <name>renderArea</name></member>
+ <member optional="true"><type>uint32_t</type> <name>clearValueCount</name></member>
+ <member len="clearValueCount" noautovalidity="true">const <type>VkClearValue</type>* <name>pClearValues</name></member>
+ </type>
+ <type category="union" name="VkClearColorValue" comment="// Union allowing specification of floating point, integer, or unsigned integer color data. Actual value selected is based on image/attachment being cleared.">
+ <member><type>float</type> <name>float32</name>[4]</member>
+ <member><type>int32_t</type> <name>int32</name>[4]</member>
+ <member><type>uint32_t</type> <name>uint32</name>[4]</member>
+ </type>
+ <type category="struct" name="VkClearDepthStencilValue">
+ <member><type>float</type> <name>depth</name></member>
+ <member><type>uint32_t</type> <name>stencil</name></member>
+ </type>
+ <type category="union" name="VkClearValue" comment="// Union allowing specification of color or depth and stencil values. Actual value selected is based on attachment being cleared.">
+ <member><type>VkClearColorValue</type> <name>color</name></member>
+ <member><type>VkClearDepthStencilValue</type> <name>depthStencil</name></member>
+ </type>
+ <type category="struct" name="VkClearAttachment">
+ <member><type>VkImageAspectFlags</type> <name>aspectMask</name></member>
+ <member><type>uint32_t</type> <name>colorAttachment</name></member>
+ <member><type>VkClearValue</type> <name>clearValue</name></member>
+ </type>
+ <type category="struct" name="VkAttachmentDescription">
+ <member optional="true"><type>VkAttachmentDescriptionFlags</type> <name>flags</name></member>
+ <member><type>VkFormat</type> <name>format</name></member>
+ <member><type>VkSampleCountFlagBits</type> <name>samples</name></member>
+ <member><type>VkAttachmentLoadOp</type> <name>loadOp</name></member> <!-- Load operation for color or depth data -->
+ <member><type>VkAttachmentStoreOp</type> <name>storeOp</name></member> <!-- Store operation for color or depth data -->
+ <member><type>VkAttachmentLoadOp</type> <name>stencilLoadOp</name></member> <!-- Load operation for stencil data -->
+ <member><type>VkAttachmentStoreOp</type> <name>stencilStoreOp</name></member> <!-- Store operation for stencil data -->
+ <member><type>VkImageLayout</type> <name>initialLayout</name></member>
+ <member><type>VkImageLayout</type> <name>finalLayout</name></member>
+ </type>
+ <type category="struct" name="VkAttachmentReference">
+ <member><type>uint32_t</type> <name>attachment</name></member>
+ <member><type>VkImageLayout</type> <name>layout</name></member>
+ </type>
+ <type category="struct" name="VkSubpassDescription">
+ <member optional="true"><type>VkSubpassDescriptionFlags</type> <name>flags</name></member>
+ <member><type>VkPipelineBindPoint</type> <name>pipelineBindPoint</name></member> <!-- Must be VK_PIPELINE_BIND_POINT_GRAPHICS for now -->
+ <member optional="true"><type>uint32_t</type> <name>inputAttachmentCount</name></member>
+ <member len="inputAttachmentCount">const <type>VkAttachmentReference</type>* <name>pInputAttachments</name></member>
+ <member optional="true"><type>uint32_t</type> <name>colorAttachmentCount</name></member>
+ <member len="colorAttachmentCount">const <type>VkAttachmentReference</type>* <name>pColorAttachments</name></member>
+ <member optional="true" len="colorAttachmentCount">const <type>VkAttachmentReference</type>* <name>pResolveAttachments</name></member>
+ <member optional="true">const <type>VkAttachmentReference</type>* <name>pDepthStencilAttachment</name></member>
+ <member optional="true"><type>uint32_t</type> <name>preserveAttachmentCount</name></member>
+ <member len="preserveAttachmentCount">const <type>uint32_t</type>* <name>pPreserveAttachments</name></member>
+ </type>
+ <type category="struct" name="VkSubpassDependency">
+ <member><type>uint32_t</type> <name>srcSubpass</name></member>
+ <member><type>uint32_t</type> <name>dstSubpass</name></member>
+ <member><type>VkPipelineStageFlags</type> <name>srcStageMask</name></member>
+ <member><type>VkPipelineStageFlags</type> <name>dstStageMask</name></member>
+ <member optional="true"><type>VkAccessFlags</type> <name>srcAccessMask</name></member> <!-- Memory accesses from the source of the dependency to synchronize -->
+ <member optional="true"><type>VkAccessFlags</type> <name>dstAccessMask</name></member> <!-- Memory accesses from the destination of the dependency to synchronize -->
+ <member optional="true"><type>VkDependencyFlags</type> <name>dependencyFlags</name></member>
+ </type>
+ <type category="struct" name="VkRenderPassCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkRenderPassCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member optional="true"><type>uint32_t</type> <name>attachmentCount</name></member>
+ <member len="attachmentCount">const <type>VkAttachmentDescription</type>* <name>pAttachments</name></member>
+ <member><type>uint32_t</type> <name>subpassCount</name></member>
+ <member len="subpassCount">const <type>VkSubpassDescription</type>* <name>pSubpasses</name></member>
+ <member optional="true"><type>uint32_t</type> <name>dependencyCount</name></member>
+ <member len="dependencyCount">const <type>VkSubpassDependency</type>* <name>pDependencies</name></member>
+ </type>
+ <type category="struct" name="VkEventCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_EVENT_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkEventCreateFlags</type> <name>flags</name></member> <!-- Event creation flags -->
+ </type>
+ <type category="struct" name="VkFenceCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_FENCE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkFenceCreateFlags</type> <name>flags</name></member> <!-- Fence creation flags -->
+ </type>
+ <type category="struct" name="VkPhysicalDeviceFeatures">
+ <member><type>VkBool32</type> <name>robustBufferAccess</name></member> <!-- out of bounds buffer accesses are well defined -->
+ <member><type>VkBool32</type> <name>fullDrawIndexUint32</name></member> <!-- full 32-bit range of indices for indexed draw calls -->
+ <member><type>VkBool32</type> <name>imageCubeArray</name></member> <!-- image views which are arrays of cube maps -->
+ <member><type>VkBool32</type> <name>independentBlend</name></member> <!-- blending operations are controlled per-attachment -->
+ <member><type>VkBool32</type> <name>geometryShader</name></member> <!-- geometry stage -->
+ <member><type>VkBool32</type> <name>tessellationShader</name></member> <!-- tessellation control and evaluation stage -->
+ <member><type>VkBool32</type> <name>sampleRateShading</name></member> <!-- per-sample shading and interpolation -->
+ <member><type>VkBool32</type> <name>dualSrcBlend</name></member> <!-- blend operations which take two sources -->
+ <member><type>VkBool32</type> <name>logicOp</name></member> <!-- logic operations -->
+ <member><type>VkBool32</type> <name>multiDrawIndirect</name></member> <!-- multi draw indirect -->
+ <member><type>VkBool32</type> <name>drawIndirectFirstInstance</name></member> <!-- indirect draws can use non-zero firstInstance -->
+ <member><type>VkBool32</type> <name>depthClamp</name></member> <!-- depth clamping -->
+ <member><type>VkBool32</type> <name>depthBiasClamp</name></member> <!-- depth bias clamping -->
+ <member><type>VkBool32</type> <name>fillModeNonSolid</name></member> <!-- point and wireframe fill modes -->
+ <member><type>VkBool32</type> <name>depthBounds</name></member> <!-- depth bounds test -->
+ <member><type>VkBool32</type> <name>wideLines</name></member> <!-- lines with width greater than 1 -->
+ <member><type>VkBool32</type> <name>largePoints</name></member> <!-- points with size greater than 1 -->
+ <member><type>VkBool32</type> <name>alphaToOne</name></member> <!-- the fragment alpha component can be forced to maximum representable alpha value -->
+ <member><type>VkBool32</type> <name>multiViewport</name></member> <!-- viewport arrays -->
+ <member><type>VkBool32</type> <name>samplerAnisotropy</name></member> <!-- anisotropic sampler filtering -->
+ <member><type>VkBool32</type> <name>textureCompressionETC2</name></member> <!-- ETC texture compression formats -->
+ <member><type>VkBool32</type> <name>textureCompressionASTC_LDR</name></member> <!-- ASTC LDR texture compression formats -->
+ <member><type>VkBool32</type> <name>textureCompressionBC</name></member> <!-- BC1-7 texture compressed formats -->
+ <member><type>VkBool32</type> <name>occlusionQueryPrecise</name></member> <!-- precise occlusion queries returning actual sample counts -->
+ <member><type>VkBool32</type> <name>pipelineStatisticsQuery</name></member> <!-- pipeline statistics query -->
+ <member><type>VkBool32</type> <name>vertexPipelineStoresAndAtomics</name></member> <!-- stores and atomic ops on storage buffers and images are supported in vertex, tessellation, and geometry stages -->
+ <member><type>VkBool32</type> <name>fragmentStoresAndAtomics</name></member> <!-- stores and atomic ops on storage buffers and images are supported in the fragment stage -->
+ <member><type>VkBool32</type> <name>shaderTessellationAndGeometryPointSize</name></member><!-- tessellation and geometry stages can export point size -->
+ <member><type>VkBool32</type> <name>shaderImageGatherExtended</name></member> <!-- image gather with run-time values and independent offsets -->
+ <member><type>VkBool32</type> <name>shaderStorageImageExtendedFormats</name></member> <!-- the extended set of formats can be used for storage images -->
+ <member><type>VkBool32</type> <name>shaderStorageImageMultisample</name></member> <!-- multisample images can be used for storage images -->
+ <member><type>VkBool32</type> <name>shaderStorageImageReadWithoutFormat</name></member> <!-- read from storage image does not require format qualifier -->
+ <member><type>VkBool32</type> <name>shaderStorageImageWriteWithoutFormat</name></member> <!-- write to storage image does not require format qualifier -->
+ <member><type>VkBool32</type> <name>shaderUniformBufferArrayDynamicIndexing</name></member> <!-- arrays of uniform buffers can be accessed with dynamically uniform indices -->
+ <member><type>VkBool32</type> <name>shaderSampledImageArrayDynamicIndexing</name></member> <!-- arrays of sampled images can be accessed with dynamically uniform indices -->
+ <member><type>VkBool32</type> <name>shaderStorageBufferArrayDynamicIndexing</name></member> <!-- arrays of storage buffers can be accessed with dynamically uniform indices -->
+ <member><type>VkBool32</type> <name>shaderStorageImageArrayDynamicIndexing</name></member> <!-- arrays of storage images can be accessed with dynamically uniform indices -->
+ <member><type>VkBool32</type> <name>shaderClipDistance</name></member> <!-- clip distance in shaders -->
+ <member><type>VkBool32</type> <name>shaderCullDistance</name></member> <!-- cull distance in shaders -->
+ <member><type>VkBool32</type> <name>shaderFloat64</name></member> <!-- 64-bit floats (doubles) in shaders -->
+ <member><type>VkBool32</type> <name>shaderInt64</name></member> <!-- 64-bit integers in shaders -->
+ <member><type>VkBool32</type> <name>shaderInt16</name></member> <!-- 16-bit integers in shaders -->
+ <member><type>VkBool32</type> <name>shaderResourceResidency</name></member> <!-- shader can use texture operations that return resource residency information (requires sparseNonResident support) -->
+ <member><type>VkBool32</type> <name>shaderResourceMinLod</name></member> <!-- shader can use texture operations that specify minimum resource level of detail -->
+ <member><type>VkBool32</type> <name>sparseBinding</name></member> <!-- Sparse resources support: Resource memory can be managed at opaque page level rather than object level -->
+ <member><type>VkBool32</type> <name>sparseResidencyBuffer</name></member> <!-- Sparse resources support: GPU can access partially resident buffers -->
+ <member><type>VkBool32</type> <name>sparseResidencyImage2D</name></member> <!-- Sparse resources support: GPU can access partially resident 2D (non-MSAA non-depth/stencil) images -->
+ <member><type>VkBool32</type> <name>sparseResidencyImage3D</name></member> <!-- Sparse resources support: GPU can access partially resident 3D images -->
+ <member><type>VkBool32</type> <name>sparseResidency2Samples</name></member> <!-- Sparse resources support: GPU can access partially resident MSAA 2D images with 2 samples -->
+ <member><type>VkBool32</type> <name>sparseResidency4Samples</name></member> <!-- Sparse resources support: GPU can access partially resident MSAA 2D images with 4 samples -->
+ <member><type>VkBool32</type> <name>sparseResidency8Samples</name></member> <!-- Sparse resources support: GPU can access partially resident MSAA 2D images with 8 samples -->
+ <member><type>VkBool32</type> <name>sparseResidency16Samples</name></member> <!-- Sparse resources support: GPU can access partially resident MSAA 2D images with 16 samples -->
+ <member><type>VkBool32</type> <name>sparseResidencyAliased</name></member> <!-- Sparse resources support: GPU can correctly access data aliased into multiple locations (opt-in) -->
+ <member><type>VkBool32</type> <name>variableMultisampleRate</name></member> <!-- multisample rate must be the same for all pipelines in a subpass -->
+ <member><type>VkBool32</type> <name>inheritedQueries</name></member> <!-- Queries may be inherited from primary to secondary command buffers -->
+ </type>
+ <type category="struct" name="VkPhysicalDeviceSparseProperties" returnedonly="true">
+ <member><type>VkBool32</type> <name>residencyStandard2DBlockShape</name></member> <!-- Sparse resources support: GPU will access all 2D (single sample) sparse resources using the standard sparse image block shapes (based on pixel format) -->
+ <member><type>VkBool32</type> <name>residencyStandard2DMultisampleBlockShape</name></member> <!-- Sparse resources support: GPU will access all 2D (multisample) sparse resources using the standard sparse image block shapes (based on pixel format) -->
+ <member><type>VkBool32</type> <name>residencyStandard3DBlockShape</name></member> <!-- Sparse resources support: GPU will access all 3D sparse resources using the standard sparse image block shapes (based on pixel format) -->
+ <member><type>VkBool32</type> <name>residencyAlignedMipSize</name></member> <!-- Sparse resources support: Images with mip level dimensions that are NOT a multiple of the sparse image block dimensions will be placed in the mip tail -->
+ <member><type>VkBool32</type> <name>residencyNonResidentStrict</name></member> <!-- Sparse resources support: GPU can consistently access non-resident regions of a resource, all reads return as if data is 0, writes are discarded -->
+ </type>
+ <type category="struct" name="VkPhysicalDeviceLimits" returnedonly="true">
+ <!-- resource maximum sizes -->
+ <member><type>uint32_t</type> <name>maxImageDimension1D</name></member> <!-- max 1D image dimension -->
+ <member><type>uint32_t</type> <name>maxImageDimension2D</name></member> <!-- max 2D image dimension -->
+ <member><type>uint32_t</type> <name>maxImageDimension3D</name></member> <!-- max 3D image dimension -->
+ <member><type>uint32_t</type> <name>maxImageDimensionCube</name></member> <!-- max cubemap image dimension -->
+ <member><type>uint32_t</type> <name>maxImageArrayLayers</name></member> <!-- max layers for image arrays -->
+ <member><type>uint32_t</type> <name>maxTexelBufferElements</name></member> <!-- max texel buffer size (fstexels) -->
+ <member><type>uint32_t</type> <name>maxUniformBufferRange</name></member> <!-- max uniform buffer range (bytes) -->
+ <member><type>uint32_t</type> <name>maxStorageBufferRange</name></member> <!-- max storage buffer range (bytes) -->
+ <member><type>uint32_t</type> <name>maxPushConstantsSize</name></member> <!-- max size of the push constants pool (bytes) -->
+ <!-- memory limits -->
+ <member><type>uint32_t</type> <name>maxMemoryAllocationCount</name></member> <!-- max number of device memory allocations supported -->
+ <member><type>uint32_t</type> <name>maxSamplerAllocationCount</name></member> <!-- max number of samplers that can be allocated on a device -->
+ <member><type>VkDeviceSize</type> <name>bufferImageGranularity</name></member> <!-- Granularity (in bytes) at which buffers and images can be bound to adjacent memory for simultaneous usage -->
+ <member><type>VkDeviceSize</type> <name>sparseAddressSpaceSize</name></member> <!-- Total address space available for sparse allocations (bytes) -->
+ <!-- descriptor set limits -->
+ <member><type>uint32_t</type> <name>maxBoundDescriptorSets</name></member> <!-- max number of descriptors sets that can be bound to a pipeline -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorSamplers</name></member> <!-- max number of samplers allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorUniformBuffers</name></member> <!-- max number of uniform buffers allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorStorageBuffers</name></member> <!-- max number of storage buffers allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorSampledImages</name></member> <!-- max number of sampled images allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorStorageImages</name></member> <!-- max number of storage images allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageDescriptorInputAttachments</name></member> <!-- max number of input attachments allowed per-stage in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxPerStageResources</name></member> <!-- max number of resources allowed by a single stage -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetSamplers</name></member> <!-- max number of samplers allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetUniformBuffers</name></member> <!-- max number of uniform buffers allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetUniformBuffersDynamic</name></member> <!-- max number of dynamic uniform buffers allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetStorageBuffers</name></member> <!-- max number of storage buffers allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetStorageBuffersDynamic</name></member> <!-- max number of dynamic storage buffers allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetSampledImages</name></member> <!-- max number of sampled images allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetStorageImages</name></member> <!-- max number of storage images allowed in all stages in a descriptor set -->
+ <member><type>uint32_t</type> <name>maxDescriptorSetInputAttachments</name></member> <!-- max number of input attachments allowed in all stages in a descriptor set -->
+ <!-- vertex stage limits -->
+ <member><type>uint32_t</type> <name>maxVertexInputAttributes</name></member> <!-- max number of vertex input attribute slots -->
+ <member><type>uint32_t</type> <name>maxVertexInputBindings</name></member> <!-- max number of vertex input binding slots -->
+ <member><type>uint32_t</type> <name>maxVertexInputAttributeOffset</name></member> <!-- max vertex input attribute offset added to vertex buffer offset -->
+ <member><type>uint32_t</type> <name>maxVertexInputBindingStride</name></member> <!-- max vertex input binding stride -->
+ <member><type>uint32_t</type> <name>maxVertexOutputComponents</name></member> <!-- max number of output components written by vertex shader -->
+ <!-- tessellation control stage limits -->
+ <member><type>uint32_t</type> <name>maxTessellationGenerationLevel</name></member> <!-- max level supported by tessellation primitive generator -->
+ <member><type>uint32_t</type> <name>maxTessellationPatchSize</name></member> <!-- max patch size (vertices) -->
+ <member><type>uint32_t</type> <name>maxTessellationControlPerVertexInputComponents</name></member> <!-- max number of input components per-vertex in TCS -->
+ <member><type>uint32_t</type> <name>maxTessellationControlPerVertexOutputComponents</name></member> <!-- max number of output components per-vertex in TCS -->
+ <member><type>uint32_t</type> <name>maxTessellationControlPerPatchOutputComponents</name></member> <!-- max number of output components per-patch in TCS -->
+ <member><type>uint32_t</type> <name>maxTessellationControlTotalOutputComponents</name></member> <!-- max total number of per-vertex and per-patch output components in TCS -->
+ <!-- tessellation evaluation stage limits -->
+ <member><type>uint32_t</type> <name>maxTessellationEvaluationInputComponents</name></member> <!-- max number of input components per vertex in TES -->
+ <member><type>uint32_t</type> <name>maxTessellationEvaluationOutputComponents</name></member> <!-- max number of output components per vertex in TES -->
+ <!-- geometry stage limits -->
+ <member><type>uint32_t</type> <name>maxGeometryShaderInvocations</name></member> <!-- max invocation count supported in geometry shader -->
+ <member><type>uint32_t</type> <name>maxGeometryInputComponents</name></member> <!-- max number of input components read in geometry stage -->
+ <member><type>uint32_t</type> <name>maxGeometryOutputComponents</name></member> <!-- max number of output components written in geometry stage -->
+ <member><type>uint32_t</type> <name>maxGeometryOutputVertices</name></member> <!-- max number of vertices that can be emitted in geometry stage -->
+ <member><type>uint32_t</type> <name>maxGeometryTotalOutputComponents</name></member> <!-- max total number of components (all vertices) written in geometry stage -->
+ <!-- fragment stage limits -->
+ <member><type>uint32_t</type> <name>maxFragmentInputComponents</name></member> <!-- max number of input compontents read in fragment stage -->
+ <member><type>uint32_t</type> <name>maxFragmentOutputAttachments</name></member> <!-- max number of output attachments written in fragment stage -->
+ <member><type>uint32_t</type> <name>maxFragmentDualSrcAttachments</name></member> <!-- max number of output attachments written when using dual source blending -->
+ <member><type>uint32_t</type> <name>maxFragmentCombinedOutputResources</name></member><!-- max total number of storage buffers, storage images and output buffers -->
+ <!-- compute stage limits -->
+ <member><type>uint32_t</type> <name>maxComputeSharedMemorySize</name></member> <!-- max total storage size of work group local storage (bytes) -->
+ <member><type>uint32_t</type> <name>maxComputeWorkGroupCount</name>[3]</member> <!-- max num of compute work groups that may be dispatched by a single command (x,y,z) -->
+ <member><type>uint32_t</type> <name>maxComputeWorkGroupInvocations</name></member> <!-- max total compute invocations in a single local work group -->
+ <member><type>uint32_t</type> <name>maxComputeWorkGroupSize</name>[3]</member> <!-- max local size of a compute work group (x,y,z) -->
+ <member><type>uint32_t</type> <name>subPixelPrecisionBits</name></member> <!-- number bits of subpixel precision in screen x and y-->
+ <member><type>uint32_t</type> <name>subTexelPrecisionBits</name></member> <!-- number bits of precision for selecting texel weights-->
+ <member><type>uint32_t</type> <name>mipmapPrecisionBits</name></member> <!-- number bits of precision for selecting mipmap weights -->
+ <member><type>uint32_t</type> <name>maxDrawIndexedIndexValue</name></member> <!-- max index value for indexed draw calls (for 32-bit indices) -->
+ <member><type>uint32_t</type> <name>maxDrawIndirectCount</name></member> <!-- max draw count for indirect draw calls -->
+ <member><type>float</type> <name>maxSamplerLodBias</name></member> <!-- max absolute sampler level of detail bias -->
+ <member><type>float</type> <name>maxSamplerAnisotropy</name></member> <!-- max degree of sampler anisotropy -->
+ <member><type>uint32_t</type> <name>maxViewports</name></member> <!-- max number of active viewports -->
+ <member><type>uint32_t</type> <name>maxViewportDimensions</name>[2]</member> <!-- max viewport dimensions (x,y) -->
+ <member><type>float</type> <name>viewportBoundsRange</name>[2]</member> <!-- viewport bounds range (min,max) -->
+ <member><type>uint32_t</type> <name>viewportSubPixelBits</name></member> <!-- number bits of subpixel precision for viewport -->
+ <member><type>size_t</type> <name>minMemoryMapAlignment</name></member> <!-- min required alignment of pointers returned by MapMemory (bytes) -->
+ <member><type>VkDeviceSize</type> <name>minTexelBufferOffsetAlignment</name></member> <!-- min required alignment for texel buffer offsets (bytes) -->
+ <member><type>VkDeviceSize</type> <name>minUniformBufferOffsetAlignment</name></member> <!-- min required alignment for uniform buffer sizes and offsets (bytes) -->
+ <member><type>VkDeviceSize</type> <name>minStorageBufferOffsetAlignment</name></member> <!-- min required alignment for storage buffer offsets (bytes) -->
+ <member><type>int32_t</type> <name>minTexelOffset</name></member> <!-- min texel offset for OpTextureSampleOffset -->
+ <member><type>uint32_t</type> <name>maxTexelOffset</name></member> <!-- max texel offset for OpTextureSampleOffset -->
+ <member><type>int32_t</type> <name>minTexelGatherOffset</name></member> <!-- min texel offset for OpTextureGatherOffset -->
+ <member><type>uint32_t</type> <name>maxTexelGatherOffset</name></member> <!-- max texel offset for OpTextureGatherOffset -->
+ <member><type>float</type> <name>minInterpolationOffset</name></member> <!-- furthest negative offset for interpolateAtOffset -->
+ <member><type>float</type> <name>maxInterpolationOffset</name></member> <!-- furthest positive offset for interpolateAtOffset -->
+ <member><type>uint32_t</type> <name>subPixelInterpolationOffsetBits</name></member> <!-- number of subpixel bits for interpolateAtOffset -->
+ <member><type>uint32_t</type> <name>maxFramebufferWidth</name></member> <!-- max width for a framebuffer -->
+ <member><type>uint32_t</type> <name>maxFramebufferHeight</name></member> <!-- max height for a framebuffer -->
+ <member><type>uint32_t</type> <name>maxFramebufferLayers</name></member> <!-- max layer count for a layered framebuffer -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>framebufferColorSampleCounts</name></member> <!-- supported color sample counts for a framebuffer -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>framebufferDepthSampleCounts</name></member> <!-- supported depth sample counts for a framebuffer -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>framebufferStencilSampleCounts</name></member> <!-- supported stencil sample counts for a framebuffer -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>framebufferNoAttachmentsSampleCounts</name></member> <!-- supported sample counts for a framebuffer with no attachments -->
+ <member><type>uint32_t</type> <name>maxColorAttachments</name></member> <!-- max number of color attachments per subpass -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>sampledImageColorSampleCounts</name></member> <!-- supported color sample counts for a non-integer sampled image -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>sampledImageIntegerSampleCounts</name></member> <!-- supported sample counts for an integer image -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>sampledImageDepthSampleCounts</name></member> <!-- supported depth sample counts for a sampled image -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>sampledImageStencilSampleCounts</name></member> <!-- supported stencil sample counts for a sampled image -->
+ <member optional="true"><type>VkSampleCountFlags</type> <name>storageImageSampleCounts</name></member> <!-- supported sample counts for a storage image -->
+ <member><type>uint32_t</type> <name>maxSampleMaskWords</name></member> <!-- max number of sample mask words -->
+ <member><type>VkBool32</type> <name>timestampComputeAndGraphics</name></member> <!-- timestamps on graphics and compute queues -->
+ <member><type>float</type> <name>timestampPeriod</name></member> <!-- number of nanoseconds it takes for timestamp query value to increment by 1 -->
+ <member><type>uint32_t</type> <name>maxClipDistances</name></member> <!-- max number of clip distances -->
+ <member><type>uint32_t</type> <name>maxCullDistances</name></member> <!-- max number of cull distances -->
+ <member><type>uint32_t</type> <name>maxCombinedClipAndCullDistances</name></member> <!-- max combined number of user clipping -->
+ <member><type>uint32_t</type> <name>discreteQueuePriorities</name></member> <!-- distinct queue priorities available -->
+ <member><type>float</type> <name>pointSizeRange</name>[2]</member> <!-- range (min,max) of supported point sizes -->
+ <member><type>float</type> <name>lineWidthRange</name>[2]</member> <!-- range (min,max) of supported line widths -->
+ <member><type>float</type> <name>pointSizeGranularity</name></member> <!-- granularity of supported point sizes -->
+ <member><type>float</type> <name>lineWidthGranularity</name></member> <!-- granularity of supported line widths -->
+ <member><type>VkBool32</type> <name>strictLines</name></member> <!-- line rasterization follows preferred rules -->
+ <member><type>VkBool32</type> <name>standardSampleLocations</name></member> <!-- supports standard sample locations for all supported sample counts -->
+ <member><type>VkDeviceSize</type> <name>optimalBufferCopyOffsetAlignment</name></member> <!-- optimal offset of buffer copies -->
+ <member><type>VkDeviceSize</type> <name>optimalBufferCopyRowPitchAlignment</name></member><!-- optimal pitch of buffer copies -->
+ <member><type>VkDeviceSize</type> <name>nonCoherentAtomSize</name></member> <!-- minimum size and alignment for non-coherent host-mapped device memory access -->
+ </type>
+ <type category="struct" name="VkSemaphoreCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkSemaphoreCreateFlags</type> <name>flags</name></member> <!-- Semaphore creation flags -->
+ </type>
+ <type category="struct" name="VkQueryPoolCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkQueryPoolCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkQueryType</type> <name>queryType</name></member>
+ <member><type>uint32_t</type> <name>queryCount</name></member>
+ <member optional="true" noautovalidity="true"><type>VkQueryPipelineStatisticFlags</type> <name>pipelineStatistics</name></member> <!-- Optional -->
+ </type>
+ <type category="struct" name="VkFramebufferCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkFramebufferCreateFlags</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkRenderPass</type> <name>renderPass</name></member>
+ <member optional="true"><type>uint32_t</type> <name>attachmentCount</name></member>
+ <member len="attachmentCount">const <type>VkImageView</type>* <name>pAttachments</name></member>
+ <member><type>uint32_t</type> <name>width</name></member>
+ <member><type>uint32_t</type> <name>height</name></member>
+ <member><type>uint32_t</type> <name>layers</name></member>
+ </type>
+ <type category="struct" name="VkDrawIndirectCommand">
+ <member><type>uint32_t</type> <name>vertexCount</name></member>
+ <member><type>uint32_t</type> <name>instanceCount</name></member>
+ <member><type>uint32_t</type> <name>firstVertex</name></member>
+ <member><type>uint32_t</type> <name>firstInstance</name></member>
+ </type>
+ <type category="struct" name="VkDrawIndexedIndirectCommand">
+ <member><type>uint32_t</type> <name>indexCount</name></member>
+ <member><type>uint32_t</type> <name>instanceCount</name></member>
+ <member><type>uint32_t</type> <name>firstIndex</name></member>
+ <member><type>int32_t</type> <name>vertexOffset</name></member>
+ <member><type>uint32_t</type> <name>firstInstance</name></member>
+ </type>
+ <type category="struct" name="VkDispatchIndirectCommand">
+ <member><type>uint32_t</type> <name>x</name></member>
+ <member><type>uint32_t</type> <name>y</name></member>
+ <member><type>uint32_t</type> <name>z</name></member>
+ </type>
+ <type category="struct" name="VkSubmitInfo">
+ <member values="VK_STRUCTURE_TYPE_SUBMIT_INFO"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>uint32_t</type> <name>waitSemaphoreCount</name></member>
+ <member len="waitSemaphoreCount">const <type>VkSemaphore</type>* <name>pWaitSemaphores</name></member>
+ <member len="waitSemaphoreCount">const <type>VkPipelineStageFlags</type>* <name>pWaitDstStageMask</name></member>
+ <member optional="true"><type>uint32_t</type> <name>commandBufferCount</name></member>
+ <member len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></member>
+ <member optional="true"><type>uint32_t</type> <name>signalSemaphoreCount</name></member>
+ <member len="signalSemaphoreCount">const <type>VkSemaphore</type>* <name>pSignalSemaphores</name></member>
+ </type>
+ <!-- WSI extensions -->
+ <type category="struct" name="VkDisplayPropertiesKHR" returnedonly="true">
+ <member><type>VkDisplayKHR</type> <name>display</name></member> <!-- Handle of the display object -->
+ <member len="null-terminated">const <type>char</type>* <name>displayName</name></member> <!-- Name of the display -->
+ <member><type>VkExtent2D</type> <name>physicalDimensions</name></member> <!-- In millimeters? -->
+ <member><type>VkExtent2D</type> <name>physicalResolution</name></member> <!-- Max resolution for CRT? -->
+ <member optional="true"><type>VkSurfaceTransformFlagsKHR</type> <name>supportedTransforms</name></member> <!-- one or more bits from VkSurfaceTransformFlagsKHR -->
+ <member><type>VkBool32</type> <name>planeReorderPossible</name></member> <!-- VK_TRUE if the overlay plane's z-order can be changed on this display. -->
+ <member><type>VkBool32</type> <name>persistentContent</name></member> <!-- VK_TRUE if this is a "smart" display that supports self-refresh/internal buffering. -->
+ </type>
+ <type category="struct" name="VkDisplayPlanePropertiesKHR" returnedonly="true">
+ <member><type>VkDisplayKHR</type> <name>currentDisplay</name></member> <!-- Display the plane is currently associated with. Will be VK_NULL_HANDLE if the plane is not in use. -->
+ <member><type>uint32_t</type> <name>currentStackIndex</name></member> <!-- Current z-order of the plane. -->
+ </type>
+ <type category="struct" name="VkDisplayModeParametersKHR">
+ <member><type>VkExtent2D</type> <name>visibleRegion</name></member> <!-- Visible scanout region. -->
+ <member><type>uint32_t</type> <name>refreshRate</name></member> <!-- Number of times per second the display is updated. -->
+ </type>
+ <type category="struct" name="VkDisplayModePropertiesKHR" returnedonly="true">
+ <member><type>VkDisplayModeKHR</type> <name>displayMode</name></member> <!-- Handle of this display mode. -->
+ <member><type>VkDisplayModeParametersKHR</type> <name>parameters</name></member> <!-- The parameters this mode uses. -->
+ </type>
+ <type category="struct" name="VkDisplayModeCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDisplayModeCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkDisplayModeParametersKHR</type> <name>parameters</name></member> <!-- The parameters this mode uses. -->
+ </type>
+ <type category="struct" name="VkDisplayPlaneCapabilitiesKHR" returnedonly="true">
+ <member optional="true"><type>VkDisplayPlaneAlphaFlagsKHR</type> <name>supportedAlpha</name></member> <!-- Types of alpha blending supported, if any. -->
+ <member><type>VkOffset2D</type> <name>minSrcPosition</name></member> <!-- Does the plane have any position and extent restrictions? -->
+ <member><type>VkOffset2D</type> <name>maxSrcPosition</name></member>
+ <member><type>VkExtent2D</type> <name>minSrcExtent</name></member>
+ <member><type>VkExtent2D</type> <name>maxSrcExtent</name></member>
+ <member><type>VkOffset2D</type> <name>minDstPosition</name></member>
+ <member><type>VkOffset2D</type> <name>maxDstPosition</name></member>
+ <member><type>VkExtent2D</type> <name>minDstExtent</name></member>
+ <member><type>VkExtent2D</type> <name>maxDstExtent</name></member>
+ </type>
+ <type category="struct" name="VkDisplaySurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkDisplaySurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkDisplayModeKHR</type> <name>displayMode</name></member> <!-- The mode to use when displaying this surface -->
+ <member><type>uint32_t</type> <name>planeIndex</name></member> <!-- The plane on which this surface appears. Must be between 0 and the value returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR() in pPropertyCount. -->
+ <member><type>uint32_t</type> <name>planeStackIndex</name></member> <!-- The z-order of the plane. -->
+ <member><type>VkSurfaceTransformFlagBitsKHR</type> <name>transform</name></member> <!-- Transform to apply to the images as part of the scanout operation -->
+ <member><type>float</type> <name>globalAlpha</name></member> <!-- Global alpha value. Must be between 0 and 1, inclusive. Ignored if alphaMode is not VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR -->
+ <member><type>VkDisplayPlaneAlphaFlagBitsKHR</type> <name>alphaMode</name></member> <!-- What type of alpha blending to use. Must be a bit from vkGetDisplayPlanePropertiesKHR::supportedAlpha. -->
+ <member><type>VkExtent2D</type> <name>imageExtent</name></member> <!-- size of the images to use with this surface -->
+ </type>
+ <type category="struct" name="VkDisplayPresentInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkRect2D</type> <name>srcRect</name></member> <!-- Rectangle within the presentable image to read pixel data from when presenting to the display. -->
+ <member><type>VkRect2D</type> <name>dstRect</name></member> <!-- Rectangle within the current display mode's visible region to display srcRectangle in. -->
+ <member><type>VkBool32</type> <name>persistent</name></member> <!-- For smart displays, use buffered mode. If the display properties member "persistentMode" is VK_FALSE, this member must always be VK_FALSE. -->
+ </type>
+ <type category="struct" name="VkSurfaceCapabilitiesKHR" returnedonly="true">
+ <member><type>uint32_t</type> <name>minImageCount</name></member> <!-- Supported minimum number of images for the surface -->
+ <member><type>uint32_t</type> <name>maxImageCount</name></member> <!-- Supported maximum number of images for the surface, 0 for unlimited -->
+ <member><type>VkExtent2D</type> <name>currentExtent</name></member> <!-- Current image width and height for the surface, (0, 0) if undefined -->
+ <member><type>VkExtent2D</type> <name>minImageExtent</name></member> <!-- Supported minimum image width and height for the surface -->
+ <member><type>VkExtent2D</type> <name>maxImageExtent</name></member> <!-- Supported maximum image width and height for the surface -->
+ <member><type>uint32_t</type> <name>maxImageArrayLayers</name></member> <!-- Supported maximum number of image layers for the surface -->
+ <member optional="true"><type>VkSurfaceTransformFlagsKHR</type> <name>supportedTransforms</name></member> <!-- 1 or more bits representing the transforms supported -->
+ <member><type>VkSurfaceTransformFlagBitsKHR</type> <name>currentTransform</name></member> <!-- The surface's current transform relative to the device's natural orientation -->
+ <member optional="true"><type>VkCompositeAlphaFlagsKHR</type> <name>supportedCompositeAlpha</name></member> <!-- 1 or more bits representing the alpha compositing modes supported -->
+ <member optional="true"><type>VkImageUsageFlags</type> <name>supportedUsageFlags</name></member> <!-- Supported image usage flags for the surface -->
+ </type>
+ <type category="struct" name="VkAndroidSurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkAndroidSurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member noautovalidity="true"><type>ANativeWindow</type>* <name>window</name></member>
+ </type>
+ <type category="struct" name="VkMirSurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkMirSurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member noautovalidity="true"><type>MirConnection</type>* <name>connection</name></member>
+ <member noautovalidity="true"><type>MirSurface</type>* <name>mirSurface</name></member>
+ </type>
+ <type category="struct" name="VkViSurfaceCreateInfoNN">
+ <member values="VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkViSurfaceCreateFlagsNN</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>void</type>* <name>window</name></member>
+ </type>
+ <type category="struct" name="VkWaylandSurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkWaylandSurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member noautovalidity="true">struct <type>wl_display</type>* <name>display</name></member>
+ <member noautovalidity="true">struct <type>wl_surface</type>* <name>surface</name></member>
+ </type>
+ <type category="struct" name="VkWin32SurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkWin32SurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>HINSTANCE</type> <name>hinstance</name></member>
+ <member><type>HWND</type> <name>hwnd</name></member>
+ </type>
+ <type category="struct" name="VkXlibSurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkXlibSurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member noautovalidity="true"><type>Display</type>* <name>dpy</name></member>
+ <member><type>Window</type> <name>window</name></member>
+ </type>
+ <type category="struct" name="VkXcbSurfaceCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkXcbSurfaceCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member noautovalidity="true"><type>xcb_connection_t</type>* <name>connection</name></member>
+ <member><type>xcb_window_t</type> <name>window</name></member>
+ </type>
+ <type category="struct" name="VkSurfaceFormatKHR" returnedonly="true">
+ <member><type>VkFormat</type> <name>format</name></member> <!-- Supported pair of rendering format -->
+ <member><type>VkColorSpaceKHR</type> <name>colorSpace</name></member> <!-- and color space for the surface -->
+ </type>
+ <type category="struct" name="VkSwapchainCreateInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkSwapchainCreateFlagsKHR</type> <name>flags</name></member> <!-- Reserved -->
+ <member><type>VkSurfaceKHR</type> <name>surface</name></member> <!-- The swapchain's target surface -->
+ <member><type>uint32_t</type> <name>minImageCount</name></member> <!-- Minimum number of presentation images the application needs -->
+ <member><type>VkFormat</type> <name>imageFormat</name></member> <!-- Format of the presentation images -->
+ <member><type>VkColorSpaceKHR</type> <name>imageColorSpace</name></member> <!-- Colorspace of the presentation images -->
+ <member><type>VkExtent2D</type> <name>imageExtent</name></member> <!-- Dimensions of the presentation images -->
+ <member><type>uint32_t</type> <name>imageArrayLayers</name></member> <!-- Determines the number of views for multiview/stereo presentation -->
+ <member><type>VkImageUsageFlags</type> <name>imageUsage</name></member> <!-- Bits indicating how the presentation images will be used -->
+ <member><type>VkSharingMode</type> <name>imageSharingMode</name></member> <!-- Sharing mode used for the presentation images -->
+ <member optional="true"><type>uint32_t</type> <name>queueFamilyIndexCount</name></member> <!-- Number of queue families having access to the images in case of concurrent sharing mode -->
+ <member noautovalidity="true" len="queueFamilyIndexCount">const <type>uint32_t</type>* <name>pQueueFamilyIndices</name></member> <!-- Array of queue family indices having access to the images in case of concurrent sharing mode -->
+ <member><type>VkSurfaceTransformFlagBitsKHR</type> <name>preTransform</name></member> <!-- The transform, relative to the device's natural orientation, applied to the image content prior to presentation -->
+ <member><type>VkCompositeAlphaFlagBitsKHR</type> <name>compositeAlpha</name></member> <!-- The alpha blending mode used when compositing this surface with other surfaces in the window system -->
+ <member><type>VkPresentModeKHR</type> <name>presentMode</name></member> <!-- Which presentation mode to use for presents on this swap chain -->
+ <member><type>VkBool32</type> <name>clipped</name></member> <!-- Specifies whether presentable images may be affected by window clip regions -->
+ <member optional="true"><type>VkSwapchainKHR</type> <name>oldSwapchain</name></member> <!-- Existing swap chain to replace, if any -->
+ </type>
+ <type category="struct" name="VkPresentInfoKHR">
+ <member values="VK_STRUCTURE_TYPE_PRESENT_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member validextensionstructs="VkDisplayPresentInfoKHR">const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>uint32_t</type> <name>waitSemaphoreCount</name></member> <!-- Number of semaphores to wait for before presenting -->
+ <member optional="true" len="waitSemaphoreCount">const <type>VkSemaphore</type>* <name>pWaitSemaphores</name></member> <!-- Semaphores to wait for before presenting -->
+ <member><type>uint32_t</type> <name>swapchainCount</name></member> <!-- Number of swap chains to present in this call -->
+ <member len="swapchainCount">const <type>VkSwapchainKHR</type>* <name>pSwapchains</name></member> <!-- Swapchains to present an image from -->
+ <member len="swapchainCount">const <type>uint32_t</type>* <name>pImageIndices</name></member> <!-- Indices of which swapchain images to present -->
+ <member optional="true" len="swapchainCount"><type>VkResult</type>* <name>pResults</name></member> <!-- Optional (i.e. if non-NULL) VkResult for each swapchain -->
+ </type>
+ <type category="struct" name="VkDebugReportCallbackCreateInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDebugReportFlagsEXT</type> <name>flags</name></member> <!-- Indicates which events call this callback-->
+ <member><type>PFN_vkDebugReportCallbackEXT</type> <name>pfnCallback</name></member> <!-- Function pointer of a callback function-->
+ <member optional="true"><type>void</type>* <name>pUserData</name></member> <!-- User data provided to callback function -->
+ </type>
+ <type category="struct" name="VkValidationFlagsEXT">
+ <member><type>VkStructureType</type> <name>sType</name></member> <!-- Must be VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT -->
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>uint32_t</type> <name>disabledValidationCheckCount</name></member> <!-- Number of validation checks to disable -->
+ <member len="disabledValidationCheckCount"><type>VkValidationCheckEXT</type>* <name>pDisabledValidationChecks</name></member> <!-- Validation checks to disable -->
+ </type>
+ <type category="struct" name="VkPipelineRasterizationStateRasterizationOrderAMD">
+ <member values="VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkRasterizationOrderAMD</type> <name>rasterizationOrder</name></member> <!-- Rasterization order to use for the pipeline -->
+ </type>
+ <type category="struct" name="VkDebugMarkerObjectNameInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDebugReportObjectTypeEXT</type> <name>objectType</name></member> <!-- The type of the object -->
+ <member><type>uint64_t</type> <name>object</name></member> <!-- The handle of the object, cast to uint64_t -->
+ <member len="null-terminated">const <type>char</type>* <name>pObjectName</name></member> <!-- Name to apply to the object -->
+ </type>
+ <type category="struct" name="VkDebugMarkerObjectTagInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkDebugReportObjectTypeEXT</type> <name>objectType</name></member> <!-- The type of the object -->
+ <member><type>uint64_t</type> <name>object</name></member> <!-- The handle of the object, cast to uint64_t -->
+ <member><type>uint64_t</type> <name>tagName</name></member> <!-- The name of the tag to set on the object -->
+ <member><type>size_t</type> <name>tagSize</name></member> <!-- The length in bytes of the tag data -->
+ <member len="tagSize">const <type>void</type>* <name>pTag</name></member> <!-- Tag data to attach to the object -->
+ </type>
+ <type category="struct" name="VkDebugMarkerMarkerInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member len="null-terminated">const <type>char</type>* <name>pMarkerName</name></member> <!-- Name of the debug marker -->
+ <member optional="true"><type>float</type> <name>color</name>[4]</member> <!-- Optional color for debug marker -->
+ </type>
+ <type category="struct" name="VkDedicatedAllocationImageCreateInfoNV">
+ <member values="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkBool32</type> <name>dedicatedAllocation</name></member> <!-- Whether this image uses a dedicated allocation -->
+ </type>
+ <type category="struct" name="VkDedicatedAllocationBufferCreateInfoNV">
+ <member values="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkBool32</type> <name>dedicatedAllocation</name></member> <!-- Whether this buffer uses a dedicated allocation -->
+ </type>
+ <type category="struct" name="VkDedicatedAllocationMemoryAllocateInfoNV">
+ <member values="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member optional="true"><type>VkImage</type> <name>image</name></member> <!-- Image that this allocation will be bound to -->
+ <member optional="true"><type>VkBuffer</type> <name>buffer</name></member> <!-- Buffer that this allocation will be bound to -->
+ </type>
+ <type category="struct" name="VkExternalImageFormatPropertiesNV" returnedonly="true">
+ <member><type>VkImageFormatProperties</type> <name>imageFormatProperties</name></member>
+ <member optional="true"><type>VkExternalMemoryFeatureFlagsNV</type> <name>externalMemoryFeatures</name></member>
+ <member optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>exportFromImportedHandleTypes</name></member>
+ <member optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>compatibleHandleTypes</name></member>
+ </type>
+ <type category="struct" name="VkExternalMemoryImageCreateInfoNV">
+ <member values="VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>handleTypes</name></member>
+ </type>
+ <type category="struct" name="VkExportMemoryAllocateInfoNV">
+ <member values="VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>handleTypes</name></member>
+ </type>
+ <type category="struct" name="VkImportMemoryWin32HandleInfoNV">
+ <member values="VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>handleType</name></member>
+ <member optional="true"><type>HANDLE</type> <name>handle</name></member>
+ </type>
+ <type category="struct" name="VkExportMemoryWin32HandleInfoNV">
+ <member values="VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true">const <type>SECURITY_ATTRIBUTES</type>* <name>pAttributes</name></member>
+ <member optional="true"><type>DWORD</type> <name>dwAccess</name></member>
+ </type>
+ <type category="struct" name="VkWin32KeyedMutexAcquireReleaseInfoNV">
+ <member values="VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>uint32_t</type> <name>acquireCount</name></member>
+ <member len="acquireCount">const <type>VkDeviceMemory</type>* <name>pAcquireSyncs</name></member>
+ <member len="acquireCount">const <type>uint64_t</type>* <name>pAcquireKeys</name></member>
+ <member len="acquireCount">const <type>uint32_t</type>* <name>pAcquireTimeoutMilliseconds</name></member>
+ <member optional="true"><type>uint32_t</type> <name>releaseCount</name></member>
+ <member len="releaseCount">const <type>VkDeviceMemory</type>* <name>pReleaseSyncs</name></member>
+ <member len="releaseCount">const <type>uint64_t</type>* <name>pReleaseKeys</name></member>
+ </type>
+
+ <type category="struct" name="VkDeviceGeneratedCommandsFeaturesNVX">
+ <member values="VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>VkBool32</type> <name>computeBindingPointSupport</name></member>
+ </type>
+ <type category="struct" name="VkDeviceGeneratedCommandsLimitsNVX">
+ <member values="VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>maxIndirectCommandsLayoutTokenCount</name></member>
+ <member><type>uint32_t</type> <name>maxObjectEntryCounts</name></member>
+ <member><type>uint32_t</type> <name>minSequenceCountBufferOffsetAlignment</name></member>
+ <member><type>uint32_t</type> <name>minSequenceIndexBufferOffsetAlignment</name></member>
+ <member><type>uint32_t</type> <name>minCommandsTokenBufferOffsetAlignment</name></member>
+ </type>
+ <type category="struct" name="VkIndirectCommandsTokenNVX">
+ <member><type>VkIndirectCommandsTokenTypeNVX</type> <name>tokenType</name></member>
+ <member><type>VkBuffer</type> <name>buffer</name></member> <!-- buffer containing tableEntries and additional data for indirectCommands -->
+ <member><type>VkDeviceSize</type> <name>offset</name></member> <!-- offset from the base address of the buffer -->
+ </type>
+ <type category="struct" name="VkIndirectCommandsLayoutTokenNVX">
+ <member><type>VkIndirectCommandsTokenTypeNVX</type> <name>tokenType</name></member>
+ <member><type>uint32_t</type> <name>bindingUnit</name></member> <!-- Binding unit for vertex attribute / descriptor set, offset for pushconstants -->
+ <member><type>uint32_t</type> <name>dynamicCount</name></member> <!-- Number of variable dynamic values for descriptor set / push constants -->
+ <member><type>uint32_t</type> <name>divisor</name></member> <!-- Rate the which the array is advanced per element (must be power of 2, minimum 1) -->
+ </type>
+ <type category="struct" name="VkIndirectCommandsLayoutCreateInfoNVX">
+ <member values="VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>VkPipelineBindPoint</type> <name>pipelineBindPoint</name></member>
+ <member><type>VkIndirectCommandsLayoutUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>uint32_t</type> <name>tokenCount</name></member>
+ <member len="tokenCount">const <type>VkIndirectCommandsLayoutTokenNVX</type>* <name>pTokens</name></member>
+ </type>
+ <type category="struct" name="VkCmdProcessCommandsInfoNVX">
+ <member values="VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member externsync="true"><type>VkObjectTableNVX</type> <name>objectTable</name></member>
+ <member><type>VkIndirectCommandsLayoutNVX</type> <name>indirectCommandsLayout</name></member>
+ <member><type>uint32_t</type> <name>indirectCommandsTokenCount</name></member>
+ <member len="indirectCommandsTokenCount">const <type>VkIndirectCommandsTokenNVX</type>* <name>pIndirectCommandsTokens</name></member>
+ <member><type>uint32_t</type> <name>maxSequencesCount</name></member>
+ <member optional="true" externsync="true"><type>VkCommandBuffer</type> <name>targetCommandBuffer</name></member>
+ <member optional="true"><type>VkBuffer</type> <name>sequencesCountBuffer</name></member>
+ <member optional="true"><type>VkDeviceSize</type> <name>sequencesCountOffset</name></member>
+ <member optional="true"><type>VkBuffer</type> <name>sequencesIndexBuffer</name></member>
+ <member optional="true"><type>VkDeviceSize</type> <name>sequencesIndexOffset</name></member>
+ </type>
+ <type category="struct" name="VkCmdReserveSpaceForCommandsInfoNVX">
+ <member values="VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member externsync="true"><type>VkObjectTableNVX</type> <name>objectTable</name></member>
+ <member><type>VkIndirectCommandsLayoutNVX</type> <name>indirectCommandsLayout</name></member>
+ <member><type>uint32_t</type> <name>maxSequencesCount</name></member>
+ </type>
+ <type category="struct" name="VkObjectTableCreateInfoNVX">
+ <member values="VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>objectCount</name></member>
+ <member len="objectCount">const <type>VkObjectEntryTypeNVX</type>* <name>pObjectEntryTypes</name></member>
+ <member len="objectCount">const <type>uint32_t</type>* <name>pObjectEntryCounts</name></member>
+ <member len="objectCount">const <type>VkObjectEntryUsageFlagsNVX</type>* <name>pObjectEntryUsageFlags</name></member>
+
+ <member><type>uint32_t</type> <name>maxUniformBuffersPerDescriptor</name></member>
+ <member><type>uint32_t</type> <name>maxStorageBuffersPerDescriptor</name></member>
+ <member><type>uint32_t</type> <name>maxStorageImagesPerDescriptor</name></member>
+ <member><type>uint32_t</type> <name>maxSampledImagesPerDescriptor</name></member>
+ <member><type>uint32_t</type> <name>maxPipelineLayouts</name></member>
+ </type>
+ <type category="struct" name="VkObjectTableEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ </type>
+ <type category="struct" name="VkObjectTablePipelineEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>VkPipeline</type> <name>pipeline</name></member>
+ </type>
+ <type category="struct" name="VkObjectTableDescriptorSetEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>VkPipelineLayout</type> <name>pipelineLayout</name></member>
+ <member><type>VkDescriptorSet</type> <name>descriptorSet</name></member>
+ </type>
+ <type category="struct" name="VkObjectTableVertexBufferEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>VkBuffer</type> <name>buffer</name></member>
+ </type>
+ <type category="struct" name="VkObjectTableIndexBufferEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>VkBuffer</type> <name>buffer</name></member>
+ <member><type>VkIndexType</type> <name>indexType</name></member>
+ </type>
+ <type category="struct" name="VkObjectTablePushConstantEntryNVX">
+ <member><type>VkObjectEntryTypeNVX</type> <name>type</name></member>
+ <member><type>VkObjectEntryUsageFlagsNVX</type> <name>flags</name></member>
+ <member><type>VkPipelineLayout</type> <name>pipelineLayout</name></member>
+ <member><type>VkShaderStageFlags</type> <name>stageFlags</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceFeatures2KHR">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkPhysicalDeviceFeatures</type> <name>features</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkPhysicalDeviceProperties</type> <name>properties</name></member>
+ </type>
+ <type category="struct" name="VkFormatProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkFormatProperties</type> <name>formatProperties</name></member>
+ </type>
+ <type category="struct" name="VkImageFormatProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkImageFormatProperties</type> <name>imageFormatProperties</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceImageFormatInfo2KHR">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkFormat</type> <name>format</name></member>
+ <member><type>VkImageType</type> <name>type</name></member>
+ <member><type>VkImageTiling</type> <name>tiling</name></member>
+ <member><type>VkImageUsageFlags</type> <name>usage</name></member>
+ <member optional="true"><type>VkImageCreateFlags</type> <name>flags</name></member>
+ </type>
+ <type category="struct" name="VkQueueFamilyProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkQueueFamilyProperties</type> <name>queueFamilyProperties</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceMemoryProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkPhysicalDeviceMemoryProperties</type> <name>memoryProperties</name></member>
+ </type>
+ <type category="struct" name="VkSparseImageFormatProperties2KHR" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkSparseImageFormatProperties</type> <name>properties</name></member>
+ </type>
+ <type category="struct" name="VkPhysicalDeviceSparseImageFormatInfo2KHR">
+ <member values="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member> <!-- Pointer to next structure -->
+ <member><type>VkFormat</type> <name>format</name></member>
+ <member><type>VkImageType</type> <name>type</name></member>
+ <member><type>VkSampleCountFlagBits</type> <name>samples</name></member>
+ <member><type>VkImageUsageFlags</type> <name>usage</name></member>
+ <member><type>VkImageTiling</type> <name>tiling</name></member>
+ </type>
+ <type category="struct" name="VkSurfaceCapabilities2EXT" returnedonly="true">
+ <member values="VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>minImageCount</name></member> <!-- Supported minimum number of images for the surface -->
+ <member><type>uint32_t</type> <name>maxImageCount</name></member> <!-- Supported maximum number of images for the surface, 0 for unlimited -->
+ <member><type>VkExtent2D</type> <name>currentExtent</name></member> <!-- Current image width and height for the surface, (0, 0) if undefined -->
+ <member><type>VkExtent2D</type> <name>minImageExtent</name></member> <!-- Supported minimum image width and height for the surface -->
+ <member><type>VkExtent2D</type> <name>maxImageExtent</name></member> <!-- Supported maximum image width and height for the surface -->
+ <member><type>uint32_t</type> <name>maxImageArrayLayers</name></member> <!-- Supported maximum number of image layers for the surface -->
+ <member optional="true"><type>VkSurfaceTransformFlagsKHR</type> <name>supportedTransforms</name></member> <!-- 1 or more bits representing the transforms supported -->
+ <member><type>VkSurfaceTransformFlagBitsKHR</type> <name>currentTransform</name></member> <!-- The surface's current transform relative to the device's natural orientation -->
+ <member optional="true"><type>VkCompositeAlphaFlagsKHR</type> <name>supportedCompositeAlpha</name></member> <!-- 1 or more bits representing the alpha compositing modes supported -->
+ <member optional="true"><type>VkImageUsageFlags</type> <name>supportedUsageFlags</name></member> <!-- Supported image usage flags for the surface -->
+ <member optional="true"><type>VkSurfaceCounterFlagsEXT</type> <name>supportedSurfaceCounters</name></member>
+ </type>
+ <type category="struct" name="VkDisplayPowerInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>VkDisplayPowerStateEXT</type> <name>powerState</name></member>
+ </type>
+ <type category="struct" name="VkDeviceEventInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>VkDeviceEventTypeEXT</type> <name>deviceEvent</name></member>
+ </type>
+ <type category="struct" name="VkDisplayEventInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>VkDisplayEventTypeEXT</type> <name>displayEvent</name></member>
+ </type>
+ <type category="struct" name="VkSwapchainCounterCreateInfoEXT">
+ <member values="VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>VkSurfaceCounterFlagsEXT</type> <name>surfaceCounters</name></member>
+ </type>
+ </types>
+
+ <!-- SECTION: Vulkan enumerant (token) definitions. -->
+
+ <enums name="API Constants" comment="Misc. hardcoded constants - not an enumerated type">
+ <!-- This is part of the header boilerplate -->
+ <enum value="256" name="VK_MAX_PHYSICAL_DEVICE_NAME_SIZE"/>
+ <enum value="16" name="VK_UUID_SIZE"/>
+ <enum value="256" name="VK_MAX_EXTENSION_NAME_SIZE"/>
+ <enum value="256" name="VK_MAX_DESCRIPTION_SIZE"/>
+ <enum value="32" name="VK_MAX_MEMORY_TYPES"/>
+ <enum value="16" name="VK_MAX_MEMORY_HEAPS"/> <!-- The maximum number of unique memory heaps, each of which supporting 1 or more memory types. -->
+ <enum value="1000.0f" name="VK_LOD_CLAMP_NONE"/>
+ <enum value="(~0U)" name="VK_REMAINING_MIP_LEVELS"/>
+ <enum value="(~0U)" name="VK_REMAINING_ARRAY_LAYERS"/>
+ <enum value="(~0ULL)" name="VK_WHOLE_SIZE"/>
+ <enum value="(~0U)" name="VK_ATTACHMENT_UNUSED"/>
+ <enum value="1" name="VK_TRUE"/>
+ <enum value="0" name="VK_FALSE"/>
+ <enum value="(~0U)" name="VK_QUEUE_FAMILY_IGNORED"/>
+ <enum value="(~0U)" name="VK_SUBPASS_EXTERNAL"/>
+ </enums>
+
+ <!-- Unlike OpenGL, most tokens in Vulkan are actual typed enumerants in
+ their own numeric namespaces. The "name" attribute is the C enum
+ type name, and is pulled in from a <type> definition above
+ (slightly clunky, but retains the type / enum distinction). "type"
+ attributes of "enum" or "bitmask" indicate that these values should
+ be generated inside an appropriate definition. -->
+
+ <enums name="VkImageLayout" type="enum">
+ <enum value="0" name="VK_IMAGE_LAYOUT_UNDEFINED" comment="Implicit layout an image is when its contents are undefined due to various reasons (e.g. right after creation)"/>
+ <enum value="1" name="VK_IMAGE_LAYOUT_GENERAL" comment="General layout when image can be used for any kind of access"/>
+ <enum value="2" name="VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL" comment="Optimal layout when image is only used for color attachment read/write"/>
+ <enum value="3" name="VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL" comment="Optimal layout when image is only used for depth/stencil attachment read/write"/>
+ <enum value="4" name="VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL" comment="Optimal layout when image is used for read only depth/stencil attachment and shader access"/>
+ <enum value="5" name="VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL" comment="Optimal layout when image is used for read only shader access"/>
+ <enum value="6" name="VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL" comment="Optimal layout when image is used only as source of transfer operations"/>
+ <enum value="7" name="VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL" comment="Optimal layout when image is used only as destination of transfer operations"/>
+ <enum value="8" name="VK_IMAGE_LAYOUT_PREINITIALIZED" comment="Initial layout used when the data is populated by the CPU"/>
+ </enums>
+ <enums name="VkAttachmentLoadOp" type="enum">
+ <enum value="0" name="VK_ATTACHMENT_LOAD_OP_LOAD"/>
+ <enum value="1" name="VK_ATTACHMENT_LOAD_OP_CLEAR"/>
+ <enum value="2" name="VK_ATTACHMENT_LOAD_OP_DONT_CARE"/>
+ </enums>
+ <enums name="VkAttachmentStoreOp" type="enum">
+ <enum value="0" name="VK_ATTACHMENT_STORE_OP_STORE"/>
+ <enum value="1" name="VK_ATTACHMENT_STORE_OP_DONT_CARE"/>
+ </enums>
+ <enums name="VkImageType" type="enum">
+ <enum value="0" name="VK_IMAGE_TYPE_1D"/>
+ <enum value="1" name="VK_IMAGE_TYPE_2D"/>
+ <enum value="2" name="VK_IMAGE_TYPE_3D"/>
+ </enums>
+ <enums name="VkImageTiling" type="enum">
+ <enum value="0" name="VK_IMAGE_TILING_OPTIMAL"/>
+ <enum value="1" name="VK_IMAGE_TILING_LINEAR"/>
+ </enums>
+ <enums name="VkImageViewType" type="enum">
+ <enum value="0" name="VK_IMAGE_VIEW_TYPE_1D"/>
+ <enum value="1" name="VK_IMAGE_VIEW_TYPE_2D"/>
+ <enum value="2" name="VK_IMAGE_VIEW_TYPE_3D"/>
+ <enum value="3" name="VK_IMAGE_VIEW_TYPE_CUBE"/>
+ <enum value="4" name="VK_IMAGE_VIEW_TYPE_1D_ARRAY"/>
+ <enum value="5" name="VK_IMAGE_VIEW_TYPE_2D_ARRAY"/>
+ <enum value="6" name="VK_IMAGE_VIEW_TYPE_CUBE_ARRAY"/>
+ </enums>
+ <enums name="VkCommandBufferLevel" type="enum">
+ <enum value="0" name="VK_COMMAND_BUFFER_LEVEL_PRIMARY"/>
+ <enum value="1" name="VK_COMMAND_BUFFER_LEVEL_SECONDARY"/>
+ </enums>
+ <enums name="VkComponentSwizzle" type="enum">
+ <enum value="0" name="VK_COMPONENT_SWIZZLE_IDENTITY"/>
+ <enum value="1" name="VK_COMPONENT_SWIZZLE_ZERO"/>
+ <enum value="2" name="VK_COMPONENT_SWIZZLE_ONE"/>
+ <enum value="3" name="VK_COMPONENT_SWIZZLE_R"/>
+ <enum value="4" name="VK_COMPONENT_SWIZZLE_G"/>
+ <enum value="5" name="VK_COMPONENT_SWIZZLE_B"/>
+ <enum value="6" name="VK_COMPONENT_SWIZZLE_A"/>
+ </enums>
+ <enums name="VkDescriptorType" type="enum">
+ <enum value="0" name="VK_DESCRIPTOR_TYPE_SAMPLER"/>
+ <enum value="1" name="VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER"/>
+ <enum value="2" name="VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE"/>
+ <enum value="3" name="VK_DESCRIPTOR_TYPE_STORAGE_IMAGE"/>
+ <enum value="4" name="VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER"/>
+ <enum value="5" name="VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER"/>
+ <enum value="6" name="VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER"/>
+ <enum value="7" name="VK_DESCRIPTOR_TYPE_STORAGE_BUFFER"/>
+ <enum value="8" name="VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC"/>
+ <enum value="9" name="VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC"/>
+ <enum value="10" name="VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT"/>
+ </enums>
+ <enums name="VkQueryType" type="enum">
+ <enum value="0" name="VK_QUERY_TYPE_OCCLUSION"/>
+ <enum value="1" name="VK_QUERY_TYPE_PIPELINE_STATISTICS" comment="Optional"/>
+ <enum value="2" name="VK_QUERY_TYPE_TIMESTAMP"/>
+ </enums>
+ <enums name="VkBorderColor" type="enum">
+ <enum value="0" name="VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK"/>
+ <enum value="1" name="VK_BORDER_COLOR_INT_TRANSPARENT_BLACK"/>
+ <enum value="2" name="VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK"/>
+ <enum value="3" name="VK_BORDER_COLOR_INT_OPAQUE_BLACK"/>
+ <enum value="4" name="VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE"/>
+ <enum value="5" name="VK_BORDER_COLOR_INT_OPAQUE_WHITE"/>
+ </enums>
+ <enums name="VkPipelineBindPoint" type="enum">
+ <enum value="0" name="VK_PIPELINE_BIND_POINT_GRAPHICS"/>
+ <enum value="1" name="VK_PIPELINE_BIND_POINT_COMPUTE"/>
+ </enums>
+ <enums name="VkPipelineCacheHeaderVersion" type="enum">
+ <enum value="1" name="VK_PIPELINE_CACHE_HEADER_VERSION_ONE"/>
+ </enums>
+ <enums name="VkPrimitiveTopology" type="enum">
+ <enum value="0" name="VK_PRIMITIVE_TOPOLOGY_POINT_LIST"/>
+ <enum value="1" name="VK_PRIMITIVE_TOPOLOGY_LINE_LIST"/>
+ <enum value="2" name="VK_PRIMITIVE_TOPOLOGY_LINE_STRIP"/>
+ <enum value="3" name="VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST"/>
+ <enum value="4" name="VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP"/>
+ <enum value="5" name="VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN"/>
+ <enum value="6" name="VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY"/>
+ <enum value="7" name="VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY"/>
+ <enum value="8" name="VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY"/>
+ <enum value="9" name="VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY"/>
+ <enum value="10" name="VK_PRIMITIVE_TOPOLOGY_PATCH_LIST"/>
+ </enums>
+ <enums name="VkSharingMode" type="enum">
+ <enum value="0" name="VK_SHARING_MODE_EXCLUSIVE"/>
+ <enum value="1" name="VK_SHARING_MODE_CONCURRENT"/>
+ </enums>
+ <enums name="VkIndexType" type="enum">
+ <enum value="0" name="VK_INDEX_TYPE_UINT16"/>
+ <enum value="1" name="VK_INDEX_TYPE_UINT32"/>
+ </enums>
+ <enums name="VkFilter" type="enum">
+ <enum value="0" name="VK_FILTER_NEAREST"/>
+ <enum value="1" name="VK_FILTER_LINEAR"/>
+ </enums>
+ <enums name="VkSamplerMipmapMode" type="enum">
+ <enum value="0" name="VK_SAMPLER_MIPMAP_MODE_NEAREST" comment="Choose nearest mip level"/>
+ <enum value="1" name="VK_SAMPLER_MIPMAP_MODE_LINEAR" comment="Linear filter between mip levels"/>
+ </enums>
+ <enums name="VkSamplerAddressMode" type="enum">
+ <enum value="0" name="VK_SAMPLER_ADDRESS_MODE_REPEAT"/>
+ <enum value="1" name="VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT"/>
+ <enum value="2" name="VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE"/>
+ <enum value="3" name="VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER"/>
+ <!-- <enum value="4" name="VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE" comment="Reserved for VK_KHR_sampler_mirror_clamp_to_edge, do not alias!"/> -->
+ </enums>
+ <enums name="VkCompareOp" type="enum">
+ <enum value="0" name="VK_COMPARE_OP_NEVER"/>
+ <enum value="1" name="VK_COMPARE_OP_LESS"/>
+ <enum value="2" name="VK_COMPARE_OP_EQUAL"/>
+ <enum value="3" name="VK_COMPARE_OP_LESS_OR_EQUAL"/>
+ <enum value="4" name="VK_COMPARE_OP_GREATER"/>
+ <enum value="5" name="VK_COMPARE_OP_NOT_EQUAL"/>
+ <enum value="6" name="VK_COMPARE_OP_GREATER_OR_EQUAL"/>
+ <enum value="7" name="VK_COMPARE_OP_ALWAYS"/>
+ </enums>
+ <enums name="VkPolygonMode" type="enum">
+ <enum value="0" name="VK_POLYGON_MODE_FILL"/>
+ <enum value="1" name="VK_POLYGON_MODE_LINE"/>
+ <enum value="2" name="VK_POLYGON_MODE_POINT"/>
+ </enums>
+ <enums name="VkCullModeFlagBits" type="bitmask">
+ <enum value="0" name="VK_CULL_MODE_NONE"/>
+ <enum bitpos="0" name="VK_CULL_MODE_FRONT_BIT"/>
+ <enum bitpos="1" name="VK_CULL_MODE_BACK_BIT"/>
+ <enum value="0x00000003" name="VK_CULL_MODE_FRONT_AND_BACK"/>
+ </enums>
+ <enums name="VkFrontFace" type="enum">
+ <enum value="0" name="VK_FRONT_FACE_COUNTER_CLOCKWISE"/>
+ <enum value="1" name="VK_FRONT_FACE_CLOCKWISE"/>
+ </enums>
+ <enums name="VkBlendFactor" type="enum">
+ <enum value="0" name="VK_BLEND_FACTOR_ZERO"/>
+ <enum value="1" name="VK_BLEND_FACTOR_ONE"/>
+ <enum value="2" name="VK_BLEND_FACTOR_SRC_COLOR"/>
+ <enum value="3" name="VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR"/>
+ <enum value="4" name="VK_BLEND_FACTOR_DST_COLOR"/>
+ <enum value="5" name="VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR"/>
+ <enum value="6" name="VK_BLEND_FACTOR_SRC_ALPHA"/>
+ <enum value="7" name="VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA"/>
+ <enum value="8" name="VK_BLEND_FACTOR_DST_ALPHA"/>
+ <enum value="9" name="VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA"/>
+ <enum value="10" name="VK_BLEND_FACTOR_CONSTANT_COLOR"/>
+ <enum value="11" name="VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR"/>
+ <enum value="12" name="VK_BLEND_FACTOR_CONSTANT_ALPHA"/>
+ <enum value="13" name="VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA"/>
+ <enum value="14" name="VK_BLEND_FACTOR_SRC_ALPHA_SATURATE"/>
+ <enum value="15" name="VK_BLEND_FACTOR_SRC1_COLOR"/>
+ <enum value="16" name="VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR"/>
+ <enum value="17" name="VK_BLEND_FACTOR_SRC1_ALPHA"/>
+ <enum value="18" name="VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA"/>
+ </enums>
+ <enums name="VkBlendOp" type="enum">
+ <enum value="0" name="VK_BLEND_OP_ADD"/>
+ <enum value="1" name="VK_BLEND_OP_SUBTRACT"/>
+ <enum value="2" name="VK_BLEND_OP_REVERSE_SUBTRACT"/>
+ <enum value="3" name="VK_BLEND_OP_MIN"/>
+ <enum value="4" name="VK_BLEND_OP_MAX"/>
+ </enums>
+ <enums name="VkStencilOp" type="enum">
+ <enum value="0" name="VK_STENCIL_OP_KEEP"/>
+ <enum value="1" name="VK_STENCIL_OP_ZERO"/>
+ <enum value="2" name="VK_STENCIL_OP_REPLACE"/>
+ <enum value="3" name="VK_STENCIL_OP_INCREMENT_AND_CLAMP"/>
+ <enum value="4" name="VK_STENCIL_OP_DECREMENT_AND_CLAMP"/>
+ <enum value="5" name="VK_STENCIL_OP_INVERT"/>
+ <enum value="6" name="VK_STENCIL_OP_INCREMENT_AND_WRAP"/>
+ <enum value="7" name="VK_STENCIL_OP_DECREMENT_AND_WRAP"/>
+ </enums>
+ <enums name="VkLogicOp" type="enum">
+ <enum value="0" name="VK_LOGIC_OP_CLEAR"/>
+ <enum value="1" name="VK_LOGIC_OP_AND"/>
+ <enum value="2" name="VK_LOGIC_OP_AND_REVERSE"/>
+ <enum value="3" name="VK_LOGIC_OP_COPY"/>
+ <enum value="4" name="VK_LOGIC_OP_AND_INVERTED"/>
+ <enum value="5" name="VK_LOGIC_OP_NO_OP"/>
+ <enum value="6" name="VK_LOGIC_OP_XOR"/>
+ <enum value="7" name="VK_LOGIC_OP_OR"/>
+ <enum value="8" name="VK_LOGIC_OP_NOR"/>
+ <enum value="9" name="VK_LOGIC_OP_EQUIVALENT"/>
+ <enum value="10" name="VK_LOGIC_OP_INVERT"/>
+ <enum value="11" name="VK_LOGIC_OP_OR_REVERSE"/>
+ <enum value="12" name="VK_LOGIC_OP_COPY_INVERTED"/>
+ <enum value="13" name="VK_LOGIC_OP_OR_INVERTED"/>
+ <enum value="14" name="VK_LOGIC_OP_NAND"/>
+ <enum value="15" name="VK_LOGIC_OP_SET"/>
+ </enums>
+ <enums name="VkInternalAllocationType" type="enum">
+ <enum value="0" name="VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE"/>
+ </enums>
+ <enums name="VkSystemAllocationScope" type="enum">
+ <enum value="0" name="VK_SYSTEM_ALLOCATION_SCOPE_COMMAND"/>
+ <enum value="1" name="VK_SYSTEM_ALLOCATION_SCOPE_OBJECT"/>
+ <enum value="2" name="VK_SYSTEM_ALLOCATION_SCOPE_CACHE"/>
+ <enum value="3" name="VK_SYSTEM_ALLOCATION_SCOPE_DEVICE"/>
+ <enum value="4" name="VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE"/>
+ </enums>
+ <enums name="VkPhysicalDeviceType" type="enum">
+ <enum value="0" name="VK_PHYSICAL_DEVICE_TYPE_OTHER"/>
+ <enum value="1" name="VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU"/>
+ <enum value="2" name="VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU"/>
+ <enum value="3" name="VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU"/>
+ <enum value="4" name="VK_PHYSICAL_DEVICE_TYPE_CPU"/>
+ </enums>
+ <enums name="VkVertexInputRate" type="enum">
+ <enum value="0" name="VK_VERTEX_INPUT_RATE_VERTEX"/>
+ <enum value="1" name="VK_VERTEX_INPUT_RATE_INSTANCE"/>
+ </enums>
+ <enums name="VkFormat" type="enum" comment="Vulkan format definitions">
+ <enum value="0" name="VK_FORMAT_UNDEFINED"/>
+ <enum value="1" name="VK_FORMAT_R4G4_UNORM_PACK8"/>
+ <enum value="2" name="VK_FORMAT_R4G4B4A4_UNORM_PACK16"/>
+ <enum value="3" name="VK_FORMAT_B4G4R4A4_UNORM_PACK16"/>
+ <enum value="4" name="VK_FORMAT_R5G6B5_UNORM_PACK16"/>
+ <enum value="5" name="VK_FORMAT_B5G6R5_UNORM_PACK16"/>
+ <enum value="6" name="VK_FORMAT_R5G5B5A1_UNORM_PACK16"/>
+ <enum value="7" name="VK_FORMAT_B5G5R5A1_UNORM_PACK16"/>
+ <enum value="8" name="VK_FORMAT_A1R5G5B5_UNORM_PACK16"/>
+ <enum value="9" name="VK_FORMAT_R8_UNORM"/>
+ <enum value="10" name="VK_FORMAT_R8_SNORM"/>
+ <enum value="11" name="VK_FORMAT_R8_USCALED"/>
+ <enum value="12" name="VK_FORMAT_R8_SSCALED"/>
+ <enum value="13" name="VK_FORMAT_R8_UINT"/>
+ <enum value="14" name="VK_FORMAT_R8_SINT"/>
+ <enum value="15" name="VK_FORMAT_R8_SRGB"/>
+ <enum value="16" name="VK_FORMAT_R8G8_UNORM"/>
+ <enum value="17" name="VK_FORMAT_R8G8_SNORM"/>
+ <enum value="18" name="VK_FORMAT_R8G8_USCALED"/>
+ <enum value="19" name="VK_FORMAT_R8G8_SSCALED"/>
+ <enum value="20" name="VK_FORMAT_R8G8_UINT"/>
+ <enum value="21" name="VK_FORMAT_R8G8_SINT"/>
+ <enum value="22" name="VK_FORMAT_R8G8_SRGB"/>
+ <enum value="23" name="VK_FORMAT_R8G8B8_UNORM"/>
+ <enum value="24" name="VK_FORMAT_R8G8B8_SNORM"/>
+ <enum value="25" name="VK_FORMAT_R8G8B8_USCALED"/>
+ <enum value="26" name="VK_FORMAT_R8G8B8_SSCALED"/>
+ <enum value="27" name="VK_FORMAT_R8G8B8_UINT"/>
+ <enum value="28" name="VK_FORMAT_R8G8B8_SINT"/>
+ <enum value="29" name="VK_FORMAT_R8G8B8_SRGB"/>
+ <enum value="30" name="VK_FORMAT_B8G8R8_UNORM"/>
+ <enum value="31" name="VK_FORMAT_B8G8R8_SNORM"/>
+ <enum value="32" name="VK_FORMAT_B8G8R8_USCALED"/>
+ <enum value="33" name="VK_FORMAT_B8G8R8_SSCALED"/>
+ <enum value="34" name="VK_FORMAT_B8G8R8_UINT"/>
+ <enum value="35" name="VK_FORMAT_B8G8R8_SINT"/>
+ <enum value="36" name="VK_FORMAT_B8G8R8_SRGB"/>
+ <enum value="37" name="VK_FORMAT_R8G8B8A8_UNORM"/>
+ <enum value="38" name="VK_FORMAT_R8G8B8A8_SNORM"/>
+ <enum value="39" name="VK_FORMAT_R8G8B8A8_USCALED"/>
+ <enum value="40" name="VK_FORMAT_R8G8B8A8_SSCALED"/>
+ <enum value="41" name="VK_FORMAT_R8G8B8A8_UINT"/>
+ <enum value="42" name="VK_FORMAT_R8G8B8A8_SINT"/>
+ <enum value="43" name="VK_FORMAT_R8G8B8A8_SRGB"/>
+ <enum value="44" name="VK_FORMAT_B8G8R8A8_UNORM"/>
+ <enum value="45" name="VK_FORMAT_B8G8R8A8_SNORM"/>
+ <enum value="46" name="VK_FORMAT_B8G8R8A8_USCALED"/>
+ <enum value="47" name="VK_FORMAT_B8G8R8A8_SSCALED"/>
+ <enum value="48" name="VK_FORMAT_B8G8R8A8_UINT"/>
+ <enum value="49" name="VK_FORMAT_B8G8R8A8_SINT"/>
+ <enum value="50" name="VK_FORMAT_B8G8R8A8_SRGB"/>
+ <enum value="51" name="VK_FORMAT_A8B8G8R8_UNORM_PACK32"/>
+ <enum value="52" name="VK_FORMAT_A8B8G8R8_SNORM_PACK32"/>
+ <enum value="53" name="VK_FORMAT_A8B8G8R8_USCALED_PACK32"/>
+ <enum value="54" name="VK_FORMAT_A8B8G8R8_SSCALED_PACK32"/>
+ <enum value="55" name="VK_FORMAT_A8B8G8R8_UINT_PACK32"/>
+ <enum value="56" name="VK_FORMAT_A8B8G8R8_SINT_PACK32"/>
+ <enum value="57" name="VK_FORMAT_A8B8G8R8_SRGB_PACK32"/>
+ <enum value="58" name="VK_FORMAT_A2R10G10B10_UNORM_PACK32"/>
+ <enum value="59" name="VK_FORMAT_A2R10G10B10_SNORM_PACK32"/>
+ <enum value="60" name="VK_FORMAT_A2R10G10B10_USCALED_PACK32"/>
+ <enum value="61" name="VK_FORMAT_A2R10G10B10_SSCALED_PACK32"/>
+ <enum value="62" name="VK_FORMAT_A2R10G10B10_UINT_PACK32"/>
+ <enum value="63" name="VK_FORMAT_A2R10G10B10_SINT_PACK32"/>
+ <enum value="64" name="VK_FORMAT_A2B10G10R10_UNORM_PACK32"/>
+ <enum value="65" name="VK_FORMAT_A2B10G10R10_SNORM_PACK32"/>
+ <enum value="66" name="VK_FORMAT_A2B10G10R10_USCALED_PACK32"/>
+ <enum value="67" name="VK_FORMAT_A2B10G10R10_SSCALED_PACK32"/>
+ <enum value="68" name="VK_FORMAT_A2B10G10R10_UINT_PACK32"/>
+ <enum value="69" name="VK_FORMAT_A2B10G10R10_SINT_PACK32"/>
+ <enum value="70" name="VK_FORMAT_R16_UNORM"/>
+ <enum value="71" name="VK_FORMAT_R16_SNORM"/>
+ <enum value="72" name="VK_FORMAT_R16_USCALED"/>
+ <enum value="73" name="VK_FORMAT_R16_SSCALED"/>
+ <enum value="74" name="VK_FORMAT_R16_UINT"/>
+ <enum value="75" name="VK_FORMAT_R16_SINT"/>
+ <enum value="76" name="VK_FORMAT_R16_SFLOAT"/>
+ <enum value="77" name="VK_FORMAT_R16G16_UNORM"/>
+ <enum value="78" name="VK_FORMAT_R16G16_SNORM"/>
+ <enum value="79" name="VK_FORMAT_R16G16_USCALED"/>
+ <enum value="80" name="VK_FORMAT_R16G16_SSCALED"/>
+ <enum value="81" name="VK_FORMAT_R16G16_UINT"/>
+ <enum value="82" name="VK_FORMAT_R16G16_SINT"/>
+ <enum value="83" name="VK_FORMAT_R16G16_SFLOAT"/>
+ <enum value="84" name="VK_FORMAT_R16G16B16_UNORM"/>
+ <enum value="85" name="VK_FORMAT_R16G16B16_SNORM"/>
+ <enum value="86" name="VK_FORMAT_R16G16B16_USCALED"/>
+ <enum value="87" name="VK_FORMAT_R16G16B16_SSCALED"/>
+ <enum value="88" name="VK_FORMAT_R16G16B16_UINT"/>
+ <enum value="89" name="VK_FORMAT_R16G16B16_SINT"/>
+ <enum value="90" name="VK_FORMAT_R16G16B16_SFLOAT"/>
+ <enum value="91" name="VK_FORMAT_R16G16B16A16_UNORM"/>
+ <enum value="92" name="VK_FORMAT_R16G16B16A16_SNORM"/>
+ <enum value="93" name="VK_FORMAT_R16G16B16A16_USCALED"/>
+ <enum value="94" name="VK_FORMAT_R16G16B16A16_SSCALED"/>
+ <enum value="95" name="VK_FORMAT_R16G16B16A16_UINT"/>
+ <enum value="96" name="VK_FORMAT_R16G16B16A16_SINT"/>
+ <enum value="97" name="VK_FORMAT_R16G16B16A16_SFLOAT"/>
+ <enum value="98" name="VK_FORMAT_R32_UINT"/>
+ <enum value="99" name="VK_FORMAT_R32_SINT"/>
+ <enum value="100" name="VK_FORMAT_R32_SFLOAT"/>
+ <enum value="101" name="VK_FORMAT_R32G32_UINT"/>
+ <enum value="102" name="VK_FORMAT_R32G32_SINT"/>
+ <enum value="103" name="VK_FORMAT_R32G32_SFLOAT"/>
+ <enum value="104" name="VK_FORMAT_R32G32B32_UINT"/>
+ <enum value="105" name="VK_FORMAT_R32G32B32_SINT"/>
+ <enum value="106" name="VK_FORMAT_R32G32B32_SFLOAT"/>
+ <enum value="107" name="VK_FORMAT_R32G32B32A32_UINT"/>
+ <enum value="108" name="VK_FORMAT_R32G32B32A32_SINT"/>
+ <enum value="109" name="VK_FORMAT_R32G32B32A32_SFLOAT"/>
+ <enum value="110" name="VK_FORMAT_R64_UINT"/>
+ <enum value="111" name="VK_FORMAT_R64_SINT"/>
+ <enum value="112" name="VK_FORMAT_R64_SFLOAT"/>
+ <enum value="113" name="VK_FORMAT_R64G64_UINT"/>
+ <enum value="114" name="VK_FORMAT_R64G64_SINT"/>
+ <enum value="115" name="VK_FORMAT_R64G64_SFLOAT"/>
+ <enum value="116" name="VK_FORMAT_R64G64B64_UINT"/>
+ <enum value="117" name="VK_FORMAT_R64G64B64_SINT"/>
+ <enum value="118" name="VK_FORMAT_R64G64B64_SFLOAT"/>
+ <enum value="119" name="VK_FORMAT_R64G64B64A64_UINT"/>
+ <enum value="120" name="VK_FORMAT_R64G64B64A64_SINT"/>
+ <enum value="121" name="VK_FORMAT_R64G64B64A64_SFLOAT"/>
+ <enum value="122" name="VK_FORMAT_B10G11R11_UFLOAT_PACK32"/>
+ <enum value="123" name="VK_FORMAT_E5B9G9R9_UFLOAT_PACK32"/>
+ <enum value="124" name="VK_FORMAT_D16_UNORM"/>
+ <enum value="125" name="VK_FORMAT_X8_D24_UNORM_PACK32"/>
+ <enum value="126" name="VK_FORMAT_D32_SFLOAT"/>
+ <enum value="127" name="VK_FORMAT_S8_UINT"/>
+ <enum value="128" name="VK_FORMAT_D16_UNORM_S8_UINT"/>
+ <enum value="129" name="VK_FORMAT_D24_UNORM_S8_UINT"/>
+ <enum value="130" name="VK_FORMAT_D32_SFLOAT_S8_UINT"/>
+ <enum value="131" name="VK_FORMAT_BC1_RGB_UNORM_BLOCK"/>
+ <enum value="132" name="VK_FORMAT_BC1_RGB_SRGB_BLOCK"/>
+ <enum value="133" name="VK_FORMAT_BC1_RGBA_UNORM_BLOCK"/>
+ <enum value="134" name="VK_FORMAT_BC1_RGBA_SRGB_BLOCK"/>
+ <enum value="135" name="VK_FORMAT_BC2_UNORM_BLOCK"/>
+ <enum value="136" name="VK_FORMAT_BC2_SRGB_BLOCK"/>
+ <enum value="137" name="VK_FORMAT_BC3_UNORM_BLOCK"/>
+ <enum value="138" name="VK_FORMAT_BC3_SRGB_BLOCK"/>
+ <enum value="139" name="VK_FORMAT_BC4_UNORM_BLOCK"/>
+ <enum value="140" name="VK_FORMAT_BC4_SNORM_BLOCK"/>
+ <enum value="141" name="VK_FORMAT_BC5_UNORM_BLOCK"/>
+ <enum value="142" name="VK_FORMAT_BC5_SNORM_BLOCK"/>
+ <enum value="143" name="VK_FORMAT_BC6H_UFLOAT_BLOCK"/>
+ <enum value="144" name="VK_FORMAT_BC6H_SFLOAT_BLOCK"/>
+ <enum value="145" name="VK_FORMAT_BC7_UNORM_BLOCK"/>
+ <enum value="146" name="VK_FORMAT_BC7_SRGB_BLOCK"/>
+ <enum value="147" name="VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK"/>
+ <enum value="148" name="VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK"/>
+ <enum value="149" name="VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK"/>
+ <enum value="150" name="VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK"/>
+ <enum value="151" name="VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK"/>
+ <enum value="152" name="VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK"/>
+ <enum value="153" name="VK_FORMAT_EAC_R11_UNORM_BLOCK"/>
+ <enum value="154" name="VK_FORMAT_EAC_R11_SNORM_BLOCK"/>
+ <enum value="155" name="VK_FORMAT_EAC_R11G11_UNORM_BLOCK"/>
+ <enum value="156" name="VK_FORMAT_EAC_R11G11_SNORM_BLOCK"/>
+ <enum value="157" name="VK_FORMAT_ASTC_4x4_UNORM_BLOCK"/>
+ <enum value="158" name="VK_FORMAT_ASTC_4x4_SRGB_BLOCK"/>
+ <enum value="159" name="VK_FORMAT_ASTC_5x4_UNORM_BLOCK"/>
+ <enum value="160" name="VK_FORMAT_ASTC_5x4_SRGB_BLOCK"/>
+ <enum value="161" name="VK_FORMAT_ASTC_5x5_UNORM_BLOCK"/>
+ <enum value="162" name="VK_FORMAT_ASTC_5x5_SRGB_BLOCK"/>
+ <enum value="163" name="VK_FORMAT_ASTC_6x5_UNORM_BLOCK"/>
+ <enum value="164" name="VK_FORMAT_ASTC_6x5_SRGB_BLOCK"/>
+ <enum value="165" name="VK_FORMAT_ASTC_6x6_UNORM_BLOCK"/>
+ <enum value="166" name="VK_FORMAT_ASTC_6x6_SRGB_BLOCK"/>
+ <enum value="167" name="VK_FORMAT_ASTC_8x5_UNORM_BLOCK"/>
+ <enum value="168" name="VK_FORMAT_ASTC_8x5_SRGB_BLOCK"/>
+ <enum value="169" name="VK_FORMAT_ASTC_8x6_UNORM_BLOCK"/>
+ <enum value="170" name="VK_FORMAT_ASTC_8x6_SRGB_BLOCK"/>
+ <enum value="171" name="VK_FORMAT_ASTC_8x8_UNORM_BLOCK"/>
+ <enum value="172" name="VK_FORMAT_ASTC_8x8_SRGB_BLOCK"/>
+ <enum value="173" name="VK_FORMAT_ASTC_10x5_UNORM_BLOCK"/>
+ <enum value="174" name="VK_FORMAT_ASTC_10x5_SRGB_BLOCK"/>
+ <enum value="175" name="VK_FORMAT_ASTC_10x6_UNORM_BLOCK"/>
+ <enum value="176" name="VK_FORMAT_ASTC_10x6_SRGB_BLOCK"/>
+ <enum value="177" name="VK_FORMAT_ASTC_10x8_UNORM_BLOCK"/>
+ <enum value="178" name="VK_FORMAT_ASTC_10x8_SRGB_BLOCK"/>
+ <enum value="179" name="VK_FORMAT_ASTC_10x10_UNORM_BLOCK"/>
+ <enum value="180" name="VK_FORMAT_ASTC_10x10_SRGB_BLOCK"/>
+ <enum value="181" name="VK_FORMAT_ASTC_12x10_UNORM_BLOCK"/>
+ <enum value="182" name="VK_FORMAT_ASTC_12x10_SRGB_BLOCK"/>
+ <enum value="183" name="VK_FORMAT_ASTC_12x12_UNORM_BLOCK"/>
+ <enum value="184" name="VK_FORMAT_ASTC_12x12_SRGB_BLOCK"/>
+ </enums>
+ <enums name="VkStructureType" type="enum" comment="Structure type enumerant">
+ <enum value="0" name="VK_STRUCTURE_TYPE_APPLICATION_INFO"/>
+ <enum value="1" name="VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO"/>
+ <enum value="2" name="VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO"/>
+ <enum value="3" name="VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO"/>
+ <enum value="4" name="VK_STRUCTURE_TYPE_SUBMIT_INFO"/>
+ <enum value="5" name="VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO"/>
+ <enum value="6" name="VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE"/>
+ <enum value="7" name="VK_STRUCTURE_TYPE_BIND_SPARSE_INFO"/>
+ <enum value="8" name="VK_STRUCTURE_TYPE_FENCE_CREATE_INFO"/>
+ <enum value="9" name="VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO"/>
+ <enum value="10" name="VK_STRUCTURE_TYPE_EVENT_CREATE_INFO"/>
+ <enum value="11" name="VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO"/>
+ <enum value="12" name="VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO"/>
+ <enum value="13" name="VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO"/>
+ <enum value="14" name="VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO"/>
+ <enum value="15" name="VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO"/>
+ <enum value="16" name="VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO"/>
+ <enum value="17" name="VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO"/>
+ <enum value="18" name="VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO"/>
+ <enum value="19" name="VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO"/>
+ <enum value="20" name="VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO"/>
+ <enum value="21" name="VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO"/>
+ <enum value="22" name="VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO"/>
+ <enum value="23" name="VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO"/>
+ <enum value="24" name="VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO"/>
+ <enum value="25" name="VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO"/>
+ <enum value="26" name="VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO"/>
+ <enum value="27" name="VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO"/>
+ <enum value="28" name="VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO"/>
+ <enum value="29" name="VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO"/>
+ <enum value="30" name="VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO"/>
+ <enum value="31" name="VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO"/>
+ <enum value="32" name="VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO"/>
+ <enum value="33" name="VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO"/>
+ <enum value="34" name="VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO"/>
+ <enum value="35" name="VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET"/>
+ <enum value="36" name="VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET"/>
+ <enum value="37" name="VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO"/>
+ <enum value="38" name="VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO"/>
+ <enum value="39" name="VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO"/>
+ <enum value="40" name="VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO"/>
+ <enum value="41" name="VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO"/>
+ <enum value="42" name="VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO"/>
+ <enum value="43" name="VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO"/>
+ <enum value="44" name="VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER"/>
+ <enum value="45" name="VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER"/>
+ <enum value="46" name="VK_STRUCTURE_TYPE_MEMORY_BARRIER"/>
+ <enum value="47" name="VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO"/> <!-- Reserved for internal use by the loader, layers, and ICDs -->
+ <enum value="48" name="VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO"/> <!-- Reserved for internal use by the loader, layers, and ICDs -->
+ </enums>
+ <enums name="VkSubpassContents" type="enum">
+ <enum value="0" name="VK_SUBPASS_CONTENTS_INLINE"/>
+ <enum value="1" name="VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS"/>
+ </enums>
+ <enums name="VkResult" type="enum" comment="Error and return codes">
+ <!-- Return codes for successful operation execution (positive values) -->
+ <enum value="0" name="VK_SUCCESS" comment="Command completed successfully"/>
+ <enum value="1" name="VK_NOT_READY" comment="A fence or query has not yet completed"/>
+ <enum value="2" name="VK_TIMEOUT" comment="A wait operation has not completed in the specified time"/>
+ <enum value="3" name="VK_EVENT_SET" comment="An event is signaled"/>
+ <enum value="4" name="VK_EVENT_RESET" comment="An event is unsignaled"/>
+ <enum value="5" name="VK_INCOMPLETE" comment="A return array was too small for the result"/>
+ <!-- Error codes (negative values) -->
+ <enum value="-1" name="VK_ERROR_OUT_OF_HOST_MEMORY" comment="A host memory allocation has failed"/>
+ <enum value="-2" name="VK_ERROR_OUT_OF_DEVICE_MEMORY" comment="A device memory allocation has failed"/>
+ <enum value="-3" name="VK_ERROR_INITIALIZATION_FAILED" comment="Initialization of a object has failed"/>
+ <enum value="-4" name="VK_ERROR_DEVICE_LOST" comment="The logical device has been lost. See &lt;&lt;devsandqueues-lost-device&gt;&gt;"/>
+ <enum value="-5" name="VK_ERROR_MEMORY_MAP_FAILED" comment="Mapping of a memory object has failed"/>
+ <enum value="-6" name="VK_ERROR_LAYER_NOT_PRESENT" comment="Layer specified does not exist"/>
+ <enum value="-7" name="VK_ERROR_EXTENSION_NOT_PRESENT" comment="Extension specified does not exist"/>
+ <enum value="-8" name="VK_ERROR_FEATURE_NOT_PRESENT" comment="Requested feature is not available on this device"/>
+ <enum value="-9" name="VK_ERROR_INCOMPATIBLE_DRIVER" comment="Unable to find a Vulkan driver"/>
+ <enum value="-10" name="VK_ERROR_TOO_MANY_OBJECTS" comment="Too many objects of the type have already been created"/>
+ <enum value="-11" name="VK_ERROR_FORMAT_NOT_SUPPORTED" comment="Requested format is not supported on this device"/>
+ <enum value="-12" name="VK_ERROR_FRAGMENTED_POOL" comment="A requested pool allocation has failed due to fragmentation of the pool's memory"/>
+ <unused start="-12"/>
+ </enums>
+ <enums name="VkDynamicState" type="enum">
+ <enum value="0" name="VK_DYNAMIC_STATE_VIEWPORT"/>
+ <enum value="1" name="VK_DYNAMIC_STATE_SCISSOR"/>
+ <enum value="2" name="VK_DYNAMIC_STATE_LINE_WIDTH"/>
+ <enum value="3" name="VK_DYNAMIC_STATE_DEPTH_BIAS"/>
+ <enum value="4" name="VK_DYNAMIC_STATE_BLEND_CONSTANTS"/>
+ <enum value="5" name="VK_DYNAMIC_STATE_DEPTH_BOUNDS"/>
+ <enum value="6" name="VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK"/>
+ <enum value="7" name="VK_DYNAMIC_STATE_STENCIL_WRITE_MASK"/>
+ <enum value="8" name="VK_DYNAMIC_STATE_STENCIL_REFERENCE"/>
+ </enums>
+
+ <!-- Flags -->
+ <enums name="VkQueueFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_QUEUE_GRAPHICS_BIT" comment="Queue supports graphics operations"/>
+ <enum bitpos="1" name="VK_QUEUE_COMPUTE_BIT" comment="Queue supports compute operations"/>
+ <enum bitpos="2" name="VK_QUEUE_TRANSFER_BIT" comment="Queue supports transfer operations"/>
+ <enum bitpos="3" name="VK_QUEUE_SPARSE_BINDING_BIT" comment="Queue supports sparse resource memory management operations"/>
+ </enums>
+ <enums name="VkMemoryPropertyFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT" comment="If otherwise stated, then allocate memory on device"/>
+ <enum bitpos="1" name="VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT" comment="Memory is mappable by host"/>
+ <enum bitpos="2" name="VK_MEMORY_PROPERTY_HOST_COHERENT_BIT" comment="Memory will have i/o coherency. If not set, application may need to use vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges to flush/invalidate host cache"/>
+ <enum bitpos="3" name="VK_MEMORY_PROPERTY_HOST_CACHED_BIT" comment="Memory will be cached by the host"/>
+ <enum bitpos="4" name="VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT" comment="Memory may be allocated by the driver when it is required"/>
+ </enums>
+ <enums name="VkMemoryHeapFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_MEMORY_HEAP_DEVICE_LOCAL_BIT" comment="If set, heap represents device memory"/>
+ </enums>
+ <enums name="VkAccessFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_ACCESS_INDIRECT_COMMAND_READ_BIT" comment="Controls coherency of indirect command reads"/>
+ <enum bitpos="1" name="VK_ACCESS_INDEX_READ_BIT" comment="Controls coherency of index reads"/>
+ <enum bitpos="2" name="VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT" comment="Controls coherency of vertex attribute reads"/>
+ <enum bitpos="3" name="VK_ACCESS_UNIFORM_READ_BIT" comment="Controls coherency of uniform buffer reads"/>
+ <enum bitpos="4" name="VK_ACCESS_INPUT_ATTACHMENT_READ_BIT" comment="Controls coherency of input attachment reads"/>
+ <enum bitpos="5" name="VK_ACCESS_SHADER_READ_BIT" comment="Controls coherency of shader reads"/>
+ <enum bitpos="6" name="VK_ACCESS_SHADER_WRITE_BIT" comment="Controls coherency of shader writes"/>
+ <enum bitpos="7" name="VK_ACCESS_COLOR_ATTACHMENT_READ_BIT" comment="Controls coherency of color attachment reads"/>
+ <enum bitpos="8" name="VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT" comment="Controls coherency of color attachment writes"/>
+ <enum bitpos="9" name="VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT" comment="Controls coherency of depth/stencil attachment reads"/>
+ <enum bitpos="10" name="VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT" comment="Controls coherency of depth/stencil attachment writes"/>
+ <enum bitpos="11" name="VK_ACCESS_TRANSFER_READ_BIT" comment="Controls coherency of transfer reads"/>
+ <enum bitpos="12" name="VK_ACCESS_TRANSFER_WRITE_BIT" comment="Controls coherency of transfer writes"/>
+ <enum bitpos="13" name="VK_ACCESS_HOST_READ_BIT" comment="Controls coherency of host reads"/>
+ <enum bitpos="14" name="VK_ACCESS_HOST_WRITE_BIT" comment="Controls coherency of host writes"/>
+ <enum bitpos="15" name="VK_ACCESS_MEMORY_READ_BIT" comment="Controls coherency of memory reads"/>
+ <enum bitpos="16" name="VK_ACCESS_MEMORY_WRITE_BIT" comment="Controls coherency of memory writes"/>
+ </enums>
+ <enums name="VkBufferUsageFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_BUFFER_USAGE_TRANSFER_SRC_BIT" comment="Can be used as a source of transfer operations"/>
+ <enum bitpos="1" name="VK_BUFFER_USAGE_TRANSFER_DST_BIT" comment="Can be used as a destination of transfer operations"/>
+ <enum bitpos="2" name="VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT" comment="Can be used as TBO"/>
+ <enum bitpos="3" name="VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT" comment="Can be used as IBO"/>
+ <enum bitpos="4" name="VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT" comment="Can be used as UBO"/>
+ <enum bitpos="5" name="VK_BUFFER_USAGE_STORAGE_BUFFER_BIT" comment="Can be used as SSBO"/>
+ <enum bitpos="6" name="VK_BUFFER_USAGE_INDEX_BUFFER_BIT" comment="Can be used as source of fixed-function index fetch (index buffer)"/>
+ <enum bitpos="7" name="VK_BUFFER_USAGE_VERTEX_BUFFER_BIT" comment="Can be used as source of fixed-function vertex fetch (VBO)"/>
+ <enum bitpos="8" name="VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT" comment="Can be the source of indirect parameters (e.g. indirect buffer, parameter buffer)"/>
+ </enums>
+ <enums name="VkBufferCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_BUFFER_CREATE_SPARSE_BINDING_BIT" comment="Buffer should support sparse backing"/>
+ <enum bitpos="1" name="VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT" comment="Buffer should support sparse backing with partial residency"/>
+ <enum bitpos="2" name="VK_BUFFER_CREATE_SPARSE_ALIASED_BIT" comment="Buffer should support constent data access to physical memory ranges mapped into multiple locations of sparse buffers"/>
+ </enums>
+ <enums name="VkShaderStageFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_SHADER_STAGE_VERTEX_BIT"/>
+ <enum bitpos="1" name="VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT"/>
+ <enum bitpos="2" name="VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT"/>
+ <enum bitpos="3" name="VK_SHADER_STAGE_GEOMETRY_BIT"/>
+ <enum bitpos="4" name="VK_SHADER_STAGE_FRAGMENT_BIT"/>
+ <enum bitpos="5" name="VK_SHADER_STAGE_COMPUTE_BIT"/>
+ <enum value="0x0000001F" name="VK_SHADER_STAGE_ALL_GRAPHICS"/>
+ <enum value="0x7FFFFFFF" name="VK_SHADER_STAGE_ALL"/>
+ </enums>
+ <enums name="VkImageUsageFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_IMAGE_USAGE_TRANSFER_SRC_BIT" comment="Can be used as a source of transfer operations"/>
+ <enum bitpos="1" name="VK_IMAGE_USAGE_TRANSFER_DST_BIT" comment="Can be used as a destination of transfer operations"/>
+ <enum bitpos="2" name="VK_IMAGE_USAGE_SAMPLED_BIT" comment="Can be sampled from (SAMPLED_IMAGE and COMBINED_IMAGE_SAMPLER descriptor types)"/>
+ <enum bitpos="3" name="VK_IMAGE_USAGE_STORAGE_BIT" comment="Can be used as storage image (STORAGE_IMAGE descriptor type)"/>
+ <enum bitpos="4" name="VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT" comment="Can be used as framebuffer color attachment"/>
+ <enum bitpos="5" name="VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" comment="Can be used as framebuffer depth/stencil attachment"/>
+ <enum bitpos="6" name="VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT" comment="Image data not needed outside of rendering"/>
+ <enum bitpos="7" name="VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT" comment="Can be used as framebuffer input attachment"/>
+ </enums>
+ <enums name="VkImageCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_IMAGE_CREATE_SPARSE_BINDING_BIT" comment="Image should support sparse backing"/>
+ <enum bitpos="1" name="VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT" comment="Image should support sparse backing with partial residency"/>
+ <enum bitpos="2" name="VK_IMAGE_CREATE_SPARSE_ALIASED_BIT" comment="Image should support constent data access to physical memory ranges mapped into multiple locations of sparse images"/>
+ <enum bitpos="3" name="VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT" comment="Allows image views to have different format than the base image"/>
+ <enum bitpos="4" name="VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT" comment="Allows creating image views with cube type from the created image"/>
+ </enums>
+ <enums name="VkPipelineCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"/>
+ <enum bitpos="1" name="VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"/>
+ <enum bitpos="2" name="VK_PIPELINE_CREATE_DERIVATIVE_BIT"/>
+ </enums>
+ <enums name="VkColorComponentFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_COLOR_COMPONENT_R_BIT"/>
+ <enum bitpos="1" name="VK_COLOR_COMPONENT_G_BIT"/>
+ <enum bitpos="2" name="VK_COLOR_COMPONENT_B_BIT"/>
+ <enum bitpos="3" name="VK_COLOR_COMPONENT_A_BIT"/>
+ </enums>
+ <enums name="VkFenceCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_FENCE_CREATE_SIGNALED_BIT"/>
+ </enums>
+ <enums name="VkFormatFeatureFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" comment="Format can be used for sampled images (SAMPLED_IMAGE and COMBINED_IMAGE_SAMPLER descriptor types)"/>
+ <enum bitpos="1" name="VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" comment="Format can be used for storage images (STORAGE_IMAGE descriptor type)"/>
+ <enum bitpos="2" name="VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" comment="Format supports atomic operations in case it is used for storage images"/>
+ <enum bitpos="3" name="VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" comment="Format can be used for uniform texel buffers (TBOs)"/>
+ <enum bitpos="4" name="VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" comment="Format can be used for storage texel buffers (IBOs)"/>
+ <enum bitpos="5" name="VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" comment="Format supports atomic operations in case it is used for storage texel buffers"/>
+ <enum bitpos="6" name="VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" comment="Format can be used for vertex buffers (VBOs)"/>
+ <enum bitpos="7" name="VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" comment="Format can be used for color attachment images"/>
+ <enum bitpos="8" name="VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" comment="Format supports blending in case it is used for color attachment images"/>
+ <enum bitpos="9" name="VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" comment="Format can be used for depth/stencil attachment images"/>
+ <enum bitpos="10" name="VK_FORMAT_FEATURE_BLIT_SRC_BIT" comment="Format can be used as the source image of blits with vkCmdBlitImage"/>
+ <enum bitpos="11" name="VK_FORMAT_FEATURE_BLIT_DST_BIT" comment="Format can be used as the destination image of blits with vkCmdBlitImage"/>
+ <enum bitpos="12" name="VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT" comment="Format can be filtered with VK_FILTER_LINEAR when being sampled"/>
+ </enums>
+ <enums name="VkQueryControlFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_QUERY_CONTROL_PRECISE_BIT" comment="Require precise results to be collected by the query"/>
+ </enums>
+ <enums name="VkQueryResultFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_QUERY_RESULT_64_BIT" comment="Results of the queries are written to the destination buffer as 64-bit values"/>
+ <enum bitpos="1" name="VK_QUERY_RESULT_WAIT_BIT" comment="Results of the queries are waited on before proceeding with the result copy"/>
+ <enum bitpos="2" name="VK_QUERY_RESULT_WITH_AVAILABILITY_BIT" comment="Besides the results of the query, the availability of the results is also written"/>
+ <enum bitpos="3" name="VK_QUERY_RESULT_PARTIAL_BIT" comment="Copy the partial results of the query even if the final results are not available"/>
+ </enums>
+ <enums name="VkCommandBufferUsageFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT"/>
+ <enum bitpos="1" name="VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT"/>
+ <enum bitpos="2" name="VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT" comment="Command buffer may be submitted/executed more than once simultaneously"/>
+ </enums>
+ <enums name="VkQueryPipelineStatisticFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT" comment="Optional"/>
+ <enum bitpos="1" name="VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT" comment="Optional"/>
+ <enum bitpos="2" name="VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT" comment="Optional"/>
+ <enum bitpos="3" name="VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT" comment="Optional"/>
+ <enum bitpos="4" name="VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT" comment="Optional"/>
+ <enum bitpos="5" name="VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT" comment="Optional"/>
+ <enum bitpos="6" name="VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT" comment="Optional"/>
+ <enum bitpos="7" name="VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT" comment="Optional"/>
+ <enum bitpos="8" name="VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT" comment="Optional"/>
+ <enum bitpos="9" name="VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT" comment="Optional"/>
+ <enum bitpos="10" name="VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT" comment="Optional"/>
+ </enums>
+ <enums name="VkImageAspectFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_IMAGE_ASPECT_COLOR_BIT"/>
+ <enum bitpos="1" name="VK_IMAGE_ASPECT_DEPTH_BIT"/>
+ <enum bitpos="2" name="VK_IMAGE_ASPECT_STENCIL_BIT"/>
+ <enum bitpos="3" name="VK_IMAGE_ASPECT_METADATA_BIT"/>
+ </enums>
+ <enums name="VkSparseImageFormatFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT" comment="Image uses a single mip tail region for all array layers"/>
+ <enum bitpos="1" name="VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT" comment="Image requires mip level dimensions to be an integer multiple of the sparse image block dimensions for non-tail mip levels."/>
+ <enum bitpos="2" name="VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT" comment="Image uses a non-standard sparse image block dimensions"/>
+ </enums>
+ <enums name="VkSparseMemoryBindFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_SPARSE_MEMORY_BIND_METADATA_BIT" comment="Operation binds resource metadata to memory"/>
+ </enums>
+ <enums name="VkPipelineStageFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT" comment="Before subsequent commands are processed"/>
+ <enum bitpos="1" name="VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT" comment="Draw/DispatchIndirect command fetch"/>
+ <enum bitpos="2" name="VK_PIPELINE_STAGE_VERTEX_INPUT_BIT" comment="Vertex/index fetch"/>
+ <enum bitpos="3" name="VK_PIPELINE_STAGE_VERTEX_SHADER_BIT" comment="Vertex shading"/>
+ <enum bitpos="4" name="VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT" comment="Tessellation control shading"/>
+ <enum bitpos="5" name="VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT" comment="Tessellation evaluation shading"/>
+ <enum bitpos="6" name="VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT" comment="Geometry shading"/>
+ <enum bitpos="7" name="VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT" comment="Fragment shading"/>
+ <enum bitpos="8" name="VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT" comment="Early fragment (depth and stencil) tests"/>
+ <enum bitpos="9" name="VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT" comment="Late fragment (depth and stencil) tests"/>
+ <enum bitpos="10" name="VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT" comment="Color attachment writes"/>
+ <enum bitpos="11" name="VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT" comment="Compute shading"/>
+ <enum bitpos="12" name="VK_PIPELINE_STAGE_TRANSFER_BIT" comment="Transfer/copy operations"/>
+ <enum bitpos="13" name="VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT" comment="After previous commands have completed"/>
+ <enum bitpos="14" name="VK_PIPELINE_STAGE_HOST_BIT" comment="Indicates host (CPU) is a source/sink of the dependency"/>
+ <enum bitpos="15" name="VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT" comment="All stages of the graphics pipeline"/>
+ <enum bitpos="16" name="VK_PIPELINE_STAGE_ALL_COMMANDS_BIT" comment="All stages supported on the queue"/>
+ </enums>
+ <enums name="VkCommandPoolCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_COMMAND_POOL_CREATE_TRANSIENT_BIT" comment="Command buffers have a short lifetime"/>
+ <enum bitpos="1" name="VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT" comment="Command buffers may release their memory individually"/>
+ </enums>
+ <enums name="VkCommandPoolResetFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT" comment="Release resources owned by the pool"/>
+ </enums>
+ <enums name="VkCommandBufferResetFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT" comment="Release resources owned by the buffer"/>
+ </enums>
+ <enums name="VkSampleCountFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_SAMPLE_COUNT_1_BIT" comment="Sample count 1 supported"/>
+ <enum bitpos="1" name="VK_SAMPLE_COUNT_2_BIT" comment="Sample count 2 supported"/>
+ <enum bitpos="2" name="VK_SAMPLE_COUNT_4_BIT" comment="Sample count 4 supported"/>
+ <enum bitpos="3" name="VK_SAMPLE_COUNT_8_BIT" comment="Sample count 8 supported"/>
+ <enum bitpos="4" name="VK_SAMPLE_COUNT_16_BIT" comment="Sample count 16 supported"/>
+ <enum bitpos="5" name="VK_SAMPLE_COUNT_32_BIT" comment="Sample count 32 supported"/>
+ <enum bitpos="6" name="VK_SAMPLE_COUNT_64_BIT" comment="Sample count 64 supported"/>
+ </enums>
+ <enums name="VkAttachmentDescriptionFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT" comment="The attachment may alias physical memory of another attachment in the same render pass"/>
+ </enums>
+ <enums name="VkStencilFaceFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_STENCIL_FACE_FRONT_BIT" comment="Front face"/>
+ <enum bitpos="1" name="VK_STENCIL_FACE_BACK_BIT" comment="Back face"/>
+ <enum value="0x00000003" name="VK_STENCIL_FRONT_AND_BACK" comment="Front and back faces"/>
+ </enums>
+ <enums name="VkDescriptorPoolCreateFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT" comment="Descriptor sets may be freed individually"/>
+ </enums>
+ <enums name="VkDependencyFlagBits" type="bitmask">
+ <enum bitpos="0" name="VK_DEPENDENCY_BY_REGION_BIT" comment="Dependency is per pixel region "/>
+ </enums>
+ <!-- WSI extensions -->
+ <enums name="VkPresentModeKHR" type="enum">
+ <enum value="0" name="VK_PRESENT_MODE_IMMEDIATE_KHR"/>
+ <enum value="1" name="VK_PRESENT_MODE_MAILBOX_KHR"/>
+ <enum value="2" name="VK_PRESENT_MODE_FIFO_KHR"/>
+ <enum value="3" name="VK_PRESENT_MODE_FIFO_RELAXED_KHR"/>
+ </enums>
+ <enums name="VkColorSpaceKHR" type="enum">
+ <enum value="0" name="VK_COLOR_SPACE_SRGB_NONLINEAR_KHR"/>
+ </enums>
+ <enums name="VkDisplayPlaneAlphaFlagBitsKHR" type="bitmask">
+ <enum bitpos="0" name="VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR"/>
+ <enum bitpos="1" name="VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR"/>
+ <enum bitpos="2" name="VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR"/>
+ <enum bitpos="3" name="VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR"/>
+ </enums>
+ <enums name="VkCompositeAlphaFlagBitsKHR" type="bitmask">
+ <enum bitpos="0" name="VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR"/>
+ <enum bitpos="1" name="VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR"/>
+ <enum bitpos="2" name="VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR"/>
+ <enum bitpos="3" name="VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR"/>
+ </enums>
+ <enums name="VkSurfaceTransformFlagBitsKHR" type="bitmask">
+ <enum bitpos="0" name="VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR"/>
+ <enum bitpos="1" name="VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR"/>
+ <enum bitpos="2" name="VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR"/>
+ <enum bitpos="3" name="VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR"/>
+ <enum bitpos="4" name="VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR"/>
+ <enum bitpos="5" name="VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR"/>
+ <enum bitpos="6" name="VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR"/>
+ <enum bitpos="7" name="VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR"/>
+ <enum bitpos="8" name="VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR"/>
+ </enums>
+ <enums name="VkDebugReportFlagBitsEXT" type="bitmask">
+ <enum bitpos="0" name="VK_DEBUG_REPORT_INFORMATION_BIT_EXT"/>
+ <enum bitpos="1" name="VK_DEBUG_REPORT_WARNING_BIT_EXT"/>
+ <enum bitpos="2" name="VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT"/>
+ <enum bitpos="3" name="VK_DEBUG_REPORT_ERROR_BIT_EXT"/>
+ <enum bitpos="4" name="VK_DEBUG_REPORT_DEBUG_BIT_EXT"/>
+ </enums>
+ <enums name="VkDebugReportObjectTypeEXT" type="enum">
+ <enum value="0" name="VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT"/>
+ <enum value="1" name="VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT"/>
+ <enum value="2" name="VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT"/>
+ <enum value="3" name="VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT"/>
+ <enum value="4" name="VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT"/>
+ <enum value="5" name="VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT"/>
+ <enum value="6" name="VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT"/>
+ <enum value="7" name="VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT"/>
+ <enum value="8" name="VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT"/>
+ <enum value="9" name="VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT"/>
+ <enum value="10" name="VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT"/>
+ <enum value="11" name="VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT"/>
+ <enum value="12" name="VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT"/>
+ <enum value="13" name="VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT"/>
+ <enum value="14" name="VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT"/>
+ <enum value="15" name="VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT"/>
+ <enum value="16" name="VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT"/>
+ <enum value="17" name="VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT"/>
+ <enum value="18" name="VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT"/>
+ <enum value="19" name="VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT"/>
+ <enum value="20" name="VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT"/>
+ <enum value="21" name="VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT"/>
+ <enum value="22" name="VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT"/>
+ <enum value="23" name="VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT"/>
+ <enum value="24" name="VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT"/>
+ <enum value="25" name="VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT"/>
+ <enum value="26" name="VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT"/>
+ <enum value="27" name="VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT"/>
+ <enum value="28" name="VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT"/>
+ <enum value="29" name="VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT"/>
+ <enum value="30" name="VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT"/>
+ <enum value="31" name="VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT"/>
+ <enum value="32" name="VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT"/>
+ </enums>
+ <enums name="VkDebugReportErrorEXT" type="enum">
+ <enum value="0" name="VK_DEBUG_REPORT_ERROR_NONE_EXT"/> <!-- Used for INFO & other non-error messages -->
+ <enum value="1" name="VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT"/> <!-- Callbacks were not destroyed prior to calling DestroyInstance -->
+ </enums>
+ <enums name="VkRasterizationOrderAMD" type="enum">
+ <enum value="0" name="VK_RASTERIZATION_ORDER_STRICT_AMD"/> <!-- Rasterization order strictly follows API order -->
+ <enum value="1" name="VK_RASTERIZATION_ORDER_RELAXED_AMD"/> <!-- Rasterization order may not follow API order -->
+ </enums>
+ <enums name="VkExternalMemoryHandleTypeFlagBitsNV" type="bitmask">
+ <enum bitpos="0" name="VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV"/>
+ <enum bitpos="1" name="VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV"/>
+ <enum bitpos="2" name="VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV"/>
+ <enum bitpos="3" name="VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV"/>
+ </enums>
+ <enums name="VkExternalMemoryFeatureFlagBitsNV" type="bitmask">
+ <enum bitpos="0" name="VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV"/>
+ <enum bitpos="1" name="VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV"/>
+ <enum bitpos="2" name="VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV"/>
+ </enums>
+ <enums name="VkValidationCheckEXT" type="enum">
+ <enum value="0" name="VK_VALIDATION_CHECK_ALL_EXT"/>
+ <!-- Placeholder for validation enums to be defined for VK_EXT_Validation_flags extension -->
+ </enums>
+ <enums name="VkIndirectCommandsLayoutUsageFlagBitsNVX" type="bitmask">
+ <enum bitpos="0" name="VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX"/> <!-- sequences can be processed in implementation-dependent order -->
+ <enum bitpos="1" name="VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX"/> <!-- likely generated with a high difference in actual sequencesCount and maxSequencesCount -->
+ <enum bitpos="2" name="VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX"/> <!-- likely to contain draw/dispatch calls that are zero-sized -->
+ <enum bitpos="3" name="VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX"/> <!-- custom sequence index permutation (32-bit) is provided -->
+ </enums>
+ <enums name="VkObjectEntryUsageFlagBitsNVX" type="bitmask">
+ <enum bitpos="0" name="VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX"/>
+ <enum bitpos="1" name="VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX"/>
+ </enums>
+ <enums name="VkIndirectCommandsTokenTypeNVX" type="enum">
+ <enum value="0" name="VK_INDIRECT_COMMANDS_TOKEN_PIPELINE_NVX"/> <!-- array of 32bit tableEntry in the object table -->
+ <enum value="1" name="VK_INDIRECT_COMMANDS_TOKEN_DESCRIPTOR_SET_NVX"/> <!-- array of (32 bit tableEntry + variable count 32bit offsets) -->
+ <enum value="2" name="VK_INDIRECT_COMMANDS_TOKEN_INDEX_BUFFER_NVX"/> <!-- array of (32 bit tableEntry + optional 32bit offset) -->
+ <enum value="3" name="VK_INDIRECT_COMMANDS_TOKEN_VERTEX_BUFFER_NVX"/> <!-- array of (32 bit tableEntry + optional 32bit offset) -->
+ <enum value="4" name="VK_INDIRECT_COMMANDS_TOKEN_PUSH_CONSTANT_NVX"/> <!-- array of (32 bit tableEntry + variable count 32bit values ) -->
+ <enum value="5" name="VK_INDIRECT_COMMANDS_TOKEN_DRAW_INDEXED_NVX"/> <!-- array of VkDrawIndexedIndirectCommand -->
+ <enum value="6" name="VK_INDIRECT_COMMANDS_TOKEN_DRAW_NVX"/> <!-- array of VkDrawIndirectCommand -->
+ <enum value="7" name="VK_INDIRECT_COMMANDS_TOKEN_DISPATCH_NVX"/> <!-- array of VkDispatchIndirectCommand -->
+ </enums>
+ <enums name="VkObjectEntryTypeNVX" type="enum">
+ <enum value="0" name="VK_OBJECT_ENTRY_DESCRIPTOR_SET_NVX"/>
+ <enum value="1" name="VK_OBJECT_ENTRY_PIPELINE_NVX"/>
+ <enum value="2" name="VK_OBJECT_ENTRY_INDEX_BUFFER_NVX"/>
+ <enum value="3" name="VK_OBJECT_ENTRY_VERTEX_BUFFER_NVX"/>
+ <enum value="4" name="VK_OBJECT_ENTRY_PUSH_CONSTANT_NVX"/>
+ </enums>
+ <enums name="VkSurfaceCounterFlagBitsEXT" type="bitmask">
+ <enum bitpos="0" name="VK_SURFACE_COUNTER_VBLANK_EXT"/>
+ </enums>
+ <enums name="VkDisplayPowerStateEXT" type="enum">
+ <enum value="0" name="VK_DISPLAY_POWER_STATE_OFF_EXT"/>
+ <enum value="1" name="VK_DISPLAY_POWER_STATE_SUSPEND_EXT"/>
+ <enum value="2" name="VK_DISPLAY_POWER_STATE_ON_EXT"/>
+ </enums>
+ <enums name="VkDeviceEventTypeEXT" type="enum">
+ <enum value="0" name="VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT"/>
+ </enums>
+ <enums name="VkDisplayEventTypeEXT" type="enum">
+ <enum value="0" name="VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT"/>
+ </enums>
+
+ <!-- SECTION: Vulkan command definitions -->
+ <commands>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_INCOMPATIBLE_DRIVER">
+ <proto><type>VkResult</type> <name>vkCreateInstance</name></proto>
+ <param>const <type>VkInstanceCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkInstance</type>* <name>pInstance</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyInstance</name></proto>
+ <param optional="true" externsync="true"><type>VkInstance</type> <name>instance</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
+ <proto><type>VkResult</type> <name>vkEnumeratePhysicalDevices</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPhysicalDeviceCount</name></param>
+ <param optional="true" len="pPhysicalDeviceCount"><type>VkPhysicalDevice</type>* <name>pPhysicalDevices</name></param>
+ </command>
+ <command>
+ <proto><type>PFN_vkVoidFunction</type> <name>vkGetDeviceProcAddr</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param len="null-terminated">const <type>char</type>* <name>pName</name></param>
+ </command>
+ <command>
+ <proto><type>PFN_vkVoidFunction</type> <name>vkGetInstanceProcAddr</name></proto>
+ <param optional="true"><type>VkInstance</type> <name>instance</name></param>
+ <param len="null-terminated">const <type>char</type>* <name>pName</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceQueueFamilyProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pQueueFamilyPropertyCount</name></param>
+ <param optional="true" len="pQueueFamilyPropertyCount"><type>VkQueueFamilyProperties</type>* <name>pQueueFamilyProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceMemoryProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceMemoryProperties</type>* <name>pMemoryProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceFeatures</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceFeatures</type>* <name>pFeatures</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceFormatProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkFormatProperties</type>* <name>pFormatProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_FORMAT_NOT_SUPPORTED">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceImageFormatProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkImageType</type> <name>type</name></param>
+ <param><type>VkImageTiling</type> <name>tiling</name></param>
+ <param><type>VkImageUsageFlags</type> <name>usage</name></param>
+ <param optional="true"><type>VkImageCreateFlags</type> <name>flags</name></param>
+ <param><type>VkImageFormatProperties</type>* <name>pImageFormatProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_FEATURE_NOT_PRESENT,VK_ERROR_TOO_MANY_OBJECTS,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkCreateDevice</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param>const <type>VkDeviceCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDevice</type>* <name>pDevice</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyDevice</name></proto>
+ <param optional="true" externsync="true"><type>VkDevice</type> <name>device</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkEnumerateInstanceLayerProperties</name></proto>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkLayerProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_LAYER_NOT_PRESENT">
+ <proto><type>VkResult</type> <name>vkEnumerateInstanceExtensionProperties</name></proto>
+ <param optional="true" len="null-terminated">const <type>char</type>* <name>pLayerName</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkExtensionProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkEnumerateDeviceLayerProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkLayerProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_LAYER_NOT_PRESENT">
+ <proto><type>VkResult</type> <name>vkEnumerateDeviceExtensionProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="true" len="null-terminated">const <type>char</type>* <name>pLayerName</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkExtensionProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetDeviceQueue</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param><type>uint32_t</type> <name>queueIndex</name></param>
+ <param><type>VkQueue</type>* <name>pQueue</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkQueueSubmit</name></proto>
+ <param externsync="true"><type>VkQueue</type> <name>queue</name></param>
+ <param optional="true"><type>uint32_t</type> <name>submitCount</name></param>
+ <param len="submitCount" externsync="pSubmits[].pWaitSemaphores[],pSubmits[].pSignalSemaphores[]">const <type>VkSubmitInfo</type>* <name>pSubmits</name></param>
+ <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkQueueWaitIdle</name></proto>
+ <param><type>VkQueue</type> <name>queue</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkDeviceWaitIdle</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <implicitexternsyncparams>
+ <param>all sname:VkQueue objects created from pname:device</param>
+ </implicitexternsyncparams>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_TOO_MANY_OBJECTS">
+ <proto><type>VkResult</type> <name>vkAllocateMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkMemoryAllocateInfo</type>* <name>pAllocateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDeviceMemory</type>* <name>pMemory</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkFreeMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_MEMORY_MAP_FAILED">
+ <proto><type>VkResult</type> <name>vkMapMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>VkDeviceSize</type> <name>size</name></param>
+ <param optional="true"><type>VkMemoryMapFlags</type> <name>flags</name></param>
+ <param><type>void</type>** <name>ppData</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkUnmapMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkDeviceMemory</type> <name>memory</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkFlushMappedMemoryRanges</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>memoryRangeCount</name></param>
+ <param len="memoryRangeCount">const <type>VkMappedMemoryRange</type>* <name>pMemoryRanges</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkInvalidateMappedMemoryRanges</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>memoryRangeCount</name></param>
+ <param len="memoryRangeCount">const <type>VkMappedMemoryRange</type>* <name>pMemoryRanges</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetDeviceMemoryCommitment</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param><type>VkDeviceSize</type>* <name>pCommittedMemoryInBytes</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetBufferMemoryRequirements</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkMemoryRequirements</type>* <name>pMemoryRequirements</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkBindBufferMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param><type>VkDeviceSize</type> <name>memoryOffset</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetImageMemoryRequirements</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param><type>VkMemoryRequirements</type>* <name>pMemoryRequirements</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkBindImageMemory</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkImage</type> <name>image</name></param>
+ <param><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param><type>VkDeviceSize</type> <name>memoryOffset</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetImageSparseMemoryRequirements</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pSparseMemoryRequirementCount</name></param>
+ <param optional="true" len="pSparseMemoryRequirementCount"><type>VkSparseImageMemoryRequirements</type>* <name>pSparseMemoryRequirements</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceSparseImageFormatProperties</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkImageType</type> <name>type</name></param>
+ <param><type>VkSampleCountFlagBits</type> <name>samples</name></param>
+ <param><type>VkImageUsageFlags</type> <name>usage</name></param>
+ <param><type>VkImageTiling</type> <name>tiling</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkSparseImageFormatProperties</type>* <name>pProperties</name></param>
+ </command>
+ <command queues="sparse_binding" successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkQueueBindSparse</name></proto>
+ <param externsync="true"><type>VkQueue</type> <name>queue</name></param>
+ <param optional="true"><type>uint32_t</type> <name>bindInfoCount</name></param>
+ <param len="bindInfoCount" externsync="pBindInfo[].pWaitSemaphores[],pBindInfo[].pSignalSemaphores[],pBindInfo[].pBufferBinds[].buffer,pBindInfo[].pImageOpaqueBinds[].image,pBindInfo[].pImageBinds[].image">const <type>VkBindSparseInfo</type>* <name>pBindInfo</name></param>
+ <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateFence</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkFenceCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkFence</type>* <name>pFence</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyFence</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkResetFences</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>fenceCount</name></param>
+ <param len="fenceCount" externsync="true">const <type>VkFence</type>* <name>pFences</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_NOT_READY" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkGetFenceStatus</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkFence</type> <name>fence</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_TIMEOUT" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkWaitForFences</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>fenceCount</name></param>
+ <param len="fenceCount">const <type>VkFence</type>* <name>pFences</name></param>
+ <param><type>VkBool32</type> <name>waitAll</name></param>
+ <param><type>uint64_t</type> <name>timeout</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateSemaphore</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkSemaphoreCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSemaphore</type>* <name>pSemaphore</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroySemaphore</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkSemaphore</type> <name>semaphore</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateEvent</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkEventCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkEvent</type>* <name>pEvent</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyEvent</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkEvent</type> <name>event</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_EVENT_SET,VK_EVENT_RESET" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkGetEventStatus</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkEvent</type> <name>event</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkSetEvent</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkEvent</type> <name>event</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkResetEvent</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkEvent</type> <name>event</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateQueryPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkQueryPoolCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkQueryPool</type>* <name>pQueryPool</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyQueryPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_NOT_READY" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
+ <proto><type>VkResult</type> <name>vkGetQueryPoolResults</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>firstQuery</name></param>
+ <param><type>uint32_t</type> <name>queryCount</name></param>
+ <param><type>size_t</type> <name>dataSize</name></param>
+ <param len="dataSize"><type>void</type>* <name>pData</name></param>
+ <param><type>VkDeviceSize</type> <name>stride</name></param>
+ <param optional="true"><type>VkQueryResultFlags</type> <name>flags</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateBuffer</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkBufferCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkBuffer</type>* <name>pBuffer</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyBuffer</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkBuffer</type> <name>buffer</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateBufferView</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkBufferViewCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkBufferView</type>* <name>pView</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyBufferView</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkBufferView</type> <name>bufferView</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateImage</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkImageCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkImage</type>* <name>pImage</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyImage</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkImage</type> <name>image</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetImageSubresourceLayout</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param>const <type>VkImageSubresource</type>* <name>pSubresource</name></param>
+ <param><type>VkSubresourceLayout</type>* <name>pLayout</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateImageView</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkImageViewCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkImageView</type>* <name>pView</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyImageView</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkImageView</type> <name>imageView</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
+ <proto><type>VkResult</type> <name>vkCreateShaderModule</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkShaderModuleCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkShaderModule</type>* <name>pShaderModule</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyShaderModule</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkShaderModule</type> <name>shaderModule</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreatePipelineCache</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkPipelineCacheCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkPipelineCache</type>* <name>pPipelineCache</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyPipelineCache</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkPipelineCache</type> <name>pipelineCache</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetPipelineCacheData</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkPipelineCache</type> <name>pipelineCache</name></param>
+ <param optional="false,true"><type>size_t</type>* <name>pDataSize</name></param>
+ <param optional="true" len="pDataSize"><type>void</type>* <name>pData</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkMergePipelineCaches</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkPipelineCache</type> <name>dstCache</name></param>
+ <param><type>uint32_t</type> <name>srcCacheCount</name></param>
+ <param len="srcCacheCount">const <type>VkPipelineCache</type>* <name>pSrcCaches</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
+ <proto><type>VkResult</type> <name>vkCreateGraphicsPipelines</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true"><type>VkPipelineCache</type> <name>pipelineCache</name></param>
+ <param><type>uint32_t</type> <name>createInfoCount</name></param>
+ <param len="createInfoCount">const <type>VkGraphicsPipelineCreateInfo</type>* <name>pCreateInfos</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param len="createInfoCount"><type>VkPipeline</type>* <name>pPipelines</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
+ <proto><type>VkResult</type> <name>vkCreateComputePipelines</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true"><type>VkPipelineCache</type> <name>pipelineCache</name></param>
+ <param><type>uint32_t</type> <name>createInfoCount</name></param>
+ <param len="createInfoCount">const <type>VkComputePipelineCreateInfo</type>* <name>pCreateInfos</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param len="createInfoCount"><type>VkPipeline</type>* <name>pPipelines</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyPipeline</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkPipeline</type> <name>pipeline</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreatePipelineLayout</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkPipelineLayoutCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkPipelineLayout</type>* <name>pPipelineLayout</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyPipelineLayout</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkPipelineLayout</type> <name>pipelineLayout</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_TOO_MANY_OBJECTS">
+ <proto><type>VkResult</type> <name>vkCreateSampler</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkSamplerCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSampler</type>* <name>pSampler</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroySampler</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkSampler</type> <name>sampler</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateDescriptorSetLayout</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkDescriptorSetLayoutCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDescriptorSetLayout</type>* <name>pSetLayout</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyDescriptorSetLayout</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkDescriptorSetLayout</type> <name>descriptorSetLayout</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateDescriptorPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkDescriptorPoolCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDescriptorPool</type>* <name>pDescriptorPool</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyDescriptorPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkDescriptorPool</type> <name>descriptorPool</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkResetDescriptorPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkDescriptorPool</type> <name>descriptorPool</name></param>
+ <param optional="true"><type>VkDescriptorPoolResetFlags</type> <name>flags</name></param>
+ <implicitexternsyncparams>
+ <param>any sname:VkDescriptorSet objects allocated from pname:descriptorPool</param>
+ </implicitexternsyncparams>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_FRAGMENTED_POOL">
+ <proto><type>VkResult</type> <name>vkAllocateDescriptorSets</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="pAllocateInfo::descriptorPool">const <type>VkDescriptorSetAllocateInfo</type>* <name>pAllocateInfo</name></param>
+ <param len="pAllocateInfo::descriptorSetCount"><type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkFreeDescriptorSets</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkDescriptorPool</type> <name>descriptorPool</name></param>
+ <param><type>uint32_t</type> <name>descriptorSetCount</name></param>
+ <param noautovalidity="true" externsync="true" len="descriptorSetCount">const <type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkUpdateDescriptorSets</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true"><type>uint32_t</type> <name>descriptorWriteCount</name></param>
+ <param len="descriptorWriteCount" externsync="pDescriptorWrites[].dstSet">const <type>VkWriteDescriptorSet</type>* <name>pDescriptorWrites</name></param>
+ <param optional="true"><type>uint32_t</type> <name>descriptorCopyCount</name></param>
+ <param len="descriptorCopyCount" externsync="pDescriptorCopies[].dstSet">const <type>VkCopyDescriptorSet</type>* <name>pDescriptorCopies</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateFramebuffer</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkFramebufferCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkFramebuffer</type>* <name>pFramebuffer</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyFramebuffer</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkFramebuffer</type> <name>framebuffer</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateRenderPass</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkRenderPassCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkRenderPass</type>* <name>pRenderPass</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyRenderPass</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkRenderPass</type> <name>renderPass</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetRenderAreaGranularity</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkRenderPass</type> <name>renderPass</name></param>
+ <param><type>VkExtent2D</type>* <name>pGranularity</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateCommandPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkCommandPoolCreateInfo</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkCommandPool</type>* <name>pCommandPool</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyCommandPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkResetCommandPool</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
+ <param optional="true"><type>VkCommandPoolResetFlags</type> <name>flags</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkAllocateCommandBuffers</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="pAllocateInfo::commandPool">const <type>VkCommandBufferAllocateInfo</type>* <name>pAllocateInfo</name></param>
+ <param len="pAllocateInfo::commandBufferCount"><type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkFreeCommandBuffers</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
+ <param><type>uint32_t</type> <name>commandBufferCount</name></param>
+ <param noautovalidity="true" externsync="true" len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkBeginCommandBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param>const <type>VkCommandBufferBeginInfo</type>* <name>pBeginInfo</name></param>
+ <implicitexternsyncparams>
+ <param>the sname:VkCommandPool that pname:commandBuffer was allocated from</param>
+ </implicitexternsyncparams>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkEndCommandBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <implicitexternsyncparams>
+ <param>the sname:VkCommandPool that pname:commandBuffer was allocated from</param>
+ </implicitexternsyncparams>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkResetCommandBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param optional="true"><type>VkCommandBufferResetFlags</type> <name>flags</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdBindPipeline</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkPipelineBindPoint</type> <name>pipelineBindPoint</name></param>
+ <param><type>VkPipeline</type> <name>pipeline</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetViewport</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>firstViewport</name></param>
+ <param><type>uint32_t</type> <name>viewportCount</name></param>
+ <param len="viewportCount" noautovalidity="true">const <type>VkViewport</type>* <name>pViewports</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetScissor</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>firstScissor</name></param>
+ <param><type>uint32_t</type> <name>scissorCount</name></param>
+ <param len="scissorCount">const <type>VkRect2D</type>* <name>pScissors</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetLineWidth</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>float</type> <name>lineWidth</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetDepthBias</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>float</type> <name>depthBiasConstantFactor</name></param>
+ <param><type>float</type> <name>depthBiasClamp</name></param>
+ <param><type>float</type> <name>depthBiasSlopeFactor</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetBlendConstants</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param>const <type>float</type> <name>blendConstants</name>[4]</param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetDepthBounds</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>float</type> <name>minDepthBounds</name></param>
+ <param><type>float</type> <name>maxDepthBounds</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetStencilCompareMask</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
+ <param><type>uint32_t</type> <name>compareMask</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetStencilWriteMask</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
+ <param><type>uint32_t</type> <name>writeMask</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetStencilReference</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
+ <param><type>uint32_t</type> <name>reference</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdBindDescriptorSets</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkPipelineBindPoint</type> <name>pipelineBindPoint</name></param>
+ <param><type>VkPipelineLayout</type> <name>layout</name></param>
+ <param><type>uint32_t</type> <name>firstSet</name></param>
+ <param><type>uint32_t</type> <name>descriptorSetCount</name></param>
+ <param len="descriptorSetCount">const <type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
+ <param optional="true"><type>uint32_t</type> <name>dynamicOffsetCount</name></param>
+ <param len="dynamicOffsetCount">const <type>uint32_t</type>* <name>pDynamicOffsets</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdBindIndexBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>VkIndexType</type> <name>indexType</name></param>
+ </command>
+ <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdBindVertexBuffers</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>firstBinding</name></param>
+ <param><type>uint32_t</type> <name>bindingCount</name></param>
+ <param len="bindingCount">const <type>VkBuffer</type>* <name>pBuffers</name></param>
+ <param len="bindingCount">const <type>VkDeviceSize</type>* <name>pOffsets</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDraw</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>vertexCount</name></param>
+ <param><type>uint32_t</type> <name>instanceCount</name></param>
+ <param><type>uint32_t</type> <name>firstVertex</name></param>
+ <param><type>uint32_t</type> <name>firstInstance</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDrawIndexed</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>indexCount</name></param>
+ <param><type>uint32_t</type> <name>instanceCount</name></param>
+ <param><type>uint32_t</type> <name>firstIndex</name></param>
+ <param><type>int32_t</type> <name>vertexOffset</name></param>
+ <param><type>uint32_t</type> <name>firstInstance</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDrawIndirect</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>uint32_t</type> <name>drawCount</name></param>
+ <param><type>uint32_t</type> <name>stride</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDrawIndexedIndirect</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>uint32_t</type> <name>drawCount</name></param>
+ <param><type>uint32_t</type> <name>stride</name></param>
+ </command>
+ <command queues="compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="compute">
+ <proto><type>void</type> <name>vkCmdDispatch</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>x</name></param>
+ <param><type>uint32_t</type> <name>y</name></param>
+ <param><type>uint32_t</type> <name>z</name></param>
+ </command>
+ <command queues="compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="compute">
+ <proto><type>void</type> <name>vkCmdDispatchIndirect</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdCopyBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>srcBuffer</name></param>
+ <param><type>VkBuffer</type> <name>dstBuffer</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkBufferCopy</type>* <name>pRegions</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdCopyImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>srcImage</name></param>
+ <param><type>VkImageLayout</type> <name>srcImageLayout</name></param>
+ <param><type>VkImage</type> <name>dstImage</name></param>
+ <param><type>VkImageLayout</type> <name>dstImageLayout</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkImageCopy</type>* <name>pRegions</name></param>
+ </command>
+ <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdBlitImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>srcImage</name></param>
+ <param><type>VkImageLayout</type> <name>srcImageLayout</name></param>
+ <param><type>VkImage</type> <name>dstImage</name></param>
+ <param><type>VkImageLayout</type> <name>dstImageLayout</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkImageBlit</type>* <name>pRegions</name></param>
+ <param><type>VkFilter</type> <name>filter</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdCopyBufferToImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>srcBuffer</name></param>
+ <param><type>VkImage</type> <name>dstImage</name></param>
+ <param><type>VkImageLayout</type> <name>dstImageLayout</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkBufferImageCopy</type>* <name>pRegions</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdCopyImageToBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>srcImage</name></param>
+ <param><type>VkImageLayout</type> <name>srcImageLayout</name></param>
+ <param><type>VkBuffer</type> <name>dstBuffer</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkBufferImageCopy</type>* <name>pRegions</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdUpdateBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>dstBuffer</name></param>
+ <param><type>VkDeviceSize</type> <name>dstOffset</name></param>
+ <param><type>VkDeviceSize</type> <name>dataSize</name></param>
+ <param len="dataSize">const <type>void</type>* <name>pData</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer" comment="transfer support is only available when VK_KHR_maintenance1 is enabled, as documented in valid usage language in the specification">
+ <proto><type>void</type> <name>vkCmdFillBuffer</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>dstBuffer</name></param>
+ <param><type>VkDeviceSize</type> <name>dstOffset</name></param>
+ <param><type>VkDeviceSize</type> <name>size</name></param>
+ <param><type>uint32_t</type> <name>data</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdClearColorImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param><type>VkImageLayout</type> <name>imageLayout</name></param>
+ <param>const <type>VkClearColorValue</type>* <name>pColor</name></param>
+ <param><type>uint32_t</type> <name>rangeCount</name></param>
+ <param len="rangeCount">const <type>VkImageSubresourceRange</type>* <name>pRanges</name></param>
+ </command>
+ <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdClearDepthStencilImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>image</name></param>
+ <param><type>VkImageLayout</type> <name>imageLayout</name></param>
+ <param>const <type>VkClearDepthStencilValue</type>* <name>pDepthStencil</name></param>
+ <param><type>uint32_t</type> <name>rangeCount</name></param>
+ <param len="rangeCount">const <type>VkImageSubresourceRange</type>* <name>pRanges</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdClearAttachments</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>attachmentCount</name></param>
+ <param len="attachmentCount">const <type>VkClearAttachment</type>* <name>pAttachments</name></param>
+ <param><type>uint32_t</type> <name>rectCount</name></param>
+ <param len="rectCount">const <type>VkClearRect</type>* <name>pRects</name></param>
+ </command>
+ <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdResolveImage</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkImage</type> <name>srcImage</name></param>
+ <param><type>VkImageLayout</type> <name>srcImageLayout</name></param>
+ <param><type>VkImage</type> <name>dstImage</name></param>
+ <param><type>VkImageLayout</type> <name>dstImageLayout</name></param>
+ <param><type>uint32_t</type> <name>regionCount</name></param>
+ <param len="regionCount">const <type>VkImageResolve</type>* <name>pRegions</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdSetEvent</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkEvent</type> <name>event</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>stageMask</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdResetEvent</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkEvent</type> <name>event</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>stageMask</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdWaitEvents</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>eventCount</name></param>
+ <param len="eventCount">const <type>VkEvent</type>* <name>pEvents</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>srcStageMask</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>dstStageMask</name></param>
+ <param optional="true"><type>uint32_t</type> <name>memoryBarrierCount</name></param>
+ <param len="memoryBarrierCount">const <type>VkMemoryBarrier</type>* <name>pMemoryBarriers</name></param>
+ <param optional="true"><type>uint32_t</type> <name>bufferMemoryBarrierCount</name></param>
+ <param len="bufferMemoryBarrierCount">const <type>VkBufferMemoryBarrier</type>* <name>pBufferMemoryBarriers</name></param>
+ <param optional="true"><type>uint32_t</type> <name>imageMemoryBarrierCount</name></param>
+ <param len="imageMemoryBarrierCount">const <type>VkImageMemoryBarrier</type>* <name>pImageMemoryBarriers</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdPipelineBarrier</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>srcStageMask</name></param>
+ <param><type>VkPipelineStageFlags</type> <name>dstStageMask</name></param>
+ <param optional="true"><type>VkDependencyFlags</type> <name>dependencyFlags</name></param>
+ <param optional="true"><type>uint32_t</type> <name>memoryBarrierCount</name></param>
+ <param len="memoryBarrierCount">const <type>VkMemoryBarrier</type>* <name>pMemoryBarriers</name></param>
+ <param optional="true"><type>uint32_t</type> <name>bufferMemoryBarrierCount</name></param>
+ <param len="bufferMemoryBarrierCount">const <type>VkBufferMemoryBarrier</type>* <name>pBufferMemoryBarriers</name></param>
+ <param optional="true"><type>uint32_t</type> <name>imageMemoryBarrierCount</name></param>
+ <param len="imageMemoryBarrierCount">const <type>VkImageMemoryBarrier</type>* <name>pImageMemoryBarriers</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdBeginQuery</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>query</name></param>
+ <param optional="true"><type>VkQueryControlFlags</type> <name>flags</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdEndQuery</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>query</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdResetQueryPool</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>firstQuery</name></param>
+ <param><type>uint32_t</type> <name>queryCount</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdWriteTimestamp</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkPipelineStageFlagBits</type> <name>pipelineStage</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>query</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary" pipeline="transfer">
+ <proto><type>void</type> <name>vkCmdCopyQueryPoolResults</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkQueryPool</type> <name>queryPool</name></param>
+ <param><type>uint32_t</type> <name>firstQuery</name></param>
+ <param><type>uint32_t</type> <name>queryCount</name></param>
+ <param><type>VkBuffer</type> <name>dstBuffer</name></param>
+ <param><type>VkDeviceSize</type> <name>dstOffset</name></param>
+ <param><type>VkDeviceSize</type> <name>stride</name></param>
+ <param optional="true"><type>VkQueryResultFlags</type> <name>flags</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdPushConstants</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkPipelineLayout</type> <name>layout</name></param>
+ <param><type>VkShaderStageFlags</type> <name>stageFlags</name></param>
+ <param><type>uint32_t</type> <name>offset</name></param>
+ <param><type>uint32_t</type> <name>size</name></param>
+ <param len="size">const <type>void</type>* <name>pValues</name></param>
+ </command>
+ <command queues="graphics" renderpass="outside" cmdbufferlevel="primary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdBeginRenderPass</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param>const <type>VkRenderPassBeginInfo</type>* <name>pRenderPassBegin</name></param>
+ <param><type>VkSubpassContents</type> <name>contents</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdNextSubpass</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkSubpassContents</type> <name>contents</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdEndRenderPass</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ </command>
+ <command queues="transfer,graphics,compute" renderpass="both" cmdbufferlevel="primary">
+ <proto><type>void</type> <name>vkCmdExecuteCommands</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>uint32_t</type> <name>commandBufferCount</name></param>
+ <param len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_NATIVE_WINDOW_IN_USE_KHR">
+ <proto><type>VkResult</type> <name>vkCreateAndroidSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkAndroidSurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceDisplayPropertiesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkDisplayPropertiesKHR</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceDisplayPlanePropertiesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkDisplayPlanePropertiesKHR</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetDisplayPlaneSupportedDisplaysKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>planeIndex</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pDisplayCount</name></param>
+ <param optional="true" len="pDisplayCount"><type>VkDisplayKHR</type>* <name>pDisplays</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetDisplayModePropertiesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkDisplayKHR</type> <name>display</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkDisplayModePropertiesKHR</type>* <name>pProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
+ <proto><type>VkResult</type> <name>vkCreateDisplayModeKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param externsync="true"><type>VkDisplayKHR</type> <name>display</name></param>
+ <param>const <type>VkDisplayModeCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDisplayModeKHR</type>* <name>pMode</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetDisplayPlaneCapabilitiesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param externsync="true"><type>VkDisplayModeKHR</type> <name>mode</name></param>
+ <param><type>uint32_t</type> <name>planeIndex</name></param>
+ <param><type>VkDisplayPlaneCapabilitiesKHR</type>* <name>pCapabilities</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateDisplayPlaneSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkDisplaySurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INCOMPATIBLE_DISPLAY_KHR,VK_ERROR_DEVICE_LOST,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkCreateSharedSwapchainsKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>uint32_t</type> <name>swapchainCount</name></param>
+ <param len="swapchainCount" externsync="pCreateInfos[].surface,pCreateInfos[].oldSwapchain">const <type>VkSwapchainCreateInfoKHR</type>* <name>pCreateInfos</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param len="swapchainCount"><type>VkSwapchainKHR</type>* <name>pSwapchains</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateMirSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkMirSurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command>
+ <proto><type>VkBool32</type> <name>vkGetPhysicalDeviceMirPresentationSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param><type>MirConnection</type>* <name>connection</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroySurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param optional="true" externsync="true"><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceSurfaceSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param><type>VkBool32</type>* <name>pSupported</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceSurfaceCapabilitiesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param><type>VkSurfaceCapabilitiesKHR</type>* <name>pSurfaceCapabilities</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceSurfaceFormatsKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pSurfaceFormatCount</name></param>
+ <param optional="true" len="pSurfaceFormatCount"><type>VkSurfaceFormatKHR</type>* <name>pSurfaceFormats</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceSurfacePresentModesKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPresentModeCount</name></param>
+ <param optional="true" len="pPresentModeCount"><type>VkPresentModeKHR</type>* <name>pPresentModes</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST,VK_ERROR_SURFACE_LOST_KHR,VK_ERROR_NATIVE_WINDOW_IN_USE_KHR">
+ <proto><type>VkResult</type> <name>vkCreateSwapchainKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="pCreateInfo.surface,pCreateInfo.oldSwapchain">const <type>VkSwapchainCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSwapchainKHR</type>* <name>pSwapchain</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroySwapchainKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param optional="true" externsync="true"><type>VkSwapchainKHR</type> <name>swapchain</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetSwapchainImagesKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkSwapchainKHR</type> <name>swapchain</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pSwapchainImageCount</name></param>
+ <param optional="true" len="pSwapchainImageCount"><type>VkImage</type>* <name>pSwapchainImages</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_TIMEOUT,VK_NOT_READY,VK_SUBOPTIMAL_KHR" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST,VK_ERROR_OUT_OF_DATE_KHR,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkAcquireNextImageKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkSwapchainKHR</type> <name>swapchain</name></param>
+ <param><type>uint64_t</type> <name>timeout</name></param>
+ <param optional="true" externsync="true"><type>VkSemaphore</type> <name>semaphore</name></param>
+ <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
+ <param><type>uint32_t</type>* <name>pImageIndex</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_SUBOPTIMAL_KHR" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST,VK_ERROR_OUT_OF_DATE_KHR,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkQueuePresentKHR</name></proto>
+ <param externsync="true"><type>VkQueue</type> <name>queue</name></param>
+ <param externsync="pPresentInfo.pWaitSemaphores[],pPresentInfo.pSwapchains[]">const <type>VkPresentInfoKHR</type>* <name>pPresentInfo</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_NATIVE_WINDOW_IN_USE_KHR">
+ <proto><type>VkResult</type> <name>vkCreateViSurfaceNN</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkViSurfaceCreateInfoNN</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateWaylandSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkWaylandSurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command>
+ <proto><type>VkBool32</type> <name>vkGetPhysicalDeviceWaylandPresentationSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param>struct <type>wl_display</type>* <name>display</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateWin32SurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkWin32SurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command>
+ <proto><type>VkBool32</type> <name>vkGetPhysicalDeviceWin32PresentationSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateXlibSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkXlibSurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command>
+ <proto><type>VkBool32</type> <name>vkGetPhysicalDeviceXlibPresentationSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param><type>Display</type>* <name>dpy</name></param>
+ <param><type>VisualID</type> <name>visualID</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateXcbSurfaceKHR</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkXcbSurfaceCreateInfoKHR</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
+ </command>
+ <command>
+ <proto><type>VkBool32</type> <name>vkGetPhysicalDeviceXcbPresentationSupportKHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
+ <param><type>xcb_connection_t</type>* <name>connection</name></param>
+ <param><type>xcb_visualid_t</type> <name>visual_id</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateDebugReportCallbackEXT</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param>const <type>VkDebugReportCallbackCreateInfoEXT</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkDebugReportCallbackEXT</type>* <name>pCallback</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyDebugReportCallbackEXT</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param externsync="true"><type>VkDebugReportCallbackEXT</type> <name>callback</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDebugReportMessageEXT</name></proto>
+ <param><type>VkInstance</type> <name>instance</name></param>
+ <param><type>VkDebugReportFlagsEXT</type> <name>flags</name></param>
+ <param><type>VkDebugReportObjectTypeEXT</type> <name>objectType</name></param>
+ <param><type>uint64_t</type> <name>object</name></param>
+ <param><type>size_t</type> <name>location</name></param>
+ <param><type>int32_t</type> <name>messageCode</name></param>
+ <param len="null-terminated">const <type>char</type>* <name>pLayerPrefix</name></param>
+ <param len="null-terminated">const <type>char</type>* <name>pMessage</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkDebugMarkerSetObjectNameEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="pNameInfo.object"><type>VkDebugMarkerObjectNameInfoEXT</type>* <name>pNameInfo</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkDebugMarkerSetObjectTagEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="pTagInfo.object"><type>VkDebugMarkerObjectTagInfoEXT</type>* <name>pTagInfo</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdDebugMarkerBeginEXT</name></proto>
+ <param><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkDebugMarkerMarkerInfoEXT</type>* <name>pMarkerInfo</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdDebugMarkerEndEXT</name></proto>
+ <param><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdDebugMarkerInsertEXT</name></proto>
+ <param><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkDebugMarkerMarkerInfoEXT</type>* <name>pMarkerInfo</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_FORMAT_NOT_SUPPORTED">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceExternalImageFormatPropertiesNV</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkImageType</type> <name>type</name></param>
+ <param><type>VkImageTiling</type> <name>tiling</name></param>
+ <param><type>VkImageUsageFlags</type> <name>usage</name></param>
+ <param optional="true"><type>VkImageCreateFlags</type> <name>flags</name></param>
+ <param optional="true"><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>externalHandleType</name></param>
+ <param><type>VkExternalImageFormatPropertiesNV</type>* <name>pExternalImageFormatProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_TOO_MANY_OBJECTS,VK_ERROR_OUT_OF_HOST_MEMORY">
+ <proto><type>VkResult</type> <name>vkGetMemoryWin32HandleNV</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkDeviceMemory</type> <name>memory</name></param>
+ <param><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>handleType</name></param>
+ <param><type>HANDLE</type>* <name>pHandle</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDrawIndirectCountAMD</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>VkBuffer</type> <name>countBuffer</name></param>
+ <param><type>VkDeviceSize</type> <name>countBufferOffset</name></param>
+ <param><type>uint32_t</type> <name>maxDrawCount</name></param>
+ <param><type>uint32_t</type> <name>stride</name></param>
+ </command>
+ <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary" pipeline="graphics">
+ <proto><type>void</type> <name>vkCmdDrawIndexedIndirectCountAMD</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param><type>VkBuffer</type> <name>buffer</name></param>
+ <param><type>VkDeviceSize</type> <name>offset</name></param>
+ <param><type>VkBuffer</type> <name>countBuffer</name></param>
+ <param><type>VkDeviceSize</type> <name>countBufferOffset</name></param>
+ <param><type>uint32_t</type> <name>maxDrawCount</name></param>
+ <param><type>uint32_t</type> <name>stride</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="inside" cmdbufferlevel="primary,secondary">
+ <proto><type>void</type> <name>vkCmdProcessCommandsNVX</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param>const <type>VkCmdProcessCommandsInfoNVX</type>* <name>pProcessCommandsInfo</name></param>
+ </command>
+ <command queues="graphics,compute" renderpass="inside" cmdbufferlevel="secondary">
+ <proto><type>void</type> <name>vkCmdReserveSpaceForCommandsNVX</name></proto>
+ <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
+ <param>const <type>VkCmdReserveSpaceForCommandsInfoNVX</type>* <name>pReserveSpaceInfo</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateIndirectCommandsLayoutNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkIndirectCommandsLayoutCreateInfoNVX</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkIndirectCommandsLayoutNVX</type>* <name>pIndirectCommandsLayout</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyIndirectCommandsLayoutNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkIndirectCommandsLayoutNVX</type> <name>indirectCommandsLayout</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateObjectTableNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkObjectTableCreateInfoNVX</type>* <name>pCreateInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkObjectTableNVX</type>* <name>pObjectTable</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyObjectTableNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkObjectTableNVX</type> <name>objectTable</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkRegisterObjectsNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkObjectTableNVX</type> <name>objectTable</name></param>
+ <param><type>uint32_t</type> <name>objectCount</name></param>
+ <param len="objectCount">const <type>VkObjectTableEntryNVX</type>* const* <name>ppObjectTableEntries</name></param>
+ <param len="objectCount">const <type>uint32_t</type>* <name>pObjectIndices</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkUnregisterObjectsNVX</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkObjectTableNVX</type> <name>objectTable</name></param>
+ <param><type>uint32_t</type> <name>objectCount</name></param>
+ <param len="objectCount">const <type>VkObjectEntryTypeNVX</type>* <name>pObjectEntryTypes</name></param>
+ <param len="objectCount">const <type>uint32_t</type>* <name>pObjectIndices</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkDeviceGeneratedCommandsFeaturesNVX</type>* <name>pFeatures</name></param>
+ <param><type>VkDeviceGeneratedCommandsLimitsNVX</type>* <name>pLimits</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceFeatures2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceFeatures2KHR</type>* <name>pFeatures</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceProperties2KHR</type>* <name>pProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceFormatProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkFormat</type> <name>format</name></param>
+ <param><type>VkFormatProperties2KHR</type>* <name>pFormatProperties</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_FORMAT_NOT_SUPPORTED">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceImageFormatProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param>const <type>VkPhysicalDeviceImageFormatInfo2KHR</type>* <name>pImageFormatInfo</name></param>
+ <param><type>VkImageFormatProperties2KHR</type>* <name>pImageFormatProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceQueueFamilyProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pQueueFamilyPropertyCount</name></param>
+ <param optional="true" len="pQueueFamilyPropertyCount"><type>VkQueueFamilyProperties2KHR</type>* <name>pQueueFamilyProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceMemoryProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkPhysicalDeviceMemoryProperties2KHR</type>* <name>pMemoryProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkGetPhysicalDeviceSparseImageFormatProperties2KHR</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param>const <type>VkPhysicalDeviceSparseImageFormatInfo2KHR</type>* <name>pFormatInfo</name></param>
+ <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
+ <param optional="true" len="pPropertyCount"><type>VkSparseImageFormatProperties2KHR</type>* <name>pProperties</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkTrimCommandPoolKHR</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
+ <param optional="true"><type>VkCommandPoolTrimFlagsKHR</type> <name>flags</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkReleaseDisplayEXT</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkDisplayKHR</type> <name>display</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkAcquireXlibDisplayEXT</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>Display</type>* <name>dpy</name></param>
+ <param><type>VkDisplayKHR</type> <name>display</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkGetRandROutputDisplayEXT</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>Display</type>* <name>dpy</name></param>
+ <param><type>RROutput</type> <name>rrOutput</name></param>
+ <param><type>VkDisplayKHR</type>* <name>pDisplay</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkDisplayPowerControlEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkDisplayKHR</type> <name>display</name></param>
+ <param>const <type>VkDisplayPowerInfoEXT</type>* <name>pDisplayPowerInfo</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkRegisterDeviceEventEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkDeviceEventInfoEXT</type>* <name>pDeviceEventInfo</name></param>
+ <param>const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkFence</type>* <name>pFence</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS">
+ <proto><type>VkResult</type> <name>vkRegisterDisplayEventEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkDisplayKHR</type> <name>display</name></param>
+ <param>const <type>VkDisplayEventInfoEXT</type>* <name>pDisplayEventInfo</name></param>
+ <param>const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkFence</type>* <name>pFence</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS,VK_ERROR_DEVICE_LOST,VK_ERROR_OUT_OF_DATE_KHR">
+ <proto><type>VkResult</type> <name>vkGetSwapchainCounterEXT</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkSwapchainKHR</type> <name>swapchain</name></param>
+ <param><type>VkSurfaceCounterFlagBitsEXT</type> <name>counter</name></param>
+ <param><type>uint64_t</type>* <name>pCounterValue</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
+ <proto><type>VkResult</type> <name>vkGetPhysicalDeviceSurfaceCapabilities2EXT</name></proto>
+ <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
+ <param><type>VkSurfaceKHR</type> <name>surface</name></param>
+ <param><type>VkSurfaceCapabilities2EXT</type>* <name>pSurfaceCapabilities</name></param>
+ </command>
+ </commands>
+
+ <!-- SECTION: Vulkan API interface definitions -->
+ <feature api="vulkan" name="VK_VERSION_1_0" number="1.0">
+ <require comment="Header boilerplate">
+ <type name="vk_platform"/>
+ </require>
+ <require comment="API version">
+ <type name="VK_API_VERSION"/>
+ <type name="VK_API_VERSION_1_0"/>
+ <type name="VK_VERSION_MAJOR"/>
+ <type name="VK_VERSION_MINOR"/>
+ <type name="VK_VERSION_PATCH"/>
+ <type name="VK_HEADER_VERSION"/>
+ </require>
+ <require comment="API constants">
+ <enum name="VK_LOD_CLAMP_NONE"/>
+ <enum name="VK_REMAINING_MIP_LEVELS"/>
+ <enum name="VK_REMAINING_ARRAY_LAYERS"/>
+ <enum name="VK_WHOLE_SIZE"/>
+ <enum name="VK_ATTACHMENT_UNUSED"/>
+ <enum name="VK_TRUE"/>
+ <enum name="VK_FALSE"/>
+ <type name="VK_NULL_HANDLE"/>
+ <enum name="VK_QUEUE_FAMILY_IGNORED"/>
+ <enum name="VK_SUBPASS_EXTERNAL"/>
+ <type name="VkPipelineCacheHeaderVersion"/>
+ </require>
+ <require comment="Device initialization">
+ <command name="vkCreateInstance"/>
+ <command name="vkDestroyInstance"/>
+ <command name="vkEnumeratePhysicalDevices"/>
+ <command name="vkGetPhysicalDeviceFeatures"/>
+ <command name="vkGetPhysicalDeviceFormatProperties"/>
+ <command name="vkGetPhysicalDeviceImageFormatProperties"/>
+ <command name="vkGetPhysicalDeviceProperties"/>
+ <command name="vkGetPhysicalDeviceQueueFamilyProperties"/>
+ <command name="vkGetPhysicalDeviceMemoryProperties"/>
+ <command name="vkGetInstanceProcAddr"/>
+ <command name="vkGetDeviceProcAddr"/>
+ </require>
+ <require comment="Device commands">
+ <command name="vkCreateDevice"/>
+ <command name="vkDestroyDevice"/>
+ </require>
+ <require comment="Extension discovery commands">
+ <command name="vkEnumerateInstanceExtensionProperties"/>
+ <command name="vkEnumerateDeviceExtensionProperties"/>
+ </require>
+ <require comment="Layer discovery commands">
+ <command name="vkEnumerateInstanceLayerProperties"/>
+ <command name="vkEnumerateDeviceLayerProperties"/>
+ </require>
+ <require comment="queue commands">
+ <command name="vkGetDeviceQueue"/>
+ <command name="vkQueueSubmit"/>
+ <command name="vkQueueWaitIdle"/>
+ <command name="vkDeviceWaitIdle"/>
+ </require>
+ <require comment="Memory commands">
+ <command name="vkAllocateMemory"/>
+ <command name="vkFreeMemory"/>
+ <command name="vkMapMemory"/>
+ <command name="vkUnmapMemory"/>
+ <command name="vkFlushMappedMemoryRanges"/>
+ <command name="vkInvalidateMappedMemoryRanges"/>
+ <command name="vkGetDeviceMemoryCommitment"/>
+ </require>
+ <require comment="Memory management API commands">
+ <command name="vkBindBufferMemory"/>
+ <command name="vkBindImageMemory"/>
+ <command name="vkGetBufferMemoryRequirements"/>
+ <command name="vkGetImageMemoryRequirements"/>
+ </require>
+ <require comment="Sparse resource memory management API commands">
+ <command name="vkGetImageSparseMemoryRequirements"/>
+ <command name="vkGetPhysicalDeviceSparseImageFormatProperties"/>
+ <command name="vkQueueBindSparse"/>
+ </require>
+ <require comment="Fence commands">
+ <command name="vkCreateFence"/>
+ <command name="vkDestroyFence"/>
+ <command name="vkResetFences"/>
+ <command name="vkGetFenceStatus"/>
+ <command name="vkWaitForFences"/>
+ </require>
+ <require comment="Queue semaphore commands">
+ <command name="vkCreateSemaphore"/>
+ <command name="vkDestroySemaphore"/>
+ </require>
+ <require comment="Event commands">
+ <command name="vkCreateEvent"/>
+ <command name="vkDestroyEvent"/>
+ <command name="vkGetEventStatus"/>
+ <command name="vkSetEvent"/>
+ <command name="vkResetEvent"/>
+ </require>
+ <require comment="Query commands">
+ <command name="vkCreateQueryPool"/>
+ <command name="vkDestroyQueryPool"/>
+ <command name="vkGetQueryPoolResults"/>
+ </require>
+ <require comment="Buffer commands">
+ <command name="vkCreateBuffer"/>
+ <command name="vkDestroyBuffer"/>
+ </require>
+ <require comment="Buffer view commands">
+ <command name="vkCreateBufferView"/>
+ <command name="vkDestroyBufferView"/>
+ </require>
+ <require comment="Image commands">
+ <command name="vkCreateImage"/>
+ <command name="vkDestroyImage"/>
+ <command name="vkGetImageSubresourceLayout"/>
+ </require>
+ <require comment="Image view commands">
+ <command name="vkCreateImageView"/>
+ <command name="vkDestroyImageView"/>
+ </require>
+ <require comment="Shader commands">
+ <command name="vkCreateShaderModule"/>
+ <command name="vkDestroyShaderModule"/>
+ </require>
+ <require comment="Pipeline Cache commands">
+ <command name="vkCreatePipelineCache"/>
+ <command name="vkDestroyPipelineCache"/>
+ <command name="vkGetPipelineCacheData"/>
+ <command name="vkMergePipelineCaches"/>
+ </require>
+ <require comment="Pipeline commands">
+ <command name="vkCreateGraphicsPipelines"/>
+ <command name="vkCreateComputePipelines"/>
+ <command name="vkDestroyPipeline"/>
+ </require>
+ <require comment="Pipeline layout commands">
+ <command name="vkCreatePipelineLayout"/>
+ <command name="vkDestroyPipelineLayout"/>
+ </require>
+ <require comment="Sampler commands">
+ <command name="vkCreateSampler"/>
+ <command name="vkDestroySampler"/>
+ </require>
+ <require comment="Descriptor set commands">
+ <command name="vkCreateDescriptorSetLayout"/>
+ <command name="vkDestroyDescriptorSetLayout"/>
+ <command name="vkCreateDescriptorPool"/>
+ <command name="vkDestroyDescriptorPool"/>
+ <command name="vkResetDescriptorPool"/>
+ <command name="vkAllocateDescriptorSets"/>
+ <command name="vkFreeDescriptorSets"/>
+ <command name="vkUpdateDescriptorSets"/>
+ </require>
+ <require comment="Pass commands">
+ <command name="vkCreateFramebuffer"/>
+ <command name="vkDestroyFramebuffer"/>
+ <command name="vkCreateRenderPass"/>
+ <command name="vkDestroyRenderPass"/>
+ <command name="vkGetRenderAreaGranularity"/>
+ </require>
+ <require comment="Command pool commands">
+ <command name="vkCreateCommandPool"/>
+ <command name="vkDestroyCommandPool"/>
+ <command name="vkResetCommandPool"/>
+ </require>
+ <require comment="Command buffer commands">
+ <command name="vkAllocateCommandBuffers"/>
+ <command name="vkFreeCommandBuffers"/>
+ <command name="vkBeginCommandBuffer"/>
+ <command name="vkEndCommandBuffer"/>
+ <command name="vkResetCommandBuffer"/>
+ </require>
+ <require comment="Command buffer building commands">
+ <command name="vkCmdBindPipeline"/>
+ <command name="vkCmdSetViewport"/>
+ <command name="vkCmdSetScissor"/>
+ <command name="vkCmdSetLineWidth"/>
+ <command name="vkCmdSetDepthBias"/>
+ <command name="vkCmdSetBlendConstants"/>
+ <command name="vkCmdSetDepthBounds"/>
+ <command name="vkCmdSetStencilCompareMask"/>
+ <command name="vkCmdSetStencilWriteMask"/>
+ <command name="vkCmdSetStencilReference"/>
+ <command name="vkCmdBindDescriptorSets"/>
+ <command name="vkCmdBindIndexBuffer"/>
+ <command name="vkCmdBindVertexBuffers"/>
+ <command name="vkCmdDraw"/>
+ <command name="vkCmdDrawIndexed"/>
+ <command name="vkCmdDrawIndirect"/>
+ <command name="vkCmdDrawIndexedIndirect"/>
+ <command name="vkCmdDispatch"/>
+ <command name="vkCmdDispatchIndirect"/>
+ <command name="vkCmdCopyBuffer"/>
+ <command name="vkCmdCopyImage"/>
+ <command name="vkCmdBlitImage"/>
+ <command name="vkCmdCopyBufferToImage"/>
+ <command name="vkCmdCopyImageToBuffer"/>
+ <command name="vkCmdUpdateBuffer"/>
+ <command name="vkCmdFillBuffer"/>
+ <command name="vkCmdClearColorImage"/>
+ <command name="vkCmdClearDepthStencilImage"/>
+ <command name="vkCmdClearAttachments"/>
+ <command name="vkCmdResolveImage"/>
+ <command name="vkCmdSetEvent"/>
+ <command name="vkCmdResetEvent"/>
+ <command name="vkCmdWaitEvents"/>
+ <command name="vkCmdPipelineBarrier"/>
+ <command name="vkCmdBeginQuery"/>
+ <command name="vkCmdEndQuery"/>
+ <command name="vkCmdResetQueryPool"/>
+ <command name="vkCmdWriteTimestamp"/>
+ <command name="vkCmdCopyQueryPoolResults"/>
+ <command name="vkCmdPushConstants"/>
+ <command name="vkCmdBeginRenderPass"/>
+ <command name="vkCmdNextSubpass"/>
+ <command name="vkCmdEndRenderPass"/>
+ <command name="vkCmdExecuteCommands"/>
+ </require>
+ <require comment="Types not directly used by the API">
+ <!-- Include <type name="typename"/> here for e.g. structs that
+ are not parameter types of commands, but still need to be
+ defined in the API.
+ -->
+ <type name="VkBufferMemoryBarrier"/>
+ <type name="VkDispatchIndirectCommand"/>
+ <type name="VkDrawIndexedIndirectCommand"/>
+ <type name="VkDrawIndirectCommand"/>
+ <type name="VkImageMemoryBarrier"/>
+ <type name="VkMemoryBarrier"/>
+ </require>
+ </feature>
+
+ <!-- SECTION: Vulkan extension interface definitions -->
+ <extensions>
+ <!-- WSI extensions -->
+ <extension name="VK_KHR_surface" number="1" type="instance" supported="vulkan">
+ <require>
+ <enum value="25" name="VK_KHR_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_surface&quot;" name="VK_KHR_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" dir="-" extends="VkResult" name="VK_ERROR_SURFACE_LOST_KHR"/>
+ <enum offset="1" dir="-" extends="VkResult" name="VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"/>
+ <enum value="VK_COLOR_SPACE_SRGB_NONLINEAR_KHR" name="VK_COLORSPACE_SRGB_NONLINEAR_KHR"/>
+ <command name="vkDestroySurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceSurfaceSupportKHR"/>
+ <command name="vkGetPhysicalDeviceSurfaceCapabilitiesKHR"/>
+ <command name="vkGetPhysicalDeviceSurfaceFormatsKHR"/>
+ <command name="vkGetPhysicalDeviceSurfacePresentModesKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_swapchain" number="2" type="device" requires="VK_KHR_surface" supported="vulkan">
+ <require>
+ <enum value="68" name="VK_KHR_SWAPCHAIN_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_swapchain&quot;" name="VK_KHR_SWAPCHAIN_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PRESENT_INFO_KHR"/>
+ <enum offset="2" extends="VkImageLayout" name="VK_IMAGE_LAYOUT_PRESENT_SRC_KHR"/>
+ <enum offset="3" extends="VkResult" name="VK_SUBOPTIMAL_KHR"/>
+ <enum offset="4" dir="-" extends="VkResult" name="VK_ERROR_OUT_OF_DATE_KHR"/>
+ <command name="vkCreateSwapchainKHR"/>
+ <command name="vkDestroySwapchainKHR"/>
+ <command name="vkGetSwapchainImagesKHR"/>
+ <command name="vkAcquireNextImageKHR"/>
+ <command name="vkQueuePresentKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_display" number="3" type="instance" requires="VK_KHR_surface" supported="vulkan">
+ <require>
+ <enum value="21" name="VK_KHR_DISPLAY_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_display&quot;" name="VK_KHR_DISPLAY_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkDisplayPlaneAlphaFlagsKHR"/>
+ <type name="VkDisplayPlaneAlphaFlagBitsKHR"/>
+ <type name="VkDisplayPropertiesKHR"/>
+ <type name="VkDisplayModeParametersKHR"/>
+ <type name="VkDisplayModePropertiesKHR"/>
+ <type name="VkDisplayModeCreateInfoKHR"/>
+ <type name="VkDisplayPlaneCapabilitiesKHR"/>
+ <type name="VkDisplayPlanePropertiesKHR"/>
+ <type name="VkDisplaySurfaceCreateInfoKHR"/>
+ <command name="vkGetPhysicalDeviceDisplayPropertiesKHR"/>
+ <command name="vkGetPhysicalDeviceDisplayPlanePropertiesKHR"/>
+ <command name="vkGetDisplayPlaneSupportedDisplaysKHR"/>
+ <command name="vkGetDisplayModePropertiesKHR"/>
+ <command name="vkCreateDisplayModeKHR"/>
+ <command name="vkGetDisplayPlaneCapabilitiesKHR"/>
+ <command name="vkCreateDisplayPlaneSurfaceKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_display_swapchain" number="4" type="device" requires="VK_KHR_swapchain,VK_KHR_display" supported="vulkan">
+ <require>
+ <enum value="9" name="VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_display_swapchain&quot;" name="VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR"/>
+ <enum offset="1" dir="-" extends="VkResult" name="VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"/>
+ <type name="VkDisplayPresentInfoKHR"/>
+ <command name="vkCreateSharedSwapchainsKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_xlib_surface" number="5" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_XLIB_KHR" supported="vulkan">
+ <require>
+ <enum value="6" name="VK_KHR_XLIB_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_xlib_surface&quot;" name="VK_KHR_XLIB_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkXlibSurfaceCreateFlagsKHR"/>
+ <type name="VkXlibSurfaceCreateInfoKHR"/>
+ <command name="vkCreateXlibSurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceXlibPresentationSupportKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_xcb_surface" number="6" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_XCB_KHR" supported="vulkan">
+ <require>
+ <enum value="6" name="VK_KHR_XCB_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_xcb_surface&quot;" name="VK_KHR_XCB_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkXcbSurfaceCreateFlagsKHR"/>
+ <type name="VkXcbSurfaceCreateInfoKHR"/>
+ <command name="vkCreateXcbSurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceXcbPresentationSupportKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_wayland_surface" number="7" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_WAYLAND_KHR" supported="vulkan">
+ <require>
+ <enum value="5" name="VK_KHR_WAYLAND_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_wayland_surface&quot;" name="VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkWaylandSurfaceCreateFlagsKHR"/>
+ <type name="VkWaylandSurfaceCreateInfoKHR"/>
+ <command name="vkCreateWaylandSurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceWaylandPresentationSupportKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_mir_surface" number="8" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_MIR_KHR" supported="vulkan">
+ <require>
+ <enum value="4" name="VK_KHR_MIR_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_mir_surface&quot;" name="VK_KHR_MIR_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkMirSurfaceCreateFlagsKHR"/>
+ <type name="VkMirSurfaceCreateInfoKHR"/>
+ <command name="vkCreateMirSurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceMirPresentationSupportKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_android_surface" number="9" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_ANDROID_KHR" supported="vulkan">
+ <require>
+ <enum value="6" name="VK_KHR_ANDROID_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_android_surface&quot;" name="VK_KHR_ANDROID_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkAndroidSurfaceCreateFlagsKHR"/>
+ <type name="VkAndroidSurfaceCreateInfoKHR"/>
+ <command name="vkCreateAndroidSurfaceKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_win32_surface" number="10" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_WIN32_KHR" supported="vulkan">
+ <require>
+ <enum value="5" name="VK_KHR_WIN32_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_win32_surface&quot;" name="VK_KHR_WIN32_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR"/>
+ <type name="VkWin32SurfaceCreateFlagsKHR"/>
+ <type name="VkWin32SurfaceCreateInfoKHR"/>
+ <command name="vkCreateWin32SurfaceKHR"/>
+ <command name="vkGetPhysicalDeviceWin32PresentationSupportKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_ANDROID_native_buffer" number="11" supported="disabled">
+ <require>
+ <enum value="4" name="VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION"/>
+ <enum value="11" name="VK_ANDROID_NATIVE_BUFFER_NUMBER"/>
+ <enum value="&quot;VK_ANDROID_native_buffer&quot;" name="VK_ANDROID_NATIVE_BUFFER_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_debug_report" number="12" type="instance" author="Google, Inc." contact="Courtney Goeltzenleuchter @courtney" supported="vulkan">
+ <require>
+ <enum value="4" name="VK_EXT_DEBUG_REPORT_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_debug_report&quot;" name="VK_EXT_DEBUG_REPORT_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT"/>
+ <enum offset="1" dir="-" extends="VkResult" name="VK_ERROR_VALIDATION_FAILED_EXT"/>
+ <enum value="VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT" name="VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT"/>
+ <type name="VkDebugReportObjectTypeEXT"/>
+ <type name="VkDebugReportErrorEXT"/>
+ <command name="vkCreateDebugReportCallbackEXT"/>
+ <command name="vkDestroyDebugReportCallbackEXT"/>
+ <command name="vkDebugReportMessageEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_glsl_shader" number="13" type="device" author="NVIDIA" contact="Piers Daniell @pdaniell" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_GLSL_SHADER_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_glsl_shader&quot;" name="VK_NV_GLSL_SHADER_EXTENSION_NAME"/>
+ <enum offset="0" dir="-" extends="VkResult" name="VK_ERROR_INVALID_SHADER_NV"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_1" number="14" author="NVIDIA" contact="Piers Daniell @pdaniell" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_1_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_1&quot;" name="VK_NV_EXTENSION_1_EXTENSION_NAME"/>
+ <enum offset="0" dir="-" extends="VkResult" name="VK_NV_EXTENSION_1_ERROR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_sampler_mirror_clamp_to_edge" type="device" number="15" author="KHR" contact="Tobias Hector @tobias" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_sampler_mirror_clamp_to_edge&quot;" name="VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME"/>
+ <enum value="4" extends="VkSamplerAddressMode" name="VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE" comment="Note that this defines what was previously a core enum, and so uses the 'value' attribute rather than 'offset', and does not have a suffix. This is a special case, and should not be repeated"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_filter_cubic" number="16" type="device" author="IMG" contact="Tobias Hector @tobias" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_IMG_FILTER_CUBIC_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_filter_cubic&quot;" name="VK_IMG_FILTER_CUBIC_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkFilter" name="VK_FILTER_CUBIC_IMG"/>
+ <enum bitpos="13" extends="VkFormatFeatureFlagBits" name="VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" comment="Format can be filtered with VK_FILTER_CUBIC_IMG when being sampled"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_17" number="17" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_17_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_17&quot;" name="VK_AMD_EXTENSION_17_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_18" number="18" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_18_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_18&quot;" name="VK_AMD_EXTENSION_18_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_rasterization_order" number="19" type="device" author="AMD" contact="Daniel Rakos @aqnuep" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_rasterization_order&quot;" name="VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD"/>
+ <type name="VkRasterizationOrderAMD"/>
+ <type name="VkPipelineRasterizationStateRasterizationOrderAMD"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_20" number="20" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_20_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_20&quot;" name="VK_AMD_EXTENSION_20_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_shader_trinary_minmax" number="21" type="device" author="AMD" contact="quentin.lin@amd.com" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_shader_trinary_minmax&quot;" name="VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_shader_explicit_vertex_parameter" number="22" type="device" author="AMD" contact="quentin.lin@amd.com" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_shader_explicit_vertex_parameter&quot;" name="VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_debug_marker" number="23" type="device" author="Baldur Karlsson" contact="baldurk@baldurk.org" supported="vulkan">
+ <require>
+ <enum value="3" name="VK_EXT_DEBUG_MARKER_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_debug_marker&quot;" name="VK_EXT_DEBUG_MARKER_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT"/>
+ <type name="VkDebugMarkerObjectNameInfoEXT"/>
+ <type name="VkDebugMarkerObjectTagInfoEXT"/>
+ <type name="VkDebugMarkerMarkerInfoEXT"/>
+ <command name="vkDebugMarkerSetObjectTagEXT"/>
+ <command name="vkDebugMarkerSetObjectNameEXT"/>
+ <command name="vkCmdDebugMarkerBeginEXT"/>
+ <command name="vkCmdDebugMarkerEndEXT"/>
+ <command name="vkCmdDebugMarkerInsertEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_24" number="24" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_24_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_24&quot;" name="VK_AMD_EXTENSION_24_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_25" number="25" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_25_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_25&quot;" name="VK_AMD_EXTENSION_25_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_gcn_shader" number="26" type="device" author="AMD" contact="dominik.witczak@amd.com" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_GCN_SHADER_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_gcn_shader&quot;" name="VK_AMD_GCN_SHADER_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_dedicated_allocation" number="27" type="device" author="NVIDIA" contact="Jeff Bolz @jbolz" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_dedicated_allocation&quot;" name="VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV"/>
+ <type name="VkDedicatedAllocationImageCreateInfoNV"/>
+ <type name="VkDedicatedAllocationBufferCreateInfoNV"/>
+ <type name="VkDedicatedAllocationMemoryAllocateInfoNV"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_extension_28" number="28" author="NVIDIA" contact="Piers Daniell @pdaniell" supported="disabled">
+ <require>
+ <enum value="0" name="VK_EXT_EXTENSION_28_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_28&quot;" name="VK_EXT_EXTENSION_28_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_29" number="29" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_29_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_29&quot;" name="VK_NVX_EXTENSION_29_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_30" number="30" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_30_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_30&quot;" name="VK_NVX_EXTENSION_30_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_31" number="31" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_31_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_31&quot;" name="VK_NVX_EXTENSION_31_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_32" number="32" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_32_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_32&quot;" name="VK_AMD_EXTENSION_32_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_33" number="33" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_33_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_33&quot;" name="VK_AMD_EXTENSION_33_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_draw_indirect_count" number="34" type="device" author="AMD" contact="Daniel Rakos @aqnuep" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_draw_indirect_count&quot;" name="VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME"/>
+ <command name="vkCmdDrawIndirectCountAMD"/>
+ <command name="vkCmdDrawIndexedIndirectCountAMD"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_35" number="35" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_35_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_35&quot;" name="VK_AMD_EXTENSION_35_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_negative_viewport_height" number="36" type="device" author="AMD" contact="Matthaeus G. Chajdas @anteru" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_negative_viewport_height&quot;" name="VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_gpu_shader_half_float" number="37" type="device" author="AMD" contact="Dominik Witczak @dominikwitczak_amd" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_gpu_shader_half_float&quot;" name="VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_shader_ballot" number="38" type="device" author="AMD" contact="Dominik Witczak @dominikwitczak_amd" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_AMD_SHADER_BALLOT_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_shader_ballot&quot;" name="VK_AMD_SHADER_BALLOT_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_39" number="39" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_39_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_39&quot;" name="VK_AMD_EXTENSION_39_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_40" number="40" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_40_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_40&quot;" name="VK_AMD_EXTENSION_40_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_41" number="41" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_41_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_41&quot;" name="VK_AMD_EXTENSION_41_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_42" number="42" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_42_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_42&quot;" name="VK_AMD_EXTENSION_42_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_43" number="43" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_43_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_43&quot;" name="VK_AMD_EXTENSION_43_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_44" number="44" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_44_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_44&quot;" name="VK_AMD_EXTENSION_44_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_45" number="45" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_45_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_45&quot;" name="VK_AMD_EXTENSION_45_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_46" number="46" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_46_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_46&quot;" name="VK_AMD_EXTENSION_46_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_AMD_extension_47" number="47" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+ <require>
+ <enum value="0" name="VK_AMD_EXTENSION_47_SPEC_VERSION"/>
+ <enum value="&quot;VK_AMD_extension_47&quot;" name="VK_AMD_EXTENSION_47_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_48" number="48" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_48_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_48&quot;" name="VK_NVX_EXTENSION_48_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_GOOGLE_extension_49" number="49" author="GOOGLE" contact="Jean-Francois Roy @jfroy" supported="disabled">
+ <require>
+ <enum value="0" name="VK_GOOGLE_EXTENSION_49_SPEC_VERSION"/>
+ <enum value="&quot;VK_GOOGLE_extension_49&quot;" name="VK_GOOGLE_EXTENSION_49_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_GOOGLE_extension_50" number="50" author="GOOGLE" contact="Jean-Francois Roy @jfroy" supported="disabled">
+ <require>
+ <enum value="0" name="VK_GOOGLE_EXTENSION_50_SPEC_VERSION"/>
+ <enum value="&quot;VK_GOOGLE_extension_50&quot;" name="VK_GOOGLE_EXTENSION_50_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_51" number="51" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_51_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_51&quot;" name="VK_NVX_EXTENSION_51_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_extension_52" number="52" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NVX_EXTENSION_52_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_extension_52&quot;" name="VK_NVX_EXTENSION_52_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_53" number="53" author="NVIDIA" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_53_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_53&quot;" name="VK_NV_EXTENSION_53_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_54" number="54" author="NVIDIA" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_54_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_54&quot;" name="VK_NV_EXTENSION_54_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_format_pvrtc" number="55" type="device" author="IMG" contact="Tobias Hector @tobias" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_IMG_FORMAT_PVRTC_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_format_pvrtc&quot;" name="VK_IMG_FORMAT_PVRTC_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkFormat" name="VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG"/>
+ <enum offset="1" extends="VkFormat" name="VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG"/>
+ <enum offset="2" extends="VkFormat" name="VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG"/>
+ <enum offset="3" extends="VkFormat" name="VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG"/>
+ <enum offset="4" extends="VkFormat" name="VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG"/>
+ <enum offset="5" extends="VkFormat" name="VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG"/>
+ <enum offset="6" extends="VkFormat" name="VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG"/>
+ <enum offset="7" extends="VkFormat" name="VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_external_memory_capabilities" number="56" type="instance" author="NVIDIA" contact="James jones @cubanismo" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_external_memory_capabilities&quot;" name="VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME"/>
+ <type name="VkExternalMemoryHandleTypeFlagsNV"/>
+ <type name="VkExternalMemoryHandleTypeFlagBitsNV"/>
+ <type name="VkExternalMemoryFeatureFlagsNV"/>
+ <type name="VkExternalMemoryFeatureFlagBitsNV"/>
+ <type name="VkExternalImageFormatPropertiesNV"/>
+ <command name="vkGetPhysicalDeviceExternalImageFormatPropertiesNV"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_external_memory" number="57" type="device" requires="VK_NV_external_memory_capabilities" author="NVIDIA" contact="James jones @cubanismo" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_EXTERNAL_MEMORY_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_external_memory&quot;" name="VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV"/>
+ <type name="VkExternalMemoryImageCreateInfoNV"/>
+ <type name="VkExportMemoryAllocateInfoNV"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_external_memory_win32" number="58" type="device" requires="VK_NV_external_memory_capabilities,VK_NV_external_memory" author="NVIDIA" contact="James jones @cubanismo" protect="VK_USE_PLATFORM_WIN32_KHR" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_external_memory_win32&quot;" name="VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV"/>
+ <type name="VkImportMemoryWin32HandleInfoNV"/>
+ <type name="VkExportMemoryWin32HandleInfoNV"/>
+ <command name="vkGetMemoryWin32HandleNV"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_win32_keyed_mutex" number="59" type="device" requires="VK_NV_external_memory_capabilities,VK_NV_external_memory_win32" author="NVIDIA" contact="Carsten Rohde" protect="VK_USE_PLATFORM_WIN32_KHR" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_win32_keyed_mutex&quot;" name="VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV"/>
+ <type name="VkWin32KeyedMutexAcquireReleaseInfoNV"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_get_physical_device_properties2" number="60" author="KHR" contact="Jeff Bolz @jbolz" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_get_physical_device_properties2&quot;" name="VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR"/>
+ <enum offset="3" extends="VkStructureType" name="VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR"/>
+ <enum offset="4" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR"/>
+ <enum offset="5" extends="VkStructureType" name="VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR"/>
+ <enum offset="6" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR"/>
+ <enum offset="7" extends="VkStructureType" name="VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR"/>
+ <enum offset="8" extends="VkStructureType" name="VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR"/>
+ <type name="VkPhysicalDeviceFeatures2KHR"/>
+ <type name="VkPhysicalDeviceProperties2KHR"/>
+ <type name="VkFormatProperties2KHR"/>
+ <type name="VkImageFormatProperties2KHR"/>
+ <type name="VkPhysicalDeviceImageFormatInfo2KHR"/>
+ <type name="VkQueueFamilyProperties2KHR"/>
+ <type name="VkPhysicalDeviceMemoryProperties2KHR"/>
+ <type name="VkSparseImageFormatProperties2KHR"/>
+ <type name="VkPhysicalDeviceSparseImageFormatInfo2KHR"/>
+ <command name="vkGetPhysicalDeviceFeatures2KHR"/>
+ <command name="vkGetPhysicalDeviceProperties2KHR"/>
+ <command name="vkGetPhysicalDeviceFormatProperties2KHR"/>
+ <command name="vkGetPhysicalDeviceImageFormatProperties2KHR"/>
+ <command name="vkGetPhysicalDeviceQueueFamilyProperties2KHR"/>
+ <command name="vkGetPhysicalDeviceMemoryProperties2KHR"/>
+ <command name="vkGetPhysicalDeviceSparseImageFormatProperties2KHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_61" number="61" author="KHR" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_61_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_61&quot;" name="VK_KHR_EXTENSION_61_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_validation_flags" number="62" type="instance" author="Google, Inc." contact="Tobin Ehlis @tobine" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_VALIDATION_FLAGS_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_validation_flags&quot;" name="VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT"/>
+ <type name="VkValidationFlagsEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_NN_vi_surface" number="63" author="NN" contact="Mathias Heyer @mheyer" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_VI_NN" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NN_VI_SURFACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_NN_vi_surface&quot;" name="VK_NN_VI_SURFACE_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN"/>
+ <type name="VkViSurfaceCreateFlagsNN"/>
+ <type name="VkViSurfaceCreateInfoNN"/>
+ <command name="vkCreateViSurfaceNN"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_shader_draw_parameters" number="64" type="device" author="KHR" contact="Daniel Koch @dgkoch" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_shader_draw_parameters&quot;" name="VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_shader_subgroup_ballot" number="65" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_shader_subgroup_ballot&quot;" name="VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_shader_subgroup_vote" number="66" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_shader_subgroup_vote&quot;" name="VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_ARM_extension_01" number="67" type="device" author="ARM" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+ <require>
+ <enum value="0" name="VK_ARM_EXTENSION_01_SPEC_VERSION"/>
+ <enum value="&quot;VK_ARM_extension_01&quot;" name="VK_ARM_EXTENSION_01_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_ARM_extension_02" number="68" type="device" author="ARM" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+ <require>
+ <enum value="0" name="VK_ARM_EXTENSION_02_SPEC_VERSION"/>
+ <enum value="&quot;VK_ARM_extension_02&quot;" name="VK_ARM_EXTENSION_02_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_69" number="69" type="device" author="IMG" contact="Tobias Hector @tobias" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_69_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_69&quot;" name="VK_IMG_EXTENSION_69_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_maintenance1" number="70" author="KHR" contact="Piers Daniell @pdaniell" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_KHR_MAINTENANCE1_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_maintenance1&quot;" name="VK_KHR_MAINTENANCE1_EXTENSION_NAME"/>
+ <enum offset="0" dir="-" extends="VkResult" name="VK_ERROR_OUT_OF_POOL_MEMORY_KHR"/>
+ <enum bitpos="14" extends="VkFormatFeatureFlagBits" name="VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR" comment="Format can be used as the source image of image transfer commands"/>
+ <enum bitpos="15" extends="VkFormatFeatureFlagBits" name="VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR" comment="Format can be used as the destination image of image transfer commands"/>
+ <enum bitpos="5" extends="VkImageCreateFlagBits" name="VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR" comment="The 3D image can be viewed as a 2D or 2D array image"/>
+ <command name="vkTrimCommandPoolKHR"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_71" number="71" author="KHR" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_71_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_71&quot;" name="VK_KHR_EXTENSION_71_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_72" number="72" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_72_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_72&quot;" name="VK_KHR_EXTENSION_72_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_73" number="73" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_73_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_73&quot;" name="VK_KHR_EXTENSION_73_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_74" number="74" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_74_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_74&quot;" name="VK_KHR_EXTENSION_74_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_75" number="75" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_75_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_75&quot;" name="VK_KHR_EXTENSION_75_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_76" number="76" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_76_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_76&quot;" name="VK_KHR_EXTENSION_76_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_77" number="77" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_77_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_77&quot;" name="VK_KHR_EXTENSION_77_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_78" number="78" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_78_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_78&quot;" name="VK_KHR_EXTENSION_78_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_79" number="79" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_79_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_79&quot;" name="VK_KHR_EXTENSION_79_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_80" number="80" author="KHR" contact="James Jones @cubanismo" supported="disable">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_80_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_80&quot;" name="VK_KHR_EXTENSION_80_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_81" number="81" author="KHR" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_81_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_81&quot;" name="VK_KHR_EXTENSION_81_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_82" number="82" author="KHR" contact="Jeff Bolz @jbolz" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_82_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_82&quot;" name="VK_KHR_EXTENSION_82_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_83" number="83" author="KHR" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_83_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_83&quot;" name="VK_KHR_EXTENSION_83_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_84" number="84" author="KHR" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_84_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_84&quot;" name="VK_KHR_EXTENSION_84_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_85" number="85" author="KHR" contact="Ian Elliott @ianelliott" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_85_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_85&quot;" name="VK_KHR_EXTENSION_85_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_86" number="86" author="KHR" contact="Markus Tavenrath @mtavenrath" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_86_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_86&quot;" name="VK_KHR_EXTENSION_86_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NVX_device_generated_commands" number="87" type="device" author="NVIDIA" contact="Christoph Kubisch @pixeljetstream" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION"/>
+ <enum value="&quot;VK_NVX_device_generated_commands&quot;" name="VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX"/>
+ <enum offset="3" extends="VkStructureType" name="VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX"/>
+ <enum offset="4" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX"/>
+ <enum offset="5" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX"/>
+ <enum bitpos="17" extends="VkPipelineStageFlagBits" name="VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX"/>
+ <enum bitpos="17" extends="VkAccessFlagBits" name="VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX"/>
+ <enum bitpos="18" extends="VkAccessFlagBits" name="VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX"/>
+ <type name="VkObjectTableNVX"/>
+ <type name="VkIndirectCommandsLayoutNVX"/>
+ <type name="VkIndirectCommandsLayoutUsageFlagsNVX"/>
+ <type name="VkObjectEntryUsageFlagsNVX"/>
+ <type name="VkIndirectCommandsLayoutUsageFlagBitsNVX"/>
+ <type name="VkIndirectCommandsTokenTypeNVX"/>
+ <type name="VkObjectEntryUsageFlagBitsNVX"/>
+ <type name="VkObjectEntryTypeNVX"/>
+ <type name="VkDeviceGeneratedCommandsFeaturesNVX"/>
+ <type name="VkDeviceGeneratedCommandsLimitsNVX"/>
+ <type name="VkIndirectCommandsTokenNVX"/>
+ <type name="VkIndirectCommandsLayoutTokenNVX"/>
+ <type name="VkIndirectCommandsLayoutCreateInfoNVX"/>
+ <type name="VkCmdProcessCommandsInfoNVX"/>
+ <type name="VkCmdReserveSpaceForCommandsInfoNVX"/>
+ <type name="VkObjectTableCreateInfoNVX"/>
+ <type name="VkObjectTableEntryNVX"/>
+ <type name="VkObjectTablePipelineEntryNVX"/>
+ <type name="VkObjectTableDescriptorSetEntryNVX"/>
+ <type name="VkObjectTableVertexBufferEntryNVX"/>
+ <type name="VkObjectTableIndexBufferEntryNVX"/>
+ <type name="VkObjectTablePushConstantEntryNVX"/>
+ <command name="vkCmdProcessCommandsNVX"/>
+ <command name="vkCmdReserveSpaceForCommandsNVX"/>
+ <command name="vkCreateIndirectCommandsLayoutNVX"/>
+ <command name="vkDestroyIndirectCommandsLayoutNVX"/>
+ <command name="vkCreateObjectTableNVX"/>
+ <command name="vkDestroyObjectTableNVX"/>
+ <command name="vkRegisterObjectsNVX"/>
+ <command name="vkUnregisterObjectsNVX"/>
+ <command name="vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_88" number="88" author="NV" contact="Eric Werness @ewerness" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_88_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_88&quot;" name="VK_KHR_EXTENSION_88_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_direct_mode_display" number="89" type="instance" requires="VK_KHR_display" author="NVIDIA" contact="James Jones @cubanismo" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_direct_mode_display&quot;" name="VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME"/>
+ <command name="vkReleaseDisplayEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_acquire_xlib_display" number="90" type="instance" requires="VK_EXT_direct_mode_display,VK_KHR_display" author="NVIDIA" contact="James Jones @cubanismo" protect="VK_USE_PLATFORM_XLIB_XRANDR_EXT" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_acquire_xlib_display&quot;" name="VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME"/>
+ <command name="vkAcquireXlibDisplayEXT"/>
+ <command name="vkGetRandROutputDisplayEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_display_surface_counter" number="91" type="instance" requires="VK_KHR_display" author="NVIDIA" contact="James Jones @cubanismo" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_display_surface_counter&quot;" name="VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT"/>
+ <type name="VkSurfaceCounterFlagsEXT"/>
+ <type name="VkSurfaceCounterFlagBitsEXT"/>
+ <type name="VkSurfaceCapabilities2EXT"/>
+ <command name="vkGetPhysicalDeviceSurfaceCapabilities2EXT"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_display_control" number="92" type="device" requires="VK_KHR_display,VK_EXT_display_surface_counter,VK_KHR_swapchain" author="NVIDIA" contact="James Jones @cubanismo" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_EXT_DISPLAY_CONTROL_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_display_control&quot;" name="VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT"/>
+ <enum offset="2" extends="VkStructureType" name="VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT"/>
+ <enum offset="3" extends="VkStructureType" name="VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT"/>
+ <type name="VkDisplayPowerStateEXT"/>
+ <type name="VkDeviceEventTypeEXT"/>
+ <type name="VkDisplayEventTypeEXT"/>
+ <type name="VkDisplayPowerInfoEXT"/>
+ <type name="VkDeviceEventInfoEXT"/>
+ <type name="VkDisplayEventInfoEXT"/>
+ <type name="VkSwapchainCounterCreateInfoEXT"/>
+ <command name="vkDisplayPowerControlEXT"/>
+ <command name="vkRegisterDeviceEventEXT"/>
+ <command name="vkRegisterDisplayEventEXT"/>
+ <command name="vkGetSwapchainCounterEXT"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_93" number="93" author="GOOGLE" contact="Ian Elliott @ianelliott" supported="disabled">
+ <require>
+ <enum value="0" name="VK_GOOGLE_EXTENSION_93_SPEC_VERSION"/>
+ <enum value="&quot;VK_GOOGLE_extension_93&quot;" name="VK_GOOGLE_EXTENSION_93_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_94" number="94" author="Codeplay" contact="Neil Henning @neil_henning" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_94_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_94&quot;" name="VK_KHR_EXTENSION_94_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_95" number="95" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_95_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_95&quot;" name="VK_NV_EXTENSION_95_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_96" number="96" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_96_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_96&quot;" name="VK_NV_EXTENSION_96_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_97" number="97" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_97_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_97&quot;" name="VK_NV_EXTENSION_97_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_98" number="98" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_98_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_98&quot;" name="VK_NV_EXTENSION_98_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_99" number="99" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_99_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_99&quot;" name="VK_NV_EXTENSION_99_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_100" number="100" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_100_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_100&quot;" name="VK_NV_EXTENSION_100_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_101" number="101" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_101_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_101&quot;" name="VK_NV_EXTENSION_101_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_102" number="102" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_102_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_102&quot;" name="VK_NV_EXTENSION_102_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_103" number="103" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_103_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_103&quot;" name="VK_NV_EXTENSION_103_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_NV_extension_104" number="104" author="NVIDIA" contact="Mathias Schott @mschott" supported="disabled">
+ <require>
+ <enum value="0" name="VK_NV_EXTENSION_104_SPEC_VERSION"/>
+ <enum value="&quot;VK_NV_extension_104&quot;" name="VK_NV_EXTENSION_104_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_swapchain_colorspace" number="105" author="GOOGLE" contact="Courtney Goeltzenleuchter @courtneygo" requires="VK_KHR_surface" supported="vulkan">
+ <require>
+ <enum value="1" name="VK_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_swapchain_colorspace&quot;" name="VK_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME"/>
+ <enum offset="1" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT"/>
+ <enum offset="2" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT"/>
+ <enum offset="3" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_SCRGB_LINEAR_EXT"/>
+ <enum offset="4" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_SCRGB_NONLINEAR_EXT"/>
+ <enum offset="5" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_DCI_P3_LINEAR_EXT"/>
+ <enum offset="6" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT"/>
+ <enum offset="7" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_BT709_LINEAR_EXT"/>
+ <enum offset="8" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_BT709_NONLINEAR_EXT"/>
+ <enum offset="9" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_BT2020_LINEAR_EXT"/>
+ <enum offset="10" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_BT2020_NONLINEAR_EXT"/>
+ <enum offset="11" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT"/>
+ <enum offset="12" extends="VkColorSpaceKHR" name="VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT"/>
+ </require>
+ </extension>
+ <extension name="VK_EXT_extension_106" number="106" author="GOOGLE" contact="Courtney Goeltzenleuchter @courtneygo" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_106_SPEC_VERSION"/>
+ <enum value="&quot;VK_EXT_extension_106&quot;" name="VK_KHR_EXTENSION_106_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_107" number="107" author="IMG" contact="Michael Worcester @michaelworcester" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_107_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_107&quot;" name="VK_IMG_EXTENSION_107_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_108" number="108" author="IMG" contact="Michael Worcester @michaelworcester" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_108_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_108&quot;" name="VK_IMG_EXTENSION_108_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_109" number="109" author="IMG" contact="Michael Worcester @michaelworcester" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_109_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_109&quot;" name="VK_IMG_EXTENSION_109_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_110" number="110" author="IMG" contact="Michael Worcester @michaelworcester" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_110_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_110&quot;" name="VK_IMG_EXTENSION_110_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_IMG_extension_111" number="111" author="IMG" contact="Michael Worcester @michaelworcester" supported="disabled">
+ <require>
+ <enum value="0" name="VK_IMG_EXTENSION_111_SPEC_VERSION"/>
+ <enum value="&quot;VK_IMG_extension_111&quot;" name="VK_IMG_EXTENSION_111_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_112" number="112" author="KHR" contact="Alon Or-bach @alonorbach" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_112_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_112&quot;" name="VK_KHR_EXTENSION_112_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_113" number="113" author="KHX" contact="Cass Everitt @casseveritt" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_113_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_113&quot;" name="VK_KHR_EXTENSION_113_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_114" number="114" author="KHX" contact="Cass Everitt @casseveritt" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_114_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_114&quot;" name="VK_KHR_EXTENSION_114_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_115" number="115" author="KHX" contact="Cass Everitt @casseveritt" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_115_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_115&quot;" name="VK_KHR_EXTENSION_115_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_116" number="116" author="KHX" contact="Cass Everitt @casseveritt" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_116_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_116&quot;" name="VK_KHR_EXTENSION_116_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ <extension name="VK_KHR_extension_117" number="117" author="KHR" contact="Kenneth Benzie @kbenzie" supported="disabled">
+ <require>
+ <enum value="0" name="VK_KHR_EXTENSION_117_SPEC_VERSION"/>
+ <enum value="&quot;VK_KHR_extension_117&quot;" name="VK_KHR_EXTENSION_117_EXTENSION_NAME"/>
+ </require>
+ </extension>
+ </extensions>
+</registry>
diff --git a/src/gui/vulkan/vulkan.pri b/src/gui/vulkan/vulkan.pri
new file mode 100644
index 0000000000..dab8725de7
--- /dev/null
+++ b/src/gui/vulkan/vulkan.pri
@@ -0,0 +1,52 @@
+qtConfig(vulkan) {
+ CONFIG += generated_privates
+
+ HEADERS += \
+ vulkan/qvulkaninstance.h \
+ vulkan/qplatformvulkaninstance.h \
+ vulkan/qvulkanwindow.h \
+ vulkan/qvulkanwindow_p.h
+
+ SOURCES += \
+ vulkan/qvulkaninstance.cpp \
+ vulkan/qplatformvulkaninstance.cpp \
+ vulkan/qvulkanfunctions.cpp \
+ vulkan/qvulkanwindow.cpp
+
+ # Applications must inherit the Vulkan header include path.
+ QMAKE_USE += vulkan/nolink
+}
+
+# Generate qvulkanfunctions.h, qvulkanfunctions_p.h, qvulkanfunctions_p.cpp
+QMAKE_QVKGEN_INPUT = vulkan/vk.xml
+QMAKE_QVKGEN_LICENSE_HEADER = $$QT_SOURCE_TREE/header.LGPL
+qtPrepareTool(QMAKE_QVKGEN, qvkgen)
+
+qvkgen_h.commands = $$QMAKE_QVKGEN ${QMAKE_FILE_IN} $$shell_quote($$QMAKE_QVKGEN_LICENSE_HEADER) ${QMAKE_FILE_OUT_PATH}/${QMAKE_FILE_OUT_BASE}
+qvkgen_h.output = $$OUT_PWD/vulkan/qvulkanfunctions.h
+qvkgen_h.input = QMAKE_QVKGEN_INPUT
+qtConfig(vulkan): \
+ qvkgen_h.variable_out = HEADERS
+else: \
+ qvkgen_h.CONFIG += target_predeps no_link
+QMAKE_EXTRA_COMPILERS += qvkgen_h
+
+qvkgen_ph.commands = $$escape_expand(\\n)
+qvkgen_ph.output = $$OUT_PWD/vulkan/qvulkanfunctions_p.h
+qvkgen_ph.input = QMAKE_QVKGEN_INPUT
+qvkgen_ph.depends += $$OUT_PWD/vulkan/qvulkanfunctions.h
+qtConfig(vulkan): \
+ qvkgen_ph.variable_out = HEADERS
+else: \
+ qvkgen_ph.CONFIG += target_predeps no_link
+QMAKE_EXTRA_COMPILERS += qvkgen_ph
+
+qvkgen_pimpl.commands = $$escape_expand(\\n)
+qvkgen_pimpl.output = $$OUT_PWD/vulkan/qvulkanfunctions_p.cpp
+qvkgen_pimpl.input = QMAKE_QVKGEN_INPUT
+qvkgen_pimpl.depends += $$OUT_PWD/vulkan/qvulkanfunctions_p.h
+qtConfig(vulkan): \
+ qvkgen_pimpl.variable_out = SOURCES
+else: \
+ qvkgen_pimpl.CONFIG += target_predeps no_link
+QMAKE_EXTRA_COMPILERS += qvkgen_pimpl