[Mesa-dev] [PATCH v2 19/25] radeonsi: generate an explicit switch instruction over vertex streams
Nicolai Hähnle
nhaehnle at gmail.com
Tue Dec 6 10:48:30 UTC 2016
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
SimplifyCFG generates a switch instruction anyway when all four streams
are present, but is simultaneously not smart enough to eliminate some
redundant jumps that it generates.
The generated assembly is still a bit silly, probably because the
control flow annotation doesn't know how to handle a switch with uniform
condition.
---
src/gallium/drivers/radeonsi/si_shader.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 4200da5..b545c4f 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6273,35 +6273,38 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
for (i = 0; i < gsinfo->num_outputs; ++i) {
outputs[i].semantic_name = gsinfo->output_semantic_name[i];
outputs[i].semantic_index = gsinfo->output_semantic_index[i];
for (int chan = 0; chan < 4; chan++) {
outputs[i].vertex_stream[chan] =
(gsinfo->output_streams[i] >> (2 * chan)) & 3;
}
}
+ LLVMBasicBlockRef end_bb;
+ LLVMValueRef switch_inst;
+
+ end_bb = LLVMAppendBasicBlockInContext(gallivm->context, ctx.main_fn, "end");
+ switch_inst = LLVMBuildSwitch(builder, stream_id, end_bb, 4);
+
for (int stream = 0; stream < 4; stream++) {
- struct lp_build_if_state if_ctx_stream;
+ LLVMBasicBlockRef bb;
if (!gsinfo->num_stream_output_components[stream])
continue;
if (stream > 0 && !gs_selector->so.num_outputs)
continue;
- LLVMValueRef is_stream =
- LLVMBuildICmp(builder, LLVMIntEQ,
- stream_id,
- lp_build_const_int32(gallivm, stream), "");
-
- lp_build_if(&if_ctx_stream, gallivm, is_stream);
+ bb = LLVMInsertBasicBlockInContext(gallivm->context, end_bb, "out");
+ LLVMAddCase(switch_inst, lp_build_const_int32(gallivm, stream), bb);
+ LLVMPositionBuilderAtEnd(builder, bb);
/* Fetch vertex data from GSVS ring */
for (i = 0; i < gsinfo->num_outputs; ++i) {
for (unsigned chan = 0; chan < 4; chan++) {
if (outputs[i].vertex_stream[chan] != stream) {
outputs[i].values[chan] = ctx.soa.bld_base.base.undef;
continue;
}
args[2] = lp_build_const_int32(
@@ -6321,23 +6324,25 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
/* Streamout and exports. */
if (gs_selector->so.num_outputs) {
si_llvm_emit_streamout(&ctx, outputs,
gsinfo->num_outputs,
stream);
}
if (stream == 0)
si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
- lp_build_endif(&if_ctx_stream);
+ LLVMBuildBr(builder, end_bb);
}
+ LLVMPositionBuilderAtEnd(builder, end_bb);
+
LLVMBuildRetVoid(gallivm->builder);
/* Dump LLVM IR before any optimization passes */
if (sscreen->b.debug_flags & DBG_PREOPT_IR &&
r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY))
LLVMDumpModule(bld_base->base.gallivm->module);
si_llvm_finalize_module(&ctx,
r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY));
--
2.7.4
More information about the mesa-dev
mailing list