From 8c1422dca5ac524a6a57ffaa14556e95126b787f Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 27 Oct 2020 14:30:20 -0400 Subject: [PATCH] zink: add a pipe_context::invalidate_resource hook this creates new backing objects for the invalidated resource and, if needed, rebinds it to any descriptor sets it might be used in by invalidating the descriptor state and creating new view objects Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.c | 75 ++++++++++++++++++++++++ src/gallium/drivers/zink/zink_context.h | 3 + src/gallium/drivers/zink/zink_resource.c | 32 ++++++++++ 3 files changed, 110 insertions(+) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 55ed0c09e37..2799a3eed66 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -960,6 +960,13 @@ zink_set_shader_images(struct pipe_context *pctx, invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE); } +static void +sampler_view_buffer_clear(struct zink_context *ctx, struct zink_sampler_view *sampler_view) +{ + zink_descriptor_set_refs_clear(&sampler_view->desc_set_refs, sampler_view); + zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL); +} + static void zink_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader_type, @@ -978,6 +985,20 @@ zink_set_sampler_views(struct pipe_context *pctx, struct zink_sampler_view *b = zink_sampler_view(pview); if (b && b->base.texture) { struct zink_resource *res = zink_resource(b->base.texture); + if (res->base.target == PIPE_BUFFER && + res->bind_history & BITFIELD64_BIT(ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW)) { + /* 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 + */ + struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, b->base.format, b->base.u.buf.offset, b->base.u.buf.size); + if (buffer_view == b->buffer_view) + p_atomic_dec(&buffer_view->reference.count); + else { + sampler_view_buffer_clear(ctx, b); + b->buffer_view = buffer_view; + } + } res->bind_history |= BITFIELD_BIT(ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW); res->bind_stages |= 1 << shader_type; } @@ -2148,6 +2169,60 @@ zink_set_stream_output_targets(struct pipe_context *pctx, } } +void +zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res) +{ + assert(res->base.target == PIPE_BUFFER); + + for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; shader++) { + if (!(res->bind_stages & (1 << shader))) + continue; + for (enum zink_descriptor_type type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) { + if (!(res->bind_history & BITFIELD64_BIT(type))) + continue; + + uint32_t usage = zink_program_get_descriptor_usage(ctx, shader, type); + while (usage) { + const int i = u_bit_scan(&usage); + struct zink_resource *cres = get_resource_for_descriptor(ctx, type, shader, i); + if (res != cres) + continue; + + switch (type) { + case ZINK_DESCRIPTOR_TYPE_SSBO: { + struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][i]; + util_range_add(&res->base, &res->valid_buffer_range, ssbo->buffer_offset, + ssbo->buffer_offset + ssbo->buffer_size); + break; + } + case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: { + struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][i]); + sampler_view_buffer_clear(ctx, sampler_view); + sampler_view->buffer_view = get_buffer_view(ctx, res, sampler_view->base.format, + sampler_view->base.u.buf.offset, sampler_view->base.u.buf.size); + break; + } + case ZINK_DESCRIPTOR_TYPE_IMAGE: { + struct zink_image_view *image_view = &ctx->image_views[shader][i]; + zink_descriptor_set_refs_clear(&image_view->desc_set_refs, image_view); + zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL); + image_view->buffer_view = get_buffer_view(ctx, res, image_view->base.format, + image_view->base.u.buf.offset, image_view->base.u.buf.size); + assert(image_view->buffer_view); + util_range_add(&res->base, &res->valid_buffer_range, image_view->base.u.buf.offset, + image_view->base.u.buf.offset + image_view->base.u.buf.size); + break; + } + default: + break; + } + + invalidate_descriptor_state(ctx, shader, type); + } + } + } +} + static bool init_batch(struct zink_context *ctx, struct zink_batch *batch, unsigned idx) { diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 161dce031e5..5f30030fa61 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -322,6 +322,9 @@ zink_rect_from_box(const struct pipe_box *box) return (struct u_rect){box->x, box->x + box->width, box->y, box->y + box->height}; } +void +zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res); + void zink_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *dinfo, diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 4d1d8735762..b0f73b006df 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -573,6 +573,37 @@ zink_resource_from_handle(struct pipe_screen *pscreen, #endif } +static void +zink_resource_invalidate(struct pipe_context *pctx, struct pipe_resource *pres) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_resource *res = zink_resource(pres); + struct zink_screen *screen = zink_screen(pctx->screen); + + if (pres->target != PIPE_BUFFER) + return; + + if (res->valid_buffer_range.start > res->valid_buffer_range.end) + return; + + util_range_set_empty(&res->valid_buffer_range); + if (!zink_get_resource_usage(res)) + return; + + struct zink_resource_object *old_obj = res->obj; + struct zink_resource_object *new_obj = resource_object_create(screen, pres, NULL, NULL); + if (!new_obj) { + debug_printf("new backing resource alloc failed!"); + return; + } + res->obj = new_obj; + res->access_stage = 0; + res->access = 0; + zink_resource_rebind(ctx, res); + zink_descriptor_set_refs_clear(&old_obj->desc_set_refs, old_obj); + zink_resource_object_reference(screen, &old_obj, NULL); +} + static void zink_transfer_copy_bufimage(struct zink_context *ctx, struct zink_resource *dst, @@ -946,4 +977,5 @@ zink_context_resource_init(struct pipe_context *pctx) pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region; pctx->buffer_subdata = u_default_buffer_subdata; pctx->texture_subdata = u_default_texture_subdata; + pctx->invalidate_resource = zink_resource_invalidate; }