[Mesa-dev] [PATCH 26/31] radeonsi: make si_generate_gs_copy_shader usable as a standalone function
Nicolai Hähnle
nhaehnle at gmail.com
Mon Oct 31 22:11:13 UTC 2016
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
It really only depends on the shader selector.
---
src/gallium/drivers/radeonsi/si_shader.c | 79 +++++++++++++++++---------------
1 file changed, 43 insertions(+), 36 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 58f8c15..e755399 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6073,106 +6073,119 @@ int si_compile_llvm(struct si_screen *sscreen,
static void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
{
if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind)
LLVMBuildRetVoid(ctx->gallivm.builder);
else
LLVMBuildRet(ctx->gallivm.builder, ret);
}
/* Generate code for the hardware VS shader stage to go with a geometry shader */
-static int si_generate_gs_copy_shader(struct si_screen *sscreen,
- struct si_shader_context *ctx,
- struct si_shader *gs,
- struct pipe_debug_callback *debug)
+static struct si_shader *
+si_generate_gs_copy_shader(struct si_screen *sscreen,
+ LLVMTargetMachineRef tm,
+ struct si_shader_selector *gs_selector,
+ struct pipe_debug_callback *debug)
{
- struct gallivm_state *gallivm = &ctx->gallivm;
- struct lp_build_tgsi_context *bld_base = &ctx->soa.bld_base;
+ struct si_shader_context ctx;
+ struct si_shader *shader;
+ struct gallivm_state *gallivm = &ctx.gallivm;
+ struct lp_build_tgsi_context *bld_base = &ctx.soa.bld_base;
struct lp_build_context *uint = &bld_base->uint_bld;
struct si_shader_output_values *outputs;
- struct tgsi_shader_info *gsinfo = &gs->selector->info;
+ struct tgsi_shader_info *gsinfo = &gs_selector->info;
LLVMValueRef args[9];
int i, r;
outputs = MALLOC(gsinfo->num_outputs * sizeof(outputs[0]));
- si_init_shader_ctx(ctx, sscreen, ctx->shader, ctx->tm);
- ctx->type = PIPE_SHADER_VERTEX;
- ctx->is_gs_copy_shader = true;
+ shader = CALLOC_STRUCT(si_shader);
+ if (!shader)
+ return NULL;
- create_meta_data(ctx);
- create_function(ctx);
- preload_ring_buffers(ctx);
+ shader->selector = gs_selector;
+ si_init_shader_ctx(&ctx, sscreen, shader, tm);
+ ctx.type = PIPE_SHADER_VERTEX;
+ ctx.is_gs_copy_shader = true;
+
+ create_meta_data(&ctx);
+ create_function(&ctx);
+ preload_ring_buffers(&ctx);
- args[0] = ctx->gsvs_ring[0];
+ args[0] = ctx.gsvs_ring[0];
args[1] = lp_build_mul_imm(uint,
- LLVMGetParam(ctx->main_fn,
- ctx->param_vertex_id),
+ LLVMGetParam(ctx.main_fn,
+ ctx.param_vertex_id),
4);
args[3] = uint->zero;
args[4] = uint->one; /* OFFEN */
args[5] = uint->zero; /* IDXEN */
args[6] = uint->one; /* GLC */
args[7] = uint->one; /* SLC */
args[8] = uint->zero; /* TFE */
/* Fetch vertex data from GSVS ring */
for (i = 0; i < gsinfo->num_outputs; ++i) {
unsigned chan;
outputs[i].name = gsinfo->output_semantic_name[i];
outputs[i].sid = gsinfo->output_semantic_index[i];
for (chan = 0; chan < 4; chan++) {
args[2] = lp_build_const_int32(gallivm,
(i * 4 + chan) *
- gs->selector->gs_max_out_vertices * 16 * 4);
+ gs_selector->gs_max_out_vertices * 16 * 4);
outputs[i].values[chan] =
LLVMBuildBitCast(gallivm->builder,
lp_build_intrinsic(gallivm->builder,
"llvm.SI.buffer.load.dword.i32.i32",
- ctx->i32, args, 9,
+ ctx.i32, args, 9,
LLVMReadOnlyAttribute),
- ctx->f32, "");
+ ctx.f32, "");
}
}
si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
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,
+ si_llvm_finalize_module(&ctx,
r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY));
- r = si_compile_llvm(sscreen, &ctx->shader->binary,
- &ctx->shader->config, ctx->tm,
+ r = si_compile_llvm(sscreen, &ctx.shader->binary,
+ &ctx.shader->config, ctx.tm,
bld_base->base.gallivm->module,
debug, PIPE_SHADER_GEOMETRY,
"GS Copy Shader");
if (!r) {
if (r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY))
fprintf(stderr, "GS Copy Shader:\n");
- si_shader_dump(sscreen, ctx->shader, debug,
+ si_shader_dump(sscreen, ctx.shader, debug,
PIPE_SHADER_GEOMETRY, stderr);
- r = si_shader_binary_upload(sscreen, ctx->shader);
+ r = si_shader_binary_upload(sscreen, ctx.shader);
}
- si_llvm_dispose(ctx);
+ si_llvm_dispose(&ctx);
FREE(outputs);
- return r;
+
+ if (r != 0) {
+ FREE(shader);
+ shader = NULL;
+ }
+ return shader;
}
static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
FILE *f)
{
int i;
fprintf(f, "SHADER KEY\n");
switch (shader) {
@@ -7131,30 +7144,24 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
}
if (G_0286CC_ANCILLARY_ENA(shader->config.spi_ps_input_addr))
shader->info.num_input_vgprs += 1;
if (G_0286CC_SAMPLE_COVERAGE_ENA(shader->config.spi_ps_input_addr))
shader->info.num_input_vgprs += 1;
if (G_0286CC_POS_FIXED_PT_ENA(shader->config.spi_ps_input_addr))
shader->info.num_input_vgprs += 1;
}
if (ctx.type == PIPE_SHADER_GEOMETRY) {
- shader->gs_copy_shader = CALLOC_STRUCT(si_shader);
- shader->gs_copy_shader->selector = shader->selector;
- ctx.shader = shader->gs_copy_shader;
- r = si_generate_gs_copy_shader(sscreen, &ctx,
- shader, debug);
- if (r) {
- free(shader->gs_copy_shader);
- shader->gs_copy_shader = NULL;
- return r;
- }
+ shader->gs_copy_shader =
+ si_generate_gs_copy_shader(sscreen, tm, shader->selector, debug);
+ if (!shader->gs_copy_shader)
+ return -1;
}
return 0;
}
/**
* Create, compile and return a shader part (prolog or epilog).
*
* \param sscreen screen
* \param list list of shader parts of the same category
--
2.7.4
More information about the mesa-dev
mailing list