[Mesa-dev] [RFC PATCH 28/56] glsl: patch in/out qualifier
Chris Forbes
chrisf at ijw.co.nz
Sat Sep 20 18:41:08 PDT 2014
From: Fabian Bieler <fabianbieler at fastmail.fm>
---
src/glsl/ast.h | 1 +
src/glsl/ast_to_hir.cpp | 48 +++++++++++++++++---
src/glsl/ast_type.cpp | 3 +-
src/glsl/builtin_variables.cpp | 18 +++++---
src/glsl/glsl_lexer.ll | 3 +-
src/glsl/glsl_parser.yy | 15 ++++---
src/glsl/glsl_parser_extras.cpp | 2 +
src/glsl/glsl_types.cpp | 5 +++
src/glsl/glsl_types.h | 6 +++
src/glsl/ir.cpp | 2 +
src/glsl/ir.h | 1 +
src/glsl/ir_print_visitor.cpp | 5 ++-
src/glsl/ir_reader.cpp | 2 +
src/glsl/ir_set_program_inouts.cpp | 75 +++++++++++++++++++++++++++++--
src/glsl/link_varyings.cpp | 15 ++++++-
src/glsl/lower_named_interface_blocks.cpp | 1 +
src/glsl/lower_packed_varyings.cpp | 1 +
17 files changed, 176 insertions(+), 27 deletions(-)
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index a74f35d..3261268 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -432,6 +432,7 @@ struct ast_type_qualifier {
unsigned out:1;
unsigned centroid:1;
unsigned sample:1;
+ unsigned patch:1;
unsigned uniform:1;
unsigned smooth:1;
unsigned flat:1;
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 0d93b48..2490990 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2473,6 +2473,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
var->data.stream = qual->stream;
}
+ if (qual->flags.q.patch)
+ var->data.patch = 1;
+
if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
var->type = glsl_type::error_type;
_mesa_glsl_error(loc, state,
@@ -3114,14 +3117,17 @@ handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
num_vertices = state->out_qualifier->vertices;
}
- /* This function should only be called for arrays. */
- if (!var->type->is_array()) {
- assert(state->error);
+ if (!var->type->is_array() && !var->data.patch) {
+ _mesa_glsl_error(&loc, state,
+ "tessellation control shader outputs must be arrays");
/* To avoid cascading failures, short circuit the checks below. */
return;
}
+ if (var->data.patch)
+ return;
+
if (var->type->is_unsized_array()) {
if (num_vertices != 0)
var->type = glsl_type::get_array_instance(var->type->fields.array,
@@ -3678,10 +3684,7 @@ ast_declarator_list::hir(exec_list *instructions,
}
} else if (var->data.mode == ir_var_shader_out) {
if (state->stage == MESA_SHADER_TESS_CTRL) {
- // XXX: only allow non-arrays with patch-out attribute
- if (var->type->is_array()) {
- handle_tess_ctrl_shader_output_decl(state, loc, var);
- }
+ handle_tess_ctrl_shader_output_decl(state, loc, var);
}
}
@@ -3797,6 +3800,33 @@ ast_declarator_list::hir(exec_list *instructions,
}
+ /* From section 4.3.4 of the GLSL 4.00 spec:
+ * "Input variables may not be declared using the patch in qualifier
+ * in tessellation control or geometry shaders."
+ *
+ * From section 4.3.6 of the GLSL 4.00 spec:
+ * "It is an error to use patch out in a vertex, tessellation
+ * evaluation, or geometry shader."
+ *
+ * This doesn't explicitly forbid using them in a fragment shader, but
+ * that's probably just an oversight.
+ */
+ if (state->stage != MESA_SHADER_TESS_EVAL
+ && this->type->qualifier.flags.q.patch
+ && this->type->qualifier.flags.q.in) {
+
+ _mesa_glsl_error(&loc, state, "'patch in' can only be used in a "
+ "tessellation evaluation shader");
+ }
+
+ if (state->stage != MESA_SHADER_TESS_CTRL
+ && this->type->qualifier.flags.q.patch
+ && this->type->qualifier.flags.q.out) {
+
+ _mesa_glsl_error(&loc, state, "'patch out' can only be used in a "
+ "tessellation control shader");
+ }
+
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
*/
if (this->type->qualifier.precision != ast_precision_none) {
@@ -5267,6 +5297,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
fields[i].sample = qual->flags.q.sample ? 1 : 0;
+ fields[i].patch = qual->flags.q.patch ? 1 : 0;
/* Only save explicitly defined streams in block's field */
fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
@@ -5576,6 +5607,8 @@ ast_interface_block::hir(exec_list *instructions,
earlier_per_vertex->fields.structure[j].centroid;
fields[i].sample =
earlier_per_vertex->fields.structure[j].sample;
+ fields[i].patch =
+ earlier_per_vertex->fields.structure[j].patch;
}
}
@@ -5741,6 +5774,7 @@ ast_interface_block::hir(exec_list *instructions,
var->data.interpolation = fields[i].interpolation;
var->data.centroid = fields[i].centroid;
var->data.sample = fields[i].sample;
+ var->data.patch = fields[i].patch;
var->init_interface_type(block_type);
if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index 69175eb..4c7b3fc 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -85,7 +85,8 @@ bool
ast_type_qualifier::has_auxiliary_storage() const
{
return this->flags.q.centroid
- || this->flags.q.sample;
+ || this->flags.q.sample
+ || this->flags.q.patch;
}
const char*
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index 7ba0fe8..97ef68c 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -853,10 +853,13 @@ builtin_variable_generator::generate_tcs_special_vars()
add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");// XXX: or sysval?
add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID");
- add_output(VARYING_SLOT_TESS_LEVEL_OUTER,
+ ir_variable *var;
+ var = add_output(VARYING_SLOT_TESS_LEVEL_OUTER,
array(float_t, 4), "gl_TessLevelOuter");
- add_output(VARYING_SLOT_TESS_LEVEL_INNER,
+ var->data.patch = 1;
+ var = add_output(VARYING_SLOT_TESS_LEVEL_INNER,
array(float_t, 2), "gl_TessLevelInner");
+ var->data.patch = 1;
}
@@ -870,10 +873,13 @@ builtin_variable_generator::generate_tes_special_vars()
add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");// XXX: or sysval?
add_system_value(SYSTEM_VALUE_TESS_COORD, vec3_t, "gl_TessCoord");
- add_input(VARYING_SLOT_TESS_LEVEL_OUTER,
- array(float_t, 4), "gl_TessLevelOuter");
- add_input(VARYING_SLOT_TESS_LEVEL_INNER,
- array(float_t, 2), "gl_TessLevelInner");
+ ir_variable *var;
+ var = add_input(VARYING_SLOT_TESS_LEVEL_OUTER,
+ array(float_t, 4), "gl_TessLevelOuter");
+ var->data.patch = 1;
+ var = add_input(VARYING_SLOT_TESS_LEVEL_INNER,
+ array(float_t, 2), "gl_TessLevelInner");
+ var->data.patch = 1;
}
diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
index b7c4aad..2229161 100644
--- a/src/glsl/glsl_lexer.ll
+++ b/src/glsl/glsl_lexer.ll
@@ -296,6 +296,8 @@ invariant KEYWORD(120, 100, 120, 100, INVARIANT);
flat KEYWORD(130, 100, 130, 300, FLAT);
smooth KEYWORD(130, 300, 130, 300, SMOOTH);
noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
+noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
+patch KEYWORD_WITH_ALT(0, 300, 400, 0, yyextra->ARB_tessellation_shader_enable, PATCH);
sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D);
sampler2D return SAMPLER2D;
@@ -546,7 +548,6 @@ usamplerBuffer KEYWORD(140, 300, 140, 0, USAMPLERBUFFER);
/* Additional reserved words in GLSL ES 3.00 */
resource KEYWORD(0, 300, 0, 0, RESOURCE);
-patch KEYWORD(0, 300, 0, 0, PATCH);
sample KEYWORD_WITH_ALT(400, 300, 400, 0, yyextra->ARB_gpu_shader5_enable, SAMPLE);
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index d3cfb97..dbab815 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -131,8 +131,9 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK
%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
-%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING SAMPLE
+%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING PATCH SAMPLE
%token NOPERSPECTIVE FLAT SMOOTH
+%token ROW_MAJOR PACKED_TOK
%token MAT2X2 MAT2X3 MAT2X4
%token MAT3X2 MAT3X3 MAT3X4
%token MAT4X2 MAT4X3 MAT4X4
@@ -180,18 +181,18 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
/* Reserved words that are not actually used in the grammar.
*/
-%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO
+%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS GOTO
%token INLINE_TOK NOINLINE PUBLIC_TOK STATIC EXTERN EXTERNAL
%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK
%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
%token SAMPLER3DRECT
%token SIZEOF CAST NAMESPACE USING
-%token RESOURCE PATCH
+%token RESOURCE
%token SUBROUTINE
%token ERROR_TOK
-%token COMMON PARTITION ACTIVE FILTER ROW_MAJOR
+%token COMMON PARTITION ACTIVE FILTER
%type <identifier> variable_identifier
%type <node> statement
@@ -1796,7 +1797,11 @@ auxiliary_storage_qualifier:
memset(& $$, 0, sizeof($$));
$$.flags.q.sample = 1;
}
- /* TODO: "patch" also goes here someday. */
+ | PATCH
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.patch = 1;
+ }
storage_qualifier:
CONST_TOK
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 357e3b1..0b45f44 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -814,6 +814,8 @@ _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
printf("centroid ");
if (q->flags.q.sample)
printf("sample ");
+ if (q->flags.q.patch)
+ printf("patch ");
if (q->flags.q.uniform)
printf("uniform ");
if (q->flags.q.smooth)
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index 66e9b13..1ed3a24 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -109,6 +109,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].centroid = fields[i].centroid;
this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
+ this->fields.structure[i].patch = fields[i].patch;
}
}
@@ -137,6 +138,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].centroid = fields[i].centroid;
this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
+ this->fields.structure[i].patch = fields[i].patch;
}
}
@@ -511,6 +513,9 @@ glsl_type::record_compare(const glsl_type *b) const
if (this->fields.structure[i].sample
!= b->fields.structure[i].sample)
return false;
+ if (this->fields.structure[i].patch
+ != b->fields.structure[i].patch)
+ return false;
}
return true;
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index d545533..0fe9f5f 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -710,6 +710,12 @@ struct glsl_struct_field {
unsigned matrix_layout:2;
/**
+ * For interface blocks, 1 if this variable is a per-patch input or output
+ * (as in ir_variable::patch). 0 otherwise.
+ */
+ unsigned patch:1;
+
+ /**
* For interface blocks, it has a value if this variable uses multiple vertex
* streams (as in ir_variable::stream). -1 otherwise.
*/
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 739a9f4..e3b200c 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1564,6 +1564,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->data.read_only = false;
this->data.centroid = false;
this->data.sample = false;
+ this->data.patch = false;
this->data.invariant = false;
this->data.how_declared = ir_var_declared_normally;
this->data.mode = mode;
@@ -1680,6 +1681,7 @@ ir_function_signature::qualifiers_match(exec_list *params)
a->data.interpolation != b->data.interpolation ||
a->data.centroid != b->data.centroid ||
a->data.sample != b->data.sample ||
+ a->data.patch != b->data.patch ||
a->data.image_read_only != b->data.image_read_only ||
a->data.image_write_only != b->data.image_write_only ||
a->data.image_coherent != b->data.image_coherent ||
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 8003f88..94c330a 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -560,6 +560,7 @@ public:
unsigned read_only:1;
unsigned centroid:1;
unsigned sample:1;
+ unsigned patch:1;
unsigned invariant:1;
unsigned precise:1;
diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
index bd39805..1cf28ea 100644
--- a/src/glsl/ir_print_visitor.cpp
+++ b/src/glsl/ir_print_visitor.cpp
@@ -163,6 +163,7 @@ void ir_print_visitor::visit(ir_variable *ir)
const char *const cent = (ir->data.centroid) ? "centroid " : "";
const char *const samp = (ir->data.sample) ? "sample " : "";
+ const char *const patc = (ir->data.patch) ? "patch " : "";
const char *const inv = (ir->data.invariant) ? "invariant " : "";
const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
"in ", "out ", "inout ",
@@ -172,8 +173,8 @@ void ir_print_visitor::visit(ir_variable *ir)
const char *const interp[] = { "", "smooth", "flat", "noperspective" };
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
- fprintf(f, "(%s%s%s%s%s%s) ",
- cent, samp, inv, mode[ir->data.mode],
+ fprintf(f, "(%s%s%s%s%s%s%s) ",
+ cent, samp, patc, inv, mode[ir->data.mode],
stream[ir->data.stream],
interp[ir->data.interpolation]);
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index ae00e79..456dd4f 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -414,6 +414,8 @@ ir_reader::read_declaration(s_expression *expr)
var->data.centroid = 1;
} else if (strcmp(qualifier->value(), "sample") == 0) {
var->data.sample = 1;
+ } else if (strcmp(qualifier->value(), "patch") == 0) {
+ var->data.patch = 1;
} else if (strcmp(qualifier->value(), "invariant") == 0) {
var->data.invariant = 1;
} else if (strcmp(qualifier->value(), "uniform") == 0) {
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index 97ead75..ff15362 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -130,6 +130,24 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
type = type->fields.array;
}
+ if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ var->data.mode == ir_var_shader_in && type->is_array()) {
+ type = type->fields.array;
+ }
+
+ if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ var->data.mode == ir_var_shader_out && !var->data.patch) {
+ assert(type->is_array());
+ type = type->fields.array;
+ }
+
+ if (this->shader_stage == MESA_SHADER_TESS_EVAL &&
+ var->data.mode == ir_var_shader_in &&
+ type->is_array() && !var->data.patch) {
+ assert(type->is_array());
+ type = type->fields.array;
+ }
+
mark(this->prog, var, 0, type->count_attribute_slots(),
this->shader_stage == MESA_SHADER_FRAGMENT);
}
@@ -155,6 +173,9 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
*
* *Except gl_PrimitiveIDIn, as noted below.
*
+ * For tessellation control shaders all inputs and non-patch outputs are
+ * arrays. For tessellation evaluation shaders non-patch inputs are arrays.
+ *
* If the index can't be interpreted as a constant, or some other problem
* occurs, then nothing will be marked and false will be returned.
*/
@@ -174,6 +195,36 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
type = type->fields.array;
}
+ if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ var->data.mode == ir_var_shader_in) {
+ /* The only tessellation control shader inputs that are not arrays are
+ * gl_PatchVerticesIn, gl_PrimitiveID and gl_InvocationID.
+ * These can't be indexed so for them this code should never be reached.
+ */
+ assert(type->is_array());
+ type = type->fields.array;
+ }
+
+ if (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ var->data.mode == ir_var_shader_out && !var->data.patch) {
+ /* XXX: User defined outputs could be patch non-array but indexable,
+ * e.g.: patch out mat4 foo;
+ * what to do?
+ */
+ assert(type->is_array());
+ type = type->fields.array;
+ }
+
+ if (this->shader_stage == MESA_SHADER_TESS_EVAL &&
+ var->data.mode == ir_var_shader_in && !var->data.patch) {
+ /* XXX: User defined inputs could be patch non-array but indexable,
+ * e.g.: patch in mat4 bar;
+ * what to do?
+ */
+ assert(type->is_array());
+ type = type->fields.array;
+ }
+
/* The code below only handles:
*
* - Indexing into matrices
@@ -246,8 +297,16 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
*/
if (ir_dereference_variable * const deref_var =
inner_array->array->as_dereference_variable()) {
- if (this->shader_stage == MESA_SHADER_GEOMETRY &&
- deref_var->var->data.mode == ir_var_shader_in) {
+ if ((this->shader_stage == MESA_SHADER_GEOMETRY &&
+ deref_var->var->data.mode == ir_var_shader_in) ||
+ (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ deref_var->var->data.mode == ir_var_shader_in) ||
+ (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ deref_var->var->data.mode == ir_var_shader_out &&
+ !deref_var->var->data.patch) ||
+ (this->shader_stage == MESA_SHADER_TESS_EVAL &&
+ deref_var->var->data.mode == ir_var_shader_in &&
+ !deref_var->var->data.patch)) {
/* foo is a geometry shader input, so i is the vertex, and j the
* part of the input we're accessing.
*/
@@ -265,8 +324,16 @@ 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 (this->shader_stage == MESA_SHADER_GEOMETRY &&
- deref_var->var->data.mode == ir_var_shader_in) {
+ if ((this->shader_stage == MESA_SHADER_GEOMETRY &&
+ deref_var->var->data.mode == ir_var_shader_in) ||
+ (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ deref_var->var->data.mode == ir_var_shader_in) ||
+ (this->shader_stage == MESA_SHADER_TESS_CTRL &&
+ deref_var->var->data.mode == ir_var_shader_out &&
+ !deref_var->var->data.patch) ||
+ (this->shader_stage == MESA_SHADER_TESS_EVAL &&
+ deref_var->var->data.mode == ir_var_shader_in &&
+ !deref_var->var->data.patch)) {
/* foo is a geometry shader input, so i is the vertex, and we're
* accessing the entire input.
*/
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index ee54666..53c26d2 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -116,6 +116,18 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
return;
}
+ if (input->data.patch != output->data.patch) {
+ linker_error(prog,
+ "%s shader output `%s' %s patch qualifier, "
+ "but %s shader input %s patch qualifier\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ (output->data.patch) ? "has" : "lacks",
+ _mesa_shader_stage_to_string(consumer_stage),
+ (input->data.patch) ? "has" : "lacks");
+ return;
+ }
+
if (input->data.invariant != output->data.invariant) {
linker_error(prog,
"%s shader output `%s' %s invariant qualifier, "
@@ -991,7 +1003,8 @@ varying_matches::compute_packing_class(const ir_variable *var)
*
* Therefore, the packing class depends only on the interpolation type.
*/
- unsigned packing_class = var->data.centroid | (var->data.sample << 1);
+ unsigned packing_class = var->data.centroid | (var->data.sample << 1) |
+ (var->data.patch << 2);
packing_class *= 4;
packing_class += var->data.interpolation;
return packing_class;
diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp
index 7304c51..2f1e3af 100644
--- a/src/glsl/lower_named_interface_blocks.cpp
+++ b/src/glsl/lower_named_interface_blocks.cpp
@@ -158,6 +158,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
iface_t->fields.structure[i].interpolation;
new_var->data.centroid = iface_t->fields.structure[i].centroid;
new_var->data.sample = iface_t->fields.structure[i].sample;
+ new_var->data.patch = iface_t->fields.structure[i].patch;
new_var->init_interface_type(iface_t);
hash_table_insert(interface_namespace, new_var,
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 7801483..0c8696d 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -555,6 +555,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
}
packed_var->data.centroid = unpacked_var->data.centroid;
packed_var->data.sample = unpacked_var->data.sample;
+ packed_var->data.patch = unpacked_var->data.patch;
packed_var->data.interpolation = unpacked_var->data.interpolation;
packed_var->data.location = location;
unpacked_var->insert_before(packed_var);
--
2.1.0
More information about the mesa-dev
mailing list