本页内容

QRhiCommandBuffer 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
继承自: QRhiResource

公共类型

enum BeginPassFlag { ExternalContent, DoNotTrackResourcesForCompute }
flags BeginPassFlags
DynamicOffset
enum IndexFormat { IndexUInt16, IndexUInt32 }
VertexInput

公共函数

void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr, QRhiCommandBuffer::BeginPassFlags flags = {})
void beginExternal()
void beginPass(QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates = nullptr, QRhiCommandBuffer::BeginPassFlags flags = {})
void debugMarkBegin(const QByteArray &name)
void debugMarkEnd()
void debugMarkMsg(const QByteArray &msg)
void dispatch(int x, int y, int z)
void draw(quint32 vertexCount, quint32 instanceCount = 1, quint32 firstVertex = 0, quint32 firstInstance = 0)
void drawIndexed(quint32 indexCount, quint32 instanceCount = 1, quint32 firstIndex = 0, qint32 vertexOffset = 0, quint32 firstInstance = 0)
(since 6.12) void drawIndexedIndirect(QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride = sizeof(QRhiIndexedIndirectDrawCommand))
(since 6.12) void drawIndirect(QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride = sizeof(QRhiIndirectDrawCommand))
void endComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr)
void endExternal()
void endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr)
double lastCompletedGpuTime()
const QRhiNativeHandles *nativeHandles()
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates)
void setBlendConstants(const QColor &c)
void setComputePipeline(QRhiComputePipeline *ps)
void setGraphicsPipeline(QRhiGraphicsPipeline *ps)
void setScissor(const QRhiScissor &scissor)
void setShaderResources(QRhiShaderResourceBindings *srb = nullptr, int dynamicOffsetCount = 0, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets = nullptr)
(since 6.9) void setShadingRate(const QSize &coarsePixelSize)
void setStencilRef(quint32 refValue)
void setVertexInput(int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf = nullptr, quint32 indexOffset = 0, QRhiCommandBuffer::IndexFormat indexFormat = IndexUInt16)
void setViewport(const QRhiViewport &viewport)

重新实现的公共函数

virtual QRhiResource::Type resourceType() const override

详细说明

目前应用程序无法创建。获取有效 QRhiCommandBuffer 的唯一方法是通过QRhiSwapChain::currentFrameCommandBuffer() 从目标交换链中获取,或者在完全离屏渲染的情况下,通过QRhi::beginOffscreenFrame() 进行初始化。

注意:这是一个 兼容性保证有限的 RHI API,详情请参阅QRhi 。

成员类型文档

enum QRhiCommandBuffer::BeginPassFlag
flags QRhiCommandBuffer::BeginPassFlags

QRhi::beginPass() 的标志值

常量值描述
QRhiCommandBuffer::ExternalContent0x01指定本通过中将调用QRhiCommandBuffer::beginExternal()。某些后端(尤其是 Vulkan)若未设置此标志却仍调用beginExternal(),则会失败。
QRhiCommandBuffer::DoNotTrackResourcesForCompute0x02指定如果跟踪资源的唯一目的是为计算生成屏障,则无需跟踪本渲染通道中使用的资源。这意味着该帧中不存在计算通道。这是一个优化提示,某些后端(特别是 OpenGL)可能会将其纳入考虑,从而允许它们跳过某些操作。 当帧中的某个渲染阶段设置了此标志时,在该帧中调用 `beginComputePass()` 可能会导致意外行为,具体取决于渲染阶段与计算阶段之间的资源依赖关系。

BeginPassFlags 类型是QFlags<BeginPassFlag> 的 typedef。它存储 BeginPassFlag 值的按“或”运算组合。

[alias] QRhiCommandBuffer::DynamicOffset

std::pair<int, quint32> 的同义词。第一个条目是绑定,第二个是缓冲区中的偏移量。

enum QRhiCommandBuffer::IndexFormat

指定索引的数据类型

常量值描述
QRhiCommandBuffer::IndexUInt160无符号 16 位(quint16)
QRhiCommandBuffer::IndexUInt321无符号 32 位 (quint32)

[alias] QRhiCommandBuffer::VertexInput

std::pair<QRhiBuffer *, quint32> 的同义词。第二个元素是第一个元素指定的缓冲区中的偏移量。

成员函数文档

void QRhiCommandBuffer::beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr, QRhiCommandBuffer::BeginPassFlags flags = {})

记录开始一个新的计算轮次。

resourceUpdates,当不为空时,指定一个待提交并随后释放的资源更新批处理。

注意:请 勿假设任何状态或资源绑定会在不同计算轮次之间持续存在。

注意:一个 计算通道可以记录setComputePipeline()、setShaderResources() 和dispatch() 调用,但不包括图形调用。一般功能(例如调试标记和beginExternal())在渲染通道和计算通道中均可用。

注意: 仅当报告支持Compute 功能时,计算阶段 才可用。

flags 目前未被使用。

void QRhiCommandBuffer::beginExternal()

当前一个应用程序即将通过直接调用图形 API 函数,将命令入队到当前遍历的命令缓冲区时,调用此函数。

注意:此功能 仅在通过beginPass() 或beginComputePass() 预先声明该意图时可用。因此,仅当通过指定QRhiCommandBuffer::ExternalContent 启动渲染通道录制时,才应调用此函数。

在 Vulkan、Metal 或 Direct3D 12 中,可以通过nativeHandles() 查询原生命令缓冲区或编码器对象,并将命令加入其队列。在 OpenGL 或 Direct3D 11 中,可以从QRhi::nativeHandles() 获取(设备)上下文。 但是,在执行此操作时,必须确保QRhiCommandBuffer 的状态始终保持最新。因此,要求将任何外部添加的命令记录封装在beginExternal()和endExternal()之间。从概念上讲,这与QPainter 中的beginNativePainting()和endNativePainting()函数相同。

对于 OpenGL 而言,该函数还承担一项额外任务:确保该渲染上下文在当前线程中被设为活动上下文。

注意:一旦 调用 beginExternal(),在调用endExternal() 之前,不得在QRhiCommandBuffer 上调用任何其他渲染阶段特定函数(如set* 或draw* )。

警告:某些 后端在 beginExternal() -endExternal() 代码块内调用QRhiCommandBuffer::nativeHandles() 时,返回的原生命令缓冲区对象可能与主命令缓冲区对象不同。因此,在调用 beginExternal() 之后,务必(重新)查询原生命令缓冲区对象。 具体而言,这意味着以 Vulkan 为例,外部记录的 Vulkan 命令会被放置到一个辅助命令缓冲区中(带有 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)。当在 begin/endExternal 之间调用nativeHandles() 时,该函数会返回此辅助命令缓冲区。

另请参阅 endExternal() 和nativeHandles()。

void QRhiCommandBuffer::beginPass(QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates = nullptr, QRhiCommandBuffer::BeginPassFlags flags = {})

记录针对渲染目标rt 开始的新渲染迭代。

resourceUpdates,当该值不为空时,指定一个资源更新批次,该批次将被提交并随后释放。

渲染目标的颜色和深度/模板缓冲区通常会被清空。清空值在colorClearValue 和depthStencilClearValue 中指定。例外情况是当渲染目标使用QRhiTextureRenderTarget::PreserveColorContents 和/或QRhiTextureRenderTarget::PreserveDepthStencilContents 创建时,此时将忽略清空值。

注意:启用 保留颜色或深度内容会导致性能下降,具体程度取决于底层硬件。采用瓦片架构的移动端 GPU 因无需将先前内容重新加载到瓦片缓冲区中,因此能从中受益。 同样地,使用QRhiTexture 作为深度缓冲区的QRhiTextureRenderTarget (渲染目标)效率低于QRhiRenderBuffer ,因为使用深度纹理会触发将数据写入纹理的需求,而渲染缓冲区则无需此操作(因为API不允许从渲染缓冲区采样或读取数据)。

注意:请 勿假设任何状态或资源绑定会在渲染通道之间保持不变。

注意: QRhiCommandBuffer的 set 和draw 函数只能在渲染通道内部调用。此外,除setGraphicsPipeline() 之外,这些函数 要求命令缓冲区中已设置好渲染管线。否则,根据后端不同,可能会出现未定义的问题。

如果rt 是QRhiTextureRenderTarget ,则 beginPass() 会进行检查,以确认渲染目标所引用的纹理和渲染缓冲区对象是否为最新版本。 这类似于setShaderResources()对QRhiShaderResourceBindings 所执行的操作。如果自QRhiTextureRenderTarget::create()以来任何附件已被重建,则会对rt 隐式调用create()。因此,如果rt 有一个QRhiTexture 颜色附件texture ,且需要将纹理调整为不同尺寸,则以下操作是有效的:

QRhiTextureRenderTarget *rt = rhi->newTextureRenderTarget({ { texture } });
rt->create();
// ...
texture->setPixelSize(new_size);
texture->create();
cb->beginPass(rt, colorClear, dsClear); // this is ok, no explicit rt->create() is required before

flags 允许控制某些高级功能。一个常用的标志是ExternalContents 。每当在由该函数启动的渲染通道内调用beginExternal() 时,都应指定此标志。

另请参阅 endPass() 和BeginPassFlags 。

void QRhiCommandBuffer::debugMarkBegin(const QByteArray &name)

在命令缓冲区中记录一个命名调试组,并使用指定的name 。该信息会在RenderDoc和XCode等图形调试工具中显示。分组的结束由debugMarkEnd()表示。

注意: 当不支持QRhi::DebugMarkers 或未设置QRhi::EnableDebugMarkers 时,该操作将被忽略 。

注意:可在 帧内的任何位置调用,无论是在渲染通道内部还是外部。

void QRhiCommandBuffer::debugMarkEnd()

记录调试组的结束。

注意: 当不支持QRhi::DebugMarkers 或未设置QRhi::EnableDebugMarkers 时,此指令将被忽略 。

注意:可在 帧内的任意位置调用,无论是在处理阶段内部还是外部。

void QRhiCommandBuffer::debugMarkMsg(const QByteArray &msg)

将调试消息msg 插入到命令流中。

注意: 当不支持QRhi::DebugMarkers 或未设置QRhi::EnableDebugMarkers 时,该操作将被忽略 。

注意:在 某些后端中 ,debugMarkMsg() 仅在处理阶段内部受支持,若在处理阶段外部调用则会被忽略。而在其他后端中,该消息会在帧内的任意位置被记录。

void QRhiCommandBuffer::dispatch(int x, int y, int z)

记录了计算工作项的调度情况,其中x 、y 和z 分别指定了相应维度中的本地工作组数量。

注意:此 函数只能在计算通过内调用,即在beginComputePass() 和endComputePass() 调用之间。

注意: x 、y 和z 在运行时必须符合底层图形 API 实现的限制。最大值通常为 65535。

注意:还需注意 本地工作组大小的可能限制。这在着色器中指定,例如:layout(local_size_x = 16, local_size_y = 16) in; 。例如,在 OpenGL 中,规范规定单个本地工作组中的调用次数(即local_size_x 、local_size_y 和local_size_z 的乘积)的最小值为 1024,而在 OpenGL ES (3.1) 中,该值可能低至 128。 这意味着,由于上述示例中的调用次数为 256,某些 OpenGL ES 实现可能会拒绝该示例。

void QRhiCommandBuffer::draw(quint32 vertexCount, quint32 instanceCount = 1, quint32 firstVertex = 0, quint32 firstInstance = 0)

记录一个未索引的绘制操作。

顶点数量在vertexCount 中指定。若需进行实例化绘制,请将instanceCount 设置为1以外的值。firstVertex 是待绘制第一个顶点的索引。绘制多个实例时,第一个实例ID由firstInstance 指定。

注意: firstInstance 可能不被支持,且当QRhi::BaseInstance 功能被报告为不支持时,该参数将被忽略。在这种情况下,第一个实例 ID 始终为 0。目前 OpenGL 完全不支持QRhi::BaseInstance ,这主要是由于 OpenGL ES 的限制,因此可移植的应用程序不应设计为依赖此参数。

注意: 需要访问当前顶点或实例索引的着色器 必须使用gl_VertexIndex 和gl_InstanceIndex (即与 Vulkan 兼容的内置变量),而不是gl_VertexID 和gl_InstanceID 。

注意:当 firstInstance 不为零时,在某些底层 3D API 中,gl_InstanceIndex 不会包含基值。这一点由QRhi::InstanceIndexIncludesBaseInstance 特性所指示。如果无法避免依赖实例的基值,建议应用程序根据该特性报告的结果,有条件地将该值作为统一变量(uniform)传递,并在着色器中将其加到gl_InstanceIndex 上。

注意:此 函数只能在渲染通道内调用,即在beginPass()与endPass()调用之间。

void QRhiCommandBuffer::drawIndexed(quint32 indexCount, quint32 instanceCount = 1, quint32 firstIndex = 0, qint32 vertexOffset = 0, quint32 firstInstance = 0)

记录一次带索引的绘制操作。

顶点数量在 `indexCount` 中指定。`firstIndex ` 是基索引。索引缓冲区中的有效偏移量由 `indexOffset + firstIndex * n ` 给出,其中 `n ` 根据索引元素类型为 2 或 4。`indexOffset ` 在 `setVertexInput()` 中指定。

注意: 对于某些后端(例如 Metal),索引缓冲区中的有效偏移量 必须对齐到 4 字节。在这些后端中,NonFourAlignedEffectiveIndexBufferOffset 功能将被报告为不支持。

vertexOffset (也称为base vertex )是一个有符号值,在将元素索引到顶点缓冲区之前会将其加到元素索引上。此功能并非总是受支持,当QRhi::BaseVertex 功能被报告为不支持时,该值将被忽略。

对于实例化绘制,请将instanceCount 设置为 1 以外的值。在绘制多个实例时,第一个实例 ID 由firstInstance 指定。

注意: firstInstance 可能不受支持,当QRhi::BaseInstance 功能被报告为不支持时,该参数将被忽略。在这种情况下,第一个实例 ID 始终为 0。目前 OpenGL 完全不支持QRhi::BaseInstance ,这主要是由于 OpenGL ES 的限制,因此可移植的应用程序不应依赖此参数。

注意: 需要访问当前顶点或实例索引的着色器 必须使用gl_VertexIndex 和gl_InstanceIndex (即与 Vulkan 兼容的内置变量),而不是gl_VertexID 和gl_InstanceID 。

注意:当 firstInstance 不为零时,在某些底层 3D API 中,gl_InstanceIndex 不会包含基值。这由QRhi::InstanceIndexIncludesBaseInstance 特性所指示。如果无法避免依赖实例的基值,建议应用程序根据该特性报告的结果,有条件地将该值作为统一变量(uniform)传入,并在着色器中将其加到gl_InstanceIndex 中。

注意:该 函数只能在渲染通道内调用,即在beginPass()和endPass()调用之间。

[since 6.12] void QRhiCommandBuffer::drawIndexedIndirect(QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride = sizeof(QRhiIndexedIndirectDrawCommand))

记录一个带索引的间接绘制操作。

绘制参数由indirectBuffer 中指定的缓冲区提供,该缓冲区必须包含一个类型为QRhiIndexedIndirectDrawCommand 的元素数组。QRhiIndexedIndirectDrawCommand 中的参数含义与drawIndexed()中的相同。

indirectBufferOffset 指定了从缓冲区中读取参数的起始偏移量(以字节为单位)。

drawCount 指定要发出的此类绘制命令的数量。

stride 指定缓冲区中每个绘制命令结构的字节大小。这允许在需要时在命令之间穿插自定义数据。该值必须是4的倍数,且大于或等于 sizeof(QRhiIndexedIndirectDrawCommand)。

注意: 只有当报告支持QRhi::DrawIndirectMulti 功能且stride为默认值时,drawCount 的值 大于1才受原生支持。否则,该函数通过记录多个绘制调用来自行模拟多绘制,与重复调用drawIndexed()相比并无性能优势。

注意:此 函数只能在渲染通道内调用,即在beginPass() 和endPass() 调用之间。

该函数于 Qt 6.12 中引入。

[since 6.12] void QRhiCommandBuffer::drawIndirect(QRhiBuffer *indirectBuffer, quint32 indirectBufferOffset, quint32 drawCount, quint32 stride = sizeof(QRhiIndirectDrawCommand))

记录一个未索引的间接绘制操作。

读取参数由indirectBuffer 中指定的缓冲区提供,该缓冲区必须包含一个类型为QRhiIndirectDrawCommand 的元素数组。QRhiIndirectDrawCommand 中的参数含义与draw()中的相同。

indirectBufferOffset 指定了从缓冲区中读取参数时的偏移量(以字节为单位)。

drawCount 指定要发出的此类绘制命令的数量。

stride 指定缓冲区中每个绘制命令结构的字节大小。这允许在需要时在命令之间穿插自定义数据。该值必须是 4 的倍数,且大于或等于 sizeof(QRhiIndirectDrawCommand)。

注意: 只有当报告支持QRhi::DrawIndirectMulti 功能且stride为默认值时,drawCount 的值 大于1才受原生支持。否则,该函数通过记录多个绘制调用模拟多绘制,与重复调用draw()相比并无性能优势。

注意:此 函数只能在渲染阶段内调用,即在beginPass() 和endPass() 调用之间。

该函数于 Qt 6.12 中引入。

void QRhiCommandBuffer::endComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr)

结束当前计算周期的记录。

resourceUpdates,当该值不为空时,指定一个资源更新批次,该批次将被提交并随后释放。

void QRhiCommandBuffer::endExternal()

当外部添加的命令被记录到命令缓冲区或上下文中后,将调用此函数。

注意: 调用此函数后,必须将所有 QRhiCommandBuffer 状态视为无效。如果在外部命令之后还记录了更多的绘制调用,则必须重新设置管线、顶点和索引缓冲区以及其他状态。

另请参阅 beginExternal() 和nativeHandles()。

void QRhiCommandBuffer::endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr)

结束当前渲染周期的记录。

resourceUpdates,当该值不为空时,指定一个待提交并随后释放的资源更新批次。

另请参阅 beginPass()。

double QRhiCommandBuffer::lastCompletedGpuTime()

返回在创建QRhi 时启用了QRhi::EnableTimestamps 功能时的最后一个可用时间戳(单位为秒)。该值表示在最后一个完成的帧期间,GPU上经过的时间。

注意: 当QRhi::Timestamps 功能未被报告为受支持,或者未将QRhi::EnableTimestamps 传递给QRhi::create()时,请 勿期望结果为0以外的数值。 虽然存在例外情况——某些图形 API(如 Metal)无需执行额外操作(时间戳查询)即可获取计时数据——但可移植的应用程序在确认需要时,应始终有意识地选择启用时间戳收集,并据此调用此函数。

在解释该值时必须谨慎,因为其精度和粒度通常不受 Qt 控制,而是取决于底层图形 API 及其实现。特别是,不建议比较不同图形 API 和硬件之间的值,此类比较可能毫无意义。

计时值很可能以异步方式提供。因此,返回值可能是 0(例如,在前 1-2 帧时),也可能是指代某个先前帧的最后已知值。 在某些情况下(例如调整窗口大小时),该值也可能再次变为 0。通常情况下,在 beginFrame() 中会获取最新的可用值,并且一旦 beginFrame() 返回,即可通过此函数查询该值。

注意:请 勿假设该值对应于上一帧(currently_recorded - 1 )。它也可能对应于currently_recorded - 2 或currently_recorded - 3 。具体行为可能取决于图形 API 及其实现方式。

请注意,根据平台的不同,GPU 频率调节和 GPU 时钟变化可能带来的影响。例如,在 Windows 系统上,使用现代显卡时,即使提交的工作负载相似或相同,不同帧之间返回的时序也可能存在相当大的波动。一般而言,这超出了 Qt 的控制和解决范围。 不过,当环境变量QT_D3D_STABLE_POWER_STATE 被设置为非零值时,D3D12后端会自动调用ID3D12Device::SetStablePowerState()。 这可以大大稳定结果。它还可能对通过QElapsedTimer 测量的 CPU 侧计时产生非同小可的影响,特别是在涉及离屏帧时。

注意:切勿 在QT_D3D_STABLE_POWER_STATE 设置为有效状态时将应用程序部署到生产环境。详情请参阅Windows API文档。

另请参阅 QRhi::Timestamps 和QRhi::EnableTimestamps 。

const QRhiNativeHandles *QRhiCommandBuffer::nativeHandles()

返回一个指向后端特定QRhiNativeHandles 子类的指针,例如QRhiVulkanCommandBufferNativeHandles 。当后端不支持或不适用于暴露底层本机资源时,返回值为nullptr 。

另请参阅 QRhiVulkanCommandBufferNativeHandles 、QRhiMetalCommandBufferNativeHandles 、beginExternal() 以及endExternal()。

[override virtual] QRhiResource::Type QRhiCommandBuffer::resourceType() const

重写:QRhiResource::resourceType() const。

返回资源类型。

void QRhiCommandBuffer::resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates)

有时,在不启动渲染阶段的情况下提交资源更新是必要的,或者只是更方便。使用resourceUpdates 调用此函数,是向beginPass()调用(或endPass()调用,后者在读回情况下较为常见)传入resourceUpdates 的替代方案。

注意:不能 在渲染通道内部调用此函数。

void QRhiCommandBuffer::setBlendConstants(const QColor &c)

将活动混合常数设置为c 的记录。

只有当绑定的管道已设置QRhiGraphicsPipeline::UsesBlendConstants 时,才能调用此函数。

注意:此 函数只能在渲染通道内调用,即在beginPass()和endPass()调用之间。

void QRhiCommandBuffer::setComputePipeline(QRhiComputePipeline *ps)

记录设置新的计算管道ps 。

注意: 必须在命令缓冲区中记录setShaderResources() 或dispatch() 命令之前调用此 函数。

注意: QRhi 会优化掉同一计算通道内不必要的调用,因此应用程序无需为了避免调用此函数而进行过度优化。

注意:该 函数只能在计算通过内调用,即在beginComputePass() 和endComputePass() 调用之间。

void QRhiCommandBuffer::setGraphicsPipeline(QRhiGraphicsPipeline *ps)

记录设置新的图形管道ps 。

注意: 在命令缓冲区中记录其他set 或draw 命令之前,必须先调用此 函数。

注意: QRhi 会优化掉同一渲染通道内不必要的调用,因此应用程序方面无需为了避免调用此函数而过度优化。

注意:此 函数只能在渲染通道内调用,即在beginPass() 和endPass() 调用之间。

注意: 新的图形管道ps 必须是一个有效的指针。

设置一个不带UsesScissor 标志的图形管道,将在适用剪切功能的图形 API 中禁用剪切,或者将剪切矩形设置为与上次设置的视口匹配(在剪切功能实际上始终处于活动状态的图形 API 中),以确保在QRhi 后端之间保持一致的行为。

void QRhiCommandBuffer::setScissor(const QRhiScissor &scissor)

该函数用于设置在scissor 中指定的活动剪切矩形。

仅当绑定管道设置了UsesScissor 时,才可调用此函数。当活动管道上设置了该标志时,必须调用此函数,因为剪切测试将被启用,因此必须提供一个剪切矩形。

注意: QRhi 采用 OpenGL 风格的视口坐标系,即 x 和 y 坐标以左下角为原点。

注意:此 函数只能在渲染通道内调用,即在beginPass()和endPass()调用之间。

void QRhiCommandBuffer::setShaderResources(QRhiShaderResourceBindings *srb = nullptr, int dynamicOffsetCount = 0, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets = nullptr)

将一组着色器资源(例如,统一缓冲区或纹理)绑定在一起的记录,这些资源对一个或多个着色器阶段可见。

srb 该参数可以为空,此时将使用当前图形或计算管道关联的QRhiShaderResourceBindings 。当srb 不为空时,它必须是layout-compatible ,这意味着其布局(绑定数量、每个绑定的类型及绑定编号)必须与调用管道create()时关联的QRhiShaderResourceBindings 完全匹配。

在某些情况下,看似不必要的 setShaderResources() 调用是强制要求的:例如在重建由srb 引用的资源时,如先更改QRhiBuffer 的大小,随后调用QRhiBuffer::create(), 此时,关联的原生对象(例如 Vulkan 中的描述符集)会在此处更新,以指向当前支持QRhiBuffer 、QRhiTexture 、QRhiSampler 对象的原生资源,这些对象由srb 引用。在此情况下,即使srb 与上次调用时相同,也必须调用 setShaderResources()。

当srb 不为空时,保证在 create() 中用于构建管道的QRhiShaderResourceBindings 对象不会以任何形式被访问。事实上,此时该对象甚至无需有效:在 create() 之后销毁管道关联的 srb,并在每次 setShaderResources() 调用中显式指定另一个layout compatible 对象,这种做法是有效的。

dynamicOffsets 允许为通过 `QRhiShaderResourceBinding::uniformBufferWithDynamicOffset()` 与 `srb ` 关联的统一缓冲区指定缓冲区偏移量。这与在 `srb ` 本身中提供偏移量不同:动态偏移量无需为每个不同的偏移量构建新的 `QRhiShaderResourceBindings `,可以避免写入底层描述符(在适用的后端中),因此可能更高效。dynamicOffsets 的每个元素都是一个binding -offset 对。dynamicOffsetCount 指定了dynamicOffsets 中的元素个数。

注意: dynamicOffsets 中的所有 偏移量必须按字节对齐到QRhi::ubufAlignment()返回的值。

注意:某些 后端可能会限制支持的动态偏移量数量。请避免使用大于 8 的dynamicOffsetCount 。

注意: QRhi 会在单个渲染通道内优化掉不必要的调用(同时考虑上述条件),因此应用程序端无需过度优化以避免调用此函数。

注意:此 函数只能在渲染或计算阶段内部调用,即在beginPass()与endPass()之间,或beginComputePass()与endComputePass()之间。

[since 6.9] void QRhiCommandBuffer::setShadingRate(const QSize &coarsePixelSize)

将后续绘制调用的着色速率设置为coarsePixelSize 。

默认值为 1x1。

仅当报告支持QRhi::VariableRateShading 功能,且命令缓冲区中绑定的QRhiGraphicsPipeline 在创建时声明了QRhiGraphicsPipeline::UsesShadingRate 时,此功能才有效。

调用QRhi::supportedShadingRates() 可检查给定采样数下支持哪些着色速率。

当同时使用 `QRhiShadingRateMap ` 和本函数时,每个瓦片将采用两者中较高的着色速率。目前无法控制组合器的行为。

该函数于 Qt 6.9 中引入。

void QRhiCommandBuffer::setStencilRef(quint32 refValue)

将活动模板参考值设置为refValue 的记录。

只有当已绑定的管道设置了QRhiGraphicsPipeline::UsesStencilRef 时,才能调用此函数。

注意:此 函数只能在渲染通道内调用,即在beginPass()和endPass()调用之间。

void QRhiCommandBuffer::setVertexInput(int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf = nullptr, quint32 indexOffset = 0, QRhiCommandBuffer::IndexFormat indexFormat = IndexUInt16)

记录顶点输入绑定。

后续drawIndexed() 命令所使用的索引缓冲区由indexBuf 、indexOffset 和indexFormat 指定。当不需要索引绘制时,indexBuf 可设置为 null。

顶点缓冲区绑定是批量处理的。startBinding 指定第一个绑定编号。随后,记录的命令会将bindings 中的每个缓冲区绑定到绑定点startBinding + i ,其中i 是bindings 中的索引。bindings 中的每个元素指定一个QRhiBuffer 和一个偏移量。

注意:某些 后端可能会限制顶点缓冲区绑定的数量。请避免使用大于 8 的bindingCount 。

在同一渲染通道中多余的顶点输入和索引更改会被大多数后端自动忽略,因此应用程序无需过度优化以避免调用此函数。

注意:此 函数只能在渲染通道内调用,即在beginPass() 和endPass() 调用之间。

举一个简单的例子,假设有一个具有两个输入的顶点着色器:

layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;

并假设数据以交错格式提供,仅使用 2 个浮点数表示位置(即每个顶点 5 个浮点数:x、y、r、g、b)。然后可以使用以下输入布局为该着色器创建一个QRhiGraphicsPipeline :

QRhiVertexInputLayout inputLayout;
inputLayout.setBindings({
    { 5 * sizeof(float) }
});
inputLayout.setAttributes({
    { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
    { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
});

这里有一个缓冲区绑定(绑定编号为 0),有两个输入引用它。在录制渲染通道时,一旦管道设置完成,可以像下面这样简单地指定顶点绑定,假设 vbuf 是包含所有交错位置+颜色数据的QRhiBuffer :

const QRhiCommandBuffer::VertexInput vbufBinding(vbuf, 0);
cb->setVertexInput(0, 1, &vbufBinding);

void QRhiCommandBuffer::setViewport(const QRhiViewport &viewport)

该函数用于设置在viewport 中指定的活动视口矩形。

对于底层图形 API 始终启用剪切功能的后端,当活动QRhiGraphicsPipeline 未设置UsesScissor 时,此函数还会将剪切范围设置为与视口匹配。

注意: QRhi 采用 OpenGL 风格的视口坐标系,即 x 和 y 坐标以左下角为原点。

注意:此 函数只能在渲染通道内调用,即在beginPass() 和endPass() 调用之间。

© 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.