i965/skl: Send a message header when doing constant loads SIMD4x2
authorNeil Roberts <neil@linux.intel.com>
Thu, 12 Mar 2015 17:41:07 +0000 (17:41 +0000)
committerNeil Roberts <neil@linux.intel.com>
Tue, 17 Mar 2015 16:32:11 +0000 (16:32 +0000)
Commit 0ac4c272755c7 made it add a header for the send message when
using SIMD4x2 on Skylake because without this it will end up using
SIMD8D. However the patch missed the case when a sampler is being used
to implement constant loads from a buffer surface in a SIMD4x2 vertex
shader.

This fixes 29 Piglit tests, mostly related to the ARL instruction in
vertex programs.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
Tested-by: Anuj Phogat <anuj.phogat@gmail.com>
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_vp.cpp

index 010a5c48e8d55f3449458e715f62bb21c48462c8..e3a94ffb125b3393c469ec566d4e142a4baf5454 100644 (file)
@@ -1049,18 +1049,38 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
 {
    assert(surf_index.type == BRW_REGISTER_TYPE_UD);
 
+   struct brw_reg src = offset;
+   bool header_present = false;
+   int mlen = 1;
+
+   if (brw->gen >= 9) {
+      /* Skylake requires a message header in order to use SIMD4x2 mode. */
+      src = retype(brw_vec4_grf(offset.nr - 1, 0), BRW_REGISTER_TYPE_UD);
+      mlen = 2;
+      header_present = true;
+
+      brw_push_insn_state(p);
+      brw_set_default_mask_control(p, BRW_MASK_DISABLE);
+      brw_MOV(p, src, retype(brw_vec4_grf(0, 0), BRW_REGISTER_TYPE_UD));
+      brw_set_default_access_mode(p, BRW_ALIGN_1);
+
+      brw_MOV(p, get_element_ud(src, 2),
+              brw_imm_ud(GEN9_SAMPLER_SIMD_MODE_EXTENSION_SIMD4X2));
+      brw_pop_insn_state(p);
+   }
+
    if (surf_index.file == BRW_IMMEDIATE_VALUE) {
 
       brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND);
       brw_set_dest(p, insn, dst);
-      brw_set_src0(p, insn, offset);
+      brw_set_src0(p, insn, src);
       brw_set_sampler_message(p, insn,
                               surf_index.dw1.ud,
                               0, /* LD message ignores sampler unit */
                               GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
                               1, /* rlen */
-                              1, /* mlen */
-                              false, /* no header */
+                              mlen,
+                              header_present,
                               BRW_SAMPLER_SIMD_MODE_SIMD4X2,
                               0);
 
@@ -1089,8 +1109,8 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
                               0 /* sampler */,
                               GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
                               1 /* rlen */,
-                              1 /* mlen */,
-                              false /* header */,
+                              mlen /* mlen */,
+                              header_present /* header */,
                               BRW_SAMPLER_SIMD_MODE_SIMD4X2,
                               0);
       brw_inst_set_exec_size(p->brw, insn_or, BRW_EXECUTE_1);
@@ -1102,7 +1122,7 @@ vec4_generator::generate_pull_constant_load_gen7(vec4_instruction *inst,
       /* dst = send(offset, a0.0) */
       brw_inst *insn_send = brw_next_insn(p, BRW_OPCODE_SEND);
       brw_set_dest(p, insn_send, dst);
-      brw_set_src0(p, insn_send, offset);
+      brw_set_src0(p, insn_send, src);
       brw_set_indirect_send_descriptor(p, insn_send, BRW_SFID_SAMPLER, addr);
 
       brw_pop_insn_state(p);
index 195c6f5dae7ed4642b45894a38d7f9d8433e96b1..d5c6e9b5741c14e09fa49f8580bdfb61da5bd0b7 100644 (file)
@@ -1783,6 +1783,15 @@ vec4_visitor::visit(ir_expression *ir)
 
       if (brw->gen >= 7) {
          dst_reg grf_offset = dst_reg(this, glsl_type::int_type);
+
+         /* We have to use a message header on Skylake to get SIMD4x2 mode.
+          * Reserve space for the register.
+          */
+         if (brw->gen >= 9) {
+            grf_offset.reg_offset++;
+            alloc.sizes[grf_offset.reg] = 2;
+         }
+
          grf_offset.type = offset.type;
 
          emit(MOV(grf_offset, offset));
@@ -3477,6 +3486,15 @@ vec4_visitor::emit_pull_constant_load(bblock_t *block, vec4_instruction *inst,
 
    if (brw->gen >= 7) {
       dst_reg grf_offset = dst_reg(this, glsl_type::int_type);
+
+      /* We have to use a message header on Skylake to get SIMD4x2 mode.
+       * Reserve space for the register.
+       */
+      if (brw->gen >= 9) {
+         grf_offset.reg_offset++;
+         alloc.sizes[grf_offset.reg] = 2;
+      }
+
       grf_offset.type = offset.type;
       emit_before(block, inst, MOV(grf_offset, offset));
 
index ba3264dce6fa29b357e867678ef752ed609672ce..c3b0233eba223e8c65414abb2c8588aeb95d4bec 100644 (file)
@@ -527,6 +527,15 @@ vec4_vs_visitor::get_vp_src_reg(const prog_src_register &src)
 
          /* Add the small constant index to the address register */
          src_reg reladdr = src_reg(this, glsl_type::int_type);
+
+         /* We have to use a message header on Skylake to get SIMD4x2 mode.
+          * Reserve space for the register.
+          */
+         if (brw->gen >= 9) {
+            reladdr.reg_offset++;
+            alloc.sizes[reladdr.reg] = 2;
+         }
+
          dst_reg dst_reladdr = dst_reg(reladdr);
          dst_reladdr.writemask = WRITEMASK_X;
          emit(ADD(dst_reladdr, this->vp_addr_reg, src_reg(src.Index)));