sampler_view->batch_uses &= ~BITFIELD_BIT(batch->batch_id);
if (sampler_view->base.target == PIPE_BUFFER) {
struct zink_buffer_view *buffer_view = sampler_view->buffer_view;
- zink_buffer_view_reference(ctx, &buffer_view, NULL);
+ zink_buffer_view_reference(screen, &buffer_view, NULL);
} else {
struct zink_surface *surface = sampler_view->image_view;
pipe_surface_reference((struct pipe_surface**)&surface, NULL);
set_foreach(batch->bufferviews, entry) {
struct zink_buffer_view *buffer_view = (struct zink_buffer_view *)entry->key;
buffer_view->batch_uses &= ~BITFIELD64_BIT(batch->batch_id);
- zink_buffer_view_reference(ctx, &buffer_view, NULL);
+ zink_buffer_view_reference(screen, &buffer_view, NULL);
_mesa_set_remove(batch->bufferviews, entry);
}
get_buffer_view(struct zink_context *ctx, struct zink_resource *res, enum pipe_format format, uint32_t offset, uint32_t range)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
- struct zink_buffer_view *buffer_view;
+ struct zink_buffer_view *buffer_view = NULL;
VkBufferViewCreateInfo bvci = {};
bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
bvci.buffer = res->obj->buffer;
bvci.range = range;
uint32_t hash = hash_bufferview(&bvci);
- VkBufferView view;
- if (vkCreateBufferView(screen->dev, &bvci, NULL, &view) != VK_SUCCESS)
- return NULL;
- buffer_view = CALLOC_STRUCT(zink_buffer_view);
- if (!buffer_view) {
- vkDestroyBufferView(screen->dev, view, NULL);
- return NULL;
- }
- pipe_reference_init(&buffer_view->reference, 1);
- buffer_view->buffer_view = view;
- buffer_view->hash = hash;
+ simple_mtx_lock(&screen->bufferview_mtx);
+ struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->bufferview_cache, hash, &bvci);
+ if (he) {
+ buffer_view = he->data;
+ p_atomic_inc(&buffer_view->reference.count);
+ } else {
+ VkBufferView view;
+ if (vkCreateBufferView(screen->dev, &bvci, NULL, &view) != VK_SUCCESS)
+ goto out;
+ buffer_view = CALLOC_STRUCT(zink_buffer_view);
+ if (!buffer_view) {
+ vkDestroyBufferView(screen->dev, view, NULL);
+ goto out;
+ }
+ pipe_reference_init(&buffer_view->reference, 1);
+ buffer_view->bvci = bvci;
+ buffer_view->buffer_view = view;
+ buffer_view->hash = hash;
+ _mesa_hash_table_insert_pre_hashed(&screen->bufferview_cache, hash, &buffer_view->bvci, buffer_view);
+ }
+out:
+ simple_mtx_unlock(&screen->bufferview_mtx);
return buffer_view;
}
}
void
-zink_destroy_buffer_view(struct zink_context *ctx, struct zink_buffer_view *buffer_view)
-{
- vkDestroyBufferView(zink_screen(ctx->base.screen)->dev, buffer_view->buffer_view, NULL);
+zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view)
+{
+ simple_mtx_lock(&screen->bufferview_mtx);
+ struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->bufferview_cache, buffer_view->hash, &buffer_view->bvci);
+ assert(he);
+ _mesa_hash_table_remove(&screen->bufferview_cache, he);
+ simple_mtx_unlock(&screen->bufferview_mtx);
+ vkDestroyBufferView(screen->dev, buffer_view->buffer_view, NULL);
FREE(buffer_view);
}
struct zink_sampler_view *view = zink_sampler_view(pview);
zink_descriptor_set_refs_clear(&view->desc_set_refs, view);
if (pview->texture->target == PIPE_BUFFER)
- zink_buffer_view_reference(zink_context(pctx), &view->buffer_view, NULL);
+ zink_buffer_view_reference(zink_screen(pctx->screen), &view->buffer_view, NULL);
else {
struct pipe_surface *psurf = &view->image_view->base;
pipe_surface_reference(&psurf, NULL);
zink_descriptor_set_refs_clear(&image_view->desc_set_refs, image_view);
if (image_view->base.resource->target == PIPE_BUFFER)
- zink_buffer_view_reference(ctx, &image_view->buffer_view, NULL);
+ zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
else
pipe_surface_reference((struct pipe_surface**)&image_view->surface, NULL);
pipe_resource_reference(&image_view->base.resource, NULL);
struct zink_buffer_view {
struct pipe_reference reference;
+ VkBufferViewCreateInfo bvci;
VkBufferView buffer_view;
uint32_t hash;
uint32_t batch_uses;
unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags);
void
-zink_destroy_buffer_view(struct zink_context *ctx, struct zink_buffer_view *buffer_view);
+zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view);
void
debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr);
static inline void
-zink_buffer_view_reference(struct zink_context *ctx,
- struct zink_buffer_view **dst,
- struct zink_buffer_view *src)
+zink_buffer_view_reference(struct zink_screen *screen,
+ struct zink_buffer_view **dst,
+ struct zink_buffer_view *src)
{
struct zink_buffer_view *old_dst = dst ? *dst : NULL;
if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
(debug_reference_descriptor)debug_describe_zink_buffer_view))
- zink_destroy_buffer_view(ctx, old_dst);
+ zink_destroy_buffer_view(screen, old_dst);
if (dst) *dst = src;
}
return memcmp(a, b, sizeof(VkImageViewCreateInfo)) == 0;
}
+static bool
+equals_bvci(const void *a, const void *b)
+{
+ return memcmp(a, b, sizeof(VkBufferViewCreateInfo)) == 0;
+}
+
static VkDeviceSize
get_video_mem(struct zink_screen *screen)
{
pipe_surface_reference(&psurf, NULL);
}
+ hash_table_foreach(&screen->bufferview_cache, entry) {
+ struct zink_buffer_view *bv = (struct zink_buffer_view*)entry->data;
+ zink_buffer_view_reference(screen, &bv, NULL);
+ }
+
simple_mtx_destroy(&screen->surface_mtx);
+ simple_mtx_destroy(&screen->bufferview_mtx);
u_transfer_helper_destroy(pscreen->transfer_helper);
zink_screen_update_pipeline_cache(screen);
screen->total_mem = get_video_mem(screen);
simple_mtx_init(&screen->surface_mtx, mtx_plain);
+ simple_mtx_init(&screen->bufferview_mtx, mtx_plain);
_mesa_hash_table_init(&screen->surface_cache, screen, NULL, equals_ivci);
+ _mesa_hash_table_init(&screen->bufferview_cache, screen, NULL, equals_bvci);
return screen;