radeonsi: update dirty_level_mask only after the first draw after FB change

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
Marek Olšák 2017-01-24 03:25:40 +01:00
parent cecc068774
commit 879c73fac8
3 changed files with 31 additions and 24 deletions

View file

@ -177,6 +177,7 @@ struct si_framebuffer {
unsigned dirty_cbufs;
bool dirty_zsbuf;
bool any_dst_linear;
bool do_update_surf_dirtiness;
};
struct si_clip_state {

View file

@ -2487,6 +2487,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
sctx->need_check_render_feedback = true;
sctx->do_update_shaders = true;
sctx->framebuffer.do_update_surf_dirtiness = true;
}
static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom *atom)
@ -3533,6 +3534,7 @@ static void si_texture_barrier(struct pipe_context *ctx, unsigned flags)
sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 |
SI_CONTEXT_INV_GLOBAL_L2 |
SI_CONTEXT_FLUSH_AND_INV_CB;
sctx->framebuffer.do_update_surf_dirtiness = true;
}
/* This only ensures coherency for shader image/buffer stores. */

View file

@ -992,6 +992,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
sctx->framebuffer.dirty_cbufs |=
((1 << sctx->framebuffer.state.nr_cbufs) - 1);
sctx->framebuffer.dirty_zsbuf = true;
sctx->framebuffer.do_update_surf_dirtiness = true;
si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
}
@ -1188,32 +1189,35 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
sctx->b.flags |= SI_CONTEXT_VGT_STREAMOUT_SYNC;
}
/* Set the depth buffer as dirty. */
if (sctx->framebuffer.state.zsbuf) {
struct pipe_surface *surf = sctx->framebuffer.state.zsbuf;
struct r600_texture *rtex = (struct r600_texture *)surf->texture;
if (sctx->framebuffer.do_update_surf_dirtiness) {
/* Set the depth buffer as dirty. */
if (sctx->framebuffer.state.zsbuf) {
struct pipe_surface *surf = sctx->framebuffer.state.zsbuf;
struct r600_texture *rtex = (struct r600_texture *)surf->texture;
if (!rtex->tc_compatible_htile)
rtex->dirty_level_mask |= 1 << surf->u.tex.level;
if (rtex->surface.flags & RADEON_SURF_SBUFFER)
rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
}
if (sctx->framebuffer.compressed_cb_mask) {
struct pipe_surface *surf;
struct r600_texture *rtex;
unsigned mask = sctx->framebuffer.compressed_cb_mask;
do {
unsigned i = u_bit_scan(&mask);
surf = sctx->framebuffer.state.cbufs[i];
rtex = (struct r600_texture*)surf->texture;
if (rtex->fmask.size)
if (!rtex->tc_compatible_htile)
rtex->dirty_level_mask |= 1 << surf->u.tex.level;
if (rtex->dcc_gather_statistics)
rtex->separate_dcc_dirty = true;
} while (mask);
if (rtex->surface.flags & RADEON_SURF_SBUFFER)
rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
}
if (sctx->framebuffer.compressed_cb_mask) {
struct pipe_surface *surf;
struct r600_texture *rtex;
unsigned mask = sctx->framebuffer.compressed_cb_mask;
do {
unsigned i = u_bit_scan(&mask);
surf = sctx->framebuffer.state.cbufs[i];
rtex = (struct r600_texture*)surf->texture;
if (rtex->fmask.size)
rtex->dirty_level_mask |= 1 << surf->u.tex.level;
if (rtex->dcc_gather_statistics)
rtex->separate_dcc_dirty = true;
} while (mask);
}
sctx->framebuffer.do_update_surf_dirtiness = false;
}
pipe_resource_reference(&ib.buffer, NULL);