i965: Share OPCODE_TEX between brw_wm_emit.c and brw_wm_glsl.c.
authorEric Anholt <eric@anholt.net>
Wed, 19 Aug 2009 21:48:11 +0000 (14:48 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 14 Nov 2009 00:04:10 +0000 (16:04 -0800)
New comments should explain some of the confusion about how this message
works.

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 7db212e..c497e8a 100644 (file)
@@ -420,6 +420,14 @@ void emit_sop(struct brw_compile *p,
              GLuint cond,
              const struct brw_reg *arg0,
              const struct brw_reg *arg1);
+void emit_tex(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,
+             GLboolean shadow);
 void emit_wpos_xy(struct brw_wm_compile *c,
                  const struct brw_reg *dst,
                  GLuint mask,
index a47bf3f..52bb739 100644 (file)
@@ -818,24 +818,41 @@ void emit_math2(struct brw_wm_compile *c,
    }
    brw_pop_insn_state(p);
 }
-                    
 
 
-static void emit_tex( struct brw_wm_compile *c,
-                     const struct brw_wm_instruction *inst,
-                     struct brw_reg *dst,
-                     GLuint dst_flags,
-                     struct brw_reg *arg )
+void emit_tex(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,
+             GLboolean shadow)
 {
    struct brw_compile *p = &c->func;
+   struct brw_reg dst_retyped;
    GLuint cur_mrf = 2, response_length;
    GLuint i, nr_texcoords;
    GLuint emit;
    GLuint msg_type;
+   GLuint mrf_per_channel;
+   GLuint simd_mode;
+
+   if (c->dispatch_width == 16) {
+      mrf_per_channel = 2;
+      response_length = 8;
+      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
+      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
+   } else {
+      mrf_per_channel = 1;
+      response_length = 4;
+      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
+      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
+   }
 
    /* How many input regs are there?
     */
-   switch (inst->tex_idx) {
+   switch (tex_idx) {
    case TEXTURE_1D_INDEX:
       emit = WRITEMASK_X;
       nr_texcoords = 1;
@@ -855,56 +872,66 @@ static void emit_tex( struct brw_wm_compile *c,
       abort();
    }
 
+   /* Pre-Ironlake, the 8-wide sampler always took u,v,r. */
+   if (!BRW_IS_IGDNG(p->brw) && c->dispatch_width == 8)
+      nr_texcoords = 3;
+
    /* For shadow comparisons, we have to supply u,v,r. */
-   if (inst->tex_shadow)
+   if (shadow)
       nr_texcoords = 3;
 
+   /* Emit the texcoords. */
    for (i = 0; i < nr_texcoords; i++) {
       if (emit & (1<<i))
         brw_MOV(p, brw_message_reg(cur_mrf), arg[i]);
       else
         brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
-      cur_mrf += 2;
+      cur_mrf += mrf_per_channel;
    }
 
    /* Fill in the shadow comparison reference value. */
-   if (inst->tex_shadow) {
+   if (shadow) {
       if (BRW_IS_IGDNG(p->brw)) {
         /* Fill in the cube map array index value. */
         brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
-        cur_mrf += 2;
+        cur_mrf += mrf_per_channel;
+      } else if (c->dispatch_width == 8) {
+        /* Fill in the LOD bias value. */
+        brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
+        cur_mrf += mrf_per_channel;
       }
       brw_MOV(p, brw_message_reg(cur_mrf), arg[2]);
-      cur_mrf += 2;
+      cur_mrf += mrf_per_channel;
    }
 
-   response_length = 8;                /* always */
-
    if (BRW_IS_IGDNG(p->brw)) {
-       if (inst->tex_shadow)
-           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG;
-       else
-           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_IGDNG;
+      if (shadow)
+        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG;
+      else
+        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_IGDNG;
    } else {
-       if (inst->tex_shadow)
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
-       else
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+      /* Note that G45 and older determines shadow compare and dispatch width
+       * from message length for most messages.
+       */
+      if (c->dispatch_width == 16 && shadow)
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+      else
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
    }
 
    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,
              response_length,
              cur_mrf - 1,
              0,
              1,
-             BRW_SAMPLER_SIMD_MODE_SIMD16);
+             simd_mode);
 }
 
 
@@ -1530,7 +1557,9 @@ void brw_wm_emit( struct brw_wm_compile *c )
         /* Texturing operations:
          */
       case OPCODE_TEX:
-        emit_tex(c, inst, dst, dst_flags, args[0]);
+        emit_tex(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
+                 inst->tex_idx, inst->tex_unit,
+                 inst->tex_shadow);
         break;
 
       case OPCODE_TXB:
index 42a13fc..4af01a5 100644 (file)
@@ -1871,94 +1871,6 @@ static void emit_txb(struct brw_wm_compile *c,
                BRW_SAMPLER_SIMD_MODE_SIMD8);   
 }
 
-
-static void emit_tex(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 msg_len;
-    GLuint i, nr;
-    GLuint emit;
-    GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
-    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:
-           emit = WRITEMASK_X;
-           nr = 1;
-           break;
-       case TEXTURE_2D_INDEX:
-       case TEXTURE_RECT_INDEX:
-           emit = WRITEMASK_XY;
-           nr = 2;
-           break;
-       case TEXTURE_3D_INDEX:
-       case TEXTURE_CUBE_INDEX:
-           emit = WRITEMASK_XYZ;
-           nr = 3;
-           break;
-       default:
-           /* invalid target */
-           abort();
-    }
-    msg_len = 1;
-
-    /* move/load S, T, R coords */
-    for (i = 0; i < nr; i++) {
-       static const GLuint swz[4] = {0,1,2,2};
-       if (emit & (1<<i))
-           brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
-       else
-           brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
-       msg_len += 1;
-    }
-
-    if (shadow) {
-       brw_MOV(p, brw_message_reg(5), brw_imm_f(0));  /* lod / bias */
-       brw_MOV(p, brw_message_reg(6), src[2]);        /* ref value / R coord */
-    }
-
-    if (BRW_IS_IGDNG(p->brw)) {
-        if (shadow)
-            msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG;
-        else
-            msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_IGDNG;
-    } else {
-        /* Does it work for shadow on SIMD8 ? */
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
-    }
-    
-    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 */
-               shadow ? 6 : 4,                             /* msg_length */
-               0,                                          /* eot */
-               1,
-               BRW_SAMPLER_SIMD_MODE_SIMD8);   
-
-    if (shadow)
-       brw_MOV(p, dst[3], brw_imm_f(1.0));
-}
-
-
 /**
  * Resolve subroutine calls after code emit is done.
  */
@@ -2179,7 +2091,12 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
                emit_noise4(c, inst);
                break;
            case OPCODE_TEX:
-               emit_tex(c, inst);
+               emit_tex(c, dst, dst_flags, args[0],
+                        get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
+                                0, 1, 0, 0),
+                        inst->TexSrcTarget,
+                        inst->TexSrcUnit,
+                        (c->key.shadowtex_mask & (1 << inst->TexSrcUnit)) != 0);
                break;
            case OPCODE_TXB:
                emit_txb(c, inst);