mesa: Branch 'glsl-compiler-1' - 4 commits

Brian Paul brianp at kemper.freedesktop.org
Sat Mar 24 22:02:29 UTC 2007


 src/mesa/shader/slang/slang_codegen.c |   22 -
 src/mesa/shader/slang/slang_emit.c    |  315 ---------------------------
 src/mesa/shader/slang/slang_ir.c      |  387 ++++++++++++++++++++++++++++++++++
 src/mesa/shader/slang/slang_ir.h      |   27 ++
 src/mesa/sources                      |    1 
 src/mesa/tnl/t_context.c              |   21 -
 6 files changed, 429 insertions(+), 344 deletions(-)

New commits:
diff-tree 0e71d08e8df7f59da74e78212fe8433ceb7c7315 (from b50b036ffb795a12106bd59b1a08b0287a8b3388)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Mar 24 10:18:14 2007 -0600

    Properly free the slang_ir_node->Store data (use ref counting).

diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
index 5790d0a..11c09d3 100644
--- a/src/mesa/shader/slang/slang_ir.c
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -106,33 +106,65 @@ _slang_ir_info(slang_ir_opcode opcode)
    return NULL;
 }
 
+
 static const char *
-slang_ir_name(slang_ir_opcode opcode)
+_slang_ir_name(slang_ir_opcode opcode)
 {
    return _slang_ir_info(opcode)->IrName;
 }
 
 
-
 /**
- * Recursively free an IR tree.
+ * Since many IR nodes might point to the same IR storage info, we need
+ * to be careful when deleting things.
+ * Before deleting an IR tree, traverse it and do refcounting on the
+ * IR storage nodes.  Use the refcount info during delete to free things
+ * properly.
  */
-void
-_slang_free_ir_tree(slang_ir_node *n)
+static void
+_slang_refcount_storage(slang_ir_node *n)
 {
-#if 1
    GLuint i;
    if (!n)
       return;
+   if (n->Store)
+      n->Store->RefCount++;
+   for (i = 0; i < 3; i++)
+      _slang_refcount_storage(n->Children[i]);
+}
+
+
+static void
+_slang_free_ir(slang_ir_node *n)
+{
+   GLuint i;
+   if (!n)
+      return;
+
+   if (n->Store) {
+      n->Store->RefCount--;
+      if (n->Store->RefCount == 0) {
+         free(n->Store);
+         n->Store = NULL;
+      }
+   }
+
    for (i = 0; i < 3; i++)
       _slang_free_ir_tree(n->Children[i]);
    /* Do not free n->List since it's a child elsewhere */
    free(n);
-#endif
 }
 
 
-
+/**
+ * Recursively free an IR tree.
+ */
+void
+_slang_free_ir_tree(slang_ir_node *n)
+{
+   _slang_refcount_storage(n);
+   _slang_free_ir(n);
+}
 
 
 
@@ -149,6 +181,7 @@ swizzle_string(GLuint swizzle)
    return s;
 }
 
+
 static const char *
 writemask_string(GLuint writemask)
 {
@@ -163,6 +196,7 @@ writemask_string(GLuint writemask)
    return s;
 }
 
+
 static const char *
 storage_string(const slang_ir_storage *st)
 {
@@ -204,12 +238,11 @@ spaces(int n)
 }
 
 
-#define IND 0
-
-
 void
 _slang_print_ir_tree(const slang_ir_node *n, int indent)
 {
+#define IND 0
+
    if (!n)
       return;
 #if !IND
@@ -346,7 +379,7 @@ _slang_print_ir_tree(const slang_ir_node
       _slang_print_ir_tree(n->Children[0], indent + 3);
       break;
    default:
-      printf("%s (%p, %p)  (store %p)\n", slang_ir_name(n->Opcode),
+      printf("%s (%p, %p)  (store %p)\n", _slang_ir_name(n->Opcode),
              (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
       _slang_print_ir_tree(n->Children[0], indent+3);
       _slang_print_ir_tree(n->Children[1], indent+3);
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 2b7d822..2e90409 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -147,6 +147,7 @@ struct _slang_ir_storage
    GLint Index;  /**< -1 means unallocated */
    GLint Size;  /**< number of floats */
    GLuint Swizzle;
+   GLint RefCount; /**< Used during IR tree delete */
 };
 
 typedef struct _slang_ir_storage slang_ir_storage;
diff-tree b50b036ffb795a12106bd59b1a08b0287a8b3388 (from dc3015f1574f26704c3498c56915b5570d777da4)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Mar 24 10:16:49 2007 -0600

    When computing render_inputs_bitset, omit primary color if we have a fragment program and it doesn't need FRAG_ATTRIB_COL0.  Silences valgrind warnings.

diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f665485..fa42a3d 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -102,6 +102,8 @@ void
 _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
+   const struct gl_vertex_program *vp = ctx->VertexProgram._Current;
+   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
 
    if (new_state & (_NEW_HINT)) {
       ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog);
@@ -118,7 +120,9 @@ _tnl_InvalidateState( GLcontext *ctx, GL
 
       RENDERINPUTS_ZERO( tnl->render_inputs_bitset );
       RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS );
-      RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 );
+      if (!fp || fp->Base.InputsRead & FRAG_BIT_COL0) {
+         RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 );
+      }
       for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
          if (ctx->Texture._EnabledCoordUnits & (1 << i)) {
             RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) );
@@ -151,15 +155,12 @@ _tnl_InvalidateState( GLcontext *ctx, GL
       RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE );
 
    /* check for varying vars which are written by the vertex program */
-   {
-      struct gl_vertex_program *vp = ctx->VertexProgram._Current;
-      if (vp) {
-         GLuint i;
-         for (i = 0; i < MAX_VARYING; i++) {
-            if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
-               RENDERINPUTS_SET(tnl->render_inputs_bitset,
-                                _TNL_ATTRIB_GENERIC(i));
-            }
+   if (vp) {
+      GLuint i;
+      for (i = 0; i < MAX_VARYING; i++) {
+         if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
+            RENDERINPUTS_SET(tnl->render_inputs_bitset,
+                             _TNL_ATTRIB_GENERIC(i));
          }
       }
    }
diff-tree dc3015f1574f26704c3498c56915b5570d777da4 (from b2bc563142c93fd9bfa503f7b9e5e99c7d450ccc)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Mar 24 09:40:20 2007 -0600

    move some code into new slang_ir.c file

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 2eb509b..2210b95 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -402,24 +402,6 @@ static slang_asm_info AsmInfo[] = {
 };
 
 
-/**
- * Recursively free an IR tree.
- */
-static void
-_slang_free_ir_tree(slang_ir_node *n)
-{
-#if 1
-   GLuint i;
-   if (!n)
-      return;
-   for (i = 0; i < 3; i++)
-      _slang_free_ir_tree(n->Children[i]);
-   /* Do not free n->List since it's a child elsewhere */
-   free(n);
-#endif
-}
-
-
 static slang_ir_node *
 new_node3(slang_ir_opcode op,
           slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
@@ -1639,7 +1621,7 @@ _slang_gen_select(slang_assemble_ctx *A,
    tree = new_seq(ifNode, tmpVar);
    tree = new_seq(tmpDecl, tree);
 
-   slang_print_ir(tree, 10);
+   /*_slang_print_ir_tree(tree, 10);*/
    return tree;
 }
 
@@ -2835,7 +2817,7 @@ _slang_codegen_function(slang_assemble_c
 #endif
 #if 0
    printf("************* IR for %s *******\n", (char*)fun->header.a_name);
-   slang_print_ir(n, 0);
+   _slang_print_ir_tree(n, 0);
 #endif
 #if 0
    printf("************* End codegen function ************\n\n");
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6ec20da..ace68d1 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -66,102 +66,6 @@ typedef struct
 } slang_emit_info;
 
 
-/**
- * Assembly and IR info
- */
-typedef struct
-{
-   slang_ir_opcode IrOpcode;
-   const char *IrName;
-   gl_inst_opcode InstOpcode;
-   GLuint ResultSize, NumParams;
-} slang_ir_info;
-
-
-
-static const slang_ir_info IrInfo[] = {
-   /* binary ops */
-   { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
-   { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
-   { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
-   { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
-   { IR_DOT4, "IR_DOT_4", OPCODE_DP4, 1, 2 },
-   { IR_DOT3, "IR_DOT_3", OPCODE_DP3, 1, 2 },
-   { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
-   { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
-   { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
-   { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
-   { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
-   { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
-   { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
-   { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
-   { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
-   { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
-   { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
-   { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
-   /* unary ops */
-   { IR_I_TO_F, "IR_I_TO_F", OPCODE_NOP, 1, 1 },
-   { IR_F_TO_I, "IR_F_TO_I", OPCODE_INT, 4, 1 }, /* 4 floats to 4 ints */
-   { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
-   { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
-   { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
-   { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
-   { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
-   { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
-   { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
-   { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
-   { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
-   { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
-   { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 },
-   { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
-   { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
-   { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
-   { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
-   { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
-   { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
-
-   /* other */
-   { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
-   { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
-   { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
-   { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
-   { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
-   { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
-   { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
-   { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
-   { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 },
-   { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
-   { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
-   { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
-   { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
-   { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
-   { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
-   { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
-   { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
-   { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
-   { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
-   { IR_NOP, NULL, OPCODE_NOP, 0, 0 }
-};
-
-
-static const slang_ir_info *
-slang_find_ir_info(slang_ir_opcode opcode)
-{
-   GLuint i;
-   for (i = 0; IrInfo[i].IrName; i++) {
-      if (IrInfo[i].IrOpcode == opcode) {
-	 return IrInfo + i;
-      }
-   }
-   return NULL;
-}
-
-static const char *
-slang_ir_name(slang_ir_opcode opcode)
-{
-   return slang_find_ir_info(opcode)->IrName;
-}
-
 
 /**
  * Swizzle a swizzle.  That is, return swz2(swz1)
@@ -194,221 +98,6 @@ _slang_new_ir_storage(enum register_file
 }
 
 
-static const char *
-swizzle_string(GLuint swizzle)
-{
-   static char s[6];
-   GLuint i;
-   s[0] = '.';
-   for (i = 1; i < 5; i++) {
-      s[i] = "xyzw"[GET_SWZ(swizzle, i-1)];
-   }
-   s[i] = 0;
-   return s;
-}
-
-static const char *
-writemask_string(GLuint writemask)
-{
-   static char s[6];
-   GLuint i, j = 0;
-   s[j++] = '.';
-   for (i = 0; i < 4; i++) {
-      if (writemask & (1 << i))
-         s[j++] = "xyzw"[i];
-   }
-   s[j] = 0;
-   return s;
-}
-
-static const char *
-storage_string(const slang_ir_storage *st)
-{
-   static const char *files[] = {
-      "TEMP",
-      "LOCAL_PARAM",
-      "ENV_PARAM",
-      "STATE",
-      "INPUT",
-      "OUTPUT",
-      "NAMED_PARAM",
-      "CONSTANT",
-      "UNIFORM",
-      "WRITE_ONLY",
-      "ADDRESS",
-      "SAMPLER",
-      "UNDEFINED"
-   };
-   static char s[100];
-#if 0
-   if (st->Size == 1)
-      sprintf(s, "%s[%d]", files[st->File], st->Index);
-   else
-      sprintf(s, "%s[%d..%d]", files[st->File], st->Index,
-              st->Index + st->Size - 1);
-#endif
-   assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
-   sprintf(s, "%s[%d]", files[st->File], st->Index);
-   return s;
-}
-
-
-static void
-spaces(int n)
-{
-   while (n-- > 0) {
-      printf(" ");
-   }
-}
-
-#define IND 0
-void
-slang_print_ir(const slang_ir_node *n, int indent)
-{
-   if (!n)
-      return;
-#if !IND
-   if (n->Opcode != IR_SEQ)
-#else
-      printf("%3d:", indent);
-#endif
-      spaces(indent);
-
-   switch (n->Opcode) {
-   case IR_SEQ:
-#if IND
-      printf("SEQ  at %p\n", (void*) n);
-#endif
-      assert(n->Children[0]);
-      assert(n->Children[1]);
-      slang_print_ir(n->Children[0], indent + IND);
-      slang_print_ir(n->Children[1], indent + IND);
-      break;
-   case IR_SCOPE:
-      printf("NEW SCOPE\n");
-      assert(!n->Children[1]);
-      slang_print_ir(n->Children[0], indent + 3);
-      break;
-   case IR_MOVE:
-      printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask));
-      slang_print_ir(n->Children[0], indent+3);
-      slang_print_ir(n->Children[1], indent+3);
-      break;
-   case IR_LABEL:
-      printf("LABEL: %s\n", n->Label->Name);
-      break;
-   case IR_COND:
-      printf("COND\n");
-      slang_print_ir(n->Children[0], indent + 3);
-      break;
-   case IR_JUMP:
-      printf("JUMP %s\n", n->Label->Name);
-      break;
-
-   case IR_IF:
-      printf("IF \n");
-      slang_print_ir(n->Children[0], indent+3);
-      spaces(indent);
-      printf("THEN\n");
-      slang_print_ir(n->Children[1], indent+3);
-      if (n->Children[2]) {
-         spaces(indent);
-         printf("ELSE\n");
-         slang_print_ir(n->Children[2], indent+3);
-      }
-      spaces(indent);
-      printf("ENDIF\n");
-      break;
-
-   case IR_BEGIN_SUB:
-      printf("BEGIN_SUB\n");
-      break;
-   case IR_END_SUB:
-      printf("END_SUB\n");
-      break;
-   case IR_RETURN:
-      printf("RETURN\n");
-      break;
-   case IR_CALL:
-      printf("CALL\n");
-      break;
-
-   case IR_LOOP:
-      printf("LOOP\n");
-      slang_print_ir(n->Children[0], indent+3);
-      if (n->Children[1]) {
-         spaces(indent);
-         printf("TAIL:\n");
-         slang_print_ir(n->Children[1], indent+3);
-      }
-      spaces(indent);
-      printf("ENDLOOP\n");
-      break;
-   case IR_CONT:
-      printf("CONT\n");
-      break;
-   case IR_BREAK:
-      printf("BREAK\n");
-      break;
-   case IR_BREAK_IF_FALSE:
-      printf("BREAK_IF_FALSE\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_BREAK_IF_TRUE:
-      printf("BREAK_IF_TRUE\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_CONT_IF_FALSE:
-      printf("CONT_IF_FALSE\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_CONT_IF_TRUE:
-      printf("CONT_IF_TRUE\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-
-   case IR_VAR:
-      printf("VAR %s%s at %s  store %p\n",
-             (n->Var ? (char *) n->Var->a_name : "TEMP"),
-             swizzle_string(n->Store->Swizzle),
-             storage_string(n->Store), (void*) n->Store);
-      break;
-   case IR_VAR_DECL:
-      printf("VAR_DECL %s (%p) at %s  store %p\n",
-             (n->Var ? (char *) n->Var->a_name : "TEMP"),
-             (void*) n->Var, storage_string(n->Store),
-             (void*) n->Store);
-      break;
-   case IR_FIELD:
-      printf("FIELD %s of\n", n->Field);
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_FLOAT:
-      printf("FLOAT %g %g %g %g\n",
-             n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
-      break;
-   case IR_I_TO_F:
-      printf("INT_TO_FLOAT\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_F_TO_I:
-      printf("FLOAT_TO_INT\n");
-      slang_print_ir(n->Children[0], indent+3);
-      break;
-   case IR_SWIZZLE:
-      printf("SWIZZLE %s of  (store %p) \n",
-             swizzle_string(n->Store->Swizzle), (void*) n->Store);
-      slang_print_ir(n->Children[0], indent + 3);
-      break;
-   default:
-      printf("%s (%p, %p)  (store %p)\n", slang_ir_name(n->Opcode),
-             (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
-      slang_print_ir(n->Children[0], indent+3);
-      slang_print_ir(n->Children[1], indent+3);
-   }
-}
-
-
 /**
  * Allocate temporary storage for an intermediate result (such as for
  * a multiply or add, etc.
@@ -713,7 +402,7 @@ static struct prog_instruction *
 emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    struct prog_instruction *inst;
-   const slang_ir_info *info = slang_find_ir_info(n->Opcode);
+   const slang_ir_info *info = _slang_ir_info(n->Opcode);
    char *srcAnnot[3], *dstAnnot;
    GLuint i;
 
@@ -1347,8 +1036,6 @@ emit_loop(slang_emit_info *emitInfo, sla
    GLuint beginInstLoc, tailInstLoc, endInstLoc;
    slang_ir_node *ir;
 
-   slang_print_ir(n, 10);
-
    /* emit OPCODE_BGNLOOP */
    beginInstLoc = prog->NumInstructions;
    if (emitInfo->EmitHighLevelInstructions) {
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 37dd38e..2b7d822 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -175,4 +175,30 @@ typedef struct slang_ir_node_
 } slang_ir_node;
 
 
+
+/**
+ * Assembly and IR info
+ */
+typedef struct
+{
+   slang_ir_opcode IrOpcode;
+   const char *IrName;
+   gl_inst_opcode InstOpcode;
+   GLuint ResultSize, NumParams;
+} slang_ir_info;
+
+
+
+extern const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode);
+
+
+extern void
+_slang_free_ir_tree(slang_ir_node *n);
+
+
+extern void
+_slang_print_ir_tree(const slang_ir_node *n, int indent);
+
+
 #endif /* SLANG_IR_H */
diff --git a/src/mesa/sources b/src/mesa/sources
index 628599c..73fd581 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -179,6 +179,7 @@ SLANG_SOURCES =	\
 	shader/slang/slang_compile_struct.c	\
 	shader/slang/slang_compile_variable.c	\
 	shader/slang/slang_emit.c	\
+	shader/slang/slang_ir.c	\
 	shader/slang/slang_label.c	\
 	shader/slang/slang_library_noise.c	\
 	shader/slang/slang_link.c	\
diff-tree b2bc563142c93fd9bfa503f7b9e5e99c7d450ccc (from 8f9db0f81c13c3244f07333f33a15bfe098e0f31)
Author: Brian <brian at yutani.localnet.net>
Date:   Sat Mar 24 09:39:24 2007 -0600

    IR utility functions

diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
new file mode 100644
index 0000000..5790d0a
--- /dev/null
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -0,0 +1,354 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "imports.h"
+#include "context.h"
+#include "slang_ir.h"
+#include "prog_print.h"
+
+
+static const slang_ir_info IrInfo[] = {
+   /* binary ops */
+   { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
+   { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
+   { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
+   { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
+   { IR_DOT4, "IR_DOT_4", OPCODE_DP4, 1, 2 },
+   { IR_DOT3, "IR_DOT_3", OPCODE_DP3, 1, 2 },
+   { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
+   { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
+   { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
+   { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
+   { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
+   { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
+   { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
+   { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
+   { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
+   { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
+   { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
+   { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
+   /* unary ops */
+   { IR_I_TO_F, "IR_I_TO_F", OPCODE_NOP, 1, 1 },
+   { IR_F_TO_I, "IR_F_TO_I", OPCODE_INT, 4, 1 }, /* 4 floats to 4 ints */
+   { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
+   { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
+   { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
+   { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
+   { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
+   { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
+   { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
+   { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
+   { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
+   { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
+   { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 },
+   { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
+   { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
+   { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
+   { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
+   { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
+   { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
+
+   /* other */
+   { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
+   { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
+   { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
+   { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
+   { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
+   { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
+   { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
+   { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
+   { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 },
+   { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
+   { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
+   { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
+   { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
+   { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
+   { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
+   { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
+   { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
+   { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
+   { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
+   { IR_NOP, NULL, OPCODE_NOP, 0, 0 }
+};
+
+
+const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode)
+{
+   GLuint i;
+   for (i = 0; IrInfo[i].IrName; i++) {
+      if (IrInfo[i].IrOpcode == opcode) {
+	 return IrInfo + i;
+      }
+   }
+   return NULL;
+}
+
+static const char *
+slang_ir_name(slang_ir_opcode opcode)
+{
+   return _slang_ir_info(opcode)->IrName;
+}
+
+
+
+/**
+ * Recursively free an IR tree.
+ */
+void
+_slang_free_ir_tree(slang_ir_node *n)
+{
+#if 1
+   GLuint i;
+   if (!n)
+      return;
+   for (i = 0; i < 3; i++)
+      _slang_free_ir_tree(n->Children[i]);
+   /* Do not free n->List since it's a child elsewhere */
+   free(n);
+#endif
+}
+
+
+
+
+
+
+static const char *
+swizzle_string(GLuint swizzle)
+{
+   static char s[6];
+   GLuint i;
+   s[0] = '.';
+   for (i = 1; i < 5; i++) {
+      s[i] = "xyzw"[GET_SWZ(swizzle, i-1)];
+   }
+   s[i] = 0;
+   return s;
+}
+
+static const char *
+writemask_string(GLuint writemask)
+{
+   static char s[6];
+   GLuint i, j = 0;
+   s[j++] = '.';
+   for (i = 0; i < 4; i++) {
+      if (writemask & (1 << i))
+         s[j++] = "xyzw"[i];
+   }
+   s[j] = 0;
+   return s;
+}
+
+static const char *
+storage_string(const slang_ir_storage *st)
+{
+   static const char *files[] = {
+      "TEMP",
+      "LOCAL_PARAM",
+      "ENV_PARAM",
+      "STATE",
+      "INPUT",
+      "OUTPUT",
+      "NAMED_PARAM",
+      "CONSTANT",
+      "UNIFORM",
+      "WRITE_ONLY",
+      "ADDRESS",
+      "SAMPLER",
+      "UNDEFINED"
+   };
+   static char s[100];
+#if 0
+   if (st->Size == 1)
+      sprintf(s, "%s[%d]", files[st->File], st->Index);
+   else
+      sprintf(s, "%s[%d..%d]", files[st->File], st->Index,
+              st->Index + st->Size - 1);
+#endif
+   assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
+   sprintf(s, "%s[%d]", files[st->File], st->Index);
+   return s;
+}
+
+
+static void
+spaces(int n)
+{
+   while (n-- > 0) {
+      printf(" ");
+   }
+}
+
+
+#define IND 0
+
+
+void
+_slang_print_ir_tree(const slang_ir_node *n, int indent)
+{
+   if (!n)
+      return;
+#if !IND
+   if (n->Opcode != IR_SEQ)
+#else
+      printf("%3d:", indent);
+#endif
+      spaces(indent);
+
+   switch (n->Opcode) {
+   case IR_SEQ:
+#if IND
+      printf("SEQ  at %p\n", (void*) n);
+#endif
+      assert(n->Children[0]);
+      assert(n->Children[1]);
+      _slang_print_ir_tree(n->Children[0], indent + IND);
+      _slang_print_ir_tree(n->Children[1], indent + IND);
+      break;
+   case IR_SCOPE:
+      printf("NEW SCOPE\n");
+      assert(!n->Children[1]);
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+   case IR_MOVE:
+      printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask));
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      _slang_print_ir_tree(n->Children[1], indent+3);
+      break;
+   case IR_LABEL:
+      printf("LABEL: %s\n", n->Label->Name);
+      break;
+   case IR_COND:
+      printf("COND\n");
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+   case IR_JUMP:
+      printf("JUMP %s\n", n->Label->Name);
+      break;
+
+   case IR_IF:
+      printf("IF \n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      spaces(indent);
+      printf("THEN\n");
+      _slang_print_ir_tree(n->Children[1], indent+3);
+      if (n->Children[2]) {
+         spaces(indent);
+         printf("ELSE\n");
+         _slang_print_ir_tree(n->Children[2], indent+3);
+      }
+      spaces(indent);
+      printf("ENDIF\n");
+      break;
+
+   case IR_BEGIN_SUB:
+      printf("BEGIN_SUB\n");
+      break;
+   case IR_END_SUB:
+      printf("END_SUB\n");
+      break;
+   case IR_RETURN:
+      printf("RETURN\n");
+      break;
+   case IR_CALL:
+      printf("CALL\n");
+      break;
+
+   case IR_LOOP:
+      printf("LOOP\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      if (n->Children[1]) {
+         spaces(indent);
+         printf("TAIL:\n");
+         _slang_print_ir_tree(n->Children[1], indent+3);
+      }
+      spaces(indent);
+      printf("ENDLOOP\n");
+      break;
+   case IR_CONT:
+      printf("CONT\n");
+      break;
+   case IR_BREAK:
+      printf("BREAK\n");
+      break;
+   case IR_BREAK_IF_FALSE:
+      printf("BREAK_IF_FALSE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_BREAK_IF_TRUE:
+      printf("BREAK_IF_TRUE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_CONT_IF_FALSE:
+      printf("CONT_IF_FALSE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_CONT_IF_TRUE:
+      printf("CONT_IF_TRUE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+
+   case IR_VAR:
+      printf("VAR %s%s at %s  store %p\n",
+             (n->Var ? (char *) n->Var->a_name : "TEMP"),
+             swizzle_string(n->Store->Swizzle),
+             storage_string(n->Store), (void*) n->Store);
+      break;
+   case IR_VAR_DECL:
+      printf("VAR_DECL %s (%p) at %s  store %p\n",
+             (n->Var ? (char *) n->Var->a_name : "TEMP"),
+             (void*) n->Var, storage_string(n->Store),
+             (void*) n->Store);
+      break;
+   case IR_FIELD:
+      printf("FIELD %s of\n", n->Field);
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_FLOAT:
+      printf("FLOAT %g %g %g %g\n",
+             n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
+      break;
+   case IR_I_TO_F:
+      printf("INT_TO_FLOAT\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_F_TO_I:
+      printf("FLOAT_TO_INT\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_SWIZZLE:
+      printf("SWIZZLE %s of  (store %p) \n",
+             swizzle_string(n->Store->Swizzle), (void*) n->Store);
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+   default:
+      printf("%s (%p, %p)  (store %p)\n", slang_ir_name(n->Opcode),
+             (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      _slang_print_ir_tree(n->Children[1], indent+3);
+   }
+}



More information about the mesa-commit mailing list