[Mesa-dev] [PATCH 1/6] radeonsi: load streamout buffer descriptors before use

Marek Olšák maraeo at gmail.com
Tue Sep 13 17:13:38 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_shader.c | 67 ++++++++++++++++----------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index be6fae7..b9ad4be 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -105,21 +105,20 @@ struct si_shader_context
 	unsigned uniform_md_kind;
 	LLVMValueRef empty_md;
 
 	LLVMValueRef const_buffers[SI_NUM_CONST_BUFFERS];
 	LLVMValueRef lds;
 	LLVMValueRef shader_buffers[SI_NUM_SHADER_BUFFERS];
 	LLVMValueRef sampler_views[SI_NUM_SAMPLERS];
 	LLVMValueRef sampler_states[SI_NUM_SAMPLERS];
 	LLVMValueRef fmasks[SI_NUM_SAMPLERS];
 	LLVMValueRef images[SI_NUM_IMAGES];
-	LLVMValueRef so_buffers[4];
 	LLVMValueRef esgs_ring;
 	LLVMValueRef gsvs_ring[4];
 	LLVMValueRef gs_next_vertex[4];
 	LLVMValueRef return_value;
 
 	LLVMTypeRef voidt;
 	LLVMTypeRef i1;
 	LLVMTypeRef i8;
 	LLVMTypeRef i32;
 	LLVMTypeRef i64;
@@ -2253,31 +2252,64 @@ static void si_dump_streamout(struct pipe_stream_output_info *so)
 			i, so->output[i].output_buffer,
 			so->output[i].dst_offset, so->output[i].dst_offset + so->output[i].num_components - 1,
 			so->output[i].register_index,
 			mask & 1 ? "x" : "",
 		        mask & 2 ? "y" : "",
 		        mask & 4 ? "z" : "",
 		        mask & 8 ? "w" : "");
 	}
 }
 
+static void load_streamout_descriptors(struct si_shader_context *ctx,
+				       LLVMValueRef so_buffers[4])
+{
+	struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+	struct gallivm_state *gallivm = bld_base->base.gallivm;
+	unsigned i;
+
+	/* Streamout can only be used if the shader is compiled as VS. */
+	if (!ctx->shader->selector->so.num_outputs ||
+	    (ctx->type == PIPE_SHADER_VERTEX &&
+	     (ctx->shader->key.vs.as_es ||
+	      ctx->shader->key.vs.as_ls)) ||
+	    (ctx->type == PIPE_SHADER_TESS_EVAL &&
+	     ctx->shader->key.tes.as_es))
+		return;
+
+	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
+					    SI_PARAM_RW_BUFFERS);
+
+	/* Load the resources, we rely on the code sinking to do the rest */
+	for (i = 0; i < 4; ++i) {
+		if (ctx->shader->selector->so.stride[i]) {
+			LLVMValueRef offset = lp_build_const_int32(gallivm,
+								   SI_VS_STREAMOUT_BUF0 + i);
+
+			so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
+		}
+	}
+}
+
 /* On SI, the vertex shader is responsible for writing streamout data
  * to buffers. */
 static void si_llvm_emit_streamout(struct si_shader_context *ctx,
 				   struct si_shader_output_values *outputs,
 				   unsigned noutput)
 {
 	struct pipe_stream_output_info *so = &ctx->shader->selector->so;
 	struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
 	LLVMBuilderRef builder = gallivm->builder;
 	int i, j;
 	struct lp_build_if_state if_ctx;
+	LLVMValueRef so_buffers[4];
+
+	load_streamout_descriptors(ctx, so_buffers);
 
 	/* Get bits [22:16], i.e. (so_param >> 16) & 127; */
 	LLVMValueRef so_vtx_count =
 		unpack_param(ctx, ctx->param_streamout_config, 16, 7);
 
 	LLVMValueRef tid = get_thread_id(ctx);
 
 	/* can_emit = tid < so_vtx_count; */
 	LLVMValueRef can_emit =
 		LLVMBuildICmp(builder, LLVMIntULT, tid, so_vtx_count, "");
@@ -2359,21 +2391,21 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
 				}
 				break;
 			}
 
 			LLVMValueRef can_emit_stream =
 				LLVMBuildICmp(builder, LLVMIntEQ,
 					      stream_id,
 					      lp_build_const_int32(gallivm, stream), "");
 
 			lp_build_if(&if_ctx_stream, gallivm, can_emit_stream);
-			build_tbuffer_store_dwords(ctx, ctx->so_buffers[buf_idx],
+			build_tbuffer_store_dwords(ctx, so_buffers[buf_idx],
 						   vdata, num_comps,
 						   so_write_offset[buf_idx],
 						   LLVMConstInt(ctx->i32, 0, 0),
 						   so->output[i].dst_offset*4);
 			lp_build_endif(&if_ctx_stream);
 		}
 	}
 	lp_build_endif(&if_ctx);
 }
 
@@ -5917,49 +5949,20 @@ static void preload_images(struct si_shader_context *ctx)
 						 lp_build_const_int32(gallivm, i));
 
 		if (info->images_writemask & (1 << i) &&
 		    !(info->images_buffers & (1 << i)))
 			rsrc = force_dcc_off(ctx, rsrc);
 
 		ctx->images[i] = rsrc;
 	}
 }
 
-static void preload_streamout_buffers(struct si_shader_context *ctx)
-{
-	struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
-	struct gallivm_state *gallivm = bld_base->base.gallivm;
-	unsigned i;
-
-	/* Streamout can only be used if the shader is compiled as VS. */
-	if (!ctx->shader->selector->so.num_outputs ||
-	    (ctx->type == PIPE_SHADER_VERTEX &&
-	     (ctx->shader->key.vs.as_es ||
-	      ctx->shader->key.vs.as_ls)) ||
-	    (ctx->type == PIPE_SHADER_TESS_EVAL &&
-	     ctx->shader->key.tes.as_es))
-		return;
-
-	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
-					    SI_PARAM_RW_BUFFERS);
-
-	/* Load the resources, we rely on the code sinking to do the rest */
-	for (i = 0; i < 4; ++i) {
-		if (ctx->shader->selector->so.stride[i]) {
-			LLVMValueRef offset = lp_build_const_int32(gallivm,
-								   SI_VS_STREAMOUT_BUF0 + i);
-
-			ctx->so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
-		}
-	}
-}
-
 /**
  * Load ESGS and GSVS ring buffer resource descriptors and save the variables
  * for later use.
  */
 static void preload_ring_buffers(struct si_shader_context *ctx)
 {
 	struct gallivm_state *gallivm =
 		ctx->radeon_bld.soa.bld_base.base.gallivm;
 
 	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
@@ -6490,21 +6493,20 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen,
 	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;
 
 	create_meta_data(ctx);
 	create_function(ctx);
-	preload_streamout_buffers(ctx);
 	preload_ring_buffers(ctx);
 
 	args[0] = ctx->gsvs_ring[0];
 	args[1] = lp_build_mul_imm(uint,
 				   LLVMGetParam(ctx->radeon_bld.main_fn,
 						ctx->param_vertex_id),
 				   4);
 	args[3] = uint->zero;
 	args[4] = uint->one;  /* OFFEN */
 	args[5] = uint->zero; /* IDXEN */
@@ -6792,21 +6794,20 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 		assert(!"Unsupported shader type");
 		return -1;
 	}
 
 	create_meta_data(&ctx);
 	create_function(&ctx);
 	preload_constants(&ctx);
 	preload_shader_buffers(&ctx);
 	preload_samplers(&ctx);
 	preload_images(&ctx);
-	preload_streamout_buffers(&ctx);
 	preload_ring_buffers(&ctx);
 
 	if (ctx.is_monolithic && sel->type == PIPE_SHADER_FRAGMENT &&
 	    shader->key.ps.prolog.poly_stipple) {
 		LLVMValueRef list = LLVMGetParam(ctx.radeon_bld.main_fn,
 						 SI_PARAM_RW_BUFFERS);
 		si_llvm_emit_polygon_stipple(&ctx, list,
 					     SI_PARAM_POS_FIXED_PT);
 	}
 
-- 
2.7.4



More information about the mesa-dev mailing list