simvx.graphics.renderer.bindless_draw2d_pass

Bindless co-batched 2D pass for the item pipeline (design §3 Decision D, P3b).

The main-framebuffer 2D submit. It carries texture_id and the is_msdf flag per vertex and draws through ONE unified pipeline (ui2d.vert / ui2d.frag). So a run of consecutive items sharing only (clip, blend) – different-texture sprites and glyph runs and untextured fills – collapses into a single vkCmdDrawIndexed that selects the texture per primitive via ui_textures[nonuniformEXT(tex_id)] and branches on the is_msdf bit (linear sample vs median-MSDF decode, the latter ported verbatim from text.frag so glyph AA is pixel-identical).

The MSDF atlas is registered into the engine’s bindless ui_textures[] array (the same array sprites use), so a glyph item just references that slot like any other textured item. The atlas slot is refreshed when the atlas version bumps (the view is recreated on re-upload).

Module Contents

Classes

BindlessBatch

One co-batched draw: a contiguous range under a (topology, clip, blend) scope.

BindlessDraw2DPass

GPU pass that draws bindless co-batched 2D geometry (design §3 D).

Data

API

simvx.graphics.renderer.bindless_draw2d_pass.__all__

[‘BindlessDraw2DPass’, ‘BindlessBatch’]

simvx.graphics.renderer.bindless_draw2d_pass.log

‘getLogger(…)’

simvx.graphics.renderer.bindless_draw2d_pass.FLAG_IS_MSDF

1

class simvx.graphics.renderer.bindless_draw2d_pass.BindlessBatch[source]

Bases: typing.NamedTuple

One co-batched draw: a contiguous range under a (topology, clip, blend) scope.

clip is the scissor rect (or None for full-screen); blend is the blend-mode string selecting the per-blend pipeline. The texture and is_msdf selection are PER VERTEX, so a single triangle batch covers many textures (different-texture sprites + MSDF glyph runs + untextured fills).

Triangle batches (line=False) are indexed draws: vert_offset is the base vertex, idx_offset/count the index range. Line batches (line=True) are non-indexed: vert_offset is the first vertex and count the vertex count in the shared line vertex buffer. Lines use a different topology so they cannot merge with triangles; they break a run and render through the line pipeline, preserving painter order.

clip: tuple[int, int, int, int] | None

None

blend: str

None

vert_offset: int

None

idx_offset: int

None

count: int

None

line: bool

False

class simvx.graphics.renderer.bindless_draw2d_pass.BindlessDraw2DPass(engine: Any, text_pass: Any = None)[source]

GPU pass that draws bindless co-batched 2D geometry (design §3 D).

Owns the unified ui2d pipeline (one per blend mode), one extended-vertex buffer + index buffer (host-visible, growable arena), and binds the engine’s bindless texture descriptor set (the same ui_textures[] sprites use). The MSDF atlas is registered into that array via :meth:sync_atlas_slot.

Initialization

__slots__

(‘_engine’, ‘_text_pass’, ‘_pipelines’, ‘_pipeline_layout’, ‘_line_pipeline’, ‘_line_pipeline_layout…

setup(render_pass: Any = None, extent: tuple[int, int] | None = None) None[source]
sync_atlas_slot() int[source]

Register / refresh the MSDF atlas in the bindless array; return its slot.

The glyph items reference this slot as their per-vertex tex_id. The atlas view is recreated when the atlas version bumps (re-upload), so the bindless descriptor is rewritten to the new view while keeping the same slot id stable (so already-built geometry stays valid).

property atlas_slot: int[source]

The bindless slot of the MSDF atlas (-1 until :meth:sync_atlas_slot).

set_atlas_slot(slot: int) None[source]

Borrow an already-registered MSDF atlas slot (N1, the HDR-lane pass).

The HDR-target 2D pass and the swapchain 2D pass bind the SAME engine bindless ui_textures[] descriptor set, so the atlas slot index is valid in both. Only the swapchain pass owns the registration (calls

Meth:

sync_atlas_slot); the HDR pass mirrors its slot here each frame to avoid a redundant second descriptor write for the same atlas view.

render(cmd: Any, width: int, height: int, ui_width: int, ui_height: int, *, verts: numpy.ndarray, indices: numpy.ndarray, line_verts: numpy.ndarray, batches: list[simvx.graphics.renderer.bindless_draw2d_pass.BindlessBatch]) None[source]

Upload the co-batched geometry and issue one draw per batch.

verts is a contiguous :data:UI2D_VERTEX_DTYPE array of triangle vertices (all batches concatenated, camera already applied), indices the matching uint32 index stream, line_verts the (separate) line vertices, batches the ordered per-(topology, clip, blend) runs. A triangle batch is ONE vkCmdDrawIndexed regardless of how many textures it touches; a line batch is ONE vkCmdDraw.

cleanup() None[source]