i965: Add support for texturing with bias to i965 FS backend.
authorEric Anholt <eric@anholt.net>
Sun, 29 Aug 2010 05:34:30 +0000 (22:34 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 30 Aug 2010 17:26:05 +0000 (10:26 -0700)
Fixes 5 piglit tests for bias.  Note that LOD is a 1.30 feature and
not yet supported.

src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_fs.cpp

index f7a68cead7c731029458b67be03fbd8658aa9f88..6b8e9e05d08bf41aec4d8759c2fdcf7e46c99df4 100644 (file)
 #define BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_GEN5       1
 #define BRW_SAMPLER_MESSAGE_SAMPLE_LOD_GEN5        2
 #define BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_GEN5    3
+#define BRW_SAMPLER_MESSAGE_SAMPLE_DERIVS_GEN5     4
+#define BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE_GEN5 5
+#define BRW_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE_GEN5 6
 
 /* for GEN5 only */
 #define BRW_SAMPLER_SIMD_MODE_SIMD4X2                   0
index 1ef27ce9cee79ab2083a5fc02e1b4c939f9b7688..233fee47dc5d1d0679414c8e4db113fd5d4f9314 100644 (file)
@@ -68,6 +68,8 @@ enum fs_opcodes {
    FS_OPCODE_DDY,
    FS_OPCODE_LINTERP,
    FS_OPCODE_TEX,
+   FS_OPCODE_TXB,
+   FS_OPCODE_TXL,
 };
 
 static int using_new_fs = -1;
@@ -921,15 +923,24 @@ fs_visitor::visit(ir_texture *ir)
     * performance relevant?
     */
    fs_reg dst = fs_reg(this, glsl_type::vec4_type);
-   this->result = dst;
 
    switch (ir->op) {
    case ir_tex:
       inst = emit(fs_inst(FS_OPCODE_TEX, dst, fs_reg(MRF, base_mrf)));
       break;
    case ir_txb:
+      ir->lod_info.bias->accept(this);
+      emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result));
+      mlen++;
+
+      inst = emit(fs_inst(FS_OPCODE_TXB, dst, fs_reg(MRF, base_mrf)));
+      break;
    case ir_txl:
-      assert(!"FINISHME");
+      ir->lod_info.lod->accept(this);
+      emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result));
+      mlen++;
+
+      inst = emit(fs_inst(FS_OPCODE_TXL, dst, fs_reg(MRF, base_mrf)));
       break;
    case ir_txd:
    case ir_txf:
@@ -937,6 +948,8 @@ fs_visitor::visit(ir_texture *ir)
       break;
    }
 
+   this->result = dst;
+
    if (ir->shadow_comparitor)
       inst->shadow_compare = true;
    inst->mlen = mlen;
@@ -1382,24 +1395,49 @@ fs_visitor::generate_math(fs_inst *inst,
 void
 fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 {
-   int msg_type;
+   int msg_type = -1;
+   int rlen = 4;
 
    if (intel->gen == 5) {
-      if (inst->shadow_compare)
-        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_GEN5;
-      else
-        msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_GEN5;
+      switch (inst->opcode) {
+      case FS_OPCODE_TEX:
+        if (inst->shadow_compare) {
+           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_GEN5;
+        } else {
+           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_GEN5;
+        }
+        break;
+      case FS_OPCODE_TXB:
+        if (inst->shadow_compare) {
+           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE_GEN5;
+        } else {
+           msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_GEN5;
+        }
+        break;
+      }
    } else {
-      /* Note that G45 and older determines shadow compare and dispatch width
-       * from message length for most messages.
-       */
-      if (inst->shadow_compare)
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
-      else
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+      switch (inst->opcode) {
+      case FS_OPCODE_TEX:
+        /* Note that G45 and older determines shadow compare and dispatch width
+         * from message length for most messages.
+         */
+        if (inst->shadow_compare) {
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+        } else {
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+        }
+      case FS_OPCODE_TXB:
+        if (inst->shadow_compare) {
+           assert(!"FINISHME: shadow compare with bias.");
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+        } else {
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+           rlen = 8;
+        }
+        break;
+      }
    }
-
-   int response_length = 4;
+   assert(msg_type != -1);
 
    /* g0 header. */
    src.nr--;
@@ -1412,7 +1450,7 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
              inst->sampler,
              WRITEMASK_XYZW,
              msg_type,
-             response_length,
+             rlen,
              inst->mlen + 1,
              0,
              1,
@@ -1649,6 +1687,8 @@ fs_visitor::generate_code()
         generate_linterp(inst, dst, src);
         break;
       case FS_OPCODE_TEX:
+      case FS_OPCODE_TXB:
+      case FS_OPCODE_TXL:
         generate_tex(inst, dst, src[0]);
         break;
       case FS_OPCODE_FB_WRITE: