ac/nir: mark some texture intrinsics as convergent
authorRhys Perry <pendingchaos02@gmail.com>
Wed, 29 May 2019 15:07:44 +0000 (16:07 +0100)
committerRhys Perry <pendingchaos02@gmail.com>
Tue, 4 Jun 2019 16:30:53 +0000 (17:30 +0100)
Otherwise LLVM can sink them and their texture coordinate calculations
into divergent branches.

v2: simplify the conditions on which the intrinsic is marked as convergent
v3: only mark as convergent in FS and CS with derivative groups

Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/amd/common/ac_nir_to_llvm.c

index 833b1e54abc76e8a30c6a4db5b66e9fa73150536..dd673cf5ea0e43a59f0f561c1e52858e82901b9e 100644 (file)
@@ -38,6 +38,7 @@ struct ac_nir_context {
        struct ac_shader_abi *abi;
 
        gl_shader_stage stage;
+       shader_info *info;
 
        LLVMValueRef *ssa_defs;
 
@@ -1394,6 +1395,22 @@ static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx,
        }
 
        args->attributes = AC_FUNC_ATTR_READNONE;
+       bool cs_derivs = ctx->stage == MESA_SHADER_COMPUTE &&
+                        ctx->info->cs.derivative_group != DERIVATIVE_GROUP_NONE;
+       if (ctx->stage == MESA_SHADER_FRAGMENT || cs_derivs) {
+               /* Prevent texture instructions with implicit derivatives from being
+                * sinked into branches. */
+               switch (instr->op) {
+               case nir_texop_tex:
+               case nir_texop_txb:
+               case nir_texop_lod:
+                       args->attributes |= AC_FUNC_ATTR_CONVERGENT;
+                       break;
+               default:
+                       break;
+               }
+       }
+
        return ac_build_image_opcode(&ctx->ac, args);
 }
 
@@ -4354,6 +4371,7 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
        ctx.abi = abi;
 
        ctx.stage = nir->info.stage;
+       ctx.info = &nir->info;
 
        ctx.main_function = LLVMGetBasicBlockParent(LLVMGetInsertBlock(ctx.ac.builder));