summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/ir_set_program_inouts.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2015-11-15 04:22:10 -0800
committerKenneth Graunke <[email protected]>2017-01-06 15:55:39 -0800
commit5c580e64cc206ab160e1767c42e4d6c81f67da4d (patch)
tree2ce6ecebfcb03fad1927522f19d39c00ec127ce4 /src/compiler/glsl/ir_set_program_inouts.cpp
parent8b5749f65ac434961308ccb579fb8a816e4f29d5 (diff)
glsl: Mark whole variable used for ClipDistance and TessLevel*.
There's no point in trying to mark partial array access for gl_ClipDistance, gl_TessLevelOuter, or gl_TessLevelInner - they're special built-in variables that control fixed function hardware, and will likely be used in an all-or-nothing fashion. Since these arrays only occupy 1-2 varying slots, we have to avoid our normal processing which increments the slot value by the array index. (I wrote this code before i965 switched from ir_set_program_inouts to nir_shader_gather_info. It's not used by anyone today, and I'm not sure how valuable it is...the alternative to GLSL IR lowering is NIR compact arrays, at which point you should use nir_gather_info.) Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/compiler/glsl/ir_set_program_inouts.cpp')
-rw-r--r--src/compiler/glsl/ir_set_program_inouts.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/compiler/glsl/ir_set_program_inouts.cpp b/src/compiler/glsl/ir_set_program_inouts.cpp
index 66f0c1ebf08..376d9c693fa 100644
--- a/src/compiler/glsl/ir_set_program_inouts.cpp
+++ b/src/compiler/glsl/ir_set_program_inouts.cpp
@@ -330,6 +330,23 @@ is_multiple_vertices(gl_shader_stage stage, ir_variable *var)
return false;
}
+/**
+ * Return true if \p var is a GLSL built-in array that controls fixed-function
+ * aspects of the pipeline. These have to be used as a whole.
+ */
+static bool
+is_fixed_function_array(ir_variable *var)
+{
+ switch (var->data.location) {
+ case VARYING_SLOT_TESS_LEVEL_OUTER:
+ case VARYING_SLOT_TESS_LEVEL_INNER:
+ case VARYING_SLOT_CLIP_DIST0:
+ return true;
+ default:
+ return false;
+ }
+}
+
ir_visitor_status
ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
{
@@ -362,9 +379,12 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
} else if (ir_dereference_variable * const deref_var =
ir->array->as_dereference_variable()) {
/* ir => foo[i], where foo is a variable. */
- if (is_multiple_vertices(this->shader_stage, deref_var->var)) {
- /* foo is a geometry or tessellation shader input, so i is
- * the vertex, and we're accessing the entire input.
+ if (is_multiple_vertices(this->shader_stage, deref_var->var) ||
+ is_fixed_function_array(deref_var->var)) {
+ /* In the first case, foo is a geometry or tessellation shader input,
+ * so i is the vertex, and we're accessing the entire input. In the
+ * second case, foo is a GLSL built-in array that controls
+ * fixed-function hardware, which is consumed as a whole.
*/
mark_whole_variable(deref_var->var);
/* We've now taken care of foo, but i might contain a subexpression