X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir_validate.cpp;h=3f0dea74e27b76f844a3da9c296e75d7d12b1f72;hb=e16531fbe3a79bc27cf00701616a260b452597ef;hp=71defc8159306cdea63cee25e7ea8f33c0c1089a;hpb=40d9337406709d0e5e143c51dc5d57921a91aab9;p=mesa.git diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 71defc81593..3f0dea74e27 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -35,7 +35,8 @@ #include "ir.h" #include "ir_hierarchical_visitor.h" -#include "program/hash_table.h" +#include "util/hash_table.h" +#include "util/set.h" #include "glsl_types.h" namespace { @@ -44,23 +45,24 @@ class ir_validate : public ir_hierarchical_visitor { public: ir_validate() { - this->ht = hash_table_ctor(0, hash_table_pointer_hash, - hash_table_pointer_compare); + this->ir_set = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); this->current_function = NULL; - this->callback = ir_validate::validate_ir; - this->data = ht; + this->callback_enter = ir_validate::validate_ir; + this->data_enter = ir_set; } ~ir_validate() { - hash_table_dtor(this->ht); + _mesa_set_destroy(this->ir_set, NULL); } virtual ir_visitor_status visit(ir_variable *v); virtual ir_visitor_status visit(ir_dereference_variable *ir); + virtual ir_visitor_status visit_enter(ir_discard *ir); virtual ir_visitor_status visit_enter(ir_if *ir); virtual ir_visitor_status visit_enter(ir_function *ir); @@ -79,7 +81,7 @@ public: ir_function *current_function; - struct hash_table *ht; + struct set *ir_set; }; } /* anonymous namespace */ @@ -93,14 +95,14 @@ ir_validate::visit(ir_dereference_variable *ir) abort(); } - if (hash_table_find(ht, ir->var) == NULL) { + if (_mesa_set_search(ir_set, ir->var) == NULL) { printf("ir_dereference_variable @ %p specifies undeclared variable " "`%s' @ %p\n", (void *) ir, ir->var->name, (void *) ir->var); abort(); } - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); return visit_continue; } @@ -132,6 +134,20 @@ ir_validate::visit_enter(class ir_dereference_array *ir) return visit_continue; } +ir_visitor_status +ir_validate::visit_enter(ir_discard *ir) +{ + if (ir->condition && ir->condition->type != glsl_type::bool_type) { + printf("ir_discard condition %s type instead of bool.\n", + ir->condition->type->name); + ir->print(); + printf("\n"); + abort(); + } + + return visit_continue; +} + ir_visitor_status ir_validate::visit_enter(ir_if *ir) { @@ -167,14 +183,12 @@ ir_validate::visit_enter(ir_function *ir) */ this->current_function = ir; - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); /* 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; - + foreach_in_list(ir_instruction, sig, &ir->signatures) { if (sig->ir_type != ir_type_function_signature) { printf("Non-signature in signature list of function `%s'\n", ir->name); @@ -213,7 +227,7 @@ ir_validate::visit_enter(ir_function_signature *ir) abort(); } - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); return visit_continue; } @@ -243,6 +257,7 @@ ir_validate::visit_leave(ir_expression *ir) case ir_unop_log: case ir_unop_exp2: case ir_unop_log2: + case ir_unop_saturate: assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); assert(ir->type == ir->operands[0]->type); break; @@ -314,12 +329,18 @@ ir_validate::visit_leave(ir_expression *ir) case ir_unop_ceil: case ir_unop_floor: case ir_unop_fract: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT || + ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->operands[0]->type == ir->type); + break; case ir_unop_sin: case ir_unop_cos: - case ir_unop_sin_reduced: - case ir_unop_cos_reduced: case ir_unop_dFdx: + case ir_unop_dFdx_coarse: + case ir_unop_dFdx_fine: case ir_unop_dFdy: + case ir_unop_dFdy_coarse: + case ir_unop_dFdy_fine: assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); assert(ir->operands[0]->type == ir->type); break; @@ -337,6 +358,11 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type == glsl_type::vec4_type); break; + case ir_unop_pack_double_2x32: + assert(ir->type == glsl_type::double_type); + assert(ir->operands[0]->type == glsl_type::uvec2_type); + break; + case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_unorm_2x16: case ir_unop_unpack_half_2x16: @@ -356,6 +382,11 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type == glsl_type::uint_type); break; + case ir_unop_unpack_double_2x32: + assert(ir->type == glsl_type::uvec2_type); + assert(ir->operands[0]->type == glsl_type::double_type); + break; + case ir_unop_bitfield_reverse: assert(ir->operands[0]->type == ir->type); assert(ir->type->is_integer()); @@ -373,6 +404,54 @@ ir_validate::visit_leave(ir_expression *ir) /* XXX what can we assert here? */ break; + case ir_unop_interpolate_at_centroid: + assert(ir->operands[0]->type == ir->type); + assert(ir->operands[0]->type->is_float()); + break; + + case ir_unop_d2f: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + break; + case ir_unop_f2d: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type->base_type == GLSL_TYPE_DOUBLE); + break; + case ir_unop_d2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; + case ir_unop_i2d: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_DOUBLE); + break; + case ir_unop_d2u: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_UINT); + break; + case ir_unop_u2d: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); + assert(ir->type->base_type == GLSL_TYPE_DOUBLE); + break; + case ir_unop_d2b: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_BOOL); + break; + + case ir_unop_frexp_sig: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT || + ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_DOUBLE); + break; + case ir_unop_frexp_exp: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT || + ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; + case ir_unop_subroutine_to_int: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; case ir_binop_add: case ir_binop_sub: case ir_binop_mul: @@ -467,14 +546,16 @@ ir_validate::visit_leave(ir_expression *ir) case ir_binop_logic_and: case ir_binop_logic_xor: case ir_binop_logic_or: - assert(ir->type == glsl_type::bool_type); - assert(ir->operands[0]->type == glsl_type::bool_type); - assert(ir->operands[1]->type == glsl_type::bool_type); + assert(ir->type->base_type == GLSL_TYPE_BOOL); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + assert(ir->operands[1]->type->base_type == GLSL_TYPE_BOOL); break; case ir_binop_dot: - assert(ir->type == glsl_type::float_type); - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type == glsl_type::float_type || + ir->type == glsl_type::double_type); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT || + ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); assert(ir->operands[0]->type->is_vector()); assert(ir->operands[0]->type == ir->operands[1]->type); break; @@ -492,7 +573,6 @@ ir_validate::visit_leave(ir_expression *ir) break; case ir_binop_ubo_load: - assert(ir->operands[0]->as_constant()); assert(ir->operands[0]->type == glsl_type::uint_type); assert(ir->operands[1]->type == glsl_type::uint_type); @@ -500,7 +580,8 @@ ir_validate::visit_leave(ir_expression *ir) case ir_binop_ldexp: assert(ir->operands[0]->type == ir->type); - assert(ir->operands[0]->type->is_float()); + assert(ir->operands[0]->type->is_float() || + ir->operands[0]->type->is_double()); assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT); assert(ir->operands[0]->type->components() == ir->operands[1]->type->components()); @@ -512,17 +593,34 @@ ir_validate::visit_leave(ir_expression *ir) && ir->operands[1]->type->is_integer()); break; + case ir_binop_interpolate_at_offset: + assert(ir->operands[0]->type == ir->type); + assert(ir->operands[0]->type->is_float()); + assert(ir->operands[1]->type->components() == 2); + assert(ir->operands[1]->type->is_float()); + break; + + case ir_binop_interpolate_at_sample: + assert(ir->operands[0]->type == ir->type); + assert(ir->operands[0]->type->is_float()); + assert(ir->operands[1]->type == glsl_type::int_type); + break; + case ir_triop_fma: - assert(ir->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type->base_type == GLSL_TYPE_FLOAT || + ir->type->base_type == GLSL_TYPE_DOUBLE); assert(ir->type == ir->operands[0]->type); assert(ir->type == ir->operands[1]->type); assert(ir->type == ir->operands[2]->type); break; case ir_triop_lrp: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT || + ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE); assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type); + assert(ir->operands[2]->type == ir->operands[0]->type || + ir->operands[2]->type == glsl_type::float_type || + ir->operands[2]->type == glsl_type::double_type); break; case ir_triop_csel: @@ -634,11 +732,10 @@ ir_validate::visit(ir_variable *ir) * in the ir_dereference_variable handler to ensure that a variable is * declared before it is dereferenced. */ - if (ir->name) + if (ir->name && ir->is_name_ralloced()) assert(ralloc_parent(ir->name) == ir); - hash_table_insert(ht, ir, ir); - + _mesa_set_add(ir_set, ir); /* If a variable is an array, verify that the maximum array index is in * bounds. There was once an error in AST-to-HIR conversion that set this @@ -662,10 +759,15 @@ ir_validate::visit(ir_variable *ir) ir->get_interface_type()->fields.structure; for (unsigned i = 0; i < ir->get_interface_type()->length; i++) { if (fields[i].type->array_size() > 0) { - if (ir->max_ifc_array_access[i] >= fields[i].type->length) { + const unsigned *const max_ifc_array_access = + ir->get_max_ifc_array_access(); + + assert(max_ifc_array_access != NULL); + + if (max_ifc_array_access[i] >= fields[i].type->length) { printf("ir_variable has maximum access out of bounds for " "field %s (%d vs %d)\n", fields[i].name, - ir->max_ifc_array_access[i], fields[i].type->length); + max_ifc_array_access[i], fields[i].type->length); ir->print(); abort(); } @@ -680,6 +782,14 @@ ir_validate::visit(ir_variable *ir) abort(); } + if (ir->data.mode == ir_var_uniform + && is_gl_identifier(ir->name) + && ir->get_state_slots() == NULL) { + printf("built-in uniform has no state\n"); + ir->print(); + abort(); + } + return visit_continue; } @@ -710,7 +820,7 @@ ir_validate::visit_enter(ir_assignment *ir) } } - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); return visit_continue; } @@ -779,15 +889,15 @@ dump_ir: void ir_validate::validate_ir(ir_instruction *ir, void *data) { - struct hash_table *ht = (struct hash_table *) data; + struct set *ir_set = (struct set *) data; - if (hash_table_find(ht, ir)) { + if (_mesa_set_search(ir_set, ir)) { printf("Instruction node present twice in ir tree:\n"); ir->print(); printf("\n"); abort(); } - hash_table_insert(ht, ir, ir); + _mesa_set_add(ir_set, ir); } void @@ -795,7 +905,7 @@ check_node_type(ir_instruction *ir, void *data) { (void) data; - if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) { + if (ir->ir_type >= ir_type_max) { printf("Instruction node with unset type\n"); ir->print(); printf("\n"); } @@ -816,9 +926,7 @@ validate_ir_tree(exec_list *instructions) v.run(instructions); - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; - + foreach_in_list(ir_instruction, ir, instructions) { visit_tree(ir, check_node_type, NULL); } #endif