aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp229
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp8
-rw-r--r--mesalib/src/glsl/glsl_types.cpp10
-rw-r--r--mesalib/src/glsl/glsl_types.h12
-rw-r--r--mesalib/src/glsl/ir.cpp4
-rw-r--r--mesalib/src/glsl/ir.h48
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp58
-rw-r--r--mesalib/src/glsl/link_varyings.cpp6
-rw-r--r--mesalib/src/glsl/linker.cpp2
-rw-r--r--mesalib/src/glsl/lower_named_interface_blocks.cpp6
10 files changed, 315 insertions, 68 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index b644b22c7..3551a5956 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -60,6 +60,10 @@
static void
detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
exec_list *instructions);
+static void
+remove_per_vertex_blocks(exec_list *instructions,
+ _mesa_glsl_parse_state *state, ir_variable_mode mode);
+
void
_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
@@ -114,6 +118,40 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
var->remove();
instructions->push_head(var);
}
+
+ /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec:
+ *
+ * If multiple shaders using members of a built-in block belonging to
+ * the same interface are linked together in the same program, they
+ * must all redeclare the built-in block in the same way, as described
+ * in section 4.3.7 "Interface Blocks" for interface block matching, or
+ * a link error will result.
+ *
+ * The phrase "using members of a built-in block" implies that if two
+ * shaders are linked together and one of them *does not use* any members
+ * of the built-in block, then that shader does not need to have a matching
+ * redeclaration of the built-in block.
+ *
+ * This appears to be a clarification to the behaviour established for
+ * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL
+ * version.
+ *
+ * The definition of "interface" in section 4.3.7 that applies here is as
+ * follows:
+ *
+ * The boundary between adjacent programmable pipeline stages: This
+ * spans all the outputs in all compilation units of the first stage
+ * and all the inputs in all compilation units of the second stage.
+ *
+ * Therefore this rule applies to both inter- and intra-stage linking.
+ *
+ * The easiest way to implement this is to check whether the shader uses
+ * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply
+ * remove all the relevant variable declaration from the IR, so that the
+ * linker won't see them and complain about mismatches.
+ */
+ remove_per_vertex_blocks(instructions, state, ir_var_shader_in);
+ remove_per_vertex_blocks(instructions, state, ir_var_shader_out);
}
@@ -1961,6 +1999,45 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
return true;
}
+
+static glsl_interp_qualifier
+interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
+ ir_variable_mode mode,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ glsl_interp_qualifier interpolation;
+ if (qual->flags.q.flat)
+ interpolation = INTERP_QUALIFIER_FLAT;
+ else if (qual->flags.q.noperspective)
+ interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+ else if (qual->flags.q.smooth)
+ interpolation = INTERP_QUALIFIER_SMOOTH;
+ else
+ interpolation = INTERP_QUALIFIER_NONE;
+
+ if (interpolation != INTERP_QUALIFIER_NONE) {
+ if (mode != ir_var_shader_in && mode != ir_var_shader_out) {
+ _mesa_glsl_error(loc, state,
+ "interpolation qualifier `%s' can only be applied to "
+ "shader inputs or outputs.",
+ interpolation_string(interpolation));
+
+ }
+
+ if ((state->target == vertex_shader && mode == ir_var_shader_in) ||
+ (state->target == fragment_shader && mode == ir_var_shader_out)) {
+ _mesa_glsl_error(loc, state,
+ "interpolation qualifier `%s' cannot be applied to "
+ "vertex shader inputs or fragment shader outputs",
+ interpolation_string(interpolation));
+ }
+ }
+
+ return interpolation;
+}
+
+
static void
apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
ir_variable *var,
@@ -2095,34 +2172,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
}
}
- if (qual->flags.q.flat)
- var->interpolation = INTERP_QUALIFIER_FLAT;
- else if (qual->flags.q.noperspective)
- var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
- else if (qual->flags.q.smooth)
- var->interpolation = INTERP_QUALIFIER_SMOOTH;
- else
- var->interpolation = INTERP_QUALIFIER_NONE;
-
- if (var->interpolation != INTERP_QUALIFIER_NONE) {
- ir_variable_mode mode = (ir_variable_mode) var->mode;
-
- if (mode != ir_var_shader_in && mode != ir_var_shader_out) {
- _mesa_glsl_error(loc, state,
- "interpolation qualifier `%s' can only be applied to "
- "shader inputs or outputs.",
- var->interpolation_string());
-
- }
-
- if ((state->target == vertex_shader && mode == ir_var_shader_in) ||
- (state->target == fragment_shader && mode == ir_var_shader_out)) {
- _mesa_glsl_error(loc, state,
- "interpolation qualifier `%s' cannot be applied to "
- "vertex shader inputs or fragment shader outputs",
- var->interpolation_string());
- }
- }
+ var->interpolation =
+ interpret_interpolation_qualifier(qual, (ir_variable_mode) var->mode,
+ state, loc);
var->pixel_center_integer = qual->flags.q.pixel_center_integer;
var->origin_upper_left = qual->flags.q.origin_upper_left;
@@ -4410,6 +4462,10 @@ ast_type_specifier::hir(exec_list *instructions,
* AST for each can be processed the same way into a set of
* \c glsl_struct_field to describe the members.
*
+ * If we're processing an interface block, var_mode should be the type of the
+ * interface block (ir_var_shader_in, ir_var_shader_out, or ir_var_uniform).
+ * If we're processing a structure, var_mode should be ir_var_auto.
+ *
* \return
* The number of fields processed. A pointer to the array structure fields is
* stored in \c *fields_ret.
@@ -4422,7 +4478,8 @@ ast_process_structure_or_interface_block(exec_list *instructions,
glsl_struct_field **fields_ret,
bool is_interface,
bool block_row_major,
- bool allow_reserved_names)
+ bool allow_reserved_names,
+ ir_variable_mode var_mode)
{
unsigned decl_count = 0;
@@ -4506,6 +4563,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,
fields[i].type = field_type;
fields[i].name = decl->identifier;
fields[i].location = -1;
+ fields[i].interpolation =
+ interpret_interpolation_qualifier(qual, var_mode, state, &loc);
+ fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
if (qual->flags.q.row_major || qual->flags.q.column_major) {
if (!qual->flags.q.uniform) {
@@ -4584,7 +4644,8 @@ ast_struct_specifier::hir(exec_list *instructions,
&fields,
false,
false,
- false /* allow_reserved_names */);
+ false /* allow_reserved_names */,
+ ir_var_auto);
validate_identifier(this->name, loc, state);
@@ -4665,20 +4726,6 @@ ast_interface_block::hir(exec_list *instructions,
packing = GLSL_INTERFACE_PACKING_STD140;
}
- bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
- bool block_row_major = this->layout.flags.q.row_major;
- exec_list declared_variables;
- glsl_struct_field *fields;
- unsigned int num_variables =
- ast_process_structure_or_interface_block(&declared_variables,
- state,
- &this->declarations,
- loc,
- &fields,
- true,
- block_row_major,
- redeclaring_per_vertex);
-
ir_variable_mode var_mode;
const char *iface_type_name;
if (this->layout.flags.q.in) {
@@ -4696,6 +4743,21 @@ ast_interface_block::hir(exec_list *instructions,
assert(!"interface block layout qualifier not found!");
}
+ bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
+ bool block_row_major = this->layout.flags.q.row_major;
+ exec_list declared_variables;
+ glsl_struct_field *fields;
+ unsigned int num_variables =
+ ast_process_structure_or_interface_block(&declared_variables,
+ state,
+ &this->declarations,
+ loc,
+ &fields,
+ true,
+ block_row_major,
+ redeclaring_per_vertex,
+ var_mode);
+
if (!redeclaring_per_vertex)
validate_identifier(this->block_name, loc, state);
@@ -4768,6 +4830,10 @@ ast_interface_block::hir(exec_list *instructions,
} else {
fields[i].location =
earlier_per_vertex->fields.structure[j].location;
+ fields[i].interpolation =
+ earlier_per_vertex->fields.structure[j].interpolation;
+ fields[i].centroid =
+ earlier_per_vertex->fields.structure[j].centroid;
}
}
@@ -4831,8 +4897,24 @@ ast_interface_block::hir(exec_list *instructions,
* field selector ( . ) operator (analogously to structures)."
*/
if (this->instance_name) {
- if (!redeclaring_per_vertex)
+ if (redeclaring_per_vertex) {
+ /* When a built-in in an unnamed interface block is redeclared,
+ * get_variable_being_redeclared() calls
+ * check_builtin_array_max_size() to make sure that built-in array
+ * variables aren't redeclared to illegal sizes. But we're looking
+ * at a redeclaration of a named built-in interface block. So we
+ * have to manually call check_builtin_array_max_size() for all parts
+ * of the interface that are arrays.
+ */
+ for (unsigned i = 0; i < num_variables; i++) {
+ if (fields[i].type->is_array()) {
+ const unsigned size = fields[i].type->array_size();
+ check_builtin_array_max_size(fields[i].name, size, loc, state);
+ }
+ }
+ } else {
validate_identifier(this->instance_name, loc, state);
+ }
ir_variable *var;
@@ -4903,6 +4985,8 @@ ast_interface_block::hir(exec_list *instructions,
new(state) ir_variable(fields[i].type,
ralloc_strdup(state, fields[i].name),
var_mode);
+ var->interpolation = fields[i].interpolation;
+ var->centroid = fields[i].centroid;
var->init_interface_type(block_type);
if (redeclaring_per_vertex) {
@@ -4958,7 +5042,8 @@ ast_interface_block::hir(exec_list *instructions,
foreach_list_safe(node, instructions) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var != NULL &&
- var->get_interface_type() == earlier_per_vertex) {
+ var->get_interface_type() == earlier_per_vertex &&
+ var->mode == var_mode) {
state->symbols->disable_variable(var->name);
var->remove();
}
@@ -5095,3 +5180,55 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
user_defined_fs_output->name);
}
}
+
+
+static void
+remove_per_vertex_blocks(exec_list *instructions,
+ _mesa_glsl_parse_state *state, ir_variable_mode mode)
+{
+ /* Find the gl_PerVertex interface block of the appropriate (in/out) mode,
+ * if it exists in this shader type.
+ */
+ const glsl_type *per_vertex = NULL;
+ switch (mode) {
+ case ir_var_shader_in:
+ if (ir_variable *gl_in = state->symbols->get_variable("gl_in"))
+ per_vertex = gl_in->get_interface_type();
+ break;
+ case ir_var_shader_out:
+ if (ir_variable *gl_Position =
+ state->symbols->get_variable("gl_Position")) {
+ per_vertex = gl_Position->get_interface_type();
+ }
+ break;
+ default:
+ assert(!"Unexpected mode");
+ break;
+ }
+
+ /* If we didn't find a built-in gl_PerVertex interface block, then we don't
+ * need to do anything.
+ */
+ if (per_vertex == NULL)
+ return;
+
+ /* If the interface block is used by the shader, then we don't need to do
+ * anything.
+ */
+ interface_block_usage_visitor v(mode, per_vertex);
+ v.run(instructions);
+ if (v.usage_found())
+ return;
+
+ /* Remove any ir_variable declarations that refer to the interface block
+ * we're removing.
+ */
+ foreach_list_safe(node, instructions) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+ if (var != NULL && var->get_interface_type() == per_vertex &&
+ var->mode == mode) {
+ state->symbols->disable_variable(var->name);
+ var->remove();
+ }
+ }
+}
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index fc1115bc4..018daf67f 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -326,6 +326,8 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,
this->fields[this->num_fields].name = name;
this->fields[this->num_fields].row_major = false;
this->fields[this->num_fields].location = slot;
+ this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE;
+ this->fields[this->num_fields].centroid = 0;
this->num_fields++;
}
@@ -888,8 +890,8 @@ builtin_variable_generator::generate_varyings()
if (state->target == geometry_shader) {
const glsl_type *per_vertex_in_type =
this->per_vertex_in.construct_interface_instance();
- ir_variable *var = add_variable("gl_in", array(per_vertex_in_type, 0),
- ir_var_shader_in, -1);
+ add_variable("gl_in", array(per_vertex_in_type, 0),
+ ir_var_shader_in, -1);
}
if (state->target == vertex_shader || state->target == geometry_shader) {
const glsl_type *per_vertex_out_type =
@@ -899,6 +901,8 @@ builtin_variable_generator::generate_varyings()
ir_variable *var =
add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
fields[i].location);
+ var->interpolation = fields[i].interpolation;
+ var->centroid = fields[i].centroid;
var->init_interface_type(per_vertex_out_type);
}
}
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 80a6e71a7..bc8d87f5f 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -101,6 +101,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
fields[i].name);
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].row_major = fields[i].row_major;
}
}
@@ -126,6 +128,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
fields[i].name);
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].row_major = fields[i].row_major;
}
}
@@ -455,6 +459,12 @@ glsl_type::record_key_compare(const void *a, const void *b)
if (key1->fields.structure[i].location
!= key2->fields.structure[i].location)
return 1;
+ if (key1->fields.structure[i].interpolation
+ != key2->fields.structure[i].interpolation)
+ return 1;
+ if (key1->fields.structure[i].centroid
+ != key2->fields.structure[i].centroid)
+ return 1;
}
return 0;
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index e60c19132..4b5b6efb3 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -590,6 +590,18 @@ struct glsl_struct_field {
* Ignored for structs.
*/
int location;
+
+ /**
+ * For interface blocks, the interpolation mode (as in
+ * ir_variable::interpolation). 0 otherwise.
+ */
+ unsigned interpolation:2;
+
+ /**
+ * For interface blocks, 1 if this variable uses centroid interpolation (as
+ * in ir_variable::centroid). 0 otherwise.
+ */
+ unsigned centroid:1;
};
static inline unsigned int
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 54a8e400c..c682e3ed5 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1616,9 +1616,9 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
const char *
-ir_variable::interpolation_string() const
+interpolation_string(unsigned interpolation)
{
- switch (this->interpolation) {
+ switch (interpolation) {
case INTERP_QUALIFIER_NONE: return "no";
case INTERP_QUALIFIER_SMOOTH: return "smooth";
case INTERP_QUALIFIER_FLAT: return "flat";
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index aac8cbb7d..8d5bec9c1 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -312,6 +312,22 @@ struct ir_state_slot {
int swizzle;
};
+
+/**
+ * Get the string value for an interpolation qualifier
+ *
+ * \return The string that would be used in a shader to specify \c
+ * mode will be returned.
+ *
+ * This function is used to generate error messages of the form "shader
+ * uses %s interpolation qualifier", so in the case where there is no
+ * interpolation qualifier, it returns "no".
+ *
+ * This function should only be used on a shader input or output variable.
+ */
+const char *interpolation_string(unsigned interpolation);
+
+
class ir_variable : public ir_instruction {
public:
ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
@@ -332,20 +348,6 @@ public:
/**
- * Get the string value for the interpolation qualifier
- *
- * \return The string that would be used in a shader to specify \c
- * mode will be returned.
- *
- * This function is used to generate error messages of the form "shader
- * uses %s interpolation qualifier", so in the case where there is no
- * interpolation qualifier, it returns "no".
- *
- * This function should only be used on a shader input or output variable.
- */
- const char *interpolation_string() const;
-
- /**
* Determine how this variable should be interpolated based on its
* interpolation qualifier (if present), whether it is gl_Color or
* gl_SecondaryColor, and whether flatshading is enabled in the current GL
@@ -579,6 +581,24 @@ public:
unsigned location_frac:2;
/**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was not an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_array will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_nonarray:1;
+
+ /**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_nonarray will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_array:1;
+
+ /**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index baea837b5..51ca593ff 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -75,7 +75,63 @@ program_resource_visitor::process(ir_variable *var)
*/
/* Only strdup the name if we actually will need to modify it. */
- if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
+ if (var->from_named_ifc_block_array) {
+ /* lower_named_interface_blocks created this variable by lowering an
+ * interface block array to an array variable. For example if the
+ * original source code was:
+ *
+ * out Blk { vec4 bar } foo[3];
+ *
+ * Then the variable is now:
+ *
+ * out vec4 bar[3];
+ *
+ * We need to visit each array element using the names constructed like
+ * so:
+ *
+ * Blk[0].bar
+ * Blk[1].bar
+ * Blk[2].bar
+ */
+ assert(t->is_array());
+ const glsl_type *ifc_type = var->get_interface_type();
+ char *name = ralloc_strdup(NULL, ifc_type->name);
+ size_t name_length = strlen(name);
+ for (unsigned i = 0; i < t->length; i++) {
+ size_t new_length = name_length;
+ ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i,
+ var->name);
+ /* Note: row_major is only meaningful for uniform blocks, and
+ * lowering is only applied to non-uniform interface blocks, so we
+ * can safely pass false for row_major.
+ */
+ recursion(var->type, &name, new_length, false, NULL);
+ }
+ ralloc_free(name);
+ } else if (var->from_named_ifc_block_nonarray) {
+ /* lower_named_interface_blocks created this variable by lowering a
+ * named interface block (non-array) to an ordinary variable. For
+ * example if the original source code was:
+ *
+ * out Blk { vec4 bar } foo;
+ *
+ * Then the variable is now:
+ *
+ * out vec4 bar;
+ *
+ * We need to visit this variable using the name:
+ *
+ * Blk.bar
+ */
+ const glsl_type *ifc_type = var->get_interface_type();
+ char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name);
+ /* Note: row_major is only meaningful for uniform blocks, and lowering
+ * is only applied to non-uniform interface blocks, so we can safely
+ * pass false for row_major.
+ */
+ recursion(var->type, &name, strlen(name), false, NULL);
+ ralloc_free(name);
+ } else if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
char *name = ralloc_strdup(NULL, var->name);
recursion(var->type, &name, strlen(name), false, NULL);
ralloc_free(name);
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 4ba6d8a20..be36b5f8f 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -125,9 +125,9 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
"interpolation qualifier\n",
_mesa_glsl_shader_target_name(producer_type),
output->name,
- output->interpolation_string(),
+ interpolation_string(output->interpolation),
_mesa_glsl_shader_target_name(consumer_type),
- input->interpolation_string());
+ interpolation_string(input->interpolation));
return;
}
}
@@ -328,7 +328,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
const unsigned vector_elements =
this->matched_candidate->type->fields.array->vector_elements;
unsigned actual_array_size = this->is_clip_distance_mesa ?
- prog->Vert.ClipDistanceArraySize :
+ prog->LastClipDistanceArraySize :
this->matched_candidate->type->array_size();
if (this->is_subscripted) {
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index b23c31a16..d8f655c39 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -2100,6 +2100,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
validate_vertex_shader_executable(prog, sh);
if (!prog->LinkStatus)
goto done;
+ prog->LastClipDistanceArraySize = prog->Vert.ClipDistanceArraySize;
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],
sh);
@@ -2132,6 +2133,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
validate_geometry_shader_executable(prog, sh);
if (!prog->LinkStatus)
goto done;
+ prog->LastClipDistanceArraySize = prog->Geom.ClipDistanceArraySize;
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
sh);
diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp
index f415252ba..d59d11150 100644
--- a/mesalib/src/glsl/lower_named_interface_blocks.cpp
+++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp
@@ -140,6 +140,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,
var_name,
(ir_variable_mode) var->mode);
+ new_var->from_named_ifc_block_nonarray = 1;
} else {
const glsl_type *new_array_type =
glsl_type::get_array_instance(
@@ -149,8 +150,13 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
new(mem_ctx) ir_variable(new_array_type,
var_name,
(ir_variable_mode) var->mode);
+ new_var->from_named_ifc_block_array = 1;
}
new_var->location = iface_t->fields.structure[i].location;
+ new_var->explicit_location = (new_var->location >= 0);
+ new_var->interpolation =
+ iface_t->fields.structure[i].interpolation;
+ new_var->centroid = iface_t->fields.structure[i].centroid;
new_var->init_interface_type(iface_t);
hash_table_insert(interface_namespace, new_var,