r600g: update dirty_level_mask after the 1-st draw after FB change
authorConstantine Kharlamov <Hi-Angel@yandex.ru>
Thu, 13 Apr 2017 20:56:28 +0000 (23:56 +0300)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 19 Apr 2017 06:15:22 +0000 (08:15 +0200)
Ported from radeonsi. Testing with Kane&Lynch2 shows ≈1k skipped updates per
frame on average.

No piglit changes with tests/gpu.py, gbm mode.

Signed-off-by: Constantine Kharlamov <Hi-Angel@yandex.ru>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 5697da4af9dc544ab97f03dd2fddad701c93a454..19ad50409799195351d0d0df3e3e88d3c82701c1 100644 (file)
@@ -1550,6 +1550,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
 
        r600_set_sample_locations_constant_buffer(rctx);
+       rctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
 static void evergreen_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
index 7f1ecc278b68949322ead605c7f7c3f13c82b397..e1715e8628e2d190a30e637a6143e32a8a5c7cb6 100644 (file)
@@ -189,6 +189,7 @@ struct r600_framebuffer {
        bool cb0_is_integer;
        bool is_msaa_resolve;
        bool dual_src_blend;
+       bool do_update_surf_dirtiness;
 };
 
 struct r600_sample_mask {
index 06100abc4a4c2f4acc3d750da529dc83d2c4e9a8..fc93eb02ad2b141ed2a62cbbd825bed77d4f80a7 100644 (file)
@@ -1209,6 +1209,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
 
        r600_set_sample_locations_constant_buffer(rctx);
+       rctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
 static uint32_t sample_locs_2x[] = {
index 5be49dcdfe94dc2bb6c1e3ab9e25cfdb27ad4497..7b52be36cda6e2bb73101476bb4e8ce21b530321 100644 (file)
@@ -99,6 +99,7 @@ static void r600_texture_barrier(struct pipe_context *ctx, unsigned flags)
                       R600_CONTEXT_FLUSH_AND_INV_CB |
                       R600_CONTEXT_FLUSH_AND_INV |
                       R600_CONTEXT_WAIT_3D_IDLE;
+       rctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
 static unsigned r600_conv_pipe_prim(unsigned prim)
@@ -1732,6 +1733,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
        if (unlikely(dirty_tex_counter != rctx->b.last_dirty_tex_counter)) {
                rctx->b.last_dirty_tex_counter = dirty_tex_counter;
                r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
+               rctx->framebuffer.do_update_surf_dirtiness = true;
        }
 
        if (!r600_update_derived_state(rctx)) {
@@ -2034,29 +2036,32 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
                radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_SQ_NON_EVENT));
        }
 
-       /* Set the depth buffer as dirty. */
-       if (rctx->framebuffer.state.zsbuf) {
-               struct pipe_surface *surf = rctx->framebuffer.state.zsbuf;
-               struct r600_texture *rtex = (struct r600_texture *)surf->texture;
+       if (rctx->framebuffer.do_update_surf_dirtiness) {
+               /* Set the depth buffer as dirty. */
+               if (rctx->framebuffer.state.zsbuf) {
+                       struct pipe_surface *surf = rctx->framebuffer.state.zsbuf;
+                       struct r600_texture *rtex = (struct r600_texture *)surf->texture;
 
-               rtex->dirty_level_mask |= 1 << surf->u.tex.level;
+                       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 (rctx->framebuffer.compressed_cb_mask) {
-               struct pipe_surface *surf;
-               struct r600_texture *rtex;
-               unsigned mask = rctx->framebuffer.compressed_cb_mask;
+                       if (rtex->surface.flags & RADEON_SURF_SBUFFER)
+                               rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
+               }
+               if (rctx->framebuffer.compressed_cb_mask) {
+                       struct pipe_surface *surf;
+                       struct r600_texture *rtex;
+                       unsigned mask = rctx->framebuffer.compressed_cb_mask;
 
-               do {
-                       unsigned i = u_bit_scan(&mask);
-                       surf = rctx->framebuffer.state.cbufs[i];
-                       rtex = (struct r600_texture*)surf->texture;
+                       do {
+                               unsigned i = u_bit_scan(&mask);
+                               surf = rctx->framebuffer.state.cbufs[i];
+                               rtex = (struct r600_texture*)surf->texture;
 
-                       rtex->dirty_level_mask |= 1 << surf->u.tex.level;
+                               rtex->dirty_level_mask |= 1 << surf->u.tex.level;
 
-               } while (mask);
+                       } while (mask);
+               }
+               rctx->framebuffer.do_update_surf_dirtiness = false;
        }
 
        pipe_resource_reference(&ib.buffer, NULL);