Module: Mesa Branch: master Commit: f19946ca6ecd236592e136a2c45e9bce329f691c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f19946ca6ecd236592e136a2c45e9bce329f691c
Author: Mike Blumenkrantz <[email protected]> Date: Tue Jan 26 18:10:13 2021 -0500 zink: stop unmapping resources it turns out there's not actually a requirement that resources be unmapped, which means that a ton of overhead can be saved both in the unmap codepath (the cpu overhead here is pretty insane) and then also when mapping cached resource memory, as the map can now be added to the cache for immediate reuse as seen in radeonsi Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9980> --- src/gallium/drivers/zink/zink_resource.c | 44 ++++++++++++-------------------- src/gallium/drivers/zink/zink_resource.h | 2 -- src/gallium/drivers/zink/zink_screen.c | 5 ++-- src/gallium/drivers/zink/zink_screen.h | 6 +++++ 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index fa528812ea7..5d3ab47b9d1 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -125,8 +125,9 @@ cache_or_free_mem(struct zink_screen *screen, struct zink_resource_object *obj) util_dynarray_init(array, screen->resource_mem_cache); _mesa_hash_table_insert_pre_hashed(screen->resource_mem_cache, obj->mem_hash, mkey, array); } - if (util_dynarray_num_elements(array, VkDeviceMemory) < 5) { - util_dynarray_append(array, VkDeviceMemory, obj->mem); + if (util_dynarray_num_elements(array, struct mem_cache_entry) < 5) { + struct mem_cache_entry mc = { obj->mem, obj->map }; + util_dynarray_append(array, struct mem_cache_entry, mc); simple_mtx_unlock(&screen->mem_cache_mtx); return; } @@ -138,7 +139,6 @@ cache_or_free_mem(struct zink_screen *screen, struct zink_resource_object *obj) void zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *obj) { - assert(!obj->map_count); if (obj->is_buffer) { if (obj->sbuffer) vkDestroyBuffer(screen->dev, obj->sbuffer, NULL); @@ -146,7 +146,6 @@ zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_ob } else { vkDestroyImage(screen->dev, obj->image, NULL); } - simple_mtx_destroy(&obj->map_mtx); zink_descriptor_set_refs_clear(&obj->desc_set_refs, obj); cache_or_free_mem(screen, obj); @@ -363,7 +362,6 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t pipe_reference_init(&obj->reference, 1); util_dynarray_init(&obj->desc_set_refs.refs, NULL); - simple_mtx_init(&obj->map_mtx, mtx_plain); if (templ->target == PIPE_BUFFER) { VkBufferCreateInfo bci = create_bci(screen, templ, templ->bind); @@ -503,8 +501,10 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t struct hash_entry *he = _mesa_hash_table_search_pre_hashed(screen->resource_mem_cache, obj->mem_hash, &obj->mkey); struct util_dynarray *array = he ? (void*)he->data : NULL; - if (array && util_dynarray_num_elements(array, VkDeviceMemory)) { - obj->mem = util_dynarray_pop(array, VkDeviceMemory); + if (array && util_dynarray_num_elements(array, struct mem_cache_entry)) { + struct mem_cache_entry mc = util_dynarray_pop(array, struct mem_cache_entry); + obj->mem = mc.mem; + obj->map = mc.map; } simple_mtx_unlock(&screen->mem_cache_mtx); } @@ -776,26 +776,19 @@ get_most_recent_access(struct zink_resource *res, enum zink_resource_access flag static void * map_resource(struct zink_screen *screen, struct zink_resource *res) { - simple_mtx_lock(&res->obj->map_mtx); VkResult result = VK_SUCCESS; - if (!res->obj->map_count) - result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, - res->obj->size, 0, &res->obj->map); - res->obj->map_count++; - simple_mtx_unlock(&res->obj->map_mtx); + if (res->obj->map) + return res->obj->map; + result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset, + res->obj->size, 0, &res->obj->map); return result == VK_SUCCESS ? res->obj->map : NULL; } static void unmap_resource(struct zink_screen *screen, struct zink_resource *res) { - simple_mtx_lock(&res->obj->map_mtx); - res->obj->map_count--; - if (!res->obj->map_count) { - res->obj->map = NULL; - vkUnmapMemory(screen->dev, res->obj->mem); - } - simple_mtx_unlock(&res->obj->map_mtx); + res->obj->map = NULL; + vkUnmapMemory(screen->dev, res->obj->mem); } static void * @@ -805,6 +798,9 @@ buffer_transfer_map(struct zink_context *ctx, struct zink_resource *res, unsigne struct zink_screen *screen = zink_screen(ctx->base.screen); void *ptr = NULL; + if (res->base.is_user_ptr) + usage |= PIPE_MAP_PERSISTENT; + /* See if the buffer range being mapped has never been initialized, * in which case it can be mapped unsynchronized. */ if (!(usage & (PIPE_MAP_UNSYNCHRONIZED | TC_TRANSFER_MAP_NO_INFER_UNSYNCHRONIZED)) && @@ -859,10 +855,6 @@ buffer_transfer_map(struct zink_context *ctx, struct zink_resource *res, unsigne (struct pipe_resource **)&trans->staging_res, (void **)&ptr); res = zink_resource(trans->staging_res); trans->offset = offset; - /* replacing existing map, still need to increment refcount for tracking since - * unmaps will still occur - */ - p_atomic_inc(&res->obj->map_count); res->obj->map = ptr; } else { /* At this point, the buffer is always idle (we checked it above). */ @@ -1091,9 +1083,7 @@ zink_transfer_unmap(struct pipe_context *pctx, zink_transfer_flush_region(pctx, ptrans, &ptrans->box); } - if (trans->staging_res) { - unmap_resource(screen, zink_resource(trans->staging_res)); - } else + if (trans->base.b.usage & PIPE_MAP_ONCE && !trans->staging_res) unmap_resource(screen, res); if ((trans->base.b.usage & PIPE_MAP_PERSISTENT) && !(trans->base.b.usage & PIPE_MAP_COHERENT)) res->obj->persistent_maps--; diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 0602ba1b22d..61153b2e302 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -73,8 +73,6 @@ struct zink_resource_object { struct zink_batch_usage reads; struct zink_batch_usage writes; - simple_mtx_t map_mtx; - unsigned map_count; void *map; bool is_buffer; bool host_visible; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index d8d80545a5b..b984339a931 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -903,8 +903,9 @@ static void resource_cache_entry_destroy(struct zink_screen *screen, struct hash_entry *he) { struct util_dynarray *array = (void*)he->data; - util_dynarray_foreach(array, VkDeviceMemory, mem) - vkFreeMemory(screen->dev, *mem, NULL); + util_dynarray_foreach(array, struct mem_cache_entry, mc) { + vkFreeMemory(screen->dev, mc->mem, NULL); + } util_dynarray_fini(array); } diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index 8d3ff3a6a51..2e667a9d312 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -197,6 +197,12 @@ zink_screen(struct pipe_screen *pipe) return (struct zink_screen *)pipe; } + +struct mem_cache_entry { + VkDeviceMemory mem; + void *map; +}; + VkFormat zink_get_format(struct zink_screen *screen, enum pipe_format format); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
