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

Brian Paul brianp at kemper.freedesktop.org
Mon Feb 5 22:01:02 UTC 2007


 src/mesa/shader/prog_instruction.c    |    6 ++
 src/mesa/shader/prog_instruction.h    |   12 +++-
 src/mesa/shader/prog_print.c          |   56 +++++++++++++++---
 src/mesa/shader/prog_print.h          |    6 +-
 src/mesa/shader/slang/slang_codegen.c |   93 ++++++++++++++++++++++++++++---
 src/mesa/shader/slang/slang_emit.c    |  101 ++++++++++++++++++++++++++++++++--
 src/mesa/shader/slang/slang_ir.h      |   25 +++++++-
 src/mesa/swrast/s_fragprog.c          |   49 ++++++++++++++--
 src/mesa/tnl/t_vb_arbprogram.c        |    6 ++
 src/mesa/tnl/t_vp_build.c             |    2 
 10 files changed, 320 insertions(+), 36 deletions(-)

New commits:
diff-tree 5e73284cee882bc3463e013c9b468a9b84c6dbc1 (from cf92c727979e434d148b23d20f2e4e0f4bc4de61)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 15:00:48 2007 -0700

    set UseHighLevelInstructions = false for now

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 2dd9ccc..c70f73f 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -47,7 +47,7 @@
 #include "slang_print.h"
 
 
-static GLboolean UseHighLevelInstructions = GL_TRUE;
+static GLboolean UseHighLevelInstructions = GL_FALSE;
 
 static slang_ir_node *
 _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
diff-tree cf92c727979e434d148b23d20f2e4e0f4bc4de61 (from 5db088d70fbd14620c2fc7840096a05993f8e2b9)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 15:00:07 2007 -0700

    Initial implementation of high-level flow-control instructions.
    
    IF/ELSE/ENDIF and BEGIN_LOOP/END_LOOP/BREAK instructions seem to work.
    Disabled by default though until better tested.
    Implemented IR_NOT, but needs optimization.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 72f58a9..2dd9ccc 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -47,6 +47,8 @@
 #include "slang_print.h"
 
 
+static GLboolean UseHighLevelInstructions = GL_TRUE;
+
 static slang_ir_node *
 _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
 
@@ -506,6 +508,7 @@ new_node(slang_ir_opcode op, slang_ir_no
       n->Children[0] = left;
       n->Children[1] = right;
       n->Writemask = WRITEMASK_XYZW;
+      n->InstLocation = -1;
    }
    return n;
 }
@@ -567,6 +570,26 @@ new_jump(slang_atom target)
 }
 
 
+static slang_ir_node *
+new_begin_loop(void)
+{
+   slang_ir_node *n = new_node(IR_BEGIN_LOOP, NULL, NULL);
+   return n;
+}
+
+
+static slang_ir_node *
+new_end_loop(slang_ir_node *beginNode)
+{
+   slang_ir_node *n = new_node(IR_END_LOOP, NULL, NULL);
+   assert(beginNode);
+   if (n) {
+      n->BranchNode = beginNode;
+   }
+   return n;
+}
+
+
 /**
  * New IR_VAR node - a reference to a previously declared variable.
  */
@@ -1304,7 +1327,7 @@ _slang_gen_function_call_name(slang_asse
 
 
 /**
- * Generate IR tree for a while-loop.
+ * Generate IR tree for a while-loop.  Use BRA-nch instruction.
  */
 static slang_ir_node *
 _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper)
@@ -1313,7 +1336,7 @@ _slang_gen_while(slang_assemble_ctx * A,
     * label "__startWhile"
     * eval expr (child[0]), updating condcodes
     * branch if false to "__endWhile"
-    * code body
+    * body code
     * jump "__startWhile"
     * label "__endWhile"
     */
@@ -1354,6 +1377,51 @@ _slang_gen_while(slang_assemble_ctx * A,
 
 
 /**
+ * Generate IR tree for a while-loop using high-level BGNLOOP/ENDLOOP,
+ * IF/ENDIF instructions.
+ */
+static slang_ir_node *
+_slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   /*
+    * BGNLOOP
+    *    eval expr (child[0]), updating condcodes
+    *    IF !expr THEN
+    *       BRK
+    *    ENDIF
+    *    body code
+    * ENDLOOP
+    */
+   slang_ir_node *beginLoop, *endLoop, *ifThen, *endif;
+   slang_ir_node *brk, *cond, *body, *tree;
+
+   beginLoop = new_begin_loop();
+
+   cond = _slang_gen_operation(A, &oper->children[0]);
+   cond = new_node(IR_NOT, cond, NULL);
+   cond = _slang_gen_cond(cond);
+
+   ifThen = new_node(IR_IF, cond, NULL);
+   tree = new_seq(beginLoop, ifThen);
+
+   brk = new_node(IR_BREAK, NULL, NULL);
+   tree = new_seq(tree, brk);
+
+   endif = new_node(IR_ENDIF, NULL, NULL);
+   tree = new_seq(tree, endif);
+
+   body = _slang_gen_operation(A, &oper->children[1]);
+   if (body)
+      tree = new_seq(tree, body);
+
+   endLoop = new_end_loop(beginLoop);
+   tree = new_seq(tree, endLoop);
+
+   return tree;
+}
+
+
+/**
  * Generate IR tree for a do-while-loop.
  */
 static slang_ir_node *
@@ -1517,7 +1585,7 @@ _slang_gen_if(slang_assemble_ctx * A, co
  * IF/ELSE/ENDIF instructions
  */
 static slang_ir_node *
-_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper)
+_slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper)
 {
    /*
     * eval expr (child[0]), updating condcodes
@@ -1529,6 +1597,10 @@ _slang_gen_if2(slang_assemble_ctx * A, c
     *    "false" code block
     * label "__endif"
     */
+   /* XXX special cases to check for:
+    * if body of conditiona is just a "break", emit a conditional break
+    * instruction.
+    */
    const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
    slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode;
    slang_ir_node *tree;
@@ -2261,7 +2333,10 @@ _slang_gen_operation(slang_assemble_ctx 
       return _slang_gen_operation(A, &oper->children[0]);
       break;
    case slang_oper_while:
-      return _slang_gen_while(A, oper);
+      if (UseHighLevelInstructions)
+         return _slang_gen_hl_while(A, oper);
+      else
+         return _slang_gen_while(A, oper);
    case slang_oper_do:
       return _slang_gen_do(A, oper);
    case slang_oper_for:
@@ -2427,8 +2502,9 @@ _slang_gen_operation(slang_assemble_ctx 
    case slang_oper_identifier:
       return _slang_gen_variable(A, oper);
    case slang_oper_if:
-      if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) {
-         return _slang_gen_if(A, oper);
+      if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB
+          && UseHighLevelInstructions) {
+         return _slang_gen_hl_if(A, oper);
       }
       else {
          /* XXX update tnl executor */
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 756bbe9..311eea1 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1006,6 +1006,42 @@ emit_cond(slang_var_table *vt, slang_ir_
 
 
 /**
+ * Logical-NOT
+ */
+static struct prog_instruction *
+emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
+{
+   GLfloat zero = 0.0;
+   slang_ir_storage st;
+   struct prog_instruction *inst;
+
+   /* need zero constant */
+   st.File = PROGRAM_CONSTANT;
+   st.Size = 1;
+   st.Index = _mesa_add_unnamed_constant(prog->Parameters, &zero,
+                                         1, &st.Swizzle);
+
+   /* child expr */
+   (void) emit(vt, n->Children[0], prog);
+   /* XXXX if child instr is SGT convert to SLE, if SEQ, SNE, etc */
+
+   if (!n->Store)
+      if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size))
+         return NULL;
+
+   inst = new_instruction(prog, OPCODE_SEQ);
+   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
+   storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
+   storage_to_src_reg(&inst->SrcReg[1], &st);
+
+   free_temp_storage(vt, n->Children[0]);
+
+   return inst;
+}
+
+
+
+/**
  * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).
  * Ex: fix_swizzle("zyNN") -> "zyyy"
  */
@@ -1202,6 +1238,9 @@ emit(slang_var_table *vt, slang_ir_node 
    case IR_COND:
       return emit_cond(vt, n, prog);
 
+   case IR_NOT:
+      return emit_not(vt, n, prog);
+
    case IR_LABEL:
       return emit_label(n->Target, prog);
    case IR_JUMP:
@@ -1235,6 +1274,39 @@ emit(slang_var_table *vt, slang_ir_node 
          return inst;
       }
 
+   case IR_BEGIN_LOOP:
+      {
+         /* save location of this instruction, used by OPCODE_ENDLOOP */
+         n->InstLocation = prog->NumInstructions;
+         (void) new_instruction(prog, OPCODE_BGNLOOP);
+      }
+      break;
+   case IR_END_LOOP:
+      {
+         struct prog_instruction *inst;
+         inst = new_instruction(prog, OPCODE_ENDLOOP);
+         assert(n->BranchNode);
+         assert(n->BranchNode->InstLocation >= 0);
+         /* The instruction BranchTarget points to top of loop */
+         inst->BranchTarget = n->BranchNode->InstLocation;
+         return inst;
+      }
+   case IR_CONT:
+      return new_instruction(prog, OPCODE_CONT);
+   case IR_BREAK:
+      {
+         struct prog_instruction *inst;
+         inst = new_instruction(prog, OPCODE_BRK);
+         inst->DstReg.CondMask = COND_TR;  /* always true */
+         return inst;
+      }
+   case IR_BEGIN_SUB:
+      return new_instruction(prog, OPCODE_BGNSUB);
+   case IR_END_SUB:
+      return new_instruction(prog, OPCODE_ENDSUB);
+   case IR_RETURN:
+      return new_instruction(prog, OPCODE_RET);
+
    default:
       _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
       abort();
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index ac1ea4d..df5fc06 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -150,6 +150,8 @@ typedef struct slang_ir_node_
    GLfloat Value[4];    /**< If Opcode == IR_FLOAT */
    slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
    slang_ir_storage *Store;  /**< location of result of this operation */
+   GLint InstLocation;  /**< Location of instruction emitted for this node */
+   struct slang_ir_node_ *BranchNode;  /**< Used for branch instructions */
 } slang_ir_node;
 
 
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 00231ae..287dd9b 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -625,7 +625,7 @@ execute_program( GLcontext *ctx,
                  GLuint column )
 {
    const GLuint MAX_EXEC = 10000;
-   GLuint pc, total = 0;
+   GLint pc, total = 0, loopDepth = 0;
 
    if (DEBUG_FRAG) {
       printf("execute fragment program --------------------\n");
@@ -642,7 +642,7 @@ execute_program( GLcontext *ctx,
       }
 
       if (DEBUG_FRAG) {
-         _mesa_print_instruction(inst);
+         _mesa_print_instruction(inst, 0);
       }
 
       switch (inst->Opcode) {
@@ -676,8 +676,13 @@ execute_program( GLcontext *ctx,
             }
             break;
          case OPCODE_BGNLOOP: /* begin loop */
+            loopDepth++;
             break;
          case OPCODE_ENDLOOP: /* end loop */
+            loopDepth--;
+            assert(loopDepth >= 0);
+            /* subtract 1 here since pc is incremented by for(pc) loop */
+            pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */
             break;
          case OPCODE_BGNSUB: /* begin subroutine */
             break;
@@ -701,7 +706,19 @@ execute_program( GLcontext *ctx,
             }
             break;
          case OPCODE_BRK: /* break out of loop */
-            /* assert inside loop */
+            if (loopDepth == 0) {
+               _mesa_problem(ctx, "BRK not inside a loop");
+            }
+            /* search for OPCODE_ENDLOOP */
+            do {
+               pc++;
+               inst = program->Base.Instructions + pc;
+               if (inst->Opcode == OPCODE_ENDLOOP) {
+                  loopDepth--;
+                  assert(loopDepth >= 0);
+                  break;
+               }
+            } while (pc < maxInst);
             break;
          case OPCODE_CAL: /* Call subroutine */
             {
@@ -880,20 +897,25 @@ execute_program( GLcontext *ctx,
                   /* do if-clause (just continue execution) */
                }
                else {
-                  /* do else-clause, or go to endif */
+                  /* search for else-clause or endif */
+                  /* XXX could encode location of the else/endif statement
+                   * in the IF instruction to avoid searching...
+                   */
                   GLint ifDepth = 1;
                   do {
                      pc++;
                      inst = program->Base.Instructions + pc;
                      if (inst->Opcode == OPCODE_END) {
                         /* mal-formed program! */
-                        abort();
+                        _mesa_problem(ctx, "END found before ELSE/ENDIF");
+                        return GL_FALSE;
                      }
                      else if (inst->Opcode == OPCODE_IF) {
+                        /* nested if */
                         ifDepth++;
                      }
                      else if (inst->Opcode == OPCODE_ELSE) {
-                        if (ifDepth == 0) {
+                        if (ifDepth == 1) {
                            /* ok, continue normal execution */
                            break;
                         }
@@ -1335,6 +1357,10 @@ execute_program( GLcontext *ctx,
                result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
                result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
                store_vector4( inst, machine, result );
+               if (DEBUG_FRAG) {
+                  printf("SGT %g %g %g %g\n",
+                         result[0], result[1], result[2], result[3]);
+               }
             }
             break;
          case OPCODE_SIN:
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index 47fed32..6fb14e7 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -497,7 +497,7 @@ static void debug_insn( struct prog_inst
       }
 	 
       _mesa_printf("%d:\t", line);
-      _mesa_print_instruction(inst);
+      _mesa_print_instruction(inst, 0);
    }
 }
 
diff-tree 5db088d70fbd14620c2fc7840096a05993f8e2b9 (from 01001d80e26143ac768115ccb2266db2b24d4fa0)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 14:58:15 2007 -0700

    indentation for program instructions (if/else, loops)

diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index 63ff84e..9474fe9 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -2,7 +2,7 @@
  * Mesa 3-D graphics library
  * Version:  6.5.3
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-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"),
@@ -238,9 +238,22 @@ _mesa_print_alu_instruction(const struct
 /**
  * Print a single vertex/fragment program instruction.
  */
-void
-_mesa_print_instruction(const struct prog_instruction *inst)
+GLint
+_mesa_print_instruction(const struct prog_instruction *inst, GLint indent)
 {
+   GLuint i;
+
+   if (inst->Opcode == OPCODE_ELSE ||
+       inst->Opcode == OPCODE_ENDIF ||
+       inst->Opcode == OPCODE_ENDLOOP ||
+       inst->Opcode == OPCODE_ENDSUB) {
+      indent -= 3;
+   }
+   assert(indent >= 0);
+   for (i = 0; i < indent; i++) {
+      _mesa_printf(" ");
+   }
+
    switch (inst->Opcode) {
    case OPCODE_PRINT:
       _mesa_printf("PRINT '%s'", inst->Data);
@@ -306,16 +319,38 @@ _mesa_print_instruction(const struct pro
       print_comment(inst);
       break;
    case OPCODE_IF:
-      _mesa_printf("  IF (%s%s)",
+      _mesa_printf("IF (%s%s)",
                    condcode_string(inst->DstReg.CondMask),
                    swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
       print_comment(inst);
-      break;
+      return indent + 3;
    case OPCODE_ELSE:
-      _mesa_printf("  ELSE;\n");
-      break;
+      _mesa_printf("ELSE;\n");
+      return indent + 3;
    case OPCODE_ENDIF:
-      _mesa_printf("  ENDIF;\n");
+      _mesa_printf("ENDIF;\n");
+      break;
+   case OPCODE_BGNLOOP:
+      _mesa_printf("LOOP;\n");
+      return indent + 3;
+   case OPCODE_ENDLOOP:
+      _mesa_printf("ENDLOOP;\n");
+      break;
+   case OPCODE_BRK:
+      /* XXX just like BRA */
+      _mesa_printf("BRK %u (%s%s)",
+                   inst->BranchTarget,
+                   condcode_string(inst->DstReg.CondMask),
+                   swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+      print_comment(inst);
+      break;
+   case OPCODE_BGNSUB:
+      _mesa_printf("SUB;\n");
+      print_comment(inst);
+      return indent + 3;
+   case OPCODE_ENDSUB:
+      _mesa_printf("ENDSUB;\n");
+      print_comment(inst);
       break;
    case OPCODE_END:
       _mesa_printf("END");
@@ -333,6 +368,7 @@ _mesa_print_instruction(const struct pro
 				  _mesa_num_inst_src_regs(inst->Opcode));
       break;
    }
+   return indent;
 }
 
 
@@ -343,10 +379,10 @@ _mesa_print_instruction(const struct pro
 void
 _mesa_print_program(const struct gl_program *prog)
 {
-   GLuint i;
+   GLuint i, indent = 0;
    for (i = 0; i < prog->NumInstructions; i++) {
       _mesa_printf("%3d: ", i);
-      _mesa_print_instruction(prog->Instructions + i);
+      indent = _mesa_print_instruction(prog->Instructions + i, indent);
    }
 }
 
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
index 8bc2c69..19aaa53 100644
--- a/src/mesa/shader/prog_print.h
+++ b/src/mesa/shader/prog_print.h
@@ -2,7 +2,7 @@
  * Mesa 3-D graphics library
  * Version:  6.5.3
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-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"),
@@ -27,8 +27,8 @@
 #define PROG_PRINT_H
 
 
-extern void
-_mesa_print_instruction(const struct prog_instruction *inst);
+extern GLint
+_mesa_print_instruction(const struct prog_instruction *inst, GLint indent);
 
 extern void
 _mesa_print_alu_instruction(const struct prog_instruction *inst,
diff-tree 01001d80e26143ac768115ccb2266db2b24d4fa0 (from dd34fe8679fa200e55cfaf8e80bbecdecea084e3)
Author: Brian <brian at yutani.localnet.net>
Date:   Mon Feb 5 11:28:15 2007 -0700

    Initial support of loop and subroutine instructions.
    
    New high-level flow-control instructions, both at IR level and GPU instructions
    for looping and subroutines.

diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
index 0523f42..c678313 100644
--- a/src/mesa/shader/prog_instruction.c
+++ b/src/mesa/shader/prog_instruction.c
@@ -120,9 +120,13 @@ static const struct instruction_info Ins
    { OPCODE_ARL,    "ARL",   1 },
    { OPCODE_ARL_NV, "ARL",   1 },
    { OPCODE_ARR,    "ARL",   1 },
+   { OPCODE_BGNLOOP,"BGNLOOP", 0 },
+   { OPCODE_BGNSUB, "BGNSUB", 0 },
    { OPCODE_BRA,    "BRA",   0 },
+   { OPCODE_BRK,    "BRK",   0 },
    { OPCODE_CAL,    "CAL",   0 },
    { OPCODE_CMP,    "CMP",   3 },
+   { OPCODE_CONT,   "CONT",  1 },
    { OPCODE_COS,    "COS",   1 },
    { OPCODE_DDX,    "DDX",   1 },
    { OPCODE_DDY,    "DDY",   1 },
@@ -133,6 +137,8 @@ static const struct instruction_info Ins
    { OPCODE_ELSE,   "ELSE",  0 },
    { OPCODE_END,    "END",   0 },
    { OPCODE_ENDIF,  "ENDIF", 0 },
+   { OPCODE_ENDLOOP,"ENDLOOP", 0 },
+   { OPCODE_ENDSUB, "ENDSUB", 0 },
    { OPCODE_EX2,    "EX2",   1 },
    { OPCODE_EXP,    "EXP",   1 },
    { OPCODE_FLR,    "FLR",   1 },
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index f018de8..100aac4 100644
--- a/src/mesa/shader/prog_instruction.h
+++ b/src/mesa/shader/prog_instruction.h
@@ -143,9 +143,13 @@ typedef enum prog_opcode {
    OPCODE_ARL,       /*   X                X                     */
    OPCODE_ARL_NV,    /*                    2                     */
    OPCODE_ARR,       /*                    2                     */
+   OPCODE_BGNLOOP,   /*                                     opt  */
+   OPCODE_BGNSUB,    /*                                     opt  */
    OPCODE_BRA,       /*                    2                 X   */
+   OPCODE_BRK,       /*                    2                opt  */
    OPCODE_CAL,       /*                    2       2             */
    OPCODE_CMP,       /*            X                             */
+   OPCODE_CONT,      /*                                     opt  */
    OPCODE_COS,       /*            X       2       X         X   */
    OPCODE_DDX,       /*                            X         X   */
    OPCODE_DDY,       /*                            X         X   */
@@ -154,13 +158,15 @@ typedef enum prog_opcode {
    OPCODE_DPH,       /*   X        X       1.1                   */
    OPCODE_DST,       /*   X        X       X       X             */
    OPCODE_ELSE,      /*                                      X   */
-   OPCODE_END,       /*   X        X       X       X         X   */
-   OPCODE_ENDIF,      /*                                     X   */
+   OPCODE_END,       /*   X        X       X       X        opt  */
+   OPCODE_ENDIF,     /*                                     opt  */
+   OPCODE_ENDLOOP,   /*                                     opt  */
+   OPCODE_ENDSUB,    /*                                     opt  */
    OPCODE_EX2,       /*   X        X       2       X         X   */
    OPCODE_EXP,       /*   X                X                 X   */
    OPCODE_FLR,       /*   X        X       2       X         X   */
    OPCODE_FRC,       /*   X        X       2       X         X   */
-   OPCODE_IF,        /*                                      X   */
+   OPCODE_IF,        /*                                     opt  */
    OPCODE_INT,       /*                                      X   */
    OPCODE_KIL,       /*            X                             */
    OPCODE_KIL_NV,    /*                            X         X   */
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 6b7df05..72f58a9 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -1463,7 +1463,7 @@ _slang_gen_for(slang_assemble_ctx * A, c
 
 
 /**
- * Generate IR tree for an if/then/else conditional.
+ * Generate IR tree for an if/then/else conditional using BRAnch instructions.
  */
 static slang_ir_node *
 _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
@@ -1513,7 +1513,8 @@ _slang_gen_if(slang_assemble_ctx * A, co
 
 
 /**
- * Use high-level IF/ELSE/ENDIF instructions
+ * Generate IR tree for an if/then/else conditional using high-level
+ * IF/ELSE/ENDIF instructions
  */
 static slang_ir_node *
 _slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper)
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 01fb5a4..756bbe9 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -297,6 +297,32 @@ slang_print_ir(const slang_ir_node *n, i
       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_BEGIN_LOOP:
+      printf("BEGIN_LOOP\n");
+      break;
+   case IR_END_LOOP:
+      printf("END_LOOP\n");
+      break;
+   case IR_CONT:
+      printf("CONT\n");
+      break;
+   case IR_BREAK:
+      printf("BREAK\n");
+      break;
+
    case IR_VAR:
       printf("VAR %s%s at %s  store %p\n",
              (n->Var ? (char *) n->Var->a_name : "TEMP"),
@@ -313,9 +339,6 @@ slang_print_ir(const slang_ir_node *n, i
       printf("FIELD %s of\n", n->Target);
       slang_print_ir(n->Children[0], indent+3);
       break;
-   case IR_CALL:
-      printf("ASMCALL %s(%d args)\n", n->Target, 0/*XXX*/);
-      break;
    case IR_FLOAT:
       printf("FLOAT %f %f %f %f\n",
              n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 5fd72be..ac1ea4d 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -46,15 +46,27 @@ typedef enum
    IR_NOP = 0,
    IR_SEQ,     /* sequence (eval left, then right) */
    IR_SCOPE,   /* new variable scope (one child) */
+
    IR_LABEL,   /* target of a jump or cjump */
    IR_JUMP,    /* unconditional jump */
    IR_CJUMP0,  /* conditional jump if zero */
    IR_CJUMP1,  /* conditional jump if one (or non-zero) */
-   IR_COND,    /* conditional expression */
+   IR_COND,    /* conditional expression/predicate */
+
    IR_IF,      /* high-level IF */
    IR_ELSE,    /* high-level ELSE */
    IR_ENDIF,   /* high-level ENDIF */
-   IR_CALL,    /* call subroutine */
+
+   IR_BEGIN_SUB, /* begin subroutine */
+   IR_END_SUB,   /* end subroutine */
+   IR_RETURN,    /* return from subroutine */
+   IR_CALL,      /* call subroutine */
+
+   IR_BEGIN_LOOP,/* begin loop */
+   IR_END_LOOP,  /* end loop */
+   IR_CONT,      /* continue loop */
+   IR_BREAK,     /* break loop */
+
    IR_MOVE,
    IR_ADD,
    IR_SUB,
@@ -90,17 +102,22 @@ typedef enum
    IR_NOISE3,  /* noise(x, y, z) */
    IR_NOISE4,  /* noise(x, y, z, w) */
    IR_NOT,     /* logical not */
+
    IR_VAR,     /* variable reference */
    IR_VAR_DECL,/* var declaration */
+
    IR_ELEMENT, /* array element */
+   IR_FIELD,   /* struct field */
    IR_SWIZZLE, /* swizzled storage access */
+
    IR_TEX,     /* texture lookup */
    IR_TEXB,    /* texture lookup with LOD bias */
    IR_TEXP,    /* texture lookup with projection */
+
    IR_FLOAT,
-   IR_FIELD,
    IR_I_TO_F,  /* int[4] to float[4] conversion */
    IR_F_TO_I,  /* float[4] to int[4] conversion */
+
    IR_KILL     /* fragment kill/discard */
 } slang_ir_opcode;
 
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 740360d..00231ae 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -675,6 +675,14 @@ execute_program( GLcontext *ctx,
                }
             }
             break;
+         case OPCODE_BGNLOOP: /* begin loop */
+            break;
+         case OPCODE_ENDLOOP: /* end loop */
+            break;
+         case OPCODE_BGNSUB: /* begin subroutine */
+            break;
+         case OPCODE_ENDSUB: /* end subroutine */
+            break;
          case OPCODE_BRA: /* conditional branch */
             {
                /* NOTE: The branch is conditional! */
@@ -692,6 +700,9 @@ execute_program( GLcontext *ctx,
                }
             }
             break;
+         case OPCODE_BRK: /* break out of loop */
+            /* assert inside loop */
+            break;
          case OPCODE_CAL: /* Call subroutine */
             {
                /* NOTE: The call is conditional! */
@@ -722,6 +733,8 @@ execute_program( GLcontext *ctx,
                store_vector4( inst, machine, result );
             }
             break;
+         case OPCODE_CONT: /* continue loop */
+            break;
          case OPCODE_COS:
             {
                GLfloat a[4], result[4];
diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c
index 22b6089..0a443b3 100644
--- a/src/mesa/tnl/t_vb_arbprogram.c
+++ b/src/mesa/tnl/t_vb_arbprogram.c
@@ -736,9 +736,13 @@ static void (* const opcode_func[MAX_OPC
    do_NOP,/*ARL*/
    do_NOP,/*ARL_NV*/
    do_NOP,/*ARR*/
+   do_NOP,/*BGNLOOP*/
+   do_NOP,/*BGNSUB*/
    do_NOP,/*BRA*/
+   do_NOP,/*BRK*/
    do_NOP,/*CAL*/
    do_NOP,/*CMP*/
+   do_NOP,/*CONT*/
    do_NOP,/*COS*/
    do_NOP,/*DDX*/
    do_NOP,/*DDY*/
@@ -749,6 +753,8 @@ static void (* const opcode_func[MAX_OPC
    do_NOP,/*ELSE*/
    do_NOP,/*END*/
    do_NOP,/*ENDIF*/
+   do_NOP,/*ENDLOOP*/
+   do_NOP,/*ENDSUB*/
    do_EX2,
    do_EXP,
    do_FLR,



More information about the mesa-commit mailing list