QRhiTexture Class
Texture resource. More...
Header: | #include <QRhiTexture> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Gui) target_link_libraries(mytarget PRIVATE Qt6::Gui) |
qmake: | QT += gui |
Since: | Qt 6.6 |
Inherits: | QRhiResource |
Public Types
struct | NativeTexture |
enum | Flag { RenderTarget, CubeMap, MipMapped, sRGB, UsedAsTransferSource, …, OneDimensional } |
flags | Flags |
enum | Format { UnknownFormat, RGBA8, BGRA8, R8, RG8, …, ASTC_12x12 } |
Public Functions
int | arrayRangeLength() const |
int | arrayRangeStart() const |
int | arraySize() const |
virtual bool | create() = 0 |
virtual bool | createFrom(QRhiTexture::NativeTexture src) |
int | depth() const |
QRhiTexture::Flags | flags() const |
QRhiTexture::Format | format() const |
virtual QRhiTexture::NativeTexture | nativeTexture() |
QSize | pixelSize() const |
int | sampleCount() const |
void | setArrayRange(int startIndex, int count) |
void | setArraySize(int arraySize) |
void | setDepth(int depth) |
void | setFlags(QRhiTexture::Flags f) |
void | setFormat(QRhiTexture::Format fmt) |
virtual void | setNativeLayout(int layout) |
void | setPixelSize(const QSize &sz) |
void | setSampleCount(int s) |
Reimplemented Public Functions
virtual QRhiResource::Type | resourceType() const override |
Detailed Description
A QRhiTexture encapsulates a native texture object, such as a VkImage
or MTLTexture
.
A QRhiTexture instance is always created by calling the QRhi's newTexture() function. This creates no native graphics resources. To do that, call create() after setting the appropriate options, such as the format and size, although in most cases these are already set based on the arguments passed to newTexture().
Setting the flags correctly is essential, otherwise various errors can occur depending on the underlying QRhi backend and graphics API. For example, when a texture will be rendered into from a render pass via QRhiTextureRenderTarget, the texture must be created with the RenderTarget flag set. Similarly, when the texture is going to be read back, the UsedAsTransferSource flag must be set upfront. Mipmapped textures must have the MipMapped flag set. And so on. It is not possible to change the flags once create() has succeeded. To release the existing and create a new native texture object with the changed settings, call the setters and call create() again. This then might be a potentially expensive operation.
Example usage
To create a 2D texture with a size of 512x512 pixels and set its contents to all green:
QRhiTexture *texture = rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512)); if (!texture->create()) { error(); } QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); QImage image(512, 512, QImage::Format_RGBA8888); image.fill(Qt::green); batch->uploadTexture(texture, image); // ... commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call
Common patterns
A call to create() destroys any existing native resources if create() was successfully called before. If those native resources are still in use by an in-flight frame (i.e., there's a chance they are still read by the GPU), the destroying of those resources is deferred automatically. Thus a very common and convenient pattern to safely change the size of an already existing texture is the following. In practice this drops and creates a whole new native texture resource underneath, so it is not necessarily a cheap operation, but is more convenient and still faster than the alternatives, because by not destroying the texture
object itself, all references to it stay valid in other data structures (e.g., in any QShaderResourceBinding the QRhiTexture is referenced from).
// determine newSize, e.g. based on the swapchain's output size or other factors if (texture->pixelSize() != newSize) { texture->setPixelSize(newSize); if (!texture->create()) { error(); } } // continue using texture, fill it with new data
Note: This is a RHI API with limited compatibility guarantees, see QRhi for details.
See also QRhiResourceUpdateBatch, QRhi, and QRhiTextureRenderTarget.
Member Type Documentation
enum QRhiTexture::Flag
flags QRhiTexture::Flags
Flag values to specify how the texture is going to be used. Not honoring the flags set before create() and attempting to use the texture in ways that was not declared upfront can lead to unspecified behavior or decreased performance depending on the backend and the underlying graphics API.
Constant | Value | Description |
---|---|---|
QRhiTexture::RenderTarget | 1 << 0 | The texture going to be used in combination with QRhiTextureRenderTarget. |
QRhiTexture::CubeMap | 1 << 2 | The texture is a cubemap. Such textures have 6 layers, one for each face in the order of +X, -X, +Y, -Y, +Z, -Z. Cubemap textures cannot be multisample. |
QRhiTexture::MipMapped | 1 << 3 | The texture has mipmaps. The appropriate mip count is calculated automatically and can also be retrieved via QRhi::mipLevelsForSize(). The images for the mip levels have to be provided in the texture uploaded or generated via QRhiResourceUpdateBatch::generateMips(). Multisample textures cannot have mipmaps. |
QRhiTexture::sRGB | 1 << 4 | Use an sRGB format. |
QRhiTexture::UsedAsTransferSource | 1 << 5 | The texture is used as the source of a texture copy or readback, meaning the texture is given as the source in QRhiResourceUpdateBatch::copyTexture() or QRhiResourceUpdateBatch::readBackTexture(). |
QRhiTexture::UsedWithGenerateMips | 1 << 6 | The texture is going to be used with QRhiResourceUpdateBatch::generateMips(). |
QRhiTexture::UsedWithLoadStore | 1 << 7 | The texture is going to be used with image load/store operations, for example, in a compute shader. |
QRhiTexture::UsedAsCompressedAtlas | 1 << 8 | The texture has a compressed format and the dimensions of subresource uploads may not match the texture size. |
QRhiTexture::ExternalOES | 1 << 9 | The texture should use the GL_TEXTURE_EXTERNAL_OES target with OpenGL. This flag is ignored with other graphics APIs. |
QRhiTexture::ThreeDimensional | 1 << 10 | The texture is a 3D texture. Such textures should be created with the QRhi::newTexture() overload taking a depth in addition to width and height. A 3D texture can have mipmaps but cannot be multisample. When rendering into, or uploading data to a 3D texture, the layer specified in the render target's color attachment or the upload description refers to a single slice in range [0..depth-1]. The underlying graphics API may not support 3D textures at run time. Support is indicated by the QRhi::ThreeDimensionalTextures feature. |
QRhiTexture::TextureRectangleGL | 1 << 11 | The texture should use the GL_TEXTURE_RECTANGLE target with OpenGL. This flag is ignored with other graphics APIs. Just like ExternalOES, this flag is useful when working with platform APIs where native OpenGL texture objects received from the platform are wrapped in a QRhiTexture, and the platform can only provide textures for a non-2D texture target. |
QRhiTexture::TextureArray | 1 << 12 | The texture is a texture array, i.e. a single texture object that is a homogeneous array of 2D textures. Texture arrays are created with QRhi::newTextureArray(). The underlying graphics API may not support texture array objects at run time. Support is indicated by the QRhi::TextureArrays feature. When rendering into, or uploading data to a texture array, the layer specified in the render target's color attachment or the upload description selects a single element in the array. |
QRhiTexture::OneDimensional | 1 << 13 | The texture is a 1D texture. Such textures can be created by passing a 0 height and depth to QRhi::newTexture(). Note that there can be limitations on one dimensional textures depending on the underlying graphics API. For example, rendering to them or using them with mipmap-based filtering may be unsupported. This is indicated by the QRhi::OneDimensionalTextures and QRhi::OneDimensionalTextureMipmaps feature flags. |
The Flags type is a typedef for QFlags<Flag>. It stores an OR combination of Flag values.
enum QRhiTexture::Format
Specifies the texture format. See also QRhi::isTextureFormatSupported() and note that flags() can modify the format when QRhiTexture::sRGB is set.
Constant | Value | Description |
---|---|---|
QRhiTexture::UnknownFormat | 0 | Not a valid format. This cannot be passed to setFormat(). |
QRhiTexture::RGBA8 | 1 | Four component, unsigned normalized 8 bit per component. Always supported. |
QRhiTexture::BGRA8 | 2 | Four component, unsigned normalized 8 bit per component. |
QRhiTexture::R8 | 3 | One component, unsigned normalized 8 bit. |
QRhiTexture::RG8 | 4 | Two components, unsigned normalized 8 bit. |
QRhiTexture::R16 | 5 | One component, unsigned normalized 16 bit. |
QRhiTexture::RG16 | 6 | Two component, unsigned normalized 16 bit. |
QRhiTexture::RED_OR_ALPHA8 | 7 | Either same as R8, or is a similar format with the component swizzled to alpha, depending on RedOrAlpha8IsRed. |
QRhiTexture::RGBA16F | 8 | Four components, 16-bit float per component. |
QRhiTexture::RGBA32F | 9 | Four components, 32-bit float per component. |
QRhiTexture::R16F | 10 | One component, 16-bit float. |
QRhiTexture::R32F | 11 | One component, 32-bit float. |
QRhiTexture::RGB10A2 | 12 | Four components, unsigned normalized 10 bit R, G, and B, 2-bit alpha. This is a packed format so native endianness applies. Note that there is no BGR10A2. This is because RGB10A2 maps to DXGI_FORMAT_R10G10B10A2_UNORM with D3D, MTLPixelFormatRGB10A2Unorm with Metal, VK_FORMAT_A2B10G10R10_UNORM_PACK32 with Vulkan, and GL_RGB10_A2/GL_RGB/GL_UNSIGNED_INT_2_10_10_10_REV on OpenGL (ES). This is the only universally supported RGB30 option. The corresponding QImage formats are QImage::Format_BGR30 and QImage::Format_A2BGR30_Premultiplied. |
QRhiTexture::D16 | 13 | 16-bit depth (normalized unsigned integer) |
QRhiTexture::D24 | 14 | 24-bit depth (normalized unsigned integer) |
QRhiTexture::D24S8 | 15 | 24-bit depth (normalized unsigned integer), 8 bit stencil |
QRhiTexture::D32F | 16 | 32-bit depth (32-bit float) |
QRhiTexture::BC1 | 17 | |
QRhiTexture::BC2 | 18 | |
QRhiTexture::BC3 | 19 | |
QRhiTexture::BC4 | 20 | |
QRhiTexture::BC5 | 21 | |
QRhiTexture::BC6H | 22 | |
QRhiTexture::BC7 | 23 | |
QRhiTexture::ETC2_RGB8 | 24 | |
QRhiTexture::ETC2_RGB8A1 | 25 | |
QRhiTexture::ETC2_RGBA8 | 26 | |
QRhiTexture::ASTC_4x4 | 27 | |
QRhiTexture::ASTC_5x4 | 28 | |
QRhiTexture::ASTC_5x5 | 29 | |
QRhiTexture::ASTC_6x5 | 30 | |
QRhiTexture::ASTC_6x6 | 31 | |
QRhiTexture::ASTC_8x5 | 32 | |
QRhiTexture::ASTC_8x6 | 33 | |
QRhiTexture::ASTC_8x8 | 34 | |
QRhiTexture::ASTC_10x5 | 35 | |
QRhiTexture::ASTC_10x6 | 36 | |
QRhiTexture::ASTC_10x8 | 37 | |
QRhiTexture::ASTC_10x10 | 38 | |
QRhiTexture::ASTC_12x10 | 39 | |
QRhiTexture::ASTC_12x12 | 40 |
Member Function Documentation
int QRhiTexture::arrayRangeLength() const
Returns the exposed array range size when setArrayRange() was called.
See also setArrayRange().
int QRhiTexture::arrayRangeStart() const
Returns the first array layer when setArrayRange() was called.
See also setArrayRange().
int QRhiTexture::arraySize() const
Returns the texture array size.
See also setArraySize().
[pure virtual]
bool QRhiTexture::create()
Creates the corresponding native graphics resources. If there are already resources present due to an earlier create() with no corresponding destroy(), then destroy() is called implicitly first.
Returns true
when successful, false
when a graphics operation failed. Regardless of the return value, calling destroy() is always safe.
[virtual]
bool QRhiTexture::createFrom(QRhiTexture::NativeTexture src)
Similar to create(), except that no new native textures are created. Instead, the native texture resources specified by src is used.
This allows importing an existing native texture object (which must belong to the same device or sharing context, depending on the graphics API) from an external graphics engine.
Returns true if the specified existing native texture object has been successfully wrapped as a non-owning QRhiTexture.
Note: format(), pixelSize(), sampleCount(), and flags() must still be set correctly. Passing incorrect sizes and other values to QRhi::newTexture() and then following it with a createFrom() expecting that the native texture object alone is sufficient to deduce such values is wrong and will lead to problems.
Note: QRhiTexture does not take ownership of the texture object. destroy() does not free the object or any associated memory.
The opposite of this operation, exposing a QRhiTexture-created native texture object to a foreign engine, is possible via nativeTexture().
Note: When importing a 3D texture, or a texture array object, or, with OpenGL ES, an external texture, it is then especially important to set the corresponding flags (ThreeDimensional, TextureArray, ExternalOES) via setFlags() before calling this function.
int QRhiTexture::depth() const
Returns the depth for 3D textures.
See also setDepth().
QRhiTexture::Flags QRhiTexture::flags() const
Returns the texture flags.
See also setFlags().
QRhiTexture::Format QRhiTexture::format() const
Returns the texture format.
See also setFormat().
[virtual]
QRhiTexture::NativeTexture QRhiTexture::nativeTexture()
Returns the underlying native resources for this texture. The returned value will be empty if exposing the underlying native resources is not supported by the backend.
See also createFrom().
QSize QRhiTexture::pixelSize() const
Returns the size in pixels.
See also setPixelSize().
[override virtual]
QRhiResource::Type QRhiTexture::resourceType() const
Reimplements: QRhiResource::resourceType() const.
Returns the resource type.
int QRhiTexture::sampleCount() const
Returns the sample count. 1 means no multisample antialiasing.
See also setSampleCount().
void QRhiTexture::setArrayRange(int startIndex, int count)
Normally all array layers are exposed and it is up to the shader to select the layer via the third coordinate passed to the texture()
GLSL function when sampling the sampler2DArray
. When QRhi::TextureArrayRange is reported as supported, calling setArrayRange() before create() or createFrom() requests selecting only the specified range, count elements starting from startIndex. The shader logic can then be written with this in mind.
See also QRhi::TextureArrayRange.
void QRhiTexture::setArraySize(int arraySize)
Sets the texture arraySize.
See also arraySize().
void QRhiTexture::setDepth(int depth)
Sets the depth for a 3D texture.
See also depth().
void QRhiTexture::setFlags(QRhiTexture::Flags f)
Sets the texture flags to f.
See also flags().
void QRhiTexture::setFormat(QRhiTexture::Format fmt)
Sets the requested texture format to fmt.
Note: The value set is only taken into account upon the next call to create(), i.e. when the underlying graphics resource are (re)created. Setting a new value is futile otherwise and must be avoided since it can lead to inconsistent state.
See also format().
[virtual]
void QRhiTexture::setNativeLayout(int layout)
With some graphics APIs, such as Vulkan, integrating custom rendering code that uses the graphics API directly needs special care when it comes to image layouts. This function allows communicating the expected layout the image backing the QRhiTexture is in after the native rendering commands.
For example, consider rendering into a QRhiTexture's VkImage directly with Vulkan in a code block enclosed by QRhiCommandBuffer::beginExternal() and QRhiCommandBuffer::endExternal(), followed by using the image for texture sampling in a QRhi-based render pass. To avoid potentially incorrect image layout transitions, this function can be used to indicate what the image layout will be once the commands recorded in said code block complete.
Calling this function makes sense only after QRhiCommandBuffer::endExternal() and before a subsequent QRhiCommandBuffer::beginPass().
This function has no effect with QRhi backends where the underlying graphics API does not expose a concept of image layouts.
Note: With Vulkan layout is a VkImageLayout
. With Direct 3D 12 layout is a value composed of the bits from D3D12_RESOURCE_STATES
.
void QRhiTexture::setPixelSize(const QSize &sz)
Sets the texture size, specified in pixels, to sz.
Note: The value set is only taken into account upon the next call to create(), i.e. when the underlying graphics resource are (re)created. Setting a new value is futile otherwise and must be avoided since it can lead to inconsistent state. The same applies to all other setters as well.
See also pixelSize().
void QRhiTexture::setSampleCount(int s)
Sets the sample count to s.
See also sampleCount().