Mesa (main): gallivm/nir: Don't do uniform-and-broadcast access on inactive invocations.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 6 00:37:10 UTC 2022


Module: Mesa
Branch: main
Commit: 9ab4ecb1ae82db5793bc3bb17ea0cab625d88ec3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9ab4ecb1ae82db5793bc3bb17ea0cab625d88ec3

Author: Emma Anholt <emma at anholt.net>
Date:   Fri Feb 11 09:12:10 2022 -0800

gallivm/nir: Don't do uniform-and-broadcast access on inactive invocations.

In a fragment shader or inside of control flow, invocation 0 might be
inactive, and so our use-first-invocation-and-broadcast optimizations
would be invalid, and the loop logic of an emit_read_invocation would
defeat the point of these optimized paths.

For load_kernel_input, I didn't guard the uniform path with the check
because some CL tests that are currently passing are doing the
load_kernel_input under (presumably) uniform control flow.  Instead, I
dropped in a once warning for the next person to be debugging CL.

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14999>

---

 src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c | 27 +++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
index 846583c7354..43fa14a0e73 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
@@ -70,6 +70,27 @@ mask_vec(struct lp_build_nir_context *bld_base)
                        exec_mask->exec_mask, "");
 }
 
+static bool
+invocation_0_must_be_active(struct lp_build_nir_context *bld_base)
+{
+   struct lp_build_nir_soa_context * bld = (struct lp_build_nir_soa_context *)bld_base;
+
+   /* Fragment shaders may dispatch with invocation 0 inactive.  All other
+    * stages have invocation 0 active at the top.  (See
+    * lp_build_tgsi_params.mask setup in draw_llvm.c and lp_state_*.c)
+    */
+   if (bld_base->shader->info.stage == MESA_SHADER_FRAGMENT)
+      return false;
+
+   /* If we're in some control flow right now, then invocation 0 may be
+    * disabled.
+    */
+   if (bld->exec_mask.has_mask)
+      return false;
+
+   return true;
+}
+
 static LLVMValueRef
 emit_fetch_64bit(
    struct lp_build_nir_context * bld_base,
@@ -740,6 +761,10 @@ static void emit_load_kernel_arg(struct lp_build_nir_context *bld_base,
    LLVMTypeRef ptr_type = LLVMPointerType(bld_broad->elem_type, 0);
    kernel_args_ptr = LLVMBuildBitCast(builder, kernel_args_ptr, ptr_type, "");
 
+   if (!invocation_0_must_be_active(bld_base)) {
+      mesa_logw_once("Treating load_kernel_arg in control flow as uniform, results may be incorrect.");
+   }
+
    if (offset_is_uniform) {
       offset = LLVMBuildExtractElement(builder, offset, lp_build_const_int32(gallivm, 0), "");
 
@@ -998,7 +1023,7 @@ static void emit_load_ubo(struct lp_build_nir_context *bld_base,
    LLVMTypeRef ptr_type = LLVMPointerType(bld_broad->elem_type, 0);
    consts_ptr = LLVMBuildBitCast(builder, consts_ptr, ptr_type, "");
 
-   if (offset_is_uniform) {
+   if (offset_is_uniform && invocation_0_must_be_active(bld_base)) {
       offset = LLVMBuildExtractElement(builder, offset, lp_build_const_int32(gallivm, 0), "");
 
       for (unsigned c = 0; c < nc; c++) {



More information about the mesa-commit mailing list