summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2011-08-17 10:45:47 -0700
committerKenneth Graunke <[email protected]>2011-08-23 11:18:26 -0700
commit4eeb4c150598605d1be3ce6674fa63076a720ae9 (patch)
treeb587cc40dc70fdcbac02bf2d309bc520f7a19882
parentecf8963754489abfb5097c130a9bcd4cdb76b6bd (diff)
i965: Implement textureSize (TXS) on Gen4.
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 <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_emit.cpp5
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp23
3 files changed, 23 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 69e0026ee6b..d1799c0ab4f 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 5c057e9a00b..28efbd3605f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 3551e3dfe81..cbc0af02407 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -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;
}