summaryrefslogtreecommitdiffstats
path: root/src/amd/vulkan
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2019-04-29 13:41:46 +0100
committerRhys Perry <[email protected]>2019-09-16 19:42:30 +0000
commit0f29c9df315df8f8752cacc1d1ecab8cb9a2bb16 (patch)
tree9201b6c026e0d1e6b673321c76393efd5627242a /src/amd/vulkan
parentdcf13fbac9d28ac25fc2c42f87733740009ce621 (diff)
radv: keep GS threads with excessive emissions which could write to memory
Signed-off-by: Rhys Perry <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/amd/vulkan')
-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);