Mesa (master): radv: keep GS threads with excessive emissions which could write to memory

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Sep 16 19:58:28 UTC 2019


Module: Mesa
Branch: master
Commit: 0f29c9df315df8f8752cacc1d1ecab8cb9a2bb16
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f29c9df315df8f8752cacc1d1ecab8cb9a2bb16

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Mon Apr 29 13:41:46 2019 +0100

radv: keep GS threads with excessive emissions which could write to memory

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

---

 src/amd/vulkan/radv_nir_to_llvm.c | 15 +++++++++++----
 src/amd/vulkan/radv_shader.h      |  1 +
 src/amd/vulkan/radv_shader_info.c |  4 ++++
 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);




More information about the mesa-commit mailing list