diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index bef28411753..87938e33501 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -390,9 +390,18 @@ fd6_emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring, struct fd_ringbuffer *state = fd_ringbuffer_new_object(ctx->pipe, num_merged_textures * 16 * 4); for (unsigned i = 0; i < num_textures; i++) { - static const struct fd6_pipe_sampler_view dummy_view = {}; - const struct fd6_pipe_sampler_view *view = tex->textures[i] ? - fd6_pipe_sampler_view(tex->textures[i]) : &dummy_view; + const struct fd6_pipe_sampler_view *view; + + if (tex->textures[i]) { + view = fd6_pipe_sampler_view(tex->textures[i]); + if (unlikely(view->rsc_seqno != view->ptr1->seqno)) { + fd6_sampler_view_update(ctx, + fd6_pipe_sampler_view(tex->textures[i])); + } + } else { + static const struct fd6_pipe_sampler_view dummy_view = {}; + view = &dummy_view; + } OUT_RING(state, view->texconst0); OUT_RING(state, view->texconst1); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index c417ee385a7..f51d000d6b6 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -161,27 +161,41 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, { struct fd6_pipe_sampler_view *so = CALLOC_STRUCT(fd6_pipe_sampler_view); struct fd_resource *rsc = fd_resource(prsc); - enum pipe_format format = cso->format; - bool ubwc_enabled = false; - unsigned lvl, layers = 0; if (!so) return NULL; - fd6_validate_format(fd_context(pctx), rsc, format); - - if (format == PIPE_FORMAT_X32_S8X24_UINT) { - rsc = rsc->stencil; - format = rsc->base.format; - } + fd6_validate_format(fd_context(pctx), rsc, cso->format); so->base = *cso; pipe_reference(NULL, &prsc->reference); so->base.texture = prsc; so->base.reference.count = 1; so->base.context = pctx; - so->seqno = ++fd6_context(fd_context(pctx))->tex_seqno; + + fd6_sampler_view_update(fd_context(pctx), so); + + return &so->base; +} + +void +fd6_sampler_view_update(struct fd_context *ctx, struct fd6_pipe_sampler_view *so) +{ + const struct pipe_sampler_view *cso = &so->base; + struct pipe_resource *prsc = cso->texture; + struct fd_resource *rsc = fd_resource(prsc); + enum pipe_format format = cso->format; + bool ubwc_enabled = false; + unsigned lvl, layers = 0; + + if (format == PIPE_FORMAT_X32_S8X24_UINT) { + rsc = rsc->stencil; + format = rsc->base.format; + } + + so->seqno = ++fd6_context(ctx)->tex_seqno; so->ptr1 = rsc; + so->rsc_seqno = so->ptr1->seqno; if (cso->target == PIPE_BUFFER) { unsigned elements = cso->u.buf.size / util_format_get_blocksize(format); @@ -297,8 +311,6 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->width0, lvl), block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->height0, lvl), block_height))); } - - return &so->base; } static void @@ -363,6 +375,11 @@ fd6_texture_state(struct fd_context *ctx, enum pipe_shader_type type, struct fd6_pipe_sampler_view *view = fd6_pipe_sampler_view(tex->textures[i]); + /* NOTE that if the backing rsc was uncompressed between the + * time that the CSO was originally created and now, the rsc + * seqno would have changed, so we don't have to worry about + * getting a bogus cache hit. + */ key.view[i].rsc_seqno = fd_resource(view->base.texture)->seqno; key.view[i].seqno = view->seqno; } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h index 3ce43d5633b..02711541140 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.h @@ -56,6 +56,11 @@ struct fd6_pipe_sampler_view { uint32_t offset1, offset2; struct fd_resource *ptr1, *ptr2; uint16_t seqno; + + /* For detecting when a resource has transitioned from UBWC compressed + * to uncompressed, which means the sampler state needs to be updated + */ + uint16_t rsc_seqno; }; static inline struct fd6_pipe_sampler_view * @@ -64,6 +69,8 @@ fd6_pipe_sampler_view(struct pipe_sampler_view *pview) return (struct fd6_pipe_sampler_view *)pview; } +void fd6_sampler_view_update(struct fd_context *ctx, struct fd6_pipe_sampler_view *so); + void fd6_texture_init(struct pipe_context *pctx); void fd6_texture_fini(struct pipe_context *pctx);