[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