[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