Skip to content

Commit 357d24b

Browse files
committed
Add glslc options to set binding base for uniforms
Supports uniform kinds: image, texture, sampler, ubo. Optionally limit the effect to a specific shader stage.
1 parent 735a541 commit 357d24b

7 files changed

Lines changed: 142 additions & 91 deletions

File tree

glslc/src/main.cc

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,19 @@ An input file of - represents standard input.
5656
Automatically assign bindings to uniform variables that
5757
don't have an explicit 'binding' layout in the shader
5858
source.
59-
-fimage-binding-base=<value>
59+
-fimage-binding-base [stage] <value>
6060
Sets the lowest automatically assigned binding number for
61-
images.
62-
-ftexture-binding-base=<value>
61+
images. Optionally only set it for a single shader stage.
62+
-ftexture-binding-base [stage] <value>
6363
Sets the lowest automatically assigned binding number for
64-
textures.
65-
-fsampler-binding-base=<value>
64+
textures. Optionally only set it for a single shader stage.
65+
-fsampler-binding-base [stage] <value>
6666
Sets the lowest automatically assigned binding number for
67-
samplers.
68-
-fubo-binding-base=<value>
67+
samplers Optionally only set it for a single shader stage.
68+
-fubo-binding-base [stage] <value>
6969
Sets the lowest automatically assigned binding number for
70-
uniform buffer objects (UBO).
70+
uniform buffer objects (UBO). Optionally only set it for
71+
a single shader stage.
7172
-fentry-point=<name>
7273
Specify the entry point name for HLSL compilation, for
7374
all subsequent source files. Default is "main".
@@ -81,8 +82,8 @@ An input file of - represents standard input.
8182
Set limits as specified in the given file.
8283
-fshader-stage=<stage>
8384
Treat subsequent input files as having stage <stage>.
84-
Valid stages are vertex, fragment, tesscontrol, tesseval,
85-
geometry, and compute.
85+
Valid stages are vertex, vert, fragment, frag, tesscontrol,
86+
tesc, tesseval, tese, geometry, geom, compute, and comp.
8687
-g Generate source-level debug information.
8788
Currently this option has no effect.
8889
--help Display available options.
@@ -120,7 +121,7 @@ An input file of - represents standard input.
120121
// Gets the option argument for the option at *index in argv in a way consistent
121122
// with clang/gcc. On success, returns true and writes the parsed argument into
122123
// *option_argument. Returns false if any errors occur. After calling this
123-
// function, *index will the index of the last command line argument consumed.
124+
// function, *index will be the index of the last command line argument consumed.
124125
bool GetOptionArgument(int argc, char** argv, int* index,
125126
const std::string& option,
126127
string_piece* option_argument) {
@@ -235,6 +236,8 @@ int main(int argc, char** argv) {
235236
glslc::FileCompiler compiler;
236237
bool success = true;
237238
bool has_stdin_input = false;
239+
shaderc_shader_kind arg_stage; // Shader stage for a single option.
240+
uint32_t arg_base; // binding base for a single option.
238241

239242
for (int i = 1; i < argc; ++i) {
240243
const string_piece arg = argv[i];
@@ -279,50 +282,46 @@ int main(int argc, char** argv) {
279282
}
280283
} else if (arg == "-fauto-bind-uniforms") {
281284
compiler.options().SetAutoBindUniforms(true);
282-
} else if (arg.starts_with("-fimage-binding-base=")) {
283-
auto result = ParseNumber<uint32_t>(
284-
arg.substr(std::strlen("-fimage-binding-base=")).str());
285-
if (result.first) {
286-
compiler.options().SetBindingBase(shaderc_uniform_kind_image,
287-
result.second);
288-
} else {
289-
std::cerr << "glslc: error: invalid value for -fimage-binding-base"
290-
<< std::endl;
285+
} else if (arg == "-fimage-binding-base") {
286+
const auto kind = shaderc_uniform_kind_image;
287+
if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
288+
&arg_stage, &arg_base)) {
291289
return 1;
292290
}
293-
} else if (arg.starts_with("-ftexture-binding-base=")) {
294-
auto result = ParseNumber<uint32_t>(
295-
arg.substr(std::strlen("-ftexture-binding-base=")).str());
296-
if (result.first) {
297-
compiler.options().SetBindingBase(shaderc_uniform_kind_texture,
298-
result.second);
299-
} else {
300-
std::cerr << "glslc: error: invalid value for -ftexture-binding-base"
301-
<< std::endl;
291+
if (arg_stage == shaderc_glsl_infer_from_source)
292+
compiler.options().SetBindingBase(kind, arg_base);
293+
else
294+
compiler.options().SetBindingBaseForStage(arg_stage, kind, arg_base);
295+
} else if (arg == "-ftexture-binding-base") {
296+
const auto kind = shaderc_uniform_kind_texture;
297+
if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
298+
&arg_stage, &arg_base)) {
302299
return 1;
303300
}
304-
} else if (arg.starts_with("-fsampler-binding-base=")) {
305-
auto result = ParseNumber<uint32_t>(
306-
arg.substr(std::strlen("-fsampler-binding-base=")).str());
307-
if (result.first) {
308-
compiler.options().SetBindingBase(shaderc_uniform_kind_sampler,
309-
result.second);
310-
} else {
311-
std::cerr << "glslc: error: invalid value for -fsampler-binding-base"
312-
<< std::endl;
301+
if (arg_stage == shaderc_glsl_infer_from_source)
302+
compiler.options().SetBindingBase(kind, arg_base);
303+
else
304+
compiler.options().SetBindingBaseForStage(arg_stage, kind, arg_base);
305+
} else if (arg == "-fsampler-binding-base") {
306+
const auto kind = shaderc_uniform_kind_sampler;
307+
if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
308+
&arg_stage, &arg_base)) {
313309
return 1;
314310
}
315-
} else if (arg.starts_with("-fubo-binding-base=")) {
316-
auto result = ParseNumber<uint32_t>(
317-
arg.substr(std::strlen("-fubo-binding-base=")).str());
318-
if (result.first) {
319-
compiler.options().SetBindingBase(shaderc_uniform_kind_buffer,
320-
result.second);
321-
} else {
322-
std::cerr << "glslc: error: invalid value for -fubo-binding-base"
323-
<< std::endl;
311+
if (arg_stage == shaderc_glsl_infer_from_source)
312+
compiler.options().SetBindingBase(kind, arg_base);
313+
else
314+
compiler.options().SetBindingBaseForStage(arg_stage, kind, arg_base);
315+
} else if (arg == "-fubo-binding-base") {
316+
const auto kind = shaderc_uniform_kind_buffer;
317+
if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
318+
&arg_stage, &arg_base)) {
324319
return 1;
325320
}
321+
if (arg_stage == shaderc_glsl_infer_from_source)
322+
compiler.options().SetBindingBase(kind, arg_base);
323+
else
324+
compiler.options().SetBindingBaseForStage(arg_stage, kind, arg_base);
326325
} else if (arg.starts_with("-fentry-point=")) {
327326
current_entry_point_name =
328327
arg.substr(std::strlen("-fentry-point=")).str();

glslc/src/shader_stage.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ namespace glslc {
3333
shaderc_shader_kind MapStageNameToForcedKind(const string_piece& stage_name) {
3434
const StageMapping string_to_kind[] = {
3535
{"vertex", shaderc_glsl_vertex_shader},
36+
{"vert", shaderc_glsl_vertex_shader},
3637
{"fragment", shaderc_glsl_fragment_shader},
38+
{"frag", shaderc_glsl_fragment_shader},
3739
{"tesscontrol", shaderc_glsl_tess_control_shader},
40+
{"tesc", shaderc_glsl_tess_control_shader},
3841
{"tesseval", shaderc_glsl_tess_evaluation_shader},
42+
{"tese", shaderc_glsl_tess_evaluation_shader},
3943
{"geometry", shaderc_glsl_geometry_shader},
40-
{"compute", shaderc_glsl_compute_shader}};
44+
{"geom", shaderc_glsl_geometry_shader},
45+
{"compute", shaderc_glsl_compute_shader},
46+
{"comp", shaderc_glsl_compute_shader}};
4147
for (const auto& entry : string_to_kind) {
4248
if (stage_name == entry.id) return entry.stage;
4349
}

glslc/src/shader_stage.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222

2323
namespace glslc {
2424

25+
// Maps a shader stage name to a forced shader stage enum value. Returns
26+
// 'shaderc_glsl_infer_from_source' if the stage name is unrecognized.
27+
shaderc_shader_kind MapStageNameToForcedKind(
28+
const shaderc_util::string_piece& f_shader_stage_str);
29+
2530
// Parse the string piece from command line to get the force shader stage.
2631
// If the 'f_shader_stage_str' cannot be parsed to a valid force shader stage,
27-
// returns 'shaderc_glsl_infer_from_source' and an error should be emitted at
28-
// the caller site.
32+
// returns 'shaderc_glsl_infer_from_source'. Requires the string to begin with
33+
// '='.
2934
shaderc_shader_kind GetForcedShaderKindFromCmdLine(
3035
const shaderc_util::string_piece& f_shader_stage_str);
3136

glslc/test/option_fauto_bind_uniforms.py

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class FImageBindingBaseOptionRespectedOnImage(expect.ValidAssemblyFileWithSubstr
5757
"""Tests that -fimage-binding-base value is respected on images."""
5858

5959
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
60-
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base=44']
60+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', '44']
6161
expected_assembly_substr = "OpDecorate %my_img Binding 44"
6262

6363

@@ -66,7 +66,7 @@ class FImageBindingBaseOptionRespectedOnImageBuffer(expect.ValidAssemblyFileWith
6666
"""Tests that -fimage-binding-base value is respected on image buffers."""
6767

6868
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
69-
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base=44']
69+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', '44']
7070
expected_assembly_substr = "OpDecorate %my_imbuf Binding 45"
7171

7272

@@ -75,7 +75,7 @@ class FTextureBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
7575
"""Tests that -ftexture-binding-base value is respected."""
7676

7777
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
78-
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-ftexture-binding-base=44']
78+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-ftexture-binding-base', '44']
7979
expected_assembly_substr = "OpDecorate %my_tex Binding 44"
8080

8181

@@ -84,7 +84,7 @@ class FSamplerBindingBaseOptionRespected(expect.ValidAssemblyFileWithSubstr):
8484
"""Tests that -fsampler-binding-base value is respected."""
8585

8686
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
87-
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fsampler-binding-base=44']
87+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fsampler-binding-base', '44']
8888
expected_assembly_substr = "OpDecorate %my_sam Binding 44"
8989

9090

@@ -93,7 +93,7 @@ class FUboBindingBaseOptionRespectedOnBuffer(expect.ValidAssemblyFileWithSubstr)
9393
"""Tests that -fubo-binding-base value is respected."""
9494

9595
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
96-
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fubo-binding-base=44']
96+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fubo-binding-base', '44']
9797
expected_assembly_substr = "OpDecorate %my_ubo Binding 44"
9898

9999

@@ -102,104 +102,132 @@ class FImageBindingBaseNeedsValue(expect.ErrorMessageSubstr):
102102
"""Tests that -fimage-binding-base requires a value."""
103103

104104
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
105-
glslc_args = ['-S', shader, '-fimage-binding-base=']
106-
expected_error_substr = "error: invalid value for -fimage-binding-base"
105+
glslc_args = ['-S', shader, '-fimage-binding-base']
106+
expected_error_substr = "error: Option -fimage-binding-base requires at least one argument"
107107

108108

109109
@inside_glslc_testsuite('OptionFAutoBindUniforms')
110110
class FTextureBindingBaseNeedsValue(expect.ErrorMessageSubstr):
111111
"""Tests that -ftexture-binding-base requires a value."""
112112

113113
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
114-
glslc_args = ['-S', shader, '-ftexture-binding-base=']
115-
expected_error_substr = "error: invalid value for -ftexture-binding-base"
114+
glslc_args = ['-S', shader, '-ftexture-binding-base']
115+
expected_error_substr = "error: Option -ftexture-binding-base requires at least one argument"
116116

117117

118118
@inside_glslc_testsuite('OptionFAutoBindUniforms')
119119
class FSamplerBindingBaseNeedsValue(expect.ErrorMessageSubstr):
120120
"""Tests that -fsampler-binding-base requires a value."""
121121

122122
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
123-
glslc_args = ['-S', shader, '-fsampler-binding-base=']
124-
expected_error_substr = "error: invalid value for -fsampler-binding-base"
123+
glslc_args = ['-S', shader, '-fsampler-binding-base']
124+
expected_error_substr = "error: Option -fsampler-binding-base requires at least one argument"
125125

126126

127127
@inside_glslc_testsuite('OptionFAutoBindUniforms')
128128
class FUboBindingBaseNeedsValue(expect.ErrorMessageSubstr):
129129
"""Tests that -fubo-binding-base requires a value."""
130130

131131
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
132-
glslc_args = ['-S', shader, '-fubo-binding-base=']
133-
expected_error_substr = "error: invalid value for -fubo-binding-base"
132+
glslc_args = ['-S', shader, '-fubo-binding-base']
133+
expected_error_substr = "error: Option -fubo-binding-base requires at least one argument"
134134

135135

136136
@inside_glslc_testsuite('OptionFAutoBindUniforms')
137-
class FImageBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
137+
class FImageBindingBaseNeedsNumberValueIfNotStage(expect.ErrorMessageSubstr):
138138
"""Tests that -fimage-binding-base requires a number value."""
139139

140140
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
141-
glslc_args = ['-S', shader, '-fimage-binding-base=9x']
142-
expected_error_substr = "error: invalid value for -fimage-binding-base"
141+
glslc_args = ['-S', shader, '-fimage-binding-base', '9x']
142+
expected_error_substr = "error: invalid offset value 9x for -fimage-binding-base"
143143

144144

145145
@inside_glslc_testsuite('OptionFAutoBindUniforms')
146146
class FTextureBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
147147
"""Tests that -ftexture-binding-base requires a number value."""
148148

149149
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
150-
glslc_args = ['-S', shader, '-ftexture-binding-base=9x']
151-
expected_error_substr = "error: invalid value for -ftexture-binding-base"
150+
glslc_args = ['-S', shader, '-ftexture-binding-base', '9x']
151+
expected_error_substr = "error: invalid offset value 9x for -ftexture-binding-base"
152152

153153

154154
@inside_glslc_testsuite('OptionFAutoBindUniforms')
155155
class FSamplerBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
156156
"""Tests that -fsampler-binding-base requires a number value."""
157157

158158
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
159-
glslc_args = ['-S', shader, '-fsampler-binding-base=9x']
160-
expected_error_substr = "error: invalid value for -fsampler-binding-base"
159+
glslc_args = ['-S', shader, '-fsampler-binding-base', '9x']
160+
expected_error_substr = "error: invalid offset value 9x for -fsampler-binding-base"
161161

162162

163163
@inside_glslc_testsuite('OptionFAutoBindUniforms')
164164
class FUboBindingBaseNeedsNumberValue(expect.ErrorMessageSubstr):
165165
"""Tests that -fubo-binding-base requires a number value."""
166166

167167
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
168-
glslc_args = ['-S', shader, '-fubo-binding-base=9x']
169-
expected_error_substr = "error: invalid value for -fubo-binding-base"
168+
glslc_args = ['-S', shader, '-fubo-binding-base', '9x']
169+
expected_error_substr = "error: invalid offset value 9x for -fubo-binding-base"
170170

171171

172172
@inside_glslc_testsuite('OptionFAutoBindUniforms')
173173
class FImageBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
174174
"""Tests that -fimage-binding-base requires an unsigned number value."""
175175

176176
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
177-
glslc_args = ['-S', shader, '-fimage-binding-base=-6']
178-
expected_error_substr = "error: invalid value for -fimage-binding-base"
177+
glslc_args = ['-S', shader, '-fimage-binding-base', '-6']
178+
expected_error_substr = "error: invalid offset value -6 for -fimage-binding-base"
179179

180180

181181
@inside_glslc_testsuite('OptionFAutoBindUniforms')
182182
class FTextureBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
183183
"""Tests that -ftexture-binding-base requires an unsigned number value."""
184184

185185
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
186-
glslc_args = ['-S', shader, '-ftexture-binding-base=-6']
187-
expected_error_substr = "error: invalid value for -ftexture-binding-base"
186+
glslc_args = ['-S', shader, '-ftexture-binding-base', '-6']
187+
expected_error_substr = "error: invalid offset value -6 for -ftexture-binding-base"
188188

189189

190190
@inside_glslc_testsuite('OptionFAutoBindUniforms')
191191
class FSamplerBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
192192
"""Tests that -fsampler-binding-base requires an unsigned value."""
193193

194194
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
195-
glslc_args = ['-S', shader, '-fsampler-binding-base=-6']
196-
expected_error_substr = "error: invalid value for -fsampler-binding-base"
195+
glslc_args = ['-S', shader, '-fsampler-binding-base', '-6']
196+
expected_error_substr = "error: invalid offset value -6 for -fsampler-binding-base"
197197

198198

199199
@inside_glslc_testsuite('OptionFAutoBindUniforms')
200200
class FUboBindingBaseNeedsUnsignedNumberValue(expect.ErrorMessageSubstr):
201201
"""Tests that -fubo-binding-base requires an unsigned value."""
202202

203203
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
204-
glslc_args = ['-S', shader, '-fubo-binding-base=-6']
205-
expected_error_substr = "error: invalid value for -fubo-binding-base"
204+
glslc_args = ['-S', shader, '-fubo-binding-base', '-6']
205+
expected_error_substr = "error: invalid offset value -6 for -fubo-binding-base"
206+
207+
208+
@inside_glslc_testsuite('OptionFAutoBindUniforms')
209+
class FImageBindingBaseForVertOptionRespectedOnImageCompileAsVert(expect.ValidAssemblyFileWithSubstr):
210+
"""Tests that -fimage-binding-base with vert stage value is respected on images."""
211+
212+
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.vert')
213+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'vert', '44']
214+
expected_assembly_substr = "OpDecorate %my_img Binding 44"
215+
216+
217+
@inside_glslc_testsuite('OptionFAutoBindUniforms')
218+
class FImageBindingBaseForVertOptionIgnoredOnImageCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
219+
"""Tests that -fimage-binding-base with vert stage value is ignored when cmopiled as
220+
fragment."""
221+
222+
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
223+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'vert', '44']
224+
expected_assembly_substr = "OpDecorate %my_img Binding 2"
225+
226+
227+
@inside_glslc_testsuite('OptionFAutoBindUniforms')
228+
class FImageBindingBaseForFragOptionRespectedOnImageCompileAsFrag(expect.ValidAssemblyFileWithSubstr):
229+
"""Tests that -fimage-binding-base with frag stage value is respected on images."""
230+
231+
shader = FileShader(GLSL_SHADER_WITH_UNIFORMS_WITHOUT_BINDINGS, '.frag')
232+
glslc_args = ['-S', shader, '-fauto-bind-uniforms', '-fimage-binding-base', 'frag', '44']
233+
expected_assembly_substr = "OpDecorate %my_img Binding 44"

0 commit comments

Comments
 (0)