i965/fs: Translate nir_intrinsic_load_output on a fragment output.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 22 Jul 2016 04:57:00 +0000 (21:57 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Fri, 26 Aug 2016 01:36:07 +0000 (18:36 -0700)
This gets the non-coherent framebuffer fetch path hooked up to the NIR
front-end.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs_nir.cpp

index 07db5d3d374f751874d0eb701e0d921be249cbb1..7bb2d5259dc4bbd8aa8ba3cc624ddda36f3401b0 100644 (file)
@@ -3315,6 +3315,26 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld,
       break;
    }
 
+   case nir_intrinsic_load_output: {
+      const unsigned l = GET_FIELD(nir_intrinsic_base(instr),
+                                   BRW_NIR_FRAG_OUTPUT_LOCATION);
+      assert(l >= FRAG_RESULT_DATA0);
+      nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
+      assert(const_offset && "Indirect output loads not allowed");
+      const unsigned target = l - FRAG_RESULT_DATA0 + const_offset->u32[0];
+      const fs_reg tmp = bld.vgrf(dest.type, 4);
+
+      assert(!reinterpret_cast<const brw_wm_prog_key *>(key)->coherent_fb_fetch);
+      emit_non_coherent_fb_read(bld, tmp, target);
+
+      for (unsigned j = 0; j < instr->num_components; j++) {
+         bld.MOV(offset(dest, bld, j),
+                 offset(tmp, bld, nir_intrinsic_component(instr) + j));
+      }
+
+      break;
+   }
+
    case nir_intrinsic_discard:
    case nir_intrinsic_discard_if: {
       /* We track our discarded pixels in f0.1.  By predicating on it, we can