aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-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
-rw-r--r--mesalib/src/mesa/Makefile.am6
-rw-r--r--mesalib/src/mesa/drivers/dri/Makefile.am67
-rw-r--r--mesalib/src/mesa/drivers/dri/common/Makefile.am11
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c76
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.h2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/megadriver_stub.c41
-rw-r--r--mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py68
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/Makefile.am18
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/Makefile.sources6
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c19
-rw-r--r--mesalib/src/mesa/main/mtypes.h14
-rw-r--r--mesalib/src/mesa/main/shaderapi.c108
-rw-r--r--mesalib/src/mesa/program/Makefile.am14
-rw-r--r--mesalib/src/mesa/x86/read_rgba_span_x86.S8
24 files changed, 635 insertions, 206 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 4bd4034a0..ea71b3063 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,
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am
index e9c16e78e..f86caee35 100644
--- a/mesalib/src/mesa/Makefile.am
+++ b/mesalib/src/mesa/Makefile.am
@@ -19,11 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-if NEED_LIBDRICORE
-DRICORE_SUBDIR = libdricore
-endif
-
-SUBDIRS = program x86 x86-64 . $(DRICORE_SUBDIR) main/tests
+SUBDIRS = program x86 x86-64 . main/tests
if HAVE_X11_DRIVER
SUBDIRS += drivers/x11
diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am
index 7fa0ad73d..a85a5aa91 100644
--- a/mesalib/src/mesa/drivers/dri/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/Makefile.am
@@ -1,29 +1,45 @@
+dridir = $(DRI_DRIVER_INSTALL_DIR)
+
SUBDIRS =
+MEGADRIVERS =
+MEGADRIVERS_DEPS =
SUBDIRS+=common
if HAVE_I915_DRI
-SUBDIRS+=i915
+SUBDIRS += i915
+MEGADRIVERS_DEPS += i915/libi915_dri.la
+MEGADRIVERS += i915_dri.so
endif
if HAVE_I965_DRI
-SUBDIRS+=i965
+SUBDIRS += i965
+MEGADRIVERS_DEPS += i965/libi965_dri.la
+MEGADRIVERS += i965_dri.so
endif
if HAVE_NOUVEAU_DRI
-SUBDIRS+=nouveau
+SUBDIRS += nouveau
+MEGADRIVERS_DEPS += nouveau/libnouveau_dri.la
+MEGADRIVERS += nouveau_vieux_dri.so
endif
if HAVE_R200_DRI
-SUBDIRS+=r200
+SUBDIRS += r200
+MEGADRIVERS_DEPS += r200/libr200_dri.la
+MEGADRIVERS += r200_dri.so
endif
if HAVE_RADEON_DRI
-SUBDIRS+=radeon
+SUBDIRS += radeon
+MEGADRIVERS_DEPS += radeon/libradeon_dri.la
+MEGADRIVERS += radeon_dri.so
endif
if HAVE_SWRAST_DRI
-SUBDIRS+=swrast
+SUBDIRS += swrast
+MEGADRIVERS_DEPS += swrast/libswrast_dri.la
+MEGADRIVERS += swrast_dri.so
endif
pkgconfigdir = $(libdir)/pkgconfig
@@ -31,3 +47,42 @@ pkgconfig_DATA = dri.pc
driincludedir = $(includedir)/GL/internal
driinclude_HEADERS = $(top_srcdir)/include/GL/internal/dri_interface.h
+
+nodist_EXTRA_mesa_dri_drivers_la_SOURCES = dummy.cpp
+mesa_dri_drivers_la_SOURCES =
+mesa_dri_drivers_la_LDFLAGS = \
+ -module -avoid-version -shared \
+ -Wl,-Bsymbolic \
+ $()
+mesa_dri_drivers_la_LIBADD = \
+ ../../libmesa.la \
+ common/libmegadriver_stub.la \
+ common/libdricommon.la \
+ $(MEGADRIVERS_DEPS) \
+ $(DRI_LIB_DEPS) \
+ $()
+
+if NEED_MEGADRIVER
+dri_LTLIBRARIES = mesa_dri_drivers.la
+
+# Add a link to allow setting LD_LIBRARY_PATH/LIBGL_DRIVERS_PATH to /lib of the build tree.
+all-local: mesa_dri_drivers.la
+ $(MKDIR_P) $(top_builddir)/$(LIB_DIR);
+ $(AM_V_GEN)ln -f .libs/mesa_dri_drivers.so \
+ $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so;
+ $(AM_V_GEN)for i in $(MEGADRIVERS); do \
+ ln -f $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so \
+ $(top_builddir)/$(LIB_DIR)/$$i; \
+ done;
+
+# hardlink each megadriver instance, but don't actually have
+# mesa_dri_drivers.so in the set of final installed files.
+install-data-hook:
+ for i in $(MEGADRIVERS); do \
+ ln -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so \
+ $(DESTDIR)$(dridir)/$$i; \
+ done;
+ $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so
+ $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.la
+
+endif
diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.am b/mesalib/src/mesa/drivers/dri/common/Makefile.am
index ce4119d0f..9f49ff3ae 100644
--- a/mesalib/src/mesa/drivers/dri/common/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/common/Makefile.am
@@ -27,11 +27,11 @@ AM_CFLAGS = \
-I$(top_srcdir)/src/mapi \
-I$(top_srcdir)/src/mesa/ \
$(DEFINES) \
- $(LIBDRM_CFLAGS) \
$(VISIBILITY_CFLAGS)
noinst_LTLIBRARIES = \
libdricommon.la \
+ libmegadriver_stub.la \
libdri_test_stubs.la
libdricommon_la_SOURCES = \
@@ -43,4 +43,13 @@ libdri_test_stubs_la_SOURCES = \
dri_test.c
libdri_test_stubs_la_CFLAGS = $(AM_CFLAGS) -DNO_MAIN
+libmegadriver_stub_la_SOURCES = megadriver_stub.c
+
sysconf_DATA = drirc
+
+if DRICOMMON_NEED_LIBDRM
+AM_CFLAGS += $(LIBDRM_CFLAGS)
+libdricommon_la_LDFLAGS = $(LIBDRM_LIBS)
+else
+AM_CFLAGS += -D__NOT_HAVE_DRM_H
+endif
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index db44eede6..c28b0fc41 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -82,6 +82,23 @@ setupLoaderExtensions(__DRIscreen *psp,
}
/**
+ * This pointer determines which driver API we'll use in the case of the
+ * loader not passing us an explicit driver extensions list (that would,
+ * itself, contain a pointer to a driver API.)
+ *
+ * A driver's driDriverGetExtensions_drivername() can update this pointer to
+ * what it's returning, and a loader that is ignorant of createNewScreen2()
+ * will get the correct driver screen created, as long as no other
+ * driDriverGetExtensions() happened in between the first one and the
+ * createNewScreen().
+ *
+ * This allows the X Server to not require the significant dri_interface.h
+ * updates for doing createNewScreen2(), which would discourage backporting of
+ * the X Server patches to support the new loader interface.
+ */
+const struct __DriverAPIRec *globalDriverAPI = &driDriverAPI;
+
+/**
* This is the first entrypoint in the driver called by the DRI driver loader
* after dlopen()ing it.
*
@@ -89,9 +106,10 @@ setupLoaderExtensions(__DRIscreen *psp,
* Display.
*/
static __DRIscreen *
-dri2CreateNewScreen(int scrn, int fd,
- const __DRIextension **extensions,
- const __DRIconfig ***driver_configs, void *data)
+dri2CreateNewScreen2(int scrn, int fd,
+ const __DRIextension **extensions,
+ const __DRIextension **driver_extensions,
+ const __DRIconfig ***driver_configs, void *data)
{
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
@@ -100,7 +118,20 @@ dri2CreateNewScreen(int scrn, int fd,
if (!psp)
return NULL;
- psp->driver = &driDriverAPI;
+ /* By default, use the global driDriverAPI symbol (non-megadrivers). */
+ psp->driver = globalDriverAPI;
+
+ /* If the driver exposes its vtable through its extensions list
+ * (megadrivers), use that instead.
+ */
+ if (driver_extensions) {
+ for (int i = 0; driver_extensions[i]; i++) {
+ if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
+ psp->driver =
+ ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
+ }
+ }
+ }
setupLoaderExtensions(psp, extensions);
@@ -154,12 +185,31 @@ dri2CreateNewScreen(int scrn, int fd,
return psp;
}
+static __DRIscreen *
+dri2CreateNewScreen(int scrn, int fd,
+ const __DRIextension **extensions,
+ const __DRIconfig ***driver_configs, void *data)
+{
+ return dri2CreateNewScreen2(scrn, fd, extensions, NULL,
+ driver_configs, data);
+}
+
/** swrast driver createNewScreen entrypoint. */
static __DRIscreen *
-driCreateNewScreen(int scrn, const __DRIextension **extensions,
- const __DRIconfig ***driver_configs, void *data)
+driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions,
+ const __DRIconfig ***driver_configs, void *data)
+{
+ return dri2CreateNewScreen2(scrn, -1, extensions, NULL,
+ driver_configs, data);
+}
+
+static __DRIscreen *
+driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions,
+ const __DRIextension **driver_extensions,
+ const __DRIconfig ***driver_configs, void *data)
{
- return dri2CreateNewScreen(scrn, -1, extensions, driver_configs, data);
+ return dri2CreateNewScreen2(scrn, -1, extensions, driver_extensions,
+ driver_configs, data);
}
/**
@@ -688,7 +738,7 @@ const __DRIcoreExtension driCoreExtension = {
/** DRI2 interface */
const __DRIdri2Extension driDRI2Extension = {
- .base = { __DRI_DRI2, 3 },
+ .base = { __DRI_DRI2, 4 },
.createNewScreen = dri2CreateNewScreen,
.createNewDrawable = dri2CreateNewDrawable,
@@ -697,15 +747,17 @@ const __DRIdri2Extension driDRI2Extension = {
.createNewContextForAPI = dri2CreateNewContextForAPI,
.allocateBuffer = dri2AllocateBuffer,
.releaseBuffer = dri2ReleaseBuffer,
- .createContextAttribs = dri2CreateContextAttribs
+ .createContextAttribs = dri2CreateContextAttribs,
+ .createNewScreen2 = dri2CreateNewScreen2,
};
const __DRIswrastExtension driSWRastExtension = {
- { __DRI_SWRAST, __DRI_SWRAST_VERSION },
- driCreateNewScreen,
+ { __DRI_SWRAST, 4 },
+ driSWRastCreateNewScreen,
dri2CreateNewDrawable,
dri2CreateNewContextForAPI,
- dri2CreateContextAttribs
+ dri2CreateContextAttribs,
+ driSWRastCreateNewScreen2,
};
const __DRI2configQueryExtension dri2ConfigQueryExtension = {
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h
index 61c80bc45..5b56061e2 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.h
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h
@@ -116,7 +116,7 @@ struct __DriverAPIRec {
};
extern const struct __DriverAPIRec driDriverAPI;
-
+extern const struct __DriverAPIRec *globalDriverAPI;
/**
* Per-screen private driver information.
diff --git a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
new file mode 100644
index 000000000..6bf5d7327
--- /dev/null
+++ b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include "dri_util.h"
+
+static const
+__DRIconfig **stub_error_init_screen(__DRIscreen *psp)
+{
+ fprintf(stderr, "An updated DRI driver loader (libGL.so or X Server) is "
+ "required for this Mesa driver.\n");
+ return NULL;
+}
+
+/**
+ * This is a stub driDriverAPI that is referenced by dri_util.c but should
+ * never be used.
+ */
+const struct __DriverAPIRec driDriverAPI = {
+ .InitScreen = stub_error_init_screen,
+};
diff --git a/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py b/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py
new file mode 100644
index 000000000..ebe4aaa65
--- /dev/null
+++ b/mesalib/src/mesa/drivers/dri/gen-symbol-redefs.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright © 2013 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import sys
+import argparse
+import re
+import subprocess
+
+# Example usages:
+# ./gen-symbol-redefs.py i915/.libs/libi915_dri.a old_ i915 i830
+# ./gen-symbol-redefs.py r200/.libs/libr200_dri.a r200_ r200
+
+argparser = argparse.ArgumentParser(description="Generates #defines to hide driver global symbols outside of a driver's namespace.")
+argparser.add_argument("file",
+ metavar = 'file',
+ help='libdrivername.a file to read')
+argparser.add_argument("newprefix",
+ metavar = 'newprefix',
+ help='New prefix to give non-driver global symbols')
+argparser.add_argument('prefixes',
+ metavar='prefix',
+ nargs='*',
+ help='driver-specific prefixes')
+args = argparser.parse_args()
+
+stdout = subprocess.check_output(['nm', args.file])
+
+for line in stdout.splitlines():
+ m = re.match("[0-9a-z]+ [BT] (.*)", line)
+ if not m:
+ continue
+
+ symbol = m.group(1)
+
+ has_good_prefix = re.match(args.newprefix, symbol) != None
+ for prefix in args.prefixes:
+ if re.match(prefix, symbol):
+ has_good_prefix = True
+ break
+ if has_good_prefix:
+ continue
+
+ # This is the single public entrypoint.
+ if re.match("__driDriverGetExtensions", symbol):
+ continue
+
+ print '#define {0:35} {1}{0}'.format(symbol, args.newprefix)
diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am
index c51ad2d87..0837b4518 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am
@@ -34,19 +34,5 @@ AM_CFLAGS = \
$(DEFINES) \
$(VISIBILITY_CFLAGS)
-dridir = $(DRI_DRIVER_INSTALL_DIR)
-dri_LTLIBRARIES = swrast_dri.la
-
-swrast_dri_la_SOURCES = \
- $(SWRAST_C_FILES)
-
-swrast_dri_la_LDFLAGS = $(DRI_DRIVER_LDFLAGS)
-
-swrast_dri_la_LIBADD = \
- $(DRI_LIB_DEPS)
-
-# Provide compatibility with scripts for the old Mesa build system for
-# a while by putting a link to the driver into /lib of the build tree.
-all-local: swrast_dri.la
- $(MKDIR_P) $(top_builddir)/$(LIB_DIR);
- ln -f .libs/swrast_dri.so $(top_builddir)/$(LIB_DIR)/swrast_dri.so;
+noinst_LTLIBRARIES = libswrast_dri.la
+libswrast_dri_la_SOURCES = $(SWRAST_C_FILES)
diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources
index fc7ef32db..70e432feb 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources
+++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources
@@ -1,11 +1,5 @@
SWRAST_DRIVER_FILES = \
swrast.c
-SWRAST_COMMON_FILES = \
- ../common/utils.c \
- ../common/dri_util.c \
- ../common/xmlconfig.c
-
SWRAST_C_FILES = \
- $(SWRAST_COMMON_FILES) \
$(SWRAST_DRIVER_FILES)
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 4725a7f42..bfa2efd21 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -59,6 +59,7 @@
#include "swrast_priv.h"
#include "swrast/s_context.h"
+const __DRIextension **__driDriverGetExtensions_swrast(void);
/**
* Screen and config-related functions
@@ -819,7 +820,7 @@ dri_unbind_context(__DRIcontext * cPriv)
}
-const struct __DriverAPIRec driDriverAPI = {
+static const struct __DriverAPIRec swrast_driver_api = {
.InitScreen = dri_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
@@ -831,9 +832,21 @@ const struct __DriverAPIRec driDriverAPI = {
.UnbindContext = dri_unbind_context,
};
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
+static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
+ .base = { __DRI_DRIVER_VTABLE, 1 },
+ .vtable = &swrast_driver_api,
+};
+
+static const __DRIextension *swrast_driver_extensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
+ &swrast_vtable.base,
NULL
};
+
+PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void)
+{
+ globalDriverAPI = &swrast_driver_api;
+
+ return swrast_driver_extensions;
+}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 6374e8c0d..97ed1bd6a 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1965,6 +1965,12 @@ struct gl_program
GLboolean UsesGather; /**< Does this program use gather4 at all? */
+ /**
+ * For vertex and geometry shaders, true if the program uses the
+ * gl_ClipDistance output. Ignored for fragment shaders.
+ */
+ GLboolean UsesClipDistanceOut;
+
/** Named parameters, constants, etc. from program text */
struct gl_program_parameter_list *Parameters;
@@ -2009,7 +2015,6 @@ struct gl_vertex_program
{
struct gl_program Base; /**< base class */
GLboolean IsPositionInvariant;
- GLboolean UsesClipDistance;
};
@@ -2023,7 +2028,6 @@ struct gl_geometry_program
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
- GLboolean UsesClipDistance;
GLboolean UsesEndPrimitive;
};
@@ -2476,6 +2480,12 @@ struct gl_shader_program
unsigned NumUserUniformStorage;
struct gl_uniform_storage *UniformStorage;
+ /**
+ * Size of the gl_ClipDistance array that is output from the last pipeline
+ * stage before the fragment shader.
+ */
+ unsigned LastClipDistanceArraySize;
+
struct gl_uniform_block *UniformBlocks;
unsigned NumUniformBlocks;
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index d3677c851..f5c04b9f3 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -460,6 +460,31 @@ get_handle(struct gl_context *ctx, GLenum pname)
/**
+ * Check if a geometry shader query is valid at this time. If not, report an
+ * error and return false.
+ *
+ * From GL 3.2 section 6.1.16 (Shader and Program Queries):
+ *
+ * "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
+ * are queried for a program which has not been linked successfully, or
+ * which does not contain objects to form a geometry shader, then an
+ * INVALID_OPERATION error is generated."
+ */
+static bool
+check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
+{
+ if (shProg->LinkStatus &&
+ shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
+ return true;
+ }
+
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramv(linked geometry shader required)");
+ return false;
+}
+
+
+/**
* glGetProgramiv() - get shader program state.
* Note that this is for GLSL shader programs, not ARB vertex/fragment
* programs (see glGetProgramivARB).
@@ -477,9 +502,10 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
|| ctx->API == API_OPENGL_CORE
|| _mesa_is_gles3(ctx);
- /* Are geometry shaders available in this context?
+ /* True if geometry shaders (of the form that was adopted into GLSL 1.50
+ * and GL 3.2) are available in this context
*/
- const bool has_gs = _mesa_has_geometry_shaders(ctx);
+ const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
/* Are uniform buffer objects available in this context?
*/
@@ -564,20 +590,23 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
break;
*params = shProg->TransformFeedback.BufferMode;
return;
- case GL_GEOMETRY_VERTICES_OUT_ARB:
- if (!has_gs)
+ case GL_GEOMETRY_VERTICES_OUT:
+ if (!has_core_gs)
break;
- *params = shProg->Geom.VerticesOut;
+ if (check_gs_query(ctx, shProg))
+ *params = shProg->Geom.VerticesOut;
return;
- case GL_GEOMETRY_INPUT_TYPE_ARB:
- if (!has_gs)
+ case GL_GEOMETRY_INPUT_TYPE:
+ if (!has_core_gs)
break;
- *params = shProg->Geom.InputType;
+ if (check_gs_query(ctx, shProg))
+ *params = shProg->Geom.InputType;
return;
- case GL_GEOMETRY_OUTPUT_TYPE_ARB:
- if (!has_gs)
+ case GL_GEOMETRY_OUTPUT_TYPE:
+ if (!has_core_gs)
break;
- *params = shProg->Geom.OutputType;
+ if (check_gs_query(ctx, shProg))
+ *params = shProg->Geom.OutputType;
return;
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
unsigned i;
@@ -1631,55 +1660,6 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
return;
switch (pname) {
- case GL_GEOMETRY_VERTICES_OUT_ARB:
- if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
- break;
-
- if (value < 0 ||
- (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)",
- value);
- return;
- }
- shProg->Geom.VerticesOut = value;
- return;
- case GL_GEOMETRY_INPUT_TYPE_ARB:
- if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
- break;
-
- switch (value) {
- case GL_POINTS:
- case GL_LINES:
- case GL_LINES_ADJACENCY_ARB:
- case GL_TRIANGLES:
- case GL_TRIANGLES_ADJACENCY_ARB:
- shProg->Geom.InputType = value;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry input type = %s)",
- _mesa_lookup_enum_by_nr(value));
- return;
- }
- return;
- case GL_GEOMETRY_OUTPUT_TYPE_ARB:
- if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
- break;
-
- switch (value) {
- case GL_POINTS:
- case GL_LINE_STRIP:
- case GL_TRIANGLE_STRIP:
- shProg->Geom.OutputType = value;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry output type = %s)",
- _mesa_lookup_enum_by_nr(value));
- return;
- }
- return;
case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
/* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
* is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
@@ -1855,10 +1835,8 @@ _mesa_copy_linked_program_data(gl_shader_type type,
struct gl_program *dst)
{
switch (type) {
- case MESA_SHADER_VERTEX: {
- struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst;
- dst_vp->UsesClipDistance = src->Vert.UsesClipDistance;
- }
+ case MESA_SHADER_VERTEX:
+ dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;
break;
case MESA_SHADER_GEOMETRY: {
struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
@@ -1866,7 +1844,7 @@ _mesa_copy_linked_program_data(gl_shader_type type,
dst_gp->VerticesOut = src->Geom.VerticesOut;
dst_gp->InputType = src->Geom.InputType;
dst_gp->OutputType = src->Geom.OutputType;
- dst_gp->UsesClipDistance = src->Geom.UsesClipDistance;
+ dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;
dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
}
break;
diff --git a/mesalib/src/mesa/program/Makefile.am b/mesalib/src/mesa/program/Makefile.am
index ab565e251..5e05782fb 100644
--- a/mesalib/src/mesa/program/Makefile.am
+++ b/mesalib/src/mesa/program/Makefile.am
@@ -24,25 +24,13 @@ include ../Makefile.sources
AM_CPPFLAGS = $(DEFINES) $(INCLUDE_DIRS)
AM_CFLAGS = $(VISIBILITY_CFLAGS)
AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
-libdricore_program_la_CFLAGS = $(NOVISIBILITY_CFLAGS)
-libdricore_program_la_CXXFLAGS = $(NOVISIBILITY_CXXFLAGS)
SRCDIR = $(top_srcdir)/src/mesa/
BUILDDIR = $(top_builddir)/src/mesa/
-if NEED_LIBDRICORE
-DRICORE_LIB = libdricore_program.la
-endif
-
-noinst_LTLIBRARIES = $(DRICORE_LIB)
-if NEED_LIBPROGRAM
-noinst_LTLIBRARIES += libprogram.la
-else
-check_LTLIBRARIES = libprogram.la
-endif
+noinst_LTLIBRARIES = libprogram.la
libprogram_la_SOURCES = $(PROGRAM_FILES)
-libdricore_program_la_SOURCES = $(PROGRAM_FILES)
lex.yy.c: program_lexer.l
$(AM_V_GEN) $(LEX) --never-interactive --outfile=$@ $<
diff --git a/mesalib/src/mesa/x86/read_rgba_span_x86.S b/mesalib/src/mesa/x86/read_rgba_span_x86.S
index 3be4515b1..817729973 100644
--- a/mesalib/src/mesa/x86/read_rgba_span_x86.S
+++ b/mesalib/src/mesa/x86/read_rgba_span_x86.S
@@ -77,9 +77,7 @@
*/
.globl _generic_read_RGBA_span_BGRA8888_REV_MMX
-#ifndef USE_DRICORE
.hidden _generic_read_RGBA_span_BGRA8888_REV_MMX
-#endif
.type _generic_read_RGBA_span_BGRA8888_REV_MMX, @function
_generic_read_RGBA_span_BGRA8888_REV_MMX:
pushl %ebx
@@ -174,9 +172,7 @@ _generic_read_RGBA_span_BGRA8888_REV_MMX:
*/
.globl _generic_read_RGBA_span_BGRA8888_REV_SSE
-#ifndef USE_DRICORE
.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE
-#endif
.type _generic_read_RGBA_span_BGRA8888_REV_SSE, @function
_generic_read_RGBA_span_BGRA8888_REV_SSE:
pushl %esi
@@ -339,9 +335,7 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE:
.text
.globl _generic_read_RGBA_span_BGRA8888_REV_SSE2
-#ifndef USE_DRICORE
.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2
-#endif
.type _generic_read_RGBA_span_BGRA8888_REV_SSE2, @function
_generic_read_RGBA_span_BGRA8888_REV_SSE2:
pushl %esi
@@ -500,9 +494,7 @@ _generic_read_RGBA_span_BGRA8888_REV_SSE2:
.text
.globl _generic_read_RGBA_span_RGB565_MMX
-#ifndef USE_DRICORE
.hidden _generic_read_RGBA_span_RGB565_MMX
-#endif
.type _generic_read_RGBA_span_RGB565_MMX, @function
_generic_read_RGBA_span_RGB565_MMX: