i965/fs: Emit shader w/a for Gen6 gather

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Chris Forbes
2014-02-03 22:15:16 +13:00
parent c2d51aaa11
commit 73b91fe05a
2 changed files with 35 additions and 0 deletions

View File

@@ -360,6 +360,7 @@ public:
fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
fs_reg sample_index, fs_reg mcs, int sampler);
fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler);
void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
fs_reg fix_math_operand(fs_reg src);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);

View File

@@ -1699,9 +1699,43 @@ fs_visitor::visit(ir_texture *ir)
}
}
if (brw->gen == 6 && ir->op == ir_tg4) {
emit_gen6_gather_wa(c->key.tex.gen6_gather_wa[sampler], dst);
}
swizzle_result(ir, dst, sampler);
}
/**
* Apply workarounds for Gen6 gather with UINT/SINT
*/
void
fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst)
{
if (!wa)
return;
int width = (wa & WA_8BIT) ? 8 : 16;
for (int i = 0; i < 4; i++) {
fs_reg dst_f = dst.retype(BRW_REGISTER_TYPE_F);
/* Convert from UNORM to UINT */
emit(MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1))));
emit(MOV(dst, dst_f));
if (wa & WA_SIGN) {
/* Reinterpret the UINT value as a signed INT value by
* shifting the sign bit into place, then shifting back
* preserving sign.
*/
emit(SHL(dst, dst, fs_reg(32 - width)));
emit(ASR(dst, dst, fs_reg(32 - width)));
}
dst.reg_offset++;
}
}
/**
* Set up the gather channel based on the swizzle, for gather4.
*/