glsl: Don't consider things with a type containing a sampler as an lvalue.
authorEric Anholt <eric@anholt.net>
Thu, 26 Aug 2010 06:27:56 +0000 (23:27 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 26 Aug 2010 06:43:21 +0000 (23:43 -0700)
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.

src/glsl/ir.cpp

index e5ed10d3e429ec070b46d639845f1c96ccd10640..31e40cac8c69e4bea1407cf671d7ce3e70b0d0e4 100644 (file)
@@ -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;
 }