i965: Add ARB_fragment_shader_interlock support.
authorPlamena Manolova <plamena.manolova@intel.com>
Fri, 27 Apr 2018 14:06:56 +0000 (15:06 +0100)
committerPlamena Manolova <plamena.manolova@intel.com>
Fri, 1 Jun 2018 15:36:39 +0000 (16:36 +0100)
Adds suppport for ARB_fragment_shader_interlock. We achieve
the interlock and fragment ordering by issuing a memory fence
via sendc.

Signed-off-by: Plamena Manolova <plamena.manolova@intel.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
docs/features.txt
docs/relnotes/18.2.0.html
src/intel/compiler/brw_eu.h
src/intel/compiler/brw_eu_defines.h
src/intel/compiler/brw_eu_emit.c
src/intel/compiler/brw_fs_generator.cpp
src/intel/compiler/brw_fs_nir.cpp
src/intel/compiler/brw_shader.cpp
src/intel/compiler/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/intel_extensions.c

index e786bbecf4424f29f8ca58cc1538fe2db559716c..ed4050cf98ad77bb538d691395758e161acd921e 100644 (file)
@@ -300,7 +300,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve
   GL_ARB_cl_event                                       not started
   GL_ARB_compute_variable_group_size                    DONE (nvc0, radeonsi)
   GL_ARB_ES3_2_compatibility                            DONE (i965/gen8+)
-  GL_ARB_fragment_shader_interlock                      not started
+  GL_ARB_fragment_shader_interlock                      DONE (i965)
   GL_ARB_gpu_shader_int64                               DONE (i965/gen8+, nvc0, radeonsi, softpipe, llvmpipe)
   GL_ARB_parallel_shader_compile                        not started, but Chia-I Wu did some related work in 2014
   GL_ARB_post_depth_coverage                            DONE (i965, nvc0)
index 00b253c076fd0f5bef00772cecade03231466920..a3f44a29dc827cdebff891381ac916dc54597d85 100644 (file)
@@ -44,7 +44,7 @@ Note: some of the new features are only available with certain drivers.
 </p>
 
 <ul>
-<li>TBD</li>
+<li>GL_ARB_fragment_shader_interlock on i965</li>
 </ul>
 
 <h2>Bug fixes</h2>
index 2655cdb0c5c670b99071e556d3e8ab5f75d0b0bf..84d5a6f86bec60be3c501bab2ef40c65cc57fc5e 100644 (file)
@@ -509,7 +509,8 @@ brw_byte_scattered_write(struct brw_codegen *p,
 
 void
 brw_memory_fence(struct brw_codegen *p,
-                 struct brw_reg dst);
+                 struct brw_reg dst,
+                 enum opcode send_op);
 
 void
 brw_pixel_interpolator_query(struct brw_codegen *p,
index 36519af63f20acd4afa54623e21bd4b039e679c1..ee306a6c2ce1f9af98f2bfb4cb60b51ac8fe7914 100644 (file)
@@ -480,6 +480,8 @@ enum opcode {
 
    SHADER_OPCODE_GET_BUFFER_SIZE,
 
+   SHADER_OPCODE_INTERLOCK,
+
    VEC4_OPCODE_MOV_BYTES,
    VEC4_OPCODE_PACK_BYTES,
    VEC4_OPCODE_UNPACK_UNIFORM,
index 6d81c636f27ed66b0b4e281ac1dffd945cf7b8b7..c442f8cc6f4ee65656021b8f5bd1d2952368bf6b 100644 (file)
@@ -3288,7 +3288,8 @@ brw_set_memory_fence_message(struct brw_codegen *p,
 
 void
 brw_memory_fence(struct brw_codegen *p,
-                 struct brw_reg dst)
+                 struct brw_reg dst,
+                 enum opcode send_op)
 {
    const struct gen_device_info *devinfo = p->devinfo;
    const bool commit_enable =
@@ -3304,7 +3305,7 @@ brw_memory_fence(struct brw_codegen *p,
    /* Set dst as destination for dependency tracking, the MEMORY_FENCE
     * message doesn't write anything back.
     */
-   insn = next_insn(p, BRW_OPCODE_SEND);
+   insn = next_insn(p, send_op);
    dst = retype(dst, BRW_REGISTER_TYPE_UW);
    brw_set_dest(p, insn, dst);
    brw_set_src0(p, insn, dst);
@@ -3316,7 +3317,7 @@ brw_memory_fence(struct brw_codegen *p,
        * flush it too.  Use a different register so both flushes can be
        * pipelined by the hardware.
        */
-      insn = next_insn(p, BRW_OPCODE_SEND);
+      insn = next_insn(p, send_op);
       brw_set_dest(p, insn, offset(dst, 1));
       brw_set_src0(p, insn, offset(dst, 1));
       brw_set_memory_fence_message(p, insn, GEN6_SFID_DATAPORT_RENDER_CACHE,
index f49ab442fb26428d93f16827dd4bd61a71222f52..de84f468d9b4d360d12ace87d9a21f07f796f80d 100644 (file)
@@ -2277,7 +2277,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          break;
 
       case SHADER_OPCODE_MEMORY_FENCE:
-         brw_memory_fence(p, dst);
+         brw_memory_fence(p, dst, BRW_OPCODE_SEND);
+         break;
+
+      case SHADER_OPCODE_INTERLOCK:
+         /* The interlock is basically a memory fence issued via sendc */
+         brw_memory_fence(p, dst, BRW_OPCODE_SENDC);
          break;
 
       case SHADER_OPCODE_FIND_LIVE_CHANNEL: {
index e287f11e47025fdb4ef0854c1cbd9131de6f6293..166da0aa6d7ad589f8015e1be8ece97412b273c6 100644 (file)
@@ -4823,6 +4823,21 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
       break;
    }
 
+   case nir_intrinsic_begin_invocation_interlock: {
+      const fs_builder ubld = bld.group(8, 0);
+      const fs_reg tmp = ubld.vgrf(BRW_REGISTER_TYPE_UD, 2);
+
+      ubld.emit(SHADER_OPCODE_INTERLOCK, tmp)->size_written = 2 *
+         REG_SIZE;
+
+      break;
+   }
+
+   case nir_intrinsic_end_invocation_interlock: {
+      /* We don't need to do anything here */
+      break;
+   }
+
    default:
       unreachable("unknown intrinsic");
    }
index 6e81db9c29888ba06e814ba862432748417a349e..b7fb06ddbd9cd523344e767dbd750a3462ff7cc8 100644 (file)
@@ -296,6 +296,9 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op)
       return "typed_surface_write_logical";
    case SHADER_OPCODE_MEMORY_FENCE:
       return "memory_fence";
+   case SHADER_OPCODE_INTERLOCK:
+      /* For an interlock we actually issue a memory fence via sendc. */
+      return "interlock";
 
    case SHADER_OPCODE_BYTE_SCATTERED_READ:
       return "byte_scattered_read";
@@ -1003,6 +1006,7 @@ backend_instruction::has_side_effects() const
    case SHADER_OPCODE_TYPED_SURFACE_WRITE:
    case SHADER_OPCODE_TYPED_SURFACE_WRITE_LOGICAL:
    case SHADER_OPCODE_MEMORY_FENCE:
+   case SHADER_OPCODE_INTERLOCK:
    case SHADER_OPCODE_URB_WRITE_SIMD8:
    case SHADER_OPCODE_URB_WRITE_SIMD8_PER_SLOT:
    case SHADER_OPCODE_URB_WRITE_SIMD8_MASKED:
index 3d17ff97971d1d3a45e2d7809b1fef0b92332f56..7519ccc9df38d40c281f1bcfe40ca811b5e8b921 100644 (file)
@@ -1904,7 +1904,7 @@ generate_code(struct brw_codegen *p,
          break;
 
       case SHADER_OPCODE_MEMORY_FENCE:
-         brw_memory_fence(p, dst);
+         brw_memory_fence(p, dst, BRW_OPCODE_SEND);
          break;
 
       case SHADER_OPCODE_FIND_LIVE_CHANNEL: {
index 34597c5e05a8b836744df63a03f5403fa1209926..5a9369d7b43a040b7e695c775cd00fecc5b22227 100644 (file)
@@ -245,6 +245,7 @@ intelInitExtensions(struct gl_context *ctx)
       ctx->Extensions.EXT_shader_samples_identical = true;
       ctx->Extensions.OES_primitive_bounding_box = true;
       ctx->Extensions.OES_texture_buffer = true;
+      ctx->Extensions.ARB_fragment_shader_interlock = true;
 
       if (can_do_pipelined_register_writes(brw->screen)) {
          ctx->Extensions.ARB_draw_indirect = true;