summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-05-28 23:24:08 +0200
committerMarek Olšák <[email protected]>2015-07-23 00:59:27 +0200
commitfb800b3dcd32ddb6f57143b46105d677eb01da80 (patch)
treed4ff07137695c7484afabdc8ebb6474b3fd9b184 /src/glsl
parent0cfac917554aeb46bd78ba5b5f5ee1c8ed1d68bc (diff)
glsl: don't lower variable indexing on non-patch tessellation inputs/outputs
There is no way to lower them, because the array sizes are unknown at compile time. Based on a patch from: Fabian Bieler <[email protected]> v2: add comments Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ir_optimization.h5
-rw-r--r--src/glsl/lower_variable_index_to_cond_assign.cpp58
-rw-r--r--src/glsl/test_optpass.cpp3
3 files changed, 50 insertions, 16 deletions
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 688a5e18ea3..a174c9683a1 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -114,8 +114,9 @@ bool lower_discard(exec_list *instructions);
void lower_discard_flow(exec_list *instructions);
bool lower_instructions(exec_list *instructions, unsigned what_to_lower);
bool lower_noise(exec_list *instructions);
-bool lower_variable_index_to_cond_assign(exec_list *instructions,
- bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
+bool 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);
bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz);
bool lower_const_arrays_to_uniforms(exec_list *instructions);
bool lower_clip_distance(gl_shader *shader);
diff --git a/src/glsl/lower_variable_index_to_cond_assign.cpp b/src/glsl/lower_variable_index_to_cond_assign.cpp
index 4a6a76c4eba..1ab3afecc7e 100644
--- a/src/glsl/lower_variable_index_to_cond_assign.cpp
+++ b/src/glsl/lower_variable_index_to_cond_assign.cpp
@@ -335,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;
@@ -348,6 +350,8 @@ public:
}
bool progress;
+
+ gl_shader_stage stage;
bool lower_inputs;
bool lower_outputs;
bool lower_temps;
@@ -369,18 +373,44 @@ public:
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_function_in:
case ir_var_const_in:
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;
}
@@ -523,16 +553,18 @@ 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
diff --git a/src/glsl/test_optpass.cpp b/src/glsl/test_optpass.cpp
index ac3e3f48c51..fed1fabf301 100644
--- a/src/glsl/test_optpass.cpp
+++ b/src/glsl/test_optpass.cpp
@@ -124,7 +124,8 @@ do_optimization(struct exec_list *ir, const char *optimization,
} else if (sscanf(optimization, "lower_variable_index_to_cond_assign "
"( %d , %d , %d , %d ) ", &int_0, &int_1, &int_2,
&int_3) == 4) {
- return lower_variable_index_to_cond_assign(ir, int_0 != 0, int_1 != 0,
+ return lower_variable_index_to_cond_assign(MESA_SHADER_VERTEX, ir,
+ int_0 != 0, int_1 != 0,
int_2 != 0, int_3 != 0);
} else if (sscanf(optimization, "lower_quadop_vector ( %d ) ",
&int_0) == 1) {