Merge remote branch 'origin/master' into gallium_draw_llvm
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu_emit.c
index 8d6ac0083966c2b48cd180197bb4e28935153067..d2395dec288ab53624922fb644f879651a110aec 100644 (file)
@@ -102,8 +102,6 @@ static void brw_set_dest( struct brw_instruction *insn,
 static void brw_set_src0( struct brw_instruction *insn,
                           struct brw_reg reg )
 {
-   assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
-
    if (reg.type != BRW_ARCHITECTURE_REGISTER_FILE)
       assert(reg.nr < 128);
 
@@ -323,7 +321,7 @@ static void brw_set_urb_message( struct brw_context *brw,
     struct intel_context *intel = &brw->intel;
     brw_set_src1(insn, brw_imm_d(0));
 
-    if (intel->is_ironlake) {
+    if (intel->is_ironlake || intel->gen >= 6) {
         insn->bits3.urb_igdng.opcode = 0;      /* ? */
         insn->bits3.urb_igdng.offset = offset;
         insn->bits3.urb_igdng.swizzle_control = swizzle_control;
@@ -334,8 +332,16 @@ static void brw_set_urb_message( struct brw_context *brw,
         insn->bits3.urb_igdng.response_length = response_length;
         insn->bits3.urb_igdng.msg_length = msg_length;
         insn->bits3.urb_igdng.end_of_thread = end_of_thread;
-        insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
-        insn->bits2.send_igdng.end_of_thread = end_of_thread;
+       if (intel->gen >= 6) {
+          /* For SNB, the SFID bits moved to the condmod bits, and
+           * EOT stayed in bits3 above.  Does the EOT bit setting
+           * below on Ironlake even do anything?
+           */
+          insn->header.destreg__conditionalmod = BRW_MESSAGE_TARGET_URB;
+       } else {
+          insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
+          insn->bits2.send_igdng.end_of_thread = end_of_thread;
+       }
     } else {
         insn->bits3.urb.opcode = 0;    /* ? */
         insn->bits3.urb.offset = offset;
@@ -567,7 +573,7 @@ ALU2(DPH)
 ALU2(DP3)
 ALU2(DP2)
 ALU2(LINE)
-
+ALU2(PLN)
 
 
 
@@ -917,26 +923,40 @@ void brw_math( struct brw_compile *p,
               GLuint data_type,
               GLuint precision )
 {
-   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
-   GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; 
-   GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; 
+   struct intel_context *intel = &p->brw->intel;
 
-   /* Example code doesn't set predicate_control for send
-    * instructions.
-    */
-   insn->header.predicate_control = 0; 
-   insn->header.destreg__conditionalmod = msg_reg_nr;
+   if (intel->gen >= 6) {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
 
-   brw_set_dest(insn, dest);
-   brw_set_src0(insn, src);
-   brw_set_math_message(p->brw,
-                       insn, 
-                       msg_length, response_length, 
-                       function,
-                       BRW_MATH_INTEGER_UNSIGNED,
-                       precision,
-                       saturate,
-                       data_type);
+      /* Math is the same ISA format as other opcodes, except that CondModifier
+       * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
+       */
+      insn->header.destreg__conditionalmod = function;
+
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, src);
+      brw_set_src1(insn, brw_null_reg());
+   } else {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+      GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1;
+      GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1;
+      /* Example code doesn't set predicate_control for send
+       * instructions.
+       */
+      insn->header.predicate_control = 0;
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, src);
+      brw_set_math_message(p->brw,
+                          insn,
+                          msg_length, response_length,
+                          function,
+                          BRW_MATH_INTEGER_UNSIGNED,
+                          precision,
+                          saturate,
+                          data_type);
+   }
 }
 
 /**
@@ -1270,9 +1290,9 @@ void brw_SAMPLE(struct brw_compile *p,
                GLuint simd_mode)
 {
    GLboolean need_stall = 0;
-   
+
    if (writemask == 0) {
-      /*_mesa_printf("%s: zero writemask??\n", __FUNCTION__); */
+      /*printf("%s: zero writemask??\n", __FUNCTION__); */
       return;
    }
    
@@ -1304,11 +1324,17 @@ void brw_SAMPLE(struct brw_compile *p,
 
       if (newmask != writemask) {
         need_stall = 1;
-         /* _mesa_printf("need stall %x %x\n", newmask , writemask); */
+         /* printf("need stall %x %x\n", newmask , writemask); */
       }
       else {
+        GLboolean dispatch_16 = GL_FALSE;
+
         struct brw_reg m1 = brw_message_reg(msg_reg_nr);
-        
+
+        guess_execution_size(p->current, dest);
+        if (p->current->header.execution_size == BRW_EXECUTE_16)
+           dispatch_16 = GL_TRUE;
+
         newmask = ~newmask & WRITEMASK_XYZW;
 
         brw_push_insn_state(p);
@@ -1323,7 +1349,13 @@ void brw_SAMPLE(struct brw_compile *p,
 
         src0 = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW); 
         dest = offset(dest, dst_offset);
-        response_length = len * 2;
+
+        /* For 16-wide dispatch, masked channels are skipped in the
+         * response.  For 8-wide, masked channels still take up slots,
+         * and are just not written to.
+         */
+        if (dispatch_16)
+           response_length = len * 2;
       }
    }
 
@@ -1377,7 +1409,18 @@ void brw_urb_WRITE(struct brw_compile *p,
                   GLuint offset,
                   GLuint swizzle)
 {
-   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   struct intel_context *intel = &p->brw->intel;
+   struct brw_instruction *insn;
+
+   /* Sandybridge doesn't have the implied move for SENDs,
+    * and the first message register index comes from src0.
+    */
+   if (intel->gen >= 6) {
+      brw_MOV(p, brw_message_reg(msg_reg_nr), src0);
+      src0 = brw_message_reg(msg_reg_nr);
+   }
+
+   insn = next_insn(p, BRW_OPCODE_SEND);
 
    assert(msg_length < BRW_MAX_MRF);
 
@@ -1385,7 +1428,8 @@ void brw_urb_WRITE(struct brw_compile *p,
    brw_set_src0(insn, src0);
    brw_set_src1(insn, brw_imm_d(0));
 
-   insn->header.destreg__conditionalmod = msg_reg_nr;
+   if (intel->gen < 6)
+      insn->header.destreg__conditionalmod = msg_reg_nr;
 
    brw_set_urb_message(p->brw,
                       insn,