From be28daeef98fd01dcadbc7e96a387a077949a1b5 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 8 Jul 2025 14:20:34 -0400 Subject: [PATCH] zink: use a rebind counter to manage descriptor rebinds matching the pointers here breaks if pointers get reused, but a monotonically increasing value will provide reliable comparison Part-of: --- src/gallium/drivers/zink/zink_context.c | 25 ++++++++++++------------ src/gallium/drivers/zink/zink_kopper.c | 2 ++ src/gallium/drivers/zink/zink_resource.c | 1 + src/gallium/drivers/zink/zink_types.h | 6 ++++-- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 89cab13b13c..a41a63cdad6 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1162,7 +1162,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, sampler_view->base = *state; sampler_view->base.texture = NULL; pipe_resource_reference(&sampler_view->base.texture, pres); - sampler_view->obj = res->obj; + sampler_view->rebind_count = res->rebind_count; sampler_view->base.reference.count = 1; sampler_view->base.context = pctx; @@ -1295,7 +1295,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, sampler_view->tbo_size = MIN2(state->u.buf.size / blocksize, screen->info.props.limits.maxTexelBufferElements) * blocksize; return &sampler_view->base; } - sampler_view->obj = res->obj; + sampler_view->rebind_count = res->rebind_count; sampler_view->buffer_view = get_buffer_view(ctx, res, state->format, state->u.buf.offset, state->u.buf.size); err = !sampler_view->buffer_view; } @@ -2056,7 +2056,7 @@ zink_set_shader_images(struct pipe_context *pctx, a->import2d = import2d; bind_shaderimage_resource_stage(ctx, b, a->import2d, is_compute); } - a->obj = res->obj; + a->rebind_count = res->rebind_count; a->surface = surface; } } @@ -2244,13 +2244,13 @@ zink_set_sampler_views(struct pipe_context *pctx, if (!a || a->base.texture != b->base.texture || zink_resource(a->base.texture)->obj != res->obj || memcmp(&a->base.u.buf, &b->base.u.buf, sizeof(b->base.u.buf))) update = true; - } else if (b->obj != res->obj) { + } else if (b->rebind_count != res->rebind_count) { /* if this resource has been rebound while it wasn't set here, * its backing resource will have changed and thus we need to update * the bufferview */ b->buffer_view = get_buffer_view(ctx, res, b->base.format, b->base.u.buf.offset, b->base.u.buf.size); - b->obj = res->obj; + b->rebind_count = res->rebind_count; update = true; } else if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view) update = true; @@ -2260,8 +2260,8 @@ zink_set_sampler_views(struct pipe_context *pctx, if (!ctx->unordered_blitting) res->obj->unordered_read = false; } else { - if (res->obj != b->obj) { - b->obj = res->obj; + if (res->rebind_count != b->rebind_count) { + b->rebind_count = res->rebind_count; struct pipe_surface tmpl = pipe_surface_templ_from_sampler_view(&b->base, &res->base.b, b->base.target); b->image_view = zink_get_surface(ctx, &tmpl, &b->ivci); update = true; @@ -5047,7 +5047,7 @@ rebind_image(struct zink_context *ctx, struct zink_resource *res) for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) { struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]); if (sv && sv->base.texture == &res->base.b) { - sv->obj = res->obj; + sv->rebind_count = res->rebind_count; struct pipe_surface tmpl = pipe_surface_templ_from_sampler_view(&sv->base, &res->base.b, sv->base.target); sv->image_view = zink_get_surface(ctx, &tmpl, &sv->ivci); ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1); @@ -5152,8 +5152,8 @@ zink_rebind_all_images(struct zink_context *ctx) if (!sv || !sv->image_view || sv->base.texture->target == PIPE_BUFFER) continue; struct zink_resource *res = zink_resource(sv->base.texture); - if (res->obj != sv->obj) { - sv->obj = res->obj; + if (res->rebind_count != sv->rebind_count) { + sv->rebind_count = res->rebind_count; struct pipe_surface tmpl = pipe_surface_templ_from_sampler_view(&sv->base, &res->base.b, sv->base.target); sv->image_view = zink_get_surface(ctx, &tmpl, &sv->ivci); ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1); @@ -5165,11 +5165,11 @@ zink_rebind_all_images(struct zink_context *ctx) struct zink_resource *res = zink_resource(image_view->base.resource); if (!res || res->base.b.target == PIPE_BUFFER) continue; - if (ctx->image_views[i][j].obj != res->obj) { + if (ctx->image_views[i][j].rebind_count != res->rebind_count) { struct zink_resource *import2d = NULL; image_view->surface = create_image_surface(ctx, &image_view->base, i == MESA_SHADER_COMPUTE, &import2d); assert(!import2d); - image_view->obj = res->obj; + image_view->rebind_count = res->rebind_count; ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1); update_descriptor_state_image(ctx, i, j, res); if (!general_layout) @@ -5201,6 +5201,7 @@ zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resou zink_resource_copies_reset(d); /* force counter buffer reset */ d->so_valid = false; + d->rebind_count++; /* FIXME: tc buffer sharedness tracking */ if (!num_rebinds) { num_rebinds = d->bind_count[0] + d->bind_count[1]; diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index 5745231e2fc..7cfdb9bc2b5 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -648,6 +648,7 @@ kill_swapchain(struct zink_context *ctx, struct zink_resource *res) zink_batch_reference_resource(ctx, res); struct pipe_resource *pres = screen->base.resource_create(&screen->base, &res->base.b); zink_resource_object_reference(screen, &res->obj, zink_resource(pres)->obj); + res->rebind_count++; res->layout = VK_IMAGE_LAYOUT_UNDEFINED; res->swapchain = false; pipe_resource_reference(&pres, NULL); @@ -1145,6 +1146,7 @@ zink_kopper_fixup_depth_buffer(struct zink_context *ctx) struct pipe_resource *pz = screen->base.resource_create(&screen->base, &templ); struct zink_resource *z = zink_resource(pz); zink_resource_object_reference(screen, &res->obj, z->obj); + res->rebind_count++; res->base.b.width0 = ctx->fb_state.width; res->base.b.height0 = ctx->fb_state.height; pipe_resource_reference(&pz, NULL); diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 5fc47f24ba7..70e728952c8 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1780,6 +1780,7 @@ add_resource_bind(struct zink_context *ctx, struct zink_resource *res, unsigned box.depth = util_num_layers(&res->base.b, i); ctx->base.resource_copy_region(&ctx->base, &res->base.b, i, 0, 0, 0, &staging.base.b, i, &box); } + res->rebind_count++; if (old_obj->exportable) { simple_mtx_lock(&ctx->bs->exportable_lock); _mesa_set_remove_key(&ctx->bs->dmabuf_exports, &staging); diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 7a127f2ead0..e4bca1b3912 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1296,6 +1296,8 @@ struct zink_resource { VkPipelineStageFlagBits gfx_barrier; VkAccessFlagBits barrier_access[2]; //gfx, compute + unsigned rebind_count; + VkRect2D damage; bool use_damage; @@ -1577,7 +1579,7 @@ struct zink_buffer_view { struct zink_sampler_view { struct pipe_sampler_view base; VkImageViewCreateInfo ivci; - struct zink_resource_object *obj; + unsigned rebind_count; union { struct zink_surface *image_view; struct zink_buffer_view *buffer_view; @@ -1592,7 +1594,7 @@ struct zink_sampler_view { struct zink_image_view { struct pipe_image_view base; - struct zink_resource_object *obj; + unsigned rebind_count; union { struct zink_surface *surface; struct zink_buffer_view *buffer_view;