unsigned comp = nir_intrinsic_component(instr);
unsigned num_components = instr->num_components;
+ const struct brw_wm_prog_key *wm_key = (brw_wm_prog_key*) this->key;
+
+ if (wm_key->mesh_input == BRW_SOMETIMES) {
+ assert(devinfo->verx10 >= 125);
+ /* The FS payload gives us the viewport and layer clamped to valid
+ * ranges, but the spec for gl_ViewportIndex and gl_Layer includes
+ * the language:
+ * the fragment stage will read the same value written by the
+ * geometry stage, even if that value is out of range.
+ *
+ * Which is why these are normally passed as regular attributes.
+ * This isn't tested anywhere except some GL-only piglit tests
+ * though, so for the case where the FS may be used against either a
+ * traditional pipeline or a mesh one, where the position of these
+ * will change depending on the previous stage, read them from the
+ * payload to simplify things until the requisite magic is in place.
+ */
+ if (base == VARYING_SLOT_LAYER || base == VARYING_SLOT_VIEWPORT) {
+ assert(num_components == 1);
+ fs_reg g1(retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD));
+
+ unsigned mask, shift_count;
+ if (base == VARYING_SLOT_LAYER) {
+ shift_count = 16;
+ mask = 0x7ff << shift_count;
+ } else {
+ shift_count = 27;
+ mask = 0xf << shift_count;
+ }
+
+ fs_reg vp_or_layer = bld.vgrf(BRW_REGISTER_TYPE_UD);
+ bld.AND(vp_or_layer, g1, brw_imm_ud(mask));
+ fs_reg shifted_value = bld.vgrf(BRW_REGISTER_TYPE_UD);
+ bld.SHR(shifted_value, vp_or_layer, brw_imm_ud(shift_count));
+ bld.MOV(offset(dest, bld, 0), retype(shifted_value, dest.type));
+ break;
+ }
+ }
+
/* TODO(mesh): Multiview. Verify and handle these special cases for Mesh. */
/* Special case fields in the VUE header */