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++) {