QRhiResourceUpdateBatch 类

记录上传和复制类型的操作。 更多...

头文件 #include <QRhiResourceUpdateBatch>
CMakefind_package(Qt6 REQUIRED COMPONENTS Gui)
target_link_libraries(mytarget PRIVATE Qt6::Gui)
qmakeQT += gui
Qt 6.6

公共函数

voidcopyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription())
voidgenerateMips(QRhiTexture *tex)
boolhasOptimalCapacity() const
voidmerge(QRhiResourceUpdateBatch *other)
voidreadBackBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, QRhiReadbackResult *result)
voidreadBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
void释放()
voidupdateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
voiduploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
voiduploadStaticBuffer(QRhiBuffer *buf, const void *data)
voiduploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
voiduploadTexture(QRhiTexture *tex, const QImage &image)

详细描述

使用 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中,数据按原样复制,无需格式转换。如果 dstsrc 使用不同的格式创建,可能会出现未知的问题。

void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex)

为指定的纹理 tex 队列一个生成MIP贴图的操作。

支持2D和立方体贴图。

注意:纹理必须使用 QRhiTexture::MipMappedQRhiTexture::UsedWithGenerateMips 创建。

警告:QRhi 不能保证所有支持的纹理格式都可以生成MIP贴图。例如,QRhiTexture::RGBA32F 在OpenGL ES 3.0和iOS上的Metal中不是一个 filterable 格式,因此MIP贴图生成请求可能会失败。RGBA8和RGBA16F通常是filterable的,因此在需要生成MIP贴图时推荐使用这些格式。

bool QRhiResourceUpdateBatch::hasOptimalCapacity() const

当在当前批次中排队等候的缓冲区和纹理操作的数量低于合理限制时,返回true。

当添加到当前批次的缓冲区和/或纹理操作的数量达到或即将达到某一限制时,将返回false。此后,批次仍然完全功能正常,但可能需要分配额外的内存。因此,当准备帧时在一个批次中收集大量缓冲区和纹理更新的渲染器可能想要在函数返回false时考虑 提交批次启动一个新的批次

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将为空。

注意:仅当报告支持QRhiBuffer::UniformBuffer之外的使用情况时,才支持读取QRhi::ReadBackNonUniformBuffer特征。

注意:异步读取操作保证在满足以下条件之一时完成:已调用finish();或者,至少已提交N帧,包括发出读取操作的那帧,且已开始记录新帧,其中N是返回给QRhi::MaxAsyncReadbackFrames资源限制值

另请参阅:readBackTexture(),QRhi::isFeatureSupported()和QRhi::resourceLimit()。

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

按照rb所述,将纹理到主机复制操作入队。

通常,rb将指定QRhiTexture作为源。但是,当当前帧的swapchain使用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创建纹理。

注意:不能读取多采样纹理。

注意:读取返回原始字节数据,以便允许应用程序以任何方式解释它。注意渲染代码的混合设置:如果混合设置为依赖于预乘alpha,则读取的结果必须也解释为预乘。

注意:在解释生成的原始数据时,请注意读取操作是在字节序格式下进行的。因此,RGBA8纹理映射到字节序QImage格式,如QImage::Format_RGBA8888

注意:异步读取操作保证在满足以下条件之一时完成:已调用finish();或者,至少已提交N帧,包括发出读取操作的那帧,且已开始记录新帧,其中N是返回给QRhi::MaxAsyncReadbackFrames资源限制值

单个读取操作一次复制一个层的单个MIP级别(立方体贴面或3D切片或纹理数组元素)。级别和层分别由rb中的相应字段指定。

另请参阅:readBackBuffer()和QRhi::resourceLimit

void QRhiResourceUpdateBatch::release()

将批次返回到池中。这仅应在使用批次时未将其传递给QRhiCommandBuffer::beginPass(),QRhiCommandBuffer::endPass()或QRhiCommandBuffer::resourceUpdate()时使用,因为这些隐式调用destroy()。

注意:不得由应用程序删除 QRhiResourceUpdateBatch实例。

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

将更新由类型 QRhiBuffer::Dynamic 创建的 QRhiBuffer buf 中的区域的更新任务加入队列。

该区域由 offsetsize 指定。实际要写入的字节由 data 指定,它必须至少有 size 个字节可用的空间。在该函数返回后,可以安全地销毁或更改 data

注意:如果涉及主机写入,这对于通常作为在大多数后端由可见主机内存支持的缓冲区而言是这种情况,写入可能会在整个帧中累积。因此,在第 2 阶段传递给第 1 阶段的批次中更改的区域可能会在第 2 阶段的更新批次中看到更改。

注意:QRhi 无缝管理双缓冲,以防止图形管道停顿。当使用 QRhiQRhiResourceUpdateBatch 时,可以安全地忽略 QRhiBuffer 可能拥有的多个原生缓冲区对象。

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

将更新由类型 QRhiBuffer::ImmutableQRhiBuffer::Static 创建的 QRhiBuffer buf 中的区域的更新任务加入队列。

该区域由 offsetsize 指定。实际要写入的字节由 data 指定,它必须至少有 size 个字节可用的空间。在该函数返回后,可以安全地销毁或更改 data

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

将更新由类型 QRhiBuffer::ImmutableQRhiBuffer::Static 创建的整个 QRhiBuffer buf 的更新任务加入队列。

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

将上传一个或多个纹理的一级或多层图像数据的更新任务加入队列。

复制的详细信息(源 QImage 或压缩纹理数据、区域、目标层和级别)在 desc 中描述。

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

将上传纹理 tex 层 0 级别 0 的 0 级别图像数据的更新任务加入队列。

tex 必须有一个非压缩格式。它的格式还必须与 imageQImage::format() 兼容。源数据在 image 中给出。

© 2024 Qt公司有限公司。本文件包含的文档贡献版权归各自所有者所有。提供的文档受自由软件基金会发布的GNU自由文档许可协议(FDL)版本1.3的许可条款约束。Qt及其相关标志是芬兰和/或其他国家Qt公司有限公司的商标。所有其他商标均为各自所有者的财产。