Bindless Descriptor Heap - limztudio/NWBLot GitHub Wiki

Bindless Descriptor Heap

NWBLot uses one Device-owned global descriptor heap addressed by opaque 32-bit GpuDescriptorHandle values. VK_EXT_descriptor_buffer is a required Vulkan device capability and is the renderer's sole descriptor transport.

The heap supplies raster mesh and frame data, material textures and samplers, deferred and AVBOIT targets, scene and light buffers, CSG resources, traversal geometry, ray/GI/shadow data, TLAS bindings, and custom UI texture/sampler bindings.

Required Vulkan Contract

Device selection requires the descriptor-buffer feature and command entry points, plus the shader indexing features used by heap access:

  • descriptorIndexing
  • runtimeDescriptorArray
  • shaderSampledImageArrayNonUniformIndexing
  • shaderStorageBufferArrayNonUniformIndexing

descriptorBindingPartiallyBound and descriptorBindingVariableDescriptorCount are not part of the required feature floor.

DescriptorBufferManager owns persistently mapped resource and sampler segments. It obtains driver-sized bytes through vkGetDescriptorEXT, suballocates aligned blocks, binds the segments with vkCmdBindDescriptorBuffersEXT, and selects blocks with vkCmdSetDescriptorBufferOffsetsEXT.

There is no classic descriptor-set, descriptor-pool, update-after-bind, or variable-count transport in renderer code.

Handles And Lifetime

GpuDescriptorHeap allocates stable typed slots, writes descriptors, tracks command-buffer use, and collects deferred frees.

Readiness and bind checks scan only allocated slots below the per-namespace nextFresh high-water mark (freed slots stay below it until clear() resets it), rather than the full backing arrays.

  1. The owner creates or validates the backing GPU resource.
  2. It allocates and writes the matching heap slot.
  3. It publishes the valid handle to renderer or shader-visible state.
  4. A command buffer registers heap use before reading the slot.
  5. Accepted submission associates that use with a queue timeline; abandoned recording discards it.
  6. A freed slot returns to the free list only after every earlier registered use completes or is discarded.

Heap-use admission IDs increase, and collection preserves their order. Retirement decisions advance one completed prefix through the relevant uses for the locked queue-completion snapshot, instead of rescanning the same uses for each retired slot. The first incomplete use blocks only slots whose required admission range includes it. Uses from queues absent from the snapshot remain incomplete; slot freeing and later heap-use compaction retain their existing order.

When a backing resource grows or a target is recreated, the owner publishes a new handle before retiring the prior one.

Heap Sets And Bindings

The shared host/shader ABI is defined in impl/assets/graphics/bindless/binding_slots.h.

Symbol Value Meaning
NWB_BINDLESS_HEAP_RESOURCE_SET 0 resource table
NWB_BINDLESS_HEAP_SAMPLER_SET 1 sampler table
NWB_BINDLESS_HEAP_ACCEL_STRUCT_SET 2 generation-specific TLAS block
sampled image binding 0 sampled images
storage image binding 1 storage images
sampled buffer binding 2 sampled buffers
storage buffer binding 3 raw, structured, and writable buffers
uniform buffer binding 4 constant buffers
sampled 2D-array binding 5 2D-array textures
sampled 3D binding 6 3D textures
sampled uint 2D-array binding 7 unsigned 2D-array textures
sampled cube binding 8 cube textures
sampler binding 0 in set 1 samplers
acceleration-structure binding 0 in set 2 TLAS

Every pipeline layout is descriptor-buffer compatible. Pipeline-local layouts carry push constants only. Each TLAS generation owns an immutable descriptor-buffer block so replacing a TLAS cannot overwrite a descriptor visible to in-flight work.

Material Resources

A material .bind file declares plain texture2d and sampler fields in a material_constant block. The matching block/field entries in asset.parameters supply engine/ or project/ paths.

The cooker stores:

  • block and field identity
  • resource kind and source
  • asset-name hash
  • constant-byte offset

It does not store a heap handle. Runtime loading reconstructs AssetRef<Texture> or AssetRef<Sampler>; the renderer loads and caches that typed asset, resolves its heap slot, and patches a working copy of the material constant bytes.

Shader Access

Shader accessors live under impl/assets/graphics/bindless/:

  • bindless_heap.slangi: image, sampler, buffer, uniform, and TLAS accessors
  • bindless_heap_bvh.slangi: structured BVH-node access
  • bindless_heap_mesh.slangi: typed raster mesh and frame views

Dynamic indexes use non-uniform access helpers and must match the declared descriptor class.

Queue Sharing

The resource and sampler backing segments declare their Graphics/Compute sharing intent. They become Vulkan-concurrent only when the active physical queues use distinct families. Otherwise they keep an exclusive sharing contract. Graph tasks import those segments so queue routing and lifetime remain visible to the compiler.

Source Map

  • core/graphics/rhi/gpu_descriptor_heap.h: handle and heap API
  • core/graphics/vulkan/gpu_descriptor_heap.cpp: Device-owned heap and TLAS lifetime
  • core/graphics/vulkan/gpu_descriptor_heap_descriptor_buffer.cpp: descriptor-buffer implementation
  • core/graphics/rhi/binding.h: resource layout contract
  • core/graphics/vulkan/resource_bindings*.cpp: layout, write, and bind commands
  • impl/assets/graphics/bindless/: host/shader ABI and typed accessors
  • impl/ecs_render/shared/renderer_frame_types.h: renderer slot records
  • impl/ecs_render/raytrace/rt_swbvh_scene_swbvh.cpp and impl/ecs_render/raytrace/rt_swbvh_mesh_swbvh_prep.cpp: software scene/mesh BVH traversal-geometry registration (plus rt_swbvh_scene_tlas.cpp, rt_swbvh_mesh_blas.cpp, rt_swbvh_mesh_build.cpp, and rt_swbvh_bvh_infra.cpp for the scene TLAS, mesh BLAS, mesh build, and shared BVH infrastructure) Startup and rendering coverage uses selected public runtime smoke contracts.

See GPU Task Graph for ordering and Shader and Material System for material authoring.

⚠️ **GitHub.com Fallback** ⚠️