i965: Use MESA_FORMAT_B8G8R8X8_SRGB for RGB visuals
[mesa.git] / src / glsl / lower_variable_index_to_cond_assign.cpp
index f8e4a1de428a1566bb90d2921d318adc3798df01..a1ba9345e329d0b75d4499eb74b6cb6217052546 100644 (file)
@@ -76,7 +76,7 @@ compare_index_block(exec_list *instructions, ir_variable *index,
    ir_rvalue *broadcast_index = new(mem_ctx) ir_dereference_variable(index);
 
    assert(index->type->is_scalar());
-   assert(index->type->base_type == GLSL_TYPE_INT);
+   assert(index->type->base_type == GLSL_TYPE_INT || index->type->base_type == GLSL_TYPE_UINT);
    assert(components >= 1 && components <= 4);
 
    if (components > 1) {
@@ -99,7 +99,7 @@ compare_index_block(exec_list *instructions, ir_variable *index,
 
    ir_rvalue *const condition_val =
       new(mem_ctx) ir_expression(ir_binop_equal,
-                                &glsl_type::bool_type[components - 1],
+                                glsl_type::bvec(components),
                                 broadcast_index,
                                 test_indices);
 
@@ -117,11 +117,12 @@ compare_index_block(exec_list *instructions, ir_variable *index,
 }
 
 static inline bool
-is_array_or_matrix(const ir_instruction *ir)
+is_array_or_matrix(const ir_rvalue *ir)
 {
    return (ir->type->is_array() || ir->type->is_matrix());
 }
 
+namespace {
 /**
  * Replace a dereference of a variable with a specified r-value
  *
@@ -191,6 +192,12 @@ struct assignment_generator
    ir_variable* var;
 
    assignment_generator()
+      : base_ir(NULL),
+        rvalue(NULL),
+        old_index(NULL),
+        is_write(false),
+        write_mask(0),
+        var(NULL)
    {
    }
 
@@ -328,12 +335,14 @@ struct switch_generator
 
 class variable_index_to_cond_assign_visitor : public ir_rvalue_visitor {
 public:
-   variable_index_to_cond_assign_visitor(bool lower_input,
-                                        bool lower_output,
-                                        bool lower_temp,
-                                        bool lower_uniform)
+   variable_index_to_cond_assign_visitor(gl_shader_stage stage,
+                                         bool lower_input,
+                                         bool lower_output,
+                                         bool lower_temp,
+                                         bool lower_uniform)
    {
       this->progress = false;
+      this->stage = stage;
       this->lower_inputs = lower_input;
       this->lower_outputs = lower_output;
       this->lower_temps = lower_temp;
@@ -341,6 +350,8 @@ public:
    }
 
    bool progress;
+
+   gl_shader_stage stage;
    bool lower_inputs;
    bool lower_outputs;
    bool lower_temps;
@@ -358,18 +369,52 @@ public:
       if (var == NULL)
         return this->lower_temps;
 
-      switch (var->mode) {
+      switch (var->data.mode) {
       case ir_var_auto:
       case ir_var_temporary:
         return this->lower_temps;
+
       case ir_var_uniform:
+      case ir_var_shader_storage:
         return this->lower_uniforms;
-      case ir_var_in:
+
+      case ir_var_shader_shared:
+        return false;
+
+      case ir_var_function_in:
       case ir_var_const_in:
-        return (var->location == -1) ? this->lower_temps : this->lower_inputs;
-      case ir_var_out:
-        return (var->location == -1) ? this->lower_temps : this->lower_outputs;
-      case ir_var_inout:
+         return this->lower_temps;
+
+      case ir_var_shader_in:
+         /* The input array size is unknown at compiler time for non-patch
+          * inputs in TCS and TES. The arrays are sized to
+          * the implementation-dependent limit "gl_MaxPatchVertices", but
+          * the real size is stored in the "gl_PatchVerticesIn" built-in
+          * uniform.
+          *
+          * The TCS input array size is specified by
+          * glPatchParameteri(GL_PATCH_VERTICES).
+          *
+          * The TES input array size is specified by the "vertices" output
+          * layout qualifier in TCS.
+          */
+         if ((stage == MESA_SHADER_TESS_CTRL ||
+              stage == MESA_SHADER_TESS_EVAL) && !var->data.patch)
+            return false;
+         return this->lower_inputs;
+
+      case ir_var_function_out:
+         /* TCS non-patch outputs can only be indexed with "gl_InvocationID".
+          * Other expressions are not allowed.
+          */
+         if (stage == MESA_SHADER_TESS_CTRL && !var->data.patch)
+            return false;
+         return this->lower_temps;
+
+      case ir_var_shader_out:
+         return this->lower_outputs;
+
+      case ir_var_function_inout:
         return this->lower_temps;
       }
 
@@ -508,17 +553,21 @@ public:
    }
 };
 
+} /* anonymous namespace */
+
 bool
-lower_variable_index_to_cond_assign(exec_list *instructions,
-                                   bool lower_input,
-                                   bool lower_output,
-                                   bool lower_temp,
-                                   bool lower_uniform)
+lower_variable_index_to_cond_assign(gl_shader_stage stage,
+                                    exec_list *instructions,
+                                    bool lower_input,
+                                    bool lower_output,
+                                    bool lower_temp,
+                                    bool lower_uniform)
 {
-   variable_index_to_cond_assign_visitor v(lower_input,
-                                          lower_output,
-                                          lower_temp,
-                                          lower_uniform);
+   variable_index_to_cond_assign_visitor v(stage,
+                                           lower_input,
+                                           lower_output,
+                                           lower_temp,
+                                           lower_uniform);
 
    /* Continue lowering until no progress is made.  If there are multiple
     * levels of indirection (e.g., non-constant indexing of array elements and