summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-03-15 18:20:19 +0100
committerMarek Olšák <[email protected]>2015-03-16 12:54:19 +0100
commit98a23982227dce29b015dcb5a867d05f2bee4388 (patch)
tree67ae87b834acf442b734d6cf7aa2188dcda1cc95 /src
parent303d23e10d2caad69b2d122f45c78fee2906fc09 (diff)
radeonsi: implement line and polygon smoothing
Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c35
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h2
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c21
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)