summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-01-19 10:15:34 -0700
committerBrian <brian@yutani.localnet.net>2007-01-19 10:15:34 -0700
commita0092c51b1c334ef8d4a58939dc583b2aafbce69 (patch)
tree5b7f779f3f46f0078d5cacbe48639ec8442f4b1e
parent8374ccb66ff13074a3f5938da1e22a48921c5328 (diff)
Implement fragment discard/kill.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c3
-rw-r--r--src/mesa/shader/slang/slang_emit.c19
-rw-r--r--src/mesa/shader/slang/slang_ir.h3
3 files changed, 24 insertions, 1 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index ea08c46fcf..76dcca576d 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -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]),
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index ee348e5326..c660f2ceac 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -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");
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 34dd1bb691..a337d61712 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -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;