From 0b9b391c5a7acb31e5d8061169649043a38d6d0e Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 28 Mar 2011 10:22:02 +0000 Subject: xserver xkeyboard-config mesa git update 28 Mar 2011 --- mesalib/src/glsl/ast_to_hir.cpp | 13 +- mesalib/src/glsl/glsl_parser_extras.h | 4 +- mesalib/src/glsl/ir_print_visitor.cpp | 989 ++++++++++++++-------------- mesalib/src/glsl/ir_print_visitor.h | 29 +- mesalib/src/glsl/ir_validate.cpp | 1139 +++++++++++++++++---------------- mesalib/src/glsl/ir_variable.cpp | 215 ++++--- 6 files changed, 1233 insertions(+), 1156 deletions(-) (limited to 'mesalib/src/glsl') diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index cdb16fd49..9538aa62b 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -1577,7 +1577,7 @@ ast_expression::hir(exec_list *instructions, */ ir_variable *v = array->whole_variable_referenced(); if (v != NULL) - v->max_array_access = array->type->array_size(); + v->max_array_access = array->type->array_size() - 1; } } @@ -2676,17 +2676,24 @@ ast_declarator_list::hir(exec_list *instructions, * preceded by one of these precision qualifiers [...] Literal * constants do not have precision qualifiers. Neither do Boolean * variables. + * + * In GLSL ES, sampler types are also allowed. + * + * From page 87 of the GLSL ES spec: + * "RESOLUTION: Allow sampler types to take a precision qualifier." */ if (this->type->specifier->precision != ast_precision_none && !var->type->is_float() && !var->type->is_integer() + && !(var->type->is_sampler() && state->es_shader) && !(var->type->is_array() && (var->type->fields.array->is_float() || var->type->fields.array->is_integer()))) { _mesa_glsl_error(&loc, state, - "precision qualifiers apply only to floating point " - "and integer types"); + "precision qualifiers apply only to floating point" + "%s types", state->es_shader ? ", integer, and sampler" + : "and integer"); } /* Process the initializer and add its instructions to a temporary diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index b5c016fb3..6df0e160a 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -268,8 +268,8 @@ extern "C" { extern int preprocess(void *ctx, const char **shader, char **info_log, const struct gl_extensions *extensions, int api); -extern void _mesa_destroy_shader_compiler(); -extern void _mesa_destroy_shader_compiler_caches(); +extern void _mesa_destroy_shader_compiler(void); +extern void _mesa_destroy_shader_compiler_caches(void); #ifdef __cplusplus } diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 3c5c4fd20..02f3d8149 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -1,474 +1,515 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "ir_print_visitor.h" -#include "glsl_types.h" -#include "glsl_parser_extras.h" - -static void print_type(const glsl_type *t); - -void -ir_instruction::print(void) const -{ - ir_instruction *deconsted = const_cast(this); - - ir_print_visitor v; - deconsted->accept(&v); -} - -void -_mesa_print_ir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - if (state) { - for (unsigned i = 0; i < state->num_user_structures; i++) { - const glsl_type *const s = state->user_structures[i]; - - printf("(structure (%s) (%s@%p) (%u) (\n", - s->name, s->name, (void *) s, s->length); - - for (unsigned j = 0; j < s->length; j++) { - printf("\t(("); - print_type(s->fields.structure[j].type); - printf(")(%s))\n", s->fields.structure[j].name); - } - - printf(")\n"); - } - } - - printf("(\n"); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir->print(); - if (ir->ir_type != ir_type_function) - printf("\n"); - } - printf("\n)"); -} - - -void ir_print_visitor::indent(void) -{ - for (int i = 0; i < indentation; i++) - printf(" "); -} - -static void -print_type(const glsl_type *t) -{ - if (t->base_type == GLSL_TYPE_ARRAY) { - printf("(array "); - print_type(t->fields.array); - printf(" %u)", t->length); - } else if ((t->base_type == GLSL_TYPE_STRUCT) - && (strncmp("gl_", t->name, 3) != 0)) { - printf("%s@%p", t->name, (void *) t); - } else { - printf("%s", t->name); - } -} - - -void ir_print_visitor::visit(ir_variable *ir) -{ - printf("(declare "); - - const char *const cent = (ir->centroid) ? "centroid " : ""; - const char *const inv = (ir->invariant) ? "invariant " : ""; - const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ", - "const_in ", "sys ", "temporary " }; - const char *const interp[] = { "", "flat", "noperspective" }; - - printf("(%s%s%s%s) ", - cent, inv, mode[ir->mode], interp[ir->interpolation]); - - print_type(ir->type); - printf(" %s@%p)", ir->name, (void *) ir); -} - - -void ir_print_visitor::visit(ir_function_signature *ir) -{ - printf("(signature "); - indentation++; - - print_type(ir->return_type); - printf("\n"); - indent(); - - printf("(parameters\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->parameters) { - ir_variable *const inst = (ir_variable *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - - indent(); - printf(")\n"); - - indent(); - - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->body) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); - indentation--; -} - - -void ir_print_visitor::visit(ir_function *ir) -{ - printf("(function %s\n", ir->name); - indentation++; - foreach_iter(exec_list_iterator, iter, *ir) { - ir_function_signature *const sig = (ir_function_signature *) iter.get(); - indent(); - sig->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf(")\n\n"); -} - - -void ir_print_visitor::visit(ir_expression *ir) -{ - printf("(expression "); - - print_type(ir->type); - - printf(" %s ", ir->operator_string()); - - for (unsigned i = 0; i < ir->get_num_operands(); i++) { - ir->operands[i]->accept(this); - } - - printf(") "); -} - - -void ir_print_visitor::visit(ir_texture *ir) -{ - printf("(%s ", ir->opcode_string()); - - print_type(ir->type); - printf(" "); - - ir->sampler->accept(this); - printf(" "); - - ir->coordinate->accept(this); - - printf(" "); - - if (ir->offset != NULL) { - ir->offset->accept(this); - } else { - printf("0"); - } - - printf(" "); - - if (ir->op != ir_txf) { - if (ir->projector) - ir->projector->accept(this); - else - printf("1"); - - if (ir->shadow_comparitor) { - printf(" "); - ir->shadow_comparitor->accept(this); - } else { - printf(" ()"); - } - } - - printf(" "); - switch (ir->op) - { - case ir_tex: - break; - case ir_txb: - ir->lod_info.bias->accept(this); - break; - case ir_txl: - case ir_txf: - ir->lod_info.lod->accept(this); - break; - case ir_txd: - printf("("); - ir->lod_info.grad.dPdx->accept(this); - printf(" "); - ir->lod_info.grad.dPdy->accept(this); - printf(")"); - break; - }; - printf(")"); -} - - -void ir_print_visitor::visit(ir_swizzle *ir) -{ - const unsigned swiz[4] = { - ir->mask.x, - ir->mask.y, - ir->mask.z, - ir->mask.w, - }; - - printf("(swiz "); - for (unsigned i = 0; i < ir->mask.num_components; i++) { - printf("%c", "xyzw"[swiz[i]]); - } - printf(" "); - ir->val->accept(this); - printf(")"); -} - - -void ir_print_visitor::visit(ir_dereference_variable *ir) -{ - ir_variable *var = ir->variable_referenced(); - printf("(var_ref %s@%p) ", var->name, (void *) var); -} - - -void ir_print_visitor::visit(ir_dereference_array *ir) -{ - printf("(array_ref "); - ir->array->accept(this); - ir->array_index->accept(this); - printf(") "); -} - - -void ir_print_visitor::visit(ir_dereference_record *ir) -{ - printf("(record_ref "); - ir->record->accept(this); - printf(" %s) ", ir->field); -} - - -void ir_print_visitor::visit(ir_assignment *ir) -{ - printf("(assign "); - - if (ir->condition) - ir->condition->accept(this); - - char mask[5]; - unsigned j = 0; - - for (unsigned i = 0; i < 4; i++) { - if ((ir->write_mask & (1 << i)) != 0) { - mask[j] = "xyzw"[i]; - j++; - } - } - mask[j] = '\0'; - - printf(" (%s) ", mask); - - ir->lhs->accept(this); - - printf(" "); - - ir->rhs->accept(this); - printf(") "); -} - - -void ir_print_visitor::visit(ir_constant *ir) -{ - const glsl_type *const base_type = ir->type->get_base_type(); - - printf("(constant "); - print_type(ir->type); - printf(" ("); - - if (ir->type->is_array()) { - for (unsigned i = 0; i < ir->type->length; i++) - ir->get_array_element(i)->accept(this); - } else if (ir->type->is_record()) { - ir_constant *value = (ir_constant *) ir->components.get_head(); - for (unsigned i = 0; i < ir->type->length; i++) { - printf("(%s ", ir->type->fields.structure->name); - value->accept(this); - printf(")"); - - value = (ir_constant *) value->next; - } - } else { - for (unsigned i = 0; i < ir->type->components(); i++) { - if (i != 0) - printf(" "); - switch (base_type->base_type) { - case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break; - case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break; - case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break; - case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break; - default: assert(0); - } - } - } - printf(")) "); -} - - -void -ir_print_visitor::visit(ir_call *ir) -{ - printf("(call %s (", ir->callee_name()); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - inst->accept(this); - } - printf("))\n"); -} - - -void -ir_print_visitor::visit(ir_return *ir) -{ - printf("(return"); - - ir_rvalue *const value = ir->get_value(); - if (value) { - printf(" "); - value->accept(this); - } - - printf(")"); -} - - -void -ir_print_visitor::visit(ir_discard *ir) -{ - printf("(discard "); - - if (ir->condition != NULL) { - printf(" "); - ir->condition->accept(this); - } - - printf(")"); -} - - -void -ir_print_visitor::visit(ir_if *ir) -{ - printf("(if "); - ir->condition->accept(this); - - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->then_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - - indentation--; - indent(); - printf(")\n"); - - indent(); - if (!ir->else_instructions.is_empty()) { - printf("(\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->else_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); - } else { - printf("())\n"); - } -} - - -void -ir_print_visitor::visit(ir_loop *ir) -{ - printf("(loop ("); - if (ir->counter != NULL) - ir->counter->accept(this); - printf(") ("); - if (ir->from != NULL) - ir->from->accept(this); - printf(") ("); - if (ir->to != NULL) - ir->to->accept(this); - printf(") ("); - if (ir->increment != NULL) - ir->increment->accept(this); - printf(") (\n"); - indentation++; - - foreach_iter(exec_list_iterator, iter, ir->body_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - indent(); - inst->accept(this); - printf("\n"); - } - indentation--; - indent(); - printf("))\n"); -} - - -void -ir_print_visitor::visit(ir_loop_jump *ir) -{ - printf("%s", ir->is_break() ? "break" : "continue"); -} +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "ir_print_visitor.h" +#include "glsl_types.h" +#include "glsl_parser_extras.h" + +extern "C" { +#include "program/hash_table.h" +} + +static void print_type(const glsl_type *t); + +void +ir_instruction::print(void) const +{ + ir_instruction *deconsted = const_cast(this); + + ir_print_visitor v; + deconsted->accept(&v); +} + +void +_mesa_print_ir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + if (state) { + for (unsigned i = 0; i < state->num_user_structures; i++) { + const glsl_type *const s = state->user_structures[i]; + + printf("(structure (%s) (%s@%p) (%u) (\n", + s->name, s->name, (void *) s, s->length); + + for (unsigned j = 0; j < s->length; j++) { + printf("\t(("); + print_type(s->fields.structure[j].type); + printf(")(%s))\n", s->fields.structure[j].name); + } + + printf(")\n"); + } + } + + printf("(\n"); + foreach_iter(exec_list_iterator, iter, *instructions) { + ir_instruction *ir = (ir_instruction *)iter.get(); + ir->print(); + if (ir->ir_type != ir_type_function) + printf("\n"); + } + printf("\n)"); +} + +ir_print_visitor::ir_print_visitor() +{ + indentation = 0; + printable_names = + hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare); + symbols = _mesa_symbol_table_ctor(); + mem_ctx = ralloc_context(NULL); +} + +ir_print_visitor::~ir_print_visitor() +{ + hash_table_dtor(printable_names); + _mesa_symbol_table_dtor(symbols); + ralloc_free(mem_ctx); +} + +void ir_print_visitor::indent(void) +{ + for (int i = 0; i < indentation; i++) + printf(" "); +} + +const char * +ir_print_visitor::unique_name(ir_variable *var) +{ + /* Do we already have a name for this variable? */ + const char *name = (const char *) hash_table_find(this->printable_names, var); + if (name != NULL) + return name; + + /* If there's no conflict, just use the original name */ + if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) { + name = var->name; + } else { + static unsigned i = 1; + name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i); + } + hash_table_insert(this->printable_names, (void *) name, var); + _mesa_symbol_table_add_symbol(this->symbols, -1, name, var); + return name; +} + +static void +print_type(const glsl_type *t) +{ + if (t->base_type == GLSL_TYPE_ARRAY) { + printf("(array "); + print_type(t->fields.array); + printf(" %u)", t->length); + } else if ((t->base_type == GLSL_TYPE_STRUCT) + && (strncmp("gl_", t->name, 3) != 0)) { + printf("%s@%p", t->name, (void *) t); + } else { + printf("%s", t->name); + } +} + + +void ir_print_visitor::visit(ir_variable *ir) +{ + printf("(declare "); + + const char *const cent = (ir->centroid) ? "centroid " : ""; + const char *const inv = (ir->invariant) ? "invariant " : ""; + const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ", + "const_in ", "sys ", "temporary " }; + const char *const interp[] = { "", "flat", "noperspective" }; + + printf("(%s%s%s%s) ", + cent, inv, mode[ir->mode], interp[ir->interpolation]); + + print_type(ir->type); + printf(" %s)", unique_name(ir)); +} + + +void ir_print_visitor::visit(ir_function_signature *ir) +{ + _mesa_symbol_table_push_scope(symbols); + printf("(signature "); + indentation++; + + print_type(ir->return_type); + printf("\n"); + indent(); + + printf("(parameters\n"); + indentation++; + + foreach_iter(exec_list_iterator, iter, ir->parameters) { + ir_variable *const inst = (ir_variable *) iter.get(); + + indent(); + inst->accept(this); + printf("\n"); + } + indentation--; + + indent(); + printf(")\n"); + + indent(); + + printf("(\n"); + indentation++; + + foreach_iter(exec_list_iterator, iter, ir->body) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + indent(); + inst->accept(this); + printf("\n"); + } + indentation--; + indent(); + printf("))\n"); + indentation--; + _mesa_symbol_table_pop_scope(symbols); +} + + +void ir_print_visitor::visit(ir_function *ir) +{ + printf("(function %s\n", ir->name); + indentation++; + foreach_iter(exec_list_iterator, iter, *ir) { + ir_function_signature *const sig = (ir_function_signature *) iter.get(); + indent(); + sig->accept(this); + printf("\n"); + } + indentation--; + indent(); + printf(")\n\n"); +} + + +void ir_print_visitor::visit(ir_expression *ir) +{ + printf("(expression "); + + print_type(ir->type); + + printf(" %s ", ir->operator_string()); + + for (unsigned i = 0; i < ir->get_num_operands(); i++) { + ir->operands[i]->accept(this); + } + + printf(") "); +} + + +void ir_print_visitor::visit(ir_texture *ir) +{ + printf("(%s ", ir->opcode_string()); + + print_type(ir->type); + printf(" "); + + ir->sampler->accept(this); + printf(" "); + + ir->coordinate->accept(this); + + printf(" "); + + if (ir->offset != NULL) { + ir->offset->accept(this); + } else { + printf("0"); + } + + printf(" "); + + if (ir->op != ir_txf) { + if (ir->projector) + ir->projector->accept(this); + else + printf("1"); + + if (ir->shadow_comparitor) { + printf(" "); + ir->shadow_comparitor->accept(this); + } else { + printf(" ()"); + } + } + + printf(" "); + switch (ir->op) + { + case ir_tex: + break; + case ir_txb: + ir->lod_info.bias->accept(this); + break; + case ir_txl: + case ir_txf: + ir->lod_info.lod->accept(this); + break; + case ir_txd: + printf("("); + ir->lod_info.grad.dPdx->accept(this); + printf(" "); + ir->lod_info.grad.dPdy->accept(this); + printf(")"); + break; + }; + printf(")"); +} + + +void ir_print_visitor::visit(ir_swizzle *ir) +{ + const unsigned swiz[4] = { + ir->mask.x, + ir->mask.y, + ir->mask.z, + ir->mask.w, + }; + + printf("(swiz "); + for (unsigned i = 0; i < ir->mask.num_components; i++) { + printf("%c", "xyzw"[swiz[i]]); + } + printf(" "); + ir->val->accept(this); + printf(")"); +} + + +void ir_print_visitor::visit(ir_dereference_variable *ir) +{ + ir_variable *var = ir->variable_referenced(); + printf("(var_ref %s) ", unique_name(var)); +} + + +void ir_print_visitor::visit(ir_dereference_array *ir) +{ + printf("(array_ref "); + ir->array->accept(this); + ir->array_index->accept(this); + printf(") "); +} + + +void ir_print_visitor::visit(ir_dereference_record *ir) +{ + printf("(record_ref "); + ir->record->accept(this); + printf(" %s) ", ir->field); +} + + +void ir_print_visitor::visit(ir_assignment *ir) +{ + printf("(assign "); + + if (ir->condition) + ir->condition->accept(this); + + char mask[5]; + unsigned j = 0; + + for (unsigned i = 0; i < 4; i++) { + if ((ir->write_mask & (1 << i)) != 0) { + mask[j] = "xyzw"[i]; + j++; + } + } + mask[j] = '\0'; + + printf(" (%s) ", mask); + + ir->lhs->accept(this); + + printf(" "); + + ir->rhs->accept(this); + printf(") "); +} + + +void ir_print_visitor::visit(ir_constant *ir) +{ + const glsl_type *const base_type = ir->type->get_base_type(); + + printf("(constant "); + print_type(ir->type); + printf(" ("); + + if (ir->type->is_array()) { + for (unsigned i = 0; i < ir->type->length; i++) + ir->get_array_element(i)->accept(this); + } else if (ir->type->is_record()) { + ir_constant *value = (ir_constant *) ir->components.get_head(); + for (unsigned i = 0; i < ir->type->length; i++) { + printf("(%s ", ir->type->fields.structure->name); + value->accept(this); + printf(")"); + + value = (ir_constant *) value->next; + } + } else { + for (unsigned i = 0; i < ir->type->components(); i++) { + if (i != 0) + printf(" "); + switch (base_type->base_type) { + case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break; + case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break; + case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break; + case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break; + default: assert(0); + } + } + } + printf(")) "); +} + + +void +ir_print_visitor::visit(ir_call *ir) +{ + printf("(call %s (", ir->callee_name()); + foreach_iter(exec_list_iterator, iter, *ir) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + inst->accept(this); + } + printf("))\n"); +} + + +void +ir_print_visitor::visit(ir_return *ir) +{ + printf("(return"); + + ir_rvalue *const value = ir->get_value(); + if (value) { + printf(" "); + value->accept(this); + } + + printf(")"); +} + + +void +ir_print_visitor::visit(ir_discard *ir) +{ + printf("(discard "); + + if (ir->condition != NULL) { + printf(" "); + ir->condition->accept(this); + } + + printf(")"); +} + + +void +ir_print_visitor::visit(ir_if *ir) +{ + printf("(if "); + ir->condition->accept(this); + + printf("(\n"); + indentation++; + + foreach_iter(exec_list_iterator, iter, ir->then_instructions) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + indent(); + inst->accept(this); + printf("\n"); + } + + indentation--; + indent(); + printf(")\n"); + + indent(); + if (!ir->else_instructions.is_empty()) { + printf("(\n"); + indentation++; + + foreach_iter(exec_list_iterator, iter, ir->else_instructions) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + indent(); + inst->accept(this); + printf("\n"); + } + indentation--; + indent(); + printf("))\n"); + } else { + printf("())\n"); + } +} + + +void +ir_print_visitor::visit(ir_loop *ir) +{ + printf("(loop ("); + if (ir->counter != NULL) + ir->counter->accept(this); + printf(") ("); + if (ir->from != NULL) + ir->from->accept(this); + printf(") ("); + if (ir->to != NULL) + ir->to->accept(this); + printf(") ("); + if (ir->increment != NULL) + ir->increment->accept(this); + printf(") (\n"); + indentation++; + + foreach_iter(exec_list_iterator, iter, ir->body_instructions) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + indent(); + inst->accept(this); + printf("\n"); + } + indentation--; + indent(); + printf("))\n"); +} + + +void +ir_print_visitor::visit(ir_loop_jump *ir) +{ + printf("%s", ir->is_break() ? "break" : "continue"); +} diff --git a/mesalib/src/glsl/ir_print_visitor.h b/mesalib/src/glsl/ir_print_visitor.h index 4feeb8c18..c7136f11a 100644 --- a/mesalib/src/glsl/ir_print_visitor.h +++ b/mesalib/src/glsl/ir_print_visitor.h @@ -29,6 +29,10 @@ #include "ir.h" #include "ir_visitor.h" +extern "C" { +#include "program/symbol_table.h" +} + extern void _mesa_print_ir(exec_list *instructions, struct _mesa_glsl_parse_state *state); @@ -37,15 +41,8 @@ extern void _mesa_print_ir(exec_list *instructions, */ class ir_print_visitor : public ir_visitor { public: - ir_print_visitor() - { - indentation = 0; - } - - virtual ~ir_print_visitor() - { - /* empty */ - } + ir_print_visitor(); + virtual ~ir_print_visitor(); void indent(void); @@ -77,6 +74,20 @@ public: /*@}*/ private: + /** + * Fetch/generate a unique name for ir_variable. + * + * GLSL IR permits multiple ir_variables to share the same name. This works + * fine until we try to print it, when we really need a unique one. + */ + const char *unique_name(ir_variable *var); + + /** A mapping from ir_variable * -> unique printable names. */ + hash_table *printable_names; + _mesa_symbol_table *symbols; + + void *mem_ctx; + int indentation; }; diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index fe6ef8145..ec79d05ca 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -1,562 +1,577 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_validate.cpp - * - * Attempts to verify that various invariants of the IR tree are true. - * - * In particular, at the moment it makes sure that no single - * ir_instruction node except for ir_variable appears multiple times - * in the ir tree. ir_variable does appear multiple times: Once as a - * declaration in an exec_list, and multiple times as the endpoint of - * a dereference chain. - */ - -#include -#include "ir.h" -#include "ir_hierarchical_visitor.h" -#include "program/hash_table.h" -#include "glsl_types.h" - -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->current_function = NULL; - - this->callback = ir_validate::validate_ir; - this->data = ht; - } - - ~ir_validate() - { - hash_table_dtor(this->ht); - } - - 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_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); - - virtual ir_visitor_status visit_leave(ir_expression *ir); - virtual ir_visitor_status visit_leave(ir_swizzle *ir); - - virtual ir_visitor_status visit_enter(ir_assignment *ir); - virtual ir_visitor_status visit_enter(ir_call *ir); - - static void validate_ir(ir_instruction *ir, void *data); - - ir_function *current_function; - - struct hash_table *ht; -}; - - -ir_visitor_status -ir_validate::visit(ir_dereference_variable *ir) -{ - if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) { - printf("ir_dereference_variable @ %p does not specify a variable %p\n", - (void *) ir, (void *) ir->var); - abort(); - } - - if (hash_table_find(ht, 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); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit(ir_if *ir) -{ - if (ir->condition->type != glsl_type::bool_type) { - printf("ir_if 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_leave(ir_loop *ir) -{ - if (ir->counter != NULL) { - if ((ir->from == NULL) || (ir->from == 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->from != 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) -{ - /* Function definitions cannot be nested. - */ - if (this->current_function != NULL) { - printf("Function definition nested inside another function " - "definition:\n"); - printf("%s %p inside %s %p\n", - ir->name, (void *) ir, - this->current_function->name, (void *) this->current_function); - abort(); - } - - /* Store the current function hierarchy being traversed. This is used - * by the function signature visitor to ensure that the signatures are - * linked with the correct functions. - */ - this->current_function = ir; - - this->validate_ir(ir, this->data); - - /* Verify that all of the things stored in the list of signatures are, - * in fact, function signatures. - */ - foreach_list(node, &ir->signatures) { - ir_instruction *sig = (ir_instruction *) node; - - if (sig->ir_type != ir_type_function_signature) { - printf("Non-signature in signature list of function `%s'\n", - ir->name); - abort(); - } - } - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_leave(ir_function *ir) -{ - assert(ralloc_parent(ir->name) == ir); - - this->current_function = NULL; - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_enter(ir_function_signature *ir) -{ - if (this->current_function != ir->function()) { - printf("Function signature nested inside wrong function " - "definition:\n"); - printf("%p inside %s %p instead of %s %p\n", - (void *) ir, - this->current_function->name, (void *) this->current_function, - ir->function_name(), (void *) ir->function()); - abort(); - } - - if (ir->return_type == NULL) { - printf("Function signature %p for function %s has NULL return type.\n", - (void *) ir, ir->function_name()); - abort(); - } - - this->validate_ir(ir, this->data); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_leave(ir_expression *ir) -{ - switch (ir->operation) { - case ir_unop_bit_not: - assert(ir->operands[0]->type == ir->type); - break; - case ir_unop_logic_not: - assert(ir->type->base_type == GLSL_TYPE_BOOL); - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - break; - - case ir_unop_neg: - case ir_unop_abs: - case ir_unop_sign: - case ir_unop_rcp: - case ir_unop_rsq: - case ir_unop_sqrt: - assert(ir->type == ir->operands[0]->type); - break; - - case ir_unop_exp: - case ir_unop_log: - case ir_unop_exp2: - case ir_unop_log2: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type == ir->operands[0]->type); - break; - - case ir_unop_f2i: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->base_type == GLSL_TYPE_INT); - break; - case ir_unop_i2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - case ir_unop_f2b: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->base_type == GLSL_TYPE_BOOL); - break; - case ir_unop_b2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - case ir_unop_i2b: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); - assert(ir->type->base_type == GLSL_TYPE_BOOL); - break; - case ir_unop_b2i: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->base_type == GLSL_TYPE_INT); - break; - case ir_unop_u2f: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - break; - - case ir_unop_any: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type == glsl_type::bool_type); - break; - - case ir_unop_trunc: - case ir_unop_round_even: - case ir_unop_ceil: - case ir_unop_floor: - case ir_unop_fract: - 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_dFdy: - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->operands[0]->type == ir->type); - break; - - case ir_unop_noise: - /* XXX what can we assert here? */ - break; - - case ir_binop_add: - case ir_binop_sub: - case ir_binop_mul: - case ir_binop_div: - case ir_binop_mod: - case ir_binop_min: - case ir_binop_max: - case ir_binop_pow: - if (ir->operands[0]->type->is_scalar()) - assert(ir->operands[1]->type == ir->type); - else if (ir->operands[1]->type->is_scalar()) - assert(ir->operands[0]->type == ir->type); - else if (ir->operands[0]->type->is_vector() && - ir->operands[1]->type->is_vector()) { - assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->operands[0]->type == ir->type); - } - break; - - case ir_binop_less: - case ir_binop_greater: - case ir_binop_lequal: - case ir_binop_gequal: - case ir_binop_equal: - case ir_binop_nequal: - /* The semantics of the IR operators differ from the GLSL <, >, <=, >=, - * ==, and != operators. The IR operators perform a component-wise - * comparison on scalar or vector types and return a boolean scalar or - * vector type of the same size. - */ - assert(ir->type->base_type == GLSL_TYPE_BOOL); - assert(ir->operands[0]->type == ir->operands[1]->type); - assert(ir->operands[0]->type->is_vector() - || ir->operands[0]->type->is_scalar()); - assert(ir->operands[0]->type->vector_elements - == ir->type->vector_elements); - break; - - case ir_binop_all_equal: - case ir_binop_any_nequal: - /* GLSL == and != operate on scalars, vectors, matrices and arrays, and - * return a scalar boolean. The IR matches that. - */ - assert(ir->type == glsl_type::bool_type); - assert(ir->operands[0]->type == ir->operands[1]->type); - break; - - case ir_binop_lshift: - case ir_binop_rshift: - assert(ir->operands[0]->type->is_integer() && - ir->operands[1]->type->is_integer()); - if (ir->operands[0]->type->is_scalar()) { - assert(ir->operands[1]->type->is_scalar()); - } - if (ir->operands[0]->type->is_vector() && - ir->operands[1]->type->is_vector()) { - assert(ir->operands[0]->type->components() == - ir->operands[1]->type->components()); - } - assert(ir->type == ir->operands[0]->type); - break; - - case ir_binop_bit_and: - case ir_binop_bit_xor: - case ir_binop_bit_or: - assert(ir->operands[0]->type->base_type == - ir->operands[1]->type->base_type); - assert(ir->type->is_integer()); - if (ir->operands[0]->type->is_vector() && - ir->operands[1]->type->is_vector()) { - assert(ir->operands[0]->type->vector_elements == - ir->operands[1]->type->vector_elements); - } - break; - - 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); - break; - - case ir_binop_dot: - assert(ir->type == glsl_type::float_type); - assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->operands[0]->type->is_vector()); - assert(ir->operands[0]->type == ir->operands[1]->type); - break; - - case ir_quadop_vector: - /* The vector operator collects some number of scalars and generates a - * vector from them. - * - * - All of the operands must be scalar. - * - Number of operands must matche the size of the resulting vector. - * - Base type of the operands must match the base type of the result. - */ - assert(ir->type->is_vector()); - switch (ir->type->vector_elements) { - case 2: - assert(ir->operands[0]->type->is_scalar()); - assert(ir->operands[0]->type->base_type == ir->type->base_type); - assert(ir->operands[1]->type->is_scalar()); - assert(ir->operands[1]->type->base_type == ir->type->base_type); - assert(ir->operands[2] == NULL); - assert(ir->operands[3] == NULL); - break; - case 3: - assert(ir->operands[0]->type->is_scalar()); - assert(ir->operands[0]->type->base_type == ir->type->base_type); - assert(ir->operands[1]->type->is_scalar()); - assert(ir->operands[1]->type->base_type == ir->type->base_type); - assert(ir->operands[2]->type->is_scalar()); - assert(ir->operands[2]->type->base_type == ir->type->base_type); - assert(ir->operands[3] == NULL); - break; - case 4: - assert(ir->operands[0]->type->is_scalar()); - assert(ir->operands[0]->type->base_type == ir->type->base_type); - assert(ir->operands[1]->type->is_scalar()); - assert(ir->operands[1]->type->base_type == ir->type->base_type); - assert(ir->operands[2]->type->is_scalar()); - assert(ir->operands[2]->type->base_type == ir->type->base_type); - assert(ir->operands[3]->type->is_scalar()); - assert(ir->operands[3]->type->base_type == ir->type->base_type); - break; - default: - /* The is_vector assertion above should prevent execution from ever - * getting here. - */ - assert(!"Should not get here."); - break; - } - } - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_leave(ir_swizzle *ir) -{ - int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w}; - - for (unsigned int i = 0; i < ir->type->vector_elements; i++) { - if (chans[i] >= ir->val->type->vector_elements) { - printf("ir_swizzle @ %p specifies a channel not present " - "in the value.\n", (void *) ir); - ir->print(); - abort(); - } - } - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit(ir_variable *ir) -{ - /* An ir_variable is the one thing that can (and will) appear multiple times - * in an IR tree. It is added to the hashtable so that it can be used - * in the ir_dereference_variable handler to ensure that a variable is - * declared before it is dereferenced. - */ - if (ir->name) - assert(ralloc_parent(ir->name) == ir); - - hash_table_insert(ht, ir, ir); - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_enter(ir_assignment *ir) -{ - const ir_dereference *const lhs = ir->lhs; - if (lhs->type->is_scalar() || lhs->type->is_vector()) { - if (ir->write_mask == 0) { - printf("Assignment LHS is %s, but write mask is 0:\n", - lhs->type->is_scalar() ? "scalar" : "vector"); - ir->print(); - abort(); - } - - int lhs_components = 0; - for (int i = 0; i < 4; i++) { - if (ir->write_mask & (1 << i)) - lhs_components++; - } - - if (lhs_components != ir->rhs->type->vector_elements) { - printf("Assignment count of LHS write mask channels enabled not\n" - "matching RHS vector size (%d LHS, %d RHS).\n", - lhs_components, ir->rhs->type->vector_elements); - ir->print(); - abort(); - } - } - - this->validate_ir(ir, this->data); - - return visit_continue; -} - -ir_visitor_status -ir_validate::visit_enter(ir_call *ir) -{ - ir_function_signature *const callee = ir->get_callee(); - - if (callee->ir_type != ir_type_function_signature) { - printf("IR called by ir_call is not ir_function_signature!\n"); - abort(); - } - - return visit_continue; -} - -void -ir_validate::validate_ir(ir_instruction *ir, void *data) -{ - struct hash_table *ht = (struct hash_table *) data; - - if (hash_table_find(ht, ir)) { - printf("Instruction node present twice in ir tree:\n"); - ir->print(); - printf("\n"); - abort(); - } - hash_table_insert(ht, ir, ir); -} - -void -check_node_type(ir_instruction *ir, void *data) -{ - (void) data; - - if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) { - printf("Instruction node with unset type\n"); - ir->print(); printf("\n"); - } - assert(ir->type != glsl_type::error_type); -} - -void -validate_ir_tree(exec_list *instructions) -{ - ir_validate v; - - v.run(instructions); - - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - - visit_tree(ir, check_node_type, NULL); - } -} +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ir_validate.cpp + * + * Attempts to verify that various invariants of the IR tree are true. + * + * In particular, at the moment it makes sure that no single + * ir_instruction node except for ir_variable appears multiple times + * in the ir tree. ir_variable does appear multiple times: Once as a + * declaration in an exec_list, and multiple times as the endpoint of + * a dereference chain. + */ + +#include +#include "ir.h" +#include "ir_hierarchical_visitor.h" +#include "program/hash_table.h" +#include "glsl_types.h" + +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->current_function = NULL; + + this->callback = ir_validate::validate_ir; + this->data = ht; + } + + ~ir_validate() + { + hash_table_dtor(this->ht); + } + + 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_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); + + virtual ir_visitor_status visit_leave(ir_expression *ir); + virtual ir_visitor_status visit_leave(ir_swizzle *ir); + + virtual ir_visitor_status visit_enter(ir_assignment *ir); + virtual ir_visitor_status visit_enter(ir_call *ir); + + static void validate_ir(ir_instruction *ir, void *data); + + ir_function *current_function; + + struct hash_table *ht; +}; + + +ir_visitor_status +ir_validate::visit(ir_dereference_variable *ir) +{ + if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) { + printf("ir_dereference_variable @ %p does not specify a variable %p\n", + (void *) ir, (void *) ir->var); + abort(); + } + + if (hash_table_find(ht, 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); + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit(ir_if *ir) +{ + if (ir->condition->type != glsl_type::bool_type) { + printf("ir_if 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_leave(ir_loop *ir) +{ + if (ir->counter != NULL) { + if ((ir->from == NULL) || (ir->from == 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->from != 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) +{ + /* Function definitions cannot be nested. + */ + if (this->current_function != NULL) { + printf("Function definition nested inside another function " + "definition:\n"); + printf("%s %p inside %s %p\n", + ir->name, (void *) ir, + this->current_function->name, (void *) this->current_function); + abort(); + } + + /* Store the current function hierarchy being traversed. This is used + * by the function signature visitor to ensure that the signatures are + * linked with the correct functions. + */ + this->current_function = ir; + + this->validate_ir(ir, this->data); + + /* Verify that all of the things stored in the list of signatures are, + * in fact, function signatures. + */ + foreach_list(node, &ir->signatures) { + ir_instruction *sig = (ir_instruction *) node; + + if (sig->ir_type != ir_type_function_signature) { + printf("Non-signature in signature list of function `%s'\n", + ir->name); + abort(); + } + } + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_leave(ir_function *ir) +{ + assert(ralloc_parent(ir->name) == ir); + + this->current_function = NULL; + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_enter(ir_function_signature *ir) +{ + if (this->current_function != ir->function()) { + printf("Function signature nested inside wrong function " + "definition:\n"); + printf("%p inside %s %p instead of %s %p\n", + (void *) ir, + this->current_function->name, (void *) this->current_function, + ir->function_name(), (void *) ir->function()); + abort(); + } + + if (ir->return_type == NULL) { + printf("Function signature %p for function %s has NULL return type.\n", + (void *) ir, ir->function_name()); + abort(); + } + + this->validate_ir(ir, this->data); + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_leave(ir_expression *ir) +{ + switch (ir->operation) { + case ir_unop_bit_not: + assert(ir->operands[0]->type == ir->type); + break; + case ir_unop_logic_not: + assert(ir->type->base_type == GLSL_TYPE_BOOL); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + break; + + case ir_unop_neg: + case ir_unop_abs: + case ir_unop_sign: + case ir_unop_rcp: + case ir_unop_rsq: + case ir_unop_sqrt: + assert(ir->type == ir->operands[0]->type); + break; + + case ir_unop_exp: + case ir_unop_log: + case ir_unop_exp2: + case ir_unop_log2: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type == ir->operands[0]->type); + break; + + case ir_unop_f2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; + case ir_unop_i2f: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + break; + case ir_unop_f2b: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->type->base_type == GLSL_TYPE_BOOL); + break; + case ir_unop_b2f: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + break; + case ir_unop_i2b: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_BOOL); + break; + case ir_unop_b2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; + case ir_unop_u2f: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + break; + + case ir_unop_any: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); + assert(ir->type == glsl_type::bool_type); + break; + + case ir_unop_trunc: + case ir_unop_round_even: + case ir_unop_ceil: + case ir_unop_floor: + case ir_unop_fract: + 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_dFdy: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->operands[0]->type == ir->type); + break; + + case ir_unop_noise: + /* XXX what can we assert here? */ + break; + + case ir_binop_add: + case ir_binop_sub: + case ir_binop_mul: + case ir_binop_div: + case ir_binop_mod: + case ir_binop_min: + case ir_binop_max: + case ir_binop_pow: + if (ir->operands[0]->type->is_scalar()) + assert(ir->operands[1]->type == ir->type); + else if (ir->operands[1]->type->is_scalar()) + assert(ir->operands[0]->type == ir->type); + else if (ir->operands[0]->type->is_vector() && + ir->operands[1]->type->is_vector()) { + assert(ir->operands[0]->type == ir->operands[1]->type); + assert(ir->operands[0]->type == ir->type); + } + break; + + case ir_binop_less: + case ir_binop_greater: + case ir_binop_lequal: + case ir_binop_gequal: + case ir_binop_equal: + case ir_binop_nequal: + /* The semantics of the IR operators differ from the GLSL <, >, <=, >=, + * ==, and != operators. The IR operators perform a component-wise + * comparison on scalar or vector types and return a boolean scalar or + * vector type of the same size. + */ + assert(ir->type->base_type == GLSL_TYPE_BOOL); + assert(ir->operands[0]->type == ir->operands[1]->type); + assert(ir->operands[0]->type->is_vector() + || ir->operands[0]->type->is_scalar()); + assert(ir->operands[0]->type->vector_elements + == ir->type->vector_elements); + break; + + case ir_binop_all_equal: + case ir_binop_any_nequal: + /* GLSL == and != operate on scalars, vectors, matrices and arrays, and + * return a scalar boolean. The IR matches that. + */ + assert(ir->type == glsl_type::bool_type); + assert(ir->operands[0]->type == ir->operands[1]->type); + break; + + case ir_binop_lshift: + case ir_binop_rshift: + assert(ir->operands[0]->type->is_integer() && + ir->operands[1]->type->is_integer()); + if (ir->operands[0]->type->is_scalar()) { + assert(ir->operands[1]->type->is_scalar()); + } + if (ir->operands[0]->type->is_vector() && + ir->operands[1]->type->is_vector()) { + assert(ir->operands[0]->type->components() == + ir->operands[1]->type->components()); + } + assert(ir->type == ir->operands[0]->type); + break; + + case ir_binop_bit_and: + case ir_binop_bit_xor: + case ir_binop_bit_or: + assert(ir->operands[0]->type->base_type == + ir->operands[1]->type->base_type); + assert(ir->type->is_integer()); + if (ir->operands[0]->type->is_vector() && + ir->operands[1]->type->is_vector()) { + assert(ir->operands[0]->type->vector_elements == + ir->operands[1]->type->vector_elements); + } + break; + + 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); + break; + + case ir_binop_dot: + assert(ir->type == glsl_type::float_type); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); + assert(ir->operands[0]->type->is_vector()); + assert(ir->operands[0]->type == ir->operands[1]->type); + break; + + case ir_quadop_vector: + /* The vector operator collects some number of scalars and generates a + * vector from them. + * + * - All of the operands must be scalar. + * - Number of operands must matche the size of the resulting vector. + * - Base type of the operands must match the base type of the result. + */ + assert(ir->type->is_vector()); + switch (ir->type->vector_elements) { + case 2: + assert(ir->operands[0]->type->is_scalar()); + assert(ir->operands[0]->type->base_type == ir->type->base_type); + assert(ir->operands[1]->type->is_scalar()); + assert(ir->operands[1]->type->base_type == ir->type->base_type); + assert(ir->operands[2] == NULL); + assert(ir->operands[3] == NULL); + break; + case 3: + assert(ir->operands[0]->type->is_scalar()); + assert(ir->operands[0]->type->base_type == ir->type->base_type); + assert(ir->operands[1]->type->is_scalar()); + assert(ir->operands[1]->type->base_type == ir->type->base_type); + assert(ir->operands[2]->type->is_scalar()); + assert(ir->operands[2]->type->base_type == ir->type->base_type); + assert(ir->operands[3] == NULL); + break; + case 4: + assert(ir->operands[0]->type->is_scalar()); + assert(ir->operands[0]->type->base_type == ir->type->base_type); + assert(ir->operands[1]->type->is_scalar()); + assert(ir->operands[1]->type->base_type == ir->type->base_type); + assert(ir->operands[2]->type->is_scalar()); + assert(ir->operands[2]->type->base_type == ir->type->base_type); + assert(ir->operands[3]->type->is_scalar()); + assert(ir->operands[3]->type->base_type == ir->type->base_type); + break; + default: + /* The is_vector assertion above should prevent execution from ever + * getting here. + */ + assert(!"Should not get here."); + break; + } + } + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_leave(ir_swizzle *ir) +{ + int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w}; + + for (unsigned int i = 0; i < ir->type->vector_elements; i++) { + if (chans[i] >= ir->val->type->vector_elements) { + printf("ir_swizzle @ %p specifies a channel not present " + "in the value.\n", (void *) ir); + ir->print(); + abort(); + } + } + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit(ir_variable *ir) +{ + /* An ir_variable is the one thing that can (and will) appear multiple times + * in an IR tree. It is added to the hashtable so that it can be used + * in the ir_dereference_variable handler to ensure that a variable is + * declared before it is dereferenced. + */ + if (ir->name) + assert(ralloc_parent(ir->name) == ir); + + hash_table_insert(ht, ir, 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 + * to be out of bounds. + */ + if (ir->type->array_size() > 0) { + if (ir->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->print(); + abort(); + } + } + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_enter(ir_assignment *ir) +{ + const ir_dereference *const lhs = ir->lhs; + if (lhs->type->is_scalar() || lhs->type->is_vector()) { + if (ir->write_mask == 0) { + printf("Assignment LHS is %s, but write mask is 0:\n", + lhs->type->is_scalar() ? "scalar" : "vector"); + ir->print(); + abort(); + } + + int lhs_components = 0; + for (int i = 0; i < 4; i++) { + if (ir->write_mask & (1 << i)) + lhs_components++; + } + + if (lhs_components != ir->rhs->type->vector_elements) { + printf("Assignment count of LHS write mask channels enabled not\n" + "matching RHS vector size (%d LHS, %d RHS).\n", + lhs_components, ir->rhs->type->vector_elements); + ir->print(); + abort(); + } + } + + this->validate_ir(ir, this->data); + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_enter(ir_call *ir) +{ + ir_function_signature *const callee = ir->get_callee(); + + if (callee->ir_type != ir_type_function_signature) { + printf("IR called by ir_call is not ir_function_signature!\n"); + abort(); + } + + return visit_continue; +} + +void +ir_validate::validate_ir(ir_instruction *ir, void *data) +{ + struct hash_table *ht = (struct hash_table *) data; + + if (hash_table_find(ht, ir)) { + printf("Instruction node present twice in ir tree:\n"); + ir->print(); + printf("\n"); + abort(); + } + hash_table_insert(ht, ir, ir); +} + +void +check_node_type(ir_instruction *ir, void *data) +{ + (void) data; + + if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) { + printf("Instruction node with unset type\n"); + ir->print(); printf("\n"); + } + assert(ir->type != glsl_type::error_type); +} + +void +validate_ir_tree(exec_list *instructions) +{ + ir_validate v; + + v.run(instructions); + + foreach_iter(exec_list_iterator, iter, *instructions) { + ir_instruction *ir = (ir_instruction *)iter.get(); + + visit_tree(ir, check_node_type, NULL); + } +} diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp index 18a3e0fb0..68d9ab205 100644 --- a/mesalib/src/glsl/ir_variable.cpp +++ b/mesalib/src/glsl/ir_variable.cpp @@ -36,9 +36,9 @@ generate_ARB_draw_instanced_variables(exec_list *, bool, _mesa_glsl_parser_targets); static ir_variable * -add_variable(const char *name, enum ir_variable_mode mode, int slot, - const glsl_type *type, exec_list *instructions, - glsl_symbol_table *symtab) +add_variable(exec_list *instructions, glsl_symbol_table *symtab, + const char *name, const glsl_type *type, + enum ir_variable_mode mode, int slot) { ir_variable *var = new(symtab) ir_variable(type, name, mode); @@ -71,17 +71,15 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot, } static ir_variable * -add_uniform(exec_list *instructions, - struct _mesa_glsl_parse_state *state, +add_uniform(exec_list *instructions, glsl_symbol_table *symtab, const char *name, const glsl_type *type) { - return add_variable(name, ir_var_uniform, -1, type, instructions, - state->symbols); + return add_variable(instructions, symtab, name, type, ir_var_uniform, -1); } static void -add_builtin_variable(const builtin_variable *proto, exec_list *instructions, - glsl_symbol_table *symtab) +add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab, + const builtin_variable *proto) { /* Create a new variable declaration from the description supplied by * the caller. @@ -90,18 +88,17 @@ add_builtin_variable(const builtin_variable *proto, exec_list *instructions, assert(type != NULL); - add_variable(proto->name, proto->mode, proto->slot, type, instructions, - symtab); + add_variable(instructions, symtab, proto->name, type, proto->mode, + proto->slot); } static void -add_builtin_constant(exec_list *instructions, - struct _mesa_glsl_parse_state *state, +add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab, const char *name, int value) { - ir_variable *const var = add_variable(name, ir_var_auto, - -1, glsl_type::int_type, - instructions, state->symbols); + ir_variable *const var = add_variable(instructions, symtab, + name, glsl_type::int_type, + ir_var_auto, -1); var->constant_value = new(var) ir_constant(value); } @@ -112,22 +109,24 @@ static void generate_100ES_uniforms(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - add_builtin_constant(instructions, state, "gl_MaxVertexAttribs", + glsl_symbol_table *const symtab = state->symbols; + + add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, state, "gl_MaxVertexUniformVectors", + add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors", state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, state, "gl_MaxVaryingVectors", + add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors", state->Const.MaxVaryingFloats / 4); - add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxFragmentUniformVectors", + add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformVectors", state->Const.MaxFragmentUniformComponents); - add_uniform(instructions, state, "gl_DepthRange", + add_uniform(instructions, symtab, "gl_DepthRange", state->symbols->get_type("gl_DepthRangeParameters")); } @@ -135,95 +134,97 @@ static void generate_110_uniforms(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + glsl_symbol_table *const symtab = state->symbols; + for (unsigned i = 0 ; i < Elements(builtin_110_deprecated_uniforms) ; i++) { - add_builtin_variable(& builtin_110_deprecated_uniforms[i], - instructions, state->symbols); + add_builtin_variable(instructions, symtab, + & builtin_110_deprecated_uniforms[i]); } - add_builtin_constant(instructions, state, "gl_MaxLights", + add_builtin_constant(instructions, symtab, "gl_MaxLights", state->Const.MaxLights); - add_builtin_constant(instructions, state, "gl_MaxClipPlanes", + add_builtin_constant(instructions, symtab, "gl_MaxClipPlanes", state->Const.MaxClipPlanes); - add_builtin_constant(instructions, state, "gl_MaxTextureUnits", + add_builtin_constant(instructions, symtab, "gl_MaxTextureUnits", state->Const.MaxTextureUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureCoords", + add_builtin_constant(instructions, symtab, "gl_MaxTextureCoords", state->Const.MaxTextureCoords); - add_builtin_constant(instructions, state, "gl_MaxVertexAttribs", + add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, state, "gl_MaxVertexUniformComponents", + add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformComponents", state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, state, "gl_MaxVaryingFloats", + add_builtin_constant(instructions, symtab, "gl_MaxVaryingFloats", state->Const.MaxVaryingFloats); - add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits", + add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, state, "gl_MaxFragmentUniformComponents", + add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformComponents", state->Const.MaxFragmentUniformComponents); const glsl_type *const mat4_array_type = glsl_type::get_array_instance(glsl_type::mat4_type, state->Const.MaxTextureCoords); - add_uniform(instructions, state, "gl_TextureMatrix", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixInverse", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixTranspose", mat4_array_type); - add_uniform(instructions, state, "gl_TextureMatrixInverseTranspose", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrix", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixInverse", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixTranspose", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixInverseTranspose", mat4_array_type); - add_uniform(instructions, state, "gl_DepthRange", - state->symbols->get_type("gl_DepthRangeParameters")); + add_uniform(instructions, symtab, "gl_DepthRange", + symtab->get_type("gl_DepthRangeParameters")); - add_uniform(instructions, state, "gl_ClipPlane", + add_uniform(instructions, symtab, "gl_ClipPlane", glsl_type::get_array_instance(glsl_type::vec4_type, state->Const.MaxClipPlanes)); - add_uniform(instructions, state, "gl_Point", - state->symbols->get_type("gl_PointParameters")); + add_uniform(instructions, symtab, "gl_Point", + symtab->get_type("gl_PointParameters")); const glsl_type *const material_parameters_type = - state->symbols->get_type("gl_MaterialParameters"); - add_uniform(instructions, state, "gl_FrontMaterial", material_parameters_type); - add_uniform(instructions, state, "gl_BackMaterial", material_parameters_type); + symtab->get_type("gl_MaterialParameters"); + add_uniform(instructions, symtab, "gl_FrontMaterial", material_parameters_type); + add_uniform(instructions, symtab, "gl_BackMaterial", material_parameters_type); const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(state->symbols->get_type("gl_LightSourceParameters"), state->Const.MaxLights); + glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), state->Const.MaxLights); - add_uniform(instructions, state, "gl_LightSource", light_source_array_type); + add_uniform(instructions, symtab, "gl_LightSource", light_source_array_type); const glsl_type *const light_model_products_type = - state->symbols->get_type("gl_LightModelProducts"); - add_uniform(instructions, state, "gl_FrontLightModelProduct", + symtab->get_type("gl_LightModelProducts"); + add_uniform(instructions, symtab, "gl_FrontLightModelProduct", light_model_products_type); - add_uniform(instructions, state, "gl_BackLightModelProduct", + add_uniform(instructions, symtab, "gl_BackLightModelProduct", light_model_products_type); const glsl_type *const light_products_type = - glsl_type::get_array_instance(state->symbols->get_type("gl_LightProducts"), + glsl_type::get_array_instance(symtab->get_type("gl_LightProducts"), state->Const.MaxLights); - add_uniform(instructions, state, "gl_FrontLightProduct", light_products_type); - add_uniform(instructions, state, "gl_BackLightProduct", light_products_type); + add_uniform(instructions, symtab, "gl_FrontLightProduct", light_products_type); + add_uniform(instructions, symtab, "gl_BackLightProduct", light_products_type); - add_uniform(instructions, state, "gl_TextureEnvColor", + add_uniform(instructions, symtab, "gl_TextureEnvColor", glsl_type::get_array_instance(glsl_type::vec4_type, state->Const.MaxTextureUnits)); const glsl_type *const texcoords_vec4 = glsl_type::get_array_instance(glsl_type::vec4_type, state->Const.MaxTextureCoords); - add_uniform(instructions, state, "gl_EyePlaneS", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneT", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneR", texcoords_vec4); - add_uniform(instructions, state, "gl_EyePlaneQ", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneS", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneT", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneR", texcoords_vec4); - add_uniform(instructions, state, "gl_ObjectPlaneQ", texcoords_vec4); - - add_uniform(instructions, state, "gl_Fog", - state->symbols->get_type("gl_FogParameters")); + add_uniform(instructions, symtab, "gl_EyePlaneS", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneT", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneR", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneQ", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneS", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneT", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneR", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneQ", texcoords_vec4); + + add_uniform(instructions, symtab, "gl_Fog", + symtab->get_type("gl_FogParameters")); } /* This function should only be called for ES, not desktop GL. */ @@ -232,8 +233,8 @@ generate_100ES_vs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(& builtin_core_vs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_core_vs_variables[i]); } generate_100ES_uniforms(instructions, state); @@ -248,15 +249,15 @@ generate_110_vs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(& builtin_core_vs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_core_vs_variables[i]); } for (unsigned i = 0 ; i < Elements(builtin_110_deprecated_vs_variables) ; i++) { - add_builtin_variable(& builtin_110_deprecated_vs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_110_deprecated_vs_variables[i]); } generate_110_uniforms(instructions, state); @@ -271,8 +272,8 @@ generate_110_vs_variables(exec_list *instructions, const glsl_type *const vec4_array_type = glsl_type::get_array_instance(glsl_type::vec4_type, 0); - add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type, - instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_TexCoord", vec4_array_type, ir_var_out, VERT_RESULT_TEX0); generate_ARB_draw_buffers_variables(instructions, state, false, vertex_shader); @@ -297,8 +298,8 @@ generate_130_vs_variables(exec_list *instructions, generate_120_vs_variables(instructions, state); for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { - add_builtin_variable(& builtin_130_vs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_130_vs_variables[i]); } const glsl_type *const clip_distance_array_type = @@ -306,8 +307,8 @@ generate_130_vs_variables(exec_list *instructions, state->Const.MaxClipPlanes); /* FINISHME: gl_ClipDistance needs a real location assigned. */ - add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type, - instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_ClipDistance", clip_distance_array_type, ir_var_out, -1); } @@ -344,13 +345,13 @@ generate_100ES_fs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(& builtin_core_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_core_fs_variables[i]); } for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) { - add_builtin_variable(& builtin_100ES_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_100ES_fs_variables[i]); } generate_100ES_uniforms(instructions, state); @@ -364,20 +365,20 @@ generate_110_fs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(& builtin_core_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_core_fs_variables[i]); } for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) { - add_builtin_variable(& builtin_110_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_110_fs_variables[i]); } for (unsigned i = 0 ; i < Elements(builtin_110_deprecated_fs_variables) ; i++) { - add_builtin_variable(& builtin_110_deprecated_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_110_deprecated_fs_variables[i]); } generate_110_uniforms(instructions, state); @@ -392,8 +393,8 @@ generate_110_fs_variables(exec_list *instructions, const glsl_type *const vec4_array_type = glsl_type::get_array_instance(glsl_type::vec4_type, 0); - add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type, - instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_TexCoord", vec4_array_type, ir_var_in, FRAG_ATTRIB_TEX0); generate_ARB_draw_buffers_variables(instructions, state, false, fragment_shader); @@ -408,8 +409,8 @@ generate_ARB_draw_buffers_variables(exec_list *instructions, /* gl_MaxDrawBuffers is available in all shader stages. */ ir_variable *const mdb = - add_variable("gl_MaxDrawBuffers", ir_var_auto, -1, - glsl_type::int_type, instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_MaxDrawBuffers", glsl_type::int_type, ir_var_auto, -1); if (warn) mdb->warn_extension = "GL_ARB_draw_buffers"; @@ -426,8 +427,9 @@ generate_ARB_draw_buffers_variables(exec_list *instructions, state->Const.MaxDrawBuffers); ir_variable *const fd = - add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0, - vec4_array_type, instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_FragData", vec4_array_type, + ir_var_out, FRAG_RESULT_DATA0); if (warn) fd->warn_extension = "GL_ARB_draw_buffers"; @@ -445,9 +447,9 @@ generate_ARB_draw_instanced_variables(exec_list *instructions, */ if (target == vertex_shader) { ir_variable *const inst = - add_variable("gl_InstanceIDARB", ir_var_system_value, - SYSTEM_VALUE_INSTANCE_ID, - glsl_type::int_type, instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_InstanceIDARB", glsl_type::int_type, + ir_var_system_value, SYSTEM_VALUE_INSTANCE_ID); if (warn) inst->warn_extension = "GL_ARB_draw_instanced"; @@ -463,8 +465,9 @@ generate_ARB_shader_stencil_export_variables(exec_list *instructions, /* gl_FragStencilRefARB is only available in the fragment shader. */ ir_variable *const fd = - add_variable("gl_FragStencilRefARB", ir_var_out, FRAG_RESULT_STENCIL, - glsl_type::int_type, instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_FragStencilRefARB", glsl_type::int_type, + ir_var_out, FRAG_RESULT_STENCIL); if (warn) fd->warn_extension = "GL_ARB_shader_stencil_export"; @@ -479,8 +482,8 @@ generate_120_fs_variables(exec_list *instructions, for (unsigned i = 0 ; i < Elements(builtin_120_fs_variables) ; i++) { - add_builtin_variable(& builtin_120_fs_variables[i], - instructions, state->symbols); + add_builtin_variable(instructions, state->symbols, + & builtin_120_fs_variables[i]); } } @@ -495,8 +498,8 @@ generate_130_fs_variables(exec_list *instructions, state->Const.MaxClipPlanes); /* FINISHME: gl_ClipDistance needs a real location assigned. */ - add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type, - instructions, state->symbols); + add_variable(instructions, state->symbols, + "gl_ClipDistance", clip_distance_array_type, ir_var_in, -1); } static void -- cgit v1.2.3