Module: Mesa
Branch: master
Commit: d7c38af3da86733084267bed3c90f495a2ac79c8
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=d7c38af3da86733084267bed3c90f495a2ac79c8

Author: Rob Clark <[email protected]>
Date:   Sun Feb 28 11:06:13 2021 -0800

freedreno/a6xx: Fix uncompressed resource vs stale CSO

A sequence like:

1) create sampler view CSO with UBWC resource
2) later create another sampler view or image view with the same
   resource, but a format that triggers demoting the resource to
   uncompressed
3) bind CSO created in step #1

would not work correctly, because the CSO created in step #1 is still
setup for UBWC, despite the fact that the resource had been demoted to
uncompressed.

Fortunately this is easy enough to detect, as the resource's seqno would
have been updated.

Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9321>

---

 src/gallium/drivers/freedreno/a6xx/fd6_emit.c    | 15 +++++++--
 src/gallium/drivers/freedreno/a6xx/fd6_texture.c | 41 +++++++++++++++++-------
 src/gallium/drivers/freedreno/a6xx/fd6_texture.h |  7 ++++
 3 files changed, 48 insertions(+), 15 deletions(-)

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);
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to