X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir_validate.cpp;h=6d5633916ba2fe40d6805d0971c96b2ec863ede9;hb=c5be9c126d6ca9380cd381a5eb22554e4bb71a64;hp=d6abc8eb5a828eca79574c3f8fdb6fb49c8af22b;hpb=06e41a02a3564b00404dd3dd5d6f6b5897df36e9;p=mesa.git diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index d6abc8eb5a8..6d5633916ba 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -49,8 +49,8 @@ public: this->current_function = NULL; - this->callback = ir_validate::validate_ir; - this->data = ht; + this->callback_enter = ir_validate::validate_ir; + this->data_enter = ht; } ~ir_validate() @@ -63,7 +63,6 @@ public: 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); virtual ir_visitor_status visit_leave(ir_function *ir); virtual ir_visitor_status visit_enter(ir_function_signature *ir); @@ -101,7 +100,7 @@ ir_validate::visit(ir_dereference_variable *ir) abort(); } - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); return visit_continue; } @@ -148,42 +147,6 @@ ir_validate::visit_enter(ir_if *ir) } -ir_visitor_status -ir_validate::visit_leave(ir_loop *ir) -{ - if (ir->counter != NULL) { - if ((ir->from == NULL) || (ir->to == NULL) || (ir->increment == NULL)) { - printf("ir_loop has invalid loop controls:\n" - " counter: %p\n" - " from: %p\n" - " to: %p\n" - " increment: %p\n", - (void *) ir->counter, (void *) ir->from, (void *) ir->to, - (void *) ir->increment); - abort(); - } - - if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) { - printf("ir_loop has invalid comparitor %d\n", ir->cmp); - abort(); - } - } else { - if ((ir->from != NULL) || (ir->to != NULL) || (ir->increment != NULL)) { - printf("ir_loop has invalid loop controls:\n" - " counter: %p\n" - " from: %p\n" - " to: %p\n" - " increment: %p\n", - (void *) ir->counter, (void *) ir->from, (void *) ir->to, - (void *) ir->increment); - abort(); - } - } - - return visit_continue; -} - - ir_visitor_status ir_validate::visit_enter(ir_function *ir) { @@ -204,14 +167,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); @@ -250,7 +211,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; } @@ -280,6 +241,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; @@ -356,7 +318,11 @@ ir_validate::visit_leave(ir_expression *ir) 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; @@ -410,6 +376,11 @@ 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_binop_add: case ir_binop_sub: case ir_binop_mul: @@ -418,6 +389,9 @@ ir_validate::visit_leave(ir_expression *ir) case ir_binop_min: case ir_binop_max: case ir_binop_pow: + assert(ir->operands[0]->type->base_type == + ir->operands[1]->type->base_type); + if (ir->operands[0]->type->is_scalar()) assert(ir->operands[1]->type == ir->type); else if (ir->operands[1]->type->is_scalar()) @@ -526,7 +500,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); @@ -546,6 +519,19 @@ 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 == ir->operands[0]->type); @@ -668,7 +654,7 @@ 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); @@ -679,21 +665,54 @@ ir_validate::visit(ir_variable *ir) * to be out of bounds. */ if (ir->type->array_size() > 0) { - if (ir->max_array_access >= ir->type->length) { + if (ir->data.max_array_access >= ir->type->length) { printf("ir_variable has maximum access out of bounds (%d vs %d)\n", - ir->max_array_access, ir->type->length - 1); + ir->data.max_array_access, ir->type->length - 1); ir->print(); abort(); } } - if (ir->constant_initializer != NULL && !ir->has_initializer) { + /* If a variable is an interface block (or an array of interface blocks), + * verify that the maximum array index for each interface member is in + * bounds. + */ + if (ir->is_interface_instance()) { + const glsl_struct_field *fields = + ir->get_interface_type()->fields.structure; + for (unsigned i = 0; i < ir->get_interface_type()->length; i++) { + if (fields[i].type->array_size() > 0) { + 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, + max_ifc_array_access[i], fields[i].type->length); + ir->print(); + abort(); + } + } + } + } + + if (ir->constant_initializer != NULL && !ir->data.has_initializer) { printf("ir_variable didn't have an initializer, but has a constant " "initializer value.\n"); ir->print(); 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; } @@ -724,7 +743,7 @@ ir_validate::visit_enter(ir_assignment *ir) } } - this->validate_ir(ir, this->data); + this->validate_ir(ir, this->data_enter); return visit_continue; } @@ -769,8 +788,8 @@ ir_validate::visit_enter(ir_call *ir) printf("ir_call parameter type mismatch:\n"); goto dump_ir; } - if (formal_param->mode == ir_var_function_out - || formal_param->mode == ir_var_function_inout) { + if (formal_param->data.mode == ir_var_function_out + || formal_param->data.mode == ir_var_function_inout) { if (!actual_param->is_lvalue()) { printf("ir_call out/inout parameters must be lvalues:\n"); goto dump_ir; @@ -809,7 +828,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"); } @@ -830,9 +849,7 @@ validate_ir_tree(exec_list *instructions) v.run(instructions); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - + foreach_in_list(ir_instruction, ir, instructions) { visit_tree(ir, check_node_type, NULL); } #endif