From 98a23982227dce29b015dcb5a867d05f2bee4388 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 15 Mar 2015 18:20:19 +0100 Subject: [PATCH] radeonsi: implement line and polygon smoothing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 35 +++++++++++++++---- src/gallium/drivers/radeonsi/si_state.h | 2 ++ .../drivers/radeonsi/si_state_shaders.c | 21 ++++++++--- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 1bc664a50ec..7c37a3e6fc9 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -186,6 +186,7 @@ struct si_context { struct r600_atom msaa_sample_locs; struct r600_atom msaa_config; int ps_iter_samples; + bool smoothing_enabled; /* Vertex and index buffers. */ bool vertex_buffers_dirty; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index f844fc19201..c7633dcfa39 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -617,6 +617,8 @@ static void *si_create_rs_state(struct pipe_context *ctx, rs->clip_plane_enable = state->clip_plane_enable; rs->line_stipple_enable = state->line_stipple_enable; rs->poly_stipple_enable = state->poly_stipple_enable; + rs->line_smooth = state->line_smooth; + rs->poly_smooth = state->poly_smooth; polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL || state->fill_back != PIPE_POLYGON_MODE_FILL); @@ -686,7 +688,9 @@ static void *si_create_rs_state(struct pipe_context *ctx, si_pm4_set_reg(pm4, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp)); si_pm4_set_reg(pm4, R_028A48_PA_SC_MODE_CNTL_0, S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable) | - S_028A48_MSAA_ENABLE(state->multisample) | + S_028A48_MSAA_ENABLE(state->multisample || + state->poly_smooth || + state->line_smooth) | S_028A48_VPORT_SCISSOR_ENABLE(state->scissor)); si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL, @@ -945,10 +949,15 @@ static void si_emit_db_render_state(struct si_context *sctx, struct r600_atom *s r600_write_context_reg(cs, R_028010_DB_RENDER_OVERRIDE2, 0); } - db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z) | - S_02880C_ALPHA_TO_MASK_DISABLE(sctx->framebuffer.cb0_is_integer) | + db_shader_control = S_02880C_ALPHA_TO_MASK_DISABLE(sctx->framebuffer.cb0_is_integer) | sctx->ps_db_shader_control; + /* Bug workaround for smoothing (overrasterization) on SI. */ + if (sctx->b.chip_class == SI && sctx->smoothing_enabled) + db_shader_control |= S_02880C_Z_ORDER(V_02880C_LATE_Z); + else + db_shader_control |= S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); + /* Disable the gl_SampleMask fragment shader output if MSAA is disabled. */ if (sctx->framebuffer.nr_samples <= 1 || (rs && !rs->multisample_enable)) db_shader_control &= C_02880C_MASK_EXPORT_ENABLE; @@ -2094,7 +2103,18 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, ctx->set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, SI_DRIVER_STATE_CONST_BUF, &constbuf); - sctx->msaa_sample_locs.dirty = true; + /* Smoothing (only possible with nr_samples == 1) uses the same + * sample locations as the MSAA it simulates. + * + * Therefore, don't update the sample locations when + * transitioning from no AA to smoothing-equivalent AA, and + * vice versa. + */ + if ((sctx->framebuffer.nr_samples != 1 || + old_nr_samples != SI_NUM_SMOOTH_AA_SAMPLES) && + (sctx->framebuffer.nr_samples != SI_NUM_SMOOTH_AA_SAMPLES || + old_nr_samples != 1)) + sctx->msaa_sample_locs.dirty = true; } } @@ -2205,8 +2225,10 @@ static void si_emit_msaa_sample_locs(struct r600_common_context *rctx, { struct si_context *sctx = (struct si_context *)rctx; struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs; + unsigned nr_samples = sctx->framebuffer.nr_samples; - cayman_emit_msaa_sample_locs(cs, sctx->framebuffer.nr_samples); + cayman_emit_msaa_sample_locs(cs, nr_samples > 1 ? nr_samples : + SI_NUM_SMOOTH_AA_SAMPLES); } const struct r600_atom si_atom_msaa_sample_locs = { si_emit_msaa_sample_locs, 18 }; /* number of CS dwords */ @@ -2217,7 +2239,8 @@ static void si_emit_msaa_config(struct r600_common_context *rctx, struct r600_at struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs; cayman_emit_msaa_config(cs, sctx->framebuffer.nr_samples, - sctx->ps_iter_samples, 0); + sctx->ps_iter_samples, + sctx->smoothing_enabled ? SI_NUM_SMOOTH_AA_SAMPLES : 0); } const struct r600_atom si_atom_msaa_config = { si_emit_msaa_config, 10 }; /* number of CS dwords */ diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 4e6b1e27c46..27dd2c30d96 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -68,6 +68,8 @@ struct si_state_rasterizer { float offset_units; float offset_scale; bool poly_stipple_enable; + bool line_smooth; + bool poly_smooth; }; struct si_state_dsa { diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 8c3bdc5fda5..382738a2121 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -373,6 +373,11 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx, key->ps.export_16bpc = sctx->framebuffer.export_16bpc; if (rs) { + bool is_poly = (sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES && + sctx->current_rast_prim <= PIPE_PRIM_POLYGON) || + sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES_ADJACENCY; + bool is_line = !is_poly && sctx->current_rast_prim != PIPE_PRIM_POINTS; + key->ps.color_two_side = rs->two_side; if (sctx->queued.named.blend) { @@ -381,10 +386,10 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx, !sctx->framebuffer.cb0_is_integer; } - key->ps.poly_stipple = rs->poly_stipple_enable && - ((sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES && - sctx->current_rast_prim <= PIPE_PRIM_POLYGON) || - sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES_ADJACENCY); + key->ps.poly_stipple = rs->poly_stipple_enable && is_poly; + key->ps.poly_line_smoothing = ((is_poly && rs->poly_smooth) || + (is_line && rs->line_smooth)) && + sctx->framebuffer.nr_samples <= 1; } key->ps.alpha_func = PIPE_FUNC_ALWAYS; @@ -921,6 +926,14 @@ void si_update_shaders(struct si_context *sctx) sctx->ps_db_shader_control = sctx->ps_shader->current->db_shader_control; sctx->db_render_state.dirty = true; } + + if (sctx->smoothing_enabled != sctx->ps_shader->current->key.ps.poly_line_smoothing) { + sctx->smoothing_enabled = sctx->ps_shader->current->key.ps.poly_line_smoothing; + sctx->msaa_config.dirty = true; + + if (sctx->b.chip_class == SI) + sctx->db_render_state.dirty = true; + } } void si_init_shader_functions(struct si_context *sctx) -- 2.30.2