QtBase  v6.3.1
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
QRhi Class Reference

#include <qrhi_p.h>

Public Types

enum  Implementation {
  Null , Vulkan , OpenGLES2 , D3D11 ,
  Metal
}
 
enum  Flag { EnableProfiling = 1 << 0 , EnableDebugMarkers = 1 << 1 , PreferSoftwareRenderer = 1 << 2 , EnablePipelineCacheDataSave = 1 << 3 }
 
enum  FrameOpResult { FrameOpSuccess = 0 , FrameOpError , FrameOpSwapChainOutOfDate , FrameOpDeviceLost }
 
enum  Feature {
  MultisampleTexture = 1 , MultisampleRenderBuffer , DebugMarkers , Timestamps ,
  Instancing , CustomInstanceStepRate , PrimitiveRestart , NonDynamicUniformBuffers ,
  NonFourAlignedEffectiveIndexBufferOffset , NPOTTextureRepeat , RedOrAlpha8IsRed , ElementIndexUint ,
  Compute , WideLines , VertexShaderPointSize , BaseVertex ,
  BaseInstance , TriangleFanTopology , ReadBackNonUniformBuffer , ReadBackNonBaseMipLevel ,
  TexelFetch , RenderToNonBaseMipLevel , IntAttributes , ScreenSpaceDerivatives ,
  ReadBackAnyTextureFormat , PipelineCacheDataLoadSave , ImageDataStride , RenderBufferImport ,
  ThreeDimensionalTextures , RenderTo3DTextureSlice , TextureArrays
}
 
enum  BeginFrameFlag
 
enum  EndFrameFlag { SkipPresent = 1 << 0 }
 
enum  ResourceLimit {
  TextureSizeMin = 1 , TextureSizeMax , MaxColorAttachments , FramesInFlight ,
  MaxAsyncReadbackFrames , MaxThreadGroupsPerDimension , MaxThreadsPerThreadGroup , MaxThreadGroupX ,
  MaxThreadGroupY , MaxThreadGroupZ , TextureArraySizeMax , MaxUniformBufferRange
}
 
using CleanupCallback = std::function< void(QRhi *)>
 

Public Member Functions

 ~QRhi ()
 
Implementation backend () const
 
const char * backendName () const
 
QRhiDriverInfo driverInfo () const
 
QThreadthread () const
 
void addCleanupCallback (const CleanupCallback &callback)
 
void runCleanup ()
 
QRhiGraphicsPipelinenewGraphicsPipeline ()
 
QRhiComputePipelinenewComputePipeline ()
 
QRhiShaderResourceBindingsnewShaderResourceBindings ()
 
QRhiBuffernewBuffer (QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)
 
QRhiRenderBuffernewRenderBuffer (QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount=1, QRhiRenderBuffer::Flags flags={}, QRhiTexture::Format backingFormatHint=QRhiTexture::UnknownFormat)
 
QRhiTexturenewTexture (QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
 
QRhiTexturenewTexture (QRhiTexture::Format format, int width, int height, int depth, int sampleCount=1, QRhiTexture::Flags flags={})
 
QRhiTexturenewTextureArray (QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
 
QRhiSamplernewSampler (QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
 
QRhiTextureRenderTargetnewTextureRenderTarget (const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
 
QRhiSwapChainnewSwapChain ()
 
FrameOpResult beginFrame (QRhiSwapChain *swapChain, BeginFrameFlags flags={})
 
FrameOpResult endFrame (QRhiSwapChain *swapChain, EndFrameFlags flags={})
 
bool isRecordingFrame () const
 
int currentFrameSlot () const
 
FrameOpResult beginOffscreenFrame (QRhiCommandBuffer **cb, BeginFrameFlags flags={})
 
FrameOpResult endOffscreenFrame (EndFrameFlags flags={})
 
QRhi::FrameOpResult finish ()
 
QRhiResourceUpdateBatchnextResourceUpdateBatch ()
 
QList< int > supportedSampleCounts () const
 
int ubufAlignment () const
 
int ubufAligned (int v) const
 
int mipLevelsForSize (const QSize &size) const
 
QSize sizeForMipLevel (int mipLevel, const QSize &baseLevelSize) const
 
bool isYUpInFramebuffer () const
 
bool isYUpInNDC () const
 
bool isClipDepthZeroToOne () const
 
QMatrix4x4 clipSpaceCorrMatrix () const
 
bool isTextureFormatSupported (QRhiTexture::Format format, QRhiTexture::Flags flags={}) const
 
bool isFeatureSupported (QRhi::Feature feature) const
 
int resourceLimit (ResourceLimit limit) const
 
const QRhiNativeHandlesnativeHandles ()
 
bool makeThreadLocalNativeContextCurrent ()
 
QRhiProfilerprofiler ()
 
void releaseCachedResources ()
 
bool isDeviceLost () const
 
QByteArray pipelineCacheData ()
 
void setPipelineCacheData (const QByteArray &data)
 

Static Public Member Functions

static QRhicreate (Implementation impl, QRhiInitParams *params, Flags flags={}, QRhiNativeHandles *importDevice=nullptr)
 

Static Public Attributes

static const int MAX_MIP_LEVELS = 16
 

Protected Member Functions

 QRhi ()
 

Detailed Description

Definition at line 1535 of file qrhi_p.h.

Member Typedef Documentation

◆ CleanupCallback

Definition at line 1631 of file qrhi_p.h.

Member Enumeration Documentation

◆ BeginFrameFlag

Flag values for QRhi::beginFrame()

Definition at line 1595 of file qrhi_p.h.

◆ EndFrameFlag

Flag values for QRhi::endFrame()

\value 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)

Enumerator
SkipPresent 

Definition at line 1599 of file qrhi_p.h.

◆ Feature

Flag values to indicate what features are supported by the backend currently in use.

\value 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.

\value 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.

\value DebugMarkers Indicates that debug marker groups (and so QRhiCommandBuffer::debugMarkBegin()) are supported.

\value Timestamps Indicates that command buffer timestamps are supported. Relevant for QRhiProfiler::gpuFrameTimes().

\value 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.

\value 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.

\value PrimitiveRestart Indicates that restarting the assembly of primitives when encountering an index value of 0xFFFF (\l{QRhiCommandBuffer::IndexUInt16}{IndexUInt16}) or 0xFFFFFFFF (\l{QRhiCommandBuffer::IndexUInt32}{IndexUInt32}) is enabled, for certain primitive topologies at least. QRhi will 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 values may be 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, are \l{QRhiGraphicsPipeline::LineStrip}{LineStrip} and \l{QRhiGraphicsPipeline::TriangleStrip}{TriangleStrip}.

\value NonDynamicUniformBuffers Indicates that creating buffers with the usage \l{QRhiBuffer::UniformBuffer}{UniformBuffer} and the types \l{QRhiBuffer::Immutable}{Immutable} or \l{QRhiBuffer::Static}{Static} is supported. When reported as unsupported, uniform (constant) buffers must be created as \l{QRhiBuffer::Dynamic}{Dynamic}. (which is recommended regardless)

\value NonFourAlignedEffectiveIndexBufferOffset Indicates that effective index buffer offsets ({indexOffset + firstIndex * indexComponentSize}) that are not 4 byte aligned are supported. When not supported, attempting to issue a \l{QRhiCommandBuffer::drawIndexed()}{drawIndexed()} with a non-aligned effective offset may lead to unspecified behavior. Relevant in particular for Metal, where this will be reported as unsupported.

\value NPOTTextureRepeat Indicates that the \l{QRhiSampler::Repeat}{Repeat} wrap 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 without {GL_OES_texture_npot}.

\value RedOrAlpha8IsRed Indicates that the \l{QRhiTexture::RED_OR_ALPHA8}{RED_OR_ALPHA8} format maps to a one component 8-bit red format. This is the case for all backends except OpenGL when using either OpenGL ES or a non-core profile context. There {GL_ALPHA}, a one component 8-bit alpha format, 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.

\value 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.

\value 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.

\value 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, Metal). With Vulkan, the value depends on the implementation. With OpenGL, wide lines are not supported in core profile contexts.

\value VertexShaderPointSize Indicates that the size of rasterized points set via {gl_PointSize} in the vertex shader is taken into account. When reported as not supported, drawing points with a size other than 1 is not supported. Setting {gl_PointSize} in 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.

\value BaseVertex Indicates that \l{QRhiCommandBuffer::drawIndexed()}{drawIndexed()} supports the vertexOffset argument. 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.

\value BaseInstance Indicates that instanced draw commands support the firstInstance argument. 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 OpenGL, and with Metal on older iOS devices, including the iOS Simulator.

\value TriangleFanTopology Indicates that QRhiGraphicsPipeline::setTopology() supports QRhiGraphicsPipeline::TriangleFan. In practice this feature will be unsupported with Metal and Direct 3D 11.

\value ReadBackNonUniformBuffer Indicates that \l{QRhiResourceUpdateBatch::readBackBuffer()}{reading buffer contents} is supported for QRhiBuffer instances with a usage different than UniformBuffer. In practice this feature will be unsupported with OpenGL ES 2.0.

\value 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 QRhiReadbackDescription leads to returning an all-zero image. In practice this feature will be unsupported with OpenGL ES 2.0.

\value 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.

\value RenderToNonBaseMipLevel Indicates that specifying a mip level other than 0 is supported when creating a QRhiTextureRenderTarget with a QRhiTexture as 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.

\value 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.

\value 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.

\value ReadBackAnyTextureFormat Indicates that reading back texture contents can be expected to work for any QRhiTexture::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 formats QRhiTexture::RGBA8 and QRhiTexture::BGRA8 are guaranteed to be supported for readbacks. In addition, with OpenGL, but not OpenGL ES, reading back the 1 byte per component formats QRhiTexture::R8 and QRhiTexture::RED_OR_ALPHA8 are supported as well. Reading back floating point formats QRhiTexture::RGBA16F and RGBA32F may work too with OpenGL, as long as the implementation provides support for these, but QRhi can give no guarantees, as indicated by this flag.

\value PipelineCacheDataLoadSave Indicates that the pipelineCacheData() and setPipelineCacheData() 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.

\value 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), QRhiTextureSubresourceUploadDescription::setDataStride() must not be used.

\value RenderBufferImport Indicates that QRhiRenderBuffer::createFrom() is supported. For most graphics APIs this is not sensible because QRhiRenderBuffer encapsulates texture objects internally, just like QRhiTexture. 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 a QRhiRenderBuffer.

\value ThreeDimensionalTextures Indicates that 3D textures are supported. In practice this feature will be unsupported with OpenGL and OpenGL ES versions lower than 3.0.

\value 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.

\value TextureArrays Indicates that texture arrays are supported and QRhi::newTextureArray() is functional. Note that even when texture arrays are not supported, arrays of textures are still available as those are two independent features.

Enumerator
MultisampleTexture 
MultisampleRenderBuffer 
DebugMarkers 
Timestamps 
Instancing 
CustomInstanceStepRate 
PrimitiveRestart 
NonDynamicUniformBuffers 
NonFourAlignedEffectiveIndexBufferOffset 
NPOTTextureRepeat 
RedOrAlpha8IsRed 
ElementIndexUint 
Compute 
WideLines 
VertexShaderPointSize 
BaseVertex 
BaseInstance 
TriangleFanTopology 
ReadBackNonUniformBuffer 
ReadBackNonBaseMipLevel 
TexelFetch 
RenderToNonBaseMipLevel 
IntAttributes 
ScreenSpaceDerivatives 
ReadBackAnyTextureFormat 
PipelineCacheDataLoadSave 
ImageDataStride 
RenderBufferImport 
ThreeDimensionalTextures 
RenderTo3DTextureSlice 
TextureArrays 

Definition at line 1561 of file qrhi_p.h.

◆ Flag

enum QRhi::Flag

Describes what special features to enable.

\value EnableProfiling Enables gathering timing (CPU, GPU) and resource (QRhiBuffer, QRhiTexture, etc.) information and additional metadata. See QRhiProfiler. Avoid enabling in production builds as it may involve a performance penalty. Also enables debug messages from the {qt.rhi.*} logging categories.

\value 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 QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid enabling in production builds as it may involve a performance penalty.

\value 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 with {VK_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.

\value EnablePipelineCacheDataSave Enables retrieving the pipeline cache contents, where applicable. When not set, pipelineCacheData() will return an empty blob always. Opting in is relevant in particular with backends where additional, potentially time consuming work is needed to maintain the data structures with the serialized, binary versions of shader programs. An example is OpenGL, where the "pipeline cache" is simulated by retrieving and loading shader program binaries. With backends where retrieving and restoring the pipeline cache contents is not supported, the flag has no effect. With some backends (such as, OpenGL) there are additional, disk-based caching mechanisms for shader binaries. Writing to those may get disabled whenever this flag is set since storing program binaries (OpenGL) to multiple caches is not sensible.

Enumerator
EnableProfiling 
EnableDebugMarkers 
PreferSoftwareRenderer 
EnablePipelineCacheDataSave 

Definition at line 1546 of file qrhi_p.h.

◆ FrameOpResult

Describes the result of operations that can have a soft failure.

\value FrameOpSuccess Success

\value FrameOpError Unspecified error

\value FrameOpSwapChainOutOfDate The swapchain is in an inconsistent state internally. This can be recoverable by attempting to repeat the operation (such as, beginFrame()) later.

\value 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. See isDeviceLost().

Enumerator
FrameOpSuccess 
FrameOpError 
FrameOpSwapChainOutOfDate 
FrameOpDeviceLost 

Definition at line 1554 of file qrhi_p.h.

◆ Implementation

\class QRhi
\internal
\inmodule QtGui

\brief Accelerated 2D/3D graphics API abstraction.

The Qt Rendering Hardware Interface is an abstraction for hardware accelerated
graphics APIs, such as, \l{https://www.khronos.org/opengl/}{OpenGL},
\l{https://www.khronos.org/opengles/}{OpenGL ES},
\l{https://docs.microsoft.com/en-us/windows/desktop/direct3d}{Direct3D},
\l{https://developer.apple.com/metal/}{Metal}, and
\l{https://www.khronos.org/vulkan/}{Vulkan}.

Some of the main design goals are:

\list

\li Simple, minimal, understandable, extensible. Follow the proven path of the
Qt Quick scenegraph.

\li Aim to be a product - and in the bigger picture, part of a product (Qt) -
that is usable out of the box both by internal (such as, Qt Quick) and,
eventually, external users.

\li Not a complete 1:1 wrapper for any of the underlying APIs. The feature set
is tuned towards the needs of Qt's 2D and 3D offering (QPainter, Qt Quick, Qt
3D Studio). Iterate and evolve in a sustainable manner.

\li Intrinsically cross-platform, without reinventing: abstracting
cross-platform aspects of certain APIs (such as, OpenGL context creation and
windowing system interfaces, Vulkan instance and surface management) is not in
scope here. These are delegated to the existing QtGui facilities (QWindow,
QOpenGLContext, QVulkanInstance) and its backing QPA architecture.

\endlist

Each QRhi instance 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 the QRhi instance. 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/tvOS, Direct3D on Windows).

The available backends currently are:

\list

\li OpenGL 2.1 or OpenGL ES 2.0 or newer. Some extensions are utilized when
present, for example to enable multisample framebuffers.

\li Direct3D 11.1

\li Metal

\li Vulkan 1.0, optionally with some extensions that are part of Vulkan 1.1

\li Null - A "dummy" backend that issues no graphics calls at all.

\endlist

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 QShader instances. The compilers and tools to generate such
shaders are not part of QRhi, but the core classes for using such shaders,
QShader and QShaderDescription, are.

\section2 Design Fundamentals

A QRhi cannot be instantiated directly. Instead, use the create()
function. Delete the QRhi instance normally to release the graphics device.

\section3 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 the \c new
functions of the QRhi, such as, newBuffer(), newTexture(),
newTextureRenderTarget(), newSwapChain().

\badcode
    vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData));
    if (!vbuf->create()) { error }
    ...
    delete vbuf;
\endcode

\list

\li The returned value from functions like newBuffer() is always owned by
the caller.

\li Just creating a QRhiResource subclass never allocates or initializes any
native resources. That is only done when calling the \c create() function of a
subclass, for example, QRhiBuffer::create() or QRhiTexture::create().

\li The exceptions are
QRhiTextureRenderTarget::newCompatibleRenderPassDescriptor(),
QRhiSwapChain::newCompatibleRenderPassDescriptor(), and
QRhiRenderPassDescriptor::newCompatibleRenderPassDescriptor(). There is no
\c create() operation for these and the returned object is immediately
active.

\li The resource objects themselves are treated as immutable: once a
resource has create() called, changing any parameters via the setters, such as,
QRhiTexture::setPixelSize(), has no effect, unless the underlying native
resource is released and \c create() is called again. See more about resource
reuse in the sections below.

\li The underlying native resources are scheduled for releasing by the
QRhiResource destructor, or by calling QRhiResource::destroy(). 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.

\li Note that this does not mean that a QRhiResource can freely be
destroy()'ed or deleted within a frame (that is, in a
\l{QRhiCommandBuffer::beginFrame()}{beginFrame()} -
\l{QRhiCommandBuffer::endFrame()}{endFrame()} section). As a general rule,
all referenced QRhiResource objects must stay unchanged until the frame is
submitted by calling \l{QRhiCommandBuffer::endFrame()}{endFrame()}. To ease
this, QRhiResource::deleteLater() is provided as a convenience.

\endlist

\section3 Command buffers and deferred command execution

Regardless of the design and capabilities of the underlying graphics API,
all QRhi backends implement some level of command buffers. No
QRhiCommandBuffer function issues any native bind or draw command (such as,
\c glDrawElements) directly. Commands are always recorded in a queue,
either native or provided by the QRhi backend. The command buffer is
submitted, and so execution starts only upon QRhi::endFrame() or
QRhi::finish().

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 QRhiResource subclasses 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 a QRhiResource instance within a frame (by calling \c create()
then referencing it again in the same \c{beginFrame - endFrame} section)
should be avoided as it may lead to unexpected results, depending on the
backend.

As a general rule, all referenced QRhiResource objects must stay valid and
unmodified until the frame is submitted by calling
\l{QRhiCommandBuffer::endFrame()}{endFrame()}. On the other hand, calling
\l{QRhiResource::destroy()}{destroy()} or deleting the QRhiResource are
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: \c{(re)create resources} - \c{begin frame} - \c{record
uploads and copies} - \c{start renderpass} - \c{record draw calls} - \c{end
renderpass} - \c{end frame}. Recording copy type of operations happens via
QRhiResourceUpdateBatch. Such operations are committed typically on
\l{QRhiCommandBuffer::beginPass()}{beginPass()}.

When working with legacy rendering engines designed for OpenGL, the
migration to QRhi often involves redesigning from having a single \c render
step (that performs copies and uploads, clears buffers, and issues draw
calls, all mixed together) to a clearly separated, two phase \c prepare -
\c render setup where the \c render step only starts a renderpass and
records draw calls, while all resource creation and queuing of updates,
uploads and copies happens beforehand, in the \c prepare step.

QRhi does 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 defined
\c{frame-start} and \c{frame-end} points, combined with a dedicated,
"frame" command buffer, where \c{frame-end} implies presenting, is going to
remain the primary way of operating since this is what fits Qt's various UI
technologies best.

\section3 Threading

A QRhi instance 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
and QRhi instance 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, one QOpenGLContext for each thread. When moving onto QRhi,
QOpenGLContext is replaced by QRhi, 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 QRhi instances. This is an intentional
choice since QRhi hides 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 QRhi when rendering on the main
(gui) thread, but becomes important when a separate, dedicated render
thread is used.

\section3 Resource synchronization

QRhi does 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.

\section3 Resource reuse

From the user's point of view a QRhiResource is reusable immediately after
calling QRhiResource::destroy(). With the exception of swapchains, calling
\c create() on an already created object does an implicit \c destroy(). This
provides a handy shortcut to reuse a QRhiResource instance 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 QRhiShaderResourceBindings
can reference QRhiBuffer, QRhiTexture, and QRhiSampler instances. If in a
later frame one of these buffers need to be resized or a sampler parameter
needs changing, destroying and creating a whole new QRhiBuffer or
QRhiSampler would invalidate all references to the old instance. By just
changing the appropriate parameters via QRhiBuffer::setSize() or similar
and then calling QRhiBuffer::create(), everything works as expected and
there is no need to touch the QRhiShaderResourceBindings at all, even
though there is a good chance that under the hood the QRhiBuffer is now
backed by a whole new native buffer.

\badcode
    ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256);
    ubuf->create();

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

That's it, 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().

QRhiTextureRenderTarget offers the same contract: calling QRhiCommandBuffer::beginPass() is safe even when one of the render target's associated textures or renderbuffers has been rebuilt (by calling create() 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 the QRhiTexture and calling create(), thus creating a whole new native texture resource underneath, without having to update the QRhiTextureRenderTarget as that will be done implicitly in beginPass().

Enumerator
Null 
Vulkan 
OpenGLES2 
D3D11 
Metal 

Definition at line 1538 of file qrhi_p.h.

◆ ResourceLimit

Describes the resource limit to query.

\value 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.

\value 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.

\value 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.

\value FramesInFlight The number of frames the backend may keep "in flight": with backends like Vulkan or Metal, it is the responsibility of QRhi to block whenever starting a new frame and finding the CPU is already {N - 1} frames ahead of the GPU (because the command buffer submitted in frame no. {current} - {N} has 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 the QRhi backends themselves. The current frame slot index (a value running 0, 1, .., N-1, then wrapping around) is retrievable from QRhi::currentFrameSlot(). 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 by QRhi and so not reflected here in the API.

\value MaxAsyncReadbackFrames The number of \l{QRhi::endFrame()}{submitted} frames (including the one that contains the readback) after which an asynchronous texture or buffer readback is guaranteed to complete upon \l{QRhi::beginFrame()}{starting a new frame}.

\value MaxThreadGroupsPerDimension The maximum number of compute work/thread groups that can be dispatched. Effectively the maximum value for the arguments of QRhiCommandBuffer::dispatch(). Typically 65535.

\value 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, and local_size_z in 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.

\value MaxThreadGroupX The maximum size of a work/thread group in the X dimension. Effectively the maximum value of local_size_x in the compute shader. Typically 256 or 1024.

\value MaxThreadGroupY The maximum size of a work/thread group in the Y dimension. Effectively the maximum value of local_size_y in the compute shader. Typically 256 or 1024.

\value MaxThreadGroupZ The maximum size of a work/thread group in the Z dimension. Effectively the maximum value of local_size_z in the compute shader. Typically 64 or 256.

\value TextureArraySizeMax Maximum texture array size. Typically in range 256 - 2048. Attempting to \l{QRhi::newTextureArray()}{create a texture array} with more elements will likely fail.

\value 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).

Enumerator
TextureSizeMin 
TextureSizeMax 
MaxColorAttachments 
FramesInFlight 
MaxAsyncReadbackFrames 
MaxThreadGroupsPerDimension 
MaxThreadsPerThreadGroup 
MaxThreadGroupX 
MaxThreadGroupY 
MaxThreadGroupZ 
TextureArraySizeMax 
MaxUniformBufferRange 

Definition at line 1604 of file qrhi_p.h.

Constructor & Destructor Documentation

◆ ~QRhi()

QRhi::~QRhi ( )

Destructor. Destroys the backend and releases resources.

Definition at line 4952 of file qrhi.cpp.

Here is the call graph for this function:

◆ QRhi()

QRhi::QRhi ( )
protected

Definition at line 4945 of file qrhi.cpp.

Member Function Documentation

◆ addCleanupCallback()

void QRhi::addCleanupCallback ( const CleanupCallback callback)

Registers a callback that is invoked either when the QRhi is destroyed, or when runCleanup() is called.

The callback will run with the graphics resource still available, so this provides an opportunity for the application to cleanly release QRhiResource instances belonging to the QRhi. This is particularly useful for managing the lifetime of resources stored in cache type of objects, where the cache holds QRhiResources or objects containing QRhiResources.

See also
runCleanup(), ~QRhi()

Definition at line 5176 of file qrhi.cpp.

Here is the call graph for this function:

◆ backend()

QRhi::Implementation QRhi::backend ( ) const
Returns
the backend type for this QRhi.

Definition at line 5057 of file qrhi.cpp.

◆ backendName()

const char * QRhi::backendName ( ) const
Returns
the backend type as string for this QRhi.

Definition at line 5065 of file qrhi.cpp.

◆ beginFrame()

QRhi::FrameOpResult QRhi::beginFrame ( QRhiSwapChain swapChain,
BeginFrameFlags  flags = {} 
)

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.

flags can indicate certain special cases.

The high level pattern of rendering into a QWindow using a swapchain:

\list

  • Create a swapchain.
  • Then on every frame: \badcode beginFrame(sc); updates = nextResourceUpdateBatch(); updates->... QRhiCommandBuffer *cb = sc->currentFrameCommandBuffer(); cb->beginPass(sc->currentFrameRenderTarget(), colorClear, dsClear, updates); ... cb->endPass(); ... // more passes as necessary endFrame(sc);

\endlist

Returns
QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult value on failure. Some of these should be treated as soft, "try again later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned, the swapchain is to be resized or updated by calling QRhiSwapChain::createOrResize(). The application should then attempt to generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is lost but this may also be recoverable by releasing all resources, including the QRhi itself, and then recreating all resources. See isDeviceLost() for further discussion.
See also
endFrame(), beginOffscreenFrame(), isDeviceLost()

Definition at line 6759 of file qrhi.cpp.

Here is the call graph for this function:

◆ beginOffscreenFrame()

QRhi::FrameOpResult QRhi::beginOffscreenFrame ( QRhiCommandBuffer **  cb,
BeginFrameFlags  flags = {} 
)
Starts a new offscreen frame. Provides a command buffer suitable for
recording rendering commands in \a cb. \a flags is used to indicate
certain special cases, just like with beginFrame().

\note The QRhiCommandBuffer stored 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.

The skeleton of rendering a frame without a swapchain and then reading the
frame contents back could look like the following:

\badcode
      QRhiReadbackResult rbResult;
      QRhiCommandBuffer *cb;
      beginOffscreenFrame(&cb);
      beginPass
      ...
      u = nextResourceUpdateBatch();
      u->readBackTexture(rb, &rbResult);
      endPass(u);
      endOffscreenFrame();

image data available in rbResult

See also
endOffscreenFrame(), beginFrame()

Definition at line 6904 of file qrhi.cpp.

Here is the call graph for this function:

◆ clipSpaceCorrMatrix()

QMatrix4x4 QRhi::clipSpaceCorrMatrix ( ) const
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 QMatrix4x4::perspective()), regardless of the active QRhi backend.

In a typical renderer, once {this_matrix * mvp} is used instead of just mvp, 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 on isYUpInNDC() and isClipDepthZeroToOne() can be avoided (although such logic may still become required when implementing certain advanced graphics techniques).

See \l{https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/}{this page} for a discussion of the topic from Vulkan perspective.

Definition at line 6299 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create()

QRhi * QRhi::create ( Implementation  impl,
QRhiInitParams params,
Flags  flags = {},
QRhiNativeHandles importDevice = nullptr 
)
static
Returns
a new QRhi instance with a backend for the graphics API specified by impl.

params must point to an instance of one of the backend-specific subclasses of QRhiInitParams, such as, QRhiVulkanInitParams, QRhiMetalInitParams, QRhiD3D11InitParams, QRhiGles2InitParams. See these classes for examples on creating a QRhi.

flags is optional. It is used to enable profile and debug related features that are potentially expensive and should only be used during development.

Definition at line 4978 of file qrhi.cpp.

Here is the caller graph for this function:

◆ currentFrameSlot()

int QRhi::currentFrameSlot ( ) const
Returns
the current frame slot index while recording a frame. Unspecified when called outside an active frame (that is, when isRecordingFrame() is false).

With backends like Vulkan or Metal, it is the responsibility of the QRhi backend to block whenever starting a new frame and finding the CPU is already {FramesInFlight - 1} frames ahead of the GPU (because the command buffer submitted in frame no. {current} - {FramesInFlight} has not yet completed).

Resources that tend to change between frames (such as, the native buffer object backing a QRhiBuffer with type QRhiBuffer::Dynamic) 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 QRhi backends by having a fixed number of native resource (such as, VkBuffer) slots behind a QRhiResource. 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 via resourceLimit()) and the current frame (slot) index (returned by this function).

See also
isRecordingFrame(), beginFrame(), endFrame()

Definition at line 6860 of file qrhi.cpp.

◆ driverInfo()

QRhiDriverInfo QRhi::driverInfo ( ) const
Returns
metadata for the graphics device used by this successfully initialized QRhi instance.

Definition at line 5151 of file qrhi.cpp.

Here is the call graph for this function:

◆ endFrame()

QRhi::FrameOpResult QRhi::endFrame ( QRhiSwapChain swapChain,
EndFrameFlags  flags = {} 
)

Ends, commits, and presents a frame that was started in the last beginFrame() on swapChain.

Double (or triple) buffering is managed internally by the QRhiSwapChain and QRhi.

flags can optionally be used to change the behavior in certain ways. Passing QRhi::SkipPresent skips queuing the Present command or calling swapBuffers.

Returns
QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult value on failure. Some of these should be treated as soft, "try again later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned, the swapchain is to be resized or updated by calling QRhiSwapChain::createOrResize(). The application should then attempt to generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is lost but this may also be recoverable by releasing all resources, including the QRhi itself, and then recreating all resources. See isDeviceLost() for further discussion.
See also
beginFrame(), isDeviceLost()

Definition at line 6794 of file qrhi.cpp.

Here is the call graph for this function:

◆ endOffscreenFrame()

QRhi::FrameOpResult QRhi::endOffscreenFrame ( EndFrameFlags  flags = {})

Ends and waits for the offscreen frame.

See also
beginOffscreenFrame()

Definition at line 6921 of file qrhi.cpp.

Here is the call graph for this function:

◆ finish()

QRhi::FrameOpResult QRhi::finish ( )

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.

Definition at line 6945 of file qrhi.cpp.

Here is the call graph for this function:

◆ isClipDepthZeroToOne()

bool QRhi::isClipDepthZeroToOne ( ) const
Returns
true if the underlying graphics API uses depth range [0, 1] in clip space.

In practice this is false for 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 the QRhiViewport) In some OpenGL versions glClipControl() could be used to change this, but the OpenGL backend of QRhi does 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 of QRhi do not need to take any further measures apart from pre-multiplying their projection matrices with clipSpaceCorrMatrix(). 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.

Definition at line 6277 of file qrhi.cpp.

Here is the call graph for this function:

◆ isDeviceLost()

bool QRhi::isDeviceLost ( ) const
Returns
true if the graphics device was lost.

The loss of the device is typically detected in beginFrame(), endFrame() or QRhiSwapChain::createOrResize(), depending on the backend and the underlying native APIs. The most common is endFrame() because that is where presenting happens. With some backends QRhiSwapChain::createOrResize() 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, all QRhi resources should be released, followed by destroying the QRhi. A new QRhi can 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 with QRhi are 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 QSurfaceFormat::ResetNotification on the QOpenGLContext. 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.

Definition at line 6446 of file qrhi.cpp.

Here is the call graph for this function:

◆ isFeatureSupported()

bool QRhi::isFeatureSupported ( QRhi::Feature  feature) const
Returns
true if the specified feature is supported

Definition at line 6318 of file qrhi.cpp.

Here is the call graph for this function:

◆ isRecordingFrame()

bool QRhi::isRecordingFrame ( ) const
Returns
true when there is an active frame, meaning there was a beginFrame() (or beginOffscreenFrame()) with no corresponding endFrame() (or endOffscreenFrame()) yet.
See also
currentFrameSlot(), beginFrame(), endFrame()

Definition at line 6816 of file qrhi.cpp.

◆ isTextureFormatSupported()

bool QRhi::isTextureFormatSupported ( QRhiTexture::Format  format,
QRhiTexture::Flags  flags = {} 
) const
Returns
true if the specified texture format modified by flags is supported.

The query is supported both for uncompressed and compressed formats.

Definition at line 6310 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isYUpInFramebuffer()

bool QRhi::isYUpInFramebuffer ( ) const
Returns
true if the underlying graphics API has the Y axis pointing up in framebuffers and images.

In practice this is true for OpenGL only.

Definition at line 6238 of file qrhi.cpp.

Here is the call graph for this function:

◆ isYUpInNDC()

bool QRhi::isYUpInNDC ( ) const
Returns
true if the underlying graphics API has the Y axis pointing up in its normalized device coordinate system.

In practice this is false for Vulkan only.

Note
clipSpaceCorrMatrix() includes the corresponding adjustment (to make Y point up) in its returned matrix.

Definition at line 6252 of file qrhi.cpp.

Here is the call graph for this function:

◆ makeThreadLocalNativeContextCurrent()

bool QRhi::makeThreadLocalNativeContextCurrent ( )

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 QRhi is using the OpenGL backend.

Returns
false when failed, similarly to QOpenGLContext::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 via QOpenGLContext::isValid().
See also
QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()

Definition at line 6365 of file qrhi.cpp.

Here is the call graph for this function:

◆ mipLevelsForSize()

int QRhi::mipLevelsForSize ( const QSize size) const
Returns
the number of mip levels for a given size.

Definition at line 6216 of file qrhi.cpp.

Here is the call graph for this function:

◆ nativeHandles()

const QRhiNativeHandles * QRhi::nativeHandles ( )
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, QRhiGles2NativeHandles, QRhiMetalNativeHandles as appropriate.

Note
No ownership is transferred, neither for the returned pointer nor for any native objects.

Definition at line 6344 of file qrhi.cpp.

Here is the call graph for this function:

◆ newBuffer()

QRhiBuffer * QRhi::newBuffer ( QRhiBuffer::Type  type,
QRhiBuffer::UsageFlags  usage,
int  size 
)
Returns
a new buffer with the specified type, usage, and size.
Note
Some usage and type combinations may not be supported by all backends. See \l{QRhiBuffer::UsageFlag}{UsageFlags} and \l{QRhi::NonDynamicUniformBuffers}{the feature flags}.
Backends may choose to allocate buffers bigger than size. This is done transparently to applications, so there are no special restrictions on the value of size. QRhiBuffer::size() will always report back the value that was requested in size.
See also
QRhiResource::destroy()

Definition at line 6562 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ newComputePipeline()

QRhiComputePipeline * QRhi::newComputePipeline ( )
Returns
a new compute pipeline resource.
Note
Compute is only available when the \l{QRhi::Compute}{Compute} feature is reported as supported.
See also
QRhiResource::destroy()

Definition at line 6533 of file qrhi.cpp.

Here is the call graph for this function:

◆ newGraphicsPipeline()

QRhiGraphicsPipeline * QRhi::newGraphicsPipeline ( )
Returns
a new graphics pipeline resource.
See also
QRhiResource::destroy()

Definition at line 6520 of file qrhi.cpp.

Here is the call graph for this function:

◆ newRenderBuffer()

QRhiRenderBuffer * QRhi::newRenderBuffer ( QRhiRenderBuffer::Type  type,
const QSize pixelSize,
int  sampleCount = 1,
QRhiRenderBuffer::Flags  flags = {},
QRhiTexture::Format  backingFormatHint = QRhiTexture::UnknownFormat 
)
Returns
a new renderbuffer with the specified type, pixelSize, sampleCount, and flags.

When backingFormatHint is set to a texture format other than QRhiTexture::UnknownFormat, it may be used by the backend to decide what format to use for the storage backing the renderbuffer.

Note
backingFormatHint becomes relevant typically when multisampling and floating point texture formats are involved: rendering into a multisample QRhiRenderBuffer and then resolving into a non-RGBA8 QRhiTexture implies (with some graphics APIs) that the storage backing the QRhiRenderBuffer uses the matching non-RGBA8 format. That means that passing a format like QRhiTexture::RGBA32F is important, because backends will typically opt for QRhiTexture::RGBA8 by default, which would then break later on due to attempting to set up RGBA8->RGBA32F multisample resolve in the color attachment(s) of the QRhiTextureRenderTarget.
See also
QRhiResource::destroy()

Definition at line 6589 of file qrhi.cpp.

Here is the call graph for this function:

◆ newSampler()

QRhiSampler * QRhi::newSampler ( QRhiSampler::Filter  magFilter,
QRhiSampler::Filter  minFilter,
QRhiSampler::Filter  mipmapMode,
QRhiSampler::AddressMode  addressU,
QRhiSampler::AddressMode  addressV,
QRhiSampler::AddressMode  addressW = QRhiSampler::Repeat 
)
Returns
a new sampler with the specified magnification filter magFilter, minification filter minFilter, mipmapping mode mipmapMode, and the addressing (wrap) modes addressU, addressV, and addressW.
See also
QRhiResource::destroy()

Definition at line 6679 of file qrhi.cpp.

Here is the call graph for this function:

◆ newShaderResourceBindings()

QRhiShaderResourceBindings * QRhi::newShaderResourceBindings ( )
Returns
a new shader resource binding collection resource.
See also
QRhiResource::destroy()

Definition at line 6543 of file qrhi.cpp.

Here is the call graph for this function:

◆ newSwapChain()

QRhiSwapChain * QRhi::newSwapChain ( )
Returns
a new swapchain.
See also
QRhiResource::destroy(), QRhiSwapChain::createOrResize()

Definition at line 6707 of file qrhi.cpp.

Here is the call graph for this function:

◆ newTexture() [1/2]

QRhiTexture * QRhi::newTexture ( QRhiTexture::Format  format,
const QSize pixelSize,
int  sampleCount = 1,
QRhiTexture::Flags  flags = {} 
)
Returns
a new 2D texture with the specified format, pixelSize, sampleCount, and flags.
Note
format specifies 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.
See also
QRhiResource::destroy()

Definition at line 6609 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ newTexture() [2/2]

QRhiTexture * QRhi::newTexture ( QRhiTexture::Format  format,
int  width,
int  height,
int  depth,
int  sampleCount = 1,
QRhiTexture::Flags  flags = {} 
)
Returns
a new 2D or 3D texture with the specified format, width, height, depth, sampleCount, and flags.

This overload is suitable for 3D textures because it allows specifying depth. A 3D texture must have QRhiTexture::ThreeDimensional set in flags, but using this overload that can be omitted because the flag is set implicitly whenever depth is greater than 0. For 2D and cube textures depth should be set to 0.

Note
3D textures are only functional when the ThreeDimensionalTextures feature is reported as supported at run time.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 6632 of file qrhi.cpp.

Here is the call graph for this function:

◆ newTextureArray()

QRhiTexture * QRhi::newTextureArray ( QRhiTexture::Format  format,
int  arraySize,
const QSize pixelSize,
int  sampleCount = 1,
QRhiTexture::Flags  flags = {} 
)
Returns
a new 2D texture array with the specified format, arraySize, pixelSize, sampleCount, and flags.

This function implicitly sets QRhiTexture::TextureArray in flags.

Note
Do not confuse texture arrays with arrays of textures. A QRhiTexture created by this function is usable with 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 via QRhiShaderResourceBinding::sampledTextures() and a count > 1, and declared in the shader for example like this: {layout(binding = 1) uniform sampler2D textures[4];}
This is only functional when the TextureArrays feature is reported as supported at run time.
See also
newTexture()

Definition at line 6662 of file qrhi.cpp.

Here is the call graph for this function:

◆ newTextureRenderTarget()

QRhiTextureRenderTarget * QRhi::newTextureRenderTarget ( const QRhiTextureRenderTargetDescription desc,
QRhiTextureRenderTarget::Flags  flags = {} 
)
Returns
a new texture render target with color and depth/stencil attachments given in desc, and with the specified flags.
See also
QRhiResource::destroy()

Definition at line 6696 of file qrhi.cpp.

Here is the call graph for this function:

◆ nextResourceUpdateBatch()

QRhiResourceUpdateBatch * QRhi::nextResourceUpdateBatch ( )
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 QRhiCommandBuffer::beginPass(), QRhiCommandBuffer::endPass(), or QRhiCommandBuffer::resourceUpdate(), or by calling QRhiResourceUpdateBatch::destroy() on it.
Can be called outside beginFrame() - endFrame() as well since a batch instance just collects data on its own, it does not perform any operations.
Warning
The maximum number of batches is 64. When this limit is reached, the function will return null until a batch is returned to the pool.

Definition at line 5568 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pipelineCacheData()

QByteArray QRhi::pipelineCacheData ( )
Returns
a binary data blob with data collected from the QRhiGraphicsPipeline and QRhiComputePipeline successfully created during the lifetime of this QRhi.

By saving and then, in subsequent runs of the same application, reloading the cache data, pipeline and shader creation times can potentially be accelerated.

When the PipelineCacheDataLoadSave is reported as unsupported, the returned QByteArray is empty.

When the EnablePipelineCacheDataSave flag was not specified when calling create(), the returned QByteArray may be empty, even when the PipelineCacheDataLoadSave feature is supported.

When the returned data is non-empty, it is always specific to the QRhi backend, the graphics device, and the driver implementation in use. QRhi takes care of adding the appropriate header and safeguards that ensure that the data can always be passed safely to setPipelineCacheData().

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 also
setPipelineCacheData(), create(), isFeatureSupported()

Definition at line 6478 of file qrhi.cpp.

Here is the call graph for this function:

◆ profiler()

QRhiProfiler * QRhi::profiler ( )
Returns
the associated QRhiProfiler instance.

An instance is always available for each QRhi, but it is not very useful without EnableProfiling because no data is collected without setting the flag upon creation.

Definition at line 6377 of file qrhi.cpp.

◆ releaseCachedResources()

void QRhi::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 QRhiGraphicsPipeline implementation 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.

Definition at line 6394 of file qrhi.cpp.

Here is the call graph for this function:

◆ resourceLimit()

int QRhi::resourceLimit ( ResourceLimit  limit) const
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.

Definition at line 6329 of file qrhi.cpp.

Here is the call graph for this function:

◆ runCleanup()

void QRhi::runCleanup ( )

Invokes all registered cleanup functions. The list of cleanup callbacks it then cleared. Normally destroying the QRhi does this automatically, but sometimes it can be useful to trigger cleanup in order to release all cached, non-essential resources.

See also
addCleanupCallback()

Definition at line 5189 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setPipelineCacheData()

void QRhi::setPipelineCacheData ( const QByteArray data)

Loads data into the pipeline cache, when applicable.

When the PipelineCacheDataLoadSave is reported as unsupported, the function is safe to call, but has no effect.

The blob returned by pipelineCacheData() is always specific to a QRhi backend, a graphics device, and a given version of the graphics driver. QRhi takes 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 different QRhi backend, a warning is printed and data is 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 created QRhiGraphicsPipeline and QRhiComputePipeline objects, thus accelerating, potentially, the pipeline creation.

Note
QRhi cannot give any guarantees that data has an effect on the pipeline and shader creation performance. With APIs like Vulkan, it is up to the driver to decide if data is used for some purpose, or if it is ignored.
See also
pipelineCacheData(), isFeatureSupported()

Definition at line 6510 of file qrhi.cpp.

Here is the call graph for this function:

◆ sizeForMipLevel()

QSize QRhi::sizeForMipLevel ( int  mipLevel,
const QSize baseLevelSize 
) const
Returns
the texture image size for a given mipLevel, calculated based on the level 0 size given in baseLevelSize.

Definition at line 6225 of file qrhi.cpp.

◆ supportedSampleCounts()

QList< int > QRhi::supportedSampleCounts ( ) const
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.

Definition at line 6959 of file qrhi.cpp.

Here is the call graph for this function:

◆ thread()

QThread * QRhi::thread ( ) const
Returns
the thread on which the QRhi was \l{QRhi::create()}{initialized}.

Definition at line 5159 of file qrhi.cpp.

◆ ubufAligned()

int QRhi::ubufAligned ( int  v) const
Returns
the value (typically an offset) v aligned to the uniform buffer alignment given by by ubufAlignment().

Definition at line 6207 of file qrhi.cpp.

Here is the call graph for this function:

◆ ubufAlignment()

int QRhi::ubufAlignment ( ) const
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
ubufAligned()

Definition at line 6974 of file qrhi.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ MAX_MIP_LEVELS

const int QRhi::MAX_MIP_LEVELS = 16
static

Definition at line 1711 of file qrhi_p.h.


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