From 17d7f7a292f0e9bf5b4b348eef08c699cf372a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Briano?= Date: Mon, 4 Sep 2023 22:30:04 -0700 Subject: [PATCH] intel/fs: read viewport and layer from the FS payload Reviewed-by: Caio Oliveira Part-of: --- src/intel/compiler/brw_fs_nir.cpp | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index edf470868d6..502f0105bad 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -3486,6 +3486,45 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld, 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 */