Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
QVulkanWindow Class Reference

\inmodule QtGui More...

+ Inheritance diagram for QVulkanWindow:
+ Collaboration diagram for QVulkanWindow:

Detailed Description

\inmodule QtGui

Since
5.10

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:

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;
};
class VulkanWindow : public QVulkanWindow
{
public:
return new VulkanRenderer(this);
}
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
// 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:

\list

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

\endlist

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


The documentation for this class was generated from the following file: