Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/i965/brw_fs_stencil_tex.cpp | 52 ++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs_stencil_tex.h | 1 + 2 files changed, 53 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.cpp b/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.cpp index cd746db..632f09e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.cpp @@ -250,6 +250,36 @@ emit_translate_w_to_y_tiling(fs_emitter *e, const fs_reg& coord) e->emit(e->MOV(offset(coord, 1), dst_y)); } +static void +emit_denormalize(fs_emitter *e, const fs_reg& val, const fs_reg& range) +{ + fs_reg range_f = fs_reg(e, glsl_type::float_type); + fs_reg unorm_f = fs_reg(e, glsl_type::float_type); + + /* Make sure the math is performed using floats - range is likely to be + * unsigned. Move will do the needed conversion and optimizing passes will + * remove the copy if the range is already a float. + */ + e->emit(e->MOV(range_f, range)); + + e->emit(e->MUL(unorm_f, val, range_f)); + + /* Original value will be treated as unsigned from here on. */ + e->emit(e->MOV(retype(val, BRW_REGISTER_TYPE_UD), unorm_f)); +} + +static void +emit_minify(fs_emitter *e, const fs_reg& dst, const fs_reg& src, + const fs_reg& lod) +{ + e->emit(e->ASR(dst, src, lod)); + + fs_inst *inst = e->emit(BRW_OPCODE_CMP, reg_null_d, dst, fs_reg(0)); + inst->conditional_mod = BRW_CONDITIONAL_EQ; + inst = e->emit(e->MOV(dst, fs_reg(1))); + inst->predicate = BRW_PREDICATE_NORMAL; +} + /** * All the miptrees have the same "below" layout where both levels one and two * are just below level zero. From there on level three is just below level @@ -422,6 +452,24 @@ fs_stencil_texturing::setup_base_level(struct brw_fragment_program *fp, } void +fs_stencil_texturing::emit_denormalize_coords(const fs_reg& lod) +{ + fs_reg w(e, glsl_type::uint_type); + fs_reg h(e, glsl_type::uint_type); + + emit_minify(e, w, *base_w, lod); + emit_minify(e, h, *base_h, lod); + + emit_denormalize(e, *coord, w); + emit_denormalize(e, offset(*coord, 1), h); + + /* Change the original coordinate type from float to unsigned. These + * will be later on treated as if the texture operation is texelFetch(). + */ + coord->type = BRW_REGISTER_TYPE_UD; +} + +void fs_stencil_texturing::emit_w_to_y_tiling(struct brw_fragment_program *fp, struct brw_stage_prog_data *prog_data, enum ir_texture_opcode op, @@ -439,6 +487,10 @@ fs_stencil_texturing::emit_w_to_y_tiling(struct brw_fragment_program *fp, e->emit(e->ADD(lod_ud, lod_ud, fs_reg(base_level))); } + /* Translate noormalized coordinates into texel equivalent. */ + if (op == ir_tex) + emit_denormalize_coords(lod_ud); + /* Surface is sampled as 2x2 blocks. The coordinates will modified * accordingly and the lowest bits designating the inidividual sample/pixel * need to be saved for final pixel selection. diff --git a/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.h b/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.h index 5c7c42f..691bc25 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.h +++ b/src/mesa/drivers/dri/i965/brw_fs_stencil_tex.h @@ -45,6 +45,7 @@ public: private: void setup_base_level(struct brw_fragment_program *fp, struct brw_stage_prog_data *prog_data); + void emit_denormalize_coords(const fs_reg& lod); void offset_to_w_tiled_miplevel(const fs_reg& lod); fs_emitter *e; -- 1.8.3.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev