floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.84k stars 480 forks source link

Continuous Bind Slots Restriction Unnecessary? #1082

Open kayomn opened 1 month ago

kayomn commented 1 month ago

I wanted to know why the intentional restriction that shader resource bind slots like storage buffers, images, samplers, etc. need to be used contiguously, as seen in this validation code?

bool storage_buffers_continuous = true;
for (int sbuf_index = 0; sbuf_index < SG_MAX_SHADERSTAGE_STORAGEBUFFERS; sbuf_index++) {
  const sg_shader_storage_buffer_desc* sbuf_desc = &stage_desc->storage_buffers[sbuf_index];
  if (sbuf_desc->used) {
    _SG_VALIDATE(storage_buffers_continuous, VALIDATE_SHADERDESC_NO_CONT_STORAGEBUFFERS);
    _SG_VALIDATE(sbuf_desc->readonly, VALIDATE_SHADERDESC_STORAGEBUFFER_READONLY);
  } else {
    storage_buffers_continuous = false;
  }
}

As far as I know, no API backend would require resource slots to be used in a contiguous manner. This just seems like a way of enforcing more boilerplate in shader programs for rendering pipelines that use some standardized bind points for sending their resources across.

I'd be happy to submit a PR to change this behavior, as being able to use bind points in a non-contiguous manner for images / samplers and storage buffers would be a big benefit to something I'm working on that doesn't use Sokol's shdc workflow.

floooh commented 1 month ago

I'm planning to make this more flexible in the future:

https://github.com/floooh/sokol/issues/1037

With this change there would be a proper "custom mapping" between the occupied slot indices in an sg_bindings struct and the actual backend shader stage (vertex/fragment/(and later: compute)) and bind slot, and this mapping may also be different for each 3D backend (differences between different shading languages and the various 3D API resource bindings models was the main reason why the current restriction is in place). But once we allow a different bindings-mapping for different shading language and 3D backends, this restriction should no longer apply.

It's not a trivial change though since it spans the sokol-shdc tool, all 3D backends and also needs changes in the public API, it will also make working with sokol-gfx without the sokol-shdc shader compiler a bit more awkward (since more info needs to be provided in the sg_shader_desc struct.

kayomn commented 1 month ago

What kind of API changes would be needed beyond having to specify a bind slot explicitly on the sg_shader_stage_desc sub-structures?

floooh commented 1 month ago

The change would go together with getting rid of shader stages in the rest of the API (sg_bindings and sg_apply_uniforms), instead a sokol-gfx bind slot would only be defined by a resource type (image vs sampler vs storage buffer) and a slot index, and such a resource-type + slot index would be mapped to 3D backend API specific resource bind slots (which may follow different rules for each backend).

In the sg_shader_desc, such a sokol-gfx bind slot needs to have a 3D backend specific bindinds information.

Off the top of my head:

floooh commented 13 hours ago

Work happens in this branch: https://github.com/floooh/sokol/tree/issue1037_bindings_cleanup