diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/Makefile | 2 | ||||
-rw-r--r-- | src/glsl/SConscript | 9 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 31 | ||||
-rw-r--r-- | src/glsl/builtin_variables.h | 5 | ||||
-rwxr-xr-x | src/glsl/builtins/tools/texture_builtins.py | 57 | ||||
-rw-r--r-- | src/glsl/glsl_symbol_table.cpp | 1 | ||||
-rw-r--r-- | src/glsl/glsl_types.h | 2 | ||||
-rw-r--r-- | src/glsl/ir.cpp | 20 | ||||
-rw-r--r-- | src/glsl/ir.h | 24 | ||||
-rw-r--r-- | src/glsl/ir_print_visitor.cpp | 3 | ||||
-rw-r--r-- | src/glsl/ir_reader.cpp | 17 | ||||
-rw-r--r-- | src/glsl/ir_validate.cpp | 33 | ||||
-rw-r--r-- | src/glsl/link_functions.cpp | 8 | ||||
-rw-r--r-- | src/glsl/opt_dead_functions.cpp | 223 | ||||
-rw-r--r-- | src/glsl/opt_discard_simplification.cpp | 10 | ||||
-rw-r--r-- | src/glsl/opt_function_inlining.cpp | 7 | ||||
-rw-r--r-- | src/glsl/opt_if_simplification.cpp | 10 | ||||
-rw-r--r-- | src/glsl/opt_redundant_jumps.cpp | 9 | ||||
-rw-r--r-- | src/glsl/opt_structure_splitting.cpp | 6 |
19 files changed, 317 insertions, 160 deletions
diff --git a/src/glsl/Makefile b/src/glsl/Makefile index cd7c41a2abc..e4b992dbc11 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -204,7 +204,7 @@ glcpp/glcpp-parse.c: glcpp/glcpp-parse.y bison -v -o "$@" --defines=glcpp/glcpp-parse.h $< builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o - $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@ + $(APP_CXX) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@ builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler @echo Regenerating builtin_function.cpp... diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 9ecc155c9c9..c3255835fb4 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -105,11 +105,16 @@ if env['msvc']: if env['crosscompile'] and env['platform'] != 'embedded': Import('builtin_glsl_function') else: + # Copy these files to avoid generation object files into src/mesa/program + env.Prepend(CPPPATH = ['#src/mesa/program']) + env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE')) + env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE')) + main_obj = env.StaticObject('main.cpp') mesa_objs = env.StaticObject([ - '#src/mesa/program/hash_table.c', - '#src/mesa/program/symbol_table.c', + 'hash_table.c', + 'symbol_table.c', ]) builtin_compiler = env.Program( diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 651fae808e6..cdb16fd492b 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -603,7 +603,8 @@ shift_result_type(const struct glsl_type *type_a, */ ir_rvalue * validate_assignment(struct _mesa_glsl_parse_state *state, - const glsl_type *lhs_type, ir_rvalue *rhs) + const glsl_type *lhs_type, ir_rvalue *rhs, + bool is_initializer) { /* If there is already some error in the RHS, just return it. Anything * else will lead to an avalanche of error message back to the user. @@ -617,12 +618,13 @@ validate_assignment(struct _mesa_glsl_parse_state *state, return rhs; /* If the array element types are the same and the size of the LHS is zero, - * the assignment is okay. + * the assignment is okay for initializers embedded in variable + * declarations. * * Note: Whole-array assignments are not permitted in GLSL 1.10, but this * is handled by ir_dereference::is_lvalue. */ - if (lhs_type->is_array() && rhs->type->is_array() + if (is_initializer && lhs_type->is_array() && rhs->type->is_array() && (lhs_type->element_type() == rhs->type->element_type()) && (lhs_type->array_size() == 0)) { return rhs; @@ -639,7 +641,7 @@ validate_assignment(struct _mesa_glsl_parse_state *state, ir_rvalue * do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, - ir_rvalue *lhs, ir_rvalue *rhs, + ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer, YYLTYPE lhs_loc) { void *ctx = state; @@ -665,7 +667,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, } } - ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs); + ir_rvalue *new_rhs = + validate_assignment(state, lhs->type, rhs, is_initializer); if (new_rhs == NULL) { _mesa_glsl_error(& lhs_loc, state, "type mismatch"); } else { @@ -918,7 +921,7 @@ ast_expression::hir(exec_list *instructions, op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); - result = do_assignment(instructions, state, op[0], op[1], + result = do_assignment(instructions, state, op[0], op[1], false, this->subexpressions[0]->get_location()); error_emitted = result->type->is_error(); type = result->type; @@ -1245,7 +1248,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(ctx, NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, false, this->subexpressions[0]->get_location()); type = result->type; error_emitted = (op[0]->type->is_error()); @@ -1271,7 +1274,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(ctx, NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, false, this->subexpressions[0]->get_location()); type = result->type; error_emitted = type->is_error(); @@ -1287,7 +1290,7 @@ ast_expression::hir(exec_list *instructions, ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); result = do_assignment(instructions, state, op[0]->clone(ctx, NULL), - temp_rhs, + temp_rhs, false, this->subexpressions[0]->get_location()); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); break; @@ -1303,7 +1306,7 @@ ast_expression::hir(exec_list *instructions, ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); result = do_assignment(instructions, state, op[0]->clone(ctx, NULL), - temp_rhs, + temp_rhs, false, this->subexpressions[0]->get_location()); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); break; @@ -1419,7 +1422,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(ctx, NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, false, this->subexpressions[0]->get_location()); type = result->type; error_emitted = op[0]->type->is_error(); @@ -1448,7 +1451,7 @@ ast_expression::hir(exec_list *instructions, result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL)); (void)do_assignment(instructions, state, - op[0]->clone(ctx, NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, false, this->subexpressions[0]->get_location()); type = result->type; @@ -2234,7 +2237,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, */ if (type->qualifier.flags.q.constant || type->qualifier.flags.q.uniform) { - ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); + ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs, true); if (new_rhs != NULL) { rhs = new_rhs; @@ -2276,7 +2279,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, const glsl_type *initializer_type; if (!type->qualifier.flags.q.uniform) { result = do_assignment(initializer_instructions, state, - lhs, rhs, + lhs, rhs, true, type->get_location()); initializer_type = result->type; } else diff --git a/src/glsl/builtin_variables.h b/src/glsl/builtin_variables.h index a34c67e3481..9b4f5d9e3ec 100644 --- a/src/glsl/builtin_variables.h +++ b/src/glsl/builtin_variables.h @@ -101,5 +101,10 @@ static const builtin_variable builtin_110_deprecated_uniforms[] = { { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" }, { ir_var_uniform, -1, "float", "gl_NormalScale" }, { ir_var_uniform, -1, "gl_LightModelParameters", "gl_LightModel"}, + + /* Mesa-internal ATI_envmap_bumpmap state. */ + { ir_var_uniform, -1, "vec2", "gl_MESABumpRotMatrix0"}, + { ir_var_uniform, -1, "vec2", "gl_MESABumpRotMatrix1"}, + { ir_var_uniform, -1, "vec4", "gl_MESAFogParamsOptimized"}, }; diff --git a/src/glsl/builtins/tools/texture_builtins.py b/src/glsl/builtins/tools/texture_builtins.py index 8017e943b1b..2fbe79010f9 100755 --- a/src/glsl/builtins/tools/texture_builtins.py +++ b/src/glsl/builtins/tools/texture_builtins.py @@ -6,6 +6,7 @@ import StringIO # Bitfield constants for the 'variant' argument to generate_sigs Proj = 1 Offset = 2 +Single = 4 def vec_type(g, size): if size == 1: @@ -48,8 +49,13 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0): extra_dim = get_extra_dim(sampler_type, variant & Proj, unused_fields) offset_dim = get_sampler_dim(sampler_type) + if variant & Single: + return_type = "float" + else: + return_type = g + "vec4" + # Print parameters - print " (signature " + g + "vec4" + print " (signature", return_type print " (parameters" print " (declare (in) " + g + "sampler" + sampler_type + " sampler)" print " (declare (in) " + vec_type("i" if tex_inst == "txf" else "", coord_dim + extra_dim) + " P)", @@ -67,7 +73,7 @@ def generate_sigs(g, tex_inst, sampler_type, variant = 0, unused_fields = 0): if tex_inst == "txb": print "\n (declare (in) float bias)", - print ")\n ((return (" + tex_inst + " (var_ref sampler)", + print ")\n ((return (" + tex_inst, return_type, "(var_ref sampler)", # Coordinate if extra_dim > 0: @@ -131,6 +137,11 @@ def generate_texture_functions(fs): generate_fiu_sigs("tex", "Cube") generate_fiu_sigs("tex", "1DArray") generate_fiu_sigs("tex", "2DArray") + generate_sigs("", "tex", "1DShadow", Single, 1); + generate_sigs("", "tex", "2DShadow", Single); + generate_sigs("", "tex", "CubeShadow", Single); + generate_sigs("", "tex", "1DArrayShadow", Single); + generate_sigs("", "tex", "2DArrayShadow", Single); generate_fiu_sigs("txb", "1D") generate_fiu_sigs("txb", "2D") @@ -138,6 +149,11 @@ def generate_texture_functions(fs): generate_fiu_sigs("txb", "Cube") generate_fiu_sigs("txb", "1DArray") generate_fiu_sigs("txb", "2DArray") + generate_sigs("", "txb", "1DShadow", Single, 1); + generate_sigs("", "txb", "2DShadow", Single); + generate_sigs("", "txb", "CubeShadow", Single); + generate_sigs("", "txb", "1DArrayShadow", Single); + generate_sigs("", "txb", "2DArrayShadow", Single); end_function(fs, "texture") start_function("textureProj") @@ -146,12 +162,16 @@ def generate_texture_functions(fs): generate_fiu_sigs("tex", "2D", Proj) generate_fiu_sigs("tex", "2D", Proj, 1) generate_fiu_sigs("tex", "3D", Proj) + generate_sigs("", "tex", "1DShadow", Proj | Single, 1); + generate_sigs("", "tex", "2DShadow", Proj | Single); generate_fiu_sigs("txb", "1D", Proj) generate_fiu_sigs("txb", "1D", Proj, 2) generate_fiu_sigs("txb", "2D", Proj) generate_fiu_sigs("txb", "2D", Proj, 1) generate_fiu_sigs("txb", "3D", Proj) + generate_sigs("", "txb", "1DShadow", Proj | Single, 1); + generate_sigs("", "txb", "2DShadow", Proj | Single); end_function(fs, "textureProj") start_function("textureLod") @@ -161,6 +181,9 @@ def generate_texture_functions(fs): generate_fiu_sigs("txl", "Cube") generate_fiu_sigs("txl", "1DArray") generate_fiu_sigs("txl", "2DArray") + generate_sigs("", "txl", "1DShadow", Single, 1); + generate_sigs("", "txl", "2DShadow", Single); + generate_sigs("", "txl", "1DArrayShadow", Single); end_function(fs, "textureLod") start_function("textureLodOffset") @@ -169,6 +192,9 @@ def generate_texture_functions(fs): generate_fiu_sigs("txl", "3D", Offset) generate_fiu_sigs("txl", "1DArray", Offset) generate_fiu_sigs("txl", "2DArray", Offset) + generate_sigs("", "txl", "1DShadow", Offset | Single, 1); + generate_sigs("", "txl", "2DShadow", Offset | Single); + generate_sigs("", "txl", "1DArrayShadow", Offset | Single); end_function(fs, "textureLodOffset") start_function("textureOffset") @@ -177,12 +203,18 @@ def generate_texture_functions(fs): generate_fiu_sigs("tex", "3D", Offset) generate_fiu_sigs("tex", "1DArray", Offset) generate_fiu_sigs("tex", "2DArray", Offset) + generate_sigs("", "tex", "1DShadow", Offset | Single, 1); + generate_sigs("", "tex", "2DShadow", Offset | Single); + generate_sigs("", "tex", "1DArrayShadow", Offset | Single); generate_fiu_sigs("txb", "1D", Offset) generate_fiu_sigs("txb", "2D", Offset) generate_fiu_sigs("txb", "3D", Offset) generate_fiu_sigs("txb", "1DArray", Offset) generate_fiu_sigs("txb", "2DArray", Offset) + generate_sigs("", "txb", "1DShadow", Offset | Single, 1); + generate_sigs("", "txb", "2DShadow", Offset | Single); + generate_sigs("", "txb", "1DArrayShadow", Offset | Single); end_function(fs, "textureOffset") start_function("texelFetch") @@ -207,12 +239,16 @@ def generate_texture_functions(fs): generate_fiu_sigs("tex", "2D", Proj | Offset) generate_fiu_sigs("tex", "2D", Proj | Offset, 1) generate_fiu_sigs("tex", "3D", Proj | Offset) + generate_sigs("", "tex", "1DShadow", Proj | Offset | Single, 1); + generate_sigs("", "tex", "2DShadow", Proj | Offset | Single); generate_fiu_sigs("txb", "1D", Proj | Offset) generate_fiu_sigs("txb", "1D", Proj | Offset, 2) generate_fiu_sigs("txb", "2D", Proj | Offset) generate_fiu_sigs("txb", "2D", Proj | Offset, 1) generate_fiu_sigs("txb", "3D", Proj | Offset) + generate_sigs("", "txb", "1DShadow", Proj | Offset | Single, 1); + generate_sigs("", "txb", "2DShadow", Proj | Offset | Single); end_function(fs, "textureProjOffset") start_function("textureProjLod") @@ -221,6 +257,8 @@ def generate_texture_functions(fs): generate_fiu_sigs("txl", "2D", Proj) generate_fiu_sigs("txl", "2D", Proj, 1) generate_fiu_sigs("txl", "3D", Proj) + generate_sigs("", "txl", "1DShadow", Proj | Single, 1); + generate_sigs("", "txl", "2DShadow", Proj | Single); end_function(fs, "textureProjLod") start_function("textureProjLodOffset") @@ -229,6 +267,8 @@ def generate_texture_functions(fs): generate_fiu_sigs("txl", "2D", Proj | Offset) generate_fiu_sigs("txl", "2D", Proj | Offset, 1) generate_fiu_sigs("txl", "3D", Proj | Offset) + generate_sigs("", "txl", "1DShadow", Proj | Offset | Single, 1); + generate_sigs("", "txl", "2DShadow", Proj | Offset | Single); end_function(fs, "textureProjLodOffset") start_function("textureGrad") @@ -238,6 +278,11 @@ def generate_texture_functions(fs): generate_fiu_sigs("txd", "Cube") generate_fiu_sigs("txd", "1DArray") generate_fiu_sigs("txd", "2DArray") + generate_sigs("", "txd", "1DShadow", Single, 1); + generate_sigs("", "txd", "2DShadow", Single); + generate_sigs("", "txd", "CubeShadow", Single); + generate_sigs("", "txd", "1DArrayShadow", Single); + generate_sigs("", "txd", "2DArrayShadow", Single); end_function(fs, "textureGrad") start_function("textureGradOffset") @@ -247,6 +292,10 @@ def generate_texture_functions(fs): generate_fiu_sigs("txd", "Cube", Offset) generate_fiu_sigs("txd", "1DArray", Offset) generate_fiu_sigs("txd", "2DArray", Offset) + generate_sigs("", "txd", "1DShadow", Offset | Single, 1); + generate_sigs("", "txd", "2DShadow", Offset | Single); + generate_sigs("", "txd", "1DArrayShadow", Offset | Single); + generate_sigs("", "txd", "2DArrayShadow", Offset | Single); end_function(fs, "textureGradOffset") start_function("textureProjGrad") @@ -255,6 +304,8 @@ def generate_texture_functions(fs): generate_fiu_sigs("txd", "2D", Proj) generate_fiu_sigs("txd", "2D", Proj, 1) generate_fiu_sigs("txd", "3D", Proj) + generate_sigs("", "txd", "1DShadow", Proj | Single, 1); + generate_sigs("", "txd", "2DShadow", Proj | Single); end_function(fs, "textureProjGrad") start_function("textureProjGradOffset") @@ -263,6 +314,8 @@ def generate_texture_functions(fs): generate_fiu_sigs("txd", "2D", Proj | Offset) generate_fiu_sigs("txd", "2D", Proj | Offset, 1) generate_fiu_sigs("txd", "3D", Proj | Offset) + generate_sigs("", "txd", "1DShadow", Proj | Offset | Single, 1); + generate_sigs("", "txd", "2DShadow", Proj | Offset | Single); end_function(fs, "textureProjGradOffset") diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp index 2f291d4f97f..bcb65d30182 100644 --- a/src/glsl/glsl_symbol_table.cpp +++ b/src/glsl/glsl_symbol_table.cpp @@ -137,6 +137,7 @@ void glsl_symbol_table::add_global_function(ir_function *f) symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry); assert(added == 0); + (void)added; } ir_variable *glsl_symbol_table::get_variable(const char *name) diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 3c2672c01a0..1b069df74fe 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -70,7 +70,7 @@ struct glsl_type { GLenum gl_type; glsl_base_type base_type; - unsigned sampler_dimensionality:3; + unsigned sampler_dimensionality:3; /**< \see glsl_sampler_dim */ unsigned sampler_shadow:1; unsigned sampler_array:1; unsigned sampler_type:2; /**< Type of data returned using this sampler. diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index fc356ba5275..a3623b31e5d 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1150,22 +1150,18 @@ ir_texture::get_opcode(const char *str) void -ir_texture::set_sampler(ir_dereference *sampler) +ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) { assert(sampler != NULL); + assert(type != NULL); this->sampler = sampler; + this->type = type; - switch (sampler->type->sampler_type) { - case GLSL_TYPE_FLOAT: - this->type = glsl_type::vec4_type; - break; - case GLSL_TYPE_INT: - this->type = glsl_type::ivec4_type; - break; - case GLSL_TYPE_UINT: - this->type = glsl_type::uvec4_type; - break; - } + assert(sampler->type->sampler_type == (int) type->base_type); + if (sampler->type->sampler_shadow) + assert(type->vector_elements == 4 || type->vector_elements == 1); + else + assert(type->vector_elements == 4); } diff --git a/src/glsl/ir.h b/src/glsl/ir.h index f2f902c0a77..39d4ebc7107 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1191,16 +1191,16 @@ enum ir_texture_opcode { * selected from \c ir_texture_opcodes. In the printed IR, these will * appear as: * - * Texel offset (0 or an expression) - * | Projection divisor - * | | Shadow comparitor - * | | | - * v v v - * (tex <sampler> <coordinate> 0 1 ( )) - * (txb <sampler> <coordinate> 0 1 ( ) <bias>) - * (txl <sampler> <coordinate> 0 1 ( ) <lod>) - * (txd <sampler> <coordinate> 0 1 ( ) (dPdx dPdy)) - * (txf <sampler> <coordinate> 0 <lod>) + * Texel offset (0 or an expression) + * | Projection divisor + * | | Shadow comparitor + * | | | + * v v v + * (tex <type> <sampler> <coordinate> 0 1 ( )) + * (txb <type> <sampler> <coordinate> 0 1 ( ) <bias>) + * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>) + * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy)) + * (txf <type> <sampler> <coordinate> 0 <lod>) */ class ir_texture : public ir_rvalue { public: @@ -1226,8 +1226,8 @@ public: */ const char *opcode_string(); - /** Set the sampler and infer the type. */ - void set_sampler(ir_dereference *sampler); + /** Set the sampler and type. */ + void set_sampler(ir_dereference *sampler, const glsl_type *type); /** * Do a reverse-lookup to translate a string into an ir_texture_opcode. diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index 82ccc722fa2..a84f8dfc8a1 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -187,6 +187,9 @@ void ir_print_visitor::visit(ir_texture *ir) { printf("(%s ", ir->opcode_string()); + print_type(ir->type); + printf(" "); + ir->sampler->accept(this); printf(" "); diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index af85e06ae0e..30df257be2f 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -869,6 +869,7 @@ ir_texture * ir_reader::read_texture(s_expression *expr) { s_symbol *tag = NULL; + s_expression *s_type = NULL; s_expression *s_sampler = NULL; s_expression *s_coord = NULL; s_expression *s_offset = NULL; @@ -879,11 +880,11 @@ ir_reader::read_texture(s_expression *expr) ir_texture_opcode op = ir_tex; /* silence warning */ s_pattern tex_pattern[] = - { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow }; + { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; s_pattern txf_pattern[] = - { "txf", s_sampler, s_coord, s_offset, s_lod }; + { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; s_pattern other_pattern[] = - { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; + { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; if (MATCH(expr, tex_pattern)) { op = ir_tex; @@ -900,6 +901,14 @@ ir_reader::read_texture(s_expression *expr) ir_texture *tex = new(mem_ctx) ir_texture(op); + // Read return type + const glsl_type *type = read_type(s_type); + if (type == NULL) { + ir_read_error(NULL, "when reading type in (%s ...)", + tex->opcode_string()); + return NULL; + } + // Read sampler (must be a deref) ir_dereference *sampler = read_dereference(s_sampler); if (sampler == NULL) { @@ -907,7 +916,7 @@ ir_reader::read_texture(s_expression *expr) tex->opcode_string()); return NULL; } - tex->set_sampler(sampler); + tex->set_sampler(sampler, type); // Read coordinate (any rvalue) tex->coordinate = read_rvalue(s_coord); diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 44d7549ea28..0fc3baf8690 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -70,6 +70,7 @@ public: virtual ir_visitor_status visit_leave(ir_swizzle *ir); virtual ir_visitor_status visit_enter(ir_assignment *ir); + virtual ir_visitor_status visit_enter(ir_call *ir); static void validate_ir(ir_instruction *ir, void *data); @@ -173,6 +174,19 @@ ir_validate::visit_enter(ir_function *ir) this->validate_ir(ir, this->data); + /* Verify that all of the things stored in the list of signatures are, + * in fact, function signatures. + */ + foreach_list(node, &ir->signatures) { + ir_instruction *sig = (ir_instruction *) node; + + if (sig->ir_type != ir_type_function_signature) { + printf("Non-signature in signature list of function `%s'\n", + ir->name); + abort(); + } + } + return visit_continue; } @@ -198,6 +212,12 @@ ir_validate::visit_enter(ir_function_signature *ir) abort(); } + if (ir->return_type == NULL) { + printf("Function signature %p for function %s has NULL return type.\n", + (void *) ir, ir->function_name()); + abort(); + } + this->validate_ir(ir, this->data); return visit_continue; @@ -488,6 +508,19 @@ ir_validate::visit_enter(ir_assignment *ir) return visit_continue; } +ir_visitor_status +ir_validate::visit_enter(ir_call *ir) +{ + ir_function_signature *const callee = ir->get_callee(); + + if (callee->ir_type != ir_type_function_signature) { + printf("IR called by ir_call is not ir_function_signature!\n"); + abort(); + } + + return visit_continue; +} + void ir_validate::validate_ir(ir_instruction *ir, void *data) { diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index 5851c14d624..ae8818be871 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -99,9 +99,15 @@ public: * details that may be missing. */ ir_function *f = linked->symbols->get_function(name); - if (f == NULL) + if (f == NULL) { f = new(linked) ir_function(name); + /* Add the new function to the linked IR. + */ + linked->symbols->add_function(f); + linked->ir->push_head(f); + } + ir_function_signature *linked_sig = f->exact_matching_signature(&callee->parameters); if (linked_sig == NULL) { diff --git a/src/glsl/opt_dead_functions.cpp b/src/glsl/opt_dead_functions.cpp index ceb79080a75..7c64c618c0c 100644 --- a/src/glsl/opt_dead_functions.cpp +++ b/src/glsl/opt_dead_functions.cpp @@ -1,109 +1,120 @@ - /* - * Copyright © 2010 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 opt_dead_functions.cpp - * - * Eliminates unused functions from the linked program. - */ - - #include "ir.h" - #include "ir_visitor.h" - #include "ir_expression_flattening.h" - #include "glsl_types.h" - - class signature_entry : public exec_node - { - public: - signature_entry(ir_function_signature *sig) - { - this->signature = sig; - this->used = false; - } - - ir_function_signature *signature; - bool used; - }; - - class ir_dead_functions_visitor : public ir_hierarchical_visitor { - public: - ir_dead_functions_visitor() - { - this->mem_ctx = ralloc_context(NULL); - } - - ~ir_dead_functions_visitor() - { - ralloc_free(this->mem_ctx); - } - - virtual ir_visitor_status visit_enter(ir_function_signature *); - virtual ir_visitor_status visit_enter(ir_call *); - - signature_entry *get_signature_entry(ir_function_signature *var); - - bool (*predicate)(ir_instruction *ir); - - /* List of signature_entry */ - exec_list signature_list; - void *mem_ctx; - }; - - - signature_entry * - ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) - { - foreach_iter(exec_list_iterator, iter, this->signature_list) { - signature_entry *entry = (signature_entry *)iter.get(); - if (entry->signature == sig) - return entry; - } - - signature_entry *entry = new(mem_ctx) signature_entry(sig); - this->signature_list.push_tail(entry); - return entry; - } - - - ir_visitor_status - ir_dead_functions_visitor::visit_enter(ir_function_signature *ir) - { - signature_entry *entry = this->get_signature_entry(ir); - - if (strcmp(ir->function_name(), "main") == 0) { - entry->used = true; - } - - return visit_continue; - } - - - ir_visitor_status - ir_dead_functions_visitor::visit_enter(ir_call *ir) - { - signature_entry *entry = this->get_signature_entry(ir->get_callee()); - - entry->used = true; +/* + * Copyright © 2010 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 opt_dead_functions.cpp + * + * Eliminates unused functions from the linked program. + */ + +#include "ir.h" +#include "ir_visitor.h" +#include "ir_expression_flattening.h" +#include "glsl_types.h" + +class signature_entry : public exec_node +{ +public: + signature_entry(ir_function_signature *sig) + { + this->signature = sig; + this->used = false; + } + + ir_function_signature *signature; + bool used; +}; + +class ir_dead_functions_visitor : public ir_hierarchical_visitor { +public: + ir_dead_functions_visitor() + { + this->mem_ctx = ralloc_context(NULL); + this->seen_another_function_signature = false; + } + + ~ir_dead_functions_visitor() + { + ralloc_free(this->mem_ctx); + } + + virtual ir_visitor_status visit_enter(ir_function_signature *); + virtual ir_visitor_status visit_enter(ir_call *); + + signature_entry *get_signature_entry(ir_function_signature *var); + + bool (*predicate)(ir_instruction *ir); + + bool seen_another_function_signature; + + /* List of signature_entry */ + exec_list signature_list; + void *mem_ctx; +}; + + +signature_entry * +ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) +{ + foreach_iter(exec_list_iterator, iter, this->signature_list) { + signature_entry *entry = (signature_entry *)iter.get(); + if (entry->signature == sig) + return entry; + } + + signature_entry *entry = new(mem_ctx) signature_entry(sig); + this->signature_list.push_tail(entry); + return entry; +} + + +ir_visitor_status +ir_dead_functions_visitor::visit_enter(ir_function_signature *ir) +{ + signature_entry *entry = this->get_signature_entry(ir); + + if (strcmp(ir->function_name(), "main") == 0) { + entry->used = true; + } + + /* If this is the first signature to look at, no need to descend to see + * if it has calls to another function signature. + */ + if (!this->seen_another_function_signature) { + this->seen_another_function_signature = true; + return visit_continue_with_parent; + } + + return visit_continue; +} + + +ir_visitor_status +ir_dead_functions_visitor::visit_enter(ir_call *ir) +{ + signature_entry *entry = this->get_signature_entry(ir->get_callee()); + + entry->used = true; return visit_continue; } diff --git a/src/glsl/opt_discard_simplification.cpp b/src/glsl/opt_discard_simplification.cpp index 0e577c478a9..7c2928d271c 100644 --- a/src/glsl/opt_discard_simplification.cpp +++ b/src/glsl/opt_discard_simplification.cpp @@ -95,6 +95,7 @@ public: ir_visitor_status visit_enter(ir_if *); ir_visitor_status visit_enter(ir_loop *); + ir_visitor_status visit_enter(ir_assignment *); bool progress; }; @@ -117,6 +118,15 @@ is_only_instruction(ir_discard *discard) discard->next->is_tail_sentinel()); } +/* We only care about the top level instructions, so don't descend + * into expressions. + */ +ir_visitor_status +discard_simplifier::visit_enter(ir_assignment *ir) +{ + return visit_continue_with_parent; +} + ir_visitor_status discard_simplifier::visit_enter(ir_if *ir) { diff --git a/src/glsl/opt_function_inlining.cpp b/src/glsl/opt_function_inlining.cpp index 2e7831dcbdb..8fef358cc97 100644 --- a/src/glsl/opt_function_inlining.cpp +++ b/src/glsl/opt_function_inlining.cpp @@ -126,7 +126,7 @@ ir_call::generate_inline(ir_instruction *next_ir) parameters = new ir_variable *[num_parameters]; /* Generate storage for the return value. */ - if (this->callee->return_type) { + if (!this->callee->return_type->is_void()) { retval = new(ctx) ir_variable(this->callee->return_type, "_ret_val", ir_var_auto); next_ir->insert_before(retval); @@ -209,10 +209,7 @@ ir_call::generate_inline(ir_instruction *next_ir) } /* Now push those new instructions in. */ - foreach_iter(exec_list_iterator, iter, new_instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - next_ir->insert_before(ir); - } + next_ir->insert_before(&new_instructions); /* Copy back the value of any 'out' parameters from the function body * variables to our own. diff --git a/src/glsl/opt_if_simplification.cpp b/src/glsl/opt_if_simplification.cpp index 618bacfecf1..29b1d18aa59 100644 --- a/src/glsl/opt_if_simplification.cpp +++ b/src/glsl/opt_if_simplification.cpp @@ -38,10 +38,20 @@ public: } ir_visitor_status visit_leave(ir_if *); + ir_visitor_status visit_enter(ir_assignment *); bool made_progress; }; +/* We only care about the top level "if" instructions, so don't + * descend into expressions. + */ +ir_visitor_status +ir_if_simplification_visitor::visit_enter(ir_assignment *ir) +{ + return visit_continue_with_parent; +} + bool do_if_simplification(exec_list *instructions) { diff --git a/src/glsl/opt_redundant_jumps.cpp b/src/glsl/opt_redundant_jumps.cpp index edf4bb6c224..f350fa947c9 100644 --- a/src/glsl/opt_redundant_jumps.cpp +++ b/src/glsl/opt_redundant_jumps.cpp @@ -37,10 +37,19 @@ public: virtual ir_visitor_status visit_leave(ir_if *); virtual ir_visitor_status visit_leave(ir_loop *); + virtual ir_visitor_status visit_enter(ir_assignment *); bool progress; }; +/* We only care about the top level instructions, so don't descend + * into expressions. + */ +ir_visitor_status +redundant_jumps_visitor::visit_enter(ir_assignment *ir) +{ + return visit_continue_with_parent; +} ir_visitor_status redundant_jumps_visitor::visit_leave(ir_if *ir) diff --git a/src/glsl/opt_structure_splitting.cpp b/src/glsl/opt_structure_splitting.cpp index 014407c0be2..2c1f6bb227a 100644 --- a/src/glsl/opt_structure_splitting.cpp +++ b/src/glsl/opt_structure_splitting.cpp @@ -151,6 +151,12 @@ ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir) ir_visitor_status ir_structure_reference_visitor::visit_enter(ir_assignment *ir) { + /* If there are no structure references yet, no need to bother with + * processing the expression tree. + */ + if (this->variable_list.is_empty()) + return visit_continue_with_parent; + if (ir->lhs->as_dereference_variable() && ir->rhs->as_dereference_variable() && !ir->condition) { |