google / shaderc

A collection of tools, libraries, and tests for Vulkan shader compilation.
Other
1.83k stars 356 forks source link

document use of Auto bindings for storage buffers. #1349

Open Tonyx97 opened 1 year ago

Tonyx97 commented 1 year ago

Hi, I realized there is auto binding for uniform buffers but not storage buffers, it would be nice to have that feature.

dneto0 commented 1 year ago

This is already supported, but it's not apparent.

Use -fauto-bind-uniforms for both uniform buffer objects and storage buffer objects.

Example:

#version 450

buffer ABuf { uint a; } B;

void main() {
 B.a = 1;
}

Compile with glslc a.comp -fauto-bind-uniforms -o a.spv and it assigns descriptor set 0 and binding 0.

The documentation should be improved, though!

dneto0 commented 1 year ago

The confusion is that UBO and SSBO in the original SPIR-V 1.0 are both in the "Uniform" storage class, and that naming was used for the command line option, when most people think of them as different.

Tonyx97 commented 1 year ago

Hey, I'm currently using shaderc & spirv_cross from C++, using these options:

opts.SetAutoMapLocations(true);
opts.SetAutoBindUniforms(true);
opts.SetPreserveBindings(true);
opts.SetForcedVersionProfile(460, shaderc_profile_core);
opts.SetOptimizationLevel(shaderc_optimization_level_zero);
opts.SetIncluder(std::make_unique<FileIncluder>(stage, extra_info));
opts.SetGenerateDebugInfo();
opts.AddMacroDefinition("stage_" + suffix);
opts.AddMacroDefinition("MAX_TEXTURES_PER_MATERIAL", std::to_string(shader_structs::MAX_TEXTURES_PER_MATERIAL));
opts.AddMacroDefinition("MAX_LIGHTS_PER_TYPE", std::to_string(shader_structs::MAX_LIGHTS_PER_TYPE));
opts.AddMacroDefinition("SAMPLER_CUBE(set_index, name)", "layout (set = set_index) uniform samplerCube name");
opts.AddMacroDefinition("SAMPLER_CUBE_ARRAY(set_index, name)", "layout (set = set_index) uniform samplerCube name[]");
opts.AddMacroDefinition("SAMPLER_TEXTURE(set_index, name)", "layout (set = set_index) uniform sampler2D name");
opts.AddMacroDefinition("SAMPLER_TEXTURE_ARRAY(set_index, name)", "layout (set = set_index) uniform sampler2D name[]");
opts.AddMacroDefinition("IN(type, name)", "in type name");
opts.AddMacroDefinition("OUT(type, name)", "out type name");

However it seems that bindings are not preserved (the auto location binding works perfectly though) and it only takes the bindings that are currently being used, this is a problem because I have 6 different bindings and some are shared between vertex and fragment shader, this leads to binding collision between my shader modules in Vulkan so instead of having a layout with 6 bindings (5 storage buffers and 1 variable size uniform of sampled images), I have a layout with 3 bindings because I merge the bindings from all stages so I can create the layout for the descriptor set used in the pipeline. If I don't merge I get that vertex shader uses 3 bindings (0 to 2) and the same for the fragment shader (same range of binding indices as well). The libraries I'm using for shaderc are shaderc_combinedd.lib and shaderc_combined.lib from the latest Vulkan SDK (1.3.250.1).

Tonyx97 commented 1 year ago

Not sure if it's a problem in my syntax, I've uploaded my shaders and headers, the main shader is basic.vts under shader folder. The rest is headers that basic.vts uses. assets.zip

Note: this is the code that works for me, by hardcoding the binding indices in basic.vts. What I tried is removing the ", binding = BINDING" part from all uniforms and buffers but it didn't work.