summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_state.c
diff options
context:
space:
mode:
authorGlenn Kennard <[email protected]>2014-09-10 11:54:40 +0200
committerMarek Olšák <[email protected]>2014-10-12 23:53:57 +0200
commita327fa3a068af49bb7ae00a4b03abcb91906e0d2 (patch)
tree73099704bc1d26aab47982aaa80165e20028634d /src/gallium/drivers/r600/r600_state.c
parent75e97e2e3f317c79124116f596bdf0fde9f70ef8 (diff)
r600g: Implement GL_ARB_sample_shading
Also fixes two sided lighting which was broken at least on pre-evergreen by commit b1eb00. Signed-off-by: Glenn Kennard <[email protected]> Signed-off-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_state.c')
-rw-r--r--src/gallium/drivers/r600/r600_state.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 9ca61718aba..1f933efca9e 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -486,7 +486,12 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
sc_mode_cntl = S_028A4C_MSAA_ENABLE(state->multisample) |
S_028A4C_LINE_STIPPLE_ENABLE(state->line_stipple_enable) |
- S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1);
+ S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
+ S_028A4C_PS_ITER_SAMPLE(state->multisample && rctx->ps_iter_samples > 1);
+ if (rctx->b.family == CHIP_RV770) {
+ /* workaround possible rendering corruption on RV770 with hyperz together with sample shading */
+ sc_mode_cntl |= S_028A4C_TILE_COVER_DISABLE(state->multisample && rctx->ps_iter_samples > 1);
+ }
if (rctx->b.chip_class >= R700) {
sc_mode_cntl |= S_028A4C_FORCE_EOV_REZ_ENABLE(1) |
S_028A4C_R700_ZMM_LINE_OFFSET(1) |
@@ -1245,6 +1250,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
}
rctx->framebuffer.atom.dirty = true;
+
+ r600_set_sample_locations_constant_buffer(rctx);
}
static uint32_t sample_locs_2x[] = {
@@ -1524,6 +1531,21 @@ static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_a
r600_emit_msaa_state(rctx, rctx->framebuffer.nr_samples);
}
+static void r600_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+
+ if (rctx->ps_iter_samples == min_samples)
+ return;
+
+ rctx->ps_iter_samples = min_samples;
+ if (rctx->framebuffer.nr_samples > 1) {
+ rctx->rasterizer_state.atom.dirty = true;
+ if (rctx->b.chip_class == R600)
+ rctx->db_misc_state.atom.dirty = true;
+ }
+}
+
static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
{
struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
@@ -1603,6 +1625,10 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
} else {
db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE);
}
+ if (rctx->b.chip_class == R600 && rctx->framebuffer.nr_samples > 1 && rctx->ps_iter_samples > 0) {
+ /* sample shading and hyperz causes lockups on R6xx chips */
+ db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE);
+ }
if (a->flush_depthstencil_through_cb) {
assert(a->copy_depth || a->copy_stencil);
@@ -2418,10 +2444,10 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
struct r600_command_buffer *cb = &shader->command_buffer;
struct r600_shader *rshader = &shader->shader;
unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control;
- int pos_index = -1, face_index = -1;
+ int pos_index = -1, face_index = -1, fixed_pt_position_index = -1;
unsigned tmp, sid, ufi = 0;
int need_linear = 0;
- unsigned z_export = 0, stencil_export = 0;
+ unsigned z_export = 0, stencil_export = 0, mask_export = 0;
unsigned sprite_coord_enable = rctx->rasterizer ? rctx->rasterizer->sprite_coord_enable : 0;
if (!cb->buf) {
@@ -2434,8 +2460,10 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
for (i = 0; i < rshader->ninput; i++) {
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
pos_index = i;
- if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
+ if (rshader->input[i].name == TGSI_SEMANTIC_FACE && face_index == -1)
face_index = i;
+ if (rshader->input[i].name == TGSI_SEMANTIC_SAMPLEID)
+ fixed_pt_position_index = i;
sid = rshader->input[i].spi_sid;
@@ -2452,9 +2480,12 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
tmp |= S_028644_PT_SPRITE_TEX(1);
}
- if (rshader->input[i].centroid)
+ if (rshader->input[i].interpolate_location == TGSI_INTERPOLATE_LOC_CENTROID)
tmp |= S_028644_SEL_CENTROID(1);
+ if (rshader->input[i].interpolate_location == TGSI_INTERPOLATE_LOC_SAMPLE)
+ tmp |= S_028644_SEL_SAMPLE(1);
+
if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) {
need_linear = 1;
tmp |= S_028644_SEL_LINEAR(1);
@@ -2469,16 +2500,21 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
z_export = 1;
if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
stencil_export = 1;
+ if (rshader->output[i].name == TGSI_SEMANTIC_SAMPLEMASK &&
+ rctx->framebuffer.nr_samples > 1 && rctx->ps_iter_samples > 0)
+ mask_export = 1;
}
db_shader_control |= S_02880C_Z_EXPORT_ENABLE(z_export);
db_shader_control |= S_02880C_STENCIL_REF_EXPORT_ENABLE(stencil_export);
+ db_shader_control |= S_02880C_MASK_EXPORT_ENABLE(mask_export);
if (rshader->uses_kill)
db_shader_control |= S_02880C_KILL_ENABLE(1);
exports_ps = 0;
for (i = 0; i < rshader->noutput; i++) {
if (rshader->output[i].name == TGSI_SEMANTIC_POSITION ||
- rshader->output[i].name == TGSI_SEMANTIC_STENCIL) {
+ rshader->output[i].name == TGSI_SEMANTIC_STENCIL ||
+ rshader->output[i].name == TGSI_SEMANTIC_SAMPLEMASK) {
exports_ps |= 1;
}
}
@@ -2497,9 +2533,10 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
spi_input_z = 0;
if (pos_index != -1) {
spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) |
- S_0286CC_POSITION_CENTROID(rshader->input[pos_index].centroid) |
+ S_0286CC_POSITION_CENTROID(rshader->input[pos_index].interpolate_location == TGSI_INTERPOLATE_LOC_CENTROID) |
S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) |
- S_0286CC_BARYC_SAMPLE_CNTL(1));
+ S_0286CC_BARYC_SAMPLE_CNTL(1)) |
+ S_0286CC_POSITION_SAMPLE(rshader->input[pos_index].interpolate_location == TGSI_INTERPOLATE_LOC_SAMPLE);
spi_input_z |= S_0286D8_PROVIDE_Z_TO_SPI(1);
}
@@ -2508,6 +2545,10 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) |
S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr);
}
+ if (fixed_pt_position_index != -1) {
+ spi_ps_in_control_1 |= S_0286D0_FIXED_PT_POSITION_ENA(1) |
+ S_0286D0_FIXED_PT_POSITION_ADDR(rshader->input[fixed_pt_position_index].gpr);
+ }
/* HW bug in original R600 */
if (rctx->b.family == CHIP_R600)
@@ -2531,7 +2572,7 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
/* only set some bits here, the other bits are set in the dsa state */
shader->db_shader_control = db_shader_control;
- shader->ps_depth_export = z_export | stencil_export;
+ shader->ps_depth_export = z_export | stencil_export | mask_export;
shader->sprite_coord_enable = sprite_coord_enable;
if (rctx->rasterizer)
@@ -3046,6 +3087,7 @@ void r600_init_state_functions(struct r600_context *rctx)
rctx->b.b.create_sampler_view = r600_create_sampler_view;
rctx->b.b.set_framebuffer_state = r600_set_framebuffer_state;
rctx->b.b.set_polygon_stipple = r600_set_polygon_stipple;
+ rctx->b.b.set_min_samples = r600_set_min_samples;
rctx->b.b.set_scissor_states = r600_set_scissor_states;
rctx->b.b.get_sample_position = r600_get_sample_position;
rctx->b.dma_copy = r600_dma_copy;