From 2993ccab389d6887b5f1b55981b21d9070e8f4b8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 18 Aug 2013 02:34:23 +0200 Subject: [PATCH] radeonsi: bind streamout buffers to VGT and the vertex shader MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/radeonsi_pipe.h | 2 + .../drivers/radeonsi/radeonsi_shader.c | 1 + .../drivers/radeonsi/radeonsi_shader.h | 18 ++--- src/gallium/drivers/radeonsi/si_descriptors.c | 68 +++++++++++++++++++ 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h index c5059e82dbd..9306790bdd3 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h @@ -134,6 +134,7 @@ struct r600_context { /* The order matters. */ struct r600_atom *const_buffers[SI_NUM_SHADERS]; struct r600_atom *sampler_views[SI_NUM_SHADERS]; + struct r600_atom *streamout_buffers; /* Caches must be flushed after resource descriptors are * updated in memory. */ struct r600_atom *cache_flush; @@ -164,6 +165,7 @@ struct r600_context { unsigned sprite_coord_enable; unsigned export_16bpc; struct si_buffer_resources const_buffers[SI_NUM_SHADERS]; + struct si_buffer_resources streamout_buffers; struct r600_textures_info samplers[SI_NUM_SHADERS]; struct r600_resource *border_color_table; unsigned border_color_offset; diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c index 77915aefee7..335cd79b1a8 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.c +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c @@ -1364,6 +1364,7 @@ static void create_function(struct si_shader_context *si_shader_ctx) switch (si_shader_ctx->type) { case TGSI_PROCESSOR_VERTEX: params[SI_PARAM_VERTEX_BUFFER] = params[SI_PARAM_CONST]; + params[SI_PARAM_SO_BUFFER] = params[SI_PARAM_CONST]; params[SI_PARAM_START_INSTANCE] = i32; last_sgpr = SI_PARAM_START_INSTANCE; params[SI_PARAM_VERTEX_ID] = i32; diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h index ede8bde3dee..64766c97327 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.h +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h @@ -34,10 +34,11 @@ #define SI_SGPR_CONST 0 #define SI_SGPR_SAMPLER 2 #define SI_SGPR_RESOURCE 4 -#define SI_SGPR_VERTEX_BUFFER 6 -#define SI_SGPR_START_INSTANCE 8 +#define SI_SGPR_VERTEX_BUFFER 6 /* VS only */ +#define SI_SGPR_SO_BUFFER 8 /* VS only, stream-out */ +#define SI_SGPR_START_INSTANCE 10 /* VS only */ -#define SI_VS_NUM_USER_SGPR 9 +#define SI_VS_NUM_USER_SGPR 11 #define SI_PS_NUM_USER_SGPR 6 /* LLVM function parameter indices */ @@ -47,11 +48,12 @@ /* VS only parameters */ #define SI_PARAM_VERTEX_BUFFER 3 -#define SI_PARAM_START_INSTANCE 4 -#define SI_PARAM_VERTEX_ID 5 -#define SI_PARAM_DUMMY_0 6 -#define SI_PARAM_DUMMY_1 7 -#define SI_PARAM_INSTANCE_ID 8 +#define SI_PARAM_SO_BUFFER 4 +#define SI_PARAM_START_INSTANCE 5 +#define SI_PARAM_VERTEX_ID 6 +#define SI_PARAM_DUMMY_0 7 +#define SI_PARAM_DUMMY_1 8 +#define SI_PARAM_INSTANCE_ID 9 /* PS only parameters */ #define SI_PARAM_PRIM_MASK 3 diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 5d8544848bc..a8f87815a5b 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -456,6 +456,67 @@ static void si_set_constant_buffer(struct pipe_context *ctx, uint shader, uint s si_update_descriptors(rctx, &buffers->desc); } +/* STREAMOUT BUFFERS */ + +static void si_set_streamout_targets(struct pipe_context *ctx, + unsigned num_targets, + struct pipe_stream_output_target **targets, + unsigned append_bitmask) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + struct si_buffer_resources *buffers = &rctx->streamout_buffers; + unsigned old_num_targets = rctx->b.streamout.num_targets; + unsigned i; + + /* Streamout buffers must be bound in 2 places: + * 1) in VGT by setting the VGT_STRMOUT registers + * 2) as shader resources + */ + + /* Set the VGT regs. */ + r600_set_streamout_targets(ctx, num_targets, targets, append_bitmask); + + /* Set the shader resources.*/ + for (i = 0; i < num_targets; i++) { + if (targets[i]) { + struct pipe_resource *buffer = targets[i]->buffer; + uint64_t va = r600_resource_va(ctx->screen, buffer); + + /* Set the descriptor. */ + uint32_t *desc = buffers->desc_data[i]; + desc[0] = va; + desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32); + desc[2] = 0xffffffff; + desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | + S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) | + S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | + S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W); + + /* Set the resource. */ + pipe_resource_reference(&buffers->buffers[i], buffer); + r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, + (struct r600_resource*)buffer, + buffers->shader_usage); + buffers->desc.enabled_mask |= 1 << i; + } else { + /* Clear the descriptor and unset the resource. */ + memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4); + pipe_resource_reference(&buffers->buffers[i], NULL); + buffers->desc.enabled_mask &= ~(1 << i); + } + buffers->desc.dirty_mask |= 1 << i; + } + for (; i < old_num_targets; i++) { + /* Clear the descriptor and unset the resource. */ + memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4); + pipe_resource_reference(&buffers->buffers[i], NULL); + buffers->desc.enabled_mask &= ~(1 << i); + buffers->desc.dirty_mask |= 1 << i; + } + + si_update_descriptors(rctx, &buffers->desc); +} + /* INIT/DEINIT */ void si_init_all_descriptors(struct r600_context *rctx) @@ -473,8 +534,13 @@ void si_init_all_descriptors(struct r600_context *rctx) rctx->atoms.sampler_views[i] = &rctx->samplers[i].views.desc.atom; } + si_init_buffer_resources(rctx, &rctx->streamout_buffers, 4, PIPE_SHADER_VERTEX, + SI_SGPR_SO_BUFFER, RADEON_USAGE_WRITE); + rctx->atoms.streamout_buffers = &rctx->streamout_buffers.desc.atom; + /* Set pipe_context functions. */ rctx->b.b.set_constant_buffer = si_set_constant_buffer; + rctx->b.b.set_stream_output_targets = si_set_streamout_targets; } void si_release_all_descriptors(struct r600_context *rctx) @@ -485,6 +551,7 @@ void si_release_all_descriptors(struct r600_context *rctx) si_release_buffer_resources(&rctx->const_buffers[i]); si_release_sampler_views(&rctx->samplers[i].views); } + si_release_buffer_resources(&rctx->streamout_buffers); } void si_all_descriptors_begin_new_cs(struct r600_context *rctx) @@ -495,4 +562,5 @@ void si_all_descriptors_begin_new_cs(struct r600_context *rctx) si_buffer_resources_begin_new_cs(rctx, &rctx->const_buffers[i]); si_sampler_views_begin_new_cs(rctx, &rctx->samplers[i].views); } + si_buffer_resources_begin_new_cs(rctx, &rctx->streamout_buffers); } -- 2.30.2