[Mesa-dev] [PATCH 4/4] r600g: avoid redundant CB updates

Marek Olšák maraeo at gmail.com
Wed Apr 26 17:48:55 UTC 2017


For dual source blending, CB_COLOR1_INFO is required to be the same as
CB_COLOR0_INFO.

Other than that, as long as there are no piglit regressions, I'm OK
with any development going on in gallium/drivers/r600.

If you want me to commit stuff, please send me a pull request or you
can ask for an FDO account.

Marek

On Wed, Apr 26, 2017 at 3:21 AM, Dieter Nützel <Dieter at nuetzel-hh.de> wrote:
> This one is
>
> Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>
>
> My gut feeling is 'faster than ever'!
> Even WebGL (Konqi 5.0.97) apps (HD 1920x1080) are very smooth, now.
>
> Marek can you comment and then commit?
>
> Dieter
>
>
> Am 25.04.2017 13:59, schrieb Constantine Kharlamov:
>>
>> It finishes the work started by 0c2eed0edec, quoting:
>>
>>> The main idea is to avoid setting CB_COLORi_INFO = 0 for i>0 repeatedly
>>> when those colorbuffers aren't used. This is mainly for glamor.
>>
>>
>> After 0c2eed0edec the r600g was passing null as the dirty_cbufs pointer,
>> and the current patch makes the actual use of the argument. In
>> particular, the check for null dirty_cbufs pointer in
>> evergreen_do_fast_color_clear() is removed.
>>
>> I didn't change r600_state.c because evergreen_do_fast_color_clear() is
>> only used for eg and higher, thus checks in there are useless.
>>
>> In addition to radeonsi-like modifications I also do reset in
>> r600_bind_blend_state_internal(), otherwise there're blend
>> arb_blend_func_extended regressions. Besides, I keep dirty_cbufs in
>> cb_misc_state, because it rather seem belonging there.
>>
>> Some statistics: skips ≈70 updates of CB registers per frame in
>> Kane&Lynch2.
>>
>> Signed-off-by: Constantine Kharlamov <Hi-Angel at yandex.ru>
>> ---
>>  src/gallium/drivers/r600/evergreen_state.c   | 15 +++++++++++++--
>>  src/gallium/drivers/r600/r600_blit.c         |  3 ++-
>>  src/gallium/drivers/r600/r600_hw_context.c   |  1 +
>>  src/gallium/drivers/r600/r600_pipe.h         |  1 +
>>  src/gallium/drivers/r600/r600_state_common.c |  1 +
>>  src/gallium/drivers/radeon/r600_texture.c    |  3 +--
>>  6 files changed, 19 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/gallium/drivers/r600/evergreen_state.c
>> b/src/gallium/drivers/r600/evergreen_state.c
>> index 9a6bb4e4c9..916270ec4b 100644
>> --- a/src/gallium/drivers/r600/evergreen_state.c
>> +++ b/src/gallium/drivers/r600/evergreen_state.c
>> @@ -1426,6 +1426,11 @@ static void
>> evergreen_set_framebuffer_state(struct pipe_context *ctx,
>>                          R600_CONTEXT_FLUSH_AND_INV_DB_META |
>>                          R600_CONTEXT_INV_TEX_CACHE;
>>
>> +       /* Take the maximum of the old and new count. If the new count is
>> lower,
>> +        * dirtying is needed to disable the unbound colorbuffers.
>> +        */
>> +       rctx->cb_misc_state.dirty_cbufs |=
>> +               (1 << MAX2(rctx->framebuffer.state.nr_cbufs,
>> state->nr_cbufs)) - 1;
>>         rctx->framebuffer.dirty_zsbuf |= rctx->framebuffer.state.zsbuf !=
>> state->zsbuf;
>>         util_copy_framebuffer_state(&rctx->framebuffer.state, state);
>>
>> @@ -1684,6 +1689,9 @@ static void
>> evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
>>         for (i = 0; i < nr_cbufs; i++) {
>>                 unsigned reloc, cmask_reloc;
>>
>> +               if (!(rctx->cb_misc_state.dirty_cbufs & (1 << i)))
>> +                       continue;
>> +
>>                 cb = (struct r600_surface*)state->cbufs[i];
>>                 if (!cb) {
>>                         radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO
>> + i * 0x3C,
>> @@ -1736,13 +1744,15 @@ static void
>> evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
>>                 radeon_emit(cs, reloc);
>>         }
>>         /* set CB_COLOR1_INFO for possible dual-src blending */
>> -       if (rctx->framebuffer.dual_src_blend && i == 1 && state->cbufs[0])
>> {
>> +       if (rctx->framebuffer.dual_src_blend && i == 1 && state->cbufs[0]
>> &&
>> +           rctx->cb_misc_state.dirty_cbufs & (1 << 0)) {
>>                 radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 *
>> 0x3C,
>>                                        cb->cb_color_info |
>> tex->cb_color_info);
>>                 i++;
>>         }
>>         for (; i < 8 ; i++)
>> -               radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i *
>> 0x3C, 0);
>> +               if (rctx->cb_misc_state.dirty_cbufs & (1 << i))
>> +                       radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO
>> + i * 0x3C, 0);
>>         for (; i < 12; i++)
>>                 radeon_set_context_reg(cs, R_028E50_CB_COLOR8_INFO + (i -
>> 8) * 0x1C, 0);
>>
>> @@ -1810,6 +1820,7 @@ static void
>> evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
>>                                         rctx->ps_iter_samples, 0,
>> sc_mode_cntl_1);
>>         }
>>         rctx->framebuffer.dirty_zsbuf = false;
>> +       rctx->cb_misc_state.dirty_cbufs = 0;
>>  }
>>
>>  static void evergreen_emit_polygon_offset(struct r600_context *rctx,
>> struct r600_atom *a)
>> diff --git a/src/gallium/drivers/r600/r600_blit.c
>> b/src/gallium/drivers/r600/r600_blit.c
>> index 62035a7bee..a4434b77c2 100644
>> --- a/src/gallium/drivers/r600/r600_blit.c
>> +++ b/src/gallium/drivers/r600/r600_blit.c
>> @@ -407,7 +407,8 @@ static void r600_clear(struct pipe_context *ctx,
>> unsigned buffers,
>>
>>         if (buffers & PIPE_CLEAR_COLOR && rctx->b.chip_class >= EVERGREEN)
>> {
>>                 evergreen_do_fast_color_clear(&rctx->b, fb,
>> &rctx->framebuffer.atom,
>> -                                             &buffers, NULL, color);
>> +                                             &buffers,
>> +
>> &rctx->cb_misc_state.dirty_cbufs, color);
>>                 if (!buffers)
>>                         return; /* all buffers have been fast cleared */
>>         }
>> diff --git a/src/gallium/drivers/r600/r600_hw_context.c
>> b/src/gallium/drivers/r600/r600_hw_context.c
>> index c85e346307..4054896393 100644
>> --- a/src/gallium/drivers/r600/r600_hw_context.c
>> +++ b/src/gallium/drivers/r600/r600_hw_context.c
>> @@ -375,6 +375,7 @@ void r600_begin_new_cs(struct r600_context *ctx)
>>         assert(!ctx->b.gfx.cs->prev_dw);
>>         ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
>>         ctx->framebuffer.dirty_zsbuf = true;
>> +       ctx->cb_misc_state.dirty_cbufs = (1 << 8) - 1;
>>  }
>>
>>  void r600_emit_pfp_sync_me(struct r600_context *rctx)
>> diff --git a/src/gallium/drivers/r600/r600_pipe.h
>> b/src/gallium/drivers/r600/r600_pipe.h
>> index aeba1f2635..8f1c1a8095 100644
>> --- a/src/gallium/drivers/r600/r600_pipe.h
>> +++ b/src/gallium/drivers/r600/r600_pipe.h
>> @@ -133,6 +133,7 @@ struct r600_cb_misc_state {
>>         unsigned blend_colormask; /* 8*4 bits for 8 RGBA colorbuffers */
>>         unsigned nr_cbufs;
>>         unsigned nr_ps_color_outputs;
>> +       unsigned dirty_cbufs;
>>         bool multiwrite;
>>         bool dual_src_blend;
>>  };
>> diff --git a/src/gallium/drivers/r600/r600_state_common.c
>> b/src/gallium/drivers/r600/r600_state_common.c
>> index ffb0f5a811..7716c83f84 100644
>> --- a/src/gallium/drivers/r600/r600_state_common.c
>> +++ b/src/gallium/drivers/r600/r600_state_common.c
>> @@ -187,6 +187,7 @@ static void r600_bind_blend_state_internal(struct
>> r600_context *rctx,
>>         }
>>         if (update_cb) {
>>                 r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
>> +               rctx->cb_misc_state.dirty_cbufs |= (1 <<
>> rctx->framebuffer.state.nr_cbufs) - 1;
>>         }
>>         if (rctx->framebuffer.dual_src_blend != blend->dual_src_blend) {
>>                 rctx->framebuffer.dual_src_blend = blend->dual_src_blend;
>> diff --git a/src/gallium/drivers/radeon/r600_texture.c
>> b/src/gallium/drivers/radeon/r600_texture.c
>> index 8110ec1484..ca8c75639a 100644
>> --- a/src/gallium/drivers/radeon/r600_texture.c
>> +++ b/src/gallium/drivers/radeon/r600_texture.c
>> @@ -2753,8 +2753,7 @@ void evergreen_do_fast_color_clear(struct
>> r600_common_context *rctx,
>>
>>                 evergreen_set_clear_color(tex, fb->cbufs[i]->format,
>> color);
>>
>> -               if (dirty_cbufs)
>> -                       *dirty_cbufs |= 1 << i;
>> +               *dirty_cbufs |= 1 << i;
>>                 rctx->set_atom_dirty(rctx, fb_state, true);
>>                 *buffers &= ~clear_bit;
>>         }


More information about the mesa-dev mailing list