mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 15:48:36 +02:00
radeonsi: pull iteration over vertex streams into GS copy shader logic
The iteration is not needed for normal vertex shaders. Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
parent
180ae18ec5
commit
fc0e009aa7
1 changed files with 37 additions and 25 deletions
|
|
@ -2265,11 +2265,13 @@ static void emit_streamout_output(struct si_shader_context *ctx,
|
||||||
stream_out->dst_offset * 4);
|
stream_out->dst_offset * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On SI, the vertex shader is responsible for writing streamout data
|
/**
|
||||||
* to buffers. */
|
* Write streamout data to buffers for vertex stream @p stream (different
|
||||||
|
* vertex streams can occur for GS copy shaders).
|
||||||
|
*/
|
||||||
static void si_llvm_emit_streamout(struct si_shader_context *ctx,
|
static void si_llvm_emit_streamout(struct si_shader_context *ctx,
|
||||||
struct si_shader_output_values *outputs,
|
struct si_shader_output_values *outputs,
|
||||||
unsigned noutput)
|
unsigned noutput, unsigned stream)
|
||||||
{
|
{
|
||||||
struct si_shader_selector *sel = ctx->shader->selector;
|
struct si_shader_selector *sel = ctx->shader->selector;
|
||||||
struct pipe_stream_output_info *so = &sel->so;
|
struct pipe_stream_output_info *so = &sel->so;
|
||||||
|
|
@ -2288,27 +2290,11 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
|
||||||
LLVMValueRef can_emit =
|
LLVMValueRef can_emit =
|
||||||
LLVMBuildICmp(builder, LLVMIntULT, tid, so_vtx_count, "");
|
LLVMBuildICmp(builder, LLVMIntULT, tid, so_vtx_count, "");
|
||||||
|
|
||||||
LLVMValueRef stream_id =
|
|
||||||
unpack_param(ctx, ctx->param_streamout_config, 24, 2);
|
|
||||||
|
|
||||||
/* Emit the streamout code conditionally. This actually avoids
|
/* Emit the streamout code conditionally. This actually avoids
|
||||||
* out-of-bounds buffer access. The hw tells us via the SGPR
|
* out-of-bounds buffer access. The hw tells us via the SGPR
|
||||||
* (so_vtx_count) which threads are allowed to emit streamout data. */
|
* (so_vtx_count) which threads are allowed to emit streamout data. */
|
||||||
lp_build_if(&if_ctx, gallivm, can_emit);
|
lp_build_if(&if_ctx, gallivm, can_emit);
|
||||||
|
{
|
||||||
for (int stream = 0; stream < 4; ++stream) {
|
|
||||||
struct lp_build_if_state if_ctx_stream;
|
|
||||||
|
|
||||||
if (!sel->info.num_stream_output_components[stream])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LLVMValueRef is_stream =
|
|
||||||
LLVMBuildICmp(builder, LLVMIntEQ,
|
|
||||||
stream_id,
|
|
||||||
lp_build_const_int32(gallivm, stream), "");
|
|
||||||
|
|
||||||
lp_build_if(&if_ctx_stream, gallivm, is_stream);
|
|
||||||
|
|
||||||
/* The buffer offset is computed as follows:
|
/* The buffer offset is computed as follows:
|
||||||
* ByteOffset = streamout_offset[buffer_id]*4 +
|
* ByteOffset = streamout_offset[buffer_id]*4 +
|
||||||
* (streamout_write_index + thread_id)*stride[buffer_id] +
|
* (streamout_write_index + thread_id)*stride[buffer_id] +
|
||||||
|
|
@ -2360,8 +2346,6 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
|
||||||
emit_streamout_output(ctx, so_buffers, so_write_offset,
|
emit_streamout_output(ctx, so_buffers, so_write_offset,
|
||||||
&so->output[i], &outputs[reg]);
|
&so->output[i], &outputs[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lp_build_endif(&if_ctx_stream);
|
|
||||||
}
|
}
|
||||||
lp_build_endif(&if_ctx);
|
lp_build_endif(&if_ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -2932,7 +2916,7 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
|
||||||
VS_EPILOG_PRIMID_LOC, "");
|
VS_EPILOG_PRIMID_LOC, "");
|
||||||
|
|
||||||
if (ctx->shader->selector->so.num_outputs)
|
if (ctx->shader->selector->so.num_outputs)
|
||||||
si_llvm_emit_streamout(ctx, outputs, i);
|
si_llvm_emit_streamout(ctx, outputs, i, 0);
|
||||||
si_llvm_export_vs(bld_base, outputs, i);
|
si_llvm_export_vs(bld_base, outputs, i);
|
||||||
FREE(outputs);
|
FREE(outputs);
|
||||||
}
|
}
|
||||||
|
|
@ -6354,6 +6338,7 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
|
||||||
struct si_shader_context ctx;
|
struct si_shader_context ctx;
|
||||||
struct si_shader *shader;
|
struct si_shader *shader;
|
||||||
struct gallivm_state *gallivm = &ctx.gallivm;
|
struct gallivm_state *gallivm = &ctx.gallivm;
|
||||||
|
LLVMBuilderRef builder;
|
||||||
struct lp_build_tgsi_context *bld_base = &ctx.soa.bld_base;
|
struct lp_build_tgsi_context *bld_base = &ctx.soa.bld_base;
|
||||||
struct lp_build_context *uint = &bld_base->uint_bld;
|
struct lp_build_context *uint = &bld_base->uint_bld;
|
||||||
struct si_shader_output_values *outputs;
|
struct si_shader_output_values *outputs;
|
||||||
|
|
@ -6379,6 +6364,8 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
|
||||||
si_init_shader_ctx(&ctx, sscreen, shader, tm);
|
si_init_shader_ctx(&ctx, sscreen, shader, tm);
|
||||||
ctx.type = PIPE_SHADER_VERTEX;
|
ctx.type = PIPE_SHADER_VERTEX;
|
||||||
|
|
||||||
|
builder = gallivm->builder;
|
||||||
|
|
||||||
create_meta_data(&ctx);
|
create_meta_data(&ctx);
|
||||||
create_function(&ctx);
|
create_function(&ctx);
|
||||||
preload_ring_buffers(&ctx);
|
preload_ring_buffers(&ctx);
|
||||||
|
|
@ -6395,6 +6382,14 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
|
||||||
args[7] = uint->one; /* SLC */
|
args[7] = uint->one; /* SLC */
|
||||||
args[8] = uint->zero; /* TFE */
|
args[8] = uint->zero; /* TFE */
|
||||||
|
|
||||||
|
/* Fetch the vertex stream ID.*/
|
||||||
|
LLVMValueRef stream_id;
|
||||||
|
|
||||||
|
if (gs_selector->so.num_outputs)
|
||||||
|
stream_id = unpack_param(&ctx, ctx.param_streamout_config, 24, 2);
|
||||||
|
else
|
||||||
|
stream_id = uint->zero;
|
||||||
|
|
||||||
/* Fetch vertex data from GSVS ring */
|
/* Fetch vertex data from GSVS ring */
|
||||||
for (i = 0; i < gsinfo->num_outputs; ++i) {
|
for (i = 0; i < gsinfo->num_outputs; ++i) {
|
||||||
unsigned chan;
|
unsigned chan;
|
||||||
|
|
@ -6420,8 +6415,25 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gs_selector->so.num_outputs)
|
if (gs_selector->so.num_outputs) {
|
||||||
si_llvm_emit_streamout(&ctx, outputs, gsinfo->num_outputs);
|
for (int stream = 0; stream < 4; stream++) {
|
||||||
|
struct lp_build_if_state if_ctx_stream;
|
||||||
|
|
||||||
|
if (!gsinfo->num_stream_output_components[stream])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LLVMValueRef is_stream =
|
||||||
|
LLVMBuildICmp(builder, LLVMIntEQ,
|
||||||
|
stream_id,
|
||||||
|
lp_build_const_int32(gallivm, stream), "");
|
||||||
|
|
||||||
|
lp_build_if(&if_ctx_stream, gallivm, is_stream);
|
||||||
|
si_llvm_emit_streamout(&ctx, outputs,
|
||||||
|
gsinfo->num_outputs,
|
||||||
|
stream);
|
||||||
|
lp_build_endif(&if_ctx_stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
|
si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
|
||||||
|
|
||||||
LLVMBuildRetVoid(gallivm->builder);
|
LLVMBuildRetVoid(gallivm->builder);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue