Mesa (master): i965/fs: Add instruction emit for varying-index reads of uniforms.

Eric Anholt anholt at kemper.freedesktop.org
Wed Dec 5 01:13:09 UTC 2012


Module: Mesa
Branch: master
Commit: d8214e4384aaf0ee412ad9aea80f9fec522c1e4a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d8214e4384aaf0ee412ad9aea80f9fec522c1e4a

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Nov  7 11:18:34 2012 -0800

i965/fs: Add instruction emit for varying-index reads of uniforms.

The gen7 send-from-GRF path is sufficiently different from the perspective of
IR generation and optimization that I just made it a separate opcode.

v2: fix whitespace, rebase on Ken's recent refactor.

---

 src/mesa/drivers/dri/i965/brw_defines.h   |    3 +
 src/mesa/drivers/dri/i965/brw_fs.cpp      |    2 +
 src/mesa/drivers/dri/i965/brw_fs.h        |    6 ++
 src/mesa/drivers/dri/i965/brw_fs_emit.cpp |   94 +++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 6e4fb13..3423178 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -675,6 +675,8 @@ enum opcode {
    FS_OPCODE_SPILL,
    FS_OPCODE_UNSPILL,
    FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
+   FS_OPCODE_VARYING_PULL_CONSTANT_LOAD,
+   FS_OPCODE_VARYING_PULL_CONSTANT_LOAD_GEN7,
    FS_OPCODE_MOV_DISPATCH_TO_FLAGS,
 
    VS_OPCODE_URB_WRITE,
@@ -909,6 +911,7 @@ enum brw_message_target {
 
 /* GEN7 */
 #define GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE          10
+#define GEN7_DATAPORT_DC_DWORD_SCATTERED_READ                       3
 
 #define BRW_MATH_FUNCTION_INV                              1
 #define BRW_MATH_FUNCTION_LOG                              2
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 21473e9..669f408 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -518,6 +518,8 @@ fs_visitor::implied_mrf_writes(fs_inst *inst)
    case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD:
    case FS_OPCODE_UNSPILL:
       return 1;
+   case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD:
+      return inst->header_present;
    case FS_OPCODE_SPILL:
       return 2;
    default:
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index c14e779..dae7815 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -484,6 +484,12 @@ private:
    void generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst,
                                             struct brw_reg index,
                                             struct brw_reg offset);
+   void generate_varying_pull_constant_load(fs_inst *inst, struct brw_reg dst,
+                                            struct brw_reg index);
+   void generate_varying_pull_constant_load_gen7(fs_inst *inst,
+                                                 struct brw_reg dst,
+                                                 struct brw_reg index,
+                                                 struct brw_reg offset);
    void generate_mov_dispatch_to_flags();
 
    struct brw_context *brw;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 87a5e53..37eed1b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -648,6 +648,92 @@ fs_generator::generate_uniform_pull_constant_load(fs_inst *inst,
    }
 }
 
+void
+fs_generator::generate_varying_pull_constant_load(fs_inst *inst,
+                                                  struct brw_reg dst,
+                                                  struct brw_reg index)
+{
+   assert(intel->gen < 7); /* Should use the gen7 variant. */
+   assert(inst->header_present);
+
+   assert(index.file == BRW_IMMEDIATE_VALUE &&
+	  index.type == BRW_REGISTER_TYPE_UD);
+   uint32_t surf_index = index.dw1.ud;
+
+   uint32_t msg_type, msg_control, rlen;
+   if (intel->gen >= 6)
+      msg_type = GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+   else if (intel->gen == 5 || intel->is_g4x)
+      msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+   else
+      msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+
+   if (dispatch_width == 16) {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
+      rlen = 2;
+   } else {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
+      rlen = 1;
+   }
+
+   struct brw_reg header = brw_vec8_grf(0, 0);
+   gen6_resolve_implied_move(p, &header, inst->base_mrf);
+
+   struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
+   brw_set_dest(p, send, dst);
+   brw_set_src0(p, send, header);
+   if (intel->gen < 6)
+      send->header.destreg__conditionalmod = inst->base_mrf;
+   brw_set_dp_read_message(p, send,
+                           surf_index,
+                           msg_control,
+                           msg_type,
+                           BRW_DATAPORT_READ_TARGET_DATA_CACHE,
+                           inst->mlen,
+                           inst->header_present,
+                           rlen);
+}
+
+void
+fs_generator::generate_varying_pull_constant_load_gen7(fs_inst *inst,
+                                                       struct brw_reg dst,
+                                                       struct brw_reg index,
+                                                       struct brw_reg offset)
+{
+   assert(intel->gen >= 7);
+   /* Varying-offset pull constant loads are treated as a normal expression on
+    * gen7, so the fact that it's a send message is hidden at the IR level.
+    */
+   assert(!inst->header_present);
+   assert(!inst->mlen);
+
+   assert(index.file == BRW_IMMEDIATE_VALUE &&
+	  index.type == BRW_REGISTER_TYPE_UD);
+   uint32_t surf_index = index.dw1.ud;
+
+   uint32_t msg_control, rlen, mlen;
+   if (dispatch_width == 16) {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
+      mlen = rlen = 2;
+   } else {
+      msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
+      mlen = rlen = 1;
+   }
+
+   struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
+   brw_set_dest(p, send, dst);
+   brw_set_src0(p, send, offset);
+   if (intel->gen < 6)
+      send->header.destreg__conditionalmod = inst->base_mrf;
+   brw_set_dp_read_message(p, send,
+                           surf_index,
+                           msg_control,
+                           GEN7_DATAPORT_DC_DWORD_SCATTERED_READ,
+                           BRW_DATAPORT_READ_TARGET_DATA_CACHE,
+                           mlen,
+                           inst->header_present,
+                           rlen);
+}
 
 /**
  * Cause the current pixel/sample mask (from R1.7 bits 15:0) to be transferred
@@ -1021,6 +1107,14 @@ fs_generator::generate_code(exec_list *instructions)
 	 generate_uniform_pull_constant_load(inst, dst, src[0], src[1]);
 	 break;
 
+      case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD:
+	 generate_varying_pull_constant_load(inst, dst, src[0]);
+	 break;
+
+      case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD_GEN7:
+	 generate_varying_pull_constant_load_gen7(inst, dst, src[0], src[1]);
+	 break;
+
       case FS_OPCODE_FB_WRITE:
 	 generate_fb_write(inst);
 	 break;




More information about the mesa-commit mailing list