QVulkanInstance 类

QVulkanInstance 类表示本机 Vulkan 实例,使 Vulkan 能够渲染到 QSurface . 更多...

头: #include <QVulkanInstance>
CMake: find_package(Qt6 COMPONENTS Gui REQUIRED)
target_link_libraries(mytarget PRIVATE Qt6::Gui)
qmake: QT += gui
Since: Qt 5.10

公共类型

  DebugFilter
enum Flag { NoDebugOutputRedirect }
flags Flags

公共函数

  QVulkanInstance ()
  ~QVulkanInstance ()
QVersionNumber apiVersion () const
bool create ()
void destroy ()
QVulkanDeviceFunctions * deviceFunctions (VkDevice device )
VkResult errorCode () const
QByteArrayList extensions () const
QVulkanInstance::Flags flags () const
QVulkanFunctions * functions () const
PFN_vkVoidFunction getInstanceProcAddr (const char * name )
void installDebugOutputFilter (QVulkanInstance::DebugFilter filter )
bool isValid () const
QByteArrayList layers () const
void presentAboutToBeQueued (QWindow * window )
void presentQueued (QWindow * window )
void removeDebugOutputFilter (QVulkanInstance::DebugFilter filter )
void resetDeviceFunctions (VkDevice device )
void setApiVersion (const QVersionNumber & vulkanVersion )
void setExtensions (const QByteArrayList & extensions )
void setFlags (QVulkanInstance::Flags flags )
void setLayers (const QByteArrayList & layers )
void setVkInstance (VkInstance existingVkInstance )
QVersionNumber supportedApiVersion () const
QVulkanInfoVector<QVulkanExtension> supportedExtensions () const
QVulkanInfoVector<QVulkanLayer> supportedLayers () const
bool supportsPresent (VkPhysicalDevice physicalDevice , uint32_t queueFamilyIndex , QWindow * window )
VkInstance vkInstance () const

静态公共成员

VkSurfaceKHR surfaceForWindow (QWindow * window )

详细描述

Vulkan is a cross-platform, explicit graphics and compute API. This class provides support for loading a Vulkan library and creating an 实例 in a cross-platform manner. For an introduction on Vulkan instances, refer to section 3.2 of the specification .

注意: 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 false .

注意: 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 configure indicates Vulkan support is disabled, the QVulkan* classes will be unavailable.

注意: 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.

初始化

类似于 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 () 和 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 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:

    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();
    }
					

配置

QVulkanInstance automatically enables the minimum set of extensions it needs on the newly created instance. In practice this means the 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 NoDebugOutputRedirect to setFlags () before invoking create ().

To enable additional layers and extensions, provide the list via setLayers () 和 setExtensions () 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 () 和 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 () 和 supportedExtensions () 先于调用 create ().

For example, to enable the standard validation layers, one could do the following:

    QVulkanInstance inst;
    // Enable validation layer, if supported. Messages go to qDebug by default.
    inst.setLayers({ "VK_LAYER_KHRONOS_validation" });
    bool ok = inst.create();
    if (!ok) {
        // ... Vulkan not available
    }
    if (!inst.layers().contains("VK_LAYER_KHRONOS_validation")) {
        // ... validation layer not available
    }
					

Or, alternatively, to make decisions before attempting to create a Vulkan instance:

    QVulkanInstance inst;
    if (inst.supportedLayers().contains("VK_LAYER_KHRONOS_validation")) {
        // ...
    }
    bool ok = inst.create();
    // ...
					

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 VkInstance handle already available, call setVkInstance () before invoking create (). This way no additional instances will get created, and QVulkanInstance will not own the handle.

注意: It is up to the component creating the external instance to ensure the necessary extensions are enabled on it. These are: VK_KHR_surface , the WSI-specific VK_KHR_*_surface that is appropriate for the platform in question, and VK_EXT_debug_report in case QVulkanInstance's debug output redirection is desired.

访问核心 Vulkan 命令

To access the 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 () 和 deviceFunctions ().

注意: 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.2 functions with the same signatures as described in the Vulkan API documentation .

为窗口获取本机 Vulkan 表面

The two common windowing system specific operations are getting a surface (a 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 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 vkGetPhysicalDeviceSurfaceSupportKHR and the WSI-specific vkGetPhysicalDevice*PresentationSupportKHR checks.

故障排除

Besides returning false from create () 或 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 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 QT_VULKAN_LIB 环境变量。

范例

The following is the basic outline of creating a Vulkan-capable QWindow :

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();
}
					

注意: 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.

对 Vulkan 使用 C++ 绑定

Combining Qt's Vulkan enablers with a C++ Vulkan wrapper, for example 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:

  • Some wrappers require exception support to be enabled. Qt does not use exceptions. To enable exceptions for the application, add CONFIG += exceptions .pro 文件。
  • Some wrappers call Vulkan functions directly, assuming 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 LIBS += -lvulkan or similar in the application's .pro 文件。
  • The headers for the QVulkan classes may include vulkan.h with 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 vulkan.hpp or similar before any of the QVulkan headers.

另请参阅 QVulkanFunctions and QSurface::SurfaceType .

成员类型文档编制

QVulkanInstance:: DebugFilter

Typedef for debug filtering callback functions.

另请参阅 installDebugOutputFilter () 和 removeDebugOutputFilter ().

[since 5.10] enum QVulkanInstance:: Flag
flags QVulkanInstance:: Flags

This enum describes the flags that can be passed to setFlags (). These control the behavior of create ().

常量 描述
QVulkanInstance::NoDebugOutputRedirect 0x01 Disables Vulkan debug output ( VK_EXT_debug_report ) redirection to qDebug .

该枚举在 Qt 5.10 引入或被修改。

Flags 类型是 typedef 对于 QFlags <Flag>。它存储 Flag 值的 OR 组合。

成员函数文档编制

QVulkanInstance:: QVulkanInstance ()

Constructs a new instance.

注意: No Vulkan initialization is performed in the constructor.

QVulkanInstance:: ~QVulkanInstance ()

析构函数。

注意: current() will return nullptr once the instance is destroyed.

QVersionNumber QVulkanInstance:: apiVersion () const

Returns the requested Vulkan API version against which the application expects to run, or a null version number if setApiVersion () was not called before create ().

另请参阅 setApiVersion ().

bool QVulkanInstance:: create ()

Initializes the Vulkan library and creates a new or adopts and existing Vulkan instance.

Returns 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 () 被调用。

void QVulkanInstance:: destroy ()

Destroys the underlying platform instance, thus destroying the VkInstance (when owned). The QVulkanInstance object is still reusable by calling create () 再次。

QVulkanDeviceFunctions *QVulkanInstance:: deviceFunctions ( VkDevice device )

返回 QVulkanDeviceFunctions object that exposes the device level core Vulkan command set and is guaranteed to be functional cross-platform.

注意: The Vulkan functions in the returned object must only be called with device or a child object (VkQueue, VkCommandBuffer) of device as their first parameter. This is because these functions are resolved via vkGetDeviceProcAddr in order to avoid the potential overhead of internal dispatching.

注意: The returned object is owned and managed by the QVulkanInstance . Do not destroy or alter it.

注意: The object is cached so calling this function with the same device again is a cheap operation. However, when the device gets destroyed, it is up to the application to notify the QVulkanInstance 通过调用 resetDeviceFunctions ().

The functions from the core Vulkan 1.0 API will be available always. When it comes to higher Vulkan versions, such as, 1.1 and 1.2, the QVulkanDeviceFunctions object will try to resolve the core API functions for those as well, but if the Vulkan physical device at run time has no support for those, calling any such unsupported function will lead to unspecified behavior. To properly enable support for Vulkan versions higher than 1.0, an appropriate instance API version may need to be set by calling setApiVersion () 先于 create (). In addition, applications are expected to check the physical device's apiVersion in VkPhysicalDeviceProperties.

另请参阅 functions () 和 resetDeviceFunctions ().

VkResult QVulkanInstance:: errorCode () const

Returns the Vulkan error code after an unsuccessful create (), VK_SUCCESS 否则。

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 VK_NOT_READY if the platform plugin does not support Vulkan.

QByteArrayList QVulkanInstance:: extensions () const

Returns the enabled instance extensions, if create () was called and was successful. The requested extensions otherwise.

另请参阅 setExtensions ().

QVulkanInstance::Flags QVulkanInstance:: flags () const

Returns the requested flags.

另请参阅 setFlags ().

QVulkanFunctions *QVulkanInstance:: functions () const

Returns the corresponding QVulkanFunctions object that exposes the core Vulkan command set, excluding device level functions, and is guaranteed to be functional cross-platform.

注意: The returned object is owned and managed by the QVulkanInstance . Do not destroy or alter it.

The functions from the core Vulkan 1.0 API will be available always. When it comes to higher Vulkan versions, such as, 1.1 and 1.2, the QVulkanFunctions object will try to resolve the core API functions for those as well, but if the Vulkan instance implementation at run time has no support for those, calling any such unsupported function will lead to unspecified behavior. In addition, to properly enable support for Vulkan versions higher than 1.0, an appropriate instance API version may need to be set by calling setApiVersion () 先于 create (). To query the Vulkan implementation's instance-level version, call supportedApiVersion ().

另请参阅 deviceFunctions () 和 supportedApiVersion ().

PFN_vkVoidFunction QVulkanInstance:: getInstanceProcAddr (const char * name )

Resolves the Vulkan function with the given name .

For core Vulkan commands prefer using the function wrappers retrievable from functions () 和 deviceFunctions () 代替。

void QVulkanInstance:: installDebugOutputFilter ( QVulkanInstance::DebugFilter filter )

Installs a filter function that is called for every Vulkan debug message. When the callback returns true , the message is stopped (filtered out) and will not appear on the debug output.

注意: Filtering is only effective when NoDebugOutputRedirect 不是 set . Installing filters has no effect otherwise.

注意: This function can be called before create ().

另请参阅 removeDebugOutputFilter ().

bool QVulkanInstance:: isValid () const

返回 true 若 create () was successful and the instance is valid.

QByteArrayList QVulkanInstance:: layers () const

Returns the enabled instance layers, if create () was called and was successful. The requested layers otherwise.

另请参阅 setLayers ().

[since 5.15] void QVulkanInstance:: presentAboutToBeQueued ( QWindow * window )

This function should be called by the application's renderer before queuing a present operation for window .

While on some platforms this will be a no-op, some may perform windowing system dependent synchronization. For example, on Wayland this will add send a wl_surface.frame request in order to prevent the driver from blocking for minimized windows.

该函数在 Qt 5.15 引入。

void QVulkanInstance:: presentQueued ( QWindow * window )

This function should be called by the application's renderer after queuing a present operation for 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 _NET_WM_SYNC_REQUEST_COUNTER .

void QVulkanInstance:: removeDebugOutputFilter ( QVulkanInstance::DebugFilter filter )

Removes a filter function previously installed by installDebugOutputFilter ().

注意: This function can be called before create ().

另请参阅 installDebugOutputFilter ().

void QVulkanInstance:: resetDeviceFunctions ( VkDevice device )

Invalidates and destroys the QVulkanDeviceFunctions 对象为给定 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.

另请参阅 deviceFunctions ().

void QVulkanInstance:: setApiVersion (const QVersionNumber & vulkanVersion )

Specifies the highest Vulkan API version the application is designed to use.

默认情况下 vulkanVersion is 0, which maps to Vulkan 1.0.

注意: This function can only be called before create () and has no effect if called afterwards.

注意: Be aware that Vulkan 1.1 changes the behavior with regards to the Vulkan API version field. In Vulkan 1.0 specifying an unsupported vulkanVersion led to failing create () 采用 VK_ERROR_INCOMPATIBLE_DRIVER , as was mandated by the specification. Starting with Vulkan 1.1, the specification disallows this, the driver must accept any version without failing the instance creation.

Application developers are advised to familiarize themselves with the apiVersion notes in the Vulkan specification .

另请参阅 apiVersion () 和 supportedApiVersion ().

void QVulkanInstance:: setExtensions (const QByteArrayList & extensions )

Specifies the list of additional instance 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.

注意: This function can only be called before create () and has no effect if called afterwards.

另请参阅 extensions ().

void QVulkanInstance:: setFlags ( QVulkanInstance::Flags flags )

Configures the behavior of create () based on the provided flags .

注意: This function can only be called before create () and has no effect if called afterwards.

另请参阅 flags ().

void QVulkanInstance:: setLayers (const QByteArrayList & layers )

Specifies the list of instance layers to enable. It is safe to specify unsupported layers as well because these get ignored when not supported at run time.

注意: This function can only be called before create () and has no effect if called afterwards.

另请参阅 layers ().

void QVulkanInstance:: setVkInstance ( VkInstance existingVkInstance )

使 QVulkanInstance adopt an existing VkInstance handle instead of creating a new one.

注意: existingVkInstance must have at least VK_KHR_surface and the appropriate WSI-specific VK_KHR_*_surface extensions enabled. To ensure debug output redirection is functional, VK_EXT_debug_report is needed as well.

注意: This function can only be called before create () and has no effect if called afterwards.

另请参阅 vkInstance ().

QVersionNumber QVulkanInstance:: supportedApiVersion () const

Returns the version of instance-level functionality supported by the Vulkan implementation.

In practice this is either the value returned from vkEnumerateInstanceVersion, if that function is available (with Vulkan 1.1 and newer), or 1.0.

Applications that want to branch in their Vulkan feature and API usage based on what Vulkan version is available at run time, can use this function to determine what version to pass in to setApiVersion () 先于调用 create ().

注意: This function can be called before create ().

另请参阅 setApiVersion ().

QVulkanInfoVector < QVulkanExtension > QVulkanInstance:: supportedExtensions () const

Returns the list of supported instance-level extensions.

注意: This function can be called before create ().

QVulkanInfoVector < QVulkanLayer > QVulkanInstance:: supportedLayers () const

Returns the list of supported instance-level layers.

注意: This function can be called before create ().

bool QVulkanInstance:: supportsPresent ( VkPhysicalDevice physicalDevice , uint32_t queueFamilyIndex , QWindow * window )

Returns true if the queue family with queueFamilyIndex within the physicalDevice supports presenting to 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.

[static] VkSurfaceKHR QVulkanInstance:: surfaceForWindow ( QWindow * window )

Creates or retrieves the already existing VkSurfaceKHR handle for the given window .

Returns the Vulkan surface handle or 0 when failed.

VkInstance QVulkanInstance:: vkInstance () const

Returns the VkInstance handle this QVulkanInstance wraps, or nullptr if create () has not yet been successfully called and no existing instance has been provided via setVkInstance ().

另请参阅 setVkInstance ().