Hello Vulkan Window Example

The Hello Vulkan Window Example shows the basics of using QVulkanWindow in order to display rendering with the Vulkan graphics API on systems that support this.

Image non disponible

In this example there will be no actual rendering: it simply begins and ends a render pass, which results in clearing the buffers to a fixed value. The color buffer clear value changes on every frame.

Startup

Each Qt application using Vulkan will have to have a Vulkan instance which encapsulates application-level state and initializes a Vulkan library.

A QVulkanWindow must always be associated with a QVulkanInstance and hence the example performs instance creation before the window. The QVulkanInstance object must also outlive the window.

 
Sélectionnez
    QVulkanInstance inst;

#ifndef Q_OS_ANDROID
    inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
#else
    inst.setLayers(QByteArrayList()
                   << "VK_LAYER_GOOGLE_threading"
                   << "VK_LAYER_LUNARG_parameter_validation"
                   << "VK_LAYER_LUNARG_object_tracker"
                   << "VK_LAYER_LUNARG_core_validation"
                   << "VK_LAYER_LUNARG_image"
                   << "VK_LAYER_LUNARG_swapchain"
                   << "VK_LAYER_GOOGLE_unique_objects");
#endif

    if (!inst.create())
        qFatal("Failed to create Vulkan instance: %d", inst.errorCode());

The example enables validation layers, when supported. When the requested layers are not present, the request will be ignored. Additional layers and extensions can be enabled in a similar manner.

 
Sélectionnez
    VulkanWindow w;
    w.setVulkanInstance(&inst);

    w.resize(1024, 768);
    w.show();

Once the instance is ready, it is time to create a window. Note that w lives on the stack and is declared after inst.

The QVulkanWindow Subclass

To add custom functionality to a QVulkanWindow, subclassing is used. This follows the existing patterns from QOpenGLWindow and QOpenGLWidget. However, QVulkanWindow utilizes a separate QVulkanWindowRenderer object. This resembles QQuickFramebufferObject, and allows better separation of the functions that are supposed to be reimplemented.

 
Sélectionnez
class VulkanRenderer : public QVulkanWindowRenderer
{
public:
    VulkanRenderer(QVulkanWindow *w);

    void initResources() override;
    void initSwapChainResources() override;
    void releaseSwapChainResources() override;
    void releaseResources() override;

    void startNextFrame() override;

private:
    QVulkanWindow *m_window;
    QVulkanDeviceFunctions *m_devFuncs;
    float m_green = 0;
};

class VulkanWindow : public QVulkanWindow
{
public:
    QVulkanWindowRenderer *createRenderer() override;
};

The QVulkanWindow subclass reimplements the factory function QVulkanWindow::createRenderer(). This simply returns a new instance of the QVulkanWindowRenderer