summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichel Daenzer <[email protected]>2014-02-13 15:37:11 +0900
committerMichel Dänzer <[email protected]>2014-02-27 10:27:55 +0900
commit59936a49dd0733492dfcdadb3918e6af6bc86e39 (patch)
treed1f86b5ce54145d3a3d642542ae794e377dbe898 /src
parentb3094d9927fe7aa5a84892262404aaad4d728724 (diff)
radeonsi: Prevent geometry shader from emitting too many vertices
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 77768214f5a..3a441f94909 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1905,6 +1905,7 @@ static void si_llvm_emit_vertex(
LLVMValueRef soffset = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
SI_PARAM_GS2VS_OFFSET);
LLVMValueRef gs_next_vertex;
+ LLVMValueRef can_emit, kill;
LLVMValueRef t_list_ptr;
LLVMValueRef t_list;
LLVMValueRef args[2];
@@ -1934,6 +1935,21 @@ static void si_llvm_emit_vertex(
/* Write vertex attribute values to GSVS ring */
gs_next_vertex = LLVMBuildLoad(gallivm->builder, si_shader_ctx->gs_next_vertex, "");
+
+ /* 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.
+ */
+ can_emit = LLVMBuildICmp(gallivm->builder, LLVMIntULE, gs_next_vertex,
+ lp_build_const_int32(gallivm,
+ shader->gs_max_out_vertices), "");
+ kill = lp_build_select(&bld_base->base, can_emit,
+ lp_build_const_float(gallivm, 1.0f),
+ lp_build_const_float(gallivm, -1.0f));
+ build_intrinsic(gallivm->builder, "llvm.AMDGPU.kill",
+ LLVMVoidTypeInContext(gallivm->context), &kill, 1, 0);
+
for (i = 0; i < shader->noutput; i++) {
LLVMValueRef *out_ptr =
si_shader_ctx->radeon_bld.soa.outputs[shader->output[i].index];