diff options
Diffstat (limited to 'mesalib/src/glsl')
24 files changed, 581 insertions, 114 deletions
diff --git a/mesalib/src/glsl/.dir-locals.el b/mesalib/src/glsl/.dir-locals.el new file mode 100644 index 000000000..be19e29a5 --- /dev/null +++ b/mesalib/src/glsl/.dir-locals.el @@ -0,0 +1,3 @@ +((c-mode . ((c-basic-offset . 3))) + (c++-mode . ((c-basic-offset . 3))) +) diff --git a/mesalib/src/glsl/Android.gen.mk b/mesalib/src/glsl/Android.gen.mk new file mode 100644 index 000000000..e4ccb7291 --- /dev/null +++ b/mesalib/src/glsl/Android.gen.mk @@ -0,0 +1,98 @@ +# Mesa 3-D graphics library +# +# Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com> +# Copyright (C) 2010-2011 LunarG Inc. +# +# 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 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. + +# included by glsl Android.mk for source generation + +ifeq ($(LOCAL_MODULE_CLASS),) +LOCAL_MODULE_CLASS := STATIC_LIBRARIES +endif + +intermediates := $(call local-intermediates-dir) + +sources := \ + glsl_lexer.cpp \ + glsl_parser.cpp \ + glcpp/glcpp-lex.c \ + glcpp/glcpp-parse.c + +ifneq ($(LOCAL_IS_HOST_MODULE),true) +sources += builtin_function.cpp +endif + +LOCAL_SRC_FILES := $(filter-out $(sources), $(LOCAL_SRC_FILES)) + +LOCAL_C_INCLUDES += $(intermediates) $(intermediates)/glcpp $(MESA_TOP)/src/glsl/glcpp + +sources := $(addprefix $(intermediates)/, $(sources)) +LOCAL_GENERATED_SOURCES += $(sources) + +define local-l-or-ll-to-c-or-cpp + @mkdir -p $(dir $@) + @echo "Mesa Lex: $(PRIVATE_MODULE) <= $<" + $(hide) $(LEX) --nounistd -o$@ $< +endef + +define local-y-to-c-and-h + @mkdir -p $(dir $@) + @echo "Mesa Yacc: $(PRIVATE_MODULE) <= $<" + $(hide) $(YACC) -o $@ $< +endef + +define local-yy-to-cpp-and-h + @mkdir -p $(dir $@) + @echo "Mesa Yacc: $(PRIVATE_MODULE) <= $<" + $(hide) $(YACC) -p "_mesa_glsl_" -o $@ $< + touch $(@:$1=$(YACC_HEADER_SUFFIX)) + echo '#ifndef '$(@F:$1=_h) > $(@:$1=.h) + echo '#define '$(@F:$1=_h) >> $(@:$1=.h) + cat $(@:$1=$(YACC_HEADER_SUFFIX)) >> $(@:$1=.h) + echo '#endif' >> $(@:$1=.h) + rm -f $(@:$1=$(YACC_HEADER_SUFFIX)) +endef + +$(intermediates)/glsl_lexer.cpp: $(LOCAL_PATH)/glsl_lexer.ll + $(call local-l-or-ll-to-c-or-cpp) + +$(intermediates)/glsl_parser.cpp: $(LOCAL_PATH)/glsl_parser.yy + $(call local-yy-to-cpp-and-h,.cpp) + +$(intermediates)/glcpp/glcpp-lex.c: $(LOCAL_PATH)/glcpp/glcpp-lex.l + $(call local-l-or-ll-to-c-or-cpp) + +$(intermediates)/glcpp/glcpp-parse.c: $(LOCAL_PATH)/glcpp/glcpp-parse.y + $(call local-y-to-c-and-h) + +BUILTIN_COMPILER := $(BUILD_OUT_EXECUTABLES)/mesa_builtin_compiler$(BUILD_EXECUTABLE_SUFFIX) + +builtin_function_deps := \ + $(LOCAL_PATH)/builtins/tools/generate_builtins.py \ + $(LOCAL_PATH)/builtins/tools/texture_builtins.py \ + $(BUILTIN_COMPILER) \ + $(wildcard $(LOCAL_PATH)/builtins/profiles/*) \ + $(wildcard $(LOCAL_PATH)/builtins/ir/*) + +$(intermediates)/builtin_function.cpp: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/builtins/tools/generate_builtins.py +$(intermediates)/builtin_function.cpp: $(builtin_function_deps) + @mkdir -p $(dir $@) + @echo "Gen GLSL: $(PRIVATE_MODULE) <= $(notdir $@)" + $(hide) $(PRIVATE_SCRIPT) $(BUILTIN_COMPILER) > $@ || rm -f $@ diff --git a/mesalib/src/glsl/Android.mk b/mesalib/src/glsl/Android.mk new file mode 100644 index 000000000..d0b3ff3be --- /dev/null +++ b/mesalib/src/glsl/Android.mk @@ -0,0 +1,171 @@ +# Mesa 3-D graphics library +# +# Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com> +# Copyright (C) 2010-2011 LunarG Inc. +# +# 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 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. + +# Android.mk for glsl + +LOCAL_PATH := $(call my-dir) + +# from Makefile +LIBGLCPP_SOURCES = \ + glcpp/glcpp-lex.c \ + glcpp/glcpp-parse.c \ + glcpp/pp.c + +C_SOURCES = \ + strtod.c \ + ralloc.c \ + $(LIBGLCPP_SOURCES) + +CXX_SOURCES = \ + ast_expr.cpp \ + ast_function.cpp \ + ast_to_hir.cpp \ + ast_type.cpp \ + glsl_lexer.cpp \ + glsl_parser.cpp \ + glsl_parser_extras.cpp \ + glsl_types.cpp \ + glsl_symbol_table.cpp \ + hir_field_selection.cpp \ + ir_basic_block.cpp \ + ir_clone.cpp \ + ir_constant_expression.cpp \ + ir.cpp \ + ir_expression_flattening.cpp \ + ir_function_can_inline.cpp \ + ir_function_detect_recursion.cpp \ + ir_function.cpp \ + ir_hierarchical_visitor.cpp \ + ir_hv_accept.cpp \ + ir_import_prototypes.cpp \ + ir_print_visitor.cpp \ + ir_reader.cpp \ + ir_rvalue_visitor.cpp \ + ir_set_program_inouts.cpp \ + ir_validate.cpp \ + ir_variable.cpp \ + ir_variable_refcount.cpp \ + linker.cpp \ + link_functions.cpp \ + loop_analysis.cpp \ + loop_controls.cpp \ + loop_unroll.cpp \ + lower_discard.cpp \ + lower_if_to_cond_assign.cpp \ + lower_instructions.cpp \ + lower_jumps.cpp \ + lower_mat_op_to_vec.cpp \ + lower_noise.cpp \ + lower_texture_projection.cpp \ + lower_variable_index_to_cond_assign.cpp \ + lower_vec_index_to_cond_assign.cpp \ + lower_vec_index_to_swizzle.cpp \ + lower_vector.cpp \ + opt_algebraic.cpp \ + opt_constant_folding.cpp \ + opt_constant_propagation.cpp \ + opt_constant_variable.cpp \ + opt_copy_propagation.cpp \ + opt_copy_propagation_elements.cpp \ + opt_dead_code.cpp \ + opt_dead_code_local.cpp \ + opt_dead_functions.cpp \ + opt_discard_simplification.cpp \ + opt_function_inlining.cpp \ + opt_if_simplification.cpp \ + opt_noop_swizzle.cpp \ + opt_redundant_jumps.cpp \ + opt_structure_splitting.cpp \ + opt_swizzle_swizzle.cpp \ + opt_tree_grafting.cpp \ + s_expression.cpp + +# --------------------------------------- +# Build libmesa_glsl +# --------------------------------------- + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + $(C_SOURCES) \ + $(CXX_SOURCES) \ + builtin_function.cpp + +LOCAL_C_INCLUDES := \ + $(MESA_TOP)/src/mapi \ + $(MESA_TOP)/src/mesa + +LOCAL_MODULE := libmesa_glsl + +include $(LOCAL_PATH)/Android.gen.mk +include $(MESA_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) + +# --------------------------------------- +# Build mesa_builtin_compiler for host +# --------------------------------------- + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + $(C_SOURCES) \ + $(CXX_SOURCES) \ + builtin_stubs.cpp \ + main.cpp \ + standalone_scaffolding.cpp + +LOCAL_C_INCLUDES := \ + $(MESA_TOP)/src/mapi \ + $(MESA_TOP)/src/mesa + +LOCAL_STATIC_LIBRARIES := libmesa_glsl_utils + +LOCAL_MODULE := mesa_builtin_compiler + +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_IS_HOST_MODULE := true +include $(LOCAL_PATH)/Android.gen.mk +include $(MESA_COMMON_MK) +include $(BUILD_HOST_EXECUTABLE) + +# --------------------------------------- +# Build glsl_compiler +# --------------------------------------- + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + main.cpp \ + standalone_scaffolding.cpp + +LOCAL_C_INCLUDES := \ + $(MESA_TOP)/src/mapi \ + $(MESA_TOP)/src/mesa + +LOCAL_STATIC_LIBRARIES := libmesa_glsl libmesa_glsl_utils + +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE := glsl_compiler + +include $(MESA_COMMON_MK) +include $(BUILD_EXECUTABLE) diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index adb88706f..397164cde 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -134,6 +134,8 @@ match_function_by_name(exec_list *instructions, const char *name, }
}
+ exec_list post_call_conversions;
+
if (sig != NULL) {
/* Verify that 'out' and 'inout' actual parameters are lvalues. This
* isn't done in ir_function::matching_signature because that function
@@ -141,6 +143,12 @@ match_function_by_name(exec_list *instructions, const char *name, *
* Also, validate that 'const_in' formal parameters (an extension of our
* IR) correspond to ir_constant actual parameters.
+ *
+ * Also, perform implicit conversion of arguments. Note: to implicitly
+ * convert out parameters, we need to place them in a temporary
+ * variable, and do the conversion after the call takes place. Since we
+ * haven't emitted the call yet, we'll place the post-call conversions
+ * in a temporary exec_list, and emit them later.
*/
exec_list_iterator actual_iter = actual_parameters->iterator();
exec_list_iterator formal_iter = sig->parameters.iterator();
@@ -156,6 +164,7 @@ match_function_by_name(exec_list *instructions, const char *name, _mesa_glsl_error(loc, state,
"parameter `%s' must be a constant expression",
formal->name);
+ return ir_call::get_error_instruction(ctx);
}
if ((formal->mode == ir_var_out)
@@ -185,8 +194,64 @@ match_function_by_name(exec_list *instructions, const char *name, }
if (formal->type->is_numeric() || formal->type->is_boolean()) {
- ir_rvalue *converted = convert_component(actual, formal->type);
- actual->replace_with(converted);
+ switch (formal->mode) {
+ case ir_var_const_in:
+ case ir_var_in: {
+ ir_rvalue *converted
+ = convert_component(actual, formal->type);
+ actual->replace_with(converted);
+ break;
+ }
+ case ir_var_out:
+ if (actual->type != formal->type) {
+ /* To convert an out parameter, we need to create a
+ * temporary variable to hold the value before conversion,
+ * and then perform the conversion after the function call
+ * returns.
+ *
+ * This has the effect of transforming code like this:
+ *
+ * void f(out int x);
+ * float value;
+ * f(value);
+ *
+ * Into IR that's equivalent to this:
+ *
+ * void f(out int x);
+ * float value;
+ * int out_parameter_conversion;
+ * f(out_parameter_conversion);
+ * value = float(out_parameter_conversion);
+ */
+ ir_variable *tmp =
+ new(ctx) ir_variable(formal->type,
+ "out_parameter_conversion",
+ ir_var_temporary);
+ instructions->push_tail(tmp);
+ ir_dereference_variable *deref_tmp_1
+ = new(ctx) ir_dereference_variable(tmp);
+ ir_dereference_variable *deref_tmp_2
+ = new(ctx) ir_dereference_variable(tmp);
+ ir_rvalue *converted_tmp
+ = convert_component(deref_tmp_1, actual->type);
+ ir_assignment *assignment
+ = new(ctx) ir_assignment(actual, converted_tmp);
+ post_call_conversions.push_tail(assignment);
+ actual->replace_with(deref_tmp_2);
+ }
+ break;
+ case ir_var_inout:
+ /* Inout parameters should never require conversion, since that
+ * would require an implicit conversion to exist both to and
+ * from the formal parameter type, and there are no
+ * bidirectional implicit conversions.
+ */
+ assert (actual->type == formal->type);
+ break;
+ default:
+ assert (!"Illegal formal parameter mode");
+ break;
+ }
}
actual_iter.next();
@@ -196,8 +261,11 @@ match_function_by_name(exec_list *instructions, const char *name, /* Always insert the call in the instruction stream, and return a deref
* of its return val if it returns a value, since we don't know if
* the rvalue is going to be assigned to anything or not.
+ *
+ * Also insert any out parameter conversions after the call.
*/
ir_call *call = new(ctx) ir_call(sig, actual_parameters);
+ ir_dereference_variable *deref;
if (!sig->return_type->is_void()) {
/* If the function call is a constant expression, don't
* generate the instructions to call it; just generate an
@@ -214,7 +282,6 @@ match_function_by_name(exec_list *instructions, const char *name, }
ir_variable *var;
- ir_dereference_variable *deref;
var = new(ctx) ir_variable(sig->return_type,
ralloc_asprintf(ctx, "%s_retval",
@@ -227,11 +294,12 @@ match_function_by_name(exec_list *instructions, const char *name, instructions->push_tail(assign);
deref = new(ctx) ir_dereference_variable(var);
- return deref;
} else {
instructions->push_tail(call);
- return NULL;
+ deref = NULL;
}
+ instructions->append_list(&post_call_conversions);
+ return deref;
} else {
char *str = prototype_string(NULL, name, actual_parameters);
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index d4f5065cc..c85bb0dc7 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -653,6 +653,16 @@ validate_assignment(struct _mesa_glsl_parse_state *state, return NULL;
}
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+ ir_dereference_variable *deref = access->as_dereference_variable();
+
+ if (deref && deref->var) {
+ deref->var->max_array_access = deref->type->length - 1;
+ }
+}
+
ir_rvalue *
do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer,
@@ -713,6 +723,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, rhs->type->array_size());
d->type = var->type;
}
+ mark_whole_array_access(lhs);
}
/* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
@@ -773,16 +784,6 @@ ast_node::hir(exec_list *instructions, return NULL;
}
-static void
-mark_whole_array_access(ir_rvalue *access)
-{
- ir_dereference_variable *deref = access->as_dereference_variable();
-
- if (deref) {
- deref->var->max_array_access = deref->type->length - 1;
- }
-}
-
static ir_rvalue *
do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
{
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 0b1ada90d..bfbabb320 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1132,8 +1132,10 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_shader_texture_lod)
add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1);
- if (extensions->AMD_conservative_depth)
+ if (extensions->AMD_conservative_depth) {
add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
+ add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
+ }
}
language_version = 110;
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 1851f1e20..25d02fb1e 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1111,7 +1111,7 @@ layout_qualifier_id: } } - /* Layout qualifiers for AMD_conservative_depth. */ + /* Layout qualifiers for AMD/ARB_conservative_depth. */ if (!got_one && state->AMD_conservative_depth_enable) { if (strcmp($1, "depth_any") == 0) { got_one = true; @@ -1129,7 +1129,7 @@ layout_qualifier_id: if (got_one && state->AMD_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, - "GL_AMD_conservative_depth " + "GL_ARB_conservative_depth " "layout qualifier `%s' is used\n", $1); } } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 72acc2e38..7204c9274 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -253,6 +253,7 @@ struct _mesa_glsl_extension { static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
/* target availability API availability */
/* name VS GS FS GL ES supported flag */
+ EXT(ARB_conservative_depth, true, false, true, true, false, AMD_conservative_depth),
EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true),
EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced),
EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location),
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 428cd9e36..6868b5f10 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -184,6 +184,8 @@ struct _mesa_glsl_parse_state { bool ARB_shader_stencil_export_warn;
bool AMD_conservative_depth_enable;
bool AMD_conservative_depth_warn;
+ bool ARB_conservative_depth_enable;
+ bool ARB_conservative_depth_warn;
bool AMD_shader_stencil_export_enable;
bool AMD_shader_stencil_export_warn;
bool OES_texture_3D_enable;
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 4b35b8a90..7b15c2b84 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1096,7 +1096,7 @@ ir_dereference_record::ir_dereference_record(ir_variable *var, }
bool
-ir_dereference::is_lvalue()
+ir_dereference::is_lvalue() const
{
ir_variable *var = this->variable_referenced();
@@ -1121,7 +1121,7 @@ ir_dereference::is_lvalue() }
-const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
+const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txs" };
const char *ir_texture::opcode_string()
{
@@ -1150,11 +1150,15 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) this->sampler = sampler;
this->type = type;
- 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);
+ if (this->op == ir_txs) {
+ assert(type->base_type == GLSL_TYPE_INT);
+ } else {
+ 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);
+ }
}
@@ -1310,7 +1314,7 @@ ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) #undef I
ir_variable *
-ir_swizzle::variable_referenced()
+ir_swizzle::variable_referenced() const
{
return this->val->variable_referenced();
}
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 8df2c42c3..01008092a 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -144,7 +144,7 @@ public: ir_rvalue *as_rvalue_to_saturate();
- virtual bool is_lvalue()
+ virtual bool is_lvalue() const
{
return false;
}
@@ -152,7 +152,7 @@ public: /**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced()
+ virtual ir_variable *variable_referenced() const
{
return NULL;
}
@@ -236,7 +236,7 @@ enum ir_variable_interpolation { /**
* \brief Layout qualifiers for gl_FragDepth.
*
- * The AMD_conservative_depth extension allows gl_FragDepth to be redeclared
+ * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared
* with a layout qualifier.
*/
enum ir_depth_layout {
@@ -1212,7 +1212,8 @@ enum ir_texture_opcode { ir_txb, /**< Texture look-up with LOD bias */
ir_txl, /**< Texture look-up with explicit LOD */
ir_txd, /**< Texture look-up with partial derivatvies */
- ir_txf /**< Texel fetch with explicit LOD */
+ ir_txf, /**< Texel fetch with explicit LOD */
+ ir_txs /**< Texture size */
};
@@ -1233,6 +1234,7 @@ enum ir_texture_opcode { * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
* (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
* (txf <type> <sampler> <coordinate> 0 <lod>)
+ * (txs <type> <sampler> <lod>)
*/
class ir_texture : public ir_rvalue {
public:
@@ -1355,7 +1357,7 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *);
- bool is_lvalue()
+ bool is_lvalue() const
{
return val->is_lvalue() && !mask.has_duplicates;
}
@@ -1363,7 +1365,7 @@ public: /**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced();
+ virtual ir_variable *variable_referenced() const;
ir_rvalue *val;
ir_swizzle_mask mask;
@@ -1387,12 +1389,12 @@ public: return this;
}
- bool is_lvalue();
+ bool is_lvalue() const;
/**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced() = 0;
+ virtual ir_variable *variable_referenced() const = 0;
};
@@ -1413,7 +1415,7 @@ public: /**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced()
+ virtual ir_variable *variable_referenced() const
{
return this->var;
}
@@ -1462,7 +1464,7 @@ public: /**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced()
+ virtual ir_variable *variable_referenced() const
{
return this->array->variable_referenced();
}
@@ -1496,7 +1498,7 @@ public: /**
* Get the variable that is ultimately referenced by an r-value
*/
- virtual ir_variable *variable_referenced()
+ virtual ir_variable *variable_referenced() const
{
return this->record->variable_referenced();
}
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index eac1f7492..8260b1339 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -222,7 +222,8 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const new_tex->type = this->type;
new_tex->sampler = this->sampler->clone(mem_ctx, ht);
- new_tex->coordinate = this->coordinate->clone(mem_ctx, ht);
+ if (this->coordinate)
+ new_tex->coordinate = this->coordinate->clone(mem_ctx, ht);
if (this->projector)
new_tex->projector = this->projector->clone(mem_ctx, ht);
if (this->shadow_comparitor) {
@@ -240,6 +241,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const break;
case ir_txl:
case ir_txf:
+ case ir_txs:
new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht);
break;
case ir_txd:
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index 4a607dc87..d33fc85bf 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -171,9 +171,11 @@ ir_texture::accept(ir_hierarchical_visitor *v) if (s != visit_continue) return (s == visit_continue_with_parent) ? visit_continue : s; - s = this->coordinate->accept(v); - if (s != visit_continue) - return (s == visit_continue_with_parent) ? visit_continue : s; + if (this->coordinate) { + s = this->coordinate->accept(v); + if (s != visit_continue) + return (s == visit_continue_with_parent) ? visit_continue : s; + } if (this->projector) { s = this->projector->accept(v); @@ -203,6 +205,7 @@ ir_texture::accept(ir_hierarchical_visitor *v) break; case ir_txl: case ir_txf: + case ir_txs: s = this->lod_info.lod->accept(v); if (s != visit_continue) return (s == visit_continue_with_parent) ? visit_continue : s; diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 7e3649477..89f20529e 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -244,19 +244,21 @@ void ir_print_visitor::visit(ir_texture *ir) ir->sampler->accept(this);
printf(" ");
- ir->coordinate->accept(this);
+ if (ir->op != ir_txs) {
+ ir->coordinate->accept(this);
- printf(" ");
+ printf(" ");
- if (ir->offset != NULL) {
- ir->offset->accept(this);
- } else {
- printf("0");
- }
+ if (ir->offset != NULL) {
+ ir->offset->accept(this);
+ } else {
+ printf("0");
+ }
- printf(" ");
+ printf(" ");
+ }
- if (ir->op != ir_txf) {
+ if (ir->op != ir_txf && ir->op != ir_txs) {
if (ir->projector)
ir->projector->accept(this);
else
@@ -280,6 +282,7 @@ void ir_print_visitor::visit(ir_texture *ir) break;
case ir_txl:
case ir_txf:
+ case ir_txs:
ir->lod_info.lod->accept(this);
break;
case ir_txd:
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index f3a621734..22009eebc 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -885,6 +885,8 @@ ir_reader::read_texture(s_expression *expr) { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; s_pattern txf_pattern[] = { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; + s_pattern txs_pattern[] = + { "txs", s_type, s_sampler, s_lod }; s_pattern other_pattern[] = { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; @@ -892,6 +894,8 @@ ir_reader::read_texture(s_expression *expr) op = ir_tex; } else if (MATCH(expr, txf_pattern)) { op = ir_txf; + } else if (MATCH(expr, txs_pattern)) { + op = ir_txs; } else if (MATCH(expr, other_pattern)) { op = ir_texture::get_opcode(tag->value()); if (op == -1) @@ -920,25 +924,27 @@ ir_reader::read_texture(s_expression *expr) } tex->set_sampler(sampler, type); - // Read coordinate (any rvalue) - tex->coordinate = read_rvalue(s_coord); - if (tex->coordinate == NULL) { - ir_read_error(NULL, "when reading coordinate in (%s ...)", - tex->opcode_string()); - return NULL; - } - - // Read texel offset - either 0 or an rvalue. - s_int *si_offset = SX_AS_INT(s_offset); - if (si_offset == NULL || si_offset->value() != 0) { - tex->offset = read_rvalue(s_offset); - if (tex->offset == NULL) { - ir_read_error(s_offset, "expected 0 or an expression"); + if (op != ir_txs) { + // Read coordinate (any rvalue) + tex->coordinate = read_rvalue(s_coord); + if (tex->coordinate == NULL) { + ir_read_error(NULL, "when reading coordinate in (%s ...)", + tex->opcode_string()); return NULL; } + + // Read texel offset - either 0 or an rvalue. + s_int *si_offset = SX_AS_INT(s_offset); + if (si_offset == NULL || si_offset->value() != 0) { + tex->offset = read_rvalue(s_offset); + if (tex->offset == NULL) { + ir_read_error(s_offset, "expected 0 or an expression"); + return NULL; + } + } } - if (op != ir_txf) { + if (op != ir_txf && op != ir_txs) { s_int *proj_as_int = SX_AS_INT(s_proj); if (proj_as_int && proj_as_int->value() == 1) { tex->projector = NULL; @@ -973,6 +979,7 @@ ir_reader::read_texture(s_expression *expr) break; case ir_txl: case ir_txf: + case ir_txs: tex->lod_info.lod = read_rvalue(s_lod); if (tex->lod_info.lod == NULL) { ir_read_error(NULL, "when reading LOD in (%s ...)", diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index ed6c7cb6a..193bcd2d7 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -63,6 +63,7 @@ ir_rvalue_visitor::visit_leave(ir_texture *ir) break; case ir_txf: case ir_txl: + case ir_txs: handle_rvalue(&ir->lod_info.lod); break; case ir_txd: diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index ed731b631..90a4d60d2 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -59,7 +59,8 @@ public: virtual ir_visitor_status visit(ir_variable *v);
virtual ir_visitor_status visit(ir_dereference_variable *ir);
- virtual ir_visitor_status visit(ir_if *ir);
+
+ virtual ir_visitor_status visit_enter(ir_if *ir);
virtual ir_visitor_status visit_leave(ir_loop *ir);
virtual ir_visitor_status visit_enter(ir_function *ir);
@@ -102,7 +103,7 @@ ir_validate::visit(ir_dereference_variable *ir) }
ir_visitor_status
-ir_validate::visit(ir_if *ir)
+ir_validate::visit_enter(ir_if *ir)
{
if (ir->condition->type != glsl_type::bool_type) {
printf("ir_if condition %s type instead of bool.\n",
@@ -541,7 +542,43 @@ ir_validate::visit_enter(ir_call *ir) abort();
}
+ const exec_node *formal_param_node = callee->parameters.head;
+ const exec_node *actual_param_node = ir->actual_parameters.head;
+ while (true) {
+ if (formal_param_node->is_tail_sentinel()
+ != actual_param_node->is_tail_sentinel()) {
+ printf("ir_call has the wrong number of parameters:\n");
+ goto dump_ir;
+ }
+ if (formal_param_node->is_tail_sentinel()) {
+ break;
+ }
+ const ir_variable *formal_param
+ = (const ir_variable *) formal_param_node;
+ const ir_rvalue *actual_param
+ = (const ir_rvalue *) actual_param_node;
+ if (formal_param->type != actual_param->type) {
+ printf("ir_call parameter type mismatch:\n");
+ goto dump_ir;
+ }
+ if (formal_param->mode == ir_var_out
+ || formal_param->mode == ir_var_inout) {
+ if (!actual_param->is_lvalue()) {
+ printf("ir_call out/inout parameters must be lvalues:\n");
+ goto dump_ir;
+ }
+ }
+ formal_param_node = formal_param_node->next;
+ actual_param_node = actual_param_node->next;
+ }
+
return visit_continue;
+
+dump_ir:
+ ir->print();
+ printf("callee:\n");
+ callee->print();
+ abort();
}
void
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 0d4d5d88b..3538dc5fe 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -395,7 +395,7 @@ cross_validate_globals(struct gl_shader_program *prog, /* Validate layout qualifiers for gl_FragDepth.
*
- * From the AMD_conservative_depth spec:
+ * From the AMD/ARB_conservative_depth specs:
* "If gl_FragDepth is redeclared in any fragment shader in
* a program, it must be redeclared in all fragment shaders in that
* program that have static assignments to gl_FragDepth. All
diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp index b637eb4fe..7b89a1539 100644 --- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp @@ -47,6 +47,7 @@ #include "glsl_types.h" #include "ir.h" +#include "program/hash_table.h" class ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor { public: @@ -55,6 +56,14 @@ public: this->progress = false; this->max_depth = max_depth; this->depth = 0; + + this->condition_variables = hash_table_ctor(0, hash_table_pointer_hash, + hash_table_pointer_compare); + } + + ~ir_if_to_cond_assign_visitor() + { + hash_table_dtor(this->condition_variables); } ir_visitor_status visit_enter(ir_if *); @@ -63,6 +72,8 @@ public: bool progress; unsigned max_depth; unsigned depth; + + struct hash_table *condition_variables; }; bool @@ -94,40 +105,43 @@ check_control_flow(ir_instruction *ir, void *data) void move_block_to_cond_assign(void *mem_ctx, - ir_if *if_ir, ir_variable *cond_var, bool then) + ir_if *if_ir, ir_rvalue *cond_expr, + exec_list *instructions, + struct hash_table *ht) { - exec_list *instructions; - - if (then) { - instructions = &if_ir->then_instructions; - } else { - instructions = &if_ir->else_instructions; - } - - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list_safe(node, instructions) { + ir_instruction *ir = (ir_instruction *) node; if (ir->ir_type == ir_type_assignment) { ir_assignment *assign = (ir_assignment *)ir; - ir_rvalue *cond_expr; - ir_dereference *deref = new(mem_ctx) ir_dereference_variable(cond_var); - - if (then) { - cond_expr = deref; - } else { - cond_expr = new(mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - deref, - NULL); - } - if (!assign->condition) { - assign->condition = cond_expr; - } else { - assign->condition = new(mem_ctx) ir_expression(ir_binop_logic_and, - glsl_type::bool_type, - cond_expr, - assign->condition); + if (hash_table_find(ht, assign) == NULL) { + hash_table_insert(ht, assign, assign); + + /* If the LHS of the assignment is a condition variable that was + * previously added, insert an additional assignment of false to + * the variable. + */ + const bool assign_to_cv = + hash_table_find(ht, assign->lhs->variable_referenced()) != NULL; + + if (!assign->condition) { + if (assign_to_cv) { + assign->rhs = + new(mem_ctx) ir_expression(ir_binop_logic_and, + glsl_type::bool_type, + cond_expr->clone(mem_ctx, NULL), + assign->rhs); + } else { + assign->condition = cond_expr->clone(mem_ctx, NULL); + } + } else { + assign->condition = + new(mem_ctx) ir_expression(ir_binop_logic_and, + glsl_type::bool_type, + cond_expr->clone(mem_ctx, NULL), + assign->condition); + } } } @@ -142,6 +156,7 @@ ir_if_to_cond_assign_visitor::visit_enter(ir_if *ir) { (void) ir; this->depth++; + return visit_continue; } @@ -153,9 +168,7 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) return visit_continue; bool found_control_flow = false; - ir_variable *cond_var; ir_assignment *assign; - ir_dereference_variable *deref; /* Check that both blocks don't contain anything we can't support. */ foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { @@ -171,24 +184,62 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) void *mem_ctx = ralloc_parent(ir); - /* Store the condition to a variable so the assignment conditions are - * simpler. + /* Store the condition to a variable. Move all of the instructions from + * the then-clause of the if-statement. Use the condition variable as a + * condition for all assignments. */ - cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type, - "if_to_cond_assign_condition", - ir_var_temporary); - ir->insert_before(cond_var); - - deref = new(mem_ctx) ir_dereference_variable(cond_var); - assign = new(mem_ctx) ir_assignment(deref, - ir->condition, NULL); + ir_variable *const then_var = + new(mem_ctx) ir_variable(glsl_type::bool_type, + "if_to_cond_assign_then", + ir_var_temporary); + ir->insert_before(then_var); + + ir_dereference_variable *then_cond = + new(mem_ctx) ir_dereference_variable(then_var); + + assign = new(mem_ctx) ir_assignment(then_cond, ir->condition); ir->insert_before(assign); - /* Now, move all of the instructions out of the if blocks, putting - * conditions on assignments. + move_block_to_cond_assign(mem_ctx, ir, then_cond, + &ir->then_instructions, + this->condition_variables); + + /* Add the new condition variable to the hash table. This allows us to + * find this variable when lowering other (enclosing) if-statements. + */ + hash_table_insert(this->condition_variables, then_var, then_var); + + /* If there are instructions in the else-clause, store the inverse of the + * condition to a variable. Move all of the instructions from the + * else-clause if the if-statement. Use the (inverse) condition variable + * as a condition for all assignments. */ - move_block_to_cond_assign(mem_ctx, ir, cond_var, true); - move_block_to_cond_assign(mem_ctx, ir, cond_var, false); + if (!ir->else_instructions.is_empty()) { + ir_variable *const else_var = + new(mem_ctx) ir_variable(glsl_type::bool_type, + "if_to_cond_assign_else", + ir_var_temporary); + ir->insert_before(else_var); + + ir_dereference_variable *else_cond = + new(mem_ctx) ir_dereference_variable(else_var); + + ir_rvalue *inverse = + new(mem_ctx) ir_expression(ir_unop_logic_not, + then_cond->clone(mem_ctx, NULL)); + + assign = new(mem_ctx) ir_assignment(else_cond, inverse); + ir->insert_before(assign); + + move_block_to_cond_assign(mem_ctx, ir, else_cond, + &ir->else_instructions, + this->condition_variables); + + /* Add the new condition variable to the hash table. This allows us to + * find this variable when lowering other (enclosing) if-statements. + */ + hash_table_insert(this->condition_variables, else_var, else_var); + } ir->remove(); diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp index 806f86399..23aa19bde 100644 --- a/mesalib/src/glsl/lower_instructions.cpp +++ b/mesalib/src/glsl/lower_instructions.cpp @@ -166,6 +166,10 @@ lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir) else op0 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[0], NULL); + vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, + ir->type->vector_elements, + ir->type->matrix_columns); + op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1); if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) { diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index b368b3dbc..31f6cbad3 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -35,7 +35,6 @@ #include "ast.h"
#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
#include "ir_optimization.h"
#include "ir_print_visitor.h"
#include "program.h"
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 75bd11c09..e08545b47 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -258,6 +258,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) break;
case ir_txf:
case ir_txl:
+ case ir_txs:
if (do_graft(&ir->lod_info.lod))
return visit_stop;
break;
diff --git a/mesalib/src/glsl/ralloc.c b/mesalib/src/glsl/ralloc.c index 6a5eac6b9..fb48a91c5 100644 --- a/mesalib/src/glsl/ralloc.c +++ b/mesalib/src/glsl/ralloc.c @@ -28,6 +28,11 @@ #include <string.h> #include <stdint.h> +/* Android defines SIZE_MAX in limits.h, instead of the standard stdint.h */ +#ifdef ANDROID +#include <limits.h> +#endif + #include "ralloc.h" #ifdef __GNUC__ diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 696ea757e..bbd7bb913 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -63,6 +63,8 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->API = api; + ctx->Extensions.dummy_false = false; + ctx->Extensions.dummy_true = true; ctx->Extensions.ARB_ES2_compatibility = true; ctx->Extensions.ARB_draw_buffers = true; ctx->Extensions.ARB_draw_instanced = true; |