Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/i965/brw_fs.h | 2 + src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 69 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 2b3ac34..28053da 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -520,6 +520,8 @@ public: void denormalize(const fs_reg& unorm, const fs_reg& norm, const fs_reg& range); + void translate_norm_w_to_y_tiling(int sampler, fs_reg coord); + void translate_unorm_w_to_y_tiling(int sampler, fs_reg coord); struct gl_fragment_program *fp; diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 10afe5d..e84f0a2 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1627,6 +1627,68 @@ fs_visitor::normalize(const fs_reg& norm, emit(MUL(norm, unorm_f, range_inv)); } +/** + * Emit translation of coordinates in W-tiling layout to Y-tiling. In the + * latter a tile holds twice as many pixels horizontally and half as few + * vertically. + * First the dimensions in Y-tiling layout are queried from the hardware. Then + * the width is divided and the height in turn multiplied by two in order to + * work with matching W-layout dimensions. These are used the translate the + * normalized coordinates into screen equivalent which can be then translated + * to corresponding screen coordinates in Y-layout. Finally the translated + * coordinates are normalized back. + */ +void +fs_visitor::translate_norm_w_to_y_tiling(int sampler, fs_reg coord) +{ + fs_reg unorm_x = fs_reg(this, glsl_type::uint_type); + fs_reg unorm_y = fs_reg(this, glsl_type::uint_type); + fs_reg dst_x = fs_reg(this, glsl_type::uint_type); + fs_reg dst_y = fs_reg(this, glsl_type::uint_type); + fs_reg res_info = fetch_resinfo(sampler, fs_reg(0)); + + denormalize(unorm_x, coord, res_info); + emit(SHR(unorm_x, unorm_x, fs_reg(1))); + coord.reg_offset++; + res_info.reg_offset++; + + denormalize(unorm_y, coord, res_info); + emit(SHL(unorm_y, unorm_y, fs_reg(1))); + + emit_translate_w_to_y_tiling(fs_reg(this, glsl_type::uint_type), + fs_reg(this, glsl_type::uint_type), + unorm_x, unorm_y, dst_x, dst_y); + + res_info.reg_offset = 0; + coord.reg_offset = 0; + normalize(coord, dst_x, res_info); + res_info.reg_offset++; + coord.reg_offset++; + normalize(coord, dst_y, res_info); +} + +void +fs_visitor::translate_unorm_w_to_y_tiling(int sampler, fs_reg coord) +{ + fs_reg unorm_x = fs_reg(this, glsl_type::uint_type); + fs_reg unorm_y = fs_reg(this, glsl_type::uint_type); + fs_reg dst_x = fs_reg(this, glsl_type::uint_type); + fs_reg dst_y = fs_reg(this, glsl_type::uint_type); + + emit(MOV(unorm_x, coord)); + coord.reg_offset++; + emit(MOV(unorm_y, coord)); + + emit_translate_w_to_y_tiling(fs_reg(this, glsl_type::uint_type), + fs_reg(this, glsl_type::uint_type), + unorm_x, unorm_y, dst_x, dst_y); + + coord.reg_offset = 0; + emit(MOV(coord, dst_x)); + coord.reg_offset++; + emit(MOV(coord, dst_y)); +} + void fs_visitor::visit(ir_texture *ir) { @@ -1721,6 +1783,13 @@ fs_visitor::visit(ir_texture *ir) default: assert(!"Unrecognized texture opcode"); }; + + if (c->key.tex.translate_y_to_w[sampler]) { + if (ir->op == ir_txf) + translate_unorm_w_to_y_tiling(sampler, coordinate); + else + translate_norm_w_to_y_tiling(sampler, coordinate); + } /* Writemasking doesn't eliminate channels on SIMD8 texture * samples, so don't worry about them. -- 1.8.3.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev