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