r600: work out target mask at framebuffer bind.
authorDave Airlie <airlied@redhat.com>
Mon, 5 Feb 2018 03:54:23 +0000 (13:54 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 6 Feb 2018 20:16:55 +0000 (06:16 +1000)
If we only get 1,2,3,6 framebuffers we want a sparse target mask.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c

index f8042c21c0e31db02557364fdcdb724075189b2b..4c9163c2a7b5ffc847f33ba52bbb42849cdafea2 100644 (file)
@@ -1436,7 +1436,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_surface *surf;
        struct r600_texture *rtex;
        uint32_t i, log_samples;
-
+       uint32_t target_mask = 0;
        /* Flush TC when changing the framebuffer state, because the only
         * client not using TC that can change textures is the framebuffer.
         * Other places don't typically have to flush TC.
@@ -1463,6 +1463,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
                if (!surf)
                        continue;
 
+               target_mask |= (0xf << (i * 4));
+
                rtex = (struct r600_texture*)surf->base.texture;
 
                r600_context_add_resource_size(ctx, state->cbufs[i]->texture);
@@ -1528,7 +1530,9 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
                r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
        }
 
-       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) {
+       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs ||
+           rctx->cb_misc_state.bound_cbufs_target_mask != target_mask) {
+               rctx->cb_misc_state.bound_cbufs_target_mask = target_mask;
                rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
                r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
        }
@@ -2025,7 +2029,7 @@ static void evergreen_emit_cb_misc_state(struct r600_context *rctx, struct r600_
 {
        struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
        struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom;
-       unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1;
+       unsigned fb_colormask = a->bound_cbufs_target_mask;
        unsigned ps_colormask = a->ps_color_export_mask;
        unsigned rat_colormask = evergreen_construct_rat_mask(rctx, a, a->nr_cbufs);
        radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2);
index 9e5dc221e9c72bb44c5bdb9e8f2935160988aa77..740b50aec5e8da6f126aedcb217d132395f893c7 100644 (file)
@@ -152,6 +152,7 @@ struct r600_cb_misc_state {
        unsigned cb_color_control; /* this comes from blend state */
        unsigned blend_colormask; /* 8*4 bits for 8 RGBA colorbuffers */
        unsigned nr_cbufs;
+       unsigned bound_cbufs_target_mask;
        unsigned nr_ps_color_outputs;
        unsigned ps_color_export_mask;
        unsigned image_rat_enabled_mask;
index 6ff8037d9cbeece89046b3a854acab26029c9ea7..5cf99c18b6202c501c4972349acff52ef04c9474 100644 (file)
@@ -1525,7 +1525,7 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom
                }
                radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, a->cb_color_control);
        } else {
-               unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1;
+               unsigned fb_colormask = a->bound_cbufs_target_mask;
                unsigned ps_colormask = a->ps_color_export_mask;
                unsigned multiwrite = a->multiwrite && a->nr_cbufs > 1;