simvx.graphics.renderer.buffer_manager¶
BufferManager: owns the forward renderer’s SSBOs and descriptor sets.
Extracted from Renderer so transform/material/light/shadow/joint
buffers and the Forward+ tile-culling placeholders live in one place. The
descriptor set layout and cubemap placeholder are owned here too so the
renderer can swap the IBL cubemap in via write_cubemap_descriptor.
Module Contents¶
Classes¶
Owns the renderer’s SSBOs and descriptor sets. |
Data¶
API¶
- simvx.graphics.renderer.buffer_manager.__all__¶
[‘BufferManager’, ‘SHADOW_DATA_SIZE’]
- simvx.graphics.renderer.buffer_manager.log¶
‘getLogger(…)’
- simvx.graphics.renderer.buffer_manager.SHADOW_DATA_SIZE¶
384
- simvx.graphics.renderer.buffer_manager.MAX_PROBES¶
8
- simvx.graphics.renderer.buffer_manager.PROBE_BUFFER_SIZE¶
None
- simvx.graphics.renderer.buffer_manager.IRRADIANCE_VOLUME_HEADER_SIZE¶
64
- simvx.graphics.renderer.buffer_manager.IRRADIANCE_VOLUME_MAX_PROBES¶
256
- simvx.graphics.renderer.buffer_manager.IRRADIANCE_VOLUME_BUFFER_SIZE¶
None
- class simvx.graphics.renderer.buffer_manager.BufferManager(engine: Any, max_objects: int, max_materials: int = 1024, max_lights: int = 256, max_joints: int = 256)[source]¶
Owns the renderer’s SSBOs and descriptor sets.
Main descriptor set (
ssbo_set) exposes eighteen bindings: 0: transforms, 1: materials, 2: lights, 3: shadow, 4: IBL cubemap sampler, 5: tile light indices, 6: tile info, 7/8/9: IBL irradiance cube / prefilter cube / BRDF 2D LUT, 10/11: reflection-probe irradiance / prefilter cube arrays, 12: reflection-probe box SSBO, 13: FrameGlobals UBO, 14: scene colour copy, 15: scene depth copy (written by the renderer’s :class:SceneCopyTargets), 16/17: indirect specular / diffuse hook textures (1x1 black until an SSR / SSGI producer writes them).Joint descriptor set (
joint_set) is set 2 binding 0 for skinned meshes.Initialization
- property ssbo_set: Any[source]¶
The current frame’s main SSBO descriptor set (what every pass binds).
- property joint_set: Any[source]¶
The current frame’s joint descriptor set (bound for skinned meshes).
- property transform_capacity: int[source]¶
Total transform-SSBO slots available this frame (==
max_objects).
- begin_frame_arena() None[source]¶
Reset the per-frame bump cursor. Call once at the start of every frame.
- reserve_slots(count: int) int[source]¶
Reserve a contiguous range of
counttransform slots; return its base.Bump-allocates from the shared SSBO arena. On overflow (the running cursor would pass capacity) the request is clamped to what fits, a WARNING is logged once, and a grow to
next_pow2(needed)is scheduled for the next frame boundary. The high-water mark is updated either way so a proactive grow can fire before an actual overflow recurs.Returns the base slot. The caller records draws with
first_instance = base + local_indexand writes its transforms into the SSBO at byte offsetbase * TRANSFORM_DTYPE.itemsize.
- request_joint_capacity(joint_count: int) int[source]¶
Reserve room for
joint_countbone matrices in the joint SSBO.Returns the number that fit in the CURRENT buffer (so the caller clamps its upload and never writes past the allocation). When the request exceeds capacity a grow is scheduled for the next frame boundary (mirrors the transform arena), so the dropped skeletons appear one frame later instead of corrupting device memory. Symmetric with the web
_ensureBoneBuf.
- maybe_grow() bool[source]¶
Grow the transform/AABB and joint SSBOs if scheduled. Frame-boundary only.
Reallocates when a grow is pending (an overflow clamped this frame) OR the high-water mark has crossed
_GROW_THRESHOLDof capacity (proactive). Must run OUTSIDE command recording (begin_frame or post-submit) so the reallocated buffer + descriptor rewrite never race the GPU. Returns True when a grow happened.
- write_probe_descriptors(irradiance_array_view: Any, prefilter_array_view: Any, sampler: Any) None[source]¶
Bind the ReflectionProbePass’s cubemap arrays to the forward set (bindings 10/11).
- write_probe_buffer(data: numpy.ndarray) None[source]¶
Upload the probe box SSBO bytes (count header + Probe array, binding 12).
- write_decals(data: numpy.ndarray) None[source]¶
Upload the decal SSBO bytes (count header + Decal array + tile masks, b19).
datais the block fromdecal_pack.build_decal_buffer. The base (header + record) region is a fixed :data:DECAL_BUFFER_SIZE; when the screen-tile cull is active the per-tile bitmask array is appended, so the block can exceed the initial allocation. It is grown (and its b19 descriptor repointed) on demand at the frame boundary; the growth only ever adds tile-mask capacity, so it never perturbs the record region. An all-zero block (no decals) leavesdecal_countat 0, a byte-identical no-op.
- write_irradiance_volume_header(header: numpy.ndarray) None[source]¶
Upload ONLY the volume SSBO header (64 B: grid + bounds + params, binding 18).
The per-probe SH region that follows is written by the IrradianceVolumePass SH-reduce compute (GPU), so the header upload must never touch it.
- write_ibl_descriptors(irradiance_view: Any, prefilter_view: Any, brdf_view: Any, sampler: Any) None[source]¶
Bind an IBLPass’s precomputed maps to the forward set (bindings 7/8/9).
- upload_transforms(instances: list, *, upload_aabbs: bool = False, base: int = 0) numpy.ndarray | None[source]¶
Upload instance transforms + normal matrices + material ids into the SSBO slice.
Writes into the shared transform SSBO starting at slot
base(the slice reserved for this scene-render unit;base == 0for the main scene). Returns the (N, 4, 4) column-major (GLSL-ready) model matrices so the caller can feed the exact same data to the TAA velocity pass (prev-frame transform plumbing). Returns None when there are no instances.When
upload_aabbsis True (GPU occlusion culling enabled) the per-slot LOCAL AABB SSBO is populated alongside. Off by default so the occlusion-off path performs no extra host upload (byte-identical default behaviour).
- upload_transform_block(transforms: numpy.ndarray, base: int, *, material_index: int = 0, material_ids: numpy.ndarray | None = None) numpy.ndarray | None[source]¶
Vectorized upload of a contiguous instance block (e.g. a MultiMesh).
Unlike :meth:
upload_transforms, which iterates a Python list of per- instance tuples, this packs the whole(N, 4, 4)block with no Python loop and writes it at slots[base, base+N). Returns the world-space instance centres(N, 3)(translation columns) so the caller can frustum-cull the block without re-reading the SSBO. Returns None when the block does not fit.
- set_materials(materials: numpy.ndarray) numpy.ndarray[source]¶
Upload material array. Returns the (possibly clamped) array stored.
- set_lights(lights: numpy.ndarray) None[source]¶
Upload light array prefixed with the uint32 count (GLSL LightBuffer layout).
- write_shadow_data(shadow_data: numpy.ndarray) None[source]¶
Upload raw shadow SSBO bytes (used by shadow passes + IBL-only fallback).
- write_cubemap_descriptor(view: Any, sampler: Any) None[source]¶
Bind a cubemap view+sampler to the IBL slot (binding 4).
- update_frame_globals(now: float, env: simvx.graphics.frame_globals.FrameGlobalsEnv, internal_extent: tuple[int, int], output_extent: tuple[int, int], render_scale: float = 1.0) None[source]¶
Repack + upload the per-frame FrameGlobals UBO (binding 13).
deltais derived from the scene clock (nowminus the previous call’snow) andframe_indexfrom an internal counter, so the block needs no renderer-wide frame clock.internal_extentis the HDR-chain render extent,output_extentthe swapchain extent; they are equal (andrender_scale1.0) on the unscaled path, packing the exact pre-scale block.