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.cpp49
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp7
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y20
-rw-r--r--mesalib/src/glsl/glsl_parser.yy6
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp14
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/hir_field_selection.cpp60
-rw-r--r--mesalib/src/glsl/ir_reader.cpp2
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp42
-rw-r--r--mesalib/src/glsl/linker.cpp25
-rw-r--r--mesalib/src/glsl/lower_named_interface_blocks.cpp3
11 files changed, 180 insertions, 50 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index e918adeef..4b5f04980 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -3358,7 +3358,7 @@ ast_jump_statement::hir(exec_list *instructions,
assert(state->current_function);
if (opt_return_value) {
- ir_rvalue *const ret = opt_return_value->hir(instructions, state);
+ ir_rvalue *ret = opt_return_value->hir(instructions, state);
/* The value of the return type can be NULL if the shader says
* 'return foo();' and foo() is a function that returns void.
@@ -3370,17 +3370,46 @@ ast_jump_statement::hir(exec_list *instructions,
const glsl_type *const ret_type =
(ret == NULL) ? glsl_type::void_type : ret->type;
- /* Implicit conversions are not allowed for return values. */
- if (state->current_function->return_type != ret_type) {
+ /* Implicit conversions are not allowed for return values prior to
+ * ARB_shading_language_420pack.
+ */
+ if (state->current_function->return_type != ret_type) {
YYLTYPE loc = this->get_location();
- _mesa_glsl_error(& loc, state,
- "`return' with wrong type %s, in function `%s' "
- "returning %s",
- ret_type->name,
- state->current_function->function_name(),
- state->current_function->return_type->name);
- }
+ if (state->ARB_shading_language_420pack_enable) {
+ if (!apply_implicit_conversion(state->current_function->return_type,
+ ret, state)) {
+ _mesa_glsl_error(& loc, state,
+ "Could not implicitly convert return value "
+ "to %s, in function `%s'",
+ state->current_function->return_type->name,
+ state->current_function->function_name());
+ }
+ } else {
+ _mesa_glsl_error(& loc, state,
+ "`return' with wrong type %s, in function `%s' "
+ "returning %s",
+ ret_type->name,
+ state->current_function->function_name(),
+ state->current_function->return_type->name);
+ }
+ } else if (state->current_function->return_type->base_type ==
+ GLSL_TYPE_VOID) {
+ YYLTYPE loc = this->get_location();
+
+ /* The ARB_shading_language_420pack, GLSL ES 3.0, and GLSL 4.20
+ * specs add a clarification:
+ *
+ * "A void function can only use return without a return argument, even if
+ * the return argument has void type. Return statements only accept values:
+ *
+ * void func1() { }
+ * void func2() { return func1(); } // illegal return statement"
+ */
+ _mesa_glsl_error(& loc, state,
+ "void functions can only use `return' without a "
+ "return argument");
+ }
inst = new(ctx) ir_return(ret);
} else {
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 4bb361c2e..f4ac20543 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -790,6 +790,13 @@ generate_130_uniforms(exec_list *instructions,
state->Const.MaxClipPlanes);
add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents",
state->Const.MaxVaryingFloats);
+
+ if (state->ARB_shading_language_420pack_enable) {
+ add_builtin_constant(instructions, symtab, "gl_MinProgramTexelOffset",
+ state->Const.MinProgramTexelOffset);
+ add_builtin_constant(instructions, symtab, "gl_MaxProgramTexelOffset",
+ state->Const.MaxProgramTexelOffset);
+ }
}
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index 81ba04bcc..ff5bdfe5d 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1184,14 +1184,14 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
parser->is_gles = false;
/* Add pre-defined macros. */
- if (extensions != NULL) {
- if (extensions->OES_EGL_image_external)
- add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
- }
-
if (api == API_OPENGLES2) {
- parser->is_gles = true;
- add_builtin_define(parser, "GL_ES", 1);
+ parser->is_gles = true;
+ add_builtin_define(parser, "GL_ES", 1);
+
+ if (extensions != NULL) {
+ if (extensions->OES_EGL_image_external)
+ add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
+ }
} else {
add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
@@ -1242,6 +1242,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->AMD_vertex_shader_layer)
add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
+
+ if (extensions->ARB_shading_language_420pack)
+ add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
}
}
@@ -2064,6 +2067,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
add_builtin_define (parser, "GL_ES", 1);
}
+ if (version >= 150)
+ add_builtin_define(parser, "GL_core_profile", 1);
+
/* Currently, all ES2/ES3 implementations support highp in the
* fragment shader, so we always define this macro in ES2/ES3.
* If we ever get a driver that doesn't support highp, we'll
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 6e92c2651..56367f8c6 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -267,10 +267,16 @@ version_statement:
| VERSION_TOK INTCONSTANT EOL
{
state->process_version_directive(&@2, $2, NULL);
+ if (state->error) {
+ YYERROR;
+ }
}
| VERSION_TOK INTCONSTANT any_identifier EOL
{
state->process_version_directive(&@2, $2, $3);
+ if (state->error) {
+ YYERROR;
+ }
}
;
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index c0dd71370..98627145a 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -226,6 +226,19 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
if (ident) {
if (strcmp(ident, "es") == 0) {
es_token_present = true;
+ } else if (version >= 150) {
+ if (strcmp(ident, "core") == 0) {
+ /* Accept the token. There's no need to record that this is
+ * a core profile shader since that's the only profile we support.
+ */
+ } else if (strcmp(ident, "compatibility") == 0) {
+ _mesa_glsl_error(locp, this,
+ "The compatibility profile is not supported.\n");
+ } else {
+ _mesa_glsl_error(locp, this,
+ "\"%s\" is not a valid shading language profile; "
+ "if present, it must be \"core\".\n", ident);
+ }
} else {
_mesa_glsl_error(locp, this,
"Illegal text following version number\n");
@@ -466,6 +479,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives),
EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
+ EXT(ARB_shading_language_420pack, true, true, true, true, false, ARB_shading_language_420pack),
EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample),
EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod),
EXT(ARB_gpu_shader5, true, true, true, true, false, ARB_gpu_shader5),
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 16e180d3e..95918de72 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -288,6 +288,8 @@ struct _mesa_glsl_parse_state {
bool ARB_gpu_shader5_warn;
bool AMD_vertex_shader_layer_enable;
bool AMD_vertex_shader_layer_warn;
+ bool ARB_shading_language_420pack_enable;
+ bool ARB_shading_language_420pack_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/mesalib/src/glsl/hir_field_selection.cpp b/mesalib/src/glsl/hir_field_selection.cpp
index 0035a5f81..ceb0a4cdb 100644
--- a/mesalib/src/glsl/hir_field_selection.cpp
+++ b/mesalib/src/glsl/hir_field_selection.cpp
@@ -47,20 +47,6 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
YYLTYPE loc = expr->get_location();
if (op->type->is_error()) {
/* silently propagate the error */
- } else if (op->type->is_vector()) {
- ir_swizzle *swiz = ir_swizzle::create(op,
- expr->primary_expression.identifier,
- op->type->vector_elements);
- if (swiz != NULL) {
- result = swiz;
- } else {
- /* FINISHME: Logging of error messages should be moved into
- * FINISHME: ir_swizzle::create. This allows the generation of more
- * FINISHME: specific error messages.
- */
- _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
- expr->primary_expression.identifier);
- }
} else if (op->type->base_type == GLSL_TYPE_STRUCT
|| op->type->base_type == GLSL_TYPE_INTERFACE) {
result = new(ctx) ir_dereference_record(op,
@@ -81,17 +67,51 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
const char *method;
method = call->subexpressions[0]->primary_expression.identifier;
- if (op->type->is_array() && strcmp(method, "length") == 0) {
- if (!call->expressions.is_empty())
- _mesa_glsl_error(&loc, state, "length method takes no arguments.");
+ if (strcmp(method, "length") == 0) {
+ if (!call->expressions.is_empty())
+ _mesa_glsl_error(&loc, state, "length method takes no arguments.");
- if (op->type->array_size() == 0)
- _mesa_glsl_error(&loc, state, "length called on unsized array.");
+ if (op->type->is_array()) {
+ if (op->type->array_size() == 0)
+ _mesa_glsl_error(&loc, state, "length called on unsized array.");
- result = new(ctx) ir_constant(op->type->array_size());
+ result = new(ctx) ir_constant(op->type->array_size());
+ } else if (op->type->is_vector()) {
+ if (state->ARB_shading_language_420pack_enable) {
+ /* .length() returns int. */
+ result = new(ctx) ir_constant((int) op->type->vector_elements);
+ } else {
+ _mesa_glsl_error(&loc, state, "length method on matrix only available"
+ "with ARB_shading_language_420pack.");
+ }
+ } else if (op->type->is_matrix()) {
+ if (state->ARB_shading_language_420pack_enable) {
+ /* .length() returns int. */
+ result = new(ctx) ir_constant((int) op->type->matrix_columns);
+ } else {
+ _mesa_glsl_error(&loc, state, "length method on matrix only available"
+ "with ARB_shading_language_420pack.");
+ }
+ }
} else {
_mesa_glsl_error(&loc, state, "Unknown method: `%s'.", method);
}
+ } else if (op->type->is_vector() ||
+ (state->ARB_shading_language_420pack_enable &&
+ op->type->is_scalar())) {
+ ir_swizzle *swiz = ir_swizzle::create(op,
+ expr->primary_expression.identifier,
+ op->type->vector_elements);
+ if (swiz != NULL) {
+ result = swiz;
+ } else {
+ /* FINISHME: Logging of error messages should be moved into
+ * FINISHME: ir_swizzle::create. This allows the generation of more
+ * FINISHME: specific error messages.
+ */
+ _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
+ expr->primary_expression.identifier);
+ }
} else {
_mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
"non-structure / non-vector.",
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index b3667124f..51534ca7c 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -886,7 +886,7 @@ ir_reader::read_dereference(s_expression *expr)
}
ir_rvalue *idx = read_rvalue(s_index);
- if (subject == NULL) {
+ if (idx == NULL) {
ir_read_error(NULL, "when reading the index of an array_ref");
return NULL;
}
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index ad636681f..208778e4a 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -170,6 +170,7 @@ public:
void process(ir_variable *var)
{
+ this->is_ubo_var = var->is_in_uniform_block();
if (var->is_interface_instance())
program_resource_visitor::process(var->interface_type,
var->interface_type->name);
@@ -197,6 +198,8 @@ public:
*/
unsigned num_shader_uniform_components;
+ bool is_ubo_var;
+
private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
@@ -222,7 +225,8 @@ private:
* Note that samplers do not count against this limit because they
* don't use any storage on current hardware.
*/
- this->num_shader_uniform_components += values;
+ if (!is_ubo_var)
+ this->num_shader_uniform_components += values;
}
/* If the uniform is already in the map, there's nothing more to do.
@@ -640,7 +644,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
*/
count_uniform_size uniform_size(prog->UniformHash);
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
- if (prog->_LinkedShaders[i] == NULL)
+ struct gl_shader *sh = prog->_LinkedShaders[i];
+
+ if (sh == NULL)
continue;
/* Uniforms that lack an initializer in the shader code have an initial
@@ -652,16 +658,15 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
* initializer, if present, or 0 if no initializer is present. Sampler
* types cannot have initializers."
*/
- memset(prog->_LinkedShaders[i]->SamplerUnits, 0,
- sizeof(prog->_LinkedShaders[i]->SamplerUnits));
+ memset(sh->SamplerUnits, 0, sizeof(sh->SamplerUnits));
- link_update_uniform_buffer_variables(prog->_LinkedShaders[i]);
+ link_update_uniform_buffer_variables(sh);
/* Reset various per-shader target counts.
*/
uniform_size.start_shader();
- foreach_list(node, prog->_LinkedShaders[i]->ir) {
+ foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != ir_var_uniform))
@@ -678,9 +683,14 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
uniform_size.process(var);
}
- prog->_LinkedShaders[i]->num_samplers = uniform_size.num_shader_samplers;
- prog->_LinkedShaders[i]->num_uniform_components =
- uniform_size.num_shader_uniform_components;
+ sh->num_samplers = uniform_size.num_shader_samplers;
+ sh->num_uniform_components = uniform_size.num_shader_uniform_components;
+
+ sh->num_combined_uniform_components = sh->num_uniform_components;
+ for (unsigned i = 0; i < sh->NumUniformBlocks; i++) {
+ sh->num_combined_uniform_components +=
+ sh->UniformBlocks[i].UniformBufferSize / 4;
+ }
}
const unsigned num_user_uniforms = uniform_size.num_active_uniforms;
@@ -729,6 +739,20 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
}
+ /* Determine the size of the largest uniform array queryable via
+ * glGetUniformLocation. Using this as the location scale guarantees that
+ * there is enough "room" for the array index to be stored in the low order
+ * part of the uniform location. It also makes the locations be more
+ * tightly packed.
+ */
+ unsigned max_array_size = 1;
+ for (unsigned i = 0; i < num_user_uniforms; i++) {
+ if (uniforms[i].array_elements > max_array_size)
+ max_array_size = uniforms[i].array_elements;
+ }
+
+ prog->UniformLocationBaseScale = max_array_size;
+
#ifndef NDEBUG
for (unsigned i = 0; i < num_user_uniforms; i++) {
assert(uniforms[i].storage != NULL);
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 982fe46bd..cd8d680ae 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1523,12 +1523,18 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
ctx->Const.GeometryProgram.MaxTextureImageUnits
};
- const unsigned max_uniform_components[MESA_SHADER_TYPES] = {
+ const unsigned max_default_uniform_components[MESA_SHADER_TYPES] = {
ctx->Const.VertexProgram.MaxUniformComponents,
ctx->Const.FragmentProgram.MaxUniformComponents,
ctx->Const.GeometryProgram.MaxUniformComponents
};
+ const unsigned max_combined_uniform_components[MESA_SHADER_TYPES] = {
+ ctx->Const.VertexProgram.MaxCombinedUniformComponents,
+ ctx->Const.FragmentProgram.MaxCombinedUniformComponents,
+ ctx->Const.GeometryProgram.MaxCombinedUniformComponents
+ };
+
const unsigned max_uniform_blocks[MESA_SHADER_TYPES] = {
ctx->Const.VertexProgram.MaxUniformBlocks,
ctx->Const.FragmentProgram.MaxUniformBlocks,
@@ -1546,7 +1552,22 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
shader_names[i]);
}
- if (sh->num_uniform_components > max_uniform_components[i]) {
+ if (sh->num_uniform_components > max_default_uniform_components[i]) {
+ if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
+ linker_warning(prog, "Too many %s shader default uniform block "
+ "components, but the driver will try to optimize "
+ "them out; this is non-portable out-of-spec "
+ "behavior\n",
+ shader_names[i]);
+ } else {
+ linker_error(prog, "Too many %s shader default uniform block "
+ "components",
+ shader_names[i]);
+ }
+ }
+
+ if (sh->num_combined_uniform_components >
+ max_combined_uniform_components[i]) {
if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
linker_warning(prog, "Too many %s shader uniform components, "
"but the driver will try to optimize them out; "
diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp
index eba667a8b..922cc024f 100644
--- a/mesalib/src/glsl/lower_named_interface_blocks.cpp
+++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp
@@ -72,7 +72,8 @@ public:
hash_table *interface_namespace;
flatten_named_interface_blocks_declarations(void *mem_ctx)
- : mem_ctx(mem_ctx)
+ : mem_ctx(mem_ctx),
+ interface_namespace(NULL)
{
}