"");
/* If this thread has already emitted the declared maximum number of
- * vertices, kill it: excessive vertex emissions are not supposed to
- * have any effect, and GS threads have no externally observable
- * effects other than emitting vertices.
+ * vertices, don't emit any more: excessive vertex emissions are not
+ * supposed to have any effect.
*/
can_emit = LLVMBuildICmp(ctx->ac.builder, LLVMIntULT, gs_next_vertex,
LLVMConstInt(ctx->ac.i32, ctx->shader->info.gs.vertices_out, false), "");
- ac_build_kill_if_false(&ctx->ac, can_emit);
+
+ bool use_kill = !ctx->shader_info->gs.writes_memory;
+ if (use_kill)
+ ac_build_kill_if_false(&ctx->ac, can_emit);
+ else
+ ac_build_ifcc(&ctx->ac, can_emit, 6505);
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
unsigned output_usage_mask =
ac_build_sendmsg(&ctx->ac,
AC_SENDMSG_GS_OP_EMIT | AC_SENDMSG_GS | (stream << 8),
ctx->gs_wave_id);
+
+ if (!use_kill)
+ ac_build_endif(&ctx->ac, 6505);
}
static void
instr->intrinsic == nir_intrinsic_image_deref_atomic_comp_swap) {
if (nir->info.stage == MESA_SHADER_FRAGMENT)
info->ps.writes_memory = true;
+ else if (nir->info.stage == MESA_SHADER_GEOMETRY)
+ info->gs.writes_memory = true;
}
break;
}
case nir_intrinsic_ssbo_atomic_comp_swap:
if (nir->info.stage == MESA_SHADER_FRAGMENT)
info->ps.writes_memory = true;
+ else if (nir->info.stage == MESA_SHADER_GEOMETRY)
+ info->gs.writes_memory = true;
break;
case nir_intrinsic_load_deref:
gather_intrinsic_load_deref_info(nir, instr, info);