<div dir="ltr">This is a general question for the interpolation support:<div><br></div><div>Why are we using the variable-based intrinsics directly, instead of lowering it to something index-based in the lower_io pass just like we do for normal inputs?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 16, 2014 at 1:12 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 102 +++++++++++++++++++++++++++++++<br>
 1 file changed, 102 insertions(+)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
index 46d855d..67714ec 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
@@ -1410,6 +1410,108 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)<br>
       break;<br>
    }<br>
<br>
+   case nir_intrinsic_interp_var_at_centroid:<br>
+   case nir_intrinsic_interp_var_at_sample:<br>
+   case nir_intrinsic_interp_var_at_offset: {<br>
+      /* in SIMD16 mode, the pixel interpolator returns coords interleaved<br>
+       * 8 channels at a time, same as the barycentric coords presented in<br>
+       * the FS payload. this requires a bit of extra work to support.<br>
+       */<br>
+      no16("interpolate_at_* not yet supported in SIMD16 mode.");<br>
+<br>
+      fs_reg dst_x(GRF, virtual_grf_alloc(2), BRW_REGISTER_TYPE_F);<br>
+      fs_reg dst_y = offset(dst_x, 1);<br>
+<br>
+      /* For most messages, we need one reg of ignored data; the hardware<br>
+       * requires mlen==1 even when there is no payload. in the per-slot<br>
+       * offset case, we'll replace this with the proper source data.<br>
+       */<br>
+      fs_reg src(this, glsl_type::float_type);<br>
+      int mlen = 1;     /* one reg unless overriden */<br>
+      fs_inst *inst;<br>
+<br>
+      switch (instr->intrinsic) {<br>
+      case nir_intrinsic_interp_var_at_centroid:<br>
+         inst = emit(FS_OPCODE_INTERPOLATE_AT_CENTROID, dst_x, src, fs_reg(0u));<br>
+         break;<br>
+<br>
+      case nir_intrinsic_interp_var_at_sample: {<br>
+         /* XXX: We should probably handle non-constant sample id's */<br>
+         nir_const_value *const_sample = nir_src_as_const_value(instr->src[0]);<br>
+         assert(const_sample);<br>
+         unsigned msg_data = const_sample ? const_sample->i[0] << 4 : 0;<br>
+         inst = emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_x, src,<br>
+                     fs_reg(msg_data));<br>
+         break;<br>
+      }<br>
+<br>
+      case nir_intrinsic_interp_var_at_offset: {<br>
+         nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);<br>
+<br>
+         if (const_offset) {<br>
+            unsigned off_x = MIN2((int)(const_offset->f[0] * 16), 7) & 0xf;<br>
+            unsigned off_y = MIN2((int)(const_offset->f[1] * 16), 7) & 0xf;<br>
+<br>
+            inst = emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_x, src,<br>
+                        fs_reg(off_x | (off_y << 4)));<br>
+         } else {<br>
+            src = fs_reg(this, glsl_type::ivec2_type);<br>
+            fs_reg offset_src = retype(get_nir_src(instr->src[0]),<br>
+                                       BRW_REGISTER_TYPE_F);<br>
+            for (int i = 0; i < 2; i++) {<br>
+               fs_reg temp(this, glsl_type::float_type);<br>
+               emit(MUL(temp, offset(offset_src, i), fs_reg(16.0f)));<br>
+               fs_reg itemp(this, glsl_type::int_type);<br>
+               emit(MOV(itemp, temp));  /* float to int */<br>
+<br>
+               /* Clamp the upper end of the range to +7/16.<br>
+                * ARB_gpu_shader5 requires that we support a maximum offset<br>
+                * of +0.5, which isn't representable in a S0.4 value -- if<br>
+                * we didn't clamp it, we'd end up with -8/16, which is the<br>
+                * opposite of what the shader author wanted.<br>
+                *<br>
+                * This is legal due to ARB_gpu_shader5's quantization<br>
+                * rules:<br>
+                *<br>
+                * "Not all values of <offset> may be supported; x and y<br>
+                * offsets may be rounded to fixed-point values with the<br>
+                * number of fraction bits given by the<br>
+                * implementation-dependent constant<br>
+                * FRAGMENT_INTERPOLATION_OFFSET_BITS"<br>
+                */<br>
+<br>
+               emit(BRW_OPCODE_SEL, offset(src, i), itemp, fs_reg(7))<br>
+                   ->conditional_mod = BRW_CONDITIONAL_L; /* min(src2, 7) */<br>
+            }<br>
+<br>
+            mlen = 2;<br>
+            inst = emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_x, src,<br>
+                        fs_reg(0u));<br>
+         }<br>
+         break;<br>
+      }<br>
+<br>
+      default:<br>
+         unreachable("Invalid intrinsic");<br>
+      }<br>
+<br>
+      inst->mlen = mlen;<br>
+      inst->regs_written = 2; /* 2 floats per slot returned */<br>
+      inst->pi_noperspective = instr->variables[0]->var->data.interpolation ==<br>
+                               INTERP_QUALIFIER_NOPERSPECTIVE;<br>
+<br>
+      for (unsigned j = 0; j < instr->num_components; j++) {<br>
+         fs_reg src = interp_reg(instr->variables[0]->var->data.location, j);<br>
+         src.type = dest.type;<br>
+<br>
+         fs_inst *inst = emit(FS_OPCODE_LINTERP, dest, dst_x, dst_y, src);<br>
+         if (instr->has_predicate)<br>
+            inst->predicate = BRW_PREDICATE_NORMAL;<br>
+         dest.reg_offset++;<br>
+      }<br>
+      break;<br>
+   }<br>
+<br>
    case nir_intrinsic_store_output_indirect:<br>
       has_indirect = true;<br>
    case nir_intrinsic_store_output: {<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.2.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>