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

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
Rhys Perry 2019-04-29 13:41:46 +01:00 committed by Rhys Perry
parent dcf13fbac9
commit 0f29c9df31
3 changed files with 16 additions and 4 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);