diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 49 | ||||
-rw-r--r-- | mesalib/src/glsl/builtin_variables.cpp | 7 | ||||
-rw-r--r-- | mesalib/src/glsl/glcpp/glcpp-parse.y | 20 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.cpp | 14 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.h | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/hir_field_selection.cpp | 60 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_reader.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/link_uniforms.cpp | 42 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 25 | ||||
-rw-r--r-- | mesalib/src/glsl/lower_named_interface_blocks.cpp | 3 |
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 89c1a565e..cdb8fc00d 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -292,6 +292,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 65c06903a..4ea00b000 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) { } |