simvx.graphics.renderer.gpu_batch¶
GPU-driven batch rendering with multi-draw indirect (MDI) and fallback.
Module Contents¶
Classes¶
Manages batched draw commands. |
Data¶
API¶
- simvx.graphics.renderer.gpu_batch.log¶
‘getLogger(…)’
- simvx.graphics.renderer.gpu_batch.__all__¶
[‘GPUBatch’]
- class simvx.graphics.renderer.gpu_batch.GPUBatch(engine: Any, device: Any, physical_device: Any, max_draws: int = 1000, *, use_mdi: bool = True, concurrent_families: list[int] | None = None)[source]¶
Manages batched draw commands.
When
use_mdi=True(default), usesvkCmdDrawIndexedIndirectto issue all draw commands in a single GPU call. Whenuse_mdi=False, falls back to a loop ofvkCmdDrawIndexedcalls: functionally identical but slower on GPUs that support MDI.Usage::
batch = GPUBatch(engine, device, physical_device, max_draws=100) batch.add_draw(index_count=36, first_instance=0) batch.upload() batch.on_draw(cmd)
Initialization
- add_draw(index_count: int, instance_count: int = 1, first_index: int = 0, vertex_offset: int = 0, first_instance: int = 0) int[source]¶
Add a draw command. Returns the draw index.
- add_draws(index_count: int, first_instances: numpy.ndarray | list[int]) int[source]¶
Bulk-add draw commands sharing the same mesh: avoids per-instance Python loop.
Args: index_count: Index count for the mesh (same for all draws). first_instances: (N,) array of SSBO instance indices.
Returns: Batch offset of the first added draw command.
- add_instanced_runs(index_count: int, slots: numpy.ndarray | list[int]) tuple[int, int][source]¶
Add draws for SSBO
slots, coalescing contiguous slots into instanced draws.Each maximal run of consecutive slots becomes ONE indirect command with
instance_count = run lengthandfirst_instance = run start. The vertex shader readstransforms[gl_InstanceIndex]wheregl_InstanceIndex = gl_InstanceID + first_instance, so a run of contiguous slots is drawn correctly by a single instanced command. A MultiMesh (whose N instances occupy N consecutive slots) thus collapses to a single draw.Returns
(batch_offset, command_count)wherecommand_countis the number of runs (== number of indirect commands added), fordraw_range.Must NOT be used for the occlusion-cull batch: that path needs one command per instance so the cull compute can zero
instance_countper object. Use :meth:add_drawsthere.
- draw_range(cmd: Any, offset: int, count: int) None[source]¶
Draw a sub-range of commands.
Args: cmd: Vulkan command buffer offset: First draw command index (not byte offset) count: Number of draw commands to execute
- grow(physical_device: Any, max_draws: int) None[source]¶
Reallocate the indirect buffer to hold at least
max_drawscommands.A no-op when
max_drawsdoes not exceed the current capacity. Used when the transform-SSBO arena grows so the indirect batch can keep pace. The old buffer is retired (freed after FRAMES_IN_FLIGHT resets) rather than freed immediately, anddraw_countis reset (callers rebuild after an arena grow).