From c3c61d210f0929a71e031dfb3830bf39cee583a4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg=20Kristensen?= Date: Thu, 3 Dec 2015 23:09:09 -0800 Subject: [PATCH] vk: Expose two memory types for non-LLC GPUs We're required to expose a host-visible, coherent memory type. On big core GPUs that share, LLC, we can expose one such memory type that's also cached. However, on non-LLC GPUs we can't both be cached and coherent. Thus, we expose both the required coherent type and the cached but non-coherent combination. --- src/vulkan/anv_device.c | 46 +++++++++++++++++++++++++++++++--------- src/vulkan/anv_private.h | 1 + 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index 384a457742f..a8bc409144d 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -553,15 +553,38 @@ void anv_GetPhysicalDeviceMemoryProperties( */ heap_size = 3 * physical_device->aperture_size / 4; - /* The property flags below are valid only for llc platforms. */ - pMemoryProperties->memoryTypeCount = 1; - pMemoryProperties->memoryTypes[0] = (VkMemoryType) { - .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - .heapIndex = 1, - }; + if (physical_device->info->has_llc) { + /* Big core GPUs share LLC with the CPU and thus one memory type can be + * both cached and coherent at the same time. + */ + pMemoryProperties->memoryTypeCount = 1; + pMemoryProperties->memoryTypes[0] = (VkMemoryType) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + .heapIndex = 1, + }; + } else { + /* The spec requires that we expose a host-visible, coherent memory + * type, but Atom GPUs don't share LLC. Thus we offer two memory types + * to give the application a choice between cached, but not coherent and + * coherent but uncached (WC though). + */ + pMemoryProperties->memoryTypeCount = 2; + pMemoryProperties->memoryTypes[0] = (VkMemoryType) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + .heapIndex = 1, + }; + pMemoryProperties->memoryTypes[1] = (VkMemoryType) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + .heapIndex = 1, + }; + } pMemoryProperties->memoryHeapCount = 1; pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) { @@ -976,7 +999,8 @@ VkResult anv_AllocateMemory( assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); /* We support exactly one memory heap. */ - assert(pAllocateInfo->memoryTypeIndex == 0); + assert(pAllocateInfo->memoryTypeIndex == 0 || + (!device->info.has_llc && pAllocateInfo->memoryTypeIndex < 2)); /* FINISHME: Fail if allocation request exceeds heap size. */ @@ -989,6 +1013,8 @@ VkResult anv_AllocateMemory( if (result != VK_SUCCESS) goto fail; + mem->type_index = pAllocateInfo->memoryTypeIndex; + *pMem = anv_device_memory_to_handle(mem); return VK_SUCCESS; diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 3c0441b66f3..7c8cf241624 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -784,6 +784,7 @@ __gen_combine_address(struct anv_batch *batch, void *location, struct anv_device_memory { struct anv_bo bo; + uint32_t type_index; VkDeviceSize map_size; void * map; }; -- 2.30.2