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 <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9546>
This commit is contained in:
Mike Blumenkrantz
2020-10-27 14:30:20 -04:00
committed by Marge Bot
parent d84c7c2a85
commit 8c1422dca5
3 changed files with 110 additions and 0 deletions
+75
View File
@@ -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)
{
+3
View File
@@ -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,
+32
View File
@@ -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;
}