summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/brw_wm_emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_emit.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 52bb73971b..5390fd2584 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -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: