Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2010 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "ir.h"
  25. #include "program/symbol_table.h"
  26. #include "glsl_parser_extras.h"
  27. #include "ast.h"
  28. #include "glsl_types.h"
  29.  
  30. ir_rvalue *
  31. _mesa_ast_field_selection_to_hir(const ast_expression *expr,
  32.                                  exec_list *instructions,
  33.                                  struct _mesa_glsl_parse_state *state)
  34. {
  35.    void *ctx = state;
  36.    ir_rvalue *result = NULL;
  37.    ir_rvalue *op;
  38.  
  39.    op = expr->subexpressions[0]->hir(instructions, state);
  40.  
  41.    /* There are two kinds of field selection.  There is the selection of a
  42.     * specific field from a structure, and there is the selection of a
  43.     * swizzle / mask from a vector.  Which is which is determined entirely
  44.     * by the base type of the thing to which the field selection operator is
  45.     * being applied.
  46.     */
  47.    YYLTYPE loc = expr->get_location();
  48.    if (op->type->is_error()) {
  49.       /* silently propagate the error */
  50.    } else if (op->type->is_vector()) {
  51.       ir_swizzle *swiz = ir_swizzle::create(op,
  52.                                             expr->primary_expression.identifier,
  53.                                             op->type->vector_elements);
  54.       if (swiz != NULL) {
  55.          result = swiz;
  56.       } else {
  57.          /* FINISHME: Logging of error messages should be moved into
  58.           * FINISHME: ir_swizzle::create.  This allows the generation of more
  59.           * FINISHME: specific error messages.
  60.           */
  61.          _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
  62.                           expr->primary_expression.identifier);
  63.       }
  64.    } else if (op->type->base_type == GLSL_TYPE_STRUCT) {
  65.       result = new(ctx) ir_dereference_record(op,
  66.                                               expr->primary_expression.identifier);
  67.  
  68.       if (result->type->is_error()) {
  69.          _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
  70.                           "structure",
  71.                           expr->primary_expression.identifier);
  72.       }
  73.    } else if (expr->subexpressions[1] != NULL) {
  74.       /* Handle "method calls" in GLSL 1.20 - namely, array.length() */
  75.       if (state->language_version < 120)
  76.          _mesa_glsl_error(&loc, state, "Methods not supported in GLSL 1.10.");
  77.  
  78.       ast_expression *call = expr->subexpressions[1];
  79.       assert(call->oper == ast_function_call);
  80.  
  81.       const char *method;
  82.       method = call->subexpressions[0]->primary_expression.identifier;
  83.  
  84.       if (op->type->is_array() && strcmp(method, "length") == 0) {
  85.          if (!call->expressions.is_empty())
  86.             _mesa_glsl_error(&loc, state, "length method takes no arguments.");
  87.  
  88.          if (op->type->array_size() == 0)
  89.             _mesa_glsl_error(&loc, state, "length called on unsized array.");
  90.  
  91.          result = new(ctx) ir_constant(op->type->array_size());
  92.       } else {
  93.          _mesa_glsl_error(&loc, state, "Unknown method: `%s'.", method);
  94.       }
  95.    } else {
  96.       _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
  97.                        "non-structure / non-vector.",
  98.                        expr->primary_expression.identifier);
  99.    }
  100.  
  101.    return result ? result : ir_call::get_error_instruction(ctx);
  102. }
  103.