i965: Share OPCODE_TXB between brw_wm_emit.c and brw_wm_glsl.c
authorEric Anholt <eric@anholt.net>
Wed, 19 Aug 2009 20:44:13 +0000 (13:44 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 14 Nov 2009 00:04:13 +0000 (16:04 -0800)
This should fix TXB on G45 and older in the GLSL case.

src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c

index c497e8a46b57f4ec0630285f79d34199d6ced414..b3c05eb0ad379922632ee8b2f5c3e4fb20ecf776 100644 (file)
@@ -428,6 +428,13 @@ void emit_tex(struct brw_wm_compile *c,
              GLuint tex_idx,
              GLuint sampler,
              GLboolean shadow);
+void emit_txb(struct brw_wm_compile *c,
+             struct brw_reg *dst,
+             GLuint dst_flags,
+             struct brw_reg *arg,
+             struct brw_reg depth_payload,
+             GLuint tex_idx,
+             GLuint sampler);
 void emit_wpos_xy(struct brw_wm_compile *c,
                  const struct brw_reg *dst,
                  GLuint mask,
index 52bb73971b1c679b490804a4693f0dcfc0dd1d22..5390fd25849d16127d7e470f4f794cd25522ac65 100644 (file)
@@ -935,57 +935,77 @@ void emit_tex(struct brw_wm_compile *c,
 }
 
 
-static void emit_txb( struct brw_wm_compile *c,
-                     const struct brw_wm_instruction *inst,
-                     struct brw_reg *dst,
-                     GLuint dst_flags,
-                     struct brw_reg *arg )
+void emit_txb(struct brw_wm_compile *c,
+             struct brw_reg *dst,
+             GLuint dst_flags,
+             struct brw_reg *arg,
+             struct brw_reg depth_payload,
+             GLuint tex_idx,
+             GLuint sampler)
 {
    struct brw_compile *p = &c->func;
    GLuint msgLength;
    GLuint msg_type;
-   /* Shadow ignored for txb.
+   GLuint mrf_per_channel;
+   GLuint response_length;
+   struct brw_reg dst_retyped;
+
+   /* The G45 and older chipsets don't support 8-wide dispatch for LOD biased
+    * samples, so we'll use the 16-wide instruction, leave the second halves
+    * undefined, and trust the execution mask to keep the undefined pixels
+    * from mattering.
     */
-   switch (inst->tex_idx) {
+   if (c->dispatch_width == 16 || !BRW_IS_IGDNG(p->brw)) {
+      if (BRW_IS_IGDNG(p->brw))
+        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
+      else
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+      mrf_per_channel = 2;
+      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
+      response_length = 8;
+   } else {
+      msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
+      mrf_per_channel = 1;
+      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
+      response_length = 4;
+   }
+
+   /* Shadow ignored for txb. */
+   switch (tex_idx) {
    case TEXTURE_1D_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
-      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
       break;
    case TEXTURE_2D_INDEX:
    case TEXTURE_RECT_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), arg[1]);
-      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
       break;
    case TEXTURE_3D_INDEX:
    case TEXTURE_CUBE_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), arg[1]);
-      brw_MOV(p, brw_message_reg(6), arg[2]);
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), arg[2]);
       break;
    default:
       /* unexpected target */
       abort();
    }
 
-   brw_MOV(p, brw_message_reg(8), arg[3]);
-   msgLength = 9;
-
-   if (BRW_IS_IGDNG(p->brw))
-       msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
-   else
-       msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+   brw_MOV(p, brw_message_reg(2 + 3 * mrf_per_channel), arg[3]);
+   msgLength = 2 + 4 * mrf_per_channel - 1;
 
    brw_SAMPLE(p, 
-             retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
+             dst_retyped,
              1,
-             retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
-              SURF_INDEX_TEXTURE(inst->tex_unit),
-             inst->tex_unit,     /* sampler */
-             inst->writemask,
+             retype(depth_payload, BRW_REGISTER_TYPE_UW),
+              SURF_INDEX_TEXTURE(sampler),
+             sampler,
+             dst_flags & WRITEMASK_XYZW,
              msg_type,
-             8,                /* responseLength */
+             response_length,
              msgLength,
              0,        
              1,
@@ -1563,7 +1583,8 @@ void brw_wm_emit( struct brw_wm_compile *c )
         break;
 
       case OPCODE_TXB:
-        emit_txb(c, inst, dst, dst_flags, args[0]);
+        emit_txb(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
+                 inst->tex_idx, inst->tex_unit);
         break;
 
       case OPCODE_KIL:
index 4af01a5f2aff0163ccd0cfb4075f6038c2b978cd..3ab446164c5662e07485e67efa0c48924923bfca 100644 (file)
@@ -1801,76 +1801,6 @@ static void emit_noise4( struct brw_wm_compile *c,
     release_tmps( c, mark );
 }
 
-
-/* TODO
-   BIAS on SIMD8 not working yet...
- */    
-static void emit_txb(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg dst[4], src[4], payload_reg;
-    /* Note: TexSrcUnit was already looked up through SamplerTextures[] */
-    const GLuint unit = inst->TexSrcUnit;
-    GLuint i;
-    GLuint msg_type;
-
-    assert(unit < BRW_MAX_TEX_UNIT);
-
-    payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
-
-    for (i = 0; i < 4; i++) 
-       dst[i] = get_dst_reg(c, inst, i);
-    for (i = 0; i < 4; i++)
-       src[i] = get_src_reg(c, inst, 0, i);
-
-    switch (inst->TexSrcTarget) {
-       case TEXTURE_1D_INDEX:
-           brw_MOV(p, brw_message_reg(2), src[0]);         /* s coord */
-           brw_MOV(p, brw_message_reg(3), brw_imm_f(0));   /* t coord */
-           brw_MOV(p, brw_message_reg(4), brw_imm_f(0));   /* r coord */
-           break;
-       case TEXTURE_2D_INDEX:
-       case TEXTURE_RECT_INDEX:
-           brw_MOV(p, brw_message_reg(2), src[0]);
-           brw_MOV(p, brw_message_reg(3), src[1]);
-           brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
-           break;
-       case TEXTURE_3D_INDEX:
-       case TEXTURE_CUBE_INDEX:
-           brw_MOV(p, brw_message_reg(2), src[0]);
-           brw_MOV(p, brw_message_reg(3), src[1]);
-           brw_MOV(p, brw_message_reg(4), src[2]);
-           break;
-       default:
-            /* invalid target */
-            abort();
-    }
-    brw_MOV(p, brw_message_reg(5), src[3]);          /* bias */
-    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));    /* ref (unused?) */
-
-    if (BRW_IS_IGDNG(p->brw)) {
-        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
-    } else {
-        /* Does it work well on SIMD8? */
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
-    }
-
-    brw_SAMPLE(p,
-               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  /* dest */
-               1,                                           /* msg_reg_nr */
-               retype(payload_reg, BRW_REGISTER_TYPE_UW),   /* src0 */
-               SURF_INDEX_TEXTURE(unit),
-               unit,                                        /* sampler */
-               inst->DstReg.WriteMask,                      /* writemask */
-               msg_type,                                    /* msg_type */
-               4,                                           /* response_length */
-               4,                                           /* msg_length */
-               0,                                           /* eot */
-               1,
-               BRW_SAMPLER_SIMD_MODE_SIMD8);   
-}
-
 /**
  * Resolve subroutine calls after code emit is done.
  */
@@ -2099,7 +2029,11 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
                         (c->key.shadowtex_mask & (1 << inst->TexSrcUnit)) != 0);
                break;
            case OPCODE_TXB:
-               emit_txb(c, inst);
+               emit_txb(c, dst, dst_flags, args[0],
+                        get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
+                                0, 1, 0, 0),
+                        inst->TexSrcTarget,
+                        c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]);
                break;
            case OPCODE_KIL_NV:
                emit_kil(c);