diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/Makefile.sources | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 77 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_optimization.h | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 25 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.h | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/loop_analysis.h | 9 | ||||
-rw-r--r-- | mesalib/src/glsl/lower_vertex_id.cpp | 144 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_constant_folding.cpp | 5 |
8 files changed, 217 insertions, 49 deletions
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index 2131ddafb..cb8d5a6f7 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -76,6 +76,7 @@ LIBGLSL_FILES = \ $(GLSL_SRCDIR)/lower_vec_index_to_swizzle.cpp \ $(GLSL_SRCDIR)/lower_vector.cpp \ $(GLSL_SRCDIR)/lower_vector_insert.cpp \ + $(GLSL_SRCDIR)/lower_vertex_id.cpp \ $(GLSL_SRCDIR)/lower_output_reads.cpp \ $(GLSL_SRCDIR)/lower_ubo_reference.cpp \ $(GLSL_SRCDIR)/opt_algebraic.cpp \ diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 897505c60..5ec1614be 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -3202,6 +3202,41 @@ validate_identifier(const char *identifier, YYLTYPE loc, } } +static bool +precision_qualifier_allowed(const glsl_type *type) +{ + /* Precision qualifiers apply to floating point, integer and sampler + * types. + * + * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says: + * "Any floating point or any integer declaration can have the type + * preceded by one of these precision qualifiers [...] Literal + * constants do not have precision qualifiers. Neither do Boolean + * variables. + * + * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30 + * spec also says: + * + * "Precision qualifiers are added for code portability with OpenGL + * ES, not for functionality. They have the same syntax as in OpenGL + * ES." + * + * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says: + * + * "uniform lowp sampler2D sampler; + * highp vec2 coord; + * ... + * lowp vec4 col = texture2D (sampler, coord); + * // texture2D returns lowp" + * + * From this, we infer that GLSL 1.30 (and later) should allow precision + * qualifiers on sampler types just like float and integer types. + */ + return type->is_float() + || type->is_integer() + || type->is_record() + || type->is_sampler(); +} ir_rvalue * ast_declarator_list::hir(exec_list *instructions, @@ -3689,41 +3724,13 @@ ast_declarator_list::hir(exec_list *instructions, } - /* Precision qualifiers apply to floating point, integer and sampler - * types. - * - * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says: - * "Any floating point or any integer declaration can have the type - * preceded by one of these precision qualifiers [...] Literal - * constants do not have precision qualifiers. Neither do Boolean - * variables. - * - * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30 - * spec also says: - * - * "Precision qualifiers are added for code portability with OpenGL - * ES, not for functionality. They have the same syntax as in OpenGL - * ES." - * - * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says: - * - * "uniform lowp sampler2D sampler; - * highp vec2 coord; - * ... - * lowp vec4 col = texture2D (sampler, coord); - * // texture2D returns lowp" - * - * From this, we infer that GLSL 1.30 (and later) should allow precision - * qualifiers on sampler types just like float and integer types. + /* If a precision qualifier is allowed on a type, it is allowed on + * an array of that type. */ - if (this->type->qualifier.precision != ast_precision_none - && !var->type->is_float() - && !var->type->is_integer() - && !var->type->is_record() - && !var->type->is_sampler() - && !(var->type->is_array() - && (var->type->fields.array->is_float() - || var->type->fields.array->is_integer()))) { + if (!(this->type->qualifier.precision == ast_precision_none + || precision_qualifier_allowed(var->type) + || (var->type->is_array() + && precision_qualifier_allowed(var->type->fields.array)))) { _mesa_glsl_error(&loc, state, "precision qualifiers apply only to floating point" @@ -5455,7 +5462,7 @@ ast_interface_block::hir(exec_list *instructions, } if (this->instance_name != NULL) { _mesa_glsl_error(&loc, state, - "gl_PerVertex input may not be redeclared with " + "gl_PerVertex output may not be redeclared with " "an instance name"); } break; diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 1c6f72b54..369dcd15b 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -126,6 +126,8 @@ bool optimize_redundant_jumps(exec_list *instructions); bool optimize_split_arrays(exec_list *instructions, bool linked); bool lower_offset_arrays(exec_list *instructions); +bool lower_vertex_id(gl_shader *shader); + ir_rvalue * compare_index_block(exec_list *instructions, ir_variable *index, unsigned base, unsigned components, void *mem_ctx); diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 57be4931d..7689198b0 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -559,14 +559,21 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, * vertex processing has occurred. Its value is undefined if * the vertex shader executable does not write gl_Position." * - * GLSL ES 3.00 is similar to GLSL 1.40--failing to write to gl_Position is - * not an error. + * All GLSL ES Versions are similar to GLSL 1.40--failing to write to + * gl_Position is not an error. */ if (prog->Version < (prog->IsES ? 300 : 140)) { find_assignment_visitor find("gl_Position"); find.run(shader->ir); if (!find.variable_found()) { - linker_error(prog, "vertex shader does not write to `gl_Position'\n"); + if (prog->IsES) { + linker_warning(prog, + "vertex shader does not write to `gl_Position'." + "It's value is undefined. \n"); + } else { + linker_error(prog, + "vertex shader does not write to `gl_Position'. \n"); + } return; } } @@ -1115,8 +1122,8 @@ move_non_declarations(exec_list *instructions, exec_node *last, /** * Get the function signature for main from a shader */ -static ir_function_signature * -get_main_function_signature(gl_shader *sh) +ir_function_signature * +link_get_main_function_signature(gl_shader *sh) { ir_function *const f = sh->symbols->get_function("main"); if (f != NULL) { @@ -1644,7 +1651,7 @@ link_intrastage_shaders(void *mem_ctx, */ gl_shader *main = NULL; for (unsigned i = 0; i < num_shaders; i++) { - if (get_main_function_signature(shader_list[i]) != NULL) { + if (link_get_main_function_signature(shader_list[i]) != NULL) { main = shader_list[i]; break; } @@ -1673,7 +1680,8 @@ link_intrastage_shaders(void *mem_ctx, /* The a pointer to the main function in the final linked shader (i.e., the * copy of the original shader that contained the main function). */ - ir_function_signature *const main_sig = get_main_function_signature(linked); + ir_function_signature *const main_sig = + link_get_main_function_signature(linked); /* Move any instructions other than variable declarations or function * declarations into main. @@ -1736,6 +1744,9 @@ link_intrastage_shaders(void *mem_ctx, } } + if (ctx->Const.VertexID_is_zero_based) + lower_vertex_id(linked); + /* Make a pass over all variable declarations to ensure that arrays with * unspecified sizes have a size specified. The size is inferred from the * max_array_access field. diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h index beb9bb216..9440794e2 100644 --- a/mesalib/src/glsl/linker.h +++ b/mesalib/src/glsl/linker.h @@ -26,6 +26,9 @@ #ifndef GLSL_LINKER_H #define GLSL_LINKER_H +ir_function_signature * +link_get_main_function_signature(gl_shader *sh); + extern bool link_function_calls(gl_shader_program *prog, gl_shader *main, gl_shader **shader_list, unsigned num_shaders); diff --git a/mesalib/src/glsl/loop_analysis.h b/mesalib/src/glsl/loop_analysis.h index 295dc797c..31be4f3cf 100644 --- a/mesalib/src/glsl/loop_analysis.h +++ b/mesalib/src/glsl/loop_analysis.h @@ -205,10 +205,10 @@ public: inline bool is_loop_constant() const { const bool is_const = (this->num_assignments == 0) - || ((this->num_assignments == 1) + || (((this->num_assignments == 1) && !this->conditional_or_nested_assignment && !this->read_before_write - && this->rhs_clean); + && this->rhs_clean) || this->var->data.read_only); /* If the RHS of *the* assignment is clean, then there must be exactly * one assignment of the variable. @@ -216,11 +216,6 @@ public: assert((this->rhs_clean && (this->num_assignments == 1)) || !this->rhs_clean); - /* Variables that are marked read-only *MUST* be loop constant. - */ - assert(!this->var->data.read_only - || (this->var->data.read_only && is_const)); - return is_const; } diff --git a/mesalib/src/glsl/lower_vertex_id.cpp b/mesalib/src/glsl/lower_vertex_id.cpp new file mode 100644 index 000000000..fc90bc8e6 --- /dev/null +++ b/mesalib/src/glsl/lower_vertex_id.cpp @@ -0,0 +1,144 @@ +/* + * Copyright © 2014 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. + */ + +/** + * \file lower_vertex_id.cpp + * + * There exists hardware, such as i965, that does not implement the OpenGL + * semantic for gl_VertexID. Instead, that hardware does not include the + * value of basevertex in the gl_VertexID value. To implement the OpenGL + * semantic, we'll have to convert gl_Vertex_ID to + * gl_VertexIDMESA+gl_BaseVertexMESA. + */ + +#include "glsl_symbol_table.h" +#include "ir_hierarchical_visitor.h" +#include "ir.h" +#include "ir_builder.h" +#include "linker.h" +#include "program/prog_statevars.h" + +namespace { + +class lower_vertex_id_visitor : public ir_hierarchical_visitor { +public: + explicit lower_vertex_id_visitor(ir_function_signature *main_sig, + exec_list *ir_list) + : progress(false), VertexID(NULL), gl_VertexID(NULL), + gl_BaseVertex(NULL), main_sig(main_sig), ir_list(ir_list) + { + foreach_in_list(ir_instruction, ir, ir_list) { + ir_variable *const var = ir->as_variable(); + + if (var != NULL && var->data.mode == ir_var_system_value && + var->data.location == SYSTEM_VALUE_BASE_VERTEX) { + gl_BaseVertex = var; + break; + } + } + } + + virtual ir_visitor_status visit(ir_dereference_variable *); + + bool progress; + +private: + ir_variable *VertexID; + ir_variable *gl_VertexID; + ir_variable *gl_BaseVertex; + + ir_function_signature *main_sig; + exec_list *ir_list; +}; + +} /* anonymous namespace */ + +ir_visitor_status +lower_vertex_id_visitor::visit(ir_dereference_variable *ir) +{ + if (ir->var->data.mode != ir_var_system_value || + ir->var->data.location != SYSTEM_VALUE_VERTEX_ID) + return visit_continue; + + if (VertexID == NULL) { + const glsl_type *const int_t = glsl_type::int_type; + void *const mem_ctx = ralloc_parent(ir); + + VertexID = new(mem_ctx) ir_variable(int_t, "__VertexID", + ir_var_temporary); + ir_list->push_head(VertexID); + + gl_VertexID = new(mem_ctx) ir_variable(int_t, "gl_VertexIDMESA", + ir_var_system_value); + gl_VertexID->data.how_declared = ir_var_declared_implicitly; + gl_VertexID->data.read_only = true; + gl_VertexID->data.location = SYSTEM_VALUE_VERTEX_ID_ZERO_BASE; + gl_VertexID->data.explicit_location = true; + gl_VertexID->data.explicit_index = 0; + ir_list->push_head(gl_VertexID); + + if (gl_BaseVertex == NULL) { + gl_BaseVertex = new(mem_ctx) ir_variable(int_t, "gl_BaseVertex", + ir_var_system_value); + gl_BaseVertex->data.how_declared = ir_var_declared_implicitly; + gl_BaseVertex->data.read_only = true; + gl_BaseVertex->data.location = SYSTEM_VALUE_BASE_VERTEX; + gl_BaseVertex->data.explicit_location = true; + gl_BaseVertex->data.explicit_index = 0; + ir_list->push_head(gl_BaseVertex); + } + + ir_instruction *const inst = + ir_builder::assign(VertexID, + ir_builder::add(gl_VertexID, gl_BaseVertex)); + + main_sig->body.push_head(inst); + } + + ir->var = VertexID; + progress = true; + + return visit_continue; +} + +bool +lower_vertex_id(gl_shader *shader) +{ + /* gl_VertexID only exists in the vertex shader. + */ + if (shader->Stage != MESA_SHADER_VERTEX) + return false; + + ir_function_signature *const main_sig = + link_get_main_function_signature(shader); + if (main_sig == NULL) { + assert(main_sig != NULL); + return false; + } + + lower_vertex_id_visitor v(main_sig, shader->ir); + + v.run(shader->ir); + + return v.progress; +} diff --git a/mesalib/src/glsl/opt_constant_folding.cpp b/mesalib/src/glsl/opt_constant_folding.cpp index d0e575460..74b855e5e 100644 --- a/mesalib/src/glsl/opt_constant_folding.cpp +++ b/mesalib/src/glsl/opt_constant_folding.cpp @@ -79,6 +79,11 @@ ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue) } } + /* Ditto for swizzles. */ + ir_swizzle *swiz = (*rvalue)->as_swizzle(); + if (swiz && !swiz->val->as_constant()) + return; + ir_constant *constant = (*rvalue)->constant_expression_value(); if (constant) { *rvalue = constant; |