aboutsummaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/Makefile2
-rw-r--r--src/glsl/SConscript9
-rw-r--r--src/glsl/ast_to_hir.cpp31
-rw-r--r--src/glsl/builtin_variables.h5
-rwxr-xr-xsrc/glsl/builtins/tools/texture_builtins.py57
-rw-r--r--src/glsl/glsl_symbol_table.cpp1
-rw-r--r--src/glsl/glsl_types.h2
-rw-r--r--src/glsl/ir.cpp20
-rw-r--r--src/glsl/ir.h24
-rw-r--r--src/glsl/ir_print_visitor.cpp3
-rw-r--r--src/glsl/ir_reader.cpp17
-rw-r--r--src/glsl/ir_validate.cpp33
-rw-r--r--src/glsl/link_functions.cpp8
-rw-r--r--src/glsl/opt_dead_functions.cpp223
-rw-r--r--src/glsl/opt_discard_simplification.cpp10
-rw-r--r--src/glsl/opt_function_inlining.cpp7
-rw-r--r--src/glsl/opt_if_simplification.cpp10
-rw-r--r--src/glsl/opt_redundant_jumps.cpp9
-rw-r--r--src/glsl/opt_structure_splitting.cpp6
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) {