summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir.cpp
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-08-25 23:27:56 -0700
committerEric Anholt <[email protected]>2010-08-25 23:43:21 -0700
commitc735d85395f8f0c0a71b04ebc728390970271fe2 (patch)
tree1c6573e8fcfa8ff61c20c575b2d82052decf4a54 /src/glsl/ir.cpp
parentaa2f55883b9a4e8a192c5dcc97ae7fdab2a33e0a (diff)
glsl: Don't consider things with a type containing a sampler as an lvalue.
We had ad-hoc handled some common cases by flagging sampler-typed variables as read_only, and rejected initializers of samplers. However, people could sneak them in in all sorts of surprising ways, like using whole-array or structure assignment. Fixes: glslparsertest/glsl2/sampler-01.frag glslparsertest/glsl2/sampler-03.frag glslparsertest/glsl2/sampler-04.frag glslparsertest/glsl2/sampler-06.frag Bug #27403.
Diffstat (limited to 'src/glsl/ir.cpp')
-rw-r--r--src/glsl/ir.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index e5ed10d3e42..31e40cac8c6 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -697,6 +697,20 @@ ir_dereference_record::ir_dereference_record(ir_variable *var,
? this->record->type->field_type(field) : glsl_type::error_type;
}
+bool type_contains_sampler(const glsl_type *type)
+{
+ if (type->is_array()) {
+ return type_contains_sampler(type->fields.array);
+ } else if (type->is_record()) {
+ for (unsigned int i = 0; i < type->length; i++) {
+ if (type_contains_sampler(type->fields.structure[i].type))
+ return true;
+ }
+ return false;
+ } else {
+ return type->is_sampler();
+ }
+}
bool
ir_dereference::is_lvalue()
@@ -711,6 +725,15 @@ ir_dereference::is_lvalue()
if (this->type->is_array() && !var->array_lvalue)
return false;
+ /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "Samplers cannot be treated as l-values; hence cannot be used
+ * as out or inout function parameters, nor can they be
+ * assigned into."
+ */
+ if (type_contains_sampler(this->type))
+ return false;
+
return true;
}