[Mesa-dev] [PATCH 4/6] i965/fs: Implement texture projection support.

Kenneth Graunke kenneth at whitecape.org
Mon Mar 23 17:37:58 PDT 2015


Our fragment program backend implements support for TXP directly, and
there's no NIR lowering pass to remove the projection.  When we switch
fragment program support over to NIR, we need to support it somehow.

It's easy enough to support directly.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 094303f..63d5e3b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -1749,7 +1749,8 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
 
    int lod_components = 0, offset_components = 0;
 
-   fs_reg coordinate, shadow_comparitor, lod, lod2, sample_index, mcs, offset;
+   fs_reg coordinate, shadow_comparitor, lod, lod2, sample_index, mcs;
+   fs_reg tex_offset, projector;
 
    for (unsigned i = 0; i < instr->num_srcs; i++) {
       fs_reg src = get_nir_src(instr->src[i].src);
@@ -1795,14 +1796,15 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
          sample_index = retype(src, BRW_REGISTER_TYPE_UD);
          break;
       case nir_tex_src_offset:
-         offset = retype(src, BRW_REGISTER_TYPE_D);
+         tex_offset = retype(src, BRW_REGISTER_TYPE_D);
          if (instr->is_array)
             offset_components = instr->coord_components - 1;
          else
             offset_components = instr->coord_components;
          break;
       case nir_tex_src_projector:
-         unreachable("should be lowered");
+         projector = retype(src, BRW_REGISTER_TYPE_F);
+         break;
 
       case nir_tex_src_sampler_offset: {
          /* Figure out the highest possible sampler index and mark it as used */
@@ -1826,6 +1828,13 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
       }
    }
 
+   if (projector.file != BAD_FILE) {
+      fs_reg invproj = vgrf(glsl_type::float_type);
+      emit_math(SHADER_OPCODE_RCP, invproj, projector);
+      for (int i = 0; i < 3; i++)
+         emit(MUL(offset(coordinate, i), offset(coordinate, i), invproj));
+   }
+
    if (instr->op == nir_texop_txf_ms) {
       if (brw->gen >= 7 &&
           key_tex->compressed_multisample_layout_mask & (1 << sampler)) {
@@ -1838,7 +1847,7 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
    for (unsigned i = 0; i < 3; i++) {
       if (instr->const_offset[i] != 0) {
          assert(offset_components == 0);
-         offset = fs_reg(brw_texture_offset(ctx, instr->const_offset, 3));
+         tex_offset = fs_reg(brw_texture_offset(ctx, instr->const_offset, 3));
          break;
       }
    }
@@ -1880,7 +1889,7 @@ fs_visitor::nir_emit_texture(nir_tex_instr *instr)
 
    emit_texture(op, dest_type, coordinate, instr->coord_components,
                 shadow_comparitor, lod, lod2, lod_components, sample_index,
-                offset, mcs, gather_component,
+                tex_offset, mcs, gather_component,
                 is_cube_array, is_rect, sampler, sampler_reg, texunit);
 
    fs_reg dest = get_nir_dest(instr->dest);
-- 
2.3.3



More information about the mesa-dev mailing list