From: Marek Olšák Date: Sun, 22 Feb 2015 16:25:37 +0000 (+0100) Subject: radeonsi: set up a ring buffer for tessellation factors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b6f4fdf6a9238bdb9e0589eafb22396da347b792;p=mesa.git radeonsi: set up a ring buffer for tessellation factors Reviewed-by: Michel Dänzer --- diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 25dc4e7a96d..8678fe6260b 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -42,6 +42,7 @@ static void si_destroy_context(struct pipe_context *context) pipe_resource_reference(&sctx->esgs_ring, NULL); pipe_resource_reference(&sctx->gsvs_ring, NULL); + pipe_resource_reference(&sctx->tf_ring, NULL); pipe_resource_reference(&sctx->null_const_buf.buffer, NULL); r600_resource_reference(&sctx->border_color_table, NULL); r600_resource_reference(&sctx->scratch_buffer, NULL); @@ -49,6 +50,7 @@ static void si_destroy_context(struct pipe_context *context) si_pm4_free_state(sctx, sctx->init_config, ~0); si_pm4_delete_state(sctx, gs_rings, sctx->gs_rings); + si_pm4_delete_state(sctx, tf_ring, sctx->tf_state); for (i = 0; i < Elements(sctx->vgt_shader_config); i++) si_pm4_delete_state(sctx, vgt_shader_config, sctx->vgt_shader_config[i]); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 880f7beaa19..9e2ad188801 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -204,6 +204,8 @@ struct si_context { struct si_pm4_state *gs_rings; struct pipe_resource *esgs_ring; struct pipe_resource *gsvs_ring; + struct si_pm4_state *tf_state; + struct pipe_resource *tf_ring; LLVMTargetMachineRef tm; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index b17f2f09012..25220534eb4 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -107,6 +107,7 @@ union si_state { struct si_pm4_state *es; struct si_pm4_state *gs; struct si_pm4_state *gs_rings; + struct si_pm4_state *tf_ring; struct si_pm4_state *vgt_shader_config; struct si_pm4_state *vs; struct si_pm4_state *ps; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 937e71de723..686718e4221 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1115,6 +1115,40 @@ static void si_update_spi_tmpring_size(struct si_context *sctx) S_0286E8_WAVESIZE(scratch_bytes_per_wave >> 10); } +static void si_init_tess_factor_ring(struct si_context *sctx) +{ + assert(!sctx->tf_state); + sctx->tf_state = CALLOC_STRUCT(si_pm4_state); + + sctx->tf_ring = pipe_buffer_create(sctx->b.b.screen, PIPE_BIND_CUSTOM, + PIPE_USAGE_DEFAULT, + 32768 * sctx->screen->b.info.max_se); + sctx->b.clear_buffer(&sctx->b.b, sctx->tf_ring, 0, + sctx->tf_ring->width0, fui(0), false); + assert(((sctx->tf_ring->width0 / 4) & C_030938_SIZE) == 0); + + if (sctx->b.chip_class >= CIK) { + si_pm4_set_reg(sctx->tf_state, R_030938_VGT_TF_RING_SIZE, + S_030938_SIZE(sctx->tf_ring->width0 / 4)); + si_pm4_set_reg(sctx->tf_state, R_030940_VGT_TF_MEMORY_BASE, + r600_resource(sctx->tf_ring)->gpu_address >> 8); + } else { + si_pm4_set_reg(sctx->tf_state, R_008988_VGT_TF_RING_SIZE, + S_008988_SIZE(sctx->tf_ring->width0 / 4)); + si_pm4_set_reg(sctx->tf_state, R_0089B8_VGT_TF_MEMORY_BASE, + r600_resource(sctx->tf_ring)->gpu_address >> 8); + } + si_pm4_add_bo(sctx->tf_state, r600_resource(sctx->tf_ring), + RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_RESOURCE_RW); + si_pm4_bind_state(sctx, tf_ring, sctx->tf_state); + + si_set_ring_buffer(&sctx->b.b, PIPE_SHADER_TESS_CTRL, + SI_RING_TESS_FACTOR, sctx->tf_ring, 0, + sctx->tf_ring->width0, false, false, 0, 0); + + sctx->b.flags |= SI_CONTEXT_VGT_FLUSH; +} + static void si_update_vgt_shader_config(struct si_context *sctx) { /* Calculate the index of the config. @@ -1157,6 +1191,9 @@ void si_update_shaders(struct si_context *sctx) /* Update stages before GS. */ if (sctx->tes_shader) { + if (!sctx->tf_state) + si_init_tess_factor_ring(sctx); + /* VS as LS */ si_shader_select(ctx, sctx->vs_shader); si_pm4_bind_state(sctx, ls, sctx->vs_shader->current->pm4);