From 59b3556f4c69f0e6e5430ca6ab384d2ac9372bfc Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 19 Sep 2014 00:16:12 +0200 Subject: radeonsi: program VGT_SHADER_STAGES_EN for tessellation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/si_pipe.c | 5 ++- src/gallium/drivers/radeonsi/si_pipe.h | 7 ++-- src/gallium/drivers/radeonsi/si_state.h | 2 +- src/gallium/drivers/radeonsi/si_state_shaders.c | 54 +++++++++++++++++-------- 4 files changed, 45 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 0878b8887c9..25dc4e7a96d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -36,6 +36,7 @@ static void si_destroy_context(struct pipe_context *context) { struct si_context *sctx = (struct si_context *)context; + int i; si_release_all_descriptors(sctx); @@ -48,8 +49,8 @@ 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, gs_onoff, sctx->gs_on); - si_pm4_delete_state(sctx, gs_onoff, sctx->gs_off); + for (i = 0; i < Elements(sctx->vgt_shader_config); i++) + si_pm4_delete_state(sctx, vgt_shader_config, sctx->vgt_shader_config[i]); if (sctx->pstipple_sampler_state) sctx->b.b.delete_sampler_state(&sctx->b.b, sctx->pstipple_sampler_state); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 2eaff1cd24d..880f7beaa19 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -196,11 +196,12 @@ struct si_context { /* With rasterizer discard, there doesn't have to be a pixel shader. * In that case, we bind this one: */ void *dummy_pixel_shader; - struct si_pm4_state *gs_on; - struct si_pm4_state *gs_off; - struct si_pm4_state *gs_rings; struct r600_atom cache_flush; struct pipe_constant_buffer null_const_buf; /* used for set_constant_buffer(NULL) on CIK */ + + /* VGT states. */ + struct si_pm4_state *vgt_shader_config[4]; + struct si_pm4_state *gs_rings; struct pipe_resource *esgs_ring; struct pipe_resource *gsvs_ring; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index edee6d41328..6174dad7190 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -105,7 +105,7 @@ union si_state { struct si_pm4_state *es; struct si_pm4_state *gs; struct si_pm4_state *gs_rings; - struct si_pm4_state *gs_onoff; + struct si_pm4_state *vgt_shader_config; struct si_pm4_state *vs; struct si_pm4_state *ps; struct si_pm4_state *spi; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 88edc908f72..3eec217fbd2 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -922,6 +922,41 @@ static void si_update_spi_tmpring_size(struct si_context *sctx) S_0286E8_WAVESIZE(scratch_bytes_per_wave >> 10); } +static void si_update_vgt_shader_config(struct si_context *sctx) +{ + /* Calculate the index of the config. + * 0 = VS, 1 = VS+GS, 2 = VS+Tess, 3 = VS+Tess+GS */ + unsigned index = 2*!!sctx->tes_shader + !!sctx->gs_shader; + struct si_pm4_state **pm4 = &sctx->vgt_shader_config[index]; + + if (!*pm4) { + uint32_t stages = 0; + + *pm4 = CALLOC_STRUCT(si_pm4_state); + + if (sctx->tes_shader) { + stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) | + S_028B54_HS_EN(1); + + if (sctx->gs_shader) + stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS) | + S_028B54_GS_EN(1) | + S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER); + else + stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_DS); + } else if (sctx->gs_shader) { + stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) | + S_028B54_GS_EN(1) | + S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER); + } + + si_pm4_set_reg(*pm4, R_028B54_VGT_SHADER_STAGES_EN, stages); + if (!sctx->gs_shader) + si_pm4_set_reg(*pm4, R_028A40_VGT_GS_MODE, 0); + } + si_pm4_bind_state(sctx, vgt_shader_config, *pm4); +} + void si_update_shaders(struct si_context *sctx) { struct pipe_context *ctx = (struct pipe_context*)sctx; @@ -948,34 +983,19 @@ void si_update_shaders(struct si_context *sctx) sctx->gs_shader->gs_max_out_vertices * sctx->gs_shader->info.num_outputs * 16, 64, true, true, 4, 16); - - if (!sctx->gs_on) { - sctx->gs_on = CALLOC_STRUCT(si_pm4_state); - - si_pm4_set_reg(sctx->gs_on, R_028B54_VGT_SHADER_STAGES_EN, - S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) | - S_028B54_GS_EN(1) | - S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER)); - } - si_pm4_bind_state(sctx, gs_onoff, sctx->gs_on); } else { si_shader_select(ctx, sctx->vs_shader); si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4); sctx->b.streamout.stride_in_dw = sctx->vs_shader->so.stride; - if (!sctx->gs_off) { - sctx->gs_off = CALLOC_STRUCT(si_pm4_state); - - si_pm4_set_reg(sctx->gs_off, R_028A40_VGT_GS_MODE, 0); - si_pm4_set_reg(sctx->gs_off, R_028B54_VGT_SHADER_STAGES_EN, 0); - } - si_pm4_bind_state(sctx, gs_onoff, sctx->gs_off); si_pm4_bind_state(sctx, gs_rings, NULL); si_pm4_bind_state(sctx, gs, NULL); si_pm4_bind_state(sctx, es, NULL); } + si_update_vgt_shader_config(sctx); + si_shader_select(ctx, sctx->ps_shader); if (!sctx->ps_shader->current) { -- cgit v1.2.3