Merge branch 'gallium-polygon-stipple'
[mesa.git] / src / glsl / ir_reader.cpp
index 40901dc6c92ea0cd16350dbd789aaf63f41d7644..f3a621734baddce0a955d93d364c6eaf3af92575 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-extern "C" {
-#include <talloc.h>
-}
-
 #include "ir_reader.h"
 #include "glsl_parser_extras.h"
 #include "glsl_types.h"
@@ -96,7 +92,7 @@ ir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
    }
 
    read_instructions(instructions, expr, NULL);
-   talloc_free(expr);
+   ralloc_free(expr);
 
    if (debug)
       validate_ir_tree(instructions);
@@ -110,21 +106,19 @@ ir_reader::ir_read_error(s_expression *expr, const char *fmt, ...)
    state->error = true;
 
    if (state->current_function != NULL)
-      state->info_log = talloc_asprintf_append(state->info_log,
-                          "In function %s:\n",
-                          state->current_function->function_name());
-   state->info_log = talloc_strdup_append(state->info_log, "error: ");
+      ralloc_asprintf_append(&state->info_log, "In function %s:\n",
+                            state->current_function->function_name());
+   ralloc_strcat(&state->info_log, "error: ");
 
    va_start(ap, fmt);
-   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
+   ralloc_vasprintf_append(&state->info_log, fmt, ap);
    va_end(ap);
-   state->info_log = talloc_strdup_append(state->info_log, "\n");
+   ralloc_strcat(&state->info_log, "\n");
 
    if (expr != NULL) {
-      state->info_log = talloc_strdup_append(state->info_log,
-                                            "...in this context:\n   ");
+      ralloc_strcat(&state->info_log, "...in this context:\n   ");
       expr->print();
-      state->info_log = talloc_strdup_append(state->info_log, "\n\n");
+      ralloc_strcat(&state->info_log, "\n\n");
    }
 }
 
@@ -403,6 +397,8 @@ ir_reader::read_declaration(s_expression *expr)
         var->mode = ir_var_auto;
       } else if (strcmp(qualifier->value(), "in") == 0) {
         var->mode = ir_var_in;
+      } else if (strcmp(qualifier->value(), "const_in") == 0) {
+        var->mode = ir_var_const_in;
       } else if (strcmp(qualifier->value(), "out") == 0) {
         var->mode = ir_var_out;
       } else if (strcmp(qualifier->value(), "inout") == 0) {
@@ -486,19 +482,21 @@ ir_reader::read_return(s_expression *expr)
 {
    s_expression *s_retval;
 
-   s_pattern pat[] = { "return", s_retval};
-   if (!MATCH(expr, pat)) {
-      ir_read_error(expr, "expected (return <rvalue>)");
-      return NULL;
-   }
-
-   ir_rvalue *retval = read_rvalue(s_retval);
-   if (retval == NULL) {
-      ir_read_error(NULL, "when reading return value");
+   s_pattern return_value_pat[] = { "return", s_retval};
+   s_pattern return_void_pat[] = { "return" };
+   if (MATCH(expr, return_value_pat)) {
+      ir_rvalue *retval = read_rvalue(s_retval);
+      if (retval == NULL) {
+         ir_read_error(NULL, "when reading return value");
+         return NULL;
+      }
+      return new(mem_ctx) ir_return(retval);
+   } else if (MATCH(expr, return_void_pat)) {
+      return new(mem_ctx) ir_return;
+   } else {
+      ir_read_error(expr, "expected (return <rvalue>) or (return)");
       return NULL;
    }
-
-   return new(mem_ctx) ir_return(retval);
 }
 
 
@@ -873,21 +871,22 @@ ir_texture *
 ir_reader::read_texture(s_expression *expr)
 {
    s_symbol *tag = NULL;
+   s_expression *s_type = NULL;
    s_expression *s_sampler = NULL;
    s_expression *s_coord = NULL;
-   s_list *s_offset = NULL;
+   s_expression *s_offset = NULL;
    s_expression *s_proj = NULL;
    s_list *s_shadow = NULL;
    s_expression *s_lod = NULL;
 
-   ir_texture_opcode op;
+   ir_texture_opcode op = ir_tex; /* silence warning */
 
    s_pattern tex_pattern[] =
-      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
+      { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow };
    s_pattern txf_pattern[] =
-      { "txf", s_sampler, s_coord, s_offset, s_lod };
+      { "txf", s_type, s_sampler, s_coord, s_offset, s_lod };
    s_pattern other_pattern[] =
-      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
+      { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
 
    if (MATCH(expr, tex_pattern)) {
       op = ir_tex;
@@ -897,10 +896,21 @@ ir_reader::read_texture(s_expression *expr)
       op = ir_texture::get_opcode(tag->value());
       if (op == -1)
         return NULL;
+   } else {
+      ir_read_error(NULL, "unexpected texture pattern");
+      return NULL;
    }
 
    ir_texture *tex = new(mem_ctx) ir_texture(op);
 
+   // Read return type
+   const glsl_type *type = read_type(s_type);
+   if (type == NULL) {
+      ir_read_error(NULL, "when reading type in (%s ...)",
+                   tex->opcode_string());
+      return NULL;
+   }
+
    // Read sampler (must be a deref)
    ir_dereference *sampler = read_dereference(s_sampler);
    if (sampler == NULL) {
@@ -908,7 +918,7 @@ ir_reader::read_texture(s_expression *expr)
                    tex->opcode_string());
       return NULL;
    }
-   tex->set_sampler(sampler);
+   tex->set_sampler(sampler, type);
 
    // Read coordinate (any rvalue)
    tex->coordinate = read_rvalue(s_coord);
@@ -918,18 +928,15 @@ ir_reader::read_texture(s_expression *expr)
       return NULL;
    }
 
-   // Read texel offset, i.e. (0 0 0)
-   s_int *offset_x;
-   s_int *offset_y;
-   s_int *offset_z;
-   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
-   if (!MATCH(s_offset, offset_pat)) {
-      ir_read_error(s_offset, "expected (<int> <int> <int>)");
-      return NULL;
+   // Read texel offset - either 0 or an rvalue.
+   s_int *si_offset = SX_AS_INT(s_offset);
+   if (si_offset == NULL || si_offset->value() != 0) {
+      tex->offset = read_rvalue(s_offset);
+      if (tex->offset == NULL) {
+        ir_read_error(s_offset, "expected 0 or an expression");
+        return NULL;
+      }
    }
-   tex->offsets[0] = offset_x->value();
-   tex->offsets[1] = offset_y->value();
-   tex->offsets[2] = offset_z->value();
 
    if (op != ir_txf) {
       s_int *proj_as_int = SX_AS_INT(s_proj);