radeonsi: implement line and polygon smoothing

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Marek Olšák 2015-03-15 18:20:19 +01:00
parent 303d23e10d
commit 98a2398222
4 changed files with 49 additions and 10 deletions

View file

@ -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;

View file

@ -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 */

View file

@ -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 {

View file

@ -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)