From 5c580e64cc206ab160e1767c42e4d6c81f67da4d Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sun, 15 Nov 2015 04:22:10 -0800 Subject: [PATCH] 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 Reviewed-by: Jason Ekstrand Reviewed-by: Timothy Arceri --- src/compiler/glsl/ir_set_program_inouts.cpp | 26 ++++++++++++++++++--- 1 file 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 -- 2.30.2