diff options
author | Chris Forbes <[email protected]> | 2014-02-03 22:15:16 +1300 |
---|---|---|
committer | Chris Forbes <[email protected]> | 2014-02-08 10:32:20 +1300 |
commit | 73b91fe05a2b4a09b29c69cfefda3f6c3d0ea68c (patch) | |
tree | 0b534d0b25bb1ccfebd25cfe436394201cf3f728 /src | |
parent | c2d51aaa11c2593edb9f4b9279745d39c79ff23c (diff) |
i965/fs: Emit shader w/a for Gen6 gather
Signed-off-by: Chris Forbes <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 34 |
2 files changed, 35 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 9c5c13ae393..3d668b9e471 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index d88d24c4d84..fd0813c373c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1699,10 +1699,44 @@ 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. */ uint32_t |