aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-08-26 09:04:58 +0200
committermarha <marha@users.sourceforge.net>2013-08-26 09:04:58 +0200
commit5ee5b91b019005aa27273dff01388a68c12be293 (patch)
treed2db8b0d1533d2eea8bfe77f8a6b3d52fa3f633e /mesalib/src/glsl
parent854ec4da20ddff9b830be0a7d5b81d8cb4774132 (diff)
downloadvcxsrv-5ee5b91b019005aa27273dff01388a68c12be293.tar.gz
vcxsrv-5ee5b91b019005aa27273dff01388a68c12be293.tar.bz2
vcxsrv-5ee5b91b019005aa27273dff01388a68c12be293.zip
xserver mesa fontconfig libX11 libxcb libxcb/xcb-proto xkeyboard-config git update 26 Aug 2013
xserver commit e01a3f65d3e6d92f92ef2992b338cc9625bde082 libxcb commit c52f2891b43ae77008f63700982f800371458f4d libxcb/xcb-proto commit bd7708ac1037e647b094fa7440ebb6171b9bc75f xkeyboard-config commit 77026e8c59cc64856180452c5f89be86928fea7c libX11 commit e9b14d10d0258bfcc273ff8bc84cd349dccda62c libXdmcp commit 66514a4af7eaa47e8718434356d7efce95e570cf libXext commit 7378d4bdbd33ed49ed6cfa5c4f73d7527982aab4 libfontenc commit 3acba630d8b57084f7e92c15732408711ed5137a libXinerama commit 6e1d1dc328ba8162bba2f4694e7f3c706a1491ff libXau commit 899790011304c4029e15abf410e49ce7cec17e0a xkbcomp commit 0ebdf47fd4bc434ac3d2339544c022a869510738 pixman commit 3518a0dafa63098d41e466f73d105b7e3e4b12de xextproto commit f27fcc99d1cf935cc289933326f7d3baacd5107a randrproto commit ca7cc541c2e43e6c784df19b4583ac35829d2f72 glproto commit 8e3407e02980d088e20041e79bdcdd3737e7827e mkfontscale commit f48de13423c7300f4da9f61993b624426b38ddc0 xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13 libXft commit c5e760a239afc62a1c75e0509868e35957c8df52 libXmu commit d5dac08d65c4865f311cb62c161dbb1300eecd11 libxtrans commit f6a161f2a003f4da0a2e414b4faa0ee0de0c01f0 fontconfig commit fba9efecd2ef3aca84e0a4806899c09ba95f4c19 mesa commit 7fa18774bd9d0e97a82ee9b7dfce8fc5a1041c3a
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/ast.h10
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp145
-rw-r--r--mesalib/src/glsl/ast_type.cpp3
-rw-r--r--mesalib/src/glsl/glsl_parser.yy1
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h7
-rw-r--r--mesalib/src/glsl/link_uniform_blocks.cpp17
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp56
-rw-r--r--mesalib/src/glsl/linker.cpp82
-rw-r--r--mesalib/src/glsl/linker.h15
-rw-r--r--mesalib/src/glsl/main.cpp2
11 files changed, 260 insertions, 80 deletions
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index 9b194dbd0..1c7fc63ac 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -610,6 +610,10 @@ public:
virtual void print(void) const;
bool has_qualifiers() const;
+ const struct glsl_type *glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state)
+ const;
+
ast_type_qualifier qualifier;
ast_type_specifier *specifier;
};
@@ -635,12 +639,6 @@ public:
* is used to note these cases when no type is specified.
*/
int invariant;
-
- /**
- * Flag indicating that these declarators are in a uniform block,
- * allowing UBO type qualifiers.
- */
- bool ubo_qualifiers_valid;
};
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 04b16c8aa..feff5865a 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -1797,6 +1797,28 @@ ast_type_specifier::glsl_type(const char **name,
return type;
}
+const glsl_type *
+ast_fully_specified_type::glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state) const
+{
+ const struct glsl_type *type = this->specifier->glsl_type(name, state);
+
+ if (type == NULL)
+ return NULL;
+
+ if (type->base_type == GLSL_TYPE_FLOAT
+ && state->es_shader
+ && state->target == fragment_shader
+ && this->qualifier.precision == ast_precision_none
+ && state->symbols->get_variable("#default precision") == NULL) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "no precision specified this scope for type `%s'",
+ type->name);
+ }
+
+ return type;
+}
/**
* Determine whether a toplevel variable declaration declares a varying. This
@@ -1829,11 +1851,17 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
YYLTYPE *loc,
const glsl_type *type)
{
- if (!type->is_matrix() && !type->is_record()) {
- _mesa_glsl_error(loc, state,
- "uniform block layout qualifiers row_major and "
- "column_major can only be applied to matrix and "
- "structure types");
+ if (!type->is_matrix()) {
+ /* The OpenGL ES 3.0 conformance tests did not originally allow
+ * matrix layout qualifiers on non-matrices. However, the OpenGL
+ * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were
+ * amended to specifically allow these layouts on all types. Emit
+ * a warning so that people know their code may not be portable.
+ */
+ _mesa_glsl_warning(loc, state,
+ "uniform block layout qualifiers row_major and "
+ "column_major applied to non-matrix types may "
+ "be rejected by older compilers");
} else if (type->is_record()) {
/* We allow 'layout(row_major)' on structure types because it's the only
* way to get row-major layouts on matrices contained in structures.
@@ -1841,7 +1869,7 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state,
_mesa_glsl_warning(loc, state,
"uniform block layout qualifiers row_major and "
"column_major applied to structure types is not "
- "strictly conformant and my be rejected by other "
+ "strictly conformant and may be rejected by other "
"compilers");
}
}
@@ -1929,7 +1957,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
ir_variable *var,
struct _mesa_glsl_parse_state *state,
YYLTYPE *loc,
- bool ubo_qualifiers_valid,
bool is_parameter)
{
STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
@@ -2275,13 +2302,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
}
if (qual->flags.q.row_major || qual->flags.q.column_major) {
- if (!ubo_qualifiers_valid) {
- _mesa_glsl_error(loc, state,
- "uniform block layout qualifiers row_major and "
- "column_major can only be applied to uniform block "
- "members");
- } else
- validate_matrix_layout_for_type(state, loc, var->type);
+ validate_matrix_layout_for_type(state, loc, var->type);
}
}
@@ -2693,7 +2714,7 @@ ast_declarator_list::hir(exec_list *instructions,
*/
(void) this->type->specifier->hir(instructions, state);
- decl_type = this->type->specifier->glsl_type(& type_name, state);
+ decl_type = this->type->glsl_type(& type_name, state);
if (this->declarations.is_empty()) {
/* If there is no structure involved in the program text, there are two
* possible scenarios:
@@ -2830,7 +2851,7 @@ ast_declarator_list::hir(exec_list *instructions,
}
apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
- & loc, this->ubo_qualifiers_valid, false);
+ & loc, false);
if (this->type->qualifier.flags.q.invariant) {
if ((state->target == vertex_shader) &&
@@ -3277,7 +3298,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
const char *name = NULL;
YYLTYPE loc = this->get_location();
- type = this->type->specifier->glsl_type(& name, state);
+ type = this->type->glsl_type(& name, state);
if (type == NULL) {
if (name != NULL) {
@@ -3340,7 +3361,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
* for function parameters the default mode is 'in'.
*/
apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
- false, true);
+ true);
/* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
*
@@ -3484,7 +3505,7 @@ ast_function::hir(exec_list *instructions,
const char *return_type_name;
const glsl_type *return_type =
- this->return_type->specifier->glsl_type(& return_type_name, state);
+ this->return_type->glsl_type(& return_type_name, state);
if (!return_type) {
YYLTYPE loc = this->get_location();
@@ -4225,10 +4246,8 @@ ast_iteration_statement::hir(exec_list *instructions,
* version.
*/
static bool
-is_valid_default_precision_type(const struct _mesa_glsl_parse_state *state,
- const char *type_name)
+is_valid_default_precision_type(const struct glsl_type *const type)
{
- const struct glsl_type *type = state->symbols->get_type(type_name);
if (type == NULL)
return false;
@@ -4280,13 +4299,54 @@ ast_type_specifier::hir(exec_list *instructions,
"arrays");
return NULL;
}
- if (!is_valid_default_precision_type(state, this->type_name)) {
+
+ const struct glsl_type *const type =
+ state->symbols->get_type(this->type_name);
+ if (!is_valid_default_precision_type(type)) {
_mesa_glsl_error(&loc, state,
- "default precision statements apply only to types "
+ "default precision statements apply only to "
"float, int, and sampler types");
return NULL;
}
+ if (type->base_type == GLSL_TYPE_FLOAT
+ && state->es_shader
+ && state->target == fragment_shader) {
+ /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
+ * spec says:
+ *
+ * "The fragment language has no default precision qualifier for
+ * floating point types."
+ *
+ * As a result, we have to track whether or not default precision has
+ * been specified for float in GLSL ES fragment shaders.
+ *
+ * Earlier in that same section, the spec says:
+ *
+ * "Non-precision qualified declarations will use the precision
+ * qualifier specified in the most recent precision statement
+ * that is still in scope. The precision statement has the same
+ * scoping rules as variable declarations. If it is declared
+ * inside a compound statement, its effect stops at the end of
+ * the innermost statement it was declared in. Precision
+ * statements in nested scopes override precision statements in
+ * outer scopes. Multiple precision statements for the same basic
+ * type can appear inside the same scope, with later statements
+ * overriding earlier statements within that scope."
+ *
+ * Default precision specifications follow the same scope rules as
+ * variables. So, we can track the state of the default float
+ * precision in the symbol table, and the rules will just work. This
+ * is a slight abuse of the symbol table, but it has the semantics
+ * that we want.
+ */
+ ir_variable *const junk =
+ new(state) ir_variable(type, "#default precision",
+ ir_var_temporary);
+
+ state->symbols->add_variable(junk);
+ }
+
/* FINISHME: Translate precision statements into IR. */
return NULL;
}
@@ -4367,7 +4427,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
}
const glsl_type *decl_type =
- decl_list->type->specifier->glsl_type(& type_name, state);
+ decl_list->type->glsl_type(& type_name, state);
foreach_list_typed (ast_declaration, decl, link,
&decl_list->declarations) {
@@ -4415,11 +4475,6 @@ ast_process_structure_or_interface_block(exec_list *instructions,
_mesa_glsl_error(&loc, state,
"row_major and column_major can only be "
"applied to uniform interface blocks");
- } else if (!field_type->is_matrix() && !field_type->is_record()) {
- _mesa_glsl_error(&loc, state,
- "uniform block layout qualifiers row_major and "
- "column_major can only be applied to matrix and "
- "structure types");
} else
validate_matrix_layout_for_type(state, &loc, field_type);
}
@@ -4455,6 +4510,34 @@ ast_struct_specifier::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
YYLTYPE loc = this->get_location();
+
+ /* Section 4.1.8 (Structures) of the GLSL 1.10 spec says:
+ *
+ * "Anonymous structures are not supported; so embedded structures must
+ * have a declarator. A name given to an embedded struct is scoped at
+ * the same level as the struct it is embedded in."
+ *
+ * The same section of the GLSL 1.20 spec says:
+ *
+ * "Anonymous structures are not supported. Embedded structures are not
+ * supported.
+ *
+ * struct S { float f; };
+ * struct T {
+ * S; // Error: anonymous structures disallowed
+ * struct { ... }; // Error: embedded structures disallowed
+ * S s; // Okay: nested structures with name are allowed
+ * };"
+ *
+ * The GLSL ES 1.00 and 3.00 specs have similar langauge and examples. So,
+ * we allow embedded structures in 1.10 only.
+ */
+ if (state->language_version != 110 && state->struct_specifier_depth != 0)
+ _mesa_glsl_error(&loc, state,
+ "embedded structure declartions are not allowed");
+
+ state->struct_specifier_depth++;
+
glsl_struct_field *fields;
unsigned decl_count =
ast_process_structure_or_interface_block(instructions,
@@ -4481,6 +4564,8 @@ ast_struct_specifier::hir(exec_list *instructions,
}
}
+ state->struct_specifier_depth--;
+
/* Structure type definitions do not have r-values.
*/
return NULL;
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index ce6b6a771..8aabd95f9 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -168,6 +168,9 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
if (q.flags.q.explicit_binding)
this->binding = q.binding;
+ if (q.precision != ast_precision_none)
+ this->precision = q.precision;
+
return true;
}
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index e3a57ea02..d8e589d49 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -2295,7 +2295,6 @@ member_declaration:
$$ = new(ctx) ast_declarator_list(type);
$$->set_location(yylloc);
- $$->ubo_qualifiers_valid = true;
$$->declarations.push_degenerate_list_at_head(& $2->link);
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 88f048365..8669b7762 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -71,6 +71,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->loop_nesting_ast = NULL;
this->switch_state.switch_nesting_ast = NULL;
+ this->struct_specifier_depth = 0;
this->num_builtins_to_link = 0;
/* Set default language version and extensions */
@@ -1170,7 +1171,6 @@ ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
{
this->type = type;
this->invariant = false;
- this->ubo_qualifiers_valid = false;
}
void
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index b9ca4e3a4..440c15bb8 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -159,6 +159,13 @@ struct _mesa_glsl_parse_state {
enum _mesa_glsl_parser_targets target;
/**
+ * Number of nested struct_specifier levels
+ *
+ * Outside a struct_specifer, this is zero.
+ */
+ unsigned struct_specifier_depth;
+
+ /**
* Default uniform layout qualifiers tracked during parsing.
* Currently affects uniform blocks and uniform buffer variables in
* those blocks.
diff --git a/mesalib/src/glsl/link_uniform_blocks.cpp b/mesalib/src/glsl/link_uniform_blocks.cpp
index 1083653c7..d96075849 100644
--- a/mesalib/src/glsl/link_uniform_blocks.cpp
+++ b/mesalib/src/glsl/link_uniform_blocks.cpp
@@ -59,6 +59,15 @@ private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
+ (void) type;
+ (void) name;
+ (void) row_major;
+ assert(!"Should not get here.");
+ }
+
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major, const glsl_type *record_type)
+ {
assert(this->index < this->num_variables);
gl_uniform_buffer_variable *v = &this->variables[this->index++];
@@ -85,7 +94,9 @@ private:
v->IndexName = v->Name;
}
- unsigned alignment = type->std140_base_alignment(v->RowMajor);
+ const unsigned alignment = record_type
+ ? record_type->std140_base_alignment(v->RowMajor)
+ : type->std140_base_alignment(v->RowMajor);
unsigned size = type->std140_size(v->RowMajor);
this->offset = glsl_align(this->offset, alignment);
@@ -107,6 +118,10 @@ private:
virtual void visit_field(const glsl_struct_field *field)
{
+ /* FINISHME: When support for doubles (dvec4, etc.) is added to the
+ * FINISHME: compiler, this may be incorrect for a structure in a UBO
+ * FINISHME: like struct s { struct { float f } s1; dvec4 v; };.
+ */
this->offset = glsl_align(this->offset,
field->type->std140_base_alignment(false));
}
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index 35ace1ec3..fa77157f7 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -60,7 +60,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name)
|| (type->is_array() && type->fields.array->is_interface()));
char *name_copy = ralloc_strdup(NULL, name);
- recursion(type, &name_copy, strlen(name), false);
+ recursion(type, &name_copy, strlen(name), false, NULL);
ralloc_free(name_copy);
}
@@ -77,24 +77,25 @@ 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())) {
char *name = ralloc_strdup(NULL, var->name);
- recursion(var->type, &name, strlen(name), false);
+ recursion(var->type, &name, strlen(name), false, NULL);
ralloc_free(name);
} else if (t->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->name);
- recursion(var->type, &name, strlen(name), false);
+ recursion(var->type, &name, strlen(name), false, NULL);
ralloc_free(name);
} else if (t->is_array() && t->fields.array->is_interface()) {
char *name = ralloc_strdup(NULL, var->type->fields.array->name);
- recursion(var->type, &name, strlen(name), false);
+ recursion(var->type, &name, strlen(name), false, NULL);
ralloc_free(name);
} else {
- this->visit_field(t, var->name, false);
+ this->visit_field(t, var->name, false, NULL);
}
}
void
program_resource_visitor::recursion(const glsl_type *t, char **name,
- size_t name_length, bool row_major)
+ size_t name_length, bool row_major,
+ const glsl_type *record_type)
{
/* Records need to have each field processed individually.
*
@@ -103,6 +104,9 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
* individually.
*/
if (t->is_record() || t->is_interface()) {
+ if (record_type == NULL && t->is_record())
+ record_type = t;
+
for (unsigned i = 0; i < t->length; i++) {
const char *field = t->fields.structure[i].name;
size_t new_length = name_length;
@@ -118,10 +122,18 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
}
recursion(t->fields.structure[i].type, name, new_length,
- t->fields.structure[i].row_major);
+ t->fields.structure[i].row_major, record_type);
+
+ /* Only the first leaf-field of the record gets called with the
+ * record type pointer.
+ */
+ record_type = NULL;
}
} else if (t->is_array() && (t->fields.array->is_record()
|| t->fields.array->is_interface())) {
+ if (record_type == NULL && t->fields.array->is_record())
+ record_type = t->fields.array;
+
for (unsigned i = 0; i < t->length; i++) {
size_t new_length = name_length;
@@ -129,14 +141,27 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
recursion(t->fields.array, name, new_length,
- t->fields.structure[i].row_major);
+ t->fields.structure[i].row_major, record_type);
+
+ /* Only the first leaf-field of the record gets called with the
+ * record type pointer.
+ */
+ record_type = NULL;
}
} else {
- this->visit_field(t, *name, row_major);
+ this->visit_field(t, *name, row_major, record_type);
}
}
void
+program_resource_visitor::visit_field(const glsl_type *type, const char *name,
+ bool row_major,
+ const glsl_type *record_type)
+{
+ visit_field(type, name, row_major);
+}
+
+void
program_resource_visitor::visit_field(const glsl_struct_field *field)
{
(void) field;
@@ -377,6 +402,15 @@ private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
+ (void) type;
+ (void) name;
+ (void) row_major;
+ assert(!"Should not get here.");
+ }
+
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major, const glsl_type *record_type)
+ {
assert(!type->is_record());
assert(!(type->is_array() && type->fields.array->is_record()));
assert(!type->is_interface());
@@ -421,7 +455,9 @@ private:
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
- unsigned alignment = type->std140_base_alignment(ubo_row_major);
+ const unsigned alignment = record_type
+ ? record_type->std140_base_alignment(ubo_row_major)
+ : type->std140_base_alignment(ubo_row_major);
this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
this->uniforms[id].offset = this->ubo_byte_offset;
this->ubo_byte_offset += type->std140_size(ubo_row_major);
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index f87ae0eec..8430096ac 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -373,6 +373,52 @@ link_invalidate_variable_locations(gl_shader *sh, int input_base,
/**
+ * Set UsesClipDistance and ClipDistanceArraySize based on the given shader.
+ *
+ * Also check for errors based on incorrect usage of gl_ClipVertex and
+ * gl_ClipDistance.
+ *
+ * Return false if an error was reported.
+ */
+static void
+analyze_clip_usage(const char *shader_type, struct gl_shader_program *prog,
+ struct gl_shader *shader, GLboolean *UsesClipDistance,
+ GLuint *ClipDistanceArraySize)
+{
+ *ClipDistanceArraySize = 0;
+
+ if (!prog->IsES && prog->Version >= 130) {
+ /* From section 7.1 (Vertex Shader Special Variables) of the
+ * GLSL 1.30 spec:
+ *
+ * "It is an error for a shader to statically write both
+ * gl_ClipVertex and gl_ClipDistance."
+ *
+ * This does not apply to GLSL ES shaders, since GLSL ES defines neither
+ * gl_ClipVertex nor gl_ClipDistance.
+ */
+ find_assignment_visitor clip_vertex("gl_ClipVertex");
+ find_assignment_visitor clip_distance("gl_ClipDistance");
+
+ clip_vertex.run(shader->ir);
+ clip_distance.run(shader->ir);
+ if (clip_vertex.variable_found() && clip_distance.variable_found()) {
+ linker_error(prog, "%s shader writes to both `gl_ClipVertex' "
+ "and `gl_ClipDistance'\n", shader_type);
+ return;
+ }
+ *UsesClipDistance = clip_distance.variable_found();
+ ir_variable *clip_distance_var =
+ shader->symbols->get_variable("gl_ClipDistance");
+ if (clip_distance_var)
+ *ClipDistanceArraySize = clip_distance_var->type->length;
+ } else {
+ *UsesClipDistance = false;
+ }
+}
+
+
+/**
* Verify that a vertex shader executable meets all semantic requirements.
*
* Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize
@@ -422,34 +468,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
}
}
- prog->Vert.ClipDistanceArraySize = 0;
-
- if (!prog->IsES && prog->Version >= 130) {
- /* From section 7.1 (Vertex Shader Special Variables) of the
- * GLSL 1.30 spec:
- *
- * "It is an error for a shader to statically write both
- * gl_ClipVertex and gl_ClipDistance."
- *
- * This does not apply to GLSL ES shaders, since GLSL ES defines neither
- * gl_ClipVertex nor gl_ClipDistance.
- */
- find_assignment_visitor clip_vertex("gl_ClipVertex");
- find_assignment_visitor clip_distance("gl_ClipDistance");
-
- clip_vertex.run(shader->ir);
- clip_distance.run(shader->ir);
- if (clip_vertex.variable_found() && clip_distance.variable_found()) {
- linker_error(prog, "vertex shader writes to both `gl_ClipVertex' "
- "and `gl_ClipDistance'\n");
- return;
- }
- prog->Vert.UsesClipDistance = clip_distance.variable_found();
- ir_variable *clip_distance_var =
- shader->symbols->get_variable("gl_ClipDistance");
- if (clip_distance_var)
- prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length;
- }
+ analyze_clip_usage("vertex", prog, shader, &prog->Vert.UsesClipDistance,
+ &prog->Vert.ClipDistanceArraySize);
}
@@ -480,7 +500,8 @@ validate_fragment_shader_executable(struct gl_shader_program *prog,
/**
* Verify that a geometry shader executable meets all semantic requirements
*
- * Also sets prog->Geom.VerticesIn as a side effect.
+ * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and
+ * prog->Geom.ClipDistanceArraySize as a side effect.
*
* \param shader Geometry shader executable to be verified
*/
@@ -493,6 +514,9 @@ validate_geometry_shader_executable(struct gl_shader_program *prog,
unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
prog->Geom.VerticesIn = num_vertices;
+
+ analyze_clip_usage("geometry", prog, shader, &prog->Geom.UsesClipDistance,
+ &prog->Geom.ClipDistanceArraySize);
}
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 64a683d15..8a0027d2b 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -126,6 +126,19 @@ protected:
* \param type Type of the field.
* \param name Fully qualified name of the field.
* \param row_major For a matrix type, is it stored row-major.
+ * \param record_type Type of the record containing the field.
+ *
+ * The default implementation just calls the other \c visit_field method.
+ */
+ virtual void visit_field(const glsl_type *type, const char *name,
+ bool row_major, const glsl_type *record_type);
+
+ /**
+ * Method invoked for each leaf of the variable
+ *
+ * \param type Type of the field.
+ * \param name Fully qualified name of the field.
+ * \param row_major For a matrix type, is it stored row-major.
*/
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major) = 0;
@@ -146,7 +159,7 @@ private:
* terminating \c NUL character.
*/
void recursion(const glsl_type *t, char **name, size_t name_length,
- bool row_major);
+ bool row_major, const glsl_type *record_type);
};
void
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index 60bc62827..e13d5c452 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -46,7 +46,7 @@ initialize_context(struct gl_context *ctx, gl_api api)
/* The standalone compiler needs to claim support for almost
* everything in order to compile the built-in functions.
*/
- ctx->Const.GLSLVersion = 150;
+ ctx->Const.GLSLVersion = 330;
ctx->Extensions.ARB_ES3_compatibility = true;
ctx->Const.MaxClipPlanes = 8;