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 <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9321>
This commit is contained in:
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user