CopperSpice API
1.9.2
|
Provides functionality to create a Vulkan instance. More...
Public Typedefs | |
using | DebugFilter = std::function< bool (VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *, const char *)> |
using | InstanceFlags = QFlags< InstanceOptions > |
Public Types | |
enum | InstanceOptions : uint32_t |
Static Public Methods | |
static VkSurfaceKHR | surfaceForWindow (QWindow *window) |
The QVulkanInstance class is used to load the Vulkan library by creating an instance. An instance is the connection between your CopperSpice application and the Vulkan library.
For more information about a Vulkan instance refer to the following tutorial. Creating an Instance
Platform specific support for Vulkan instances and windows with Vulkan capable surfaces is provided by the various platform plugins. Not all platforms support Vulkan and when running on an unsupported platform calling create() will fail and always return false.
The functions from Vulkan 1.1 will always be available. For newer versions like 1.3, the QVulkanDeviceFunctions or QVulkanFuntions objects will attempt to resolve the API calls. If the Vulkan physical device does not support a particular function then calling making this call can cause unspecified behavior.
To enable support for Vulkan versions higher than 1.1 an appropriate instance API version may need to be set by calling setApiVersion() before calling create(). Applications are expected to check the physical device apiVersion in the VkPhysicalDeviceProperties structure.
To query the Vulkan implementation version, call supportedApiVersion().
Like QOpenGLContext, the Vulkan instance creation does not happen until create() is called. Calling the methods supportedLayers() and supportedExtensions() will return the supported instance level layers and extensions. These two methods are safe to call before calling create(). The create() method connects to the Vulkan library and constructs a VkInstance object which is required for almost every other method in CsVulkan. Normally there is only on VkInstance per user application.
In order to render graphics using Vulkan and have the result be displayed as part of your application user interface you must create a QWindow or QVulkanWinow and pass the QVulkanInstance by calling QWindow::setVulkanInstance(). The following code is a very basic example of these steps.
QVulkanInstance automatically enables the minimum set of extensions it needs on the newly created instance. In practice this means the "VK_KHR_<OS>_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() and 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() 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.
Alternatively, to make decisions before attempting to create a Vulkan instance use the following code.
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.
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() and deviceFunctions().
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_<OS>_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.
Besides returning false from create() or nullptr from surfaceForWindow(), critical errors will also be sent to the debug output via qWarning(). The actual Vulkan error code from instance creation can be retrieved by calling errorCode() after calling create() fails.
The following is the basic outline of creating a Vulkan capable QWindow.
The CsVulkan library is responsible for destroying the VkInstance, VkSurfaceKHR, and VkDevice objects. If you are using other third party Vulkan libraries or need to access these objects directly, the ownership of these objects must remain with CsVulkan.
Some third party libraries call Vulkan functions directly. To use one of these libraries your application will need to link with CsVulkan and the Vulkan API.
Typedef for a debug filter callback functions.
Typedef for QFlags<InstanceOptions> which contains an OR combination of InstanceOptions values.
Refer to QVulkanInstance::InstanceOptions for the enum documentation.
enum QVulkanInstance::InstanceOptions : uint32_t |
This enum describes the flags which can be passed to setFlags(). They control the behavior of create().
Constant | Value | Description |
---|---|---|
QVulkanInstance::NoDebugOutputRedirect | 0x01 | Disables Vulkan debug output (VK_EXT_debug_report) redirection to qDebug. |
|
deprecated |
Constructs a new instance. No Vulkan initialization is performed in the constructor.
QVulkanInstance::~QVulkanInstance | ( | ) |
Destroys the QVulkanInstance. Calling the current() method will return a 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().
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() is called.
void QVulkanInstance::destroy | ( | ) |
Destroys the underlying platform instance, thus destroying the VkInstance (when owned). The QVulkanInstance object is still reusable by calling create() again.
QVulkanDeviceFunctions * QVulkanInstance::deviceFunctions | ( | VkDevice | device | ) |
Returns the 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.
VkResult QVulkanInstance::errorCode | ( | ) | const |
Returns the Vulkan error code after an unsuccessful call to create(), otherwise return 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.
QStringList QVulkanInstance::extensions | ( | ) | const |
Returns the enabled instance extensions if create() was called and was successful. The requested extensions otherwise.
QVulkanInstance::InstanceFlags QVulkanInstance::flags | ( | ) | const |
Returns the requested flags.
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.
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() and deviceFunctions() instead.
uint32_t 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 is not set. Installing filters has no effect otherwise.
This method can be called before create().
bool QVulkanInstance::isValid | ( | ) | const |
Returns true if create() was successful and the instance is valid.
QStringList QVulkanInstance::layers | ( | ) | const |
Returns the enabled instance layers, if create() was called and was successful. The requested layers otherwise.
void QVulkanInstance::presentAboutToBeQueued | ( | QWindow * | window | ) |
This method 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.
void QVulkanInstance::presentQueued | ( | QWindow * | window | ) |
This method 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 | ( | uint32_t | filter | ) |
Removes a filter function previously installed by installDebugOutputFilter().
This method can be called before create().
void QVulkanInstance::resetDeviceFunctions | ( | VkDevice | device | ) |
Invalidates and destroys the QVulkanDeviceFunctions object for the given device. This method 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 performed automatically.
void QVulkanInstance::setApiVersion | ( | const QVersionNumber & | vulkanVersion | ) |
Specifies the highest Vulkan API version the application is designed to use. By default the vulkanVersion is 0 which maps to Vulkan 1.1.
This method can only be called before create() and has no effect when called afterwards.
void QVulkanInstance::setExtensions | ( | const QStringList & | 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 extensions required by CsVulkan will be added automatically.
This method can only be called before create() and has no effect when called afterwards
void QVulkanInstance::setFlags | ( | QVulkanInstance::InstanceFlags | flags | ) |
void QVulkanInstance::setLayers | ( | const QStringList & | 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 method should be called before create() and has no effect if called afterwards.
void QVulkanInstance::setVkInstance | ( | VkInstance | existingVkInstance | ) |
Makes QVulkanInstance adopt an existing VkInstance handle instead of creating a new one. The given existingVkInstance must have at least "VK_KHR_surface" and the appropriate WSI specific "VK_KHR_<OS>_surface" extensions enabled. To ensure debug output redirection is functional "VK_EXT_debug_report" is needed as well.
This method should be called before create() and has no effect if called afterwards.
QVersionNumber QVulkanInstance::supportedApiVersion | ( | ) | const |
Returns the version of instance level functionality supported by the Vulkan implementation. This is the value returned from vkEnumerateInstanceVersion() if that function is available.
Applications which want to adjust the usage of the Vulkan API based on the Vulkan version available on the target system should use this method to determine what version to pass to setApiVersion() before calling create().
This method can be called before create().
QVector< QVulkanExtensionProperties > QVulkanInstance::supportedExtensions | ( | ) | const |
Returns the list of supported instance-level extensions.
This method can be called before create().
QVector< QVulkanLayerProperties > QVulkanInstance::supportedLayers | ( | ) | const |
Returns the list of supported instance level layers.
This method can be called before create().
|
static |
Creates or retrieves the already existing VkSurfaceKHR handle for the given window. Returns the Vulkan surface handle or a nullptr if this fails.
VkInstance QVulkanInstance::vkInstance | ( | ) | const |
Return 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().