i965: Implement textureSize (TXS) on Gen4.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 17 Aug 2011 17:45:47 +0000 (10:45 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 23 Aug 2011 18:18:26 +0000 (11:18 -0700)
Also, remove the BRW_SAMPLER_MESSAGE_SIMD8_RESINFO #define because
there totally isn't a SIMD8 variant.

Unfortunately, resinfo returns FLOAT32 on Broadwater/Crestline, unlike
G45 which returns a proper UINT32.  This turns out to be simple,
however: when we emit MOVs to select the desired half of the SIMD16
result, we can simply override the register type to be float so it's
converted to an integer.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_fs_emit.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 69e0026ee6b747f42e79065d8a43ff1139337c78..d1799c0ab4f28a5b9022183a5a7eab88edff76f8 100644 (file)
@@ -769,7 +769,6 @@ enum opcode {
 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_COMPARE 0
 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_COMPARE  1
 #define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO           2
-#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO             2
 #define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO            2
 #define BRW_SAMPLER_MESSAGE_SIMD4X2_LD                3
 #define BRW_SAMPLER_MESSAGE_SIMD8_LD                  3
index 5c057e9a00bf50f843cd06f29c7a74c0c034c685..28efbd3605f025f08f692bfe3f0f75212539f270 100644 (file)
@@ -292,6 +292,11 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
         assert(inst->mlen == 7 || inst->mlen == 10);
         msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS;
         break;
+      case FS_OPCODE_TXS:
+        assert(inst->mlen == 3);
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_RESINFO;
+        simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
+        break;
       default:
         assert(!"not reached");
         break;
index 3551e3dfe8151fb09ab5981b429e68bdd09f3e4b..cbc0af02407c1aa725b9d39fd8c087d2f1298fa1 100644 (file)
@@ -657,10 +657,18 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
         dPdy.reg_offset++;
       }
       mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2);
+   } else if (ir->op == ir_txs) {
+      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
+      simd16 = true;
+      this->result = reg_undef;
+      ir->lod_info.lod->accept(this);
+      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
+      mlen += 2;
    } else {
       /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
        * instructions.  We'll need to do SIMD16 here.
        */
+      simd16 = true;
       assert(ir->op == ir_txb || ir->op == ir_txl);
 
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
@@ -689,16 +697,19 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
 
       /* The unused upper half. */
       mlen++;
+   }
 
+   if (simd16) {
       /* Now, since we're doing simd16, the return is 2 interleaved
        * vec4s where the odd-indexed ones are junk. We'll need to move
        * this weirdness around to the expected layout.
        */
-      simd16 = true;
       orig_dst = dst;
-      dst = fs_reg(this, glsl_type::get_array_instance(glsl_type::vec4_type,
-                                                      2));
-      dst.type = BRW_REGISTER_TYPE_F;
+      const glsl_type *vec_type =
+        glsl_type::get_instance(ir->type->base_type, 4, 1);
+      dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2));
+      dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type)
+                              : BRW_REGISTER_TYPE_F;
    }
 
    fs_inst *inst = NULL;
@@ -715,8 +726,10 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
    case ir_txd:
       inst = emit(FS_OPCODE_TXD, dst);
       break;
-   case ir_txf:
    case ir_txs:
+      inst = emit(FS_OPCODE_TXS, dst);
+      break;
+   case ir_txf:
       assert(!"GLSL 1.30 features unsupported");
       break;
    }