From 51c5fc85e11858b11cf2a3c89ff8052fbc67faab Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 29 Nov 2013 21:26:10 +1300 Subject: [PATCH] glsl: Add ir support for `sample` qualifier; adjust compiler and linker Signed-off-by: Chris Forbes Reviewed-by: Francisco Jerez --- src/glsl/ast_to_hir.cpp | 15 +++++++++++++++ src/glsl/builtin_variables.cpp | 2 ++ src/glsl/glsl_types.cpp | 5 +++++ src/glsl/glsl_types.h | 6 ++++++ src/glsl/ir.cpp | 5 +++-- src/glsl/ir.h | 1 + src/glsl/ir_clone.cpp | 1 + src/glsl/ir_print_visitor.cpp | 5 +++-- src/glsl/ir_reader.cpp | 2 ++ src/glsl/link_varyings.cpp | 14 ++++++++++++++ src/glsl/linker.cpp | 6 ++++++ src/glsl/lower_named_interface_blocks.cpp | 1 + src/glsl/lower_packed_varyings.cpp | 1 + 13 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 37be1cb7562..f35d8679e70 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2180,6 +2180,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, if (qual->flags.q.centroid) var->centroid = 1; + if (qual->flags.q.sample) + var->sample = 1; + if (qual->flags.q.attribute && state->target != vertex_shader) { var->type = glsl_type::error_type; _mesa_glsl_error(loc, state, @@ -3277,6 +3280,14 @@ ast_declarator_list::hir(exec_list *instructions, "'centroid in' cannot be used in a vertex shader"); } + if (state->target == vertex_shader + && this->type->qualifier.flags.q.sample + && this->type->qualifier.flags.q.in) { + + _mesa_glsl_error(&loc, state, + "'sample in' cannot be used in a vertex shader"); + } + /* Section 4.3.6 of the GLSL 1.30 specification states: * "It is an error to use centroid out in a fragment shader." * @@ -4662,6 +4673,7 @@ ast_process_structure_or_interface_block(exec_list *instructions, fields[i].interpolation = 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; if (qual->flags.q.row_major || qual->flags.q.column_major) { if (!qual->flags.q.uniform) { @@ -4930,6 +4942,8 @@ ast_interface_block::hir(exec_list *instructions, earlier_per_vertex->fields.structure[j].interpolation; fields[i].centroid = earlier_per_vertex->fields.structure[j].centroid; + fields[i].sample = + earlier_per_vertex->fields.structure[j].sample; } } @@ -5084,6 +5098,7 @@ ast_interface_block::hir(exec_list *instructions, var_mode); var->interpolation = fields[i].interpolation; var->centroid = fields[i].centroid; + var->sample = fields[i].sample; var->init_interface_type(block_type); if (redeclaring_per_vertex) { diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp index d57324c2fba..d0e76e3a402 100644 --- a/src/glsl/builtin_variables.cpp +++ b/src/glsl/builtin_variables.cpp @@ -332,6 +332,7 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type, this->fields[this->num_fields].location = slot; this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE; this->fields[this->num_fields].centroid = 0; + this->fields[this->num_fields].sample = 0; this->num_fields++; } @@ -937,6 +938,7 @@ builtin_variable_generator::generate_varyings() fields[i].location); var->interpolation = fields[i].interpolation; var->centroid = fields[i].centroid; + var->sample = fields[i].sample; var->init_interface_type(per_vertex_out_type); } } diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index f740130968c..12d4ac0eeba 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -103,6 +103,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, this->fields.structure[i].location = fields[i].location; this->fields.structure[i].interpolation = fields[i].interpolation; this->fields.structure[i].centroid = fields[i].centroid; + this->fields.structure[i].sample = fields[i].sample; this->fields.structure[i].row_major = fields[i].row_major; } } @@ -130,6 +131,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, this->fields.structure[i].location = fields[i].location; this->fields.structure[i].interpolation = fields[i].interpolation; this->fields.structure[i].centroid = fields[i].centroid; + this->fields.structure[i].sample = fields[i].sample; this->fields.structure[i].row_major = fields[i].row_major; } } @@ -483,6 +485,9 @@ glsl_type::record_key_compare(const void *a, const void *b) if (key1->fields.structure[i].centroid != key2->fields.structure[i].centroid) return 1; + if (key1->fields.structure[i].sample + != key2->fields.structure[i].sample) + return 1; } return 0; diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 96eee5e64eb..fb7c9288d3f 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -634,6 +634,12 @@ struct glsl_struct_field { * in ir_variable::centroid). 0 otherwise. */ unsigned centroid:1; + + /** + * For interface blocks, 1 if this variable uses sample interpolation (as + * in ir_variable::sample). 0 otherwise. + */ + unsigned sample:1; }; static inline unsigned int diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 3be7d51707a..330b4dccbb5 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1585,7 +1585,7 @@ ir_swizzle::variable_referenced() const ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) : max_array_access(0), max_ifc_array_access(NULL), - read_only(false), centroid(false), invariant(false), + read_only(false), centroid(false), sample(false), invariant(false), how_declared(ir_var_declared_normally), mode(mode), interpolation(INTERP_QUALIFIER_NONE), atomic() { @@ -1709,7 +1709,8 @@ ir_function_signature::qualifiers_match(exec_list *params) if (a->read_only != b->read_only || !modes_match(a->mode, b->mode) || a->interpolation != b->interpolation || - a->centroid != b->centroid) { + a->centroid != b->centroid || + a->sample != b->sample) { /* parameter a's qualifiers don't match */ return a->name; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 57f3bcac026..e60ffc0834f 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -529,6 +529,7 @@ public: */ unsigned read_only:1; unsigned centroid:1; + unsigned sample:1; unsigned invariant:1; /** diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 8f57499ec97..a66864a61d1 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -52,6 +52,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const } var->read_only = this->read_only; var->centroid = this->centroid; + var->sample = this->sample; var->invariant = this->invariant; var->interpolation = this->interpolation; var->location = this->location; diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index 6ad22fe33e8..f4109fb1f4c 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -149,6 +149,7 @@ void ir_print_visitor::visit(ir_variable *ir) printf("(declare "); const char *const cent = (ir->centroid) ? "centroid " : ""; + const char *const samp = (ir->sample) ? "sample " : ""; const char *const inv = (ir->invariant) ? "invariant " : ""; const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ", "in ", "out ", "inout ", @@ -157,8 +158,8 @@ void ir_print_visitor::visit(ir_variable *ir) const char *const interp[] = { "", "smooth", "flat", "noperspective" }; STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT); - printf("(%s%s%s%s) ", - cent, inv, mode[ir->mode], interp[ir->interpolation]); + printf("(%s%s%s%s%s) ", + cent, samp, inv, mode[ir->mode], interp[ir->interpolation]); print_type(ir->type); printf(" %s)", unique_name(ir)); diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 00e2db9a3f0..7fcb34d2390 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -413,6 +413,8 @@ ir_reader::read_declaration(s_expression *expr) // FINISHME: Check for duplicate/conflicting qualifiers. if (strcmp(qualifier->value(), "centroid") == 0) { var->centroid = 1; + } else if (strcmp(qualifier->value(), "sample") == 0) { + var->sample = 1; } else if (strcmp(qualifier->value(), "invariant") == 0) { var->invariant = 1; } else if (strcmp(qualifier->value(), "uniform") == 0) { diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index be36b5f8f6b..d2a4fc82d3c 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -105,6 +105,18 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, return; } + if (input->sample != output->sample) { + linker_error(prog, + "%s shader output `%s' %s sample qualifier, " + "but %s shader input %s sample qualifier\n", + _mesa_glsl_shader_target_name(producer_type), + output->name, + (output->sample) ? "has" : "lacks", + _mesa_glsl_shader_target_name(consumer_type), + (input->sample) ? "has" : "lacks"); + return; + } + if (input->invariant != output->invariant) { linker_error(prog, "%s shader output `%s' %s invariant qualifier, " @@ -753,10 +765,12 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) * requirement by changing the interpolation type to flat here. */ producer_var->centroid = false; + producer_var->sample = false; producer_var->interpolation = INTERP_QUALIFIER_FLAT; if (consumer_var) { consumer_var->centroid = false; + consumer_var->sample = false; consumer_var->interpolation = INTERP_QUALIFIER_FLAT; } } diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 21c1bdd10f1..9e8eca5cc9e 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -765,6 +765,12 @@ cross_validate_globals(struct gl_shader_program *prog, mode_string(var), var->name); return; } + if (existing->sample != var->sample) { + linker_error(prog, "declarations for %s `%s` have " + "mismatching sample qualifiers\n", + mode_string(var), var->name); + return; + } } else variables.add_variable(var); } diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp index d59d11150e0..aa4c11070e5 100644 --- a/src/glsl/lower_named_interface_blocks.cpp +++ b/src/glsl/lower_named_interface_blocks.cpp @@ -157,6 +157,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) new_var->interpolation = iface_t->fields.structure[i].interpolation; new_var->centroid = iface_t->fields.structure[i].centroid; + new_var->sample = iface_t->fields.structure[i].sample; 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 61ee692f6b0..e097e81f1b3 100644 --- a/src/glsl/lower_packed_varyings.cpp +++ b/src/glsl/lower_packed_varyings.cpp @@ -565,6 +565,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref( packed_var->max_array_access = this->gs_input_vertices - 1; } packed_var->centroid = unpacked_var->centroid; + packed_var->sample = unpacked_var->sample; packed_var->interpolation = unpacked_var->interpolation; packed_var->location = location; unpacked_var->insert_before(packed_var); -- 2.30.2