PySide6.QtGui.QRhi¶
- class QRhi¶
Accelerated 2D/3D graphics API abstraction. More…
Added in version 6.6.
Synopsis¶
Methods¶
def
__init__()def
backend()def
backendName()def
beginFrame()def
driverInfo()def
endFrame()def
finish()def
isDeviceLost()def
isYUpInNDC()def
nativeHandles()def
newBuffer()def
newSampler()def
newSwapChain()def
newTexture()def
resourceLimit()def
statistics()def
thread()def
ubufAligned()def
ubufAlignment()
Static functions¶
def
backendName()def
create()def
probe()
Note
This documentation may contain snippets that were automatically translated from C++ to Python. We always welcome contributions to the snippet translation. If you see an issue with the translation, you can also let us know by creating a ticket on https:/bugreports.qt.io/projects/PYSIDE
Detailed Description¶
Warning
This section contains snippets that were automatically translated from C++ to Python and may contain errors.
The Qt Rendering Hardware Interface is an abstraction for hardware accelerated graphics APIs, such as, OpenGL , OpenGL ES , Direct3D , Metal , and Vulkan .
Warning
The
QRhifamily of classes in the Qt Gui module, includingQShaderandQShaderDescription, offer limited compatibility guarantees. There are no source or binary compatibility guarantees for these classes, meaning the API is only guaranteed to work with the Qt version the application was developed against. Source incompatible changes are however aimed to be kept at a minimum and will only be made in minor releases (6.7, 6.8, and so on). To use these classes in an application, link toQt::GuiPrivate(if using CMake), and include the headers with therhiprefix, for example#include <rhi/qrhi.h>.Each
QRhiinstance is backed by a backend for a specific graphics API. The selection of the backend is a run time choice and is up to the application or library that creates theQRhiinstance. Some backends are available on multiple platforms (OpenGL, Vulkan, Null), while APIs specific to a given platform are only available when running on the platform in question (Metal on macOS/iOS, Direct3D on Windows).The available backends currently are:
OpenGL 2.1 / OpenGL ES 2.0 or newer. Some extensions and newer core specification features are utilized when present, for example to enable multisample framebuffers or compute shaders. Operating in core profile contexts is supported as well. If necessary, applications can query the
feature flagsat runtime to check for features that are not supported in the OpenGL context backing theQRhi. The OpenGL backend builds onQOpenGLContext,QOpenGLFunctions, and the related cross-platform infrastructure of the Qt GUI module.Direct3D 11.2 and newer (with DXGI 1.3 and newer), using Shader Model 5.0 or newer. When the D3D runtime has no support for 11.2 features or Shader Model 5.0, initialization using an accelerated graphics device will fail, but using the software adapter is still an option.
Direct3D 12 on Windows 10 version 1703 and newer, with Shader Model 5.0 or newer. Qt requires ID3D12Device2 to be present, hence the requirement for at least version 1703 of Windows 10. The D3D12 device is by default created with specifying a minimum feature level of
D3D_FEATURE_LEVEL_11_0.Metal 1.2 or newer.
Vulkan 1.0 or newer, optionally utilizing some Vulkan 1.1 level features.
Null, a “dummy” backend that issues no graphics calls at all.
In order to allow shader code to be written once in Qt applications and libraries, all shaders are expected to be written in a single language which is then compiled into SPIR-V. Versions for various shading language are then generated from that, together with reflection information (inputs, outputs, shader resources). This is then packed into easily and efficiently serializable
QShaderinstances. The compilers and tools to generate such shaders are not part ofQRhiand the Qt GUI module, but the core classes for using such shaders,QShaderandQShaderDescription, are. The APIs and tools for performing compilation and translation are part of the Qt Shader Tools module.See the RHI Window Example for an introductory example of creating a portable, cross-platform application that performs accelerated 3D rendering onto a
QWindowusingQRhi.An Impression of the API¶
To provide a quick look at the API with a short yet complete example that does not involve window-related setup, the following is a complete, runnable cross-platform application that renders 20 frames off-screen, and then saves the generated images to files after reading back the texture contents from the GPU. For an example that renders on-screen, which then involves setting up a
QWindowand a swapchain, refer to the RHI Window Example .For brevity, the initialization of the
QRhiis done based on the platform: the sample code here chooses Direct 3D 12 on Windows, Metal on macOS and iOS, and Vulkan otherwise. OpenGL and Direct 3D 11 are never used by this application, but support for those could be introduced with a few additional lines.from PySide6.QtGui import QGuiApplication from PySide6.QtGui import QImage from PySide6.QtCore import QFile if __name__ == "__main__": app = QGuiApplication(argc, argv) #if QT_CONFIG(vulkan) inst = QVulkanInstance() #endif std.unique_ptr<QRhi> rhi #if defined(Q_OS_WIN) params = QRhiD3D12InitParams() rhi.reset(QRhi.create(QRhi.D3D12, params)) #elif QT_CONFIG(metal) params = QRhiMetalInitParams() rhi.reset(QRhi.create(QRhi.Metal, params)) #elif QT_CONFIG(vulkan) inst.setExtensions(QRhiVulkanInitParams.preferredInstanceExtensions()) if inst.create(): params = QRhiVulkanInitParams() params.inst = inst rhi.reset(QRhi.create(QRhi.Vulkan, params)) else: qFatal("Failed to create Vulkan instance") #endif if rhi: print(rhi.backendName(), rhi.driverInfo()) else: qFatal("Failed to initialize RHI") rotation = 0.0f opacity = 1.0f opacityDir = 1 std.unique_ptr<QRhiTexture> tex(rhi.newTexture(QRhiTexture.RGBA8, QSize(1280, 720), 1, QRhiTexture.RenderTarget | QRhiTexture.UsedAsTransferSource)) tex.create() std.unique_ptr<QRhiTextureRenderTarget> rt(rhi.newTextureRenderTarget({ tex.get() })) std.unique_ptr<QRhiRenderPassDescriptor> rp(rt.newCompatibleRenderPassDescriptor()) rt.setRenderPassDescriptor(rp.get()) rt.create() viewProjection = rhi.clipSpaceCorrMatrix() viewProjection.perspective(45.0f, 1280 / 720.f, 0.01f, 1000.0f) viewProjection.translate(0, 0, -4) vertexData = { // Y up, CCW 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, std.unique_ptr<QRhiBuffer> vbuf(rhi.newBuffer(QRhiBuffer.Immutable, QRhiBuffer.VertexBuffer, sizeof(vertexData))) vbuf.create() std.unique_ptr<QRhiBuffer> ubuf(rhi.newBuffer(QRhiBuffer.Dynamic, QRhiBuffer.UniformBuffer, 64 + 4)) ubuf.create() std.unique_ptr<QRhiShaderResourceBindings> srb(rhi.newShaderResourceBindings()) srb.setBindings({ QRhiShaderResourceBinding.uniformBuffer(0, QRhiShaderResourceBinding.VertexStage | QRhiShaderResourceBinding.FragmentStage, ubuf.get()) }) srb.create() std.unique_ptr<QRhiGraphicsPipeline> ps(rhi.newGraphicsPipeline()) QRhiGraphicsPipeline.TargetBlend premulAlphaBlend premulAlphaBlend.enable = True ps.setTargetBlends({ premulAlphaBlend }) auto getShader = [](QString name) { f = QFile(name) return f.open(QIODevice.OpenModeFlag.ReadOnly) if QShader.fromSerialized(f.readAll()) else QShader() ps.setShaderStages({ { QRhiShaderStage.Vertex, getShader("color.vert.qsb") }, { QRhiShaderStage.Fragment, getShader("color.frag.qsb") } }) inputLayout = QRhiVertexInputLayout() inputLayout.setBindings({ { 5 * sizeof(float) } }) inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute.Float2, 0 }, { 0, 1, QRhiVertexInputAttribute.Float3, 2 * sizeof(float) } }) ps.setVertexInputLayout(inputLayout) ps.setShaderResourceBindings(srb.get()) ps.setRenderPassDescriptor(rp.get()) ps.create() cb = QRhiCommandBuffer() for frame in range(0, 20): rhi.beginOffscreenFrame(cb) u = rhi.nextResourceUpdateBatch() if frame == 0: u.uploadStaticBuffer(vbuf.get(), vertexData) mvp = viewProjection mvp.rotate(rotation, 0, 1, 0) u.updateDynamicBuffer(ubuf.get(), 0, 64, mvp.constData()) rotation += 5.0f u.updateDynamicBuffer(ubuf.get(), 64, 4, opacity) opacity += opacityDir * 0.2f if opacity < 0.0f or opacity > 1.0f: = -1 opacity = qBound(0.0f, opacity, 1.0f) cb.beginPass(rt.get(), Qt.GlobalColor.green, { 1.0f, 0 }, u) cb.setGraphicsPipeline(ps.get()) cb.setViewport({ 0, 0, 1280, 720 }) cb.setShaderResources() QRhiCommandBuffer.VertexInput vbufBinding(vbuf.get(), 0) cb.setVertexInput(0, 1, vbufBinding) cb.draw(3) readbackResult = QRhiReadbackResult() u = rhi.nextResourceUpdateBatch() u.readBackTexture({ tex.get() }, readbackResult) cb.endPass(u) rhi.endOffscreenFrame() QImage image(uchar(readbackResult.data.constData()), readbackResult.pixelSize.width(), readbackResult.pixelSize.height(), QImage.Format.Format_RGBA8888_Premultiplied) if rhi.isYUpInFramebuffer(): image.flip() image.save(QString.asprintf("frame%d.png", frame)) return 0
The result of the application is 20
PNGimages (frame0.png - frame19.png). These contain a rotating triangle with varying opacity over a green background.The vertex and fragment shaders are expected to be processed and packaged into
.qsbfiles. The Vulkan-compatible GLSL source code is the following:color.vert
#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec3 color; layout(location = 0) out vec3 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { v_color = color; gl_Position = mvp * position; }
color.frag
#version 440 layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { fragColor = vec4(v_color * opacity, opacity); }
To manually compile and transpile these shaders to a number of targets (SPIR-V, HLSL, MSL, GLSL) and generate the
.qsbfiles the application loads at run time, runqsb --qt6 color.vert -o color.vert.qsbandqsb --qt6 color.frag -o color.frag.qsb. Alternatively, the Qt Shader Tools module offers build system integration for CMake, theqt_add_shaders()CMake function, that can achieve the same at build time.Security Considerations¶
All data consumed by
QRhiand related classes such asQShaderare considered trusted content.Warning
Application developers are advised to carefully consider the potential implications before allowing the feeding of user-provided content that is not part of the application and is not under the developers’ control. (this includes all vertex/index data, shaders, pipeline and draw call parameters, etc.)
Design Fundamentals¶
A
QRhicannot be instantiated directly. Instead, use thecreate()function. Delete theQRhiinstance normally to release the graphics device.Resources¶
Instances of classes deriving from
QRhiResource, such as,QRhiBuffer,QRhiTexture, etc., encapsulate zero, one, or more native graphics resources. Instances of such classes are always created via thenewfunctions of theQRhi, such as,newBuffer(),newTexture(),newTextureRenderTarget(),newSwapChain().QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)); if (!vbuf->create()) { error(); } // ... delete vbuf;The returned value from functions like
newBuffer()is always owned by the caller.Just creating an instance of a
QRhiResourcesubclass never allocates or initializes any native resources. That is only done when calling thecreate()function of a subclass, for example,create()orcreate().The exceptions are
newCompatibleRenderPassDescriptor(),newCompatibleRenderPassDescriptor(), andnewCompatibleRenderPassDescriptor(). There is nocreate()operation for these and the returned object is immediately active.The resource objects themselves are treated as immutable: once a resource has
create()called, changing any parameters via the setters, such as,setPixelSize(), has no effect, unless the underlying native resource is released andcreate()is called again. See more about resource reuse in the sections below.The underlying native resources are scheduled for releasing by the
QRhiResourcedestructor, or by callingdestroy(). Backends often queue release requests and defer executing them to an unspecified time, this is hidden from the applications. This way applications do not have to worry about releasing native resources that may still be in use by an in-flight frame.Note that this does not mean that a
QRhiResourcecan freely be destroy()’ed or deleted within a frame (that is, in abeginFrame()-endFrame()section). As a general rule, all referencedQRhiResourceobjects must stay unchanged until the frame is submitted by callingendFrame(). To ease this,deleteLater()is provided as a convenience.
Command buffers and deferred command execution¶
Regardless of the design and capabilities of the underlying graphics API, all
QRhibackends implement some level of command buffers. NoQRhiCommandBufferfunction issues any native bind or draw command (such as,glDrawElements) directly. Commands are always recorded in a queue, either native or provided by theQRhibackend. The command buffer is submitted, and so execution starts only uponendFrame()orfinish().The deferred nature has consequences for some types of objects. For example, writing to a dynamic buffer multiple times within a frame, in case such buffers are backed by host-visible memory, will result in making the results of all writes are visible to all draw calls in the command buffer of the frame, regardless of when the dynamic buffer update was recorded relative to a draw call.
Furthermore, instances of
QRhiResourcesubclasses must be treated immutable within a frame in which they are referenced in any way. Create all resources upfront, before starting to record commands for the next frame. Reusing aQRhiResourceinstance within a frame (by callingcreate()then referencing it again in the samebeginFrame - endFramesection) should be avoided as it may lead to unexpected results, depending on the backend.As a general rule, all referenced
QRhiResourceobjects must stay valid and unmodified until the frame is submitted by callingendFrame(). On the other hand, callingdestroy()or deleting theQRhiResourceare always safe once the frame is submitted, regardless of the status of the underlying native resources (which may still be in use by the GPU - but that is taken care of internally).Unlike APIs like OpenGL, upload and copy type of commands cannot be mixed with draw commands. The typical renderer will involve a sequence similar to the following:
(re)create resources
begin frame
record/issue uploads and copies
start recording a render pass
record draw calls
end render pass
end frame
Recording copy type of operations happens via
QRhiResourceUpdateBatch. Such operations are committed typically onbeginPass().When working with legacy rendering engines designed for OpenGL, the migration to
QRhioften involves redesigning from having a singlerenderstep (that performs copies and uploads, clears buffers, and issues draw calls, all mixed together) to a clearly separated, two phaseprepare-rendersetup where therenderstep only starts a renderpass and records draw calls, while all resource creation and queuing of updates, uploads and copies happens beforehand, in thepreparestep.QRhidoes not at the moment allow freely creating and submitting command buffers. This may be lifted in the future to some extent, in particular if compute support is introduced, but the model of well definedframe-startandframe-endpoints, combined with a dedicated, “frame” command buffer, whereframe-endimplies presenting, is going to remain the primary way of operating since this is what fits Qt’s various UI technologies best.Threading¶
A
QRhiinstance and the associated resources can be created and used on any thread but all usage must be limited to that one single thread. When rendering to multiple QWindows in an application, having a dedicated thread andQRhiinstance for each window is often advisable, as this can eliminate issues with unexpected throttling caused by presenting to multiple windows. Conceptually that is then the same as how Qt Quick scene graph’s threaded render loop operates when working directly with OpenGL: one thread for each window, oneQOpenGLContextfor each thread. When moving ontoQRhi,QOpenGLContextis replaced byQRhi, making the migration straightforward.When it comes to externally created native objects, such as OpenGL contexts passed in via
QRhiGles2NativeHandles, it is up to the application to ensure they are not misused by other threads.Resources are not shareable between
QRhiinstances. This is an intentional choice sinceQRhihides most queue, command buffer, and resource synchronization related tasks, and provides no API for them. Safe and efficient concurrent use of graphics resources from multiple threads is tied to those concepts, however, and is thus a topic that is currently out of scope, but may be introduced in the future.Note
The Metal backend requires that an autorelease pool is available on the rendering thread, ideally wrapping each iteration of the render loop. This needs no action from the users of
QRhiwhen rendering on the main (gui) thread, but becomes important when a separate, dedicated render thread is used.Resource synchronization¶
QRhidoes not expose APIs for resource barriers or image layout transitions. Such synchronization is done implicitly by the backends, where applicable (for example, Vulkan), by tracking resource usage as necessary. Buffer and image barriers are inserted before render or compute passes transparently to the application.Note
Resources within a render or compute pass are expected to be bound to a single usage during that pass. For example, a buffer can be used as vertex, index, uniform, or storage buffer, but not a combination of them within a single pass. However, it is perfectly fine to use a buffer as a storage buffer in a compute pass, and then as a vertex buffer in a render pass, for example, assuming the buffer declared both usages upon creation.
Note
Textures have this rule relaxed in certain cases, because using two subresources (typically two different mip levels) of the same texture for different access (one for load, one for store) is supported even within the same pass.
Resource reuse¶
From the user’s point of view a
QRhiResourceis reusable immediately after callingdestroy(). With the exception of swapchains, callingcreate()on an already created object does an implicitdestroy(). This provides a handy shortcut to reuse aQRhiResourceinstance with different parameters, with a new native graphics object underneath.The importance of reusing the same object lies in the fact that some objects reference other objects: for example, a
QRhiShaderResourceBindingscan referenceQRhiBuffer,QRhiTexture, andQRhiSamplerinstances. If in a later frame one of these buffers need to be resized or a sampler parameter needs changing, destroying and creating a whole newQRhiBufferorQRhiSamplerwould invalidate all references to the old instance. By just changing the appropriate parameters viasetSize()or similar and then callingcreate(), everything works as expected and there is no need to touch theQRhiShaderResourceBindingsat all, even though there is a good chance that under the hood theQRhiBufferis now backed by a whole new native buffer.QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256); ubuf->create(); QRhiShaderResourceBindings *srb = rhi->newShaderResourceBindings() srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, ubuf) }); srb->create(); // ... // now in a later frame we need to grow the buffer to a larger size ubuf->setSize(512); ubuf->create(); // same as ubuf->destroy(); ubuf->create(); // srb needs no changes whatsoever, any references in it to ubuf // stay valid. When it comes to internal details, such as that // ubuf may now be backed by a completely different native buffer // resource, that is is recognized and handled automatically by the // next setShaderResources().
QRhiTextureRenderTargetoffers the same contract: callingbeginPass()is safe even when one of the render target’s associated textures or renderbuffers has been rebuilt (by callingcreate()on it) since the creation of the render target object. This allows the application to resize a texture by setting a new pixel size on theQRhiTextureand callingcreate(), thus creating a whole new native texture resource underneath, without having to update theQRhiTextureRenderTargetas that will be done implicitly in beginPass().Pooled objects¶
In addition to resources, there are pooled objects as well, such as,
QRhiResourceUpdateBatch. An instance is retrieved via anextfunction, such as,nextResourceUpdateBatch(). The caller does not own the returned instance in this case. The only valid way of operating here is calling functions on theQRhiResourceUpdateBatchand then passing it tobeginPass()orendPass(). These functions take care of returning the batch to the pool. Alternatively, a batch can be “canceled” and returned to the pool without processing by callingrelease().A typical pattern is thus:
QRhiResourceUpdateBatch *resUpdates = rhi->nextResourceUpdateBatch(); // ... resUpdates->updateDynamicBuffer(ubuf, 0, 64, mvp.constData()); if (!image.isNull()) { resUpdates->uploadTexture(texture, image); image = QImage(); } // ... QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); // note the last argument cb->beginPass(swapchain->currentFrameRenderTarget(), clearCol, clearDs, resUpdates);Swapchain specifics¶
QRhiSwapChainfeatures some special semantics due to the peculiar nature of swapchains.It has no
create()but rather acreateOrResize(). Repeatedly calling this function is not the same as callingdestroy()followed bycreateOrResize(). This is because swapchains often have ways to handle the case where buffers need to be resized in a manner that is more efficient than a brute force destroying and recreating from scratch.An active
QRhiSwapChainmust be released by callingdestroy(), or by destroying the object, before theQWindow‘s underlying QPlatformWindow, and so the associated native window object, is destroyed. It should not be postponed because releasing the swapchain may become problematic (and with some APIs, like Vulkan, is explicitly disallowed) when the native window is not around anymore, for example because the QPlatformWindow got destroyed upon getting aclose(). Therefore, releasing the swapchain must happen whenever the targetedQWindowsends theSurfaceAboutToBeDestroyedevent. If the event does not arrive before the destruction of theQWindow- this can happen when using QCoreApplication::quit() -, then check QWindow::handle() after the event loop exits and invoke the swapchain release when non-null (meaning the underlying native window is still around).
Ownership¶
The general rule is no ownership transfer. Creating a
QRhiwith an already existing graphics device does not mean theQRhitakes ownership of the device object. Similarly, ownership is not given away when a device or texture object is “exported” vianativeHandles()ornativeTexture(). Most importantly, passing pointers in structs and via setters does not transfer ownership.Troubleshooting and Profiling¶
Error reporting¶
Functions such as
create()and the resource classes’create()member functions (e.g.,create()) indicate failure with the return value (Noneorfalse, respectively). When working withQShader,fromSerialized()returns an invalidQShader(for whichisValid()returnsfalse) when the data passed to the function cannot be successfully deserialized. Some functions,beginFrame()in particular, may also sometimes report “soft failures”, such asFrameOpSwapChainOutOfDate, which do not indicate an unrecoverable error, but rather should be seen as a “try again later” response.Warnings and errors may get printed at any time to the debug output via qWarning(). It is therefore always advisable to inspect the output of the application.
Additional debug messages can be enabled via the following logging categories. Messages from these categories are not printed by default unless explicitly enabled via QLoggingCategory or the
QT_LOGGING_RULESenvironment variable. For better interoperation with Qt Quick, the environment variableQSG_INFOalso enables these debug prints.qt.rhi.general
Additionally, applications can query the
QRhi backend nameandgraphics device informationfrom a successfully initializedQRhi. This can then be printed to the user or stored in the application logs even in production builds, if desired.Investigating rendering problems¶
When the rendering results are not as expected, or the application is experiencing problems, always consider checking with the the native 3D APIs’ debug and validation facilities.
QRhiitself features limited error checking since replicating the already existing, vast amount of functionality in the underlying layers is not reasonable.For Vulkan, controlling the Vulkan Validation Layers is not in the scope of the
QRhi, but rather can be achieved by configuring theQVulkanInstancewith the appropriate layers. For example, callinstance.setLayers({ "VK_LAYER_KHRONOS_validation" });before invokingcreate()on theQVulkanInstance. (note that this assumes that the validation layers are actually installed and available, e.g. from the Vulkan SDK) By default,QVulkanInstanceconveniently redirects the Vulkan debug messages to qDebug, meaning the validation messages get printed just like other Qt warnings.With Direct 3D 11 and 12, a graphics device with the debug layer enabled can be requested by toggling the
enableDebugLayerflag in the appropriateinit params struct. The messages appear on the debug output, which is visible in Qt Creator’s messages panel or via a tool such as DebugView .For Metal, controlling Metal Validation is outside of
QRhi‘s scope. Rather, to enable validation, run the application with the environment variableMETAL_DEVICE_WRAPPER_TYPE=1set, or run the application within XCode. There may also be further settings and environment variable in modern XCode and macOS versions. See for instance this page .
Frame captures and performance profiling¶
A Qt application rendering with
QRhito a window while relying on a 3D API under the hood, is, from the windowing and graphics pipeline perspective at least, no different from any other (non-Qt) applications using the same 3D API. This means that tools and practices for debugging and profiling applications involving 3D graphics, such as games, all apply to such a Qt application as well.A few examples of tools that can provide insights into the rendering internals of Qt applications that use
QRhi, which includes Qt Quick and Qt Quick 3D based projects as well:RenderDoc allows taking frame captures and introspecting the recorded commands and pipeline state on Windows and Linux for applications using OpenGL, Vulkan, D3D11, or D3D12. When trying to figure out why some parts of the 3D scene do not show up as expected, RenderDoc is often a fast and efficient way to check the pipeline stages and the related state and discover the missing or incorrect value. It is also a tool that is actively used when developing Qt itself.
For NVIDIA-based systems, Nsight Graphics provides a graphics debugger tool on Windows and Linux. In addition to investigating the commands in the frame and the pipeline, the vendor-specific tools allow looking at timings and hardware performance information, which is not something simple frame captures can provide.
For AMD-based systems, the Radeon GPU Profiler can be used to gain deeper insights into the application’s rendering and its performance.
As
QRhisupports Direct 3D 12, using PIX , a performance tuning and debugging tool for DirectX 12 games on Windows is an option as well.On macOS, the XCode Metal debugger can be used to take and introspect frame captures, to investigate performance details, and debug shaders. In macOS 13 it is also possible to enable an overlay that displays frame rate and other information for any Metal-based window by setting the environment variable
MTL_HUD_ENABLED=1.
On mobile and embedded platforms, there may be vendor and platform-specific tools, provided by the GPU or SoC vendor, available to perform performance profiling of application using OpenGL ES or Vulkan.
When capturing frames, remember that objects and groups of commands can be named via debug markers, as long as
debug markers were enabledfor theQRhi, and the graphics API in use supports this. To annotate the command stream, calldebugMarkBegin(),debugMarkEnd()and/ordebugMarkMsg(). This can be particularly useful in larger frames with multiple render passes. Resources are named by callingsetName()beforecreate().To perform basic timing measurements on the CPU and GPU side within the application, QElapsedTimer and
lastCompletedGpuTime()can be used. The latter is only available with select graphics APIs at the moment and requires opting in via theEnableTimestampsflag.Resource leak checking¶
When destroying a
QRhiobject without properly destroying all buffers, textures, and other resources created from it, warnings about this are printed to the debug output whenever the application is a debug build, or when theQT_RHI_LEAK_CHECKenvironment variable is set to a non-zero value. This is a simple way to discover design issues around resource handling within the application rendering logic. Note however that some platforms and underlying graphics APIs may perform their own allocation and resource leak detection as well, over which Qt will have no direct control. For example, when using Vulkan, the memory allocator may raise failing assertions in debug builds when resources that own graphics memory allocations are not destroyed before theQRhi. In addition, the Vulkan validation layer, when enabled, will issue warnings about native graphics resources that were not released. Similarly, with Direct 3D warnings may get printed about unreleased COM objects when the application does not destroy theQRhiand its resources in the correct order.- class Implementation¶
Describes which graphics API-specific backend gets used by a
QRhiinstance.Constant
Description
QRhi.Implementation.Null
QRhi.Implementation.Vulkan
QRhi.Implementation.OpenGLES2
QRhi.Implementation.D3D11
QRhi.Implementation.D3D12
QRhi.Implementation.Metal
- class Flag¶
(inherits
enum.Flag) Describes what special features to enable.Constant
Description
QRhi.Flag.EnableDebugMarkers
Enables debug marker groups. Without this frame debugging features like making debug groups and custom resource name visible in external GPU debugging tools will not be available and functions like
debugMarkBegin()will become no-ops. Avoid enabling in production builds as it may involve a small performance impact. Has no effect when theDebugMarkersfeature is not reported as supported.QRhi.Flag.EnableTimestamps
Enables GPU timestamp collection. When not set,
lastCompletedGpuTime()always returns 0. Enable this only when needed since there may be a small amount of extra work involved (e.g. timestamp queries), depending on the underlying graphics API. Has no effect when theTimestampsfeature is not reported as supported.QRhi.Flag.PreferSoftwareRenderer
Indicates that backends should prefer choosing an adapter or physical device that renders in software on the CPU. For example, with Direct3D there is typically a “Basic Render Driver” adapter available with
DXGI_ADAPTER_FLAG_SOFTWARE. Setting this flag requests the backend to choose that adapter over any other, as long as no specific adapter was forced by other backend-specific means. With Vulkan this maps to preferring physical devices withVK_PHYSICAL_DEVICE_TYPE_CPU. When not available, or when it is not possible to decide if an adapter/device is software-based, this flag is ignored. It may also be ignored with graphics APIs that have no concept and means of enumerating adapters/devices.QRhi.Flag.EnablePipelineCacheDataSave
Enables retrieving the pipeline cache contents, where applicable. When not set,
pipelineCacheData()will return an empty blob always. With backends where retrieving and restoring the pipeline cache contents is not supported, the flag has no effect and the serialized cache data is always empty. The flag provides an opt-in mechanism because the cost of maintaining the related data structures is not insignificant with some backends. With Vulkan this feature maps directly to VkPipelineCache, vkGetPipelineCacheData and VkPipelineCacheCreateInfo::pInitialData. With Direct3D 11 there is no real pipline cache, but the results of HLSL->DXBC compilations are stored and can be serialized/deserialized via this mechanism. This allows skipping the time consuming D3DCompile() in future runs of the applications for shaders that come with HLSL source instead of offline pre-compiled bytecode. This can provide a huge boost in startup and load times, if there is a lot of HLSL source compilation happening. With OpenGL the “pipeline cache” is simulated by retrieving and loading shader program binaries (if supported by the driver). With OpenGL there are additional, disk-based caching mechanisms for shader/program binaries provided by Qt. Writing to those may get disabled whenever this flag is set since storing program binaries to multiple caches is not sensible.QRhi.Flag.SuppressSmokeTestWarnings
Indicates that, with backends where this is relevant, certain, non-fatal
create()failures should not produce qWarning() calls. For example, with D3D11, passing this flag makes a number of warning messages (that appear due tocreate()failing) to become categorized debug prints instead under the commonly usedqt.rhi.generallogging category. This can be used by engines, such as Qt Quick, that feature fallback logic, i.e. they retry callingcreate()with a different set of flags (such as, PreferSoftwareRenderer), in order to hide the unconditional warnings from the output that would be printed when the firstcreate()attempt had failed.
- class FrameOpResult¶
Describes the result of operations that can have a soft failure.
Constant
Description
QRhi.FrameOpResult.FrameOpSuccess
Success
QRhi.FrameOpResult.FrameOpError
Unspecified error
QRhi.FrameOpResult.FrameOpSwapChainOutOfDate
The swapchain is in an inconsistent state internally. This can be recoverable by attempting to repeat the operation (such as,
beginFrame()) later.QRhi.FrameOpResult.FrameOpDeviceLost
The graphics device was lost. This can be recoverable by attempting to repeat the operation (such as,
beginFrame()) after releasing and reinitializing all objects backed by native graphics resources. SeeisDeviceLost().
- class Feature¶
Flag values to indicate what features are supported by the backend currently in use.
Constant
Description
QRhi.Feature.MultisampleTexture
Indicates that textures with a sample count larger than 1 are supported. In practice this feature will be unsupported with OpenGL ES versions older than 3.1, and OpenGL older than 3.0.
QRhi.Feature.MultisampleRenderBuffer
Indicates that renderbuffers with a sample count larger than 1 are supported. In practice this feature will be unsupported with OpenGL ES 2.0, and may also be unsupported with OpenGL 2.x unless the relevant extensions are present.
QRhi.Feature.DebugMarkers
Indicates that debug marker groups (and so
debugMarkBegin()) are supported.QRhi.Feature.Timestamps
Indicates that command buffer timestamps are supported. Relevant for
lastCompletedGpuTime(). This can be expected to be supported on Metal, Vulkan, Direct 3D 11 and 12, and OpenGL contexts of version 3.3 or newer. However, with some of these APIs support for timestamp queries is technically optional, and therefore it cannot be guaranteed that this feature is always supported with every implementation of them.QRhi.Feature.Instancing
Indicates that instanced drawing is supported. In practice this feature will be unsupported with OpenGL ES 2.0 and OpenGL 3.2 or older.
QRhi.Feature.CustomInstanceStepRate
Indicates that instance step rates other than 1 are supported. In practice this feature will always be unsupported with OpenGL. In addition, running with Vulkan 1.0 without VK_EXT_vertex_attribute_divisor will also lead to reporting false for this feature.
QRhi.Feature.PrimitiveRestart
Indicates that restarting the assembly of primitives when encountering an index value of 0xFFFF (
IndexUInt16) or 0xFFFFFFFF (IndexUInt32) is enabled, for certain primitive topologies at least.QRhiwill try to enable this with all backends, but in some cases it will not be supported. Dynamically controlling primitive restart is not possible since with some APIs primitive restart with a fixed index is always on. Applications must assume that whenever this feature is reported as supported, the above mentioned index valuesmaybe treated specially, depending on the topology. The only two topologies where primitive restart is guaranteed to behave identically across backends, as long as this feature is reported as supported, areLineStripandTriangleStrip.QRhi.Feature.NonDynamicUniformBuffers
Indicates that creating buffers with the usage
UniformBufferand the typesImmutableorStaticis supported. When reported as unsupported, uniform (constant) buffers must be created asDynamic. (which is recommended regardless)QRhi.Feature.NonFourAlignedEffectiveIndexBufferOffset
Indicates that effective index buffer offsets (
indexOffset + firstIndex * indexComponentSize) that are not 4 byte aligned are supported. When not supported, attempting to issue adrawIndexed()with a non-aligned effective offset may lead to unspecified behavior. Relevant in particular for Metal, where this will be reported as unsupported.QRhi.Feature.NPOTTextureRepeat
Indicates that the
Repeatwrap mode and mipmap filtering modes are supported for textures with a non-power-of-two size. In practice this can only be false with OpenGL ES 2.0 implementations withoutGL_OES_texture_npot.QRhi.Feature.RedOrAlpha8IsRed
Indicates that the
RED_OR_ALPHA8format maps to a one component 8-bitredformat. This is the case for all backends except OpenGL when using either OpenGL ES or a non-core profile context. ThereGL_ALPHA, a one component 8-bitalphaformat, is used instead. Using the special texture format allows having a single code path for creating textures, leaving it up to the backend to decide the actual format, while the feature flag can be used to pick the appropriate shader variant for sampling the texture.QRhi.Feature.ElementIndexUint
Indicates that 32-bit unsigned integer elements are supported in the index buffer. In practice this is true everywhere except when running on plain OpenGL ES 2.0 implementations without the necessary extension. When false, only 16-bit unsigned elements are supported in the index buffer.
QRhi.Feature.Compute
Indicates that compute shaders, image load/store, and storage buffers are supported. OpenGL older than 4.3 and OpenGL ES older than 3.1 have no compute support.
QRhi.Feature.WideLines
Indicates that lines with a width other than 1 are supported. When reported as not supported, the line width set on the graphics pipeline state is ignored. This can always be false with some backends (D3D11, D3D12, Metal). With Vulkan, the value depends on the implementation. With OpenGL, wide lines are not supported in core profile contexts.
QRhi.Feature.VertexShaderPointSize
Indicates that the size of rasterized points set via
gl_PointSizein the vertex shader is taken into account. When reported as not supported, drawing points with a size other than 1 is not supported. Settinggl_PointSizein the shader is still valid then, but is ignored. (for example, when generating HLSL, the assignment is silently dropped from the generated code) Note that some APIs (Metal, Vulkan) require the point size to be set in the shader explicitly whenever drawing points, even when the size is 1, as they do not automatically default to 1.QRhi.Feature.BaseVertex
Indicates that
drawIndexed()supports thevertexOffsetargument. When reported as not supported, the vertexOffset value in an indexed draw is ignored. In practice this feature will be unsupported with OpenGL and OpenGL ES versions lower than 3.2, and with Metal on older iOS devices, including the iOS Simulator.QRhi.Feature.BaseInstance
Indicates that instanced draw commands support the
firstInstanceargument. When reported as not supported, the firstInstance value is ignored and the instance ID starts from 0. In practice this feature will be unsupported with with Metal on older iOS devices, including the iOS Simulator, and all versions of OpenGL. The latter is due to OpenGL ES not supporting draw calls with a base instance at all. CurrentlyQRhi‘s OpenGL backend does not implement the functionality for OpenGL (non-ES) either, because portable applications cannot rely on a non-zero base instance in practice due to GLES.QRhi.Feature.TriangleFanTopology
Indicates that
setTopology()supportsTriangleFan. In practice this feature will be unsupported with Metal and Direct 3D 11/12.QRhi.Feature.ReadBackNonUniformBuffer
Indicates that
reading buffer contentsis supported forQRhiBufferinstances with a usage different than UniformBuffer. In practice this feature will be unsupported with OpenGL ES 2.0.QRhi.Feature.ReadBackNonBaseMipLevel
Indicates that specifying a mip level other than 0 is supported when reading back texture contents. When not supported, specifying a non-zero level in
QRhiReadbackDescriptionleads to returning an all-zero image. In practice this feature will be unsupported with OpenGL ES 2.0.QRhi.Feature.TexelFetch
Indicates that texelFetch() and textureLod() are available in shaders. In practice this will be reported as unsupported with OpenGL ES 2.0 and OpenGL 2.x contexts, because GLSL 100 es and versions before 130 do not support these functions.
QRhi.Feature.RenderToNonBaseMipLevel
Indicates that specifying a mip level other than 0 is supported when creating a
QRhiTextureRenderTargetwith aQRhiTextureas its color attachment. When not supported,create()will fail whenever the target mip level is not zero. In practice this feature will be unsupported with OpenGL ES 2.0.QRhi.Feature.IntAttributes
Indicates that specifying input attributes with signed and unsigned integer types for a shader pipeline is supported. When not supported, build() will succeed but just show a warning message and the values of the target attributes will be broken. In practice this feature will be unsupported with OpenGL ES 2.0 and OpenGL 2.x.
QRhi.Feature.ScreenSpaceDerivatives
Indicates that functions such as dFdx(), dFdy(), and fwidth() are supported in shaders. In practice this feature will be unsupported with OpenGL ES 2.0 without the GL_OES_standard_derivatives extension.
QRhi.Feature.ReadBackAnyTextureFormat
Indicates that reading back texture contents can be expected to work for any
Format. Backends other than OpenGL can be expected to return true for this feature. When reported as false, which will typically happen with OpenGL, only the formatsRGBA8andBGRA8are guaranteed to be supported for readbacks. In addition, with OpenGL, but not OpenGL ES, reading back the 1 byte per component formatsR8andRED_OR_ALPHA8are supported as well. Reading back floating point formatsRGBA16Fand RGBA32F may work too with OpenGL, as long as the implementation provides support for these, butQRhican give no guarantees, as indicated by this flag.QRhi.Feature.PipelineCacheDataLoadSave
Indicates that the
pipelineCacheData()andsetPipelineCacheData()functions are functional. When not supported, the functions will not perform any action, the retrieved blob is always empty, and thus no benefits can be expected from retrieving and, during a subsequent run of the application, reloading the pipeline cache content.QRhi.Feature.ImageDataStride
Indicates that specifying a custom stride (row length) for raw image data in texture uploads is supported. When not supported (which can happen when the underlying API is OpenGL ES 2.0 without support for GL_UNPACK_ROW_LENGTH),
setDataStride()must not be used.QRhi.Feature.RenderBufferImport
Indicates that
createFrom()is supported. For most graphics APIs this is not sensible becauseQRhiRenderBufferencapsulates texture objects internally, just likeQRhiTexture. With OpenGL however, renderbuffer object exist as a separate object type in the API, and in certain environments (for example, where one may want to associated a renderbuffer object with an EGLImage object) it is important to allow wrapping an existing OpenGL renderbuffer object with aQRhiRenderBuffer.QRhi.Feature.ThreeDimensionalTextures
Indicates that 3D textures are supported. In practice this feature will be unsupported with OpenGL and OpenGL ES versions lower than 3.0.
QRhi.Feature.RenderTo3DTextureSlice
Indicates that rendering to a slice in a 3D texture is supported. This can be unsupported with Vulkan 1.0 due to relying on VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT which is a Vulkan 1.1 feature.
QRhi.Feature.TextureArrays
Indicates that texture arrays are supported and
newTextureArray()is functional. Note that even when texture arrays are not supported, arrays of textures are still available as those are two independent features.QRhi.Feature.Tessellation
Indicates that the tessellation control and evaluation stages are supported. When reported as supported, the topology of a
QRhiGraphicsPipelinecan be set toPatches, the number of control points can be set viasetPatchControlPointCount(), and shaders for tessellation control and evaluation can be specified in theQRhiShaderStagelist. Tessellation shaders have portability issues between APIs (for example, translating GLSL/SPIR-V to HLSL is problematic due to the way hull shaders are structured, whereas Metal uses a somewhat different tessellation pipeline than others), and therefore unexpected issues may still arise, even though basic functionality is implemented across all the underlying APIs. For Direct 3D in particular, handwritten HLSL hull and domain shaders must be injected into eachQShaderfor the tessellation control and evaluation stages, respectively, since qsb cannot generate these from SPIR-V. Note that isoline tessellation should be avoided as it will not be supported by all backends. The maximum patch control point count portable between backends is 32.QRhi.Feature.GeometryShader
Indicates that the geometry shader stage is supported. When supported, a geometry shader can be specified in the
QRhiShaderStagelist. Geometry Shaders are considered an experimental feature inQRhiand can only be expected to be supported with Vulkan, Direct 3D, OpenGL (3.2+) and OpenGL ES (3.2+), assuming the implementation reports it as supported at run time. Geometry shaders have portability issues between APIs, and therefore no guarantees can be given for a universal solution. They will never be supported with Metal. Whereas with Direct 3D a handwritten HLSL geometry shader must be injected into eachQShaderfor the geometry stage since qsb cannot generate this from SPIR-V.QRhi.Feature.TextureArrayRange
Indicates that for
texture arraysit is possible to specify a range that is exposed to the shaders. Normally all array layers are exposed and it is up to the shader to select the layer (via the third coordinate passed to texture() when sampling thesampler2DArray). When supported, calling QRhiTexture::setArrayRangeStart() and QRhiTexture::setArrayRangeLength() beforebuildingorimportingthe native texture has an effect, and leads to selecting only the specified range from the array. This will be necessary in special cases, such as when working with accelerated video decoding and Direct 3D 11, because a texture array with bothD3D11_BIND_DECODERandD3D11_BIND_SHADER_RESOURCEon it is only usable as a shader resource if a single array layer is selected. Note that all this is applicable only when the texture is used as aSampledTextureorTextureshader resource, and is not compatible with image load/store. This feature is only available with some backends as it does not map well to all graphics APIs, and it is only meant to provide support for special cases anyhow. In practice the feature can be expected to be supported with Direct3D 11/12 and Vulkan.QRhi.Feature.NonFillPolygonMode
Indicates that setting a PolygonMode other than the default Fill is supported for
QRhiGraphicsPipeline. A common use case for changing the mode to Line is to get wireframe rendering. This however is not available as a core OpenGL ES feature, and is optional with Vulkan as well as some mobile GPUs may not offer the feature.QRhi.Feature.OneDimensionalTextures
Indicates that 1D textures are supported. In practice this feature will be unsupported on OpenGL ES.
QRhi.Feature.OneDimensionalTextureMipmaps
Indicates that generating 1D texture mipmaps are supported. In practice this feature will be unsupported on backends that do not report support for OneDimensionalTextures, Metal, and Direct 3D 12.
QRhi.Feature.HalfAttributes
Indicates that specifying input attributes with half precision (16bit) floating point types for a shader pipeline is supported. When not supported, build() will succeed but just show a warning message and the values of the target attributes will be broken. In practice this feature will be unsupported in some OpenGL ES 2.0 and OpenGL 2.x implementations. Note that while Direct3D 11/12 does support half precision input attributes, it does not support the half3 type. The D3D backends pass half3 attributes as half4. To ensure cross platform compatibility, half3 inputs should be padded to 8 bytes.
QRhi.Feature.RenderToOneDimensionalTexture
Indicates that 1D texture render targets are supported. In practice this feature will be unsupported on backends that do not report support for OneDimensionalTextures, and Metal.
QRhi.Feature.ThreeDimensionalTextureMipmaps
Indicates that generating 3D texture mipmaps are supported. This is typically supported with all backends starting with Qt 6.10.
QRhi.Feature.MultiView
Indicates that multiview, see e.g. VK_KHR_multiview is supported. With OpenGL ES 2.0, Direct 3D 11, and OpenGL (ES) implementations without
GL_OVR_multiview2this feature will not be supported. With Vulkan 1.1 and newer, and Direct 3D 12 multiview is typically supported. When reported as supported, creating aQRhiTextureRenderTargetwith aQRhiColorAttachmentthat references a texture array and hasmultiViewCountset enables recording a render pass that uses multiview rendering. In addition, anyQRhiGraphicsPipelineused in that render pass must havethe same view count set. Note that multiview is only available in combination with 2D texture arrays. It cannot be used to optimize the rendering into individual textures (e.g. two, for the left and right eyes). Rather, the target of a multiview render pass is always a texture array, automatically rendering to the layer (array element) corresponding to each view. Therefore this feature implies TextureArrays as well. Multiview rendering is not supported in combination with tessellation or geometry shaders. SeesetMultiViewCount()for further details on multiview rendering. This enum value has been introduced in Qt 6.7.QRhi.Feature.TextureViewFormat
Indicates that setting a
view formaton aQRhiTextureis effective. When reported as supported, setting the read (sampling) or write (render target / image load-store) view mode changes the texture’s viewing format. When unsupported, setting a view format has no effect. Note that Qt has no knowledge or control over format compatibility or resource view rules in the underlying 3D API and its implementation. Passing in unsuitable, incompatible formats may lead to errors and unspecified behavior. This is provided mainly to allow “casting” rendering into a texture created with an sRGB format to non-sRGB to avoid the unwanted linear->sRGB conversion on shader writes. Other types of casting may or may not be functional, depending on the underlying API. Currently implemented for Vulkan and Direct 3D 12. With D3D12 the feature is available only ifCastingFullyTypedFormatSupportedis supported, see https://microsoft.github.io/DirectX-Specs/d3d/RelaxedCasting.html (and note thatQRhialways uses fully typed formats for textures.) This enum value has been introduced in Qt 6.8.QRhi.Feature.ResolveDepthStencil
Indicates that resolving a multisample depth or depth-stencil texture is supported. Otherwise,
setting a depth resolve textureis not functional and must be avoided. Direct 3D 11 and 12 have no support for resolving depth/depth-stencil formats, and therefore this feature will never be supported with those. Vulkan 1.0 has no API to request resolving a depth-stencil attachment. Therefore, with Vulkan this feature will only be supported with Vulkan 1.2 and up, and on 1.1 implementations with the appropriate extensions present. This feature is provided for the rare case when resolving into a non-multisample depth texture becomes necessary, for example when rendering into an OpenXR-provided depth texture (XR_KHR_composition_layer_depth). This enum value has been introduced in Qt 6.8.QRhi.Feature.VariableRateShading
Indicates that per-draw (per-pipeline) variable rate shading is supported. When reported as supported,
setShadingRate()is functional and has an effect forQRhiGraphicsPipelineobjects that declaredUsesShadingRatein their flags. CallsupportedShadingRates()to check which rates are supported. (1x1 is always supported, other typical values are 2x2, 1x2, 2x1, 2x4, 4x2, 4x4). This feature can be expected to be supported with Direct 3D 12 and Vulkan, assuming the implementation and GPU used at run time supports VRS. This enum value has been introduced in Qt 6.9.QRhi.Feature.VariableRateShadingMap
Indicates that image-based specification of the shading rate is possible. The “image” is not necessarily a texture, it may be a native 3D API object, depending on the underlying backend and graphics API at run time. In practice this feature can be expected to be supported with Direct 3D 12, Vulkan, and Metal, assuming the GPU is modern enough to support VRS. To check if D3D12/Vulkan-style image-based VRS is suspported, use VariableRateShadingMapWithTexture instead. When this feature is reported as supported, there are two possibilities: when VariableRateShadingMapWithTexture is also true, then
QRhiShadingRateMapconsumesQRhiTextureobjects via the createFrom() overload taking aQRhiTextureargument. When VariableRateShadingMapWithTexture is false, thenQRhiShadingRateMapconsumes some other type of native objects, for example an MTLRasterizationRateMap in case of Metal. Use the createFrom() overload taking a NativeShadingRateMap in this case. This enum value has been introduced in Qt 6.9.QRhi.Feature.VariableRateShadingMapWithTexture
Indicates that image-based specification of the shading rate is supported via regular textures. In practice this may be supported with Direct 3D 12 and Vulkan. This enum value has been introduced in Qt 6.9.
QRhi.Feature.PerRenderTargetBlending
Indicates that per rendertarget blending is supported i.e. different render targets in MRT framebuffer can have different blending modes. In practice this can be expected to be supported everywhere except OpenGL ES, where it is only available with GLES 3.2 implementations. This enum value has been introduced in Qt 6.9.
QRhi.Feature.SampleVariables
Indicates that gl_SampleID, gl_SamplePosition, gl_SampleMaskIn and gl_SampleMask variables are available in fragment shaders. In practice this can be expected to be supported everywhere except OpenGL ES, where it is only available with GLES 3.2 implementations. This enum value has been introduced in Qt 6.9.
- class BeginFrameFlag¶
(inherits
enum.Flag) Flag values forbeginFrame()
- class EndFrameFlag¶
(inherits
enum.Flag) Flag values forendFrame()Constant
Description
QRhi.EndFrameFlag.SkipPresent
Specifies that no present command is to be queued or no swapBuffers call is to be made. This way no image is presented. Generating multiple frames with all having this flag set is not recommended (except, for example, for benchmarking purposes - but keep in mind that backends may behave differently when it comes to waiting for command completion without presenting so the results are not comparable between them)
- class ResourceLimit¶
Describes the resource limit to query.
Constant
Description
QRhi.ResourceLimit.TextureSizeMin
Minimum texture width and height. This is typically 1. The minimum texture size is handled gracefully, meaning attempting to create a texture with an empty size will instead create a texture with the minimum size.
QRhi.ResourceLimit.TextureSizeMax
Maximum texture width and height. This depends on the graphics API and sometimes the platform or implementation as well. Typically the value is in the range 4096 - 16384. Attempting to create textures larger than this is expected to fail.
QRhi.ResourceLimit.MaxColorAttachments
The maximum number of color attachments for a
QRhiTextureRenderTarget, in case multiple render targets are supported. When MRT is not supported, the value is 1. Otherwise this is typically 8, but watch out for the fact that OpenGL only mandates 4 as the minimum, and that is what some OpenGL ES implementations provide.QRhi.ResourceLimit.FramesInFlight
The number of frames the backend may keep “in flight”: with backends like Vulkan or Metal, it is the responsibility of
QRhito block whenever starting a new frame and finding the CPU is alreadyN - 1frames ahead of the GPU (because the command buffer submitted in frame no.current-Nhas not yet completed). The value N is what is returned from here, and is typically 2. This can be relevant to applications that integrate rendering done directly with the graphics API, as such rendering code may want to perform double (if the value is 2) buffering for resources, such as, buffers, similarly to theQRhibackends themselves. The current frame slot index (a value running 0, 1, .., N-1, then wrapping around) is retrievable fromcurrentFrameSlot(). The value is 1 for backends where the graphics API offers no such low level control over the command submission process. Note that pipelining may still happen even when this value is 1 (some backends, such as D3D11, are designed to attempt to enable this, for instance, by using an update strategy for uniform buffers that does not stall the pipeline), but that is then not controlled byQRhiand so not reflected here in the API.QRhi.ResourceLimit.MaxAsyncReadbackFrames
The number of
submittedframes (including the one that contains the readback) after which an asynchronous texture or buffer readback is guaranteed to complete uponstarting a new frame.QRhi.ResourceLimit.MaxThreadGroupsPerDimension
The maximum number of compute work/thread groups that can be dispatched. Effectively the maximum value for the arguments of
dispatch(). Typically 65535.QRhi.ResourceLimit.MaxThreadsPerThreadGroup
The maximum number of invocations in a single local work group, or in other terminology, the maximum number of threads in a thread group. Effectively the maximum value for the product of
local_size_x,local_size_y, andlocal_size_zin the compute shader. Typical values are 128, 256, 512, 1024, or 1536. Watch out that both OpenGL ES and Vulkan specify only 128 as the minimum required limit for implementations. While uncommon for Vulkan, some OpenGL ES 3.1 implementations for mobile/embedded devices only support the spec-mandated minimum value.QRhi.ResourceLimit.MaxThreadGroupX
The maximum size of a work/thread group in the X dimension. Effectively the maximum value of
local_size_xin the compute shader. Typically 256 or 1024.QRhi.ResourceLimit.MaxThreadGroupY
The maximum size of a work/thread group in the Y dimension. Effectively the maximum value of
local_size_yin the compute shader. Typically 256 or 1024.QRhi.ResourceLimit.MaxThreadGroupZ
The maximum size of a work/thread group in the Z dimension. Effectively the maximum value of
local_size_zin the compute shader. Typically 64 or 256.QRhi.ResourceLimit.TextureArraySizeMax
Maximum texture array size. Typically in range 256 - 2048. Attempting to
create a texture arraywith more elements will likely fail.QRhi.ResourceLimit.MaxUniformBufferRange
The number of bytes that can be exposed from a uniform buffer to the shaders at once. On OpenGL ES 2.0 and 3.0 implementations this may be as low as 3584 bytes (224 four component, 32 bits per component vectors). Elsewhere the value is typically 16384 (1024 vec4s) or 65536 (4096 vec4s).
QRhi.ResourceLimit.MaxVertexInputs
The number of input attributes to the vertex shader. The location in a
QRhiVertexInputAttributemust be in range[0, MaxVertexInputs-1]. The value may be as low as 8 with OpenGL ES 2.0. Elsewhere, typical values are 16, 31, or 32.QRhi.ResourceLimit.MaxVertexOutputs
The maximum number of outputs (4 component vector
outvariables) from the vertex shader. The value may be as low as 8 with OpenGL ES 2.0, and 15 with OpenGL ES 3.0 and some Metal devices. Elsewhere, a typical value is 32.QRhi.ResourceLimit.ShadingRateImageTileSize
The tile size for shading rate textures. 0 if the
VariableRateShadingMapWithTexturefeature is not supported. Otherwise a value such as 16, indicating, for example, a tile size of 16x16. Each byte in the (R8UI) shading rate texture defines then the shading rate for a tile of 16x16 pixels. SeeQRhiShadingRateMapfor details.
- PySide6.QtGui.QRhi.MAX_MIP_LEVELS¶
- __init__()¶
- backend()¶
- Return type:
Returns the backend type for this
QRhi.- backendName()¶
- Return type:
str
Returns the backend type as string for this
QRhi.- static backendName(impl)
- Parameters:
impl –
Implementation- Return type:
str
Returns a friendly name for the backend
impl, usually the name of the 3D API in use.- beginFrame(swapChain[, flags={}])¶
- Parameters:
swapChain –
QRhiSwapChainflags – Combination of
BeginFrameFlag
- Return type:
Starts a new frame targeting the next available buffer of
swapChain.A frame consists of resource updates and one or more render and compute passes.
flagscan indicate certain special cases.The high level pattern of rendering into a
QWindowusing a swapchain:Create a swapchain.
Call
createOrResize()whenever the surface size is different than before.Call
destroy()onSurfaceAboutToBeDestroyed.Then on every frame:
beginFrame(sc); updates = nextResourceUpdateBatch(); updates->... QRhiCommandBuffer *cb = sc->currentFrameCommandBuffer(); cb->beginPass(sc->currentFrameRenderTarget(), colorClear, dsClear, updates); ... cb->endPass(); ... // more passes as necessary endFrame(sc);
Returns
FrameOpSuccesson success, or anotherFrameOpResultvalue on failure. Some of these should be treated as soft, “try again later” type of errors: WhenFrameOpSwapChainOutOfDateis returned, the swapchain is to be resized or updated by callingcreateOrResize(). The application should then attempt to generate a new frame.FrameOpDeviceLostmeans the graphics device is lost but this may also be recoverable by releasing all resources, including theQRhiitself, and then recreating all resources. SeeisDeviceLost()for further discussion.- beginOffscreenFrame(cb[, flags={}])¶
- Parameters:
cb –
QRhiCommandBufferflags – Combination of
BeginFrameFlag
- Return type:
Starts a new offscreen frame. Provides a command buffer suitable for recording rendering commands in
cb.flagsis used to indicate certain special cases, just like withbeginFrame().Note
The
QRhiCommandBufferstored to *cb is not owned by the caller.Rendering without a swapchain is possible as well. The typical use case is to use it in completely offscreen applications, e.g. to generate image sequences by rendering and reading back without ever showing a window.
Usage in on-screen applications (so
beginFrame,endFrame, beginOffscreenFrame,endOffscreenFrame,beginFrame, …) is possible too but it does reduce parallelism so it should be done only infrequently.Offscreen frames do not let the CPU potentially generate another frame while the GPU is still processing the previous one. This has the side effect that if readbacks are scheduled, the results are guaranteed to be available once
endOffscreenFrame()returns. That is not the case with frames targeting a swapchain: there the GPU is potentially better utilized, but working with readback operations needs more care from the application becauseendFrame(), unlikeendOffscreenFrame(), does not guarantee that the results from the readback are available at that point.The skeleton of rendering a frame without a swapchain and then reading the frame contents back could look like the following:
QRhiReadbackResult rbResult; QRhiCommandBuffer *cb; rhi->beginOffscreenFrame(&cb); cb->beginPass(rt, colorClear, dsClear); // ... u = nextResourceUpdateBatch(); u->readBackTexture(rb, &rbResult); cb->endPass(u); rhi->endOffscreenFrame(); // image data available in rbResult
See also
- clipSpaceCorrMatrix()¶
- Return type:
Returns a matrix that can be used to allow applications keep using OpenGL-targeted vertex data and perspective projection matrices (such as, the ones generated by
perspective()), regardless of the activeQRhibackend.In a typical renderer, once
this_matrix * mvpis used instead of justmvp, vertex data with Y up and viewports with depth range 0 - 1 can be used without considering what backend (and so graphics API) is going to be used at run time. This way branching based onisYUpInNDC()andisClipDepthZeroToOne()can be avoided (although such logic may still become required when implementing certain advanced graphics techniques).See this page for a discussion of the topic from Vulkan perspective.
- static create(impl, params[, flags={}[, importDevice=None]])¶
- Parameters:
impl –
Implementationparams –
QRhiInitParamsflags – Combination of
FlagimportDevice –
QRhiNativeHandles
- Return type:
Equivalent to create(
impl,params,flags,importDevice,nullptr).- static create(impl, params, flags, importDevice, adapter)
- Parameters:
impl –
Implementationparams –
QRhiInitParamsflags – Combination of
FlagimportDevice –
QRhiNativeHandlesadapter –
QRhiAdapter
- Return type:
Returns a new
QRhiinstance with a backend for the graphics API specified byimplwith the specifiedflags. Returnsnullptrif the function fails.paramsmust point to an instance of one of the backend-specific subclasses ofQRhiInitParams, such as,QRhiVulkanInitParams,QRhiMetalInitParams,QRhiD3D11InitParams,QRhiD3D12InitParams,QRhiGles2InitParams. See these classes for examples on creating aQRhi.QRhiby design does not implement any fallback logic: if the specified API cannot be initialized, create() will fail, with warnings printed on the debug output by the backends. The clients ofQRhi, for example Qt Quick, may however provide additional logic that allow falling back to an API different than what was requested, depending on the platform. If the intention is just to test if initialization would succeed when calling create() at later point, it is preferable to useprobe()instead of create(), because with some backends probing can be implemented in a more lightweight manner as opposed to create(), which performs full initialization of the infrastructure and is wasteful if thatQRhiinstance is then thrown immediately away.importDeviceallows using an already existing graphics device, withoutQRhicreating its own. When not null, this parameter must point to an instance of one of the subclasses ofQRhiNativeHandles:QRhiVulkanNativeHandles,QRhiD3D11NativeHandles,QRhiD3D12NativeHandles,QRhiMetalNativeHandles,QRhiGles2NativeHandles. The exact details and semantics depend on the backand and the underlying graphics API.Specifying a
QRhiAdapterinadapteroffers a transparent, cross-API alternative to passing in aVkPhysicalDeviceviaQRhiVulkanNativeHandles, or an adapter LUID viaQRhiD3D12NativeHandles. The ownership ofadapteris not taken. SeeenumerateAdapters()for more information on this approach.- currentFrameSlot()¶
- Return type:
int
Returns the current frame slot index while recording a frame. Unspecified when called outside an active frame (that is, when
isRecordingFrame()isfalse).With backends like Vulkan or Metal, it is the responsibility of the
QRhibackend to block whenever starting a new frame and finding the CPU is alreadyFramesInFlight - 1frames ahead of the GPU (because the command buffer submitted in frame no.current-FramesInFlighthas not yet completed).Resources that tend to change between frames (such as, the native buffer object backing a
QRhiBufferwith typeDynamic) exist in multiple versions, so that each frame, that can be submitted while a previous one is still being processed, works with its own copy, thus avoiding the need to stall the pipeline when preparing the frame. (The contents of a resource that may still be in use in the GPU should not be touched, but simply always waiting for the previous frame to finish would reduce GPU utilization and ultimately, performance and efficiency.)Conceptually this is somewhat similar to copy-on-write schemes used by some C++ containers and other types. It may also be similar to what an OpenGL or Direct 3D 11 implementation performs internally for certain type of objects.
In practice, such double (or triple) buffering resources is realized in the Vulkan, Metal, and similar
QRhibackends by having a fixed number of native resource (such as, VkBuffer)slotsbehind aQRhiResource. That can then be indexed by a frame slot index running 0, 1, ..,FramesInFlight-1, and then wrapping around.All this is managed transparently to the users of
QRhi. However, applications that integrate rendering done directly with the graphics API may want to perform a similar double or triple buffering of their own graphics resources. That is then most easily achieved by knowing the values of the maximum number of in-flight frames (retrievable viaresourceLimit()) and the current frame (slot) index (returned by this function).See also
- driverInfo()¶
- Return type:
Returns metadata for the graphics device used by this successfully initialized
QRhiinstance.- endFrame(swapChain[, flags={}])¶
- Parameters:
swapChain –
QRhiSwapChainflags – Combination of
EndFrameFlag
- Return type:
Ends, commits, and presents a frame that was started in the last
beginFrame()onswapChain.Double (or triple) buffering is managed internally by the
QRhiSwapChainandQRhi.flagscan optionally be used to change the behavior in certain ways. PassingSkipPresentskips queuing the Present command or calling swapBuffers.Returns
FrameOpSuccesson success, or anotherFrameOpResultvalue on failure. Some of these should be treated as soft, “try again later” type of errors: WhenFrameOpSwapChainOutOfDateis returned, the swapchain is to be resized or updated by callingcreateOrResize(). The application should then attempt to generate a new frame.FrameOpDeviceLostmeans the graphics device is lost but this may also be recoverable by releasing all resources, including theQRhiitself, and then recreating all resources. SeeisDeviceLost()for further discussion.See also
- endOffscreenFrame([flags={}])¶
- Parameters:
flags – Combination of
EndFrameFlag- Return type:
Ends, submits, and waits for the offscreen frame.
flagsis not currently used.See also
- static enumerateAdapters(impl, params[, nativeHandles=None])¶
- Parameters:
impl –
Implementationparams –
QRhiInitParamsnativeHandles –
QRhiNativeHandles
- Return type:
.list of QRhiAdapter
Returns the list of adapters (physical devices) present, or an empty list when such control is not available with a given graphics API.
Backends where such level of control is not available, the returned list is always empty. Thus an empty list does not indicate there are no graphics devices in the system, but that fine-grained control over selecting which one to use is not available.
Backends for Direct 3D 11, Direct 3D 12, and Vulkan can be expected to fully support enumerating adapters. Others may not. The backend is specified by
impl. AQRhiAdapterreturned from this function must only be used in acreate()call with the sameimpl. Some underlying APIs may present further limitations, with Vulkan in particular theQRhiAdapteris specified to theQVulkanInstance(VkInstance).The caller is expected to destroy the
QRhiAdapterobjects in the list. Apart from queryinginfo(), the only purpose of these objects is to be passed on tocreate(), or the corresponding functions in higher layers such as Qt Quick.The following snippet, written specifically for Vulkan, shows how to enumerate the available physical devices and request to create a
QRhifor the chosen one. This in practice is equivalent to passing in aVkPhysicalDevicevia aQRhiVulkanNativeHandlestocreate(), but it involves less API-specific code on the application side:QRhiVulkanInitParams initParams; initParams.inst = &vulkanInstance; QRhi::AdapterList adapters = QRhi::enumerateAdapters(QRhi::Vulkan, &initParams); QRhiAdapter *chosenAdapter = nullptr; for (QRhiAdapter *adapter : adapters) { if (looksGood(adapter->info())) { chosenAdapter = adapter; break; } } QRhi *rhi = QRhi::create(QRhi::Vulkan, &initParams, {}, nullptr, chosenAdapter); qDeleteAll(adapters);
Passing in
paramsis required due to some of the underlying graphics APIs’ design. With Vulkan in particular, theQVulkanInstancemust be provided, since enumerating is not possible without it. Other fields in the backend-specificparamswill not actually be used by this function.nativeHandlesis optional. When specified, it must be a validQRhiD3D11NativeHandles,QRhiD3D12NativeHandles, orQRhiVulkanNativeHandles, similarly tocreate(). However, unlikecreate(), only the physical device (in case of Vulkan) or the adapter LUID (in case of D3D) fields are used, all other fields are ignored. This can be used the restrict the results to a given adapter. The returned list will contain 1 or 0 elements in this case.Note how in the previous code snippet the looksGood() function implementation cannot perform any platform-specific filtering based on the true adapter / physical device identity, such as the adapter LUID on Windows or the VkPhysicalDevice with Vulkan. This is because
QRhiDriverInfodoes not contain platform-specific data. Instead, usenativeHandlesto get the results filtered already inside enumerateAdapters().The following two snippets, using Direct 3D 12 as an example, are equivalent in practice:
// enumerateAdapters-based approach from Qt 6.10 on QRhiD3D12InitParams initParams; QRhiD3D12NativeHandles nativeHandles; nativeHandles.adapterLuidLow = luid.LowPart; // retrieved a LUID from somewhere, now pass it on to Qt nativeHandles.adapterLuidHigh = luid.HighPart; QRhi::AdapterList adapters = QRhi::enumerateAdapters(QRhi::D3D12, &initParams, &nativeHandles); if (adapters.isEmpty()) { qWarning("Requested adapter was not found"); } QRhi *rhi = QRhi::create(QRhi::D3D12, &initParams, {}, nullptr, adapters[0]); qDeleteAll(adapters);
// traditional approach, more lightweight QRhiD3D12InitParams initParams; QRhiD3D12NativeHandles nativeHandles; nativeHandles.adapterLuidLow = luid.LowPart; // retrieved a LUID from somewhere, now pass it on to Qt nativeHandles.adapterLuidHigh = luid.HighPart; QRhi *rhi = QRhi::create(QRhi::D3D12, &initParams, {}, &nativeHandles, nullptr);
See also
- finish()¶
- Return type:
Waits for any work on the graphics queue (where applicable) to complete, then executes all deferred operations, like completing readbacks and resource releases. Can be called inside and outside of a frame, but not inside a pass. Inside a frame it implies submitting any work on the command buffer.
Note
Avoid this function. One case where it may be needed is when the results of an enqueued readback in a swapchain-based frame are needed at a fixed given point and so waiting for the results is desired.
- isClipDepthZeroToOne()¶
- Return type:
bool
Returns
trueif the underlying graphics API uses depth range [0, 1] in clip space.In practice this is
falsefor OpenGL only, because OpenGL uses a post-projection depth range of [-1, 1]. (not to be confused with the NDC-to-window mapping controlled by glDepthRange(), which uses a range of [0, 1], unless overridden by theQRhiViewport) In some OpenGL versions glClipControl() could be used to change this, but the OpenGL backend ofQRhidoes not use that function as it is not available in OpenGL ES or OpenGL versions lower than 4.5.Note
clipSpaceCorrMatrix()includes the corresponding adjustment in its returned matrix. Therefore, many users ofQRhido not need to take any further measures apart from pre-multiplying their projection matrices withclipSpaceCorrMatrix(). However, some graphics techniques, such as, some types of shadow mapping, involve working with and outputting depth values in the shaders. These will need to query and take the value of this function into account as appropriate.- isDeviceLost()¶
- Return type:
bool
Returns true if the graphics device was lost.
The loss of the device is typically detected in
beginFrame(),endFrame()orcreateOrResize(), depending on the backend and the underlying native APIs. The most common isendFrame()because that is where presenting happens. With some backendscreateOrResize()can also fail due to a device loss. Therefore this function is provided as a generic way to check if a device loss was detected by a previous operation.When the device is lost, no further operations should be done via the
QRhi. Rather, allQRhiresources should be released, followed by destroying theQRhi. A newQRhican then be attempted to be created. If successful, all graphics resources must be reinitialized. If not, try again later, repeatedly.While simple applications may decide to not care about device loss, on the commonly used desktop platforms a device loss can happen due to a variety of reasons, including physically disconnecting the graphics adapter, disabling the device or driver, uninstalling or upgrading the graphics driver, or due to errors that lead to a graphics device reset. Some of these can happen under perfectly normal circumstances as well, for example the upgrade of the graphics driver to a newer version is a common task that can happen at any time while a Qt application is running. Users may very well expect applications to be able to survive this, even when the application is actively using an API like OpenGL or Direct3D.
Qt’s own frameworks built on top of
QRhi, such as, Qt Quick, can be expected to handle and take appropriate measures when a device loss occurs. If the data for graphics resources, such as textures and buffers, are still available on the CPU side, such an event may not be noticeable on the application level at all since graphics resources can seamlessly be reinitialized then. However, applications and libraries working directly withQRhiare expected to be prepared to check and handle device loss situations themselves.Note
With OpenGL, applications may need to opt-in to context reset notifications by setting
ResetNotificationon theQOpenGLContext. This is typically done by enabling the flag in QRhiGles2InitParams::format . Keep in mind however that some systems may generate context resets situations even when this flag is not set.Returns
trueif the specifiedfeatureis supported- isRecordingFrame()¶
- Return type:
bool
Returns true when there is an active frame, meaning there was a
beginFrame()(orbeginOffscreenFrame()) with no correspondingendFrame()(orendOffscreenFrame()) yet.See also
- isTextureFormatSupported(format[, flags={}])¶
Returns
trueif the specified textureformatmodified byflagsis supported.The query is supported both for uncompressed and compressed formats.
- isYUpInFramebuffer()¶
- Return type:
bool
Returns
trueif the underlying graphics API has the Y axis pointing up in framebuffers and images.In practice this is
truefor OpenGL only.- isYUpInNDC()¶
- Return type:
bool
Returns
trueif the underlying graphics API has the Y axis pointing up in its normalized device coordinate system.In practice this is
falsefor Vulkan only.Note
clipSpaceCorrMatrix()includes the corresponding adjustment (to make Y point up) in its returned matrix.- makeThreadLocalNativeContextCurrent()¶
- Return type:
bool
With OpenGL this makes the OpenGL context current on the current thread. The function has no effect with other backends.
Calling this function is relevant typically in Qt framework code, when one has to ensure external OpenGL code provided by the application can still run like it did before with direct usage of OpenGL, as long as the
QRhiis using the OpenGL backend.Returns false when failed, similarly to
makeCurrent(). When the operation failed,isDeviceLost()can be called to determine if there was a loss of context situation. Such a check is equivalent to checking viaisValid().See also
Returns the number of mip levels for a given
size.- nativeHandles()¶
- Return type:
Returns a pointer to the backend-specific collection of native objects for the device, context, and similar concepts used by the backend.
Cast to
QRhiVulkanNativeHandles,QRhiD3D11NativeHandles,QRhiD3D12NativeHandles,QRhiGles2NativeHandles, orQRhiMetalNativeHandlesas appropriate.Note
No ownership is transferred, neither for the returned pointer nor for any native objects.
- newBuffer(type, usage, size)¶
- Parameters:
- Return type:
Returns a new buffer with the specified
type,usage, andsize.Note
Some
usageandtypecombinations may not be supported by all backends. SeeUsageFlagsandthe feature flags.Note
Backends may choose to allocate buffers bigger than
size. This is done transparently to applications, so there are no special restrictions on the value ofsize.size()will always report back the value that was requested insize.See also
- newComputePipeline()¶
- Return type:
Returns a new compute pipeline resource.
- newGraphicsPipeline()¶
- Return type:
Returns a new graphics pipeline resource.
See also
- newRenderBuffer(type, pixelSize[, sampleCount=1[, flags={}[, backingFormatHint=QRhiTexture.UnknownFormat]]])¶
- Parameters:
- Return type:
Returns a new renderbuffer with the specified
type,pixelSize,sampleCount, andflags.When
backingFormatHintis set to a texture format other thanUnknownFormat, it may be used by the backend to decide what format to use for the storage backing the renderbuffer.Note
backingFormatHintbecomes relevant typically when multisampling and floating point texture formats are involved: rendering into a multisampleQRhiRenderBufferand then resolving into a non-RGBA8QRhiTextureimplies (with some graphics APIs) that the storage backing theQRhiRenderBufferuses the matching non-RGBA8 format. That means that passing a format likeRGBA32Fis important, because backends will typically opt forRGBA8by default, which would then break later on due to attempting to set up RGBA8->RGBA32F multisample resolve in the color attachment(s) of theQRhiTextureRenderTarget.See also
- newSampler(magFilter, minFilter, mipmapMode, addressU, addressV[, addressW=QRhiSampler.Repeat])¶
- Parameters:
magFilter –
FilterminFilter –
FiltermipmapMode –
FilteraddressU –
AddressModeaddressV –
AddressModeaddressW –
AddressMode
- Return type:
Returns a new sampler with the specified magnification filter
magFilter, minification filterminFilter, mipmapping modemipmapMode, and the addressing (wrap) modesaddressU,addressV, andaddressW.Note
Setting
mipmapModeto a value other thanNoneimplies that images for all relevant mip levels will be provided either viatexture uploadsor by callinggenerateMips()on the texture that is used with this sampler. Attempting to use the sampler with a texture that has no data for all relevant mip levels will lead to rendering errors, with the exact behavior dependent on the underlying graphics API.See also
- newShaderResourceBindings()¶
- Return type:
Returns a new shader resource binding collection resource.
See also
- newSwapChain()¶
- Return type:
Returns a new swapchain.
See also
- newTexture(format, pixelSize[, sampleCount=1[, flags={}]])¶
- Parameters:
- Return type:
Returns a new 1D or 2D texture with the specified
format,pixelSize,sampleCount, andflags.A 1D texture array must have
OneDimensionalset inflags. This function will implicitly set this flag if thepixelSizeheight is 0.Note
formatspecifies the requested internal and external format, meaning the data to be uploaded to the texture will need to be in a compatible format, while the native texture may (but is not guaranteed to, in case of OpenGL at least) use this format internally.Note
1D textures are only functional when the
OneDimensionalTexturesfeature is reported as supported at run time. Further, mipmaps on 1D textures are only functional when theOneDimensionalTextureMipmapsfeature is reported at run time.See also
- newTexture(format, width, height, depth[, sampleCount=1[, flags={}]])
- Parameters:
- Return type:
Returns a new 1D, 2D or 3D texture with the specified
format,width,height,depth,sampleCount, andflags.This overload is suitable for 3D textures because it allows specifying
depth. A 3D texture must haveThreeDimensionalset inflags, but using this overload that can be omitted because the flag is set implicitly wheneverdepthis greater than 0. For 1D, 2D and cube texturesdepthshould be set to 0.A 1D texture must have
OneDimensionalset inflags. This overload will implicitly set this flag if bothheightanddepthare 0.Note
3D textures are only functional when the
ThreeDimensionalTexturesfeature is reported as supported at run time.Note
1D textures are only functional when the
OneDimensionalTexturesfeature is reported as supported at run time. Further, mipmaps on 1D textures are only functional when theOneDimensionalTextureMipmapsfeature is reported at run time.- newTextureArray(format, arraySize, pixelSize[, sampleCount=1[, flags={}]])¶
- Parameters:
- Return type:
Returns a new 1D or 2D texture array with the specified
format,arraySize,pixelSize,sampleCount, andflags.This function implicitly sets
TextureArrayinflags.A 1D texture array must have
OneDimensionalset inflags. This function will implicitly set this flag if thepixelSizeheight is 0.Note
Do not confuse texture arrays with arrays of textures. A
QRhiTexturecreated by this function is usable with 1D or 2D array samplers in the shader, for example:layout(binding = 1) uniform sampler2DArray texArr;. Arrays of textures refers to a list of textures that are exposed to the shader viasampledTextures()and a count > 1, and declared in the shader for example like this:layout(binding = 1) uniform sampler2D textures[4];Note
This is only functional when the
TextureArraysfeature is reported as supported at run time.Note
1D textures are only functional when the
OneDimensionalTexturesfeature is reported as supported at run time. Further, mipmaps on 1D textures are only functional when theOneDimensionalTextureMipmapsfeature is reported at run time.See also
Returns a new texture render target with color and depth/stencil attachments given in
desc, and with the specifiedflags.See also
- nextResourceUpdateBatch()¶
- Return type:
Returns an available, empty batch to which copy type of operations can be recorded.
Note
the return value is not owned by the caller and must never be destroyed. Instead, the batch is returned the pool for reuse by passing it to
beginPass(),endPass(), orresourceUpdate(), or by callingrelease()on it.Note
Can be called outside
beginFrame()-endFrame()as well since a batch instance just collects data on its own, it does not perform any operations.Due to not being tied to a frame being recorded, the following sequence is valid for example:
rhi->beginFrame(swapchain); QRhiResourceUpdateBatch *u = rhi->nextResourceUpdateBatch(); u->uploadStaticBuffer(buf, data); // ... do not commit the batch rhi->endFrame(); // u stays valid (assuming buf stays valid as well) rhi->beginFrame(swapchain); swapchain->currentFrameCommandBuffer()->resourceUpdate(u); // ... draw with buf rhi->endFrame();
Warning
The maximum number of batches per
QRhiis 64. When this limit is reached, the function will return null until a batch is returned to the pool.- pipelineCacheData()¶
- Return type:
Returns a binary data blob with data collected from the
QRhiGraphicsPipelineandQRhiComputePipelinesuccessfully created during the lifetime of thisQRhi.By saving and then, in subsequent runs of the same application, reloading the cache data, pipeline and shader creation times can potentially be reduced. What exactly the cache and its serialized version includes is not specified, is always specific to the backend used, and in some cases also dependent on the particular implementation of the graphics API.
When the
PipelineCacheDataLoadSaveis reported as unsupported, the returned QByteArray is empty.When the
EnablePipelineCacheDataSaveflag was not specified when callingcreate(), the returned QByteArray may be empty, even when thePipelineCacheDataLoadSavefeature is supported.When the returned data is non-empty, it is always specific to the Qt version and
QRhibackend. In addition, in some cases there is a strong dependency to the graphics device and the exact driver version used.QRhitakes care of adding the appropriate header and safeguards that ensure that the data can always be passed safely tosetPipelineCacheData(), therefore attempting to load data from a run on another version of a driver will be handled safely and gracefully.Note
Calling
releaseCachedResources()may, depending on the backend, clear the pipeline data collected. A subsequent call to this function may then not return any data.See
EnablePipelineCacheDataSavefor further details about this feature.Note
Minimize the number of calls to this function. Retrieving the blob is not always a cheap operation, and therefore this function should only be called at a low frequency, ideally only once e.g. when closing the application.
- static probe(impl, params)¶
- Parameters:
impl –
Implementationparams –
QRhiInitParams
- Return type:
bool
Returns true if
create()can be expected to succeed when called the givenimplandparams.For some backends this is equivalent to calling
create(), checking its return value, and then destroying the resultingQRhi.For others, in particular with Metal, there may be a specific probing implementation, which allows testing in a more lightweight manner without polluting the debug output with warnings upon failures.
See also
- releaseCachedResources()¶
Attempts to release resources in the backend’s caches. This can include both CPU and GPU resources. Only memory and resources that can be recreated automatically are in scope. As an example, if the backend’s
QRhiGraphicsPipelineimplementation maintains a cache of shader compilation results, calling this function leads to emptying that cache, thus potentially freeing up memory and graphics resources.Calling this function makes sense in resource constrained environments, where at a certain point there is a need to ensure minimal resource usage, at the expense of performance.
- removeCleanupCallback(key)¶
- Parameters:
key –
void
Deregisters the callback with
key. If no cleanup callback was registered withkey, the function does nothing. Callbacks registered without a key cannot be removed.See also
addCleanupCallback()- resourceLimit(limit)¶
- Parameters:
limit –
ResourceLimit- Return type:
int
Returns the value for the specified resource
limit.The values are expected to be queried by the backends upon initialization, meaning calling this function is a light operation.
- setPipelineCacheData(data)¶
- Parameters:
data –
QByteArray
Loads
datainto the pipeline cache, when applicable.When the
PipelineCacheDataLoadSaveis reported as unsupported, the function is safe to call, but has no effect.The blob returned by
pipelineCacheData()is always specific to the Qt version, theQRhibackend, and, in some cases, also to the graphics device, and a given version of the graphics driver.QRhitakes care of adding the appropriate header and safeguards that ensure that the data can always be passed safely to this function. If there is a mismatch, e.g. because the driver has been upgraded to a newer version, or because the data was generated from a differentQRhibackend, a warning is printed anddatais safely ignored.With Vulkan, this maps directly to VkPipelineCache. Calling this function creates a new Vulkan pipeline cache object, with its initial data sourced from
data. The pipeline cache object is then used by all subsequently createdQRhiGraphicsPipelineandQRhiComputePipelineobjects, thus accelerating, potentially, the pipeline creation.With other APIs there is no real pipeline cache, but they may provide a cache with bytecode from shader compilations (D3D) or program binaries (OpenGL). In applications that perform a lot of shader compilation from source at run time this can provide a significant boost in subsequent runs if the “pipeline cache” is pre-seeded from an earlier run using this function.
Note
QRhicannot give any guarantees thatdatahas an effect on the pipeline and shader creation performance. With APIs like Vulkan, it is up to the driver to decide ifdatais used for some purpose, or if it is ignored.See
EnablePipelineCacheDataSavefor further details about this feature.Note
This mechanism offered by
QRhiis independent of the drivers’ own internal caching mechanism, if any. This means that, depending on the graphics API and its implementation, the exact effects of retrieving and then reloadingdataare not predictable. Improved performance may not be visible at all in case other caching mechanisms outside of Qt’s control are already active.Note
Minimize the number of calls to this function. Loading the blob is not always a cheap operation, and therefore this function should only be called at a low frequency, ideally only once e.g. when starting the application.
Warning
Serialized pipeline cache data is assumed to be trusted content. Qt performs robust parsing of the header and metadata included in
data, application developers are however advised to never pass in data from untrusted sources.See also
- setQueueSubmitParams(params)¶
- Parameters:
params –
QRhiNativeHandles
With backends and graphics APIs where applicable, this function allows to provide additional arguments to the next submission of commands to the graphics command queue.
In particular, with Vulkan this allows passing in a list of Vulkan semaphore objects for
vkQueueSubmit()to signal and wait on.paramsmust then be aQRhiVulkanQueueSubmitParams. This becomes essential in certain advanced use cases, such as when performing native Vulkan calls that involve having to wait on and signal VkSemaphores that the application’s custom Vulkan rendering or compute code manages. In addition, this also allows specifying additional semaphores to wait on in the nextvkQueuePresentKHR().Note
This function affects the next queue submission only, which will happen in
endFrame(),endOffscreenFrame(), orfinish(). The enqueuing of present happens inendFrame().With many other backends the implementation of this function is a no-op.
- static sizeForMipLevel(mipLevel, baseLevelSize)¶
Returns the texture image size for a given
mipLevel, calculated based on the level 0 size given inbaseLevelSize.Gathers and returns statistics about the timings and allocations of graphics resources.
Data about memory allocations is only available with some backends, where such operations are under Qt’s control. With graphics APIs where there is no lower level control over resource memory allocations, this will never be supported and all relevant fields in the results are 0.
With Vulkan in particular, the values are valid always, and are queried from the underlying memory allocator library. This gives an insight into the memory requirements of the active buffers and textures.
The same is true for Direct 3D 12. In addition to the memory allocator library’s statistics, here the result also includes a
totalUsageBytesfield which reports the total size including additional resources that are not under the memory allocator library’s control (swapchain buffers, descriptor heaps, etc.), as reported by DXGI.The values correspond to all types of memory used, combined. (i.e. video + system in case of a discreet GPU)
Additional data, such as the total time in milliseconds spent in graphics and compute pipeline creation (which usually involves shader compilation or cache lookups, and potentially expensive processing) is available with most backends.
Note
The elapsed times for operations such as pipeline creation may be affected by various factors. The results should not be compared between different backends since the concept of “pipelines” and what exactly happens under the hood during, for instance, a call to
create(), differ greatly between graphics APIs and their implementations.Note
Additionally, many drivers will likely employ various caching strategies for shaders, programs, pipelines. (independently of Qt’s own similar facilities, such as
setPipelineCacheData()or the OpenGL-specific program binary disk cache). Because such internal behavior is transparent to the API client, Qt andQRhihave no knowledge or control over the exact caching strategy, persistency, invalidation of the cached data, etc. When reading timings, such as the time spent on pipeline creation, the potential presence and unspecified behavior of driver-level caching mechanisms should be kept in mind.- supportedSampleCounts()¶
- Return type:
.list of int
Returns the list of supported sample counts.
A typical example would be (1, 2, 4, 8).
With some backend this list of supported values is fixed in advance, while with some others the (physical) device properties indicate what is supported at run time.
Returns The list of supported variable shading rates for the specified
sampleCount.1x1 is always supported.
Returns the thread on which the
QRhiwasinitialized.- ubufAligned(v)¶
- Parameters:
v – int
- Return type:
int
Returns the value (typically an offset)
valigned to the uniform buffer alignment given by byubufAlignment().- ubufAlignment()¶
- Return type:
int
Returns the minimum uniform buffer offset alignment in bytes. This is typically 256.
Attempting to bind a uniform buffer region with an offset not aligned to this value will lead to failures depending on the backend and the underlying graphics API.
See also