Commit 70403f3d authored by Laszlo Agocs's avatar Laszlo Agocs

Clean up qrhi.h by moving everything to proper docs

parent 31db4910
......@@ -223,6 +223,13 @@ QT_BEGIN_NAMESPACE
QRhiTexture::nativeHandles(). Most importantly, passing pointers in structs
and via setters does not transfer ownership.
\section3 Threading
A QRhi instance can be created and used on any thread but all usage must be
limited to that one single thread. When it comes to native objects, such as
OpenGL contexts, passed in in QRhiInitParams, it is up to the application
to ensure they are not misused by other threads.
\sa {Qt Shader Tools}
......@@ -275,24 +282,25 @@ QT_BEGIN_NAMESPACE
\enum QRhi::Feature
Flag values to indicate what features are supported by the backend currently in use.
\value MultisampleTexture Textures with sample count larger than 1 are
\value MultisampleTexture Indicates that textures with a sample count larger
than 1 are supported.
\value MultisampleRenderBuffer Renderbuffers with sample count larger than
1 are supported.
\value MultisampleRenderBuffer Indicates that renderbuffers with a sample
count larger than 1 are supported.
\value DebugMarkers Debug marker groups (and so
\value DebugMarkers Indicates that debug marker groups (and so
QRhiCommandBuffer::debugMarkBegin()) are supported.
\value Timestamps Command buffer timestamps are supported. Relevant for
\value Timestamps Indicates that command buffer timestamps are supported.
Relevant for QRhiProfiler::gpuFrameTimes().
\value Instancing Instanced drawing is supported.
\value Instancing Indicates that instanced drawing is supported.
\value CustomInstanceStepRate Instance step rate other than 1 is supported.
\value CustomInstanceStepRate Indicates that instance step rates other than
1 are supported.
\value PrimitiveRestart Restarting the assembly of primitives when
encountering an index value of 0xFFFF
\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 always enabled, for
certain primitive topologies at least. Due to the wildly varying primitive
......@@ -573,18 +581,54 @@ QT_BEGIN_NAMESPACE
\class QRhiTextureRenderTargetDescription
\inmodule QtRhi
\brief Describes the color and depth or depth/stencil attachments of a render target.
A texture render target has zero or more textures as color attachments,
zero or one renderbuffer as combined depth/stencil buffer or zero or one
texture as depth buffer.
\note \l depthStencilBuffer and \l depthTexture cannot be both set.
\class QRhiTextureRenderTargetDescription::ColorAttachment
\inmodule QtRhi
\brief Describes the color attachments of a render target.
\brief Describes the a single color attachment of a render target.
A color attachment is either a QRhiTexture or a QRhiRenderBuffer. The
former, when \l texture is set, is used in most cases.
\note \l texture and \l renderBuffer cannot be both set.
Setting renderBuffer instead is recommended only when multisampling is
needed. Relying on QRhi::MultisampleRenderBuffer is a better choice than
QRhi::MultisampleTexture in practice since the former is available in more
run time configurations (e.g. when running on OpenGL ES 3.0 which has no
support for multisample textures, but does support multisample
When targeting a non-multisample texture, the \l layer and \l level
indicate the targeted layer (face index \c{0-5} for cubemaps) and mip
When \l texture or \l renderBuffer is multisample, \l resolveTexture can be
set optionally. When set, samples are resolved automatically into that
(non-multisample) texture at the end of the render pass. When rendering
into a multisample renderbuffers, this is the only way to get resolved,
non-multisample content out of them. Multisample textures allow sampling in
shaders so for them this is just one option.
\note when resolving is enabled, the multisample data may not be written
out at all. This means that the multisample \l texture must not be used
afterwards with shaders for sampling when \l resolveTexture is set.
\class QRhiTextureUploadDescription
\inmodule QtRhi
\brief Describes a texture upload operation.
\note Cubemaps have one layer for each of the six faces in the order +X,
-X, +Y, -Y, +Z, -Z.
......@@ -597,24 +641,73 @@ QT_BEGIN_NAMESPACE
\class QRhiTextureUploadDescription::Layer::MipLevel
\inmodule QtRhi
\brief Describes one mip level in a layer in a texture upload operation.
The source content is specified either as a QImage or as a raw blob. The
former is only allowed for uncompressed textures, while the latter is only
supported for compressed ones.
\note \l image and \l compressedData cannot be both set.
\l destinationTopLeft specifies the top-left corner of the target
rectangle. Defaults to (0, 0).
An empty \l sourceSize (the default) indicates that size is assumed to be
the size of the subresource. For uncompressed textures this implies that
the size of the source \l image must match the subresource. For compressed
textures sufficient amount of data must be provided in \l compressedData.
\note With compressed textures the first upload must always match the
subresource size due to graphics API limitations with some backends.
\l sourceTopLeft is is only supported for uncompressed textures, and
specifies the top-left corner of the source rectangle.
\note Setting \l sourceSize or \l sourceTopLeft may trigger a QImage copy
internally, depending on the format and the backend.
\class QRhiTextureCopyDescription
\inmodule QtRhi
\brief Describes a texture-to-texture copy operation.
An empty \l pixelSize (the default) indicates that the entire subresource
is to be copied.
\note The source texture must be created with
\class QRhiReadbackDescription
\inmodule QtRhi
\brief Describes a readback (reading back texture contents from possibly GPU-only memory) operation.
The source of the readback operation is either a QRhiTexture or the
current backbuffer of the currently targeted QRhiSwapChain. When \l
texture is not set, the swapchain is used. Otherwise the specified
QRhiTexture is treated as the source.
\note Textures used in readbacks must be created with
\note Swapchains used in readbacks must be created with
\l layer and \l level are only applicable when the source is a QRhiTexture.
\note Multisample textures cannot be read back. Readbacks are supported for
multisample swapchain buffers however.
\class QRhiReadbackResult
\inmodule QtRhi
\brief Describes the results of a potentially asynchronous readback operation.
When \l completed is set, the function is invoked when the \l data is
available. \l format and \l pixelSize are set upon completion together with
\l data.
......@@ -635,6 +728,20 @@ QT_BEGIN_NAMESPACE
\brief Vertex, index, or uniform (constant) buffer resource.
\fn void QRhiBuffer::setSize(int sz)
Sets the size of the buffer in bytes. The size is normally specified in
QRhi::newBuffer() so this function is only used when the size has to be
changed. As with other setters, the size only takes effect when calling
build(), and for already built buffers this involves releasing the previous
native resource and creating new ones under the hood.
Backends may choose to allocate buffers bigger than \a sz in order to
fulfill alignment requirements. This is hidden from the applications and
size() will always report the size requested in \a sz.
\enum QRhiBuffer::Type
Specifies type of buffer resource.
......@@ -868,7 +975,12 @@ QT_BEGIN_NAMESPACE
\enum QRhiTextureRenderTarget::Flag
Flag values describing the load/store behavior for the render target
Flag values describing the load/store behavior for the render target. The
load/store behavior may be baked into native resources under the hood,
depending on the backend, and therefore it needs to be known upfront and
cannot be changed without rebuilding (and so releasing and creating new
native resources).
\value PreserveColorContents Indicates that the contents of the color
attachments is to be loaded when starting a render pass, instead of
......@@ -957,6 +1069,39 @@ QT_BEGIN_NAMESPACE
\class QRhiGraphicsPipeline
\inmodule QtRhi
\brief Graphics pipeline state resource.
\note Setting the shader resource bindings is mandatory but the referenced
QRhiShaderResourceBindings is not required to be built when build() is
called. Instead, QRhiShaderResourceBindings::build() must be done at latest
before QRhiCommandBuffer::setGraphicsPipeline().
\note Setting the render pass descriptor is mandatory. To obtain a
QRhiRenderPassDescriptor that can be passed to setRenderPassDescriptor(),
use either QRhiTextureRenderTarget::newCompatibleRenderPassDescriptor() or
\note Setting the vertex input layout is mandatory.
\note Setting the shader stages is mandatory.
\note sampleCount() defaults to 1 and must match the sample count of the
render target's color and depth stencil attachments.
\note The depth test, depth write, and stencil test are disabled by
\note stencilReadMask() and stencilWriteMask() apply to both faces. They
both default to 0xFF.
\fn void QRhiGraphicsPipeline::setTargetBlends(const QVector<TargetBlend> &blends)
Sets the blend specification for color attachments. Each element in \a
blends corresponds to a color attachment of the render target.
By default no blends are set, which is a shortcut to disabling blending and
enabling color write for all four channels.
......@@ -1084,11 +1229,6 @@ QT_BEGIN_NAMESPACE
Defaults to color write enabled, blending disabled. The blend values are
set up for pre-multiplied alpha (One, OneMinusSrcAlpha, One,
OneMinusSrcAlpha) by default.
Not having any TargetBlend specified in
QRhiGraphicsPipeline::setTargetBlends() disables blending and is a
convenient shortcut when having only one color attachment and no blending
is desired. Otherwise a TargetBlend for each color attachment is expected.
......@@ -1563,6 +1703,9 @@ QRhiTextureRenderTarget::QRhiTextureRenderTarget(QRhiImplementation *rhi,
the render pass descriptor so those can differ in the two
QRhiTextureRenderTarget intances.
\note resources, such as QRhiTexture instances, referenced in description()
must already be built
\sa build()
......@@ -1583,6 +1726,9 @@ QRhiTextureRenderTarget::QRhiTextureRenderTarget(QRhiImplementation *rhi,
same number and type of attachments (the actual textures can differ) and
the same flags.
\note resources, such as QRhiTexture instances, referenced in description()
must already be built
\return \c true when successful, \c false when a graphics operation failed.
Regardless of the return value, calling release() is always safe.
......@@ -214,25 +214,17 @@ struct Q_RHI_EXPORT QRhiTextureRenderTargetDescription
struct Q_RHI_EXPORT ColorAttachment {
ColorAttachment() { }
// either a texture or a renderbuffer
ColorAttachment(QRhiTexture *texture_) : texture(texture_) { }
ColorAttachment(QRhiRenderBuffer *renderBuffer_) : renderBuffer(renderBuffer_) { }
QRhiTexture *texture = nullptr;
QRhiRenderBuffer *renderBuffer = nullptr;
// for texture
int layer = 0; // face (0..5) for cubemaps
int level = 0; // only when non-multisample
int layer = 0;
int level = 0;
// When texture or renderBuffer is multisample. Optional. When set,
// samples are resolved into this non-multisample texture. Note that
// the msaa data may not be written out at all in this case. This is
// the only way to get a non-msaa texture from an msaa render target as
// we do not have an explicit resolve operation because it does not
// exist in some APIs and would not be efficient with tiled GPUs anyways.
QRhiTexture *resolveTexture = nullptr;
int resolveLayer = 0; // unused for now since cubemaps cannot be multisample
int resolveLayer = 0;
int resolveLevel = 0;
......@@ -248,7 +240,6 @@ struct Q_RHI_EXPORT QRhiTextureRenderTargetDescription
{ colorAttachments.append(colorAttachment); }
QVector<ColorAttachment> colorAttachments;
// depth-stencil is is a renderbuffer, a texture, or none
QRhiRenderBuffer *depthStencilBuffer = nullptr;
QRhiTexture *depthTexture = nullptr;
......@@ -261,7 +252,6 @@ struct Q_RHI_EXPORT QRhiTextureUploadDescription
struct Q_RHI_EXPORT Layer {
struct Q_RHI_EXPORT MipLevel {
MipLevel() { }
// either a QImage or compressed data (not both)
MipLevel(const QImage &image_) : image(image_) { }
MipLevel(const QByteArray &compressedData_) : compressedData(compressedData_) { }
......@@ -269,19 +259,7 @@ struct Q_RHI_EXPORT QRhiTextureUploadDescription
QByteArray compressedData;
QPoint destinationTopLeft;
// Empty = entire subresource. For uncompressed this then means the
// size of the source image must match the subresource. When
// non-empty, this size is used.
// Works for compressed as well, but the first compressed upload
// must always match the subresource size (and sourceSize can be
// left unset) due to gfx api limitations with some backends.
QSize sourceSize;
// This is only supported for uncompressed. Setting sourceSize or
// sourceTopLeft may trigger a QImage copy internally (depending on
// the format and the gfx api).
QPoint sourceTopLeft;
......@@ -292,7 +270,7 @@ struct Q_RHI_EXPORT QRhiTextureUploadDescription
QRhiTextureUploadDescription() { }
QRhiTextureUploadDescription(const QVector<Layer> &layers_) : layers(layers_) { }
QVector<Layer> layers; // 6 layers for cubemaps, 1 otherwise
QVector<Layer> layers;
Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription::Layer::MipLevel, Q_MOVABLE_TYPE);
......@@ -301,7 +279,7 @@ Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription, Q_MOVABLE_TYPE);
struct Q_RHI_EXPORT QRhiTextureCopyDescription
QSize pixelSize; // empty = entire subresource
QSize pixelSize;
int sourceLayer = 0;
int sourceLevel = 0;
......@@ -316,10 +294,8 @@ Q_DECLARE_TYPEINFO(QRhiTextureCopyDescription, Q_MOVABLE_TYPE);
struct Q_RHI_EXPORT QRhiReadbackDescription
QRhiReadbackDescription() { } // source is the back buffer of the swapchain of the current frame (if the swapchain supports readback)
QRhiReadbackDescription(QRhiTexture *texture_) : texture(texture_) { } // source is the specified texture
// Note that reading back an msaa image is only supported for swapchains.
// Multisample textures cannot be read back.
QRhiReadbackDescription() { }
QRhiReadbackDescription(QRhiTexture *texture_) : texture(texture_) { }
QRhiTexture *texture = nullptr;
int layer = 0;
......@@ -354,9 +330,9 @@ class Q_RHI_EXPORT QRhiBuffer : public QRhiResource
enum Type {
Immutable, // data never changes after initial upload - under the hood typically in device local (GPU) memory
Static, // data changes infrequently - under the hood typically device local and updated via a separate, host visible staging buffer
Dynamic // data changes frequently - under the hood typically host visible
enum UsageFlag {
......@@ -372,8 +348,6 @@ public:
UsageFlags usage() const { return m_usage; }
void setUsage(UsageFlags u) { m_usage = u; }
// no restrictions here, up to the backend to round up if needed (that
// won't be visible in the user-provided size reported here)
int size() const { return m_size; }
void setSize(int sz) { m_size = sz; }
......@@ -394,11 +368,11 @@ class Q_RHI_EXPORT QRhiTexture : public QRhiResource
enum Flag {
RenderTarget = 1 << 0,
ChangesFrequently = 1 << 1, // hint for backend to keep staging resources around
ChangesFrequently = 1 << 1,
CubeMap = 1 << 2,
MipMapped = 1 << 3,
sRGB = 1 << 4,
UsedAsTransferSource = 1 << 5, // will (also) be used as the source of a copy or readback
UsedAsTransferSource = 1 << 5,
UsedWithGenerateMips = 1 << 6
......@@ -474,7 +448,7 @@ class Q_RHI_EXPORT QRhiSampler : public QRhiResource
enum Filter {
None, // for mipmapMode only
......@@ -529,7 +503,7 @@ public:
enum Flag {
UsedWithSwapChainOnly = 1 << 0 // use implicit winsys buffers, don't create anything (GL)
UsedWithSwapChainOnly = 1 << 0
......@@ -593,8 +567,6 @@ class Q_RHI_EXPORT QRhiTextureRenderTarget : public QRhiRenderTarget
enum Flag {
// the load-not-clear request is baked into the resources under the rpd
// with some backends so it cannot be more dynamic than this
PreserveColorContents = 1 << 0,
PreserveDepthStencilContents = 1 << 1
......@@ -606,12 +578,8 @@ public:
Flags flags() const { return m_flags; }
void setFlags(Flags f) { m_flags = f; }
// To be called before build() with description and flags set.
// Textures in desc must already be built.
// Note setRenderPassDescriptor() in the base class, that must still be called afterwards (but before build()).
virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
// as usual, textures in desc must be built before calling build() on the rt
virtual bool build() = 0;
......@@ -654,7 +622,7 @@ public:
enum CullMode { // not a bitmask since some apis use a mask, some don't
enum CullMode {
......@@ -805,19 +773,19 @@ protected:
Topology m_topology = Triangles;
CullMode m_cullMode = None;
FrontFace m_frontFace = CCW;
QVector<TargetBlend> m_targetBlends; // no blend when empty
QVector<TargetBlend> m_targetBlends;
bool m_depthTest = false;
bool m_depthWrite = false;
CompareOp m_depthOp = Less;
bool m_stencilTest = false;
StencilOpState m_stencilFront;
StencilOpState m_stencilBack;
quint32 m_stencilReadMask = 0xFF; // applies to both faces
quint32 m_stencilWriteMask = 0xFF; // applies to both faces
int m_sampleCount = 1; // MSAA, swapchain+depthstencil must match
quint32 m_stencilReadMask = 0xFF;
quint32 m_stencilWriteMask = 0xFF;
int m_sampleCount = 1;
QVector<QRhiGraphicsShaderStage> m_shaderStages;
QRhiVertexInputLayout m_vertexInputLayout;
QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr; // must be built by the time ps' build() is called
QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
void *m_reserved;
......@@ -833,8 +801,8 @@ public:
SurfaceHasPreMulAlpha = 1 << 0,
SurfaceHasNonPreMulAlpha = 1 << 1,
sRGB = 1 << 2,
UsedAsTransferSource = 1 << 3, // will be read back
NoVSync = 1 << 4 // may be implementation specific what this results in
UsedAsTransferSource = 1 << 3,
NoVSync = 1 << 4
......@@ -853,8 +821,6 @@ public:
QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
// Alternatively, integrate with an existing swapchain, f.ex.
// QVulkanWindow. Other settings have no effect when this is set.
QObject *target() const { return m_target; }
void setTarget(QObject *obj) { m_target = obj; }
......@@ -891,8 +857,8 @@ public:
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates);
void beginPass(QRhiRenderTarget *rt,
const QRhiColorClearValue &colorClearValue, // ignored when rt has PreserveColorContents
const QRhiDepthStencilClearValue &depthStencilClearValue, // ignored when no ds attachment
const QRhiColorClearValue &colorClearValue,
const QRhiDepthStencilClearValue &depthStencilClearValue,
QRhiResourceUpdateBatch *resourceUpdates = nullptr);
void endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
......@@ -956,7 +922,7 @@ public:
void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
void uploadStaticBuffer(QRhiBuffer *buf, const void *data);
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc);
void uploadTexture(QRhiTexture *tex, const QImage &image); // shortcut
void uploadTexture(QRhiTexture *tex, const QImage &image);
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
void generateMips(QRhiTexture *tex);
......@@ -977,8 +943,6 @@ struct Q_RHI_EXPORT QRhiInitParams
// A QRhi instance can be created and used on any thread but all usage must be
// limited to that one single thread.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment