freedreno: Add dirty bit for state that needs rsc tracking

aa1ddb6fe3 skipped the tracking for the
!dirty case, but we can do a bit better and track at bind time whether
the state change is one that requires resource tracking.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9581>
This commit is contained in:
Rob Clark 2021-03-13 09:02:49 -08:00
parent 66cbe66090
commit 8cb51ba30e
4 changed files with 40 additions and 3 deletions

View file

@ -159,6 +159,9 @@ enum fd_dirty_3d_state {
FD_DIRTY_RASTERIZER_DISCARD = BIT(24),
FD_DIRTY_BLEND_DUAL = BIT(25),
#define NUM_DIRTY_BITS 26
/* additional flag for state requires updated resource tracking: */
FD_DIRTY_RESOURCE = BIT(31),
};
/* per shader-stage dirty state: */
@ -506,6 +509,31 @@ fd_stream_output_target(struct pipe_stream_output_target *target)
return (struct fd_stream_output_target *)target;
}
/**
* Does the dirty state require resource tracking, ie. in general
* does it reference some resource. There are some special cases:
*
* - FD_DIRTY_CONST can reference a resource, but cb0 is handled
* specially as if it is not a user-buffer, we expect it to be
* coming from const_uploader, so we can make some assumptions
* that future transfer_map will be UNSYNCRONIZED
* - FD_DIRTY_ZSA controls how the framebuffer is accessed
* - FD_DIRTY_BLEND needs to update GMEM reason
*
* TODO if we can make assumptions that framebuffer state is bound
* first, before blend/zsa/etc state we can move some of the ZSA/
* BLEND state handling from draw time to bind time. I think this
* is true of mesa/st, perhaps we can just document it to be a
* frontend requirement?
*/
static inline bool
fd_context_dirty_resource(enum fd_dirty_3d_state dirty)
{
return dirty & (FD_DIRTY_FRAMEBUFFER | FD_DIRTY_ZSA |
FD_DIRTY_BLEND | FD_DIRTY_SSBO | FD_DIRTY_IMAGE |
FD_DIRTY_VTXBUF | FD_DIRTY_TEX | FD_DIRTY_STREAMOUT);
}
/* Mark specified non-shader-stage related state as dirty: */
static inline void
fd_context_dirty(struct fd_context *ctx, enum fd_dirty_3d_state dirty)
@ -514,8 +542,12 @@ fd_context_dirty(struct fd_context *ctx, enum fd_dirty_3d_state dirty)
assert(util_is_power_of_two_nonzero(dirty));
STATIC_ASSERT(ffs(dirty) <= ARRAY_SIZE(ctx->gen_dirty_map));
ctx->dirty |= dirty;
ctx->gen_dirty |= ctx->gen_dirty_map[ffs(dirty) - 1];
if (fd_context_dirty_resource(dirty))
dirty |= FD_DIRTY_RESOURCE;
ctx->dirty |= dirty;
}
static inline void

View file

@ -209,7 +209,7 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info,
fd_screen_lock(ctx->screen);
if (ctx->dirty)
if (ctx->dirty & FD_DIRTY_RESOURCE)
batch_draw_tracking_for_dirty_bits(batch);
/* Mark index buffer as being read */

View file

@ -99,7 +99,7 @@ rebind_resource_in_ctx(struct fd_context *ctx, struct fd_resource *rsc)
!(ctx->dirty_shader[stage] & FD_DIRTY_CONST)) {
struct fd_constbuf_stateobj *cb = &ctx->constbuf[stage];
const unsigned num_ubos = util_last_bit(cb->enabled_mask);
for (unsigned i = 0; i < num_ubos; i++) {
for (unsigned i = 1; i < num_ubos; i++) {
if (cb->cb[i].buffer == prsc) {
fd_context_dirty_shader(ctx, stage, FD_DIRTY_SHADER_CONST);
break;

View file

@ -123,6 +123,11 @@ fd_set_constant_buffer(struct pipe_context *pctx,
fd_context_dirty_shader(ctx, shader, FD_DIRTY_SHADER_CONST);
fd_resource_set_usage(cb->buffer, FD_DIRTY_CONST);
if (index > 0) {
assert(!cb->user_buffer);
ctx->dirty |= FD_DIRTY_RESOURCE;
}
}
static void