[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