From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeonsi/si_clear.c | 32 ++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index 8ecd47fea9b..0f3546b02da 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -58,21 +58,21 @@ static void si_alloc_separate_cmask(struct si_screen *sscreen, } /* update colorbuffer state bits */ rtex->cmask.base_address_reg = rtex->cmask_buffer->gpu_address >> 8; rtex->cb_color_info |= S_028C70_FAST_CLEAR(1); p_atomic_inc(&sscreen->compressed_colortex_counter); } -static void si_set_clear_color(struct r600_texture *rtex, +static bool si_set_clear_color(struct r600_texture *rtex, enum pipe_format surface_format, const union pipe_color_union *color) { union util_color uc; memset(&uc, 0, sizeof(uc)); if (rtex->surface.bpe == 16) { /* DCC fast clear only: * CLEAR_WORD0 = R = G = B @@ -83,21 +83,25 @@ static void si_set_clear_color(struct r600_texture *rtex, uc.ui[0] = color->ui[0]; uc.ui[1] = color->ui[3]; } else if (util_format_is_pure_uint(surface_format)) { util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1); } else if (util_format_is_pure_sint(surface_format)) { util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1); } else { util_pack_color(color->f, surface_format, &uc); } + if (memcmp(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t)) == 0) + return false; + memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t)); + return true; } /** Linearize and convert luminace/intensity to red. */ enum pipe_format si_simplify_cb_format(enum pipe_format format) { format = util_format_linear(format); format = util_format_luminance_to_red(format); return util_format_intensity_to_red(format); } @@ -538,24 +542,24 @@ static void si_do_fast_color_clear(struct si_context *sctx, if (need_decompress_pass && !(tex->dirty_level_mask & (1 << level))) { tex->dirty_level_mask |= 1 << level; p_atomic_inc(&sctx->screen->compressed_colortex_counter); } /* We can change the micro tile mode before a full clear. */ si_set_optimal_micro_tile_mode(sctx->screen, tex); - si_set_clear_color(tex, fb->cbufs[i]->format, color); - - sctx->framebuffer.dirty_cbufs |= 1 << i; - si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); + if (si_set_clear_color(tex, fb->cbufs[i]->format, color)) { + sctx->framebuffer.dirty_cbufs |= 1 << i; + si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); + } *buffers &= ~clear_bit; } } static void si_clear(struct pipe_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { struct si_context *sctx = (struct si_context *)ctx; struct pipe_framebuffer_state *fb = &sctx->framebuffer.state; @@ -589,41 +593,47 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers, /* TC-compatible HTILE only supports depth clears to 0 or 1. */ if (buffers & PIPE_CLEAR_DEPTH && (!zstex->tc_compatible_htile || depth == 0 || depth == 1)) { /* Need to disable EXPCLEAR temporarily if clearing * to a new value. */ if (!zstex->depth_cleared || zstex->depth_clear_value != depth) { sctx->db_depth_disable_expclear = true; } - zstex->depth_clear_value = depth; - sctx->framebuffer.dirty_zsbuf = true; - si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); /* updates DB_DEPTH_CLEAR */ + if (zstex->depth_clear_value != (float)depth) { + /* Update DB_DEPTH_CLEAR. */ + zstex->depth_clear_value = depth; + sctx->framebuffer.dirty_zsbuf = true; + si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); + } sctx->db_depth_clear = true; si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state); } /* TC-compatible HTILE only supports stencil clears to 0. */ if (buffers & PIPE_CLEAR_STENCIL && (!zstex->tc_compatible_htile || stencil == 0)) { stencil &= 0xff; /* Need to disable EXPCLEAR temporarily if clearing * to a new value. */ if (!zstex->stencil_cleared || zstex->stencil_clear_value != stencil) { sctx->db_stencil_disable_expclear = true; } - zstex->stencil_clear_value = stencil; - sctx->framebuffer.dirty_zsbuf = true; - si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); /* updates DB_STENCIL_CLEAR */ + if (zstex->stencil_clear_value != (uint8_t)stencil) { + /* Update DB_STENCIL_CLEAR. */ + zstex->stencil_clear_value = stencil; + sctx->framebuffer.dirty_zsbuf = true; + si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); + } sctx->db_stencil_clear = true; si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state); } /* TODO: Find out what's wrong here. Fast depth clear leads to * corruption in ARK: Survival Evolved, but that may just be * a coincidence and the root cause is elsewhere. * * The corruption can be fixed by putting the DB flush before * or after the depth clear. (surprisingly) -- 2.17.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev