Mesa (master): i965: Add support for if instructions in the new FS backend.

Eric Anholt anholt at kemper.freedesktop.org
Fri Aug 27 13:20:53 PDT 2010


Module: Mesa
Branch: master
Commit: 130368f910a806a12287c7561df7dddd0fc8be40
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=130368f910a806a12287c7561df7dddd0fc8be40

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 27 12:54:12 2010 -0700

i965: Add support for if instructions in the new FS backend.

20 more piglit tests pass.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   62 +++++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 41b8ecd..7600060 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -311,6 +311,14 @@ public:
       this->predicated = false;
    }
 
+   fs_inst(int opcode)
+   {
+      this->opcode = opcode;
+      this->saturate = false;
+      this->conditional_mod = BRW_CONDITIONAL_NONE;
+      this->predicated = false;
+   }
+
    fs_inst(int opcode, fs_reg dst, fs_reg src0)
    {
       this->opcode = opcode;
@@ -932,7 +940,40 @@ fs_visitor::visit(ir_constant *ir)
 void
 fs_visitor::visit(ir_if *ir)
 {
-   assert(!"FINISHME");
+   fs_inst *inst;
+
+   /* Don't point the annotation at the if statement, because then it plus
+    * the then and else blocks get printed.
+    */
+   this->base_ir = ir->condition;
+
+   /* Generate the condition into the condition code. */
+   ir->condition->accept(this);
+   inst = emit(fs_inst(BRW_OPCODE_MOV, fs_reg(brw_null_reg()), this->result));
+   inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+   inst = emit(fs_inst(BRW_OPCODE_IF));
+   inst->predicated = true;
+
+   foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      this->base_ir = ir;
+
+      ir->accept(this);
+   }
+
+   if (!ir->else_instructions.is_empty()) {
+      emit(fs_inst(BRW_OPCODE_ELSE));
+
+      foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
+	 ir_instruction *ir = (ir_instruction *)iter.get();
+	 this->base_ir = ir;
+
+	 ir->accept(this);
+      }
+   }
+
+   emit(fs_inst(BRW_OPCODE_ENDIF));
 }
 
 void
@@ -1415,7 +1456,10 @@ fs_visitor::generate_code()
 {
    unsigned int annotation_len = 0;
    int last_native_inst = 0;
+   struct brw_instruction *if_stack[16];
+   int if_stack_depth = 0;
 
+   memset(&if_stack, 0, sizeof(if_stack));
    foreach_iter(exec_list_iterator, iter, this->instructions) {
       fs_inst *inst = (fs_inst *)iter.get();
       struct brw_reg src[3], dst;
@@ -1438,6 +1482,22 @@ fs_visitor::generate_code()
       case BRW_OPCODE_MUL:
 	 brw_MUL(p, dst, src[0], src[1]);
 	 break;
+      case BRW_OPCODE_CMP:
+	 brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]);
+	 break;
+      case BRW_OPCODE_IF:
+	 assert(if_stack_depth < 16);
+	 if_stack[if_stack_depth] = brw_IF(p, BRW_EXECUTE_8);
+	 if_stack_depth++;
+	 break;
+      case BRW_OPCODE_ELSE:
+	 if_stack[if_stack_depth - 1] =
+	    brw_ELSE(p, if_stack[if_stack_depth - 1]);
+	 break;
+      case BRW_OPCODE_ENDIF:
+	 if_stack_depth--;
+	 brw_ENDIF(p , if_stack[if_stack_depth]);
+	 break;
       case FS_OPCODE_RCP:
       case FS_OPCODE_RSQ:
       case FS_OPCODE_SQRT:



More information about the mesa-commit mailing list