QRhiResourceUpdateBatch Class
记录上传和复制类型的操作。更多...
| 标题: | #include <rhi/qrhi.h> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS GuiPrivate) target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate) |
| qmake: | QT += gui-private |
| 自: | Qt 6.6 |
公共函数
| void | copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription()) |
| void | generateMips(QRhiTexture *tex) |
| bool | hasOptimalCapacity() const |
| void | merge(QRhiResourceUpdateBatch *other) |
| void | readBackBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, QRhiReadbackResult *result) |
| void | readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result) |
| void | release() |
| void | updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data) |
(since 6.10) void | updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, QByteArray data) |
| void | uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data) |
(since 6.10) void | uploadStaticBuffer(QRhiBuffer *buf, QByteArray data) |
| void | uploadStaticBuffer(QRhiBuffer *buf, const void *data) |
(since 6.10) void | uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, QByteArray data) |
| void | uploadTexture(QRhiTexture *tex, const QImage &image) |
| void | uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc) |
详细说明
在QRhi 中,已无法在任意时刻执行复制类操作。取而代之的是,所有此类操作都会被记录到批处理中,随后通常会传递给QRhiCommandBuffer::beginPass()。此后内部发生的过程对应用程序而言是不可见的:底层实现可以推迟并以各种不同方式执行这些操作。
资源更新批次不拥有任何图形资源,也不会自行执行任何实际操作。它应被视为用于更新、上传和复制类型命令的命令缓冲区。
要从池中获取一个可用的空批处理,请调用QRhi::nextResourceUpdateBatch()。
注意:这是一个 兼容性保证有限的 RHI API,详情请参阅QRhi 。
成员函数文档
void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription())
将纹理到纹理的复制操作从src 排入队列,目标为dst ,具体说明参见desc 。
注意: 源纹理src 必须通过QRhiTexture::UsedAsTransferSource 创建。
注意: 纹理的格式必须一致。在大多数图形 API 中,数据会原样复制,不会进行任何格式转换。如果dst 和src 是用不同格式创建的,可能会出现未指定的问题。
void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex)
将指定纹理tex 的 Mipmap 生成操作加入队列。
支持 2D 和立方体纹理。当报告支持QRhi::OneDimensionalTextureMipmaps 或QRhi::ThreeDimensionalTextureMipmaps 功能时,分别支持 1D 和 3D 纹理。
注意:纹理 必须使用QRhiTexture::MipMapped 和QRhiTexture::UsedWithGenerateMips 创建。
警告: QRhi 无法保证能够为所有受支持的纹理格式生成 Mipmap。例如,在 OpenGL ES 3.0 和 iOS 上的 Metal 中,QRhiTexture::RGBA32F 并非filterable 格式,因此 Mipmap 生成请求可能会失败。 RGBA8 和 RGBA16F 通常支持滤波,因此建议在需要生成 MIP 图时使用这些格式。
bool QRhiResourceUpdateBatch::hasOptimalCapacity() const
在排入此批处理的缓冲区和纹理操作数量低于合理阈值之前,该函数返回 true。
当添加到该批处理中的缓冲区和/或纹理操作数量已达到或即将达到一定限制时,返回值为 false。此后该批处理仍可正常运行,但可能需要分配额外的内存。 因此,当渲染器在准备帧时将大量缓冲区和纹理更新收集到单个批处理中,且本函数返回 false 时,建议考虑使用submitting the batch 和starting a new one 。
void QRhiResourceUpdateBatch::merge(QRhiResourceUpdateBatch *other)
将other 批处理中所有已排队的操作复制到此批处理中。
注意: 合并操作完成后,other 可能不再包含有效数据,且不得提交,但仍需通过调用 `release()` 来释放该批处理。
这提供了一种便捷的模式:在初始化步骤中已知的资源更新会被收集到一个批处理中,随后在稍后开始首次渲染遍时,该批处理会被合并到另一个批处理中:
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::readBackBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, QRhiReadbackResult *result)
将QRhiBuffer buf 中某个区域的读回操作加入队列。该区域的大小由size 以字节为单位指定,offset 表示开始读取的偏移量(以字节为单位)。
读回操作是异步的。result 包含一个回调函数,该函数将在操作完成时被调用。数据存储在QRhiReadbackResult::data 中。操作成功完成后,QByteArray 的大小将等于size 。若操作失败,QByteArray 将为空。
注意: 仅当报告支持QRhi::ReadBackNonUniformBuffer 功能时,才支持以不同于QRhiBuffer::UniformBuffer 的方式读取 缓冲区。
注意: 当满足以下任一条件时,可保证异步回读 已完成:已调用finish();或者,至少有N 个帧已被submitted (包括发起回读操作的帧),且recording of a new frame 已启动,其中N 是QRhi::MaxAsyncReadbackFrames 返回的resource limit value 。
另请参阅 readBackTexture()、QRhi::isFeatureSupported(),以及QRhi::resourceLimit()。
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
将纹理到主机的复制操作加入队列,具体说明参见rb 。
通常情况下,rb 会指定一个QRhiTexture 作为源。但是,当当前帧中的交换链是通过QRhiSwapChain::UsedAsTransferSource 创建时,它也可以作为读回操作的源。为此,请在rb 中将纹理设置为 null。
与其他操作不同,此处的结果需要由应用程序进行处理。因此,result 不仅提供数据,还提供一个回调函数,因为批量操作本质上是异步的:
rhi->beginFrame(swapchain);
cb->beginPass(swapchain->currentFrameRenderTarget(), colorClear, dsClear);
// ...
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;
};
QRhiResourceUpdateBatch *u = nextResourceUpdateBatch();
QRhiReadbackDescription rb; // no texture -> uses the current backbuffer of sc
u->readBackTexture(rb, rbResult);
cb->endPass(u);
rhi->endFrame(swapchain);注意: 纹理必须通过QRhiTexture::UsedAsTransferSource 创建。
注意: 无法读回多采样 纹理。
注意:读回操作 返回原始字节数据,以便应用程序能够按其认为合适的方式进行解释。请注意渲染代码的混合设置:如果混合设置依赖于预乘透明度,则读回的结果也必须被解释为预乘透明度。
注意:在 解析生成的原始数据时 ,请注意读回操作采用字节序格式。因此,RGBA8 纹理会映射为字节序的QImage 格式,例如QImage::Format_RGBA8888 。
注意: 当满足以下任一条件时,可确保异步读回 已完成:已调用finish();或者,至少有N 个帧已被submitted (包括发起读回操作的帧),且recording of a new frame 已启动,其中N 是QRhi::MaxAsyncReadbackFrames 返回的resource limit value 。
单次读回操作每次复制一层中一个mip级(立方贴图面、3D切片或纹理数组元素)。mip级和层由rb 中的相应字段指定。
另请参阅 readBackBuffer() 和QRhi::resourceLimit()。
void QRhiResourceUpdateBatch::release()
将批处理归还至池中。此方法仅应在批处理未传递给QRhiCommandBuffer::beginPass()、QRhiCommandBuffer::endPass() 或QRhiCommandBuffer::resourceUpdate() 中的任意一个时使用,因为这些方法会隐式调用 destroy()。
注意: 应用程序绝不能将QRhiResourceUpdateBatch 实例通过deleted 进行销毁。
void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
将更新QRhiBuffer buf 中某个区域的操作加入队列,该区域由类型QRhiBuffer::Dynamic 创建。
该区域由offset 和size 指定。实际要写入的字节由data 指定,该区域必须至少有size 字节的可用空间。
data 该缓冲区已被复制,因此本函数返回后可安全地销毁或修改它。
注意:如果 涉及主机写入(例如在 updateDynamicBuffer() 中通常会发生这种情况,因为在大多数后端中此类缓冲区由主机可见内存支持),这些写入会在一帧内累积。因此,在第 1 阶段读取被传递给第 2 阶段的批处理所更改的区域时,可能会看到第 2 阶段更新批处理中指定的更改。
注意: QRhi 会透明地管理双缓冲机制,以防止图形管道停滞。当使用QRhi 和QRhiResourceUpdateBatch 时,可以安全地忽略QRhiBuffer 底层可能包含多个本机缓冲区对象这一事实。
[since 6.10] void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, QByteArray data)
将更新QRhiBuffer buf 中某个区域的操作加入队列,该区域由类型QRhiBuffer::Dynamic 创建。
data 通过此重载,数据会被移入批处理中,而非被复制。
这是一个重载函数。
该函数于 Qt 6.10 中引入。
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
将更新QRhiBuffer buf 中某个区域的操作加入队列,该区域是使用类型QRhiBuffer::Immutable 或QRhiBuffer::Static 创建的。
该区域由offset 和size 指定。实际要写入的字节由data 指定,该区域必须至少有size 字节的可用空间。
data 该数组已被复制,因此在本函数返回后,可安全地销毁或修改该数组。
[since 6.10] void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, QByteArray data)
将更新整个QRhiBuffer buf 的操作加入队列,该 是通过类型QRhiBuffer::Immutable 或QRhiBuffer::Static 创建的。
data 使用此重载时,数据会被移入批处理,而非被复制。
data size 必须等于buf 的大小。
这是一个重载函数。
该函数在 Qt 6.10 中引入。
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *data)
将更新整个QRhiBuffer buf 的任务加入队列,该 由类型QRhiBuffer::Immutable 或QRhiBuffer::Static 创建。
这是一个重载函数。
[since 6.10] void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, QByteArray data)
将更新QRhiBuffer buf 中某个区域的操作加入队列,该区域由类型QRhiBuffer::Immutable 或QRhiBuffer::Static 创建。
data 通过此重载,数据会被移入批处理中,而非被复制。
这是一个重载函数。
该函数在 Qt 6.10 中引入。
void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QImage &image)
将纹理tex 的第 0 层第 0 级 MIP 级别的图像数据加入上传队列。
tex 必须为未压缩格式。其格式还必须与image 中的QImage::format() 兼容。源数据详见image 。
void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
将纹理tex 中一个或多个图层的一个或多个 MIP 级别的图像数据加入上传队列。
复制操作的详细信息(源QImage 或压缩纹理数据、区域、目标图层和级别)在desc 中有详细说明。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.