mesa: Branch 'master' - 5 commits

Brian Paul brianp at kemper.freedesktop.org
Wed Mar 28 17:11:06 UTC 2007


 configs/default                       |    2 
 src/mesa/shader/prog_execute.c        |    7 +
 src/mesa/shader/prog_print.c          |   23 ++----
 src/mesa/shader/prog_print.h          |    3 
 src/mesa/shader/slang/slang_codegen.c |   34 +++++++++
 src/mesa/shader/slang/slang_emit.c    |  125 +++++++++++++++++++++-------------
 6 files changed, 134 insertions(+), 60 deletions(-)

New commits:
diff-tree dad97b4688ea25caf15cae66194db6ddbb98e936 (from a01616eed52aa4dfe3b6850b76a4cd8de119a3f3)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 28 11:06:34 2007 -0600

    Fix, clean-up code related to comparisons, condition codes, etc.

diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 64163c4..cbc71f3 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -86,6 +86,25 @@ new_subroutine(slang_emit_info *emitInfo
 }
 
 
+/**
+ * Convert a writemask to a swizzle.  Used for testing cond codes because
+ * we only want to test the cond code component(s) that was set by the
+ * previous instruction.
+ */
+static GLuint
+writemask_to_swizzle(GLuint writemask)
+{
+   if (writemask == WRITEMASK_X)
+      return SWIZZLE_XXXX;
+   if (writemask == WRITEMASK_Y)
+      return SWIZZLE_YYYY;
+   if (writemask == WRITEMASK_Z)
+      return SWIZZLE_ZZZZ;
+   if (writemask == WRITEMASK_W)
+      return SWIZZLE_WWWW;
+   return SWIZZLE_XYZW;  /* shouldn't be hit */
+}
+
 
 /**
  * Swizzle a swizzle.  That is, return swz2(swz1)
@@ -152,6 +171,8 @@ free_temp_storage(slang_var_table *vt, s
          _slang_free_temp(vt, n->Store);
          n->Store->Index = -1;
          n->Store->Size = -1;
+         _mesa_free(n->Store);
+         n->Store = NULL;
       }
    }
 }
@@ -485,6 +506,7 @@ emit_arith(slang_emit_info *emitInfo, sl
 
    /* result storage */
    if (!n->Store) {
+      /* XXX this size isn't correct, it depends on the operands */
       if (!alloc_temp_storage(emitInfo, n, info->ResultSize))
          return NULL;
    }
@@ -542,8 +564,9 @@ emit_compare(slang_emit_info *emitInfo, 
       
       assert(zeroReg >= 0);
 
+      assert(!n->Store);
       if (!n->Store) {
-         if (!alloc_temp_storage(emitInfo, n, 4))  /* 4 bools */
+         if (!alloc_temp_storage(emitInfo, n, size))  /* 'size' bools */
             return NULL;
       }
 
@@ -561,34 +584,32 @@ emit_compare(slang_emit_info *emitInfo, 
          swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y);
       }
 
-      /* Compute equality, inequality */
+      /* Compute equality, inequality (tmp1 = (A ?= B)) */
       inst = new_instruction(emitInfo, OPCODE_SNE);
       storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
       storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store);
       storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
       inst->Comment = _mesa_strdup("Compare values");
-      /* compute D = DP4(D, D)  (reduction) */
+
+      /* Compute tmp2 = DOT(tmp1, tmp1)  (reduction) */
       inst = new_instruction(emitInfo, dotOp);
-      inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-      inst->SrcReg[0].Index = n->Store->Index;
-      inst->SrcReg[0].Swizzle = swizzle;
-      inst->SrcReg[1].File = PROGRAM_TEMPORARY;
-      inst->SrcReg[1].Index = n->Store->Index;
-      inst->SrcReg[1].Swizzle = swizzle;
-      inst->DstReg.File = PROGRAM_TEMPORARY;
-      inst->DstReg.Index = n->Store->Index;
+      storage_to_src_reg(&inst->SrcReg[0], n->Store);
+      storage_to_src_reg(&inst->SrcReg[1], n->Store);
+      inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
+      free_temp_storage(emitInfo->vt, n); /* free tmp1 */
+      if (!alloc_temp_storage(emitInfo, n, 1))  /* alloc tmp2 */
+         return NULL;
+      storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
       inst->Comment = _mesa_strdup("Reduce vec to bool");
+
       if (n->Opcode == IR_EQUAL) {
-         /* compute D.x = !D.x  via D.x = (D.x == 0) */
+         /* compute tmp2.x = !tmp2.x  via tmp2.x = (tmp2.x == 0) */
          inst = new_instruction(emitInfo, OPCODE_SEQ);
-         inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-         inst->SrcReg[0].Index = n->Store->Index;
+         storage_to_src_reg(&inst->SrcReg[0], n->Store);
          inst->SrcReg[1].File = PROGRAM_CONSTANT;
          inst->SrcReg[1].Index = zeroReg;
          inst->SrcReg[1].Swizzle = zeroSwizzle;
-         inst->DstReg.File = PROGRAM_TEMPORARY;
-         inst->DstReg.Index = n->Store->Index;
-         inst->DstReg.WriteMask = WRITEMASK_X;
+         storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
          inst->Comment = _mesa_strdup("Invert true/false");
       }
    }
@@ -757,6 +778,11 @@ emit_func(slang_emit_info *emitInfo, sla
                              emitInfo->prog);
 
    if (emitInfo->EmitBeginEndSub) {
+      /* BGNSUB isn't a real instruction.
+       * We require a label (i.e. "foobar:") though, if we're going to
+       * print the program in the NV format.  The BNGSUB instruction is
+       * really just a NOP to attach the label to.
+       */
       inst = new_instruction(emitInfo, OPCODE_BGNSUB);
       inst->Comment = _mesa_strdup(n->Label->Name);
    }
@@ -800,17 +826,8 @@ emit_return(slang_emit_info *emitInfo, s
    assert(n);
    assert(n->Opcode == IR_RETURN);
    assert(n->Label);
-   inst = new_instruction(emitInfo, OPCODE_RET/*BRA*/); /*XXX TEMPORARY*/
-   inst->DstReg.CondMask = COND_TR;  /* always return/branch */
-
-   if (inst->Opcode == OPCODE_BRA) {
-      inst->BranchTarget = _slang_label_get_location(n->Label);
-      if (inst->BranchTarget < 0) {
-         _slang_label_add_reference(n->Label,
-                                    emitInfo->prog->NumInstructions - 1);
-      }
-   }
-
+   inst = new_instruction(emitInfo, OPCODE_RET);
+   inst->DstReg.CondMask = COND_TR;  /* always return */
    return inst;
 }
 
@@ -949,28 +966,34 @@ emit_move(slang_emit_info *emitInfo, sla
 }
 
 
+/**
+ * An IR_COND node wraps a boolean expression which is used by an
+ * IF or WHILE test.  This is where we'll set condition codes, if needed.
+ */
 static struct prog_instruction *
 emit_cond(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    struct prog_instruction *inst;
 
+   assert(n->Opcode == IR_COND);
+
    if (!n->Children[0])
       return NULL;
 
+   /* emit code for the expression */
    inst = emit(emitInfo, n->Children[0]);
 
+   assert(n->Children[0]->Store);
+   /*assert(n->Children[0]->Store->Size == 1);*/
+
    if (emitInfo->EmitCondCodes) {
-      /* Conditional expression (in if/while/for stmts).
-       * Need to update condition code register.
-       * Next instruction is typically an IR_IF.
-       */
       if (inst &&
           n->Children[0]->Store &&
           inst->DstReg.File == n->Children[0]->Store->File &&
           inst->DstReg.Index == n->Children[0]->Store->Index) {
          /* The previous instruction wrote to the register who's value
-          * we're testing.  Just update that instruction so that the
-          * condition codes are updated.
+          * we're testing.  Just fix that instruction so that the
+          * condition codes are computed.
           */
          inst->CondUpdate = GL_TRUE;
          n->Store = n->Children[0]->Store;
@@ -980,10 +1003,8 @@ emit_cond(slang_emit_info *emitInfo, sla
          /* This'll happen for things like "if (i) ..." where no code
           * is normally generated for the expression "i".
           * Generate a move instruction just to set condition codes.
-          * Note: must use full 4-component vector since all four
-          * condition codes must be set identically.
           */
-         if (!alloc_temp_storage(emitInfo, n, 4))
+         if (!alloc_temp_storage(emitInfo, n, 1))
             return NULL;
          inst = new_instruction(emitInfo, OPCODE_MOV);
          inst->CondUpdate = GL_TRUE;
@@ -991,13 +1012,13 @@ emit_cond(slang_emit_info *emitInfo, sla
          storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
          _slang_free_temp(emitInfo->vt, n->Store);
          inst->Comment = _mesa_strdup("COND expr");
-         return inst; /* XXX or null? */
+         return inst;
       }
    }
    else {
-      /* No-op */
+      /* No-op: the boolean result of the expression is in a regular reg */
       n->Store = n->Children[0]->Store;
-      return NULL;
+      return inst;
    }
 }
 
@@ -1042,10 +1063,15 @@ static struct prog_instruction *
 emit_if(slang_emit_info *emitInfo, slang_ir_node *n)
 {
    struct gl_program *prog = emitInfo->prog;
-   struct prog_instruction *ifInst;
+   struct prog_instruction *ifInst, *inst;
    GLuint ifInstLoc, elseInstLoc = 0;
+   GLuint condWritemask = 0;
 
-   emit(emitInfo, n->Children[0]);  /* the condition */
+   inst = emit(emitInfo, n->Children[0]);  /* the condition */
+   if (emitInfo->EmitCondCodes) {
+      assert(inst);
+      condWritemask = inst->DstReg.WriteMask;
+   }
 
 #if 0
    assert(n->Children[0]->Store->Size == 1); /* a bool! */
@@ -1056,6 +1082,10 @@ emit_if(slang_emit_info *emitInfo, slang
       ifInst = new_instruction(emitInfo, OPCODE_IF);
       if (emitInfo->EmitCondCodes) {
          ifInst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
+         /* only test the cond code (1 of 4) that was updated by the
+          * previous instruction.
+          */
+         ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
       }
       else {
          /* test reg.x */
@@ -1067,10 +1097,7 @@ emit_if(slang_emit_info *emitInfo, slang
       ifInst = new_instruction(emitInfo, OPCODE_BRA);
       ifInst->DstReg.CondMask = COND_EQ;  /* BRA if cond is zero */
       ifInst->Comment = _mesa_strdup("if zero");
-   }
-   if (emitInfo->EmitCondCodes) {
-      /* which condition code to use: */
-      ifInst->DstReg.CondSwizzle = n->Children[0]->Store->Swizzle;
+      ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
    }
 
    /* if body */
@@ -1097,7 +1124,7 @@ emit_if(slang_emit_info *emitInfo, slang
    else {
       /* no else body */
       ifInst = prog->Instructions + ifInstLoc;
-      ifInst->BranchTarget = prog->NumInstructions + 1;
+      ifInst->BranchTarget = prog->NumInstructions /*+ 1*/;
    }
 
    if (emitInfo->EmitHighLevelInstructions) {
@@ -1736,6 +1763,10 @@ _slang_emit_code(slang_ir_node *n, slang
    emitInfo.EmitComments = ctx->Shader.EmitComments;
    emitInfo.EmitBeginEndSub = 0;  /* XXX for compiler debug only */
 
+   if (!emitInfo.EmitCondCodes) {
+      emitInfo.EmitHighLevelInstructions = GL_TRUE;
+   }      
+
    (void) emit(&emitInfo, n);
 
    /* finish up by adding the END opcode to program */
diff-tree a01616eed52aa4dfe3b6850b76a4cd8de119a3f3 (from d750861dc26e3898afa2b49e3969d709dc227664)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 28 11:01:28 2007 -0600

    print condcodes if DEBUG_PROG

diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index 0438d6a..7908976 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -508,6 +508,13 @@ store_vector4(const struct prog_instruct
          machine->CondCodes[2] = generate_cc(value[2]);
       if (writeMask & WRITEMASK_W)
          machine->CondCodes[3] = generate_cc(value[3]);
+#if DEBUG_PROG
+      printf("CondCodes=(%s,%s,%s,%s) for:\n",
+             _mesa_condcode_string(machine->CondCodes[0]),
+             _mesa_condcode_string(machine->CondCodes[1]),
+             _mesa_condcode_string(machine->CondCodes[2]),
+             _mesa_condcode_string(machine->CondCodes[3]));
+#endif
    }
 }
 
diff-tree d750861dc26e3898afa2b49e3969d709dc227664 (from 59f7f6dbe9e197482f6b5e50c6a910f86c4f6694)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 28 11:01:09 2007 -0600

    expose _mesa_condcode_string(), fix some printing

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 4ecdc82..a43bebb 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -361,8 +361,8 @@ writemask_string(GLuint writeMask)
 }
 
 
-static const char *
-condcode_string(GLuint condcode)
+const char *
+_mesa_condcode_string(GLuint condcode)
 {
    switch (condcode) {
    case COND_GT:  return "GT";
@@ -390,7 +390,7 @@ print_dst_reg(const struct prog_dst_regi
 
    if (dstReg->CondMask != COND_TR) {
       _mesa_printf(" (%s.%s)",
-                   condcode_string(dstReg->CondMask),
+                   _mesa_condcode_string(dstReg->CondMask),
                    _mesa_swizzle_string(dstReg->CondSwizzle, GL_FALSE, GL_FALSE));
    }
 
@@ -561,9 +561,9 @@ _mesa_print_instruction_opt(const struct
       print_comment(inst);
       break;
    case OPCODE_BRA:
-      _mesa_printf("BRA %u (%s%s)",
+      _mesa_printf("BRA %d (%s%s)",
                    inst->BranchTarget,
-                   condcode_string(inst->DstReg.CondMask),
+                   _mesa_condcode_string(inst->DstReg.CondMask),
                    _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
       print_comment(inst);
       break;
@@ -577,7 +577,7 @@ _mesa_print_instruction_opt(const struct
       else {
          /* Use cond codes */
          _mesa_printf("IF (%s%s);",
-                      condcode_string(inst->DstReg.CondMask),
+                      _mesa_condcode_string(inst->DstReg.CondMask),
                       _mesa_swizzle_string(inst->DstReg.CondSwizzle,
                                            0, GL_FALSE));
       }
@@ -600,7 +600,7 @@ _mesa_print_instruction_opt(const struct
    case OPCODE_CONT:
       _mesa_printf("%s (%s%s); # (goto %d)",
                    _mesa_opcode_string(inst->Opcode),
-                   condcode_string(inst->DstReg.CondMask),
+                   _mesa_condcode_string(inst->DstReg.CondMask),
                    _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
                    inst->BranchTarget);
       print_comment(inst);
@@ -635,7 +635,7 @@ _mesa_print_instruction_opt(const struct
       break;
    case OPCODE_CAL:
       if (mode == PROG_PRINT_NV) {
-         _mesa_printf("CAL %s;\n", inst->Comment);
+         _mesa_printf("CAL %s;  # (goto %d)\n", inst->Comment, inst->BranchTarget);
       }
       else {
          _mesa_printf("CAL %u", inst->BranchTarget);
@@ -643,10 +643,9 @@ _mesa_print_instruction_opt(const struct
       }
       break;
    case OPCODE_RET:
-      _mesa_printf("RET (%s%s); # (goto %d)",
-                   condcode_string(inst->DstReg.CondMask),
-                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
-                   inst->BranchTarget);
+      _mesa_printf("RET (%s%s)",
+                   _mesa_condcode_string(inst->DstReg.CondMask),
+                   _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
       print_comment(inst);
       break;
 
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
index 9c7607f..36c47e0 100644
--- a/src/mesa/shader/prog_print.h
+++ b/src/mesa/shader/prog_print.h
@@ -38,6 +38,9 @@ typedef enum {
 
 
 extern const char *
+_mesa_condcode_string(GLuint condcode);
+
+extern const char *
 _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
 
 extern void
diff-tree 59f7f6dbe9e197482f6b5e50c6a910f86c4f6694 (from 20d85c609a86146b2992a05a26603c8de4a2a4f0)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 28 10:44:38 2007 -0600

    check that if/while/do-while condition is boolean or scalar

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index cf3569c..bd403b7 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -1363,6 +1363,22 @@ _slang_is_constant_cond(const slang_oper
 }
 
 
+/**
+ * Test if an operation is a scalar or boolean.
+ */
+static GLboolean
+_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_typeinfo type;
+   GLint size;
+
+   slang_typeinfo_construct(&type);
+   _slang_typeof_operation(A, oper, &type);
+   size = _slang_sizeof_type_specifier(&type.spec);
+   slang_typeinfo_destruct(&type);
+   return size == 1;
+}
+
 
 /**
  * Generate loop code using high-level IR_LOOP instruction
@@ -1378,6 +1394,12 @@ _slang_gen_while(slang_assemble_ctx * A,
    slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body;
    GLboolean isConst, constTrue;
 
+   /* type-check expression */
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'");
+      return NULL;
+   }
+
    /* Check if loop condition is a constant */
    isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
 
@@ -1434,6 +1456,12 @@ _slang_gen_do(slang_assemble_ctx * A, co
    slang_ir_node *prevLoop, *loop, *cond;
    GLboolean isConst, constTrue;
 
+   /* type-check expression */
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[1])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'");
+      return NULL;
+   }
+
    loop = new_loop(NULL);
 
    /* save old, push new loop */
@@ -1556,6 +1584,12 @@ _slang_gen_if(slang_assemble_ctx * A, co
    slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
    GLboolean isConst, constTrue;
 
+   /* type-check expression */
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'if'");
+      return NULL;
+   }
+
    isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
    if (isConst) {
       if (constTrue) {
diff-tree 20d85c609a86146b2992a05a26603c8de4a2a4f0 (from ad766b5785c728e988e25509604c08fc347aba23)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 28 09:07:41 2007 -0600

    bump version to 6.5.3 to match version.h

diff --git a/configs/default b/configs/default
index e805925..72176f1 100644
--- a/configs/default
+++ b/configs/default
@@ -10,7 +10,7 @@ CONFIG_NAME = default
 # Version info
 MESA_MAJOR=6
 MESA_MINOR=5
-MESA_TINY=2
+MESA_TINY=3
 
 # external projects.  This should be useless now that we use libdrm.
 DRM_SOURCE_PATH=$(TOP)/../drm



More information about the mesa-commit mailing list