Implement fragment discard/kill.
authorBrian <brian@yutani.localnet.net>
Fri, 19 Jan 2007 17:15:34 +0000 (10:15 -0700)
committerBrian <brian@yutani.localnet.net>
Fri, 19 Jan 2007 17:15:34 +0000 (10:15 -0700)
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_ir.h

index ea08c46..76dcca5 100644 (file)
@@ -2054,6 +2054,9 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
          RETURN_ERROR("'continue' not in loop", 0);
       }
       return new_jump(A->CurLoopCont);
+   case slang_oper_discard:
+      return new_node(IR_KILL, NULL, NULL);
+
    case slang_oper_equal:
       return new_node(IR_SEQUAL,
                       _slang_gen_operation(A, &oper->children[0]),
index ee348e5..c660f2c 100644 (file)
@@ -90,6 +90,7 @@ static slang_ir_info IrInfo[] = {
    { IR_LABEL, "IR_LABEL", 0, 0, 0 },
    { IR_JUMP, "IR_JUMP", 0, 0, 0 },
    { IR_CJUMP, "IR_CJUMP", 0, 0, 0 },
+   { IR_KILL, "IR_KILL", 0, 0, 0 },
    { IR_COND, "IR_COND", 0, 0, 0 },
    { IR_CALL, "IR_CALL", 0, 0, 0 },
    { IR_MOVE, "IR_MOVE", 0, 0, 1 },
@@ -538,6 +539,19 @@ emit_jump(const char *target, struct gl_program *prog)
 
 
 static struct prog_instruction *
+emit_kill(struct gl_program *prog)
+{
+   struct prog_instruction *inst;
+   /* NV-KILL - discard fragment depending on condition code.
+    * Note that ARB-KILL depends on sign of vector operand.
+    */
+   inst = new_instruction(prog, OPCODE_KIL_NV);
+   inst->DstReg.CondMask = COND_TR;  /* always branch */
+   return inst;
+}
+
+
+static struct prog_instruction *
 emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
 {
    struct prog_instruction *inst;
@@ -732,6 +746,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
        */
       assert(n->Store);
       assert(n->Store->File != PROGRAM_UNDEFINED);
+      if (n->Store->Index < 0) {
+         printf("#### VAR %s not allocated!\n", (char*)n->Var->a_name);
+      }
       assert(n->Store->Index >= 0);
       assert(n->Store->Size > 0);
       break;
@@ -827,6 +844,8 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
       return emit_jump(n->Target, prog);
    case IR_CJUMP:
       return emit_cjump(n->Target, prog);
+   case IR_KILL:
+      return emit_kill(prog);
 
    default:
       _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
index 34dd1bb..a337d61 100644 (file)
@@ -90,7 +90,8 @@ typedef enum
    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_F_TO_I,  /* float[4] to int[4] conversion */
+   IR_KILL     /* fragment kill/discard */
 } slang_ir_opcode;