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) {
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);
return (ir->type->is_array() || ir->type->is_matrix());
}
+namespace {
/**
* Replace a dereference of a variable with a specified r-value
*
ir_variable* var;
assignment_generator()
+ : base_ir(NULL),
+ rvalue(NULL),
+ old_index(NULL),
+ is_write(false),
+ write_mask(0),
+ var(NULL)
{
}
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;
}
bool progress;
+
+ gl_shader_stage stage;
bool lower_inputs;
bool lower_outputs;
bool lower_temps;
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_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;
}
}
};
+} /* 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