PySide6.QtGui.QRhiBuffer¶
- class QRhiBuffer¶
Vertex, index, or uniform (constant) buffer resource. More…
Added in version 6.6.
Synopsis¶
Methods¶
Virtual methods¶
Note
This documentation may contain snippets that were automatically translated from C++ to Python. We always welcome contributions to the snippet translation. If you see an issue with the translation, you can also let us know by creating a ticket on https:/bugreports.qt.io/projects/PYSIDE
Detailed Description¶
Note
This is a RHI API with limited compatibility guarantees, see
QRhifor details.A
QRhiBufferencapsulates zero, one, or more native buffer objects (such as aVkBufferorMTLBuffer). With some graphics APIs and backends certain types of buffers may not use a native buffer object at all (e.g. OpenGL if uniform buffer objects are not used), but this is transparent to the user of theQRhiBufferAPI. Similarly, the fact that some types of buffers may use two or three native buffers underneath, in order to allow efficient per-frame content update without stalling the GPU pipeline, is mostly invisible to the applications and libraries.A
QRhiBufferinstance is always created by callingthe QRhi's newBuffer() function. This creates no native graphics resources. To do that, callcreate()after setting the appropriate options, such as the type, usage flags, size, although in most cases these are already set based on the arguments passed tonewBuffer().Example usage¶
To create a uniform buffer for a shader where the GLSL uniform block contains a single
mat4member, and update the contents:QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64); if (!ubuf->create()) { error(); } QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); QMatrix4x4 mvp; // ... set up the modelview-projection matrix batch->updateDynamicBuffer(ubuf, 0, 64, mvp.constData()); // ... commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() callAn example of creating a buffer with vertex data:
const float vertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f }; QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertices)); if (!vbuf->create()) { error(); } QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); batch->uploadStaticBuffer(vbuf, vertices); // ... commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() callAn index buffer:
static const quint16 indices[] = { 0, 1, 2 }; QRhiBuffer *ibuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(indices)); if (!ibuf->create()) { error(); } QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); batch->uploadStaticBuffer(ibuf, indices); // ... commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() callCommon patterns¶
A call to
create()destroys any existing native resources ifcreate()was successfully called before. If those native resources are still in use by an in-flight frame (i.e., there’s a chance they are still read by the GPU), the destroying of those resources is deferred automatically. Thus a very common and convenient pattern to safely increase the size of an already initialized buffer is the following. In practice this drops and creates a whole new set of native resources underneath, so it is not necessarily a cheap operation, but is more convenient and still faster than the alternatives, because by not destroying thebufobject itself, all references to it stay valid in other data structures (e.g., in anyQRhiShaderResourceBindingtheQRhiBufferis referenced from).if (buf->size() < newSize) { buf->setSize(newSize); if (!buf->create()) { error(); } } // continue using buf, fill it with new dataWhen working with uniform buffers, it will sometimes be necessary to combine data for multiple draw calls into a single buffer for efficiency reasons. Be aware of the aligment requirements: with some graphics APIs offsets for a uniform buffer must be aligned to 256 bytes. This applies both to
QRhiShaderResourceBindingand to the dynamic offsets passed tosetShaderResources(). Use theubufAlignment()andubufAligned()functions to create portable code. As an example, the following is an outline for issuing multiple (N) draw calls with the same pipeline and geometry, but with a different data in the uniform buffers exposed at binding point 0. This assumes the buffer is exposed viauniformBufferWithDynamicOffset()which allows passing a QRhiCommandBuffer::DynamicOffset list tosetShaderResources().const int N = 2; const int UB_SIZE = 64 + 4; // assuming a uniform block with { mat4 matrix; float opacity; } const int ONE_UBUF_SIZE = rhi->ubufAligned(UB_SIZE); const int TOTAL_UBUF_SIZE = N * ONE_UBUF_SIZE; QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, TOTAL_UBUF_SIZE); if (!ubuf->create()) { error(); } QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); for (int i = 0; i < N; ++i) { batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE, 64, matrix.constData()); batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE + 64, 4, &opacity); } // ... // beginPass(), set pipeline, etc., and then: for (int i = 0; i < N; ++i) { QRhiCommandBuffer::DynamicOffset dynOfs[] = { { 0, i * ONE_UBUF_SIZE } }; cb->setShaderResources(srb, 1, dynOfs); cb->draw(36); }See also
- class Type¶
Specifies storage type of buffer resource.
Constant
Description
QRhiBuffer.Immutable
Indicates that the data is not expected to change ever after the initial upload. Under the hood such buffer resources are typically placed in device local (GPU) memory (on systems where applicable). Uploading new data is possible, but may be expensive. The upload typically happens by copying to a separate, host visible staging buffer from which a GPU buffer-to-buffer copy is issued into the actual GPU-only buffer.
QRhiBuffer.Static
Indicates that the data is expected to change only infrequently. Typically placed in device local (GPU) memory, where applicable. On backends where host visible staging buffers are used for uploading, the staging buffers are kept around for this type, unlike with Immutable, so subsequent uploads do not suffer in performance. Frequent updates, especially updates in consecutive frames, should be avoided.
QRhiBuffer.Dynamic
Indicates that the data is expected to change frequently. Not recommended for large buffers. Typically backed by host visible memory in 2 copies in order to allow for changing without stalling the graphics pipeline. The double buffering is managed transparently to the applications and is not exposed in the API here in any form. This is the recommended, and, with some backends, the only possible, type for buffers with
UniformBufferusage.
- class UsageFlag¶
(inherits
enum.Flag) Flag values to specify how the buffer is going to be used.Constant
Description
QRhiBuffer.VertexBuffer
Vertex buffer. This allows the
QRhiBufferto be used insetVertexInput().QRhiBuffer.IndexBuffer
Index buffer. This allows the
QRhiBufferto be used insetVertexInput().QRhiBuffer.UniformBuffer
Uniform buffer (also called constant buffer). This allows the
QRhiBufferto be used in combination withUniformBuffer. WhenNonDynamicUniformBuffersis reported as not supported, this usage can only be combined with the type Dynamic.QRhiBuffer.StorageBuffer
Storage buffer. This allows the
QRhiBufferto be used in combination withBufferLoad,BufferStore, orBufferLoadStore. This usage can only be combined with the types Immutable or Static, and is only available when theCompute featureis reported as supported.
- PySide6.QtGui.QRhiBuffer.m_type¶
- PySide6.QtGui.QRhiBuffer.m_usage¶
- PySide6.QtGui.QRhiBuffer.m_size¶
- abstract create()¶
- Return type:
bool
Creates the corresponding native graphics resources. If there are already resources present due to an earlier create() with no corresponding
destroy(), thendestroy()is called implicitly first.Returns
truewhen successful,falsewhen a graphics operation failed. Regardless of the return value, callingdestroy()is always safe.- endFullDynamicBufferUpdateForCurrentFrame()¶
To be called when the entire contents of the buffer data has been updated in the memory block returned from
beginFullDynamicBufferUpdateForCurrentFrame().- fullDynamicBufferUpdateForCurrentFrame(data[, size=0])¶
- Parameters:
data –
voidsize – int
- setSize(sz)¶
- Parameters:
sz – int
Sets the size of the buffer in bytes. The size is normally specified in
newBuffer()so this function is only used when the size has to be changed. As with other setters, the size only takes effect when callingcreate(), and for already created buffers this involves releasing the previous native resource and creating new ones under the hood.Backends may choose to allocate buffers bigger than
szin order to fulfill alignment requirements. This is hidden from the applications andsize()will always report the size requested insz.See also
Sets the buffer’s type to
t.See also
Sets the buffer’s usage flags to
u.See also
- size()¶
- Return type:
int
Returns the buffer’s size in bytes.
This is always the value that was passed to
setSize()ornewBuffer(). Internally, the native buffers may be bigger if that is required by the underlying graphics API.See also
Returns the buffer type.
See also
Returns the buffer’s usage flags.
See also