diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 1ea2594f994..bc53d280235 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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!"); diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 1de31d7db62..db132c72e1b 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -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; diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index c5d9ced1fd6..98e1ce35f56 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -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) { diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c index 825cd600702..1ec88765f44 100644 --- a/src/gallium/drivers/zink/zink_surface.c +++ b/src/gallium/drivers/zink/zink_surface.c @@ -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; diff --git a/src/gallium/drivers/zink/zink_surface.h b/src/gallium/drivers/zink/zink_surface.h index 87d6fc6fa50..e9004255220 100644 --- a/src/gallium/drivers/zink/zink_surface.h +++ b/src/gallium/drivers/zink/zink_surface.h @@ -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 *