summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/zink/zink_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/zink/zink_resource.c')
-rw-r--r--src/gallium/drivers/zink/zink_resource.c168
1 files changed, 47 insertions, 121 deletions
diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c
index 3a706a9fc9c..5080cc13429 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -78,49 +78,6 @@ debug_describe_zink_resource_object(char *buf, const struct zink_resource_object
sprintf(buf, "zink_resource_object");
}
-static uint32_t
-mem_hash(const void *key)
-{
- const struct mem_key *mkey = key;
- return _mesa_hash_data(&mkey->key, sizeof(mkey->key));
-}
-
-static bool
-mem_equals(const void *a, const void *b)
-{
- const struct mem_key *ma = a;
- const struct mem_key *mb = b;
- return !memcmp(&ma->key, &mb->key, sizeof(ma->key));
-}
-
-static void
-cache_or_free_mem(struct zink_screen *screen, struct zink_resource_object *obj)
-{
- if (obj->mkey.key.heap_index != UINT32_MAX) {
- simple_mtx_lock(&screen->mem[obj->mkey.key.heap_index].mem_cache_mtx);
- struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->mem[obj->mkey.key.heap_index].resource_mem_cache, obj->mem_hash, &obj->mkey);
- assert(he);
- struct util_dynarray *array = he->data;
- struct mem_key *mkey = (void*)he->key;
-
- unsigned seen = mkey->seen_count;
- mkey->seen_count--;
- if (util_dynarray_num_elements(array, struct mem_cache_entry) < seen) {
- struct mem_cache_entry mc = { obj->mem, obj->map };
- screen->mem[obj->mkey.key.heap_index].mem_cache_size += obj->size;
- if (sizeof(void*) == 4 && obj->map) {
- vkUnmapMemory(screen->dev, obj->mem);
- mc.map = NULL;
- }
- util_dynarray_append(array, struct mem_cache_entry, mc);
- simple_mtx_unlock(&screen->mem[obj->mkey.key.heap_index].mem_cache_mtx);
- return;
- }
- simple_mtx_unlock(&screen->mem[obj->mkey.key.heap_index].mem_cache_mtx);
- }
- vkFreeMemory(screen->dev, obj->mem, NULL);
-}
-
void
zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *obj)
{
@@ -134,7 +91,10 @@ 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);
- cache_or_free_mem(screen, obj);
+ if (obj->dedicated)
+ vkFreeMemory(screen->dev, obj->mem, NULL);
+ else
+ zink_bo_unref(screen, obj->bo);
FREE(obj);
}
@@ -155,38 +115,6 @@ zink_resource_destroy(struct pipe_screen *pscreen,
FREE(res);
}
-static uint32_t
-get_memory_type_index(struct zink_screen *screen,
- const VkMemoryRequirements *reqs,
- VkMemoryPropertyFlags props)
-{
- int32_t idx = -1;
- for (uint32_t i = 0u; i < VK_MAX_MEMORY_TYPES; i++) {
- if (((reqs->memoryTypeBits >> i) & 1) == 1) {
- if ((screen->info.mem_props.memoryTypes[i].propertyFlags & props) == props) {
- if (!(props & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) &&
- screen->info.mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
- idx = i;
- } else
- return i;
- }
- }
- }
- if (idx >= 0)
- return idx;
-
- if (props & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
- /* if no suitable cached memory can be found, fall back
- * to non-cached memory instead.
- */
- return get_memory_type_index(screen, reqs,
- props & ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
- }
-
- unreachable("Unsupported memory-type");
- return 0;
-}
-
static VkImageAspectFlags
aspect_from_format(enum pipe_format fmt)
{
@@ -636,17 +564,31 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
flags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
VkMemoryAllocateInfo mai = {0};
+ enum zink_alloc_flag aflags = templ->flags & PIPE_RESOURCE_FLAG_SPARSE ? ZINK_ALLOC_SPARSE : 0;
mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
mai.allocationSize = reqs.size;
- mai.memoryTypeIndex = get_memory_type_index(screen, &reqs, flags);
+ enum zink_heap heap = zink_heap_from_domain_flags(flags, aflags);
+ mai.memoryTypeIndex = screen->heap_map[heap];
+ if (unlikely(!(reqs.memoryTypeBits & BITFIELD_BIT(mai.memoryTypeIndex)))) {
+ /* not valid based on reqs; demote to more compatible type */
+ switch (heap) {
+ case ZINK_HEAP_DEVICE_LOCAL_VISIBLE:
+ heap = ZINK_HEAP_DEVICE_LOCAL;
+ break;
+ case ZINK_HEAP_HOST_VISIBLE_CACHED:
+ heap = ZINK_HEAP_HOST_VISIBLE_ANY;
+ break;
+ default:
+ break;
+ }
+ mai.memoryTypeIndex = screen->heap_map[heap];
+ assert(reqs.memoryTypeBits & BITFIELD_BIT(mai.memoryTypeIndex));
+ }
VkMemoryType mem_type = screen->info.mem_props.memoryTypes[mai.memoryTypeIndex];
obj->coherent = mem_type.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
if (!(templ->flags & PIPE_RESOURCE_FLAG_SPARSE))
obj->host_visible = mem_type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
- if (templ->target == PIPE_BUFFER && !obj->coherent && obj->host_visible) {
- mai.allocationSize = reqs.size = align(reqs.size, screen->info.props.limits.nonCoherentAtomSize);
- }
VkMemoryDedicatedAllocateInfo ded_alloc_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
@@ -695,46 +637,33 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
mai.pNext = &memory_wsi_info;
}
- if (!mai.pNext && !(templ->flags & (PIPE_RESOURCE_FLAG_MAP_COHERENT | PIPE_RESOURCE_FLAG_SPARSE))) {
- obj->mkey.key.reqs = reqs;
- obj->mkey.key.heap_index = mai.memoryTypeIndex;
- obj->mem_hash = mem_hash(&obj->mkey);
- simple_mtx_lock(&screen->mem[mai.memoryTypeIndex].mem_cache_mtx);
-
- struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->mem[mai.memoryTypeIndex].resource_mem_cache, obj->mem_hash, &obj->mkey);
- struct mem_key *mkey;
- if (he) {
- struct util_dynarray *array = he->data;
- mkey = (void*)he->key;
- 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;
- screen->mem[mai.memoryTypeIndex].mem_cache_size -= reqs.size;
- screen->mem[mai.memoryTypeIndex].mem_cache_count--;
- }
+ 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 {
- mkey = ralloc(screen, struct mem_key);
- memcpy(&mkey->key, &obj->mkey.key, sizeof(obj->mkey.key));
- mkey->seen_count = 0;
- struct util_dynarray *array = rzalloc(screen, struct util_dynarray);
- util_dynarray_init(array, screen);
- _mesa_hash_table_insert_pre_hashed(&screen->mem[mai.memoryTypeIndex].resource_mem_cache, obj->mem_hash, mkey, array);
+ obj->offset = zink_bo_get_offset(obj->bo);
+ obj->mem = zink_bo_get_mem(obj->bo);
+ obj->size = zink_bo_get_size(obj->bo);
}
- mkey->seen_count++;
- simple_mtx_unlock(&screen->mem[mai.memoryTypeIndex].mem_cache_mtx);
- } else
- obj->mkey.key.heap_index = UINT32_MAX;
+ } 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->mem && vkAllocateMemory(screen->dev, &mai, NULL, &obj->mem) != VK_SUCCESS) {
+ if (obj->dedicated && vkAllocateMemory(screen->dev, &mai, NULL, &obj->mem) != VK_SUCCESS) {
debug_printf("vkAllocateMemory failed\n");
goto fail2;
}
- obj->offset = 0;
- obj->size = reqs.size;
-
if (templ->target == PIPE_BUFFER) {
if (!(templ->flags & PIPE_RESOURCE_FLAG_SPARSE))
if (vkBindBufferMemory(screen->dev, obj->buffer, obj->mem, obj->offset) != VK_SUCCESS)
@@ -1109,6 +1038,8 @@ map_resource(struct zink_screen *screen, struct zink_resource *res)
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))
@@ -1120,7 +1051,10 @@ static void
unmap_resource(struct zink_screen *screen, struct zink_resource *res)
{
res->obj->map = NULL;
- vkUnmapMemory(screen->dev, res->obj->mem);
+ if (!res->obj->dedicated)
+ zink_bo_unmap(screen, res->obj->bo);
+ else
+ vkUnmapMemory(screen->dev, res->obj->mem);
}
static void *
@@ -1672,14 +1606,6 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
pscreen->resource_from_handle = zink_resource_from_handle;
}
pscreen->resource_get_param = zink_resource_get_param;
-
- screen->mem = rzalloc_array(screen, struct zink_mem_cache, screen->info.mem_props.memoryTypeCount);
- if (!screen->mem)
- return false;
- for (uint32_t i = 0; i < screen->info.mem_props.memoryTypeCount; ++i) {
- simple_mtx_init(&screen->mem[i].mem_cache_mtx, mtx_plain);
- _mesa_hash_table_init(&screen->mem[i].resource_mem_cache, screen, mem_hash, mem_equals);
- }
return true;
}