diff options
Diffstat (limited to 'mesalib/src/glsl')
34 files changed, 333 insertions, 138 deletions
diff --git a/mesalib/src/glsl/Android.mk b/mesalib/src/glsl/Android.mk index f20741e0d..f63b7daf2 100644 --- a/mesalib/src/glsl/Android.mk +++ b/mesalib/src/glsl/Android.mk @@ -46,7 +46,6 @@ LOCAL_C_INCLUDES := \ LOCAL_MODULE := libmesa_glsl -include external/stlport/libstlport.mk include $(LOCAL_PATH)/Android.gen.mk include $(MESA_COMMON_MK) include $(BUILD_STATIC_LIBRARY) diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am index 23c6fe8bb..fa8c9f5d3 100644 --- a/mesalib/src/glsl/Makefile.am +++ b/mesalib/src/glsl/Makefile.am @@ -89,8 +89,7 @@ tests_general_ir_test_SOURCES = \ tests/builtin_variable_test.cpp \ tests/invalidate_locations_test.cpp \ tests/general_ir_test.cpp \ - tests/varyings_test.cpp \ - tests/common.c + tests/varyings_test.cpp tests_general_ir_test_CFLAGS = \ $(PTHREAD_CFLAGS) tests_general_ir_test_LDADD = \ @@ -103,8 +102,7 @@ tests_uniform_initializer_test_SOURCES = \ tests/copy_constant_to_storage_tests.cpp \ tests/set_uniform_initializer_tests.cpp \ tests/uniform_initializer_utils.cpp \ - tests/uniform_initializer_utils.h \ - tests/common.c + tests/uniform_initializer_utils.h tests_uniform_initializer_test_CFLAGS = \ $(PTHREAD_CFLAGS) tests_uniform_initializer_test_LDADD = \ @@ -114,8 +112,7 @@ tests_uniform_initializer_test_LDADD = \ $(PTHREAD_LIBS) tests_sampler_types_test_SOURCES = \ - tests/sampler_types_test.cpp \ - tests/common.c + tests/sampler_types_test.cpp tests_sampler_types_test_CFLAGS = \ $(PTHREAD_CFLAGS) tests_sampler_types_test_LDADD = \ @@ -133,8 +130,7 @@ libglcpp_la_SOURCES = \ $(LIBGLCPP_FILES) glcpp_glcpp_SOURCES = \ - glcpp/glcpp.c \ - tests/common.c + glcpp/glcpp.c glcpp_glcpp_LDADD = \ libglcpp.la \ $(top_builddir)/src/libglsl_util.la \ @@ -164,7 +160,6 @@ glsl_compiler_LDADD = \ glsl_test_SOURCES = \ standalone_scaffolding.cpp \ - tests/common.c \ test.cpp \ test_optpass.cpp \ test_optpass.h @@ -247,21 +242,21 @@ dist-hook: $(RM) glcpp/tests/subtest*/*.out nir/nir_builder_opcodes.h: nir/nir_opcodes.py nir/nir_builder_opcodes_h.py - $(MKDIR_P) nir; \ - $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_builder_opcodes_h.py > $@ + $(AM_V_at)$(MKDIR_P) nir + $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_builder_opcodes_h.py > $@ nir/nir_constant_expressions.c: nir/nir_opcodes.py nir/nir_constant_expressions.py nir/nir_constant_expressions.h - $(MKDIR_P) nir; \ - $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_constant_expressions.py > $@ + $(AM_V_at)$(MKDIR_P) nir + $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_constant_expressions.py > $@ nir/nir_opcodes.h: nir/nir_opcodes.py nir/nir_opcodes_h.py - $(MKDIR_P) nir; \ - $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@ + $(AM_V_at)$(MKDIR_P) nir + $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@ nir/nir_opcodes.c: nir/nir_opcodes.py nir/nir_opcodes_c.py - $(MKDIR_P) nir; \ - $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@ + $(AM_V_at)$(MKDIR_P) nir + $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@ nir/nir_opt_algebraic.c: nir/nir_opt_algebraic.py nir/nir_algebraic.py - $(MKDIR_P) nir; \ - $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opt_algebraic.py > $@ + $(AM_V_at)$(MKDIR_P) nir + $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opt_algebraic.py > $@ diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index 284b37584..89c603580 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -71,6 +71,7 @@ env.Command('imports.c', '#src/mesa/main/imports.c', Copy('$TARGET', '$SOURCE')) env.Prepend(CPPPATH = ['#src/mesa/program']) env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE')) env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE')) +env.Command('dummy_errors.c', '#src/mesa/program/dummy_errors.c', Copy('$TARGET', '$SOURCE')) compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES']) @@ -78,6 +79,7 @@ mesa_objs = env.StaticObject([ 'imports.c', 'prog_hash_table.c', 'symbol_table.c', + 'dummy_errors.c', ]) compiler_objs += mesa_objs @@ -115,6 +117,6 @@ env.Alias('glsl_compiler', glsl_compiler) glcpp = env.Program( target = 'glcpp/glcpp', - source = ['glcpp/glcpp.c', 'tests/common.c'] + mesa_objs, + source = ['glcpp/glcpp.c'] + mesa_objs, ) env.Alias('glcpp', glcpp) diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp index ecef651f7..752d86f72 100644 --- a/mesalib/src/glsl/ast_array_index.cpp +++ b/mesalib/src/glsl/ast_array_index.cpp @@ -225,7 +225,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx, * values *do* diverge, then the behavior of the operation requiring a * dynamically uniform expression is undefined. */ - if (array->type->element_type()->is_sampler()) { + if (array->type->without_array()->is_sampler()) { if (!state->is_version(130, 100)) { if (state->es_shader) { _mesa_glsl_warning(&loc, state, diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 758361324..92e26bf24 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -863,7 +863,7 @@ process_array_constructor(exec_list *instructions, if (is_unsized_array) { constructor_type = - glsl_type::get_array_instance(constructor_type->element_type(), + glsl_type::get_array_instance(constructor_type->fields.array, parameter_count); assert(constructor_type != NULL); assert(constructor_type->length == parameter_count); @@ -876,7 +876,7 @@ process_array_constructor(exec_list *instructions, ir_rvalue *result = ir; const glsl_base_type element_base_type = - constructor_type->element_type()->base_type; + constructor_type->fields.array->base_type; /* Apply implicit conversions (not the scalar constructor rules!). See * the spec quote above. */ @@ -896,10 +896,10 @@ process_array_constructor(exec_list *instructions, } } - if (result->type != constructor_type->element_type()) { + if (result->type != constructor_type->fields.array) { _mesa_glsl_error(loc, state, "type error in array constructor: " "expected: %s, found %s", - constructor_type->element_type()->name, + constructor_type->fields.array->name, result->type->name); return ir_rvalue::error_value(ctx); } @@ -993,11 +993,15 @@ emit_inline_vector_constructor(const glsl_type *type, ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary); instructions->push_tail(var); - /* There are two kinds of vector constructors. + /* There are three kinds of vector constructors. * * - Construct a vector from a single scalar by replicating that scalar to * all components of the vector. * + * - Construct a vector from at least a matrix. This case should already + * have been taken care of in ast_function_expression::hir by breaking + * down the matrix into a series of column vectors. + * * - Construct a vector from an arbirary combination of vectors and * scalars. The components of the constructor parameters are assigned * to the vector in order until the vector is full. @@ -1091,6 +1095,14 @@ emit_inline_vector_constructor(const glsl_type *type, rhs_components = lhs_components - base_component; } + /* If we do not have any components left to copy, break out of the + * loop. This can happen when initializing a vec4 with a mat3 as the + * mat3 would have been broken into a series of column vectors. + */ + if (rhs_components == 0) { + break; + } + const ir_constant *const c = param->as_constant(); if (c == NULL) { /* Mask of fields to be written in the assignment. @@ -1681,11 +1693,11 @@ ast_function_expression::hir(exec_list *instructions, return ir_rvalue::error_value(ctx); } - /* Later, we cast each parameter to the same base type as the - * constructor. Since there are no non-floating point matrices, we - * need to break them up into a series of column vectors. + /* Matrices can never be consumed as is by any constructor but matrix + * constructors. If the constructor type is not matrix, always break the + * matrix up into a series of column vectors. */ - if (constructor_type->base_type != GLSL_TYPE_FLOAT) { + if (!constructor_type->is_matrix()) { foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) { if (!matrix->type->is_matrix()) continue; diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 14e630905..fc24305b2 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -678,7 +678,7 @@ validate_assignment(struct _mesa_glsl_parse_state *state, * is handled by ir_dereference::is_lvalue. */ if (lhs_type->is_unsized_array() && rhs->type->is_array() - && (lhs_type->element_type() == rhs->type->element_type())) { + && (lhs_type->fields.array == rhs->type->fields.array)) { if (is_initializer) { return rhs; } else { @@ -820,7 +820,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, var->data.max_array_access); } - var->type = glsl_type::get_array_instance(lhs->type->element_type(), + var->type = glsl_type::get_array_instance(lhs->type->fields.array, rhs->type->array_size()); d->type = var->type; } @@ -2330,8 +2330,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - const glsl_type *base_type = - (var->type->is_array() ? var->type->element_type() : var->type); + const glsl_type *base_type = var->type->without_array(); if (base_type->is_image()) { if (var->data.mode != ir_var_uniform && @@ -2730,7 +2729,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, * GL_ARB_conservative_depth * GL_ARB_gpu_shader5 * GL_ARB_separate_shader_objects - * GL_ARB_tesselation_shader + * GL_ARB_tessellation_shader * GL_ARB_transform_feedback3 * GL_ARB_uniform_buffer_object * @@ -2855,7 +2854,7 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc, * type and specify a size." */ if (earlier->type->is_unsized_array() && var->type->is_array() - && (var->type->element_type() == earlier->type->element_type())) { + && (var->type->fields.array == earlier->type->fields.array)) { /* FINISHME: This doesn't match the qualifiers on the two * FINISHME: declarations. It's not 100% clear whether this is * FINISHME: required or not. @@ -3608,6 +3607,51 @@ ast_declarator_list::hir(exec_list *instructions, } handle_geometry_shader_input_decl(state, loc, var); + } else if (state->stage == MESA_SHADER_FRAGMENT) { + /* From section 4.3.4 (Input Variables) of the GLSL ES 3.10 spec: + * + * It is a compile-time error to declare a fragment shader + * input with, or that contains, any of the following types: + * + * * A boolean type + * * An opaque type + * * An array of arrays + * * An array of structures + * * A structure containing an array + * * A structure containing a structure + */ + if (state->es_shader) { + const glsl_type *check_type = var->type->without_array(); + if (check_type->is_boolean() || + check_type->contains_opaque()) { + _mesa_glsl_error(&loc, state, + "fragment shader input cannot have type %s", + check_type->name); + } + if (var->type->is_array() && + var->type->fields.array->is_array()) { + _mesa_glsl_error(&loc, state, + "%s shader output " + "cannot have an array of arrays", + _mesa_shader_stage_to_string(state->stage)); + } + if (var->type->is_array() && + var->type->fields.array->is_record()) { + _mesa_glsl_error(&loc, state, + "fragment shader input " + "cannot have an array of structs"); + } + if (var->type->is_record()) { + for (unsigned i = 0; i < var->type->length; i++) { + if (var->type->fields.structure[i].type->is_array() || + var->type->fields.structure[i].type->is_record()) + _mesa_glsl_error(&loc, state, + "fragement shader input cannot have " + "a struct that contains an " + "array or struct"); + } + } + } } } else if (var->data.mode == ir_var_shader_out) { const glsl_type *check_type = var->type->without_array(); @@ -3642,7 +3686,7 @@ ast_declarator_list::hir(exec_list *instructions, if (check_type->is_record() || check_type->is_matrix()) _mesa_glsl_error(&loc, state, "fragment shader output " - "cannot have struct or array type"); + "cannot have struct or matrix type"); switch (check_type->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: @@ -3654,6 +3698,55 @@ ast_declarator_list::hir(exec_list *instructions, "type %s", check_type->name); } } + + /* From section 4.3.6 (Output Variables) of the GLSL ES 3.10 spec: + * + * It is a compile-time error to declare a vertex shader output + * with, or that contains, any of the following types: + * + * * A boolean type + * * An opaque type + * * An array of arrays + * * An array of structures + * * A structure containing an array + * * A structure containing a structure + * + * It is a compile-time error to declare a fragment shader output + * with, or that contains, any of the following types: + * + * * A boolean type + * * An opaque type + * * A matrix + * * A structure + * * An array of array + */ + if (state->es_shader) { + if (var->type->is_array() && + var->type->fields.array->is_array()) { + _mesa_glsl_error(&loc, state, + "%s shader output " + "cannot have an array of arrays", + _mesa_shader_stage_to_string(state->stage)); + } + if (state->stage == MESA_SHADER_VERTEX) { + if (var->type->is_array() && + var->type->fields.array->is_record()) { + _mesa_glsl_error(&loc, state, + "vertex shader output " + "cannot have an array of structs"); + } + if (var->type->is_record()) { + for (unsigned i = 0; i < var->type->length; i++) { + if (var->type->fields.structure[i].type->is_array() || + var->type->fields.structure[i].type->is_record()) + _mesa_glsl_error(&loc, state, + "vertex shader output cannot have a " + "struct that contains an " + "array or struct"); + } + } + } + } } /* Integer fragment inputs must be qualified with 'flat'. In GLSL ES, @@ -3850,7 +3943,15 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } - if (state->es_shader) { + /* GLSL ES 3.10 removes the restriction on unsized arrays. + * + * Section 4.1.9 (Arrays) of the GLSL ES 3.10 spec says: + * + * "Variables of the same type can be aggregated into arrays by + * declaring a name followed by brackets ([ ]) enclosing an + * optional size." + */ + if (state->es_shader && state->language_version < 310) { const glsl_type *const t = (earlier == NULL) ? var->type : earlier->type; @@ -5746,6 +5847,17 @@ ast_interface_block::hir(exec_list *instructions, const glsl_type *block_array_type = process_array_type(&loc, block_type, this->array_specifier, state); + /* From section 4.3.9 (Interface Blocks) of the GLSL ES 3.10 spec: + * + * * Arrays of arrays of blocks are not allowed + */ + if (state->es_shader && block_array_type->is_array() && + block_array_type->fields.array->is_array()) { + _mesa_glsl_error(&loc, state, + "arrays of arrays interface blocks are " + "not allowed"); + } + var = new(state) ir_variable(block_array_type, this->instance_name, var_mode); diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp index 97055d85d..efab29919 100644 --- a/mesalib/src/glsl/builtin_functions.cpp +++ b/mesalib/src/glsl/builtin_functions.cpp @@ -410,6 +410,13 @@ fp64(const _mesa_glsl_parse_state *state) return state->has_double(); } +static bool +barrier_supported(const _mesa_glsl_parse_state *state) +{ + return state->stage == MESA_SHADER_COMPUTE; + /* TODO: || stage->state == MESA_SHADER_TESS_CTRL; */ +} + /** @} */ /******************************************************************************/ @@ -654,6 +661,7 @@ private: const glsl_type *stream_type); ir_function_signature *_EndStreamPrimitive(builtin_available_predicate avail, const glsl_type *stream_type); + B0(barrier) B2(textureQueryLod); B1(textureQueryLevels); @@ -1933,6 +1941,7 @@ builtin_builder::create_builtins() _EndStreamPrimitive(gs_streams, glsl_type::uint_type), _EndStreamPrimitive(gs_streams, glsl_type::int_type), NULL); + add_function("barrier", _barrier(), NULL); add_function("textureQueryLOD", _textureQueryLod(glsl_type::sampler1D_type, glsl_type::float_type), @@ -4296,6 +4305,15 @@ builtin_builder::_EndStreamPrimitive(builtin_available_predicate avail, } ir_function_signature * +builtin_builder::_barrier() +{ + MAKE_SIG(glsl_type::void_type, barrier_supported, 0); + + body.emit(new(mem_ctx) ir_barrier()); + return sig; +} + +ir_function_signature * builtin_builder::_textureQueryLod(const glsl_type *sampler_type, const glsl_type *coord_type) { diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index be6713c46..046d5d7b5 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -778,7 +778,7 @@ _mesa_ast_set_aggregate_type(const glsl_type *type, /* If the aggregate is an array, recursively set its elements' types. */ if (type->is_array()) { - /* Each array element has the type type->element_type(). + /* Each array element has the type type->fields.array. * * E.g., if <type> if struct S[2] we want to set each element's type to * struct S. @@ -790,7 +790,7 @@ _mesa_ast_set_aggregate_type(const glsl_type *type, link); if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(type->element_type(), expr); + _mesa_ast_set_aggregate_type(type->fields.array, expr); } /* If the aggregate is a struct, recursively set its fields' types. */ diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 9c9b7efcb..f675e90cb 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -217,7 +217,7 @@ glsl_type::contains_opaque() const { case GLSL_TYPE_ATOMIC_UINT: return true; case GLSL_TYPE_ARRAY: - return element_type()->contains_opaque(); + return fields.array->contains_opaque(); case GLSL_TYPE_STRUCT: for (unsigned int i = 0; i < length; i++) { if (fields.structure[i].type->contains_opaque()) diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 5645dcd50..f54a9393e 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -228,18 +228,6 @@ struct glsl_type { const glsl_type *get_scalar_type() const; /** - * Query the type of elements in an array - * - * \return - * Pointer to the type of elements in the array for array types, or \c NULL - * for non-array types. - */ - const glsl_type *element_type() const - { - return is_array() ? fields.array : NULL; - } - - /** * Get the instance of a built-in scalar, vector, or matrix type */ static const glsl_type *get_instance(unsigned base_type, unsigned rows, @@ -556,7 +544,7 @@ struct glsl_type { if (base_type == GLSL_TYPE_ATOMIC_UINT) return ATOMIC_COUNTER_SIZE; else if (is_array()) - return length * element_type()->atomic_size(); + return length * fields.array->atomic_size(); else return 0; } diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 9e3238552..dbd064fee 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -912,7 +912,7 @@ ir_constant::zero(void *mem_ctx, const glsl_type *type) c->array_elements = ralloc_array(c, ir_constant *, type->length); for (unsigned i = 0; i < type->length; i++) - c->array_elements[i] = ir_constant::zero(c, type->element_type()); + c->array_elements[i] = ir_constant::zero(c, type->fields.array); } if (type->is_record()) { @@ -1341,7 +1341,7 @@ ir_dereference_array::set_array(ir_rvalue *value) const glsl_type *const vt = this->array->type; if (vt->is_array()) { - type = vt->element_type(); + type = vt->fields.array; } else if (vt->is_matrix()) { type = vt->column_type(); } else if (vt->is_vector()) { diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index fab1cd2d2..f90455535 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -78,6 +78,7 @@ enum ir_node_type { ir_type_discard, ir_type_emit_vertex, ir_type_end_primitive, + ir_type_barrier, ir_type_max, /**< maximum ir_type enum number, for validation */ ir_type_unset = ir_type_max }; @@ -2396,6 +2397,29 @@ public: ir_rvalue *stream; }; +/** + * IR instruction for tessellation control and compute shader barrier. + */ +class ir_barrier : public ir_instruction { +public: + ir_barrier() + : ir_instruction(ir_type_barrier) + { + } + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const + { + return new(mem_ctx) ir_barrier(); + } + + virtual ir_visitor_status accept(ir_hierarchical_visitor *); +}; + /*@}*/ /** diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.cpp b/mesalib/src/glsl/ir_hierarchical_visitor.cpp index adb629414..1d23a7766 100644 --- a/mesalib/src/glsl/ir_hierarchical_visitor.cpp +++ b/mesalib/src/glsl/ir_hierarchical_visitor.cpp @@ -80,6 +80,15 @@ ir_hierarchical_visitor::visit(ir_dereference_variable *ir) } ir_visitor_status +ir_hierarchical_visitor::visit(ir_barrier *ir) +{ + if (this->callback_enter != NULL) + this->callback_enter(ir, this->data_enter); + + return visit_continue; +} + +ir_visitor_status ir_hierarchical_visitor::visit_enter(ir_loop *ir) { if (this->callback_enter != NULL) diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.h b/mesalib/src/glsl/ir_hierarchical_visitor.h index faa52fd79..28517b6e4 100644 --- a/mesalib/src/glsl/ir_hierarchical_visitor.h +++ b/mesalib/src/glsl/ir_hierarchical_visitor.h @@ -59,7 +59,7 @@ enum ir_visitor_status { * in the composite's \c accept method. The \c accept method for a leaf-node * class will simply call the \c visit method, as usual, and pass its return * value on. The \c accept method for internal-node classes will call the \c - * visit_enter method, call the \c accpet method of each child node, and, + * visit_enter method, call the \c accept method of each child node, and, * finally, call the \c visit_leave method. If any of these return a value * other that \c visit_continue, the correct action must be taken. * @@ -87,6 +87,7 @@ public: virtual ir_visitor_status visit(class ir_variable *); virtual ir_visitor_status visit(class ir_constant *); virtual ir_visitor_status visit(class ir_loop_jump *); + virtual ir_visitor_status visit(class ir_barrier *); /** * ir_dereference_variable isn't technically a leaf, but it is treated as a diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index be5b3eaa0..d3662cf50 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -429,3 +429,9 @@ ir_end_primitive::accept(ir_hierarchical_visitor *v) return (s == visit_stop) ? s : v->visit_leave(this); } + +ir_visitor_status +ir_barrier::accept(ir_hierarchical_visitor *v) +{ + return v->visit(this); +} diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 01f52e85f..f5de6ac06 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -573,5 +573,10 @@ ir_print_visitor::visit(ir_end_primitive *ir) fprintf(f, "(end-primitive "); ir->stream->accept(this); fprintf(f, ")\n"); +} +void +ir_print_visitor::visit(ir_barrier *ir) +{ + fprintf(f, "(barrier)\n"); } diff --git a/mesalib/src/glsl/ir_print_visitor.h b/mesalib/src/glsl/ir_print_visitor.h index 98f041d1a..965e63ade 100644 --- a/mesalib/src/glsl/ir_print_visitor.h +++ b/mesalib/src/glsl/ir_print_visitor.h @@ -71,6 +71,7 @@ public: virtual void visit(ir_loop_jump *); virtual void visit(ir_emit_vertex *); virtual void visit(ir_end_primitive *); + virtual void visit(ir_barrier *); /*@}*/ private: diff --git a/mesalib/src/glsl/ir_uniform.h b/mesalib/src/glsl/ir_uniform.h index 21b5d05c1..e1b801477 100644 --- a/mesalib/src/glsl/ir_uniform.h +++ b/mesalib/src/glsl/ir_uniform.h @@ -181,6 +181,11 @@ struct gl_uniform_storage { * via the API. */ bool hidden; + + /** + * This is a built-in uniform that should not be modified through any gl API. + */ + bool builtin; }; #ifdef __cplusplus diff --git a/mesalib/src/glsl/ir_visitor.h b/mesalib/src/glsl/ir_visitor.h index 40f96ffbc..7c38481cd 100644 --- a/mesalib/src/glsl/ir_visitor.h +++ b/mesalib/src/glsl/ir_visitor.h @@ -65,6 +65,7 @@ public: virtual void visit(class ir_loop_jump *) = 0; virtual void visit(class ir_emit_vertex *) = 0; virtual void visit(class ir_end_primitive *) = 0; + virtual void visit(class ir_barrier *) = 0; /*@}*/ }; @@ -85,6 +86,7 @@ public: virtual void visit(class ir_call *) {} virtual void visit(class ir_emit_vertex *) {} virtual void visit(class ir_end_primitive *) {} + virtual void visit(class ir_barrier *) {} }; #endif /* __cplusplus */ diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp index 603873a5d..100d03c4e 100644 --- a/mesalib/src/glsl/link_atomics.cpp +++ b/mesalib/src/glsl/link_atomics.cpp @@ -207,7 +207,7 @@ link_assign_atomic_counter_resources(struct gl_context *ctx, storage->atomic_buffer_index = i; storage->offset = var->data.atomic.offset; storage->array_stride = (var->type->is_array() ? - var->type->element_type()->atomic_size() : 0); + var->type->without_array()->atomic_size() : 0); } /* Assign stage-specific fields. */ diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp index 69073841e..204acfa22 100644 --- a/mesalib/src/glsl/link_uniform_initializers.cpp +++ b/mesalib/src/glsl/link_uniform_initializers.cpp @@ -103,7 +103,7 @@ void set_sampler_binding(gl_shader_program *prog, const char *name, int binding) { struct gl_uniform_storage *const storage = - get_storage(prog->UniformStorage, prog->NumUserUniformStorage, name); + get_storage(prog->UniformStorage, prog->NumUniformStorage, name); if (storage == NULL) { assert(storage != NULL); @@ -193,7 +193,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog, struct gl_uniform_storage *const storage = get_storage(prog->UniformStorage, - prog->NumUserUniformStorage, + prog->NumUniformStorage, name); if (storage == NULL) { assert(storage != NULL); diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 2c928e144..11ae06f9b 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -589,12 +589,13 @@ private: handle_samplers(base_type, &this->uniforms[id]); handle_images(base_type, &this->uniforms[id]); - /* If there is already storage associated with this uniform, it means - * that it was set while processing an earlier shader stage. For - * example, we may be processing the uniform in the fragment shader, but - * the uniform was already processed in the vertex shader. + /* If there is already storage associated with this uniform or if the + * uniform is set as builtin, it means that it was set while processing + * an earlier shader stage. For example, we may be processing the + * uniform in the fragment shader, but the uniform was already processed + * in the vertex shader. */ - if (this->uniforms[id].storage != NULL) { + if (this->uniforms[id].storage != NULL || this->uniforms[id].builtin) { return; } @@ -619,10 +620,15 @@ private: this->uniforms[id].initialized = 0; this->uniforms[id].num_driver_storage = 0; this->uniforms[id].driver_storage = NULL; - this->uniforms[id].storage = this->values; this->uniforms[id].atomic_buffer_index = -1; this->uniforms[id].hidden = current_var->data.how_declared == ir_var_hidden; + this->uniforms[id].builtin = is_gl_identifier(name); + + /* Do not assign storage if the uniform is builtin */ + if (!this->uniforms[id].builtin) + this->uniforms[id].storage = this->values; + if (this->ubo_block_index != -1) { this->uniforms[id].block_index = this->ubo_block_index; @@ -894,7 +900,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog, { ralloc_free(prog->UniformStorage); prog->UniformStorage = NULL; - prog->NumUserUniformStorage = 0; + prog->NumUniformStorage = 0; if (prog->UniformHash != NULL) { prog->UniformHash->clear(); @@ -940,14 +946,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog, if ((var == NULL) || (var->data.mode != ir_var_uniform)) continue; - /* FINISHME: Update code to process built-in uniforms! - */ - if (is_gl_identifier(var->name)) { - uniform_size.num_shader_uniform_components += - var->type->component_slots(); - continue; - } - uniform_size.process(var); } @@ -962,16 +960,16 @@ link_assign_uniform_locations(struct gl_shader_program *prog, } } - const unsigned num_user_uniforms = uniform_size.num_active_uniforms; + const unsigned num_uniforms = uniform_size.num_active_uniforms; const unsigned num_data_slots = uniform_size.num_values; /* On the outside chance that there were no uniforms, bail out. */ - if (num_user_uniforms == 0) + if (num_uniforms == 0) return; struct gl_uniform_storage *uniforms = - rzalloc_array(prog, struct gl_uniform_storage, num_user_uniforms); + rzalloc_array(prog, struct gl_uniform_storage, num_uniforms); union gl_constant_value *data = rzalloc_array(uniforms, union gl_constant_value, num_data_slots); #ifndef NDEBUG @@ -992,11 +990,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog, if ((var == NULL) || (var->data.mode != ir_var_uniform)) continue; - /* FINISHME: Update code to process built-in uniforms! - */ - if (is_gl_identifier(var->name)) - continue; - parcel.set_and_process(prog, var); } @@ -1009,10 +1002,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog, } const unsigned hidden_uniforms = - move_hidden_uniforms_to_end(prog, uniforms, num_user_uniforms); + move_hidden_uniforms_to_end(prog, uniforms, num_uniforms); /* Reserve all the explicit locations of the active uniforms. */ - for (unsigned i = 0; i < num_user_uniforms; i++) { + for (unsigned i = 0; i < num_uniforms; i++) { if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) { /* How many new entries for this uniform? */ const unsigned entries = MAX2(1, uniforms[i].array_elements); @@ -1028,7 +1021,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog, } /* Reserve locations for rest of the uniforms. */ - for (unsigned i = 0; i < num_user_uniforms; i++) { + for (unsigned i = 0; i < num_uniforms; i++) { + + /* Built-in uniforms should not get any location. */ + if (uniforms[i].builtin) + continue; /* Explicit ones have been set already. */ if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) @@ -1055,14 +1052,14 @@ link_assign_uniform_locations(struct gl_shader_program *prog, } #ifndef NDEBUG - for (unsigned i = 0; i < num_user_uniforms; i++) { - assert(uniforms[i].storage != NULL); + for (unsigned i = 0; i < num_uniforms; i++) { + assert(uniforms[i].storage != NULL || uniforms[i].builtin); } assert(parcel.values == data_end); #endif - prog->NumUserUniformStorage = num_user_uniforms; + prog->NumUniformStorage = num_uniforms; prog->NumHiddenUniforms = hidden_uniforms; prog->UniformStorage = uniforms; diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 605748a9c..7b2d4bd23 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -56,7 +56,7 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, const glsl_type *type_to_match = input->type; if (consumer_stage == MESA_SHADER_GEOMETRY) { assert(type_to_match->is_array()); /* Enforced by ast_to_hir */ - type_to_match = type_to_match->element_type(); + type_to_match = type_to_match->fields.array; } if (type_to_match != output->type) { /* There is a bit of a special case for gl_TexCoord. This diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index ea73c6f9d..99783800b 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -224,7 +224,7 @@ public: return visit_continue; } - var->type = glsl_type::get_array_instance(var->type->element_type(), + var->type = glsl_type::get_array_instance(var->type->fields.array, this->num_vertices); var->data.max_array_access = this->num_vertices - 1; @@ -245,7 +245,7 @@ public: { const glsl_type *const vt = ir->array->type; if (vt->is_array()) - ir->type = vt->element_type(); + ir->type = vt->fields.array; return visit_continue; } }; @@ -1400,8 +1400,8 @@ link_fs_input_layout_qualifiers(struct gl_shader_program *prog, "layout qualifiers for gl_FragCoord\n"); } - /* Update the linked shader state. Note that uses_gl_fragcoord should - * accumulate the results. The other values should replace. If there + /* Update the linked shader state. Note that uses_gl_fragcoord should + * accumulate the results. The other values should replace. If there * are multiple redeclarations, all the fields except uses_gl_fragcoord * are already known to be the same. */ @@ -2693,13 +2693,23 @@ build_program_resource_list(struct gl_context *ctx, } /* Add uniforms from uniform storage. */ - for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) { + for (unsigned i = 0; i < shProg->NumUniformStorage; i++) { /* Do not add uniforms internally used by Mesa. */ if (shProg->UniformStorage[i].hidden) continue; uint8_t stageref = build_stageref(shProg, shProg->UniformStorage[i].name); + + /* Add stagereferences for uniforms in a uniform block. */ + int block_index = shProg->UniformStorage[i].block_index; + if (block_index != -1) { + for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { + if (shProg->UniformBlockStageIndex[j][block_index] != -1) + stageref |= (1 << j); + } + } + if (!add_program_resource(shProg, GL_UNIFORM, &shProg->UniformStorage[i], stageref)) return; @@ -2819,8 +2829,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage], num_shaders[stage]); - if (!prog->LinkStatus) + if (!prog->LinkStatus) { + if (sh) + ctx->Driver.DeleteShader(ctx, sh); goto done; + } switch (stage) { case MESA_SHADER_VERTEX: @@ -2833,8 +2846,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) validate_fragment_shader_executable(prog, sh); break; } - if (!prog->LinkStatus) + if (!prog->LinkStatus) { + if (sh) + ctx->Driver.DeleteShader(ctx, sh); goto done; + } _mesa_reference_shader(ctx, &prog->_LinkedShaders[stage], sh); } diff --git a/mesalib/src/glsl/lower_clip_distance.cpp b/mesalib/src/glsl/lower_clip_distance.cpp index 2d6138d5a..01f028b1f 100644 --- a/mesalib/src/glsl/lower_clip_distance.cpp +++ b/mesalib/src/glsl/lower_clip_distance.cpp @@ -114,7 +114,7 @@ lower_clip_distance_visitor::visit(ir_variable *ir) return visit_continue; assert (ir->type->is_array()); - if (!ir->type->element_type()->is_array()) { + if (!ir->type->fields.array->is_array()) { /* 1D gl_ClipDistance (used for vertex and geometry output, and fragment * input). */ @@ -123,7 +123,7 @@ lower_clip_distance_visitor::visit(ir_variable *ir) this->progress = true; this->old_clip_distance_1d_var = ir; - assert (ir->type->element_type() == glsl_type::float_type); + assert (ir->type->fields.array == glsl_type::float_type); unsigned new_size = (ir->type->array_size() + 3) / 4; /* Clone the old var so that we inherit all of its properties */ @@ -148,8 +148,8 @@ lower_clip_distance_visitor::visit(ir_variable *ir) this->progress = true; this->old_clip_distance_2d_var = ir; - assert (ir->type->element_type()->element_type() == glsl_type::float_type); - unsigned new_size = (ir->type->element_type()->array_size() + 3) / 4; + assert (ir->type->fields.array->fields.array == glsl_type::float_type); + unsigned new_size = (ir->type->fields.array->array_size() + 3) / 4; /* Clone the old var so that we inherit all of its properties */ this->new_clip_distance_2d_var = ir->clone(ralloc_parent(ir), NULL); diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index ccac83996..23412980d 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -41,12 +41,6 @@ static int glsl_version = 330; -extern "C" void -_mesa_error_no_memory(const char *caller) -{ - fprintf(stderr, "Mesa error: out of memory in %s", caller); -} - static void initialize_context(struct gl_context *ctx, gl_api api) { @@ -282,7 +276,7 @@ usage_fail(const char *name) "usage: %s [options] <file.vert | file.geom | file.frag>\n" "\n" "Possible options are:\n"; - printf(header, name, name); + printf(header, name); for (const struct option *o = compiler_opts; o->name != 0; ++o) { printf(" --%s\n", o->name); } diff --git a/mesalib/src/glsl/nir/glsl_to_nir.cpp b/mesalib/src/glsl/nir/glsl_to_nir.cpp index af758ceb0..95531bbcd 100644 --- a/mesalib/src/glsl/nir/glsl_to_nir.cpp +++ b/mesalib/src/glsl/nir/glsl_to_nir.cpp @@ -65,6 +65,7 @@ public: virtual void visit(ir_dereference_variable *); virtual void visit(ir_dereference_record *); virtual void visit(ir_dereference_array *); + virtual void visit(ir_barrier *); void create_function(ir_function *ir); @@ -930,13 +931,9 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir) } nir_dest *dest = get_instr_dest(this->result); - assert(dest->is_ssa); - nir_src src = NIR_SRC_INIT; - src.is_ssa = true; - src.ssa = &dest->ssa; - return src; + return nir_src_for_ssa(&dest->ssa); } nir_alu_instr * @@ -1893,3 +1890,11 @@ nir_visitor::visit(ir_dereference_array *ir) ralloc_steal(this->deref_tail, deref); this->deref_tail = &deref->deref; } + +void +nir_visitor::visit(ir_barrier *ir) +{ + nir_intrinsic_instr *instr = + nir_intrinsic_instr_create(this->shader, nir_intrinsic_barrier); + nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr); +} diff --git a/mesalib/src/glsl/nir/nir_intrinsics.h b/mesalib/src/glsl/nir/nir_intrinsics.h index 10192c531..bc6e6b8f4 100644 --- a/mesalib/src/glsl/nir/nir_intrinsics.h +++ b/mesalib/src/glsl/nir/nir_intrinsics.h @@ -67,6 +67,7 @@ INTRINSIC(interp_var_at_offset, 1, ARR(2), true, 0, 1, 0, */ #define BARRIER(name) INTRINSIC(name, 0, ARR(), false, 0, 0, 0, 0) +BARRIER(barrier) BARRIER(discard) /* @@ -138,12 +139,11 @@ SYSTEM_VALUE(sample_mask_in, 1) SYSTEM_VALUE(invocation_id, 1) /* - * The first index is the address to load from, and the second index is the - * number of array elements to load. Indirect loads have an additional - * register input, which is added to the constant address to compute the - * final address to load from. For UBO's (and SSBO's), the first source is - * the (possibly constant) UBO buffer index and the indirect (if it exists) - * is the second source. + * The first and only index is the base address to load from. Indirect + * loads have an additional register input, which is added to the constant + * address to compute the final address to load from. For UBO's (and + * SSBO's), the first source is the (possibly constant) UBO buffer index + * and the indirect (if it exists) is the second source. * * For vector backends, the address is in terms of one vec4, and so each array * element is +4 scalar components from the previous array element. For scalar @@ -152,9 +152,9 @@ SYSTEM_VALUE(invocation_id, 1) */ #define LOAD(name, extra_srcs, flags) \ - INTRINSIC(load_##name, extra_srcs, ARR(1), true, 0, 0, 2, flags) \ + INTRINSIC(load_##name, extra_srcs, ARR(1), true, 0, 0, 1, flags) \ INTRINSIC(load_##name##_indirect, extra_srcs + 1, ARR(1, 1), \ - true, 0, 0, 2, flags) + true, 0, 0, 1, flags) LOAD(uniform, 0, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) LOAD(ubo, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) @@ -172,7 +172,7 @@ LOAD(input, 0, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) INTRINSIC(store_##name##_indirect, 2, ARR(0, 1), false, 0, 0, \ num_indices, flags) \ -STORE(output, 2, 0) -/* STORE(ssbo, 3, 0) */ +STORE(output, 1, 0) +/* STORE(ssbo, 2, 0) */ LAST_INTRINSIC(store_output_indirect) diff --git a/mesalib/src/glsl/nir/nir_lower_atomics.c b/mesalib/src/glsl/nir/nir_lower_atomics.c index f6f89020f..0457de60d 100644 --- a/mesalib/src/glsl/nir/nir_lower_atomics.c +++ b/mesalib/src/glsl/nir/nir_lower_atomics.c @@ -109,7 +109,7 @@ lower_instr(nir_intrinsic_instr *instr, nir_function_impl *impl) } new_instr->src[0].is_ssa = true; - new_instr->src[0].ssa = offset_def;; + new_instr->src[0].ssa = offset_def; if (instr->dest.is_ssa) { nir_ssa_dest_init(&new_instr->instr, &new_instr->dest, diff --git a/mesalib/src/glsl/nir/nir_lower_io.c b/mesalib/src/glsl/nir/nir_lower_io.c index 03eed04e1..6761d5bad 100644 --- a/mesalib/src/glsl/nir/nir_lower_io.c +++ b/mesalib/src/glsl/nir/nir_lower_io.c @@ -288,7 +288,6 @@ nir_lower_io_block(nir_block *block, void *void_state) offset += intrin->variables[0]->var->data.driver_location; load->const_index[0] = offset; - load->const_index[1] = 1; if (has_indirect) load->src[0] = indirect; @@ -331,7 +330,6 @@ nir_lower_io_block(nir_block *block, void *void_state) offset += intrin->variables[0]->var->data.driver_location; store->const_index[0] = offset; - store->const_index[1] = 1; nir_src_copy(&store->src[0], &intrin->src[0], state->mem_ctx); diff --git a/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c b/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c index 4bdb80072..a57d25397 100644 --- a/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c +++ b/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c @@ -153,6 +153,11 @@ should_lower_phi(nir_phi_instr *phi, struct lower_phis_to_scalar_state *state) break; } + /* The hash table entry for 'phi' may have changed while recursing the + * dependence graph, so we need to reset it */ + entry = _mesa_hash_table_search(state->phi_table, phi); + assert(entry); + entry->data = (void *)(intptr_t)scalarizable; return scalarizable; diff --git a/mesalib/src/glsl/nir/nir_opt_algebraic.py b/mesalib/src/glsl/nir/nir_opt_algebraic.py index fa039222f..eace791f5 100644 --- a/mesalib/src/glsl/nir/nir_opt_algebraic.py +++ b/mesalib/src/glsl/nir/nir_opt_algebraic.py @@ -156,6 +156,8 @@ optimizations = [ (('fpow', a, 2.0), ('fmul', a, a)), (('fpow', a, 4.0), ('fmul', ('fmul', a, a), ('fmul', a, a))), (('fpow', 2.0, a), ('fexp2', a)), + (('fpow', ('fpow', a, 2.2), 0.454545), a), + (('fpow', ('fabs', ('fpow', a, 2.2)), 0.454545), ('fabs', a)), (('fsqrt', ('fexp2', a)), ('fexp2', ('fmul', 0.5, a))), (('frcp', ('fexp2', a)), ('fexp2', ('fneg', a))), (('frsq', ('fexp2', a)), ('fexp2', ('fmul', -0.5, a))), diff --git a/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c b/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c index b430eac8e..798506b75 100644 --- a/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c +++ b/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c @@ -73,7 +73,8 @@ are_all_uses_fadd(nir_ssa_def *def) } static nir_alu_instr * -get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs) +get_mul_for_src(nir_alu_src *src, int num_components, + uint8_t swizzle[4], bool *negate, bool *abs) { assert(src->src.is_ssa && !src->abs && !src->negate); @@ -85,16 +86,16 @@ get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs) switch (alu->op) { case nir_op_imov: case nir_op_fmov: - alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs); + alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs); break; case nir_op_fneg: - alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs); + alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs); *negate = !*negate; break; case nir_op_fabs: - alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs); + alu = get_mul_for_src(&alu->src[0], num_components, swizzle, negate, abs); *negate = false; *abs = true; break; @@ -115,12 +116,8 @@ get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs) if (!alu) return NULL; - for (unsigned i = 0; i < 4; i++) { - if (!(alu->dest.write_mask & (1 << i))) - break; - + for (unsigned i = 0; i < num_components; i++) swizzle[i] = swizzle[src->swizzle[i]]; - } return alu; } @@ -160,7 +157,9 @@ nir_opt_peephole_ffma_block(nir_block *block, void *void_state) negate = false; abs = false; - mul = get_mul_for_src(&add->src[add_mul_src], swizzle, &negate, &abs); + mul = get_mul_for_src(&add->src[add_mul_src], + add->dest.dest.ssa.num_components, + swizzle, &negate, &abs); if (mul != NULL) break; diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index a109c4e92..00db61e40 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -89,7 +89,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) { unsigned i; - shProg->NumUserUniformStorage = 0; + shProg->NumUniformStorage = 0; shProg->UniformStorage = NULL; shProg->NumUniformRemapTable = 0; shProg->UniformRemapTable = NULL; |