Mesa (master): ir_reader: Read the new assignment format (with write mask).

Kenneth Graunke kwg at kemper.freedesktop.org
Sat Sep 4 09:21:00 UTC 2010


Module: Mesa
Branch: master
Commit: 03a6276477702404f5c7a4f5f2fbb713371c7eed
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=03a6276477702404f5c7a4f5f2fbb713371c7eed

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Sep  2 23:54:40 2010 -0700

ir_reader: Read the new assignment format (with write mask).

This preserves the ability to read the old format, for momentary
compatibility with all the existing IR implementations of built-ins.

---

 src/glsl/ir_reader.cpp |   52 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index 41bfc8a..c94d4b4 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -581,23 +581,58 @@ static ir_assignment *
 read_assignment(_mesa_glsl_parse_state *st, s_list *list)
 {
    void *ctx = st;
-   if (list->length() != 4) {
-      ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
+   const unsigned list_length = list->length();
+   if (list_length < 4 || list_length > 5) {
+      ir_read_error(st, list, "expected (assign <condition> (<write mask>) "
+			      "<lhs> <rhs>)");
       return NULL;
    }
 
    s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
-   s_expression *lhs_expr  = (s_expression*) cond_expr->next;
+   s_list       *mask_list = SX_AS_LIST(cond_expr->next);
+   s_expression *lhs_expr  = (s_expression*)
+      (list_length == 4 ? cond_expr->next : cond_expr->next->next);
    s_expression *rhs_expr  = (s_expression*) lhs_expr->next;
 
-   // FINISHME: Deal with "true" condition
    ir_rvalue *condition = read_rvalue(st, cond_expr);
    if (condition == NULL) {
       ir_read_error(st, NULL, "when reading condition of assignment");
       return NULL;
    }
 
-   ir_rvalue *lhs = read_rvalue(st, lhs_expr);
+   if (list_length == 5 && mask_list == NULL || mask_list->length() > 1) {
+      ir_read_error(st, mask_list, "expected () or (<write mask>)");
+      return NULL;
+   }
+
+   unsigned mask = 0;
+   if (list_length == 5 && mask_list->length() == 1) {
+      s_symbol *mask_symbol = SX_AS_SYMBOL(mask_list->subexpressions.head);
+      if (mask_symbol == NULL) {
+	 ir_read_error(st, list, "expected a write mask; found non-symbol");
+	 return NULL;
+      }
+
+      const char *mask_str = mask_symbol->value();
+      unsigned mask_length = strlen(mask_str);
+      if (mask_length > 4) {
+	 ir_read_error(st, list, "invalid write mask: %s", mask_str);
+	 return NULL;
+      }
+
+      const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */
+
+      for (unsigned i = 0; i < mask_length; i++) {
+	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
+	    ir_read_error(st, list, "write mask contains invalid character: %c",
+			  mask_str[i]);
+	    return NULL;
+	 }
+	 mask |= 1 << idx_map[mask_str[i] - 'w'];
+      }
+   }
+
+   ir_dereference *lhs = read_dereference(st, lhs_expr);
    if (lhs == NULL) {
       ir_read_error(st, NULL, "when reading left-hand side of assignment");
       return NULL;
@@ -609,7 +644,12 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list)
       return NULL;
    }
 
-   return new(ctx) ir_assignment(lhs, rhs, condition);
+   if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
+      ir_read_error(st, list, "non-zero write mask required.");
+      return NULL;
+   }
+
+   return new(ctx) ir_assignment(lhs, rhs, condition, mask);
 }
 
 static ir_call *




More information about the mesa-commit mailing list