QRhiResourceUpdateBatch Class

Records upload and copy type of operations. More...

Header: #include <QRhiResourceUpdateBatch>
qmake: QT += rhi

Public Functions

~QRhiResourceUpdateBatch()
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription())
void generateMips(QRhiTexture *tex, int layer = 0)
void merge(QRhiResourceUpdateBatch *other)
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
void release()
void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
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)

Detailed Description

Records upload and copy type of operations.

With QRhi it is no longer possible to perform copy type of operations at arbitrary times. Instead, all such operations are recorded into batches that are then passed, most commonly, to QRhiCommandBuffer::beginPass(). What then happens under the hood is hidden from the application: the underlying implementations can defer and implement these operations in various different ways.

A resource update batch owns no graphics resources and does not perform any actual operations on its own. It should rather be viewed as a command buffer for update, upload, and copy type of commands.

To get an available, empty batch from the pool, call QRhi::nextResourceUpdateBatch().

Member Type Documentation

Property Documentation

Member Function Documentation

QRhiResourceUpdateBatch::~QRhiResourceUpdateBatch()

Destroys the instance of QRhiResourceUpdateBatch.

void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription())

Enqueues a texture-to-texture copy operation from src into dst as described by desc.

Note: The source texture src must be created with QRhiTexture::UsedAsTransferSource.

void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex, int layer = 0)

Enqueues a mipmap generation operation for the specified layer of texture tex.

Note: The texture must be created with QRhiTexture::MipMapped and QRhiTexture::UsedWithGenerateMips.

void QRhiResourceUpdateBatch::merge(QRhiResourceUpdateBatch *other)

Copies all queued operations from the other batch into this one.

Note: other is not changed in any way, typically it will still need a release()

This allows for a convenient pattern where resource updates that are already known during the initialization step are collected into a batch that is then merged into another when starting to first render pass later on:


  void init()
  {
      ...
      initialUpdates = rhi->nextResourceUpdateBatch();
      initialUpdates->uploadStaticBuffer(vbuf, vertexData);
      initialUpdates->uploadStaticBuffer(ibuf, indexData);
      ...
  }

  void render()
  {
      ...
      QRhiResourceUpdateBatch *resUpdates = rhi->nextResourceUpdateBatch();
      if (initialUpdates) {
          resUpdates->merge(initialUpdates);
          initialUpdates->release();
          initialUpdates = nullptr;
      }
      resUpdates->updateDynamicBuffer(...);
      ...
      cb->beginPass(rt, clearCol, clearDs, resUpdates);
  }

void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)

Enqueues a texture-to-host copy operation as described by rb.

Normally rb will specify a QRhiTexture as the source. However, when the swapchain in the current frame was created with QRhiSwapChain::UsedAsTransferSource, it can also be the source of the readback. For this, leave the texture set to null in rb.

Unlike other operations, the results here need to be processed by the application. Therefore, result provides not just the data but also a callback as operations on the batch are asynchronous by nature:


  beginFrame(sc);
  beginPass
  ...
  QRhiReadbackResult *rbResult = new QRhiReadbackResult;
  rbResult->completed = [rbResult] {
      {
          const QImage::Format fmt = QImage::Format_RGBA8888_Premultiplied; // fits QRhiTexture::RGBA8
          const uchar *p = reinterpret_cast<const uchar *>(rbResult->data.constData());
          QImage image(p, rbResult->pixelSize.width(), rbResult->pixelSize.height(), fmt);
          image.save("result.png");
      }
      delete rbResult;
  };
  u = nextResourceUpdateBatch();
  QRhiReadbackDescription rb; // no texture -> uses the current backbuffer of sc
  u->readBackTexture(rb, rbResult);
  endPass(u);
  endFrame(sc);

Note: The texture must be created with QRhiTexture::UsedAsTransferSource.

Note: Multisample textures cannot be read back.

Note: The readback returns raw byte data, in order to allow the applications to interpret it in any way they see fit. Be aware of the blending settings of rendering code: if the blending is set up to rely on premultiplied alpha, the results of the readback must also be interpreted as Premultiplied.

Note: When interpreting the resulting raw data, be aware that the readback happens with a byte ordered format. A RGBA8 texture maps therefore to byte ordered QImage formats, such as, QImage::Format_RGBA8888.

void QRhiResourceUpdateBatch::release()

Returns the batch to the pool. This should only be used when the batch is not passed to one of QRhiCommandBuffer::beginPass(), QRhiCommandBuffer::endPass(), or QRhiCommandBuffer::resourceUpdate() because these implicitly call release().

Note: QRhiResourceUpdateBatch instances must never by deleted by applications.

void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data)

Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Dynamic.

The region is specified offset and size. The actual bytes to write are specified by data which must have at least size bytes available. data can safely be destroyed or changed once this function returns.

Note: If host writes are involved, which is the case with updateDynamicBuffer() typically as such buffers are backed by host visible memory with most backends, they may accumulate within a frame. Thus pass 1 reading a region changed by a batch passed to pass 2 may see the changes specified in pass 2's update batch.

Note: QRhi transparently manages double buffering in order to prevent stalling the graphics pipeline. The fact that a QRhiBuffer may have multiple native underneath can be safely ignored when using the QRhi and QRhiResourceUpdateBatch.

void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data)

Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Immutable or QRhiBuffer::Static.

The region is specified offset and size. The actual bytes to write are specified by data which must have at least size bytes available. data can safely be destroyed or changed once this function returns.

void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *data)

Enqueues updating the entire QRhiBuffer buf created with the type QRhiBuffer::Immutable or QRhiBuffer::Static.

void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)

Enqueues uploading the image data for one or more mip levels in one or more layers of the texture tex.

The details of the copy (source QImage or compressed texture data, regions, target layers and levels) are described in desc.

void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QImage &image)

Enqueues uploading the image data for mip level 0 of layer 0 of the texture tex.

tex must have an uncompressed format. Its format must also be compatible with the QImage::format() of image. The source data is given in image.

Member Variable Documentation

Related Non-Members

Macro Documentation