From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 1 + src/gallium/drivers/radeonsi/si_state.h | 1 + src/gallium/drivers/radeonsi/si_state_shaders.c | 35 ++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 11e8ce4..c0497ea 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -208,6 +208,7 @@ struct si_context { struct si_vertex_element *vertex_elements; unsigned sprite_coord_enable; bool flatshade; + bool force_persample_interp; /* shader descriptors */ struct si_descriptors vertex_buffers; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index d74f6e8..5c293a2 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -686,6 +686,7 @@ static void *si_create_rs_state(struct pipe_context *ctx, rs->two_side = state->light_twoside; rs->multisample_enable = state->multisample; + rs->force_persample_interp = state->force_persample_interp; rs->clip_plane_enable = state->clip_plane_enable; rs->line_stipple_enable = state->line_stipple_enable; rs->poly_stipple_enable = state->poly_stipple_enable; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 2257499..6a56768 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -50,6 +50,7 @@ struct si_state_rasterizer { bool flatshade; bool two_side; bool multisample_enable; + bool force_persample_interp; bool line_stipple_enable; unsigned sprite_coord_enable; unsigned pa_sc_line_stipple; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index dd5fdc0..f7c258e 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1067,6 +1067,36 @@ static void si_emit_spi_ps_input(struct si_context *sctx, struct r600_atom *atom G_0286CC_LINEAR_CENTROID_ENA(input_ena) || G_0286CC_LINE_STIPPLE_TEX_ENA(input_ena)); + if (sctx->force_persample_interp) { + unsigned num_persp = G_0286CC_PERSP_SAMPLE_ENA(input_ena) + + G_0286CC_PERSP_CENTER_ENA(input_ena) + + G_0286CC_PERSP_CENTROID_ENA(input_ena); + unsigned num_linear = G_0286CC_LINEAR_SAMPLE_ENA(input_ena) + + G_0286CC_LINEAR_CENTER_ENA(input_ena) + + G_0286CC_LINEAR_CENTROID_ENA(input_ena); + + /* If only one set of (i,j) coordinates is used, we can disable + * CENTER/CENTROID, enable SAMPLE and it will load SAMPLE coordinates + * where CENTER/CENTROID are expected, effectively forcing per-sample + * interpolation. + */ + if (num_persp == 1) { + input_ena &= C_0286CC_PERSP_CENTER_ENA; + input_ena &= C_0286CC_PERSP_CENTROID_ENA; + input_ena |= G_0286CC_PERSP_SAMPLE_ENA(1); + } + if (num_linear == 1) { + input_ena &= C_0286CC_LINEAR_CENTER_ENA; + input_ena &= C_0286CC_LINEAR_CENTROID_ENA; + input_ena |= G_0286CC_LINEAR_SAMPLE_ENA(1); + } + + /* If at least 2 sets of coordinates are used, we can't use this + * trick and have to select SAMPLE using a conditional assignment + * in the shader with "force_persample_interp" being a shader constant. + */ + } + radeon_set_context_reg_seq(cs, R_0286CC_SPI_PS_INPUT_ENA, 2); radeon_emit(cs, input_ena); radeon_emit(cs, input_ena); @@ -1543,8 +1573,11 @@ bool si_update_shaders(struct si_context *sctx) si_mark_atom_dirty(sctx, &sctx->spi_map); } - if (si_pm4_state_changed(sctx, ps)) + if (si_pm4_state_changed(sctx, ps) || + sctx->force_persample_interp != rs->force_persample_interp) { + sctx->force_persample_interp = rs->force_persample_interp; si_mark_atom_dirty(sctx, &sctx->spi_ps_input); + } if (si_pm4_state_changed(sctx, ls) || si_pm4_state_changed(sctx, hs) || -- 2.1.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev