nir/spirv: Move CF emit code into vtn_cfg.c
[mesa.git] / src / glsl / ir_reader.cpp
index 28923f3b8c0bd2400e1d69c836dda55fc1296892..7c0af1b712f4e9c845413697a9c44148a0530743 100644 (file)
@@ -26,7 +26,7 @@
 #include "glsl_types.h"
 #include "s_expression.h"
 
-const static bool debug = false;
+static const bool debug = false;
 
 namespace {
 
@@ -63,6 +63,7 @@ private:
    ir_texture *read_texture(s_expression *);
    ir_emit_vertex *read_emit_vertex(s_expression *);
    ir_end_primitive *read_end_primitive(s_expression *);
+   ir_barrier *read_barrier(s_expression *);
 
    ir_dereference *read_dereference(s_expression *);
    ir_dereference_variable *read_var_ref(s_expression *);
@@ -92,7 +93,7 @@ ir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
       ir_read_error(NULL, "couldn't parse S-Expression.");
       return;
    }
-   
+
    if (scan_for_protos) {
       scan_for_prototypes(instructions, expr);
       if (state->error)
@@ -146,7 +147,7 @@ ir_reader::read_type(s_expression *expr)
 
       return glsl_type::get_array_instance(base_type, s_size->value());
    }
-   
+
    s_symbol *type_sym = SX_AS_SYMBOL(expr);
    if (type_sym == NULL) {
       ir_read_error(expr, "expected <type>");
@@ -170,9 +171,8 @@ ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
       return;
    }
 
-   foreach_list(n, &list->subexpressions) {
-      s_list *sub = SX_AS_LIST(n);
-      if (sub == NULL)
+   foreach_in_list(s_list, sub, &list->subexpressions) {
+      if (!sub->is_list())
         continue; // not a (function ...); ignore it.
 
       s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
@@ -317,8 +317,7 @@ ir_reader::read_instructions(exec_list *instructions, s_expression *expr,
       return;
    }
 
-   foreach_list(n, &list->subexpressions) {
-      s_expression *sub = (s_expression *) n;
+   foreach_in_list(s_expression, sub, &list->subexpressions) {
       ir_instruction *ir = read_instruction(sub, loop_ctx);
       if (ir != NULL) {
         /* Global variable declarations should be moved to the top, before
@@ -377,6 +376,8 @@ ir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
       inst = read_emit_vertex(list);
    } else if (strcmp(tag->value(), "end-primitive") == 0) {
       inst = read_end_primitive(list);
+   } else if (strcmp(tag->value(), "barrier") == 0) {
+      inst = read_barrier(list);
    } else {
       inst = read_rvalue(list);
       if (inst == NULL)
@@ -405,9 +406,8 @@ ir_reader::read_declaration(s_expression *expr)
    ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
                                               ir_var_auto);
 
-   foreach_list(n, &s_quals->subexpressions) {
-      s_symbol *qualifier = SX_AS_SYMBOL(n);
-      if (qualifier == NULL) {
+   foreach_in_list(s_symbol, qualifier, &s_quals->subexpressions) {
+      if (!qualifier->is_symbol()) {
         ir_read_error(expr, "qualifier list must contain only symbols");
         return NULL;
       }
@@ -417,10 +417,14 @@ ir_reader::read_declaration(s_expression *expr)
         var->data.centroid = 1;
       } else if (strcmp(qualifier->value(), "sample") == 0) {
          var->data.sample = 1;
+      } else if (strcmp(qualifier->value(), "patch") == 0) {
+         var->data.patch = 1;
       } else if (strcmp(qualifier->value(), "invariant") == 0) {
         var->data.invariant = 1;
       } else if (strcmp(qualifier->value(), "uniform") == 0) {
         var->data.mode = ir_var_uniform;
+      } else if (strcmp(qualifier->value(), "shader_storage") == 0) {
+        var->data.mode = ir_var_shader_storage;
       } else if (strcmp(qualifier->value(), "auto") == 0) {
         var->data.mode = ir_var_auto;
       } else if (strcmp(qualifier->value(), "in") == 0) {
@@ -437,6 +441,12 @@ ir_reader::read_declaration(s_expression *expr)
         var->data.mode = ir_var_function_inout;
       } else if (strcmp(qualifier->value(), "temporary") == 0) {
         var->data.mode = ir_var_temporary;
+      } else if (strcmp(qualifier->value(), "stream1") == 0) {
+        var->data.stream = 1;
+      } else if (strcmp(qualifier->value(), "stream2") == 0) {
+        var->data.stream = 2;
+      } else if (strcmp(qualifier->value(), "stream3") == 0) {
+        var->data.stream = 3;
       } else if (strcmp(qualifier->value(), "smooth") == 0) {
         var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
       } else if (strcmp(qualifier->value(), "flat") == 0) {
@@ -658,11 +668,10 @@ ir_reader::read_call(s_expression *expr)
 
    exec_list parameters;
 
-   foreach_list(n, &params->subexpressions) {
-      s_expression *expr = (s_expression *) n;
-      ir_rvalue *param = read_rvalue(expr);
+   foreach_in_list(s_expression, e, &params->subexpressions) {
+      ir_rvalue *param = read_rvalue(e);
       if (param == NULL) {
-        ir_read_error(expr, "when reading parameter to function call");
+        ir_read_error(e, "when reading parameter to function call");
         return NULL;
       }
       parameters.push_tail(param);
@@ -675,7 +684,8 @@ ir_reader::read_call(s_expression *expr)
       return NULL;
    }
 
-   ir_function_signature *callee = f->matching_signature(state, &parameters);
+   ir_function_signature *callee =
+      f->matching_signature(state, &parameters, true);
    if (callee == NULL) {
       ir_read_error(expr, "couldn't find matching signature for function "
                     "%s", name->value());
@@ -721,10 +731,9 @@ ir_reader::read_expression(s_expression *expr)
       ir_read_error(expr, "invalid operator: %s", s_op->value());
       return NULL;
    }
-    
-   int num_operands = -3; /* skip "expression" <type> <operation> */
-   foreach_list(n, &((s_list *) expr)->subexpressions)
-      ++num_operands;
+
+   /* Skip "expression" <type> <operation> by subtracting 3. */
+   int num_operands = (int) ((s_list *) expr)->subexpressions.length() - 3;
 
    int expected_operands = ir_expression::get_num_operands(op);
    if (num_operands != expected_operands) {
@@ -798,8 +807,7 @@ ir_reader::read_constant(s_expression *expr)
    if (type->is_array()) {
       unsigned elements_supplied = 0;
       exec_list elements;
-      foreach_list(n, &values->subexpressions) {
-        s_expression *elt = (s_expression *) n;
+      foreach_in_list(s_expression, elt, &values->subexpressions) {
         ir_constant *ir_elt = read_constant(elt);
         if (ir_elt == NULL)
            return NULL;
@@ -819,14 +827,12 @@ ir_reader::read_constant(s_expression *expr)
 
    // Read in list of values (at most 16).
    unsigned k = 0;
-   foreach_list(n, &values->subexpressions) {
+   foreach_in_list(s_expression, expr, &values->subexpressions) {
       if (k >= 16) {
         ir_read_error(values, "expected at most 16 numbers");
         return NULL;
       }
 
-      s_expression *expr = (s_expression *) n;
-
       if (type->base_type == GLSL_TYPE_FLOAT) {
         s_number *value = SX_AS_NUMBER(expr);
         if (value == NULL) {
@@ -954,6 +960,8 @@ ir_reader::read_texture(s_expression *expr)
       { "tg4", s_type, s_sampler, s_coord, s_offset, s_component };
    s_pattern query_levels_pattern[] =
       { "query_levels", s_type, s_sampler };
+   s_pattern texture_samples_pattern[] =
+      { "samples", s_type, s_sampler };
    s_pattern other_pattern[] =
       { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
 
@@ -971,9 +979,11 @@ ir_reader::read_texture(s_expression *expr)
       op = ir_tg4;
    } else if (MATCH(expr, query_levels_pattern)) {
       op = ir_query_levels;
+   } else if (MATCH(expr, texture_samples_pattern)) {
+      op = ir_texture_samples;
    } else if (MATCH(expr, other_pattern)) {
       op = ir_texture::get_opcode(tag->value());
-      if (op == -1)
+      if (op == (ir_texture_opcode) -1)
         return NULL;
    } else {
       ir_read_error(NULL, "unexpected texture pattern %s", tag->value());
@@ -1023,7 +1033,7 @@ ir_reader::read_texture(s_expression *expr)
 
    if (op != ir_txf && op != ir_txf_ms &&
        op != ir_txs && op != ir_lod && op != ir_tg4 &&
-       op != ir_query_levels) {
+       op != ir_query_levels && op != ir_texture_samples) {
       s_int *proj_as_int = SX_AS_INT(s_proj);
       if (proj_as_int && proj_as_int->value() == 1) {
         tex->projector = NULL;
@@ -1109,10 +1119,17 @@ ir_reader::read_texture(s_expression *expr)
 ir_emit_vertex *
 ir_reader::read_emit_vertex(s_expression *expr)
 {
-   s_pattern pat[] = { "emit-vertex" };
+   s_expression *s_stream = NULL;
+
+   s_pattern pat[] = { "emit-vertex", s_stream };
 
    if (MATCH(expr, pat)) {
-      return new(mem_ctx) ir_emit_vertex();
+      ir_rvalue *stream = read_dereference(s_stream);
+      if (stream == NULL) {
+         ir_read_error(NULL, "when reading stream info in emit-vertex");
+         return NULL;
+      }
+      return new(mem_ctx) ir_emit_vertex(stream);
    }
    ir_read_error(NULL, "when reading emit-vertex");
    return NULL;
@@ -1121,11 +1138,30 @@ ir_reader::read_emit_vertex(s_expression *expr)
 ir_end_primitive *
 ir_reader::read_end_primitive(s_expression *expr)
 {
-   s_pattern pat[] = { "end-primitive" };
+   s_expression *s_stream = NULL;
+
+   s_pattern pat[] = { "end-primitive", s_stream };
 
    if (MATCH(expr, pat)) {
-      return new(mem_ctx) ir_end_primitive();
+      ir_rvalue *stream = read_dereference(s_stream);
+      if (stream == NULL) {
+         ir_read_error(NULL, "when reading stream info in end-primitive");
+         return NULL;
+      }
+      return new(mem_ctx) ir_end_primitive(stream);
    }
    ir_read_error(NULL, "when reading end-primitive");
    return NULL;
 }
+
+ir_barrier *
+ir_reader::read_barrier(s_expression *expr)
+{
+   s_pattern pat[] = { "barrier" };
+
+   if (MATCH(expr, pat)) {
+      return new(mem_ctx) ir_barrier();
+   }
+   ir_read_error(NULL, "when reading barrier");
+   return NULL;
+}