Last active
November 26, 2025 16:00
-
-
Save cwfitzgerald/64685976d8ff96e421862d42b9704df5 to your computer and use it in GitHub Desktop.
Strawman WebGPU Bindless API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ///// Rust strawman API for Resource Tables ///// | |
| bitflags! { | |
| struct Features : u64 { | |
| // Supports only sampled texture + samplers in resource tables | |
| const SAMPLING_RESOURCE_TABLE = ..; | |
| // Supports all non-uniform resource types in resource tables | |
| const FULL_RESOURCE_TABLE = ..; | |
| } | |
| } | |
| struct Limits { | |
| // Maximum size of any single resource table. Higher is better. | |
| // Default something like 100k. | |
| max_resource_table_size: u32, | |
| // .. | |
| } | |
| struct PipelineLayoutDescriptor { | |
| resource_table_available: bool, | |
| // .. | |
| }; | |
| struct ResourceTableDescriptor { | |
| /// Maximum number of bindings in the resource table. | |
| size: u32, | |
| } | |
| impl Device { | |
| /// Creates a new resource table. The expectation is that there would be | |
| /// a relatively small number of these created during application lifetime, | |
| /// mostly for composability purposes. | |
| fn create_resource_table(ResourceTableDescriptor descriptor) -> ResourceTable; | |
| } | |
| enum BindingInUseError { | |
| BindingInUse, | |
| OutOfBounds(..), | |
| // ... | |
| } | |
| enum NoFreeBindingError { | |
| NoFreeBinding, | |
| /// ... | |
| } | |
| enum RemoveBindingError { | |
| AlreadyInUse, | |
| /// ... | |
| } | |
| struct ResourceTable { | |
| fn destroy(); | |
| /// Immediately updates the binding at the given index. The index must be unused. | |
| /// | |
| /// BindingResource::*Array() variants are not allowed here and would be eventually removed. | |
| fn update(index: u32, entry: BindingResource) -> Result<(), BindingInUseError>; | |
| /// Inserts a binding at some index in the table. If there are no free slots, return an error. | |
| /// | |
| /// This function is guarenteed to return the _lowest_ index currently free slot. | |
| /// | |
| /// BindingResource::*Array() variants are not allowed here and would be eventually removed. | |
| fn insert_binding(entry: BindingResource) -> Result<u32, NoFreeBindingError>; | |
| /// Queues an operation that removes the given binding from the index. The index may | |
| /// not be re-used until after queue.on_submitted_work_done() would have completed. | |
| /// | |
| /// See https://github.com/gpuweb/gpuweb/blob/main/proposals/bindless.md#updates-of-bindings-in-dynamic-binding-arrays | |
| /// for more discussion. | |
| fn remove_binding(index: u32) -> Result<(), RemoveBindingError>; | |
| }; | |
| impl CommandEncoder { | |
| /// Can only ever have one bound resource table at a time. This should | |
| /// be expected to be relatively expensive, so avoid changing | |
| /// it frequently. | |
| fn set_resource_table(ResourceTable table); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Strawman WGSL Syntax | |
| fn resourceTableLength() -> u32; | |
| fn getBinding<T>(index: u32) -> T | |
| where T: texture_*; | |
| fn hasBinding<T>(index: u32) -> bool; | |
| fn getBufferAt<T>(index: u32, offset: u32) -> T | |
| where T: StorageBufferCompatibleType; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Strawman GLSL/SPIR-V injestion syntax | |
| // All binding arrays bound to the shader will be redirected | |
| // to the resource table, regardless of their original binding numbers. | |
| // All point to the same heap. Can do vulkan style type aliasing. | |
| layout(set = 0, binding = 0) uniform texture2D myTextureArray[]; | |
| layout(set = 1, binding = 1) uniform texture3D myTextureArray[]; | |
| layout(set = 2, binding = 2) buffer MyBufferArray { | |
| uint data[]; | |
| } myBufferArray[]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Strawman BDA deguaring, using Slang for conciceness | |
| T* my_ptr; | |
| // OMG pointer addition + BDA | |
| my_ptr += 12; | |
| T = *my_ptr; | |
| // Pointer desugars to 32bit index into resource table and 32bit offset into buffer. | |
| // This behavior is well defined for wgpu-native-compatible spirv ingestion. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment