QVulkanWindow Class

The QVulkanWindow class is a convenience subclass of QWindow to perform Vulkan rendering. More...

Header: #include <QVulkanWindow>
CMake: find_package(Qt6 REQUIRED COMPONENTS Gui)
target_link_libraries(mytarget PRIVATE Qt6::Gui)
qmake: QT += gui
Inherits: QWindow

Public Types

(since 6.7) EnabledFeatures2Modifier
EnabledFeaturesModifier
enum Flag { PersistentResources }
flags Flags
QueueCreateInfoModifier

Public Functions

QVulkanWindow(QWindow *parent = nullptr)
virtual ~QVulkanWindow()
QList<VkPhysicalDeviceProperties> availablePhysicalDevices()
QMatrix4x4 clipCorrectionMatrix()
VkFormat colorFormat() const
int concurrentFrameCount() const
virtual QVulkanWindowRenderer *createRenderer()
VkCommandBuffer currentCommandBuffer() const
int currentFrame() const
VkFramebuffer currentFramebuffer() const
int currentSwapChainImageIndex() const
VkRenderPass defaultRenderPass() const
VkFormat depthStencilFormat() const
VkImage depthStencilImage() const
VkImageView depthStencilImageView() const
VkDevice device() const
uint32_t deviceLocalMemoryIndex() const
QVulkanWindow::Flags flags() const
void frameReady()
QImage grab()
VkCommandPool graphicsCommandPool() const
VkQueue graphicsQueue() const
uint32_t graphicsQueueFamilyIndex() const
uint32_t hostVisibleMemoryIndex() const
bool isValid() const
VkImage msaaColorImage(int idx) const
VkImageView msaaColorImageView(int idx) const
VkPhysicalDevice physicalDevice() const
const VkPhysicalDeviceProperties *physicalDeviceProperties() const
VkSampleCountFlagBits sampleCountFlagBits() const
void setDeviceExtensions(const QByteArrayList &extensions)
(since 6.7) void setEnabledFeaturesModifier(const QVulkanWindow::EnabledFeaturesModifier &modifier)
(since 6.7) void setEnabledFeaturesModifier(QVulkanWindow::EnabledFeatures2Modifier modifier)
void setFlags(QVulkanWindow::Flags flags)
void setPhysicalDeviceIndex(int idx)
void setPreferredColorFormats(const QList<VkFormat> &formats)
void setQueueCreateInfoModifier(const QVulkanWindow::QueueCreateInfoModifier &modifier)
void setSampleCount(int sampleCount)
QVulkanInfoVector<QVulkanExtension> supportedDeviceExtensions()
QList<int> supportedSampleCounts()
bool supportsGrab() const
VkImage swapChainImage(int idx) const
int swapChainImageCount() const
QSize swapChainImageSize() const
VkImageView swapChainImageView(int idx) const

Signals

void frameGrabbed(const QImage &image)

Static Public Members

Detailed Description

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 documentation first.

A typical application using QVulkanWindow may look like the following:

 class VulkanRenderer : public QVulkanWindowRenderer
 {
 public:
     VulkanRenderer(QVulkanWindow *w) : m_window(w), m_devFuncs(nullptr) { }

     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(commandBuffer, renderPassBegin, contents);
         // ...
         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({ "VK_LAYER_KHRONOS_validation" });
     if (!inst.create())
         qFatal("Failed to create Vulkan instance: %d", inst.errorCode());

     VulkanWindow w;
     w.setVulkanInstance(&inst);
     w.showMaximized();

     return app.exec();
 }

As it can be seen in the example, the main patterns in QVulkanWindow usage are:

  • The QVulkanInstance is associated via QWindow::setVulkanInstance(). It is then retrievable via QWindow::vulkanInstance() from everywhere, on any thread.
  • 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.
  • The renderer is implemented in a QVulkanWindowRenderer subclass, an instance of which is created in the createRenderer() factory function.
  • 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().
  • 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().
  • 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.
  • 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.
  • 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().

For troubleshooting, enable the logging category qt.vulkan. Critical errors are printed via qWarning() automatically.

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().

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.

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.

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 VK_FORMAT_B8G8R8A8_SRGB results in choosing an sRGB format, when available.

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 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 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.

Layers, device features, and extensions

To enable instance layers, call QVulkanInstance::setLayers() before creating the QVulkanInstance. To query what instance layer are available, call QVulkanInstance::supportedLayers().

To enable device extensions, call setDeviceExtensions() early on when setting up the QVulkanWindow. To query what device extensions are available, call supportedDeviceExtensions().

Specifying an unsupported layer or extension is handled gracefully: this will not fail instance or device creation, but the layer or extension request is rather ignored.

When it comes to device features, QVulkanWindow enables all Vulkan 1.0 features that are reported as supported from vkGetPhysicalDeviceFeatures(). As an exception to this rule, robustBufferAccess is never enabled. Use the callback mechanism described below, if enabling that feature is desired.

This is not always desirable, and may be insufficient with Vulkan 1.1 and higher. Therefore, full control over the VkPhysicalDeviceFeatures used for device creation is possible too by registering a callback function with setEnabledFeaturesModifier(). When set, the callback function is invoked, letting it alter the VkPhysicalDeviceFeatures or VkPhysicalDeviceFeatures2.

See also QVulkanInstance and QWindow.

Member Type Documentation

[since 6.7] QVulkanWindow::EnabledFeatures2Modifier

A function that is called during graphics initialization to alter the VkPhysicalDeviceFeatures2 that is changed to the VkDeviceCreateInfo.

By default QVulkanWindow enables all Vulkan 1.0 core features that the physical device reports as supported, with certain exceptions. In praticular, robustBufferAccess is always disabled in order to avoid unexpected performance hits.

This however is not always sufficient when working with Vulkan 1.1, 1.2, or 1.3 features and extensions. Hence this callback mechanism. If only Vulkan 1.0 is relevant at run time, use setEnabledFeaturesModifier() instead.

The VkPhysicalDeviceFeatures2 reference passed to the callback function with sType set, but the rest zeroed out. It is up to the function to change members to true, or set up pNext chains as it sees fit.

Note: When setting up pNext chains, make sure the referenced objects have a long enough lifetime, for example by storing them as member variables in the QVulkanWindow subclass.

This typedef was introduced in Qt 6.7.

See also setEnabledFeaturesModifier().

QVulkanWindow::EnabledFeaturesModifier

A function that is called during graphics initialization to alter the VkPhysicalDeviceFeatures that is passed in when creating a Vulkan device object.

By default QVulkanWindow enables all Vulkan 1.0 core features that the physical device reports as supported, with certain exceptions. In praticular, robustBufferAccess is always disabled in order to avoid unexpected performance hits.

The VkPhysicalDeviceFeatures reference passed in is all zeroed out at the point when the function is invoked. It is up to the function to change members as it sees fit.

Note: To control Vulkan 1.1, 1.2, or 1.3 features, use EnabledFeatures2Modifier instead.

See also setEnabledFeaturesModifier().

enum QVulkanWindow::Flag
flags QVulkanWindow::Flags

This enum describes the flags that can be passed to setFlags().

ConstantValueDescription
QVulkanWindow::PersistentResources0x01Ensures no graphics resources are released when the window becomes unexposed. The default behavior is to release everything, and reinitialize later when becoming visible again.

The Flags type is a typedef for QFlags<Flag>. It stores an OR combination of Flag values.

QVulkanWindow::QueueCreateInfoModifier

A function that is called during graphics initialization to add additional queues that should be created.

Set if the renderer needs additional queues besides the default graphics queue (e.g. a transfer queue). The provided queue family properties can be used to select the indices for the additional queues. The renderer can subsequently request the actual queue in initResources().

Note: When requesting additional graphics queues, Qt itself always requests a graphics queue. You'll need to search queueCreateInfo for the appropriate entry and manipulate it to obtain the additional queue.

See also setQueueCreateInfoModifier().

Member Function Documentation

[explicit] QVulkanWindow::QVulkanWindow(QWindow *parent = nullptr)

Constructs a new QVulkanWindow with the given parent.

The surface type is set to QSurface::VulkanSurface.

[virtual noexcept] QVulkanWindow::~QVulkanWindow()

Destructor.

QList<VkPhysicalDeviceProperties> QVulkanWindow::availablePhysicalDevices()

Returns the list of properties for the supported physical devices in the system.

Note: This function can be called before making the window visible.

QMatrix4x4 QVulkanWindow::clipCorrectionMatrix()

Returns 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 that Y is pointing upwards, and can set minDepth and maxDepth in the viewport to 0 and 1, respectively, without having to do any further corrections to the vertex Z positions. Geometry from OpenGL applications can then be used as-is, assuming a rasterization state matching the OpenGL culling and front face settings.

VkFormat QVulkanWindow::colorFormat() const

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().

See also setPreferredColorFormats().

int QVulkanWindow::concurrentFrameCount() const

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.

     class Renderer {
         void startNextFrame();
         // ...

         VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
         QVulkanWindow *m_window = nullptr;
     };

     void Renderer::startNextFrame()
     {
         const int count = m_window->concurrentFrameCount();
         // for (int i = 0; i < count; ++i)
             // m_uniformBufInfo[i] = ...
         // ...
     }

See also currentFrame().

[virtual] QVulkanWindowRenderer *QVulkanWindow::createRenderer()

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.

VkCommandBuffer QVulkanWindow::currentCommandBuffer() const

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().

int QVulkanWindow::currentFrame() const

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.

     class Renderer {
         void startNextFrame();
         // ...

         VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
         QVulkanWindow *m_window = nullptr;
     };

     void Renderer::startNextFrame()
     {
         VkDescriptorBufferInfo &uniformBufInfo(m_uniformBufInfo[m_window->currentFrame()]);
         // ...
     }

Note: This function must only be called from within startNextFrame() and, in case of asynchronous command generation, up until the call to frameReady().

See also concurrentFrameCount().

VkFramebuffer QVulkanWindow::currentFramebuffer() const

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 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().

See also defaultRenderPass().

int QVulkanWindow::currentSwapChainImageIndex() const

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().

VkRenderPass QVulkanWindow::defaultRenderPass() const

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 VK_IMAGE_LAYOUT_UNDEFINED to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR and 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().

See also currentFramebuffer().

VkFormat QVulkanWindow::depthStencilFormat() const

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().

VkImage QVulkanWindow::depthStencilImage() const

Returns the depth-stencil image.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initSwapChainResources() up until QVulkanWindowRenderer::releaseSwapChainResources().

VkImageView QVulkanWindow::depthStencilImageView() const

Returns the depth-stencil image view.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initSwapChainResources() up until QVulkanWindowRenderer::releaseSwapChainResources().

VkDevice QVulkanWindow::device() const

Returns the active logical device.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initResources() up until QVulkanWindowRenderer::releaseResources().

uint32_t QVulkanWindow::deviceLocalMemoryIndex() const

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().

Note: It is not guaranteed that this memory type is always suitable. The correct, cross-implementation solution - especially for device local images - is to manually pick a memory type after checking the mask returned from vkGetImageMemoryRequirements.

QVulkanWindow::Flags QVulkanWindow::flags() const

Return the requested flags.

See also setFlags().

[signal] void QVulkanWindow::frameGrabbed(const QImage &image)

This signal is emitted when the image is ready.

void QVulkanWindow::frameReady()

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.

See also QVulkanWindowRenderer::startNextFrame().

QImage QVulkanWindow::grab()

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 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.

The returned QImage always has a format of QImage::Format_RGBA8888. If the colorFormat() is VK_FORMAT_B8G8R8A8_UNORM, the red and blue channels are swapped automatically since this format is commonly used as the default choice for swapchain color buffers. With any other color buffer format, there is no conversion performed by this function.

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 (VK_IMAGE_USAGE_TRANSFER_SRC_BIT), and will fail otherwise.

VkCommandPool QVulkanWindow::graphicsCommandPool() const

Returns the active graphics command pool.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initResources() up until QVulkanWindowRenderer::releaseResources().

VkQueue QVulkanWindow::graphicsQueue() const

Returns the active graphics queue.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initResources() up until QVulkanWindowRenderer::releaseResources().

uint32_t QVulkanWindow::graphicsQueueFamilyIndex() const

Returns the family index of the active graphics queue.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initResources() up until QVulkanWindowRenderer::releaseResources(). Implementations of QVulkanWindowRenderer::updateQueueCreateInfo() can also call this function.

uint32_t QVulkanWindow::hostVisibleMemoryIndex() const

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().

bool QVulkanWindow::isValid() const

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.

VkImage QVulkanWindow::msaaColorImage(int idx) const

Returns the specified multisample color image, or VK_NULL_HANDLE if multisampling is not in use.

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

Returns the specified multisample color image view, or VK_NULL_HANDLE if multisampling is not in use.

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().

VkPhysicalDevice QVulkanWindow::physicalDevice() const

Returns 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

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().

VkSampleCountFlagBits QVulkanWindow::sampleCountFlagBits() const

Returns the current sample count as a VkSampleCountFlagBits value.

When targeting the default render target, the rasterizationSamples field of VkPipelineMultisampleStateCreateInfo must be set to this value.

See also setSampleCount() and supportedSampleCounts().

void QVulkanWindow::setDeviceExtensions(const QByteArrayList &extensions)

Sets the list of device 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.

[since 6.7] void QVulkanWindow::setEnabledFeaturesModifier(const QVulkanWindow::EnabledFeaturesModifier &modifier)

Sets the enabled device features modification function modifier.

Note: To control Vulkan 1.1, 1.2, or 1.3 features, use the overload taking a EnabledFeatures2Modifier instead.

Note: modifier is passed to the callback function with all members set to false. It is up to the function to change members as it sees fit.

This function was introduced in Qt 6.7.

See also EnabledFeaturesModifier.

[since 6.7] void QVulkanWindow::setEnabledFeaturesModifier(QVulkanWindow::EnabledFeatures2Modifier modifier)

Sets the enabled device features modification function modifier.

This is an overloaded function.

This function was introduced in Qt 6.7.

See also EnabledFeatures2Modifier.

void QVulkanWindow::setFlags(QVulkanWindow::Flags flags)

Configures the behavior based on the provided 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.

See also flags().

void QVulkanWindow::setPhysicalDeviceIndex(int idx)

Requests the usage of the physical device with index 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::setPreferredColorFormats(const QList<VkFormat> &formats)

Sets the preferred 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, VK_FORMAT_B8G8R8A8_UNORM.

The list in 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.

See also colorFormat().

void QVulkanWindow::setQueueCreateInfoModifier(const QVulkanWindow::QueueCreateInfoModifier &modifier)

Sets the queue create info modification function modifier.

See also QueueCreateInfoModifier.

void QVulkanWindow::setSampleCount(int sampleCount)

Requests multisample antialiasing with the given 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 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.

See also supportedSampleCounts() and sampleCountFlagBits().

QVulkanInfoVector<QVulkanExtension> QVulkanWindow::supportedDeviceExtensions()

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.

QList<int> QVulkanWindow::supportedSampleCounts()

Returns the set of supported sample counts when using the physical device selected by setPhysicalDeviceIndex(), as a sorted list.

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.

See also setSampleCount().

bool QVulkanWindow::supportsGrab() const

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().

VkImage QVulkanWindow::swapChainImage(int idx) const

Returns the specified swap chain image.

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().

int QVulkanWindow::swapChainImageCount() const

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().

QSize QVulkanWindow::swapChainImageSize() const

Returns the image size of the swapchain.

This usually matches the size of the window, but may also differ in case vkGetPhysicalDeviceSurfaceCapabilitiesKHR reports a fixed size.

In addition, it has been observed on some platforms that the Vulkan-reported surface size is different with high DPI scaling active, meaning the QWindow-reported size() multiplied with the devicePixelRatio() was 1 pixel less or more when compared to the value returned from here, presumably due to differences in rounding. Rendering code should be aware of this, and any related rendering logic must be based in the value returned from here, never on the QWindow-reported size. Regardless of which pixel size is correct in theory, Vulkan rendering must only ever rely on the Vulkan API-reported surface size. Otherwise validation errors may occur, e.g. when setting the viewport, because the application-provided values may become out-of-bounds from Vulkan's perspective.

Note: Calling this function is only valid from the invocation of QVulkanWindowRenderer::initSwapChainResources() up until QVulkanWindowRenderer::releaseSwapChainResources().

VkImageView QVulkanWindow::swapChainImageView(int idx) const

Returns the specified swap chain image view.

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().

Member Variable Documentation

const int QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT

This variable holds a constant value that is always equal to or greater than the maximum value of concurrentFrameCount().