simvx.graphics.gpu.descriptors

Descriptor pool, layout, and set management.

Module Contents

Classes

DescriptorWriteBatch

Collects VkWriteDescriptorSet structs and flushes them in a single Vulkan call.

Functions

create_pool_for_types

Create a descriptor pool from a {descriptor_type: count} mapping.

create_descriptor_set_layout

Create a descriptor set layout from a list of (binding, type, stage_flags, count) tuples.

create_descriptor_pool

Create a descriptor pool for SSBO descriptors (+ optional image samplers / UBOs).

create_ssbo_layout

Create a descriptor set layout with N SSBO bindings + optional sampler bindings.

allocate_descriptor_set

Allocate a single descriptor set from the pool.

create_texture_descriptor_pool

Create a descriptor pool for combined image samplers.

create_texture_descriptor_layout

Create a set layout for a combined-image-sampler array.

write_texture_descriptor

Write a single texture to the texture array at the given index.

write_image_descriptor

Write a combined image sampler to a descriptor set at the given binding.

write_ssbo_descriptor

Write a single SSBO buffer binding to a descriptor set.

write_ubo_descriptor

Write a single uniform-buffer binding to a descriptor set.

Data

API

simvx.graphics.gpu.descriptors.log

‘getLogger(…)’

simvx.graphics.gpu.descriptors.__all__

[‘LAYOUT_CREATE_UPDATE_AFTER_BIND’, ‘POOL_CREATE_UPDATE_AFTER_BIND’, ‘UPDATE_AFTER_BIND_BINDING_FLAG…

simvx.graphics.gpu.descriptors.POOL_CREATE_UPDATE_AFTER_BIND

2

simvx.graphics.gpu.descriptors.LAYOUT_CREATE_UPDATE_AFTER_BIND

2

simvx.graphics.gpu.descriptors.UPDATE_AFTER_BIND_BINDING_FLAGS

None

simvx.graphics.gpu.descriptors.create_pool_for_types(device: Any, sizes: dict[int, int], max_sets: int = 1) Any

Create a descriptor pool from a {descriptor_type: count} mapping.

General-purpose alternative to :func:create_descriptor_pool (which is specialised for SSBO + sampler workloads). Use this for compute passes that mix STORAGE_IMAGE, COMBINED_IMAGE_SAMPLER, UNIFORM_BUFFER, etc.

simvx.graphics.gpu.descriptors.create_descriptor_set_layout(device: Any, bindings: list[tuple[int, int, int, int]]) Any

Create a descriptor set layout from a list of (binding, type, stage_flags, count) tuples.

simvx.graphics.gpu.descriptors.create_descriptor_pool(device: Any, max_sets: int = 4, extra_samplers: int = 0, ssbo_count: int = 0, ubo_count: int = 0, update_after_bind: bool = False) Any

Create a descriptor pool for SSBO descriptors (+ optional image samplers / UBOs).

If ssbo_count is given it overrides the default max_sets * 4 SSBO descriptor count. ubo_count reserves that many uniform-buffer descriptors (e.g. the FrameGlobals UBO). Pass update_after_bind=True to allocate UPDATE_AFTER_BIND-capable sets from it.

simvx.graphics.gpu.descriptors.create_ssbo_layout(device: Any, binding_count: int = 3, extra_samplers: int = 0, trailing_ssbos: int = 0, extra_samplers_tail: int = 0, tail2_samplers: int = 0, tail2_ssbos: int = 0, tail_ubos: int = 0, tail3_samplers: int = 0, tail4_samplers: int = 0, tail5_ssbos: int = 0, tail6_ssbos: int = 0, update_after_bind: bool = False) Any

Create a descriptor set layout with N SSBO bindings + optional sampler bindings.

Binding order: binding_count SSBOs, then extra_samplers image samplers, then trailing_ssbos additional SSBOs (fragment-only, for tile light data etc.), then extra_samplers_tail more image samplers (fragment-only, e.g. the IBL irradiance / prefilter / BRDF maps that must sit after the trailing SSBOs), then tail2_samplers image samplers (e.g. reflection-probe cubemap arrays), then tail2_ssbos SSBOs (e.g. the reflection-probe box buffer), then tail_ubos uniform buffers (vertex + fragment, e.g. the FrameGlobals UBO), then tail3_samplers fragment image samplers that must sit AFTER the UBO tail (e.g. the scene colour / depth copy samplers, set0 b14/b15), then tail4_samplers fragment image samplers after those (e.g. the pluggable ambient indirect specular / diffuse hooks, set0 b16/b17), then tail5_ssbos fragment SSBOs after those (e.g. the irradiance-volume SH buffer, set0 b18), then tail6_ssbos fragment SSBOs after those (e.g. the clustered-decal buffer, set0 b19).

simvx.graphics.gpu.descriptors.allocate_descriptor_set(device: Any, pool: Any, layout: Any) Any

Allocate a single descriptor set from the pool.

simvx.graphics.gpu.descriptors.create_texture_descriptor_pool(device: Any, max_textures: int = MAX_TEXTURES, update_after_bind: bool = False) Any

Create a descriptor pool for combined image samplers.

update_after_bind must match the layout: pass True for the global bindless texture array (whose slots are written while bound), False for plain per-pass single-texture sets written once at setup.

simvx.graphics.gpu.descriptors.create_texture_descriptor_layout(device: Any, max_textures: int = MAX_TEXTURES, update_after_bind: bool = False) Any

Create a set layout for a combined-image-sampler array.

When update_after_bind is set (the global bindless texture array), the binding is UPDATE_AFTER_BIND so individual slots can be (re)written while a submitted command buffer still reads the set – not merely a recording one – and PARTIALLY_BOUND so unregistered slots need not be written. So the array can be repointed without draining the device, which is the canonical bindless pattern. That is the measured guarantee rather than a reading of the spec: tests/test_update_after_bind_contract.py binds the set, records a dispatch that samples it, submits without waiting, and rewrites the slot; the flagless arm draws VUID-vkUpdateDescriptorSets-None-03047 and the flagged arm is silent. Plain per-pass single-texture sets pass False (written once at setup, and they allocate from a non-UAB pool).

simvx.graphics.gpu.descriptors.write_texture_descriptor(device: Any, descriptor_set: Any, texture_index: int, image_view: Any, sampler: Any) None

Write a single texture to the texture array at the given index.

simvx.graphics.gpu.descriptors.write_image_descriptor(device: Any, descriptor_set: Any, binding: int, image_view: Any, sampler: Any) None

Write a combined image sampler to a descriptor set at the given binding.

simvx.graphics.gpu.descriptors.write_ssbo_descriptor(device: Any, descriptor_set: Any, binding: int, buffer: Any, size: int) None

Write a single SSBO buffer binding to a descriptor set.

simvx.graphics.gpu.descriptors.write_ubo_descriptor(device: Any, descriptor_set: Any, binding: int, buffer: Any, size: int) None

Write a single uniform-buffer binding to a descriptor set.

class simvx.graphics.gpu.descriptors.DescriptorWriteBatch(device: Any)

Collects VkWriteDescriptorSet structs and flushes them in a single Vulkan call.

Usage::

batch = DescriptorWriteBatch(device)
batch.ssbo(ds, 0, buf_a, size_a)
batch.ssbo(ds, 1, buf_b, size_b)
batch.image(ds, 2, view, sampler)
batch.flush()

Can also be used as a context manager – flush() is called on exit::

with DescriptorWriteBatch(device) as batch:
    batch.ssbo(ds, 0, buf, size)

Initialization

__slots__

(‘_device’, ‘_writes’)

ssbo(descriptor_set: Any, binding: int, buffer: Any, size: int) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue an SSBO descriptor write.

image(descriptor_set: Any, binding: int, image_view: Any, sampler: Any, image_layout: int = vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue a combined image sampler descriptor write (default layout: SHADER_READ_ONLY_OPTIMAL).

storage_image(descriptor_set: Any, binding: int, image_view: Any, image_layout: int = vk.VK_IMAGE_LAYOUT_GENERAL) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue a storage image descriptor write (compute writeable target).

uniform_buffer(descriptor_set: Any, binding: int, buffer: Any, size: int) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue a uniform buffer descriptor write.

texture(descriptor_set: Any, texture_index: int, image_view: Any, sampler: Any) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue a texture array element descriptor write.

raw(write: vulkan.VkWriteDescriptorSet) simvx.graphics.gpu.descriptors.DescriptorWriteBatch

Queue a pre-built VkWriteDescriptorSet.

flush() int

Submit all queued writes in a single vkUpdateDescriptorSets call.

Returns the number of writes submitted. The internal queue is cleared.

__enter__() simvx.graphics.gpu.descriptors.DescriptorWriteBatch
__exit__(*exc: object) None
__len__() int