zink: collapse 'dedicated' allocation into zink_bo

this simplifies all the map and memory management code

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12421>
This commit is contained in:
Mike Blumenkrantz 2021-07-30 10:09:23 -04:00 committed by Marge Bot
parent defeecb816
commit 67239cf754
4 changed files with 30 additions and 101 deletions

View File

@ -231,7 +231,8 @@ bo_create_internal(struct zink_screen *screen,
uint64_t size,
unsigned alignment,
enum zink_heap heap,
unsigned flags)
unsigned flags,
const void *pNext)
{
struct zink_bo *bo;
bool init_pb_cache;
@ -255,8 +256,9 @@ bo_create_internal(struct zink_screen *screen,
pb_cache_init_entry(&screen->pb.bo_cache, bo->cache_entry, &bo->base, heap);
}
VkMemoryAllocateInfo mai = {0};
VkMemoryAllocateInfo mai;
mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
mai.pNext = pNext;
mai.allocationSize = size;
mai.memoryTypeIndex = screen->heap_map[heap];
if (screen->info.mem_props.memoryTypes[mai.memoryTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
@ -339,7 +341,7 @@ sparse_backing_alloc(struct zink_screen *screen, struct zink_bo *bo,
size = MAX2(size, ZINK_SPARSE_BUFFER_PAGE_SIZE);
buf = zink_bo_create(screen, size, ZINK_SPARSE_BUFFER_PAGE_SIZE,
bo->base.placement, ZINK_ALLOC_NO_SUBALLOC);
bo->base.placement, ZINK_ALLOC_NO_SUBALLOC, NULL);
if (!buf) {
FREE(best_backing->chunks);
FREE(best_backing);
@ -517,7 +519,7 @@ error_alloc_commitments:
}
struct pb_buffer *
zink_bo_create(struct zink_screen *screen, uint64_t size, unsigned alignment, enum zink_heap heap, enum zink_alloc_flag flags)
zink_bo_create(struct zink_screen *screen, uint64_t size, unsigned alignment, enum zink_heap heap, enum zink_alloc_flag flags, const void *pNext)
{
struct zink_bo *bo;
/* pull in sparse flag */
@ -606,12 +608,12 @@ no_slab:
}
/* Create a new one. */
bo = bo_create_internal(screen, size, alignment, heap, flags);
bo = bo_create_internal(screen, size, alignment, heap, flags, pNext);
if (!bo) {
/* Clean up buffer managers and try again. */
clean_up_buffer_managers(screen);
bo = bo_create_internal(screen, size, alignment, heap, flags);
bo = bo_create_internal(screen, size, alignment, heap, flags, pNext);
if (!bo)
return NULL;
}
@ -896,7 +898,7 @@ bo_slab_alloc(void *priv, unsigned heap, unsigned entry_size, unsigned group_ind
}
assert(slab_size != 0);
slab->buffer = zink_bo(zink_bo_create(screen, slab_size, slab_size, heap, 0));
slab->buffer = zink_bo(zink_bo_create(screen, slab_size, slab_size, heap, 0, NULL));
if (!slab->buffer)
goto fail;

View File

@ -175,7 +175,7 @@ void
zink_bo_deinit(struct zink_screen *screen);
struct pb_buffer *
zink_bo_create(struct zink_screen *screen, uint64_t size, unsigned alignment, enum zink_heap heap, enum zink_alloc_flag flags);
zink_bo_create(struct zink_screen *screen, uint64_t size, unsigned alignment, enum zink_heap heap, enum zink_alloc_flag flags, const void *pNext);
static inline uint64_t
zink_bo_get_offset(const struct zink_bo *bo)

View File

@ -88,10 +88,7 @@ zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_ob
util_dynarray_fini(&obj->tmp);
zink_descriptor_set_refs_clear(&obj->desc_set_refs, obj);
if (obj->dedicated)
vkFreeMemory(screen->dev, obj->mem, NULL);
else
zink_bo_unref(screen, obj->bo);
zink_bo_unref(screen, obj->bo);
FREE(obj);
}
@ -645,31 +642,19 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
mai.pNext = &memory_wsi_info;
}
if (!mai.pNext) {
unsigned alignment = MAX2(reqs.alignment, 256);
if (templ->usage == PIPE_USAGE_STAGING && obj->is_buffer)
alignment = MAX2(alignment, screen->info.props.limits.minMemoryMapAlignment);
obj->alignment = alignment;
obj->bo = zink_bo(zink_bo_create(screen, reqs.size, alignment, heap, 0));
if (!obj->bo)
goto fail2;
if (aflags == ZINK_ALLOC_SPARSE) {
obj->size = templ->width0;
} else {
obj->offset = zink_bo_get_offset(obj->bo);
obj->mem = zink_bo_get_mem(obj->bo);
obj->size = zink_bo_get_size(obj->bo);
}
unsigned alignment = MAX2(reqs.alignment, 256);
if (templ->usage == PIPE_USAGE_STAGING && obj->is_buffer)
alignment = MAX2(alignment, screen->info.props.limits.minMemoryMapAlignment);
obj->alignment = alignment;
obj->bo = zink_bo(zink_bo_create(screen, reqs.size, alignment, heap, mai.pNext ? ZINK_ALLOC_NO_SUBALLOC : 0, mai.pNext));
if (!obj->bo)
goto fail2;
if (aflags == ZINK_ALLOC_SPARSE) {
obj->size = templ->width0;
} else {
obj->dedicated = true;
obj->offset = 0;
obj->size = reqs.size;
}
/* TODO: sparse buffers should probably allocate multiple regions of memory instead of giant blobs? */
if (obj->dedicated && vkAllocateMemory(screen->dev, &mai, NULL, &obj->mem) != VK_SUCCESS) {
debug_printf("vkAllocateMemory failed\n");
goto fail2;
obj->offset = zink_bo_get_offset(obj->bo);
obj->mem = zink_bo_get_mem(obj->bo);
obj->size = zink_bo_get_size(obj->bo);
}
if (templ->target == PIPE_BUFFER) {
@ -683,7 +668,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
return obj;
fail3:
vkFreeMemory(screen->dev, obj->mem, NULL);
zink_bo_unref(screen, obj->bo);
fail2:
if (templ->target == PIPE_BUFFER)
@ -1042,30 +1027,14 @@ zink_resource_init_mem_range(struct zink_screen *screen, struct zink_resource_ob
static void *
map_resource(struct zink_screen *screen, struct zink_resource *res)
{
VkResult result = VK_SUCCESS;
if (res->obj->map)
return res->obj->map;
assert(res->obj->host_visible);
if (!res->obj->dedicated)
return zink_bo_map(screen, res->obj->bo);
result = vkMapMemory(screen->dev, res->obj->mem, res->obj->offset,
res->obj->size, 0, &res->obj->map);
if (zink_screen_handle_vkresult(screen, result))
return res->obj->map;
return NULL;
return zink_bo_map(screen, res->obj->bo);
}
static void
unmap_resource(struct zink_screen *screen, struct zink_resource *res)
{
if (!res->obj->dedicated)
zink_bo_unmap(screen, res->obj->bo);
else {
if (!p_atomic_dec_zero(&res->obj->map_count))
return;
vkUnmapMemory(screen->dev, res->obj->mem);
}
res->obj->map = NULL;
zink_bo_unmap(screen, res->obj->bo);
}
static void *
@ -1196,7 +1165,7 @@ buffer_transfer_map(struct zink_context *ctx, struct zink_resource *res, unsigne
VkDeviceSize offset = res->obj->offset + trans->offset;
VkMappedMemoryRange range = zink_resource_init_mem_range(screen, res->obj, offset, size);
if (vkInvalidateMappedMemoryRanges(screen->dev, 1, &range) != VK_SUCCESS) {
vkUnmapMemory(screen->dev, res->obj->mem);
zink_bo_unmap(screen, res->obj->bo);
return NULL;
}
}
@ -1326,8 +1295,6 @@ zink_transfer_map(struct pipe_context *pctx,
}
if (sizeof(void*) == 4)
trans->base.b.usage |= ZINK_MAP_TEMPORARY;
if (res->obj->dedicated)
p_atomic_inc(&res->obj->map_count);
}
if ((usage & PIPE_MAP_PERSISTENT) && !(usage & PIPE_MAP_COHERENT))
res->obj->persistent_maps++;

View File

@ -60,8 +60,6 @@ struct zink_resource_object {
struct zink_batch_usage *reads;
struct zink_batch_usage *writes;
void *map;
unsigned map_count;
struct util_dynarray tmp;
@ -82,7 +80,6 @@ struct zink_resource_object {
VkDeviceMemory mem;
VkDeviceSize offset, size, alignment;
bool dedicated;
bool host_visible;
bool coherent;
};
@ -189,17 +186,12 @@ zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource
static inline bool
zink_resource_usage_is_unflushed(const struct zink_resource *res)
{
if (res->obj->dedicated)
return zink_batch_usage_is_unflushed(res->obj->reads) ||
zink_batch_usage_is_unflushed(res->obj->writes);
return zink_bo_has_unflushed_usage(res->obj->bo);
}
static inline bool
zink_resource_usage_is_unflushed_write(const struct zink_resource *res)
{
if (res->obj->dedicated)
return zink_batch_usage_is_unflushed(res->obj->writes);
return zink_batch_usage_is_unflushed(res->obj->bo->writes);
}
@ -207,75 +199,43 @@ zink_resource_usage_is_unflushed_write(const struct zink_resource *res)
static inline bool
zink_resource_usage_matches(const struct zink_resource *res, const struct zink_batch_state *bs)
{
if (res->obj->dedicated)
return zink_batch_usage_matches(res->obj->reads, bs) ||
zink_batch_usage_matches(res->obj->writes, bs);
return zink_bo_usage_matches(res->obj->bo, bs);
}
static inline bool
zink_resource_has_usage(const struct zink_resource *res)
{
if (res->obj->dedicated)
return zink_batch_usage_exists(res->obj->reads) ||
zink_batch_usage_exists(res->obj->writes);
return zink_bo_has_usage(res->obj->bo);
}
static inline bool
zink_resource_has_unflushed_usage(const struct zink_resource *res)
{
if (res->obj->dedicated)
return zink_batch_usage_is_unflushed(res->obj->reads) ||
zink_batch_usage_is_unflushed(res->obj->writes);
return zink_bo_has_unflushed_usage(res->obj->bo);
}
static inline bool
zink_resource_usage_check_completion(struct zink_screen *screen, struct zink_resource *res, enum zink_resource_access access)
{
if (res->obj->dedicated) {
if (access & ZINK_RESOURCE_ACCESS_READ && !zink_screen_usage_check_completion(screen, res->obj->reads))
return false;
if (access & ZINK_RESOURCE_ACCESS_WRITE && !zink_screen_usage_check_completion(screen, res->obj->writes))
return false;
return true;
}
return zink_bo_usage_check_completion(screen, res->obj->bo, access);
}
static inline void
zink_resource_usage_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
{
if (res->obj->dedicated) {
if (access & ZINK_RESOURCE_ACCESS_READ)
zink_batch_usage_wait(ctx, res->obj->reads);
if (access & ZINK_RESOURCE_ACCESS_WRITE)
zink_batch_usage_wait(ctx, res->obj->writes);
} else
zink_bo_usage_wait(ctx, res->obj->bo, access);
zink_bo_usage_wait(ctx, res->obj->bo, access);
}
static inline void
zink_resource_usage_set(struct zink_resource *res, struct zink_batch_state *bs, bool write)
{
if (res->obj->dedicated) {
if (write)
zink_batch_usage_set(&res->obj->writes, bs);
else
zink_batch_usage_set(&res->obj->reads, bs);
} else
zink_bo_usage_set(res->obj->bo, bs, write);
zink_bo_usage_set(res->obj->bo, bs, write);
}
static inline void
zink_resource_object_usage_unset(struct zink_resource_object *obj, struct zink_batch_state *bs)
{
if (obj->dedicated) {
zink_batch_usage_unset(&obj->reads, bs);
zink_batch_usage_unset(&obj->writes, bs);
} else
zink_bo_usage_unset(obj->bo, bs);
zink_bo_usage_unset(obj->bo, bs);
}
#endif