From a327fa3a068af49bb7ae00a4b03abcb91906e0d2 Mon Sep 17 00:00:00 2001 From: Glenn Kennard Date: Wed, 10 Sep 2014 11:54:40 +0200 Subject: r600g: Implement GL_ARB_sample_shading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fixes two sided lighting which was broken at least on pre-evergreen by commit b1eb00. Signed-off-by: Glenn Kennard Signed-off-by: Marek Olšák --- src/gallium/drivers/r600/r600_state.c | 60 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/r600/r600_state.c') 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; -- cgit v1.2.3