zink: move shader image descriptor set refs to underlying type

this was kinda useless since it meant that the set was invalidated any
time the shader image was unbound

Reviewed-by: Hoe Hao Cheng <haochengho12907@gmail.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11188>
This commit is contained in:
Mike Blumenkrantz 2021-03-28 11:31:56 -04:00
parent df5c97eea8
commit 2d99f10286
5 changed files with 88 additions and 51 deletions

View file

@ -623,6 +623,7 @@ get_buffer_view(struct zink_context *ctx, struct zink_resource *res, enum pipe_f
goto out;
}
pipe_reference_init(&buffer_view->reference, 1);
util_dynarray_init(&buffer_view->desc_set_refs.refs, NULL);
buffer_view->bvci = bvci;
buffer_view->buffer_view = view;
buffer_view->hash = hash;
@ -739,6 +740,7 @@ zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *bu
_mesa_hash_table_remove(&screen->bufferview_cache, he);
simple_mtx_unlock(&screen->bufferview_mtx);
vkDestroyBufferView(screen->dev, buffer_view->buffer_view, NULL);
zink_descriptor_set_refs_clear(&buffer_view->desc_set_refs, buffer_view);
FREE(buffer_view);
}
@ -1149,7 +1151,6 @@ unbind_shader_image(struct zink_context *ctx, enum pipe_shader_type stage, unsig
if (!res->image_bind_count[is_compute] && res->bind_count[is_compute])
update_binds_for_samplerviews(ctx, res, is_compute);
zink_descriptor_set_refs_clear(&image_view->desc_set_refs, image_view);
if (image_view->base.resource->target == PIPE_BUFFER)
zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
else {
@ -1183,7 +1184,6 @@ zink_set_shader_images(struct pipe_context *pctx,
for (unsigned i = 0; i < count; i++) {
struct zink_image_view *image_view = &ctx->image_views[p_stage][start_slot + i];
if (images && images[i].resource) {
util_dynarray_init(&image_view->desc_set_refs.refs, NULL);
struct zink_resource *res = zink_resource(images[i].resource);
struct zink_resource *old_res = zink_resource(image_view->base.resource);
if (!zink_resource_object_init_storage(ctx, res)) {
@ -3049,7 +3049,7 @@ check_and_rebind_buffer(struct zink_context *ctx, struct zink_resource *res, uns
}
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_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view);
zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
if (!zink_resource_object_init_storage(ctx, res)) {
debug_printf("couldn't create storage image!");

View file

@ -78,6 +78,7 @@ struct zink_buffer_view {
VkBufferView buffer_view;
uint32_t hash;
struct zink_batch_usage batch_uses;
struct zink_descriptor_refs desc_set_refs;
};
struct zink_sampler_view {
@ -91,7 +92,6 @@ struct zink_sampler_view {
struct zink_image_view {
struct pipe_image_view base;
struct zink_descriptor_refs desc_set_refs;
union {
struct zink_surface *surface;
struct zink_buffer_view *buffer_view;

View file

@ -67,7 +67,7 @@ struct zink_descriptor_set {
#endif
union {
struct zink_resource_object **res_objs;
struct zink_image_view **image_views;
struct zink_descriptor_surface *surfaces;
struct {
struct zink_sampler_view **sampler_views;
struct zink_sampler_state **sampler_states;
@ -103,6 +103,47 @@ debug_describe_zink_descriptor_pool(char *buf, const struct zink_descriptor_pool
sprintf(buf, "zink_descriptor_pool");
}
static inline uint32_t
get_sampler_view_hash(const struct zink_sampler_view *sampler_view)
{
if (!sampler_view)
return 0;
return sampler_view->base.target == PIPE_BUFFER ?
sampler_view->buffer_view->hash : sampler_view->image_view->hash;
}
static inline uint32_t
get_image_view_hash(const struct zink_image_view *image_view)
{
if (!image_view || !image_view->base.resource)
return 0;
return image_view->base.resource->target == PIPE_BUFFER ?
image_view->buffer_view->hash : image_view->surface->hash;
}
uint32_t
zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer)
{
return get_sampler_view_hash(sampler_view) ? get_sampler_view_hash(sampler_view) :
(is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
}
uint32_t
zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer)
{
return get_image_view_hash(image_view) ? get_image_view_hash(image_view) :
(is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
}
static uint32_t
get_descriptor_surface_hash(struct zink_context *ctx, struct zink_descriptor_surface *dsurf, bool is_buffer)
{
return is_buffer ? (dsurf->bufferview ? dsurf->bufferview->hash : zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view) :
(dsurf->surface ? dsurf->surface->hash : zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
}
static bool
desc_state_equal(const void *a, const void *b)
{
@ -165,9 +206,15 @@ descriptor_set_invalidate(struct zink_descriptor_set *zds)
zds->res_objs[i] = NULL;
break;
case ZINK_DESCRIPTOR_TYPE_IMAGE:
if (zds->image_views[i])
pop_desc_set_ref(zds, &zds->image_views[i]->desc_set_refs.refs);
zds->image_views[i] = NULL;
if (zds->surfaces[i].is_buffer) {
if (zds->surfaces[i].bufferview)
pop_desc_set_ref(zds, &zds->surfaces[i].bufferview->desc_set_refs.refs);
zds->surfaces[i].bufferview = NULL;
} else {
if (zds->surfaces[i].surface)
pop_desc_set_ref(zds, &zds->surfaces[i].surface->desc_set_refs.refs);
zds->surfaces[i].surface = NULL;
}
break;
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
if (zds->sampler_views[i])
@ -544,12 +591,22 @@ allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_d
struct zink_descriptor_set *alloc = ralloc_array(pool, struct zink_descriptor_set, bucket_size);
assert(alloc);
unsigned num_resources = pool->num_resources;
struct zink_resource_object **res_objs = rzalloc_array(pool, struct zink_resource_object*, num_resources * bucket_size);
assert(res_objs);
struct zink_resource_object **res_objs = NULL;
void **samplers = NULL;
if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) {
struct zink_descriptor_surface *surfaces = NULL;
switch (type) {
case ZINK_DESCRIPTOR_TYPE_IMAGE:
surfaces = rzalloc_array(pool, struct zink_descriptor_surface, num_resources * bucket_size);
assert(surfaces);
break;
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
samplers = rzalloc_array(pool, void*, num_resources * bucket_size);
assert(samplers);
FALLTHROUGH;
default:
res_objs = rzalloc_array(pool, struct zink_resource_object*, num_resources * bucket_size);
assert(res_objs);
break;
}
for (unsigned i = 0; i < bucket_size; i ++) {
struct zink_descriptor_set *zds = &alloc[i];
@ -562,11 +619,18 @@ allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_d
#ifndef NDEBUG
zds->num_resources = num_resources;
#endif
if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) {
switch (type) {
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
zds->sampler_views = (struct zink_sampler_view**)&res_objs[i * pool->key.layout->num_descriptors];
zds->sampler_states = (struct zink_sampler_state**)&samplers[i * pool->key.layout->num_descriptors];
} else
break;
case ZINK_DESCRIPTOR_TYPE_IMAGE:
zds->surfaces = &surfaces[i * pool->key.layout->num_descriptors];
break;
default:
zds->res_objs = (struct zink_resource_object**)&res_objs[i * pool->key.layout->num_descriptors];
break;
}
zds->desc_set = desc_set[i];
if (i > 0)
util_dynarray_append(&pool->alloc_desc_sets, struct zink_descriptor_set *, zds);
@ -779,9 +843,12 @@ desc_set_ref_add(struct zink_descriptor_set *zds, struct zink_descriptor_refs *r
}
static void
zink_image_view_desc_set_add(struct zink_image_view *image_view, struct zink_descriptor_set *zds, unsigned idx)
zink_image_view_desc_set_add(struct zink_image_view *image_view, struct zink_descriptor_set *zds, unsigned idx, bool is_buffer)
{
desc_set_ref_add(zds, &image_view->desc_set_refs, (void**)&zds->image_views[idx], image_view);
if (is_buffer)
desc_set_ref_add(zds, &image_view->buffer_view->desc_set_refs, (void**)&zds->surfaces[idx].bufferview, image_view->buffer_view);
else
desc_set_ref_add(zds, &image_view->surface->desc_set_refs, (void**)&zds->surfaces[idx].surface, image_view->surface);
}
static void
@ -952,12 +1019,12 @@ desc_set_image_add(struct zink_context *ctx, struct zink_descriptor_set *zds, st
* whenever a resource is destroyed
*/
#ifndef NDEBUG
uint32_t cur_hash = zink_get_image_view_hash(ctx, zds->image_views[i], is_buffer);
uint32_t cur_hash = get_descriptor_surface_hash(ctx, &zds->surfaces[i], is_buffer);
uint32_t new_hash = zink_get_image_view_hash(ctx, image_view, is_buffer);
#endif
assert(!cache_hit || cur_hash == new_hash);
if (!cache_hit)
zink_image_view_desc_set_add(image_view, zds, i);
zink_image_view_desc_set_add(image_view, zds, i, is_buffer);
}
static unsigned
@ -1240,40 +1307,6 @@ calc_descriptor_state_hash_ssbo(struct zink_context *ctx, struct zink_shader *zs
return hash;
}
static inline uint32_t
get_sampler_view_hash(const struct zink_sampler_view *sampler_view)
{
if (!sampler_view)
return 0;
return sampler_view->base.target == PIPE_BUFFER ?
sampler_view->buffer_view->hash : sampler_view->image_view->hash;
}
static inline uint32_t
get_image_view_hash(const struct zink_image_view *image_view)
{
if (!image_view || !image_view->base.resource)
return 0;
return image_view->base.resource->target == PIPE_BUFFER ?
image_view->buffer_view->hash : image_view->surface->hash;
}
uint32_t
zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer)
{
return get_sampler_view_hash(sampler_view) ? get_sampler_view_hash(sampler_view) :
(is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
}
uint32_t
zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer)
{
return get_image_view_hash(image_view) ? get_image_view_hash(image_view) :
(is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
}
static uint32_t
calc_descriptor_state_hash_sampler(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash)
{

View file

@ -119,6 +119,7 @@ create_surface(struct pipe_context *pctx,
surface->base.u.tex.last_layer = templ->u.tex.last_layer;
surface->obj = zink_resource(pres)->obj;
util_dynarray_init(&surface->framebuffer_refs, NULL);
util_dynarray_init(&surface->desc_set_refs.refs, NULL);
if (vkCreateImageView(screen->dev, ivci, NULL,
&surface->image_view) != VK_SUCCESS) {
@ -226,6 +227,7 @@ zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface)
_mesa_hash_table_remove(&screen->surface_cache, he);
simple_mtx_unlock(&screen->surface_mtx);
surface_clear_fb_refs(screen, psurface);
zink_descriptor_set_refs_clear(&surface->desc_set_refs, surface);
util_dynarray_fini(&surface->framebuffer_refs);
pipe_resource_reference(&psurface->texture, NULL);
if (surface->simage_view)
@ -255,6 +257,7 @@ zink_rebind_surface(struct zink_context *ctx, struct pipe_surface **psurface)
simple_mtx_lock(&screen->surface_mtx);
struct hash_entry *new_entry = _mesa_hash_table_search_pre_hashed(&screen->surface_cache, hash, &ivci);
surface_clear_fb_refs(screen, *psurface);
zink_descriptor_set_refs_clear(&surface->desc_set_refs, surface);
if (new_entry) {
/* reuse existing surface; old one will be cleaned up naturally */
struct zink_surface *new_surface = new_entry->data;

View file

@ -39,6 +39,7 @@ struct zink_surface {
uint32_t hash;
struct zink_batch_usage batch_uses;
struct util_dynarray framebuffer_refs;
struct zink_descriptor_refs desc_set_refs;
};
static inline struct zink_surface *