[Mesa-dev] [PATCH 6/7] i965/fs: add support for gather4 with nonconstant offsets

Chris Forbes chrisf at ijw.co.nz
Tue Oct 8 02:35:00 PDT 2013


Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 45 ++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 15cfaa7..fb27ad5 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1249,11 +1249,12 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       mlen += reg_width;
    }
 
+   bool has_nonconstant_offset = ir->offset && !ir->offset->as_constant();
+
    /* Set up the LOD info */
    switch (ir->op) {
    case ir_tex:
    case ir_lod:
-   case ir_tg4:
       break;
    case ir_txb:
       emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
@@ -1350,10 +1351,43 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
          mlen += reg_width;
       }
       break;
+   case ir_tg4:
+      if (has_nonconstant_offset) {
+         /* More crazy intermixing */
+         ir->offset->accept(this);
+         fs_reg offset_value = this->result;
+
+         for (int i = 0; i < 2; i++) { /* u, v */
+            emit(MOV(fs_reg(MRF, base_mrf + mlen), coordinate));
+            coordinate.reg_offset++;
+            mlen += reg_width;
+         }
+
+         for (int i = 0; i < 2; i++) { /* offu, offv */
+            emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), offset_value));
+            offset_value.reg_offset++;
+            mlen += reg_width;
+         }
+
+         if (ir->coordinate->type->vector_elements == 3) { /* r if present */
+            emit(MOV(fs_reg(MRF, base_mrf + mlen), coordinate));
+            coordinate.reg_offset++;
+            mlen += reg_width;
+         }
+      }
+      else {
+         /* just do the usual thing */
+         for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+            emit(MOV(fs_reg(MRF, base_mrf + mlen), coordinate));
+            coordinate.reg_offset++;
+            mlen += reg_width;
+         }
+      }
+      break;
    }
 
    /* Set up the coordinate (except for cases where it was done above) */
-   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_query_levels) {
+   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_query_levels && ir->op != ir_tg4) {
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
 	 emit(MOV(fs_reg(MRF, base_mrf + mlen), coordinate));
 	 coordinate.reg_offset++;
@@ -1373,7 +1407,12 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
    case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
    case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst); break;
    case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst); break;
-   case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst); break;
+   case ir_tg4:
+      if (has_nonconstant_offset)
+         inst = emit(SHADER_OPCODE_TG4_OFFSET, dst);
+      else
+         inst = emit(SHADER_OPCODE_TG4, dst);
+      break;
    }
    inst->base_mrf = base_mrf;
    inst->mlen = mlen;
-- 
1.8.4



More information about the mesa-dev mailing list