1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_reader.h" 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_parser_extras.h" 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_expression.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst static bool debug = false; 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_reader { 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_reader(_mesa_glsl_parse_state *); 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void read(exec_list *instructions, const char *src, bool scan_for_protos); 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx; 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_parse_state *state; 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void ir_read_error(s_expression *, const char *fmt, ...); 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *read_type(s_expression *); 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void scan_for_prototypes(exec_list *, s_expression *); 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function *read_function(s_expression *, bool skip_body); 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void read_function_sig(ir_function *, s_expression *, bool skip_body); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void read_instructions(exec_list *, s_expression *, ir_loop *); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *read_instruction(s_expression *, ir_loop *); 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *read_declaration(s_expression *); 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *read_if(s_expression *, ir_loop *); 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop *read_loop(s_expression *); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_call *read_call(s_expression *); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_return *read_return(s_expression *); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *read_rvalue(s_expression *); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *read_assignment(s_expression *); 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *read_expression(s_expression *); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_swizzle *read_swizzle(s_expression *); 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *read_constant(s_expression *); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_texture *read_texture(s_expression *); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *read_dereference(s_expression *); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *read_var_ref(s_expression *); 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::ir_reader(_mesa_glsl_parse_state *state) : state(state) 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->mem_ctx = state; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *src, bool scan_for_protos) 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_reader r(state); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.read(instructions, src, scan_for_protos); 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos) 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *sx_mem_ctx = ralloc_context(NULL); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *expr = s_expression::read_expression(sx_mem_ctx, src); 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (expr == NULL) { 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "couldn't parse S-Expression."); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scan_for_protos) { 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scan_for_prototypes(instructions, expr); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->error) 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_instructions(instructions, expr, NULL); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(sx_mem_ctx); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (debug) 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org validate_ir_tree(instructions); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::ir_read_error(s_expression *expr, const char *fmt, ...) 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_list ap; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->error = true; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function != NULL) 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_asprintf_append(&state->info_log, "In function %s:\n", 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function->function_name()); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_strcat(&state->info_log, "error: "); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(ap, fmt); 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_vasprintf_append(&state->info_log, fmt, ap); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(ap); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_strcat(&state->info_log, "\n"); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (expr != NULL) { 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_strcat(&state->info_log, "...in this context:\n "); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expr->print(); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_strcat(&state->info_log, "\n\n"); 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst glsl_type * 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_type(s_expression *expr) 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_base_type; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_int *s_size; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "array", s_base_type, s_size }; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(expr, pat)) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *base_type = read_type(s_base_type); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (base_type == NULL) { 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading base type of array type"); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::get_array_instance(base_type, s_size->value()); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *type_sym = SX_AS_SYMBOL(expr); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_sym == NULL) { 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected <type>"); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = state->symbols->get_type(type_sym->value()); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "invalid type: %s", type_sym->value()); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr) 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *list = SX_AS_LIST(expr); 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (list == NULL) { 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "Expected (<instruction> ...); found an atom."); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, list->subexpressions) { 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *sub = SX_AS_LIST(it.get()); 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sub == NULL) 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; // not a (function ...); ignore it. 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head()); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tag == NULL || strcmp(tag->value(), "function") != 0) 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; // not a (function ...); ignore it. 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function *f = read_function(sub, true); 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (f == NULL) 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(f); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_function * 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_function(s_expression *expr, bool skip_body) 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool added = false; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *name; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "function", name }; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!PARTIAL_MATCH(expr, pat)) { 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "Expected (function <name> (signature ...) ...)"); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function *f = state->symbols->get_function(name->value()); 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (f == NULL) { 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org f = new(mem_ctx) ir_function(name->value()); 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org added = state->symbols->add_function(f); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(added); 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator(); 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it.next(); // skip "function" tag 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org it.next(); // skip function name 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (/* nothing */; it.has_next(); it.next()) { 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_sig = (s_expression *) it.get(); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_function_sig(f, s_sig, skip_body); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return added ? f : NULL; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body) 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *type_expr; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *paramlist; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *body_list; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "signature", type_expr, paramlist, body_list }; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "Expected (signature <type> (parameters ...) " 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "(<instruction> ...))"); 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *return_type = read_type(type_expr); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (return_type == NULL) 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head()); 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) { 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(paramlist, "Expected (parameters ...)"); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read the parameters list into a temporary place. 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list hir_parameters; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list_iterator it = paramlist->subexpressions.iterator(); 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (it.next() /* skip "parameters" */; it.has_next(); it.next()) { 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = read_declaration((s_expression *) it.get()); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var == NULL) 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hir_parameters.push_tail(var); 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig == NULL && skip_body) { 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If scanning for prototypes, generate a new signature. */ 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig = new(mem_ctx) ir_function_signature(return_type); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig->is_builtin = true; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org f->add_signature(sig); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (sig != NULL) { 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *badvar = sig->qualifiers_match(&hir_parameters); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (badvar != NULL) { 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "function `%s' parameter `%s' qualifiers " 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "don't match prototype", f->name, badvar); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig->return_type != return_type) { 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "function `%s' return type doesn't " 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "match prototype", f->name); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* No prototype for this body exists - skip it. */ 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(sig != NULL); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig->replace_parameters(&hir_parameters); 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!skip_body && !body_list->subexpressions.is_empty()) { 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig->is_defined) { 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "function %s redefined", f->name); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function = sig; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_instructions(&sig->body, body_list, NULL); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function = NULL; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig->is_defined = true; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_instructions(exec_list *instructions, s_expression *expr, 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop *loop_ctx) 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read in a list of instructions 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *list = SX_AS_LIST(expr); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (list == NULL) { 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "Expected (<instruction> ...); found an atom."); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, list->subexpressions) { 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *sub = (s_expression*) it.get(); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *ir = read_instruction(sub, loop_ctx); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir != NULL) { 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Global variable declarations should be moved to the top, before 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * any functions that might use them. Functions are added to the 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction stream when scanning for prototypes, so without this 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * hack, they always appear before variable declarations. 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function == NULL && ir->as_variable() != NULL) 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_head(ir); 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(ir); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_instruction * 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx) 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *symbol = SX_AS_SYMBOL(expr); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (symbol != NULL) { 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL) 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL) 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *list = SX_AS_LIST(expr); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (list == NULL || list->subexpressions.is_empty()) { 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "Invalid instruction.\n"); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head()); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tag == NULL) { 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected instruction tag"); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *inst = NULL; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(tag->value(), "declare") == 0) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_declaration(list); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "assign") == 0) { 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_assignment(list); 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "if") == 0) { 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_if(list, loop_ctx); 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "loop") == 0) { 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_loop(list); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "call") == 0) { 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_call(list); 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "return") == 0) { 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_return(list); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "function") == 0) { 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_function(list, false); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = read_rvalue(list); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst == NULL) 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading instruction"); 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return inst; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_variable * 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_declaration(s_expression *expr) 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *s_quals; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_type; 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *s_name; 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "declare", s_quals, s_type, s_name }; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (declare (<qualifiers>) <type> <name>)"); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = read_type(s_type); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(), 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_auto); 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, s_quals->subexpressions) { 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *qualifier = SX_AS_SYMBOL(it.get()); 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qualifier == NULL) { 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "qualifier list must contain only symbols"); 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FINISHME: Check for duplicate/conflicting qualifiers. 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(qualifier->value(), "centroid") == 0) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->centroid = 1; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "invariant") == 0) { 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->invariant = 1; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "uniform") == 0) { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_uniform; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "auto") == 0) { 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_auto; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "in") == 0) { 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_in; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "const_in") == 0) { 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_const_in; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "out") == 0) { 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_out; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "inout") == 0) { 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_inout; 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "temporary") == 0) { 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_temporary; 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "smooth") == 0) { 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_SMOOTH; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "flat") == 0) { 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_FLAT; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(qualifier->value(), "noperspective") == 0) { 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "unknown qualifier: %s", qualifier->value()); 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add the variable to the symbol table 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->add_variable(var); 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return var; 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_if * 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_if(s_expression *expr, ir_loop *loop_ctx) 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_cond; 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_then; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_else; 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "if", s_cond, s_then, s_else }; 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (if <condition> (<then>...) (<else>...))"); 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *condition = read_rvalue(s_cond); 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (condition == NULL) { 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading condition of (if ...)"); 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *iff = new(mem_ctx) ir_if(condition); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_instructions(&iff->then_instructions, s_then, loop_ctx); 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_instructions(&iff->else_instructions, s_else, loop_ctx); 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->error) { 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete iff; 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iff = NULL; 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return iff; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_loop * 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_loop(s_expression *expr) 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body }; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (loop <counter> <from> <to> " 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "<increment> <body>)"); 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FINISHME: actually read the count/from/to fields. 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop *loop = new(mem_ctx) ir_loop; 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_instructions(&loop->body_instructions, s_body, loop); 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->error) { 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete loop; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop = NULL; 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return loop; 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_return * 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_return(s_expression *expr) 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_retval; 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern return_value_pat[] = { "return", s_retval}; 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern return_void_pat[] = { "return" }; 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(expr, return_value_pat)) { 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *retval = read_rvalue(s_retval); 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (retval == NULL) { 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading return value"); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_return(retval); 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, return_void_pat)) { 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_return; 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (return <rvalue>) or (return)"); 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_rvalue(s_expression *expr) 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *list = SX_AS_LIST(expr); 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (list == NULL || list->subexpressions.is_empty()) 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head()); 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tag == NULL) { 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected rvalue tag"); 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *rvalue = read_dereference(list); 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rvalue != NULL || state->error) 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rvalue; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (strcmp(tag->value(), "swiz") == 0) { 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rvalue = read_swizzle(list); 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "expression") == 0) { 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rvalue = read_expression(list); 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp(tag->value(), "constant") == 0) { 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rvalue = read_constant(list); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rvalue = read_texture(list); 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rvalue == NULL && !state->error) 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value()); 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rvalue; 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_assignment * 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_assignment(s_expression *expr) 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *cond_expr = NULL; 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *lhs_expr, *rhs_expr; 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *mask_list; 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat4[] = { "assign", mask_list, lhs_expr, rhs_expr }; 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat5[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr }; 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat4) && !MATCH(expr, pat5)) { 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (assign [<condition>] (<write mask>) " 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "<lhs> <rhs>)"); 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *condition = NULL; 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cond_expr != NULL) { 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition = read_rvalue(cond_expr); 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (condition == NULL) { 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading condition of assignment"); 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned mask = 0; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *mask_symbol; 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern mask_pat[] = { mask_symbol }; 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(mask_list, mask_pat)) { 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *mask_str = mask_symbol->value(); 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned mask_length = strlen(mask_str); 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask_length > 4) { 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "invalid write mask: %s", mask_str); 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */ 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < mask_length; i++) { 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask_str[i] < 'w' || mask_str[i] > 'z') { 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "write mask contains invalid character: %c", 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask_str[i]); 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= 1 << idx_map[mask_str[i] - 'w']; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!mask_list->subexpressions.is_empty()) { 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(mask_list, "expected () or (<write mask>)"); 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *lhs = read_dereference(lhs_expr); 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lhs == NULL) { 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading left-hand side of assignment"); 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *rhs = read_rvalue(rhs_expr); 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs == NULL) { 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading right-hand side of assignment"); 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) { 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "non-zero write mask required."); 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_assignment(lhs, rhs, condition, mask); 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_call * 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_call(s_expression *expr) 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *name; 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *params; 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *s_return = NULL; 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *return_deref = NULL; 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern void_pat[] = { "call", name, params }; 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern non_void_pat[] = { "call", name, s_return, params }; 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(expr, non_void_pat)) { 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return_deref = read_var_ref(s_return); 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (return_deref == NULL) { 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(s_return, "when reading a call's return storage"); 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!MATCH(expr, void_pat)) { 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (call <name> [<deref>] (<param> ...))"); 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list parameters; 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, params->subexpressions) { 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *expr = (s_expression*) it.get(); 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *param = read_rvalue(expr); 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (param == NULL) { 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "when reading parameter to function call"); 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parameters.push_tail(param); 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function *f = state->symbols->get_function(name->value()); 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (f == NULL) { 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "found call to undefined function %s", 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name->value()); 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *callee = f->matching_signature(¶meters); 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (callee == NULL) { 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "couldn't find matching signature for function " 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s", name->value()); 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (callee->return_type == glsl_type::void_type && return_deref) { 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "call has return value storage but void type"); 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (callee->return_type != glsl_type::void_type && !return_deref) { 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "call has non-void type but no return value storage"); 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_call(callee, return_deref, ¶meters); 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_expression * 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_expression(s_expression *expr) 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_type; 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *s_op; 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_arg1; 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "expression", s_type, s_op, s_arg1 }; 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!PARTIAL_MATCH(expr, pat)) { 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (expression <type> <operator> " 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "<operand> [<operand>])"); 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = read_type(s_type); 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Read the operator */ 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression_operation op = ir_expression::get_operator(s_op->value()); 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op == (ir_expression_operation) -1) { 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "invalid operator: %s", s_op->value()); 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_operands = ir_expression::get_num_operands(op); 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) { 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (expression <type> %s <operand>)", 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_op->value()); 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *arg1 = read_rvalue(s_arg1); 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *arg2 = NULL; 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (arg1 == NULL) { 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading first operand of %s", s_op->value()); 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (num_operands == 2) { 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) { 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (expression <type> %s <operand> " 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "<operand>)", s_op->value()); 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org arg2 = read_rvalue(s_arg2); 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (arg2 == NULL) { 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading second operand of %s", 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_op->value()); 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_expression(op, type, arg1, arg2); 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_swizzle * 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_swizzle(s_expression *expr) 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *swiz; 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *sub; 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "swiz", swiz, sub }; 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (swiz <swizzle> <rvalue>)"); 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strlen(swiz->value()) > 4) { 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected a valid swizzle; found %s", swiz->value()); 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *rvalue = read_rvalue(sub); 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rvalue == NULL) 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(), 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rvalue->type->vector_elements); 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir == NULL) 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "invalid swizzle"); 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ir; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant * 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_constant(s_expression *expr) 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *type_expr; 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *values; 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern pat[] = { "constant", type_expr, values }; 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(expr, pat)) { 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (constant <type> (...))"); 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = read_type(type_expr); 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (values == NULL) { 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "expected (constant <type> (...))"); 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_array()) { 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned elements_supplied = 0; 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list elements; 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, values->subexpressions) { 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *elt = (s_expression *) it.get(); 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *ir_elt = read_constant(elt); 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir_elt == NULL) 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elements.push_tail(ir_elt); 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org elements_supplied++; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (elements_supplied != type->length) { 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "expected exactly %u array elements, " 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "given %u", type->length, elements_supplied); 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_constant(type, &elements); 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant_data data = { { 0 } }; 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read in list of values (at most 16). 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned k = 0; 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, it, values->subexpressions) { 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (k >= 16) { 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "expected at most 16 numbers"); 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *expr = (s_expression*) it.get(); 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->base_type == GLSL_TYPE_FLOAT) { 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_number *value = SX_AS_NUMBER(expr); 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value == NULL) { 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "expected numbers"); 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.f[k] = value->fvalue(); 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_int *value = SX_AS_INT(expr); 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (value == NULL) { 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "expected integers"); 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type->base_type) { 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: { 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.u[k] = value->value(); 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: { 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.i[k] = value->value(); 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_BOOL: { 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org data.b[k] = value->value(); 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "unsupported constant type"); 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++k; 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (k != type->components()) { 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(values, "expected %u constant values, found %u", 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->components(), k); 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_constant(type, &data); 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_variable * 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_var_ref(s_expression *expr) 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *s_var; 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern var_pat[] = { "var_ref", s_var }; 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(expr, var_pat)) { 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = state->symbols->get_variable(s_var->value()); 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var == NULL) { 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(expr, "undeclared variable: %s", s_var->value()); 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_dereference_variable(var); 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference * 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_dereference(s_expression *expr) 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_subject; 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_index; 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *s_field; 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern array_pat[] = { "array_ref", s_subject, s_index }; 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern record_pat[] = { "record_ref", s_subject, s_field }; 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *var_ref = read_var_ref(expr); 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var_ref != NULL) { 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return var_ref; 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, array_pat)) { 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *subject = read_rvalue(s_subject); 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (subject == NULL) { 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading the subject of an array_ref"); 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *idx = read_rvalue(s_index); 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (subject == NULL) { 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading the index of an array_ref"); 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_dereference_array(subject, idx); 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, record_pat)) { 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *subject = read_rvalue(s_subject); 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (subject == NULL) { 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading the subject of a record_ref"); 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_dereference_record(subject, s_field->value()); 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_texture * 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_reader::read_texture(s_expression *expr) 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_symbol *tag = NULL; 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_type = NULL; 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_sampler = NULL; 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_coord = NULL; 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_offset = NULL; 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_proj = NULL; 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_list *s_shadow = NULL; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_lod = NULL; 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_texture_opcode op = ir_tex; /* silence warning */ 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern tex_pattern[] = 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern txf_pattern[] = 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern txs_pattern[] = 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { "txs", s_type, s_sampler, s_lod }; 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern other_pattern[] = 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MATCH(expr, tex_pattern)) { 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = ir_tex; 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, txf_pattern)) { 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = ir_txf; 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, txs_pattern)) { 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = ir_txs; 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (MATCH(expr, other_pattern)) { 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = ir_texture::get_opcode(tag->value()); 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op == -1) 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "unexpected texture pattern"); 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_texture *tex = new(mem_ctx) ir_texture(op); 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read return type 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type = read_type(s_type); 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) { 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading type in (%s ...)", 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read sampler (must be a deref) 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *sampler = read_dereference(s_sampler); 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sampler == NULL) { 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading sampler in (%s ...)", 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->set_sampler(sampler, type); 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op != ir_txs) { 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read coordinate (any rvalue) 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->coordinate = read_rvalue(s_coord); 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->coordinate == NULL) { 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading coordinate in (%s ...)", 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Read texel offset - either 0 or an rvalue. 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_int *si_offset = SX_AS_INT(s_offset); 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (si_offset == NULL || si_offset->value() != 0) { 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->offset = read_rvalue(s_offset); 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->offset == NULL) { 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(s_offset, "expected 0 or an expression"); 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op != ir_txf && op != ir_txs) { 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_int *proj_as_int = SX_AS_INT(s_proj); 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (proj_as_int && proj_as_int->value() == 1) { 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->projector = NULL; 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->projector = read_rvalue(s_proj); 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->projector == NULL) { 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading projective divide in (%s ..)", 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s_shadow->subexpressions.is_empty()) { 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->shadow_comparitor = NULL; 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->shadow_comparitor = read_rvalue(s_shadow); 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->shadow_comparitor == NULL) { 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading shadow comparitor in (%s ..)", 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (op) { 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txb: 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->lod_info.bias = read_rvalue(s_lod); 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->lod_info.bias == NULL) { 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading LOD bias in (txb ...)"); 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txl: 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txf: 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txs: 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->lod_info.lod = read_rvalue(s_lod); 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->lod_info.lod == NULL) { 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading LOD in (%s ...)", 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->opcode_string()); 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txd: { 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_expression *s_dx, *s_dy; 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s_pattern dxdy_pat[] = { s_dx, s_dy }; 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!MATCH(s_lod, dxdy_pat)) { 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(s_lod, "expected (dPdx dPdy) in (txd ...)"); 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->lod_info.grad.dPdx = read_rvalue(s_dx); 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->lod_info.grad.dPdx == NULL) { 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading dPdx in (txd ...)"); 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex->lod_info.grad.dPdy = read_rvalue(s_dy); 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex->lod_info.grad.dPdy == NULL) { 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_read_error(NULL, "when reading dPdy in (txd ...)"); 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // tex doesn't have any extra parameters. 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return tex; 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1051