summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/amd/vulkan/radv_nir_to_llvm.c15
-rw-r--r--src/amd/vulkan/radv_shader.h1
-rw-r--r--src/amd/vulkan/radv_shader_info.c4
3 files changed, 16 insertions, 4 deletions
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index ee4acf7b5a7..37c81d5b45f 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -1761,13 +1761,17 @@ visit_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVMValueRef *addr
"");
/* 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 =
@@ -1814,6 +1818,9 @@ visit_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVMValueRef *addr
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
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 874318e7dc4..57f9d160ed0 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -253,6 +253,7 @@ struct radv_shader_info {
uint8_t num_stream_output_components[4];
uint8_t output_streams[VARYING_SLOT_VAR31 + 1];
uint8_t max_stream;
+ bool writes_memory;
unsigned gsvs_vertex_size;
unsigned max_gsvs_emit_size;
unsigned vertices_in;
diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c
index e8efbf6778b..950b5bd599d 100644
--- a/src/amd/vulkan/radv_shader_info.c
+++ b/src/amd/vulkan/radv_shader_info.c
@@ -310,6 +310,8 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
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;
}
@@ -326,6 +328,8 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr,
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);