[Mesa-dev] [PATCHv3 2/3] i965: refactor texture instruction emission

Chia-I Wu olvaffe at gmail.com
Wed Oct 16 08:58:10 CEST 2013


From: Chia-I Wu <olv at lunarg.com>

Add fs_visitor::emit_texture, which is used to emit the texture instruction
after the message payload has been set up.

v2: rebased because of texture gather changes
v3: rebased because of texture-from-GRF changes

Signed-off-by: Chia-I Wu <olv at lunarg.com>
---
 src/mesa/drivers/dri/i965/brw_fs.h           |  10 +-
 src/mesa/drivers/dri/i965/brw_fs_fp.cpp      |  13 ++-
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 154 +++++++++++++--------------
 3 files changed, 85 insertions(+), 92 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index b5aed23..c2ba351 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -339,13 +339,17 @@ public:
    fs_reg rescale_texcoord(ir_texture *ir, fs_reg coordinate,
                            bool is_rect, int sampler, int texunit);
    fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
-			      fs_reg shadow_comp, fs_reg lod, fs_reg lod2);
+			      fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
+			      int sampler);
    fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                               fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
-                              fs_reg sample_index);
+                              fs_reg sample_index, int sampler);
    fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                               fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
-                              fs_reg sample_index);
+                              fs_reg sample_index, int sampler);
+   fs_inst *emit_texture(ir_texture *ir, fs_reg dst, fs_reg payload, int mlen,
+                         bool header_present, int regs_written, int sampler);
+
    fs_reg fix_math_operand(fs_reg src);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
index 1ebaa4f..da9e99f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
@@ -499,18 +499,17 @@ fs_visitor::emit_fragment_program_code()
                                        fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
                                        fpi->TexSrcUnit, fpi->TexSrcUnit);
 
-         fs_inst *inst;
          if (brw->gen >= 7) {
-            inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
+            emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy,
+                              sample_index, fpi->TexSrcUnit);
          } else if (brw->gen >= 5) {
-            inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
+            emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy,
+                              sample_index, fpi->TexSrcUnit);
          } else {
-            inst = emit_texture_gen4(ir, dst, coordinate, shadow_c, lod, dpdy);
+            emit_texture_gen4(ir, dst, coordinate, shadow_c, lod, dpdy,
+                              fpi->TexSrcUnit);
          }
 
-         inst->sampler = fpi->TexSrcUnit;
-         inst->shadow_compare = fpi->TexShadow;
-
          /* Reuse the GLSL swizzle_result() handler. */
          swizzle_result(ir, dst, fpi->TexSrcUnit);
          dst = this->result;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 9f37013..d164b04 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -901,8 +901,56 @@ fs_visitor::visit(ir_assignment *ir)
 }
 
 fs_inst *
+fs_visitor::emit_texture(ir_texture *ir, fs_reg dst, fs_reg payload, int mlen,
+                         bool header_present, int regs_written, int sampler)
+{
+   int base_mrf;
+   fs_inst *inst;
+
+   if (payload.file == MRF) {
+      base_mrf = payload.reg;
+      payload = reg_undef;
+   } else {
+      base_mrf = -1;
+   }
+
+   switch (ir->op) {
+   case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst, payload); break;
+   case ir_txb: inst = emit(FS_OPCODE_TXB, dst, payload); break;
+   case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst, payload); break;
+   case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst, payload); break;
+   case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst, payload); break;
+   case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst, payload); break;
+   case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
+   case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
+   case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break;
+   case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst, payload); break;
+   default: return NULL;
+   }
+
+   inst->base_mrf = base_mrf;
+   inst->mlen = mlen;
+   inst->header_present = header_present;
+   inst->regs_written = regs_written;
+
+   if (ir->offset != NULL && ir->op != ir_txf)
+      inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
+
+   if (ir->op == ir_tg4)
+      inst->texture_offset |= gather_channel(ir, sampler) << 16; // M0.2:16-17
+
+   inst->sampler = sampler;
+
+   if (ir->shadow_comparitor)
+      inst->shadow_compare = true;
+
+   return inst;
+}
+
+fs_inst *
 fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
-			      fs_reg shadow_c, fs_reg lod, fs_reg dPdy)
+			      fs_reg shadow_c, fs_reg lod, fs_reg dPdy,
+			      int sampler)
 {
    int mlen;
    int base_mrf = 1;
@@ -1037,30 +1085,17 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
    fs_inst *inst = NULL;
    switch (ir->op) {
    case ir_tex:
-      inst = emit(SHADER_OPCODE_TEX, dst);
-      break;
    case ir_txb:
-      inst = emit(FS_OPCODE_TXB, dst);
-      break;
    case ir_txl:
-      inst = emit(SHADER_OPCODE_TXL, dst);
-      break;
    case ir_txd:
-      inst = emit(SHADER_OPCODE_TXD, dst);
-      break;
    case ir_txs:
-      inst = emit(SHADER_OPCODE_TXS, dst);
-      break;
    case ir_txf:
-      inst = emit(SHADER_OPCODE_TXF, dst);
+      inst = emit_texture(ir, dst, fs_reg(MRF, base_mrf), mlen, true,
+                          simd16 ? 8 : 4, sampler);
       break;
    default:
       fail("unrecognized texture opcode");
    }
-   inst->base_mrf = base_mrf;
-   inst->mlen = mlen;
-   inst->header_present = true;
-   inst->regs_written = simd16 ? 8 : 4;
 
    if (simd16) {
       for (int i = 0; i < 4; i++) {
@@ -1084,7 +1119,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
 fs_inst *
 fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                               fs_reg shadow_c, fs_reg lod, fs_reg lod2,
-                              fs_reg sample_index)
+                              fs_reg sample_index, int sampler)
 {
    int mlen = 0;
    int base_mrf = 2;
@@ -1131,24 +1166,20 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       mlen += reg_width;
    }
 
-   fs_inst *inst = NULL;
    switch (ir->op) {
    case ir_tex:
-      inst = emit(SHADER_OPCODE_TEX, dst);
+   case ir_lod:
+   case ir_tg4:
       break;
    case ir_txb:
       mlen = MAX2(mlen, header_present + 4 * reg_width);
       emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
       mlen += reg_width;
-
-      inst = emit(FS_OPCODE_TXB, dst);
       break;
    case ir_txl:
       mlen = MAX2(mlen, header_present + 4 * reg_width);
       emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
       mlen += reg_width;
-
-      inst = emit(SHADER_OPCODE_TXL, dst);
       break;
    case ir_txd: {
       mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
@@ -1171,24 +1202,19 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
 	 lod2.reg_offset++;
 	 mlen += reg_width;
       }
-
-      inst = emit(SHADER_OPCODE_TXD, dst);
       break;
    }
    case ir_txs:
       emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod));
       mlen += reg_width;
-      inst = emit(SHADER_OPCODE_TXS, dst);
       break;
    case ir_query_levels:
       emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
       mlen += reg_width;
-      inst = emit(SHADER_OPCODE_TXS, dst);
       break;
    case ir_txf:
       mlen = header_present + 4 * reg_width;
       emit(MOV(fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), lod));
-      inst = emit(SHADER_OPCODE_TXF, dst);
       break;
    case ir_txf_ms:
       mlen = header_present + 4 * reg_width;
@@ -1198,34 +1224,24 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       /* sample index */
       emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), sample_index));
       mlen += reg_width;
-      inst = emit(SHADER_OPCODE_TXF_MS, dst);
-      break;
-   case ir_lod:
-      inst = emit(SHADER_OPCODE_LOD, dst);
-      break;
-   case ir_tg4:
-      inst = emit(SHADER_OPCODE_TG4, dst);
       break;
    default:
       fail("unrecognized texture opcode");
       break;
    }
-   inst->base_mrf = base_mrf;
-   inst->mlen = mlen;
-   inst->header_present = header_present;
-   inst->regs_written = 4;
 
    if (mlen > 11) {
       fail("Message length >11 disallowed by hardware\n");
    }
 
-   return inst;
+   return emit_texture(ir, dst, fs_reg(MRF, base_mrf),
+                       mlen, header_present, 4, sampler);
 }
 
 fs_inst *
 fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                               fs_reg shadow_c, fs_reg lod, fs_reg lod2,
-                              fs_reg sample_index)
+                              fs_reg sample_index, int sampler)
 {
    int reg_width = dispatch_width / 8;
    bool header_present = false;
@@ -1349,6 +1365,9 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
          next.reg_offset++;
       }
       break;
+   default:
+      fail("unrecognized texture opcode");
+      return NULL;
    }
 
    /* Set up the coordinate (except for cases where it was done above) */
@@ -1360,35 +1379,19 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       }
    }
 
-   /* Generate the SEND */
-   fs_inst *inst = NULL;
-   switch (ir->op) {
-   case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst, payload); break;
-   case ir_txb: inst = emit(FS_OPCODE_TXB, dst, payload); break;
-   case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst, payload); break;
-   case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst, payload); break;
-   case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst, payload); break;
-   case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst, payload); break;
-   case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
-   case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
-   case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break;
-   case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst, payload); break;
-   }
-   inst->base_mrf = -1;
+   int mlen;
+
    if (reg_width == 2)
-      inst->mlen = next.reg_offset * reg_width - header_present;
+      mlen = next.reg_offset * reg_width - header_present;
    else
-      inst->mlen = next.reg_offset * reg_width;
-
-   inst->header_present = header_present;
-   inst->regs_written = 4;
+      mlen = next.reg_offset * reg_width;
 
    virtual_grf_sizes[payload.reg] = next.reg_offset;
-   if (inst->mlen > 11) {
+   if (mlen > 11) {
       fail("Message length >11 disallowed by hardware\n");
    }
 
-   return inst;
+   return emit_texture(ir, dst, payload, mlen, header_present, 4, sampler);
 }
 
 fs_reg
@@ -1495,8 +1498,6 @@ fs_visitor::rescale_texcoord(ir_texture *ir, fs_reg coordinate,
 void
 fs_visitor::visit(ir_texture *ir)
 {
-   fs_inst *inst = NULL;
-
    int sampler =
       _mesa_get_sampler_uniform_value(ir->sampler, shader_prog, prog);
    /* FINISHME: We're failing to recompile our programs when the sampler is
@@ -1585,27 +1586,16 @@ fs_visitor::visit(ir_texture *ir)
    fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
 
    if (brw->gen >= 7) {
-      inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
-                               lod, lod2, sample_index);
+      emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
+                        lod, lod2, sample_index, sampler);
    } else if (brw->gen >= 5) {
-      inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
-                               lod, lod2, sample_index);
+      emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
+                        lod, lod2, sample_index, sampler);
    } else {
-      inst = emit_texture_gen4(ir, dst, coordinate, shadow_comparitor,
-                               lod, lod2);
+      emit_texture_gen4(ir, dst, coordinate, shadow_comparitor,
+                        lod, lod2, sampler);
    }
 
-   if (ir->offset != NULL && ir->op != ir_txf)
-      inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
-
-   if (ir->op == ir_tg4)
-      inst->texture_offset |= gather_channel(ir, sampler) << 16; // M0.2:16-17
-
-   inst->sampler = sampler;
-
-   if (ir->shadow_comparitor)
-      inst->shadow_compare = true;
-
    /* fixup #layers for cube map arrays */
    if (ir->op == ir_txs) {
       glsl_type const *type = ir->sampler->type;
-- 
1.8.3.1



More information about the mesa-dev mailing list