summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2015-05-19 15:01:49 +0300
committerEmil Velikov <emil.l.velikov@gmail.com>2015-07-01 15:22:41 +0100
commit81ac47605f887c9cbf5d2f3a77e7a71a28fbe37f (patch)
tree2f78b8f297756701285e618b0cf1df11727f4511
parentf8ea1430ae0bbaf68f73aa3a706d9112402e396d (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 <tapani.palli@intel.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net> Cc: "10.5" and "10.6" <mesa-stable@lists.freedesktop.org> (cherry picked from commit 9350ea6979c48772e1fb55d4f1c7c5a3cfa987b0) Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Conflicts: src/glsl/linker.cpp
-rw-r--r--src/glsl/linker.cpp78
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);