Fill (a sub-range of) a QRhiBuffer with a 4-byte pattern. More...
Detailed Description
Fill (a sub-range of) a QRhiBuffer with a 4-byte pattern.
Avoids the std::vector<char> zeros(size, 0); res.uploadStaticBuffer(buf, 0, size, zeros.data()); idiom, which pays a per-call zero-vector allocation plus a CPU→GPU upload of zero bytes. These entry points either issue a native GPU-side fill (vkCmdFillBuffer / MTLBlitCommandEncoder fillBuffer:range:value:) or route to QRhi's update batch with a thread-local zero-buffer pool so the zero source bytes are amortised across calls.
The motivating bug: Vulkan does NOT initialise VkBuffer memory — the underlying device-memory page contains whatever was there before. For sparse-uploaded SSBOs (RawLight arena, world_transforms, per_draws past drawCount, …), the un-touched bytes get read by shaders and feed garbage into the pipeline. Manifests as "wildly different lighting per resize" because each fresh VkBuffer lands on a different page. The defensive zero-fill via uploadStaticBuffer ships zeros from CPU to GPU — correct but slow; this abstraction picks the right native path.
Per-backend behaviour:
- Vulkan : vkCmdFillBuffer (CB variant) — Static buffers only, since QRhi's setupBuffer adds VK_BUFFER_USAGE_TRANSFER_DST_BIT only when m_type != Dynamic. Dynamic UBOs fall back to the update batch path. (See qrhivulkan.cpp QVkBuffer::create.)
- Metal : id<MTLBlitCommandEncoder> fillBuffer:range:value: (CB variant)
- D3D12 : currently falls back to the update batch (a future optimisation can use ClearUnorderedAccessViewUint or a thread-local zero-resource + CopyBufferRegion).
- D3D11 : fall back to the update batch.
- GL/GLES: fall back to the update batch (drivers commonly zero initialised buffer memory anyway, and GL exposes glClearBufferSubData on 4.3+ which we don't currently wire).
Both variants accept an arbitrary 4-byte pattern (replicated across the requested range). Default is 0 — the only pattern any current call site uses. offset and size MUST be 4-byte aligned (Vulkan vkCmdFillBuffer requires it; the batch fallback is permissive but the abstraction enforces the strict contract for portability).
Functions | |
| void | clearBuffer (QRhi &rhi, QRhiCommandBuffer &cb, QRhiBuffer *buf, quint32 offset, quint32 size, quint32 pattern=0u) |
| void | clearBuffer (QRhi &rhi, QRhiResourceUpdateBatch &batch, QRhiBuffer *buf, quint32 offset, quint32 size, quint32 pattern=0u) |
Function Documentation
◆ clearBuffer() [1/2]
| void score::gfx::RhiClearBuffer::clearBuffer | ( | QRhi & | rhi, |
| QRhiCommandBuffer & | cb, | ||
| QRhiBuffer * | buf, | ||
| quint32 | offset, | ||
| quint32 | size, | ||
| quint32 | pattern = 0u |
||
| ) |
CB-recording variant. Uses native fast paths inside beginExternal()/endExternal() per QRhi convention. Falls back to recording a host-side memset uploaded via a temporary update batch when no native path is available — but the batch variant is the preferred entry point for sites that aren't already inside a render pass and have only a QRhiResourceUpdateBatch in scope.
◆ clearBuffer() [2/2]
| void score::gfx::RhiClearBuffer::clearBuffer | ( | QRhi & | rhi, |
| QRhiResourceUpdateBatch & | batch, | ||
| QRhiBuffer * | buf, | ||
| quint32 | offset, | ||
| quint32 | size, | ||
| quint32 | pattern = 0u |
||
| ) |
Update-batch variant. Routes to QRhi's uploadStaticBuffer (Static buffers) or updateDynamicBuffer (Dynamic UBOs) using a thread-local zero-buffer pool — no per-call zero-vector allocation.
pattern other than 0 will allocate a small thread-local pattern buffer for the call (uncommon path); 0 hits the fast pool.