Planning: Resource binding cleanup
This would make sense after the storage-buffer update:
General idea is to allow more flexibility when mapping the sokol-gfx 'bind slot convention' to the backend API bind slots.
- Get rid of shader stages in
sg_bindings:
typedef struct sg_bindings {
uint32_t _start_canary;
sg_buffer vertex_buffers[SG_MAX_VERTEXBUFFER_BINDINGS];
int vertex_buffer_offsets[SG_MAX_VERTEXBUFFER_BINDINGS];
sg_buffer index_buffer;
int index_buffer_offset;
sg_image images[SG_MAX_IMAGE_BINDINGS];
sg_sampler samplers[SG_MAX_SAMPLER_BINDINGS];
sg_buffer storage_buffers[SG_MAX_STORAGEBUFFER_BINDINGS];
uint32_t _end_canary;
} sg_bindings;
The sg_shader_desc needs to provide a mapping from those unified "sokol-gfx bindslots" to shader stages and (probably backend-API specific) concrete bind slots (typically generated by sokol-shdc).
-
Q: also get rid of the 'implicit' backend-specific bind slot indices? This means the sg_shader_desc bind slot-mapping needs backend-specific slot indices (which is probably more transparent to the user)
-
while at it also get rid of the stage param in
sg_apply_uniforms()(and provide a mapping in sg_shader_desc instead for backends which need this) -
TL;DR: SG_SHADERSTAGE_VS/FS should only show up in sg_shader_desc.
Planning braindump:
- except for the simplified
sg_bindingsinterior, no code changes should be required if sokol-shdc is used - remove (most of) the obscure hardwired bindslot relationship between the 'sokol bind model' and backend bind models by introducing a mapping from sokol bind slots to backend API bindings
- allow gaps in the sokol bind slots, and don't complain if an sg_bindings struct has an occupied but 'unmapped' resource slot (this allows to re-use the same sg_bindings struct for different shader variants)
- in sokol-shdc, add an optional
@binding [type] [name] [slot]tag which allows to define a manual mapping from shader resources to sokol bind slots,typeis one ofuniform,image,sampler,storagebuffer, if those tags are missing, sokol-shdc will create an automatic mapping (Q: what if only sample slots are explicitly mapped?) - get rid of shader stages in the public API, they are now only a 3D-backend-specific detail in the sg_shader_desc bind slot mapping
The sokol-gfx resource binding model is:
- one 'bind space' per resource type, and across all shader stages:
- 1..X uniform bindings (the 'slot_index' in
sg_apply_uniforms()) - 1..Y image bindings (the index in
sg_bindings.images[]) - 1..Y sampler bindings (the index
sg_bindings.samplers[]) - 1..Z storage buffer bindings (the index in
sg_bindings.storabe_buffers[])
- 1..X uniform bindings (the 'slot_index' in
The following information is required in sg_shader_desc to map sokol-gfx bind slots to 3D backend API bindings:
- uniforms:
- GL:
- same as now (either a single name of a flattened array per uniform block, or a list of uniforms to be updated with a single sg_apply_uniforms call)
- D3D11:
- the shader stage
- the
Nin...: register(bN)
- Metal:
- the shader stage
- the buffer bind slot (
buffer(N)- shared bind space with vertex- and storage-buffers!) - still need hardwired reserved slots for vertex-buffers!)
- WebGPU:
- a slot index in hardwired
@group(0)(@group(0)is reserved for uniforms)
- a slot index in hardwired
- GL:
- images:
- GL:
- TBD (tricky because of combined-image-samplers...)
- D3D11:
- the shader stage
- the
Nin...: register(tN)(shared bind space with storage buffers!)
- Metal:
- the shader stage
- the texture bind slot (
texture(N))
- WebGPU:
- a slot index in
@group(1)(@group(1)is reserved for images, sampler, storage buffers across all stages)
- a slot index in
- GL:
- samplers:
- GL:
- TBD (tricky because of combined image samplers...)
- D3D11
- the shader stage
- the
Nin...: register(sN)
- Metal:
- the shader stage
- the sampler bind slot (
sampler(N))
- WebGPU
- a slot index in
@group(1)(@group(1)is reserved for images, sampler, storage buffers across all stages)
- a slot index in
- GL:
- storage buffers:
- GL:
- TBD
- D3D11:
- the shader stage
- the
Nin...: register(tN)(shared bind space with textures!)
- Metal
- the shader stage
- the buffer bind slot (
buffer(N)- shared bind space with vertex- and storage-buffers!)
- WebGPU
- a slot index in
@group(1)(@group(1)is reserved for images, sampler, storage buffers across all stages)
- a slot index in
- GL: