Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
QRhiIndirectCommandBuffer Class Referenceabstract

\variable QRhiDispatchIndirectCommand::x More...

#include <qrhi.h>

Inheritance diagram for QRhiIndirectCommandBuffer:
Collaboration diagram for QRhiIndirectCommandBuffer:

Public Types

enum  Type { Draws , IndexedDraws }
 Specifies the kind of commands an indirect command buffer holds. More...
Public Types inherited from QRhiResource
enum  Type {
  Buffer , Texture , Sampler , RenderBuffer ,
  RenderPassDescriptor , SwapChainRenderTarget , TextureRenderTarget , ShaderResourceBindings ,
  GraphicsPipeline , SwapChain , ComputePipeline , CommandBuffer ,
  ShadingRateMap , IndirectCommandBuffer
}
 Specifies type of the resource. More...

Public Member Functions

QRhiResource::Type resourceType () const override
Type type () const
void setType (Type t)
 Sets the command type t.
quint32 maxCommandCount () const
void setMaxCommandCount (quint32 count)
 Sets the capacity, the maximum number of commands, to count.
virtual bool create ()=0
 Creates the corresponding native objects.
void clear ()
 Discards all commands recorded so far.
void draw (quint32 vertexCount, quint32 instanceCount=1, quint32 firstVertex=0, quint32 firstInstance=0)
 Records a non-indexed draw command with vertexCount, instanceCount, firstVertex, and firstInstance.
void drawIndexed (quint32 indexCount, quint32 instanceCount=1, quint32 firstIndex=0, qint32 vertexOffset=0, quint32 firstInstance=0)
 Records an indexed draw command with indexCount, instanceCount, firstIndex, vertexOffset, and firstInstance.
quint32 recordedCommandCount () const
bool isGpuBuilt () const
quint32 commandCount () const
Public Member Functions inherited from QRhiResource
virtual ~QRhiResource ()
 Destructor.
virtual void destroy ()=0
 Releases (or requests deferred releasing of) the underlying native graphics resources.
void deleteLater ()
 When called without a frame being recorded, this function is equivalent to deleting the object.
QByteArray name () const
void setName (const QByteArray &name)
 Sets a name for the object.
quint64 globalResourceId () const
QRhirhi () const

Protected Member Functions

 QRhiIndirectCommandBuffer (QRhiImplementation *rhi, Type type_, quint32 maxCommandCount_)
Protected Member Functions inherited from QRhiResource
 QRhiResource (QRhiImplementation *rhi)

Protected Attributes

Type m_type
quint32 m_maxCommandCount
QByteArray m_data
quint32 m_commandCount = 0
quint64 m_generation = 0
bool m_gpuBuilt = false
quint32 m_gpuBuiltCommandCount = 0
Protected Attributes inherited from QRhiResource
QRhiImplementationm_rhi = nullptr
quint64 m_id
QByteArray m_objectName

Detailed Description

\variable QRhiDispatchIndirectCommand::x

\variable QRhiDispatchIndirectCommand::y

\variable QRhiDispatchIndirectCommand::z

\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h

Since
6.13

A prerecorded batch of indirect draw commands.

A QRhiIndirectCommandBuffer holds a number of draw commands that are recorded once and can then be replayed any number of times with a single QRhiCommandBuffer::executeIndirect() call. It is an alternative to the buffer-based QRhiCommandBuffer::drawIndirect() family of functions. Under the hood, it may do exactly the same as does (typical with Vulkan, Direct 3D, and OpenGL), or may be implemented differently (Metal).

Create one with QRhi::newIndirectCommandBuffer(), passing in the type and the maximum number of commands, and call create(). The (maximum) command count is mandatory, whichever way the commands are going to be provided: it is the capacity of the object, and create() fails when it is 0.

\badcode icb = rhi->newIndirectCommandBuffer(QRhiIndirectCommandBuffer::IndexedDraws, 1024); if (!icb->create()) { error(); }

Record commands with draw() or drawIndexed(), then hand the object to a resource update batch so that the recorded contents reach the GPU. commitIndirectCommandBuffer() has to be called after recording and before the pass that executes the commands. It is a no-op when nothing changed since the last time, so calling it every frame is cheap.

Executing happens inside a render pass:

\badcode icb->clear(); for (const Item &item : items) icb->drawIndexed(item.indexCount, 1, item.firstIndex, item.vertexOffset);

QRhiResourceUpdateBatch *u = rhi->nextResourceUpdateBatch(); u->commitIndirectCommandBuffer(icb);

cb->beginPass(rt, Qt::black, { 1.0f, 0 }, u); cb->setGraphicsPipeline(ps); cb->setVertexInput(0, 1, &vbufBinding, ibuf, 0, QRhiCommandBuffer::IndexUInt16); cb->setShaderResources(); cb->executeIndirect(icb); cb->endPass();

The commands can also be generated on the GPU instead of being recorded on the CPU. In that case fill a buffer with QRhiIndirectDrawCommand or QRhiIndexedIndirectDrawCommand entries from a compute shader, and call QRhiCommandBuffer::buildIndirect() with that buffer. That call must happen outside of any pass. The CPU-side recording functions of QRhiIndirectCommandBuffer are not used in this case.

\badcode cb->beginComputePass(); ... // a cb->dispatch() to invoke a compute shader that writes to indirectBuf cb->endComputePass();

QRhiIndirectCommandBufferBuildInfo buildInfo; buildInfo.topology = ps->topology(); buildInfo.sourceBuffer = indirectBuf; buildInfo.commandCount = itemCount; // as many as the compute shader wrote buildInfo.indexBuffer = indexBuffer; buildInfo.indexFormat = QRhiCommandBuffer::IndexUInt16; cb->buildIndirect(icb, buildInfo);

cb->beginPass(rt, Qt::black, { 1.0f, 0 }); cb->setGraphicsPipeline(ps); cb->setVertexInput(0, 1, &vbufBinding, ibuf, 0, QRhiCommandBuffer::IndexUInt16); cb->setShaderResources(); cb->executeIndirect(icb); cb->endPass();

When the number of commands is itself decided on the device, set QRhiIndirectCommandBufferBuildInfo::countBuffer instead of working out itemCount on the CPU. See \l{Command counts} below.

Definition at line 1738 of file qrhi.h.

Member Enumeration Documentation

◆ Type

Specifies the kind of commands an indirect command buffer holds.

\value Draws Non-indexed draw commands, recorded with draw(). \value IndexedDraws Indexed draw commands, recorded with drawIndexed().

Enumerator
Draws 
IndexedDraws 

Definition at line 1741 of file qrhi.h.

Constructor & Destructor Documentation

◆ QRhiIndirectCommandBuffer()

QRhiIndirectCommandBuffer::QRhiIndirectCommandBuffer ( QRhiImplementation * rhi,
Type type_,
quint32 maxCommandCount_ )
protected

Definition at line 8909 of file qrhi.cpp.

Member Function Documentation

◆ clear()

void QRhiIndirectCommandBuffer::clear ( )

Discards all commands recorded so far.

Can be called at any time, also before create(). The recorded contents only become visible to the GPU once the object is passed to QRhiResourceUpdateBatch::commitIndirectCommandBuffer().

This resets recordedCommandCount() to 0. It does not undo a QRhiCommandBuffer::buildIndirect(): an indirect command buffer that gets its commands from the GPU keeps doing so, and commandCount() is unchanged.

Note
Clearing and re-recording invalidates whatever the backend cached for the previous contents, so the per-command cost of recording is paid again. Call this only when the commands actually have to change. See \l{Recording on the CPU or building on the GPU} for why that matters at high command counts.

Definition at line 8941 of file qrhi.cpp.

◆ commandCount()

quint32 QRhiIndirectCommandBuffer::commandCount ( ) const
inline
Returns
the number of commands QRhiCommandBuffer::executeIndirect() issues by default.

This is recordedCommandCount() for a CPU-recorded indirect command buffer, and the count resolved from QRhiIndirectCommandBufferBuildInfo::commandCount once QRhiCommandBuffer::buildIndirect() has been called.

A count buffer, if there is one, can reduce the number of draws further at execution time. This function does not, and cannot, account for that.

Definition at line 1764 of file qrhi.h.

◆ create()

virtual bool QRhiIndirectCommandBuffer::create ( )
pure virtual

Creates the corresponding native objects.

Fails when maxCommandCount() is 0.

A given QRhiIndirectCommandBuffer takes its commands either from draw() and drawIndexed() followed by QRhiResourceUpdateBatch::commitIndirectCommandBuffer(), or from QRhiCommandBuffer::buildIndirect(), but not from both. Moving to the latter is one-way: clear() does not undo it, and neither does a subsequent commitIndirectCommandBuffer(); isGpuBuilt() stays true and the commands keep coming from the buffer. Call create() again to get an indirect command buffer that is populated from the CPU once more.

Note
Like with every other QRhi resource, destroy() gives up the contents, and so create() starts from an empty indirect command buffer: recordedCommandCount() is 0 afterwards. Setting a different type() or maxCommandCount() and calling create() again therefore needs the commands to be recorded again as well.
Returns
true when successful, false when a graphics operation failed.

Implemented in QMetalIndirectCommandBuffer, and QRhiBufferBackedIndirectCommandBuffer.

◆ draw()

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

Records a non-indexed draw command with vertexCount, instanceCount, firstVertex, and firstInstance.

The semantics are the same as QRhiCommandBuffer::draw().

Note
Only valid on an indirect command buffer of type Draws.

Definition at line 8956 of file qrhi.cpp.

◆ drawIndexed()

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

Records an indexed draw command with indexCount, instanceCount, firstIndex, vertexOffset, and firstInstance.

The semantics are the same as QRhiCommandBuffer::drawIndexed().

Note
Only valid on an indirect command buffer of type IndexedDraws.

Definition at line 8982 of file qrhi.cpp.

◆ isGpuBuilt()

bool QRhiIndirectCommandBuffer::isGpuBuilt ( ) const
inline
Returns
true when QRhiCommandBuffer::buildIndirect() has been called on this indirect command buffer, meaning its contents come from a QRhiBuffer instead of from draw() and drawIndexed().

Once true, this stays true until the next create().

Definition at line 1763 of file qrhi.h.

◆ maxCommandCount()

quint32 QRhiIndirectCommandBuffer::maxCommandCount ( ) const
inline
Returns
the capacity, i.e. the maximum number of commands.

Definition at line 1751 of file qrhi.h.

◆ recordedCommandCount()

quint32 QRhiIndirectCommandBuffer::recordedCommandCount ( ) const
inline
Returns
the number of commands recorded with draw() or drawIndexed() since the last clear().

This is unaffected by QRhiCommandBuffer::buildIndirect(): once the commands come from the GPU, whatever was recorded on the CPU is ignored. Use commandCount() to get the number of commands that will actually be executed.

Definition at line 1762 of file qrhi.h.

◆ resourceType()

QRhiResource::Type QRhiIndirectCommandBuffer::resourceType ( ) const
overridevirtual
Returns
the resource type.

Implements QRhiResource.

Definition at line 8919 of file qrhi.cpp.

◆ setMaxCommandCount()

void QRhiIndirectCommandBuffer::setMaxCommandCount ( quint32 count)
inline

Sets the capacity, the maximum number of commands, to count.

The capacity is normally specified in QRhi::newIndirectCommandBuffer(), so this function is only used when it has to be changed. As with other setters, it only takes effect when calling create(), which fails when count is 0.

The capacity applies regardless of how the commands are going to be provided: recording them with draw() and drawIndexed() and building them with QRhiCommandBuffer::buildIndirect() are both bounded by it.

draw() and drawIndexed() ignore, with a warning, any command past the first count ones. QRhiCommandBuffer::buildIndirect() clamps, also with a warning, when QRhiIndirectCommandBufferBuildInfo::commandCount is larger.

See also
commandCount(), recordedCommandCount()

Definition at line 1752 of file qrhi.h.

◆ setType()

void QRhiIndirectCommandBuffer::setType ( Type t)
inline

Sets the command type t.

The type is normally specified in QRhi::newIndirectCommandBuffer(), so this function is only used when it has to be changed. As with other setters, it only takes effect when calling create().

Definition at line 1749 of file qrhi.h.

◆ type()

Type QRhiIndirectCommandBuffer::type ( ) const
inline
Returns
the type of commands this indirect command buffer holds.

Definition at line 1748 of file qrhi.h.

Member Data Documentation

◆ m_commandCount

quint32 QRhiIndirectCommandBuffer::m_commandCount = 0
protected

Definition at line 1772 of file qrhi.h.

◆ m_data

QByteArray QRhiIndirectCommandBuffer::m_data
protected

Definition at line 1771 of file qrhi.h.

◆ m_generation

quint64 QRhiIndirectCommandBuffer::m_generation = 0
protected

Definition at line 1773 of file qrhi.h.

◆ m_gpuBuilt

bool QRhiIndirectCommandBuffer::m_gpuBuilt = false
protected

Definition at line 1774 of file qrhi.h.

◆ m_gpuBuiltCommandCount

quint32 QRhiIndirectCommandBuffer::m_gpuBuiltCommandCount = 0
protected

Definition at line 1775 of file qrhi.h.

◆ m_maxCommandCount

quint32 QRhiIndirectCommandBuffer::m_maxCommandCount
protected

Definition at line 1770 of file qrhi.h.

◆ m_type

Type QRhiIndirectCommandBuffer::m_type
protected

Definition at line 1769 of file qrhi.h.


The documentation for this class was generated from the following files: