[Mesa-dev] [PATCH 20/22] i965/fs/gen6: Support for sampling stencil with noormalized coordinates
Topi Pohjolainen
topi.pohjolainen at intel.com
Mon Jun 9 00:45:54 PDT 2014
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at 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
More information about the mesa-dev
mailing list