diff options
author | Tapani Pälli <[email protected]> | 2015-05-19 15:01:49 +0300 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2015-07-01 15:22:41 +0100 |
commit | 81ac47605f887c9cbf5d2f3a77e7a71a28fbe37f (patch) | |
tree | 2f78b8f297756701285e618b0cf1df11727f4511 /src | |
parent | f8ea1430ae0bbaf68f73aa3a706d9112402e396d (diff) |
glsl: validate sampler array indexing for 'constant-index-expression'
Desktop GLSL < 130 and GLSL ES < 300 allow sampler array indexing where
index can contain a loop induction variable. This extra check will warn
during linking if some of the indexes could not be turned in to constant
expressions.
v2: warning instead of error for backends that did not enable
EmitNoIndirectSampler option (have dynamic indexing)
Signed-off-by: Tapani Pälli <[email protected]>
Reviewed-by: Francisco Jerez <[email protected]>
Cc: "10.5" and "10.6" <[email protected]>
(cherry picked from commit 9350ea6979c48772e1fb55d4f1c7c5a3cfa987b0)
Signed-off-by: Emil Velikov <[email protected]>
Conflicts:
src/glsl/linker.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/linker.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index ef815aec5f1..d8f08b9b8b9 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -345,6 +345,39 @@ private: bool uses_non_zero_stream; }; +/* Class that finds array derefs and check if indexes are dynamic. */ +class dynamic_sampler_array_indexing_visitor : public ir_hierarchical_visitor +{ +public: + dynamic_sampler_array_indexing_visitor() : + dynamic_sampler_array_indexing(false) + { + } + + ir_visitor_status visit_enter(ir_dereference_array *ir) + { + if (!ir->variable_referenced()) + return visit_continue; + + if (!ir->variable_referenced()->type->contains_sampler()) + return visit_continue; + + if (!ir->array_index->constant_expression_value()) { + dynamic_sampler_array_indexing = true; + return visit_stop; + } + return visit_continue; + } + + bool uses_dynamic_sampler_array_indexing() + { + return dynamic_sampler_array_indexing; + } + +private: + bool dynamic_sampler_array_indexing; +}; + } /* anonymous namespace */ void @@ -2479,6 +2512,41 @@ check_explicit_uniform_locations(struct gl_context *ctx, delete uniform_map; } +/** + * This check is done to make sure we allow only constant expression + * indexing and "constant-index-expression" (indexing with an expression + * that includes loop induction variable). + */ +static bool +validate_sampler_array_indexing(struct gl_context *ctx, + struct gl_shader_program *prog) +{ + dynamic_sampler_array_indexing_visitor v; + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + + bool no_dynamic_indexing = + ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler; + + /* Search for array derefs in shader. */ + v.run(prog->_LinkedShaders[i]->ir); + if (v.uses_dynamic_sampler_array_indexing()) { + const char *msg = "sampler arrays indexed with non-constant " + "expressions is forbidden in GLSL %s %u"; + /* Backend has indicated that it has no dynamic indexing support. */ + if (no_dynamic_indexing) { + linker_error(prog, msg, prog->IsES ? "ES" : "", prog->Version); + return false; + } else { + linker_warning(prog, msg, prog->IsES ? "ES" : "", prog->Version); + } + } + } + return true; +} + + void link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) { @@ -2695,6 +2763,16 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir); } + /* Validation for special cases where we allow sampler array indexing + * with loop induction variable. This check emits a warning or error + * depending if backend can handle dynamic indexing. + */ + if ((!prog->IsES && prog->Version < 130) || + (prog->IsES && prog->Version < 300)) { + if (!validate_sampler_array_indexing(ctx, prog)) + goto done; + } + /* Check and validate stream emissions in geometry shaders */ validate_geometry_shader_emissions(ctx, prog); |