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 <kenneth@whitecape.org> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user