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,
"'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."
*
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) {
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;
}
}
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) {
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++;
}
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);
}
}
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;
}
}
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;
}
}
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;
* 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
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()
{
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;
*/
unsigned read_only:1;
unsigned centroid:1;
+ unsigned sample:1;
unsigned invariant:1;
/**
}
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;
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 ",
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));
// 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) {
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, "
* 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;
}
}
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);
}
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,
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);