diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2015-07-02 16:49:40 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2015-07-02 16:49:40 -0600 |
| commit | eadf998a558e2098f2fb2d04a6b7aba54a2f1f06 (patch) | |
| tree | a1fb828bd48c8e7afe48b18c0d02f6ab83a3c9c1 | |
| parent | 68f05a5a0aefff7fee8f59b23c69d1514078d399 (diff) | |
| download | usermoji-eadf998a558e2098f2fb2d04a6b7aba54a2f1f06.tar.xz | |
vulkan.h: V115 -- Reintroduce memory heaps & types. Bug #14082.
Reworked memory properties and types and added support for multiple
heaps.
| -rw-r--r-- | demos/cube.c | 44 | ||||
| -rw-r--r-- | demos/tri.c | 48 | ||||
| -rw-r--r-- | demos/vulkaninfo.c | 12 | ||||
| -rw-r--r-- | include/vulkan.h | 46 | ||||
| -rw-r--r-- | layers/mem_tracker.cpp | 27 | ||||
| -rw-r--r-- | layers/param_checker.cpp | 18 |
6 files changed, 146 insertions, 49 deletions
diff --git a/demos/cube.c b/demos/cube.c index ba241a09..15505ee6 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -303,6 +303,7 @@ struct demo { uint32_t graphics_queue_node_index; VkPhysicalDeviceProperties gpu_props; VkPhysicalDeviceQueueProperties *queue_props; + VkPhysicalDeviceMemoryProperties memory_properties; VkFramebuffer framebuffer; int width, height; @@ -370,6 +371,23 @@ struct demo { uint32_t current_buffer; }; +static VkResult memory_type_from_properties(struct demo *demo, uint32_t typeBits, VkFlags properties, uint32_t *typeIndex) +{ + // Search memtypes to find first index with those properties + for (uint32_t i = 0; i < 32; i++) { + if ((typeBits & 1) == 1) { + // Type is available, does it match user properties? + if ((demo->memory_properties.memoryTypes[i].propertyFlags & properties) == properties) { + *typeIndex = i; + return VK_SUCCESS; + } + } + typeBits >>= 1; + } + // No memory types matched, return failure + return VK_UNSUPPORTED; +} + static void demo_flush_init_cmd(struct demo *demo) { VkResult U_ASSERT_ONLY err; @@ -672,7 +690,7 @@ static void demo_prepare_depth(struct demo *demo) .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_DEVICE_ONLY, + .memoryTypeIndex = 0, }; VkDepthStencilViewCreateInfo view = { .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, @@ -696,7 +714,13 @@ static void demo_prepare_depth(struct demo *demo) err = vkGetObjectMemoryRequirements(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, &mem_reqs); - mem_alloc.allocationSize = mem_reqs.size; + + mem_alloc.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, + mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_ONLY, + &mem_alloc.memoryTypeIndex); + assert(!err); /* allocate memory */ err = vkAllocMemory(demo->device, &mem_alloc, &demo->depth.mem); @@ -912,7 +936,7 @@ static void demo_prepare_texture_image(struct demo *demo, .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = mem_props, + .memoryTypeIndex = 0, }; VkMemoryRequirements mem_reqs; @@ -927,6 +951,9 @@ static void demo_prepare_texture_image(struct demo *demo, mem_alloc.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, mem_props, &mem_alloc.memoryTypeIndex); + assert(!err); + /* allocate memory */ err = vkAllocMemory(demo->device, &mem_alloc, &(tex_obj->mem)); @@ -1091,7 +1118,7 @@ void demo_prepare_cube_data_buffer(struct demo *demo) .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memoryTypeIndex = 0, }; VkMemoryRequirements mem_reqs; size_t mem_reqs_size = sizeof(VkMemoryRequirements); @@ -1128,6 +1155,11 @@ void demo_prepare_cube_data_buffer(struct demo *demo) assert(!err && mem_reqs_size == sizeof(mem_reqs)); alloc_info.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, + mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &alloc_info.memoryTypeIndex); + assert(!err); err = vkAllocMemory(demo->device, &alloc_info, &(demo->uniform_data.mem)); assert(!err); @@ -2036,6 +2068,10 @@ static void demo_init_vk(struct demo *demo) demo->quit = false; demo->curFrame = 0; + + // Get Memory information and properties + err = vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); + assert(!err); } static void demo_init_connection(struct demo *demo) diff --git a/demos/tri.c b/demos/tri.c index 6e291a2c..b7bae339 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -172,10 +172,29 @@ struct demo { VkDescriptorPool desc_pool; VkDescriptorSet desc_set; + VkPhysicalDeviceMemoryProperties memory_properties; + bool quit; uint32_t current_buffer; }; +static VkResult memory_type_from_properties(struct demo *demo, uint32_t typeBits, VkFlags properties, uint32_t *typeIndex) +{ + // Search memtypes to find first index with those properties + for (uint32_t i = 0; i < 32; i++) { + if ((typeBits & 1) == 1) { + // Type is available, does it match user properties? + if ((demo->memory_properties.memoryTypes[i].propertyFlags & properties) == properties) { + *typeIndex = i; + return VK_SUCCESS; + } + } + typeBits >>= 1; + } + // No memory types matched, return failure + return VK_UNSUPPORTED; +} + static void demo_flush_init_cmd(struct demo *demo) { VkResult U_ASSERT_ONLY err; @@ -464,7 +483,7 @@ static void demo_prepare_depth(struct demo *demo) .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_DEVICE_ONLY, + .memoryTypeIndex = 0, }; VkDepthStencilViewCreateInfo view = { .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, @@ -486,9 +505,17 @@ static void demo_prepare_depth(struct demo *demo) &demo->depth.image); assert(!err); + /* get memory requirements for this object */ err = vkGetObjectMemoryRequirements(demo->device, VK_OBJECT_TYPE_IMAGE, demo->depth.image, &mem_reqs); + + /* select memory size and type */ mem_alloc.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, + mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_ONLY, + &mem_alloc.memoryTypeIndex); + assert(!err); /* allocate memory */ err = vkAllocMemory(demo->device, &mem_alloc, &demo->depth.mem); @@ -544,7 +571,7 @@ static void demo_prepare_texture_image(struct demo *demo, .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = mem_props, + .memoryTypeIndex = 0, }; VkMemoryRequirements mem_reqs; @@ -555,7 +582,10 @@ static void demo_prepare_texture_image(struct demo *demo, err = vkGetObjectMemoryRequirements(demo->device, VK_OBJECT_TYPE_IMAGE, tex_obj->image, &mem_reqs); - mem_alloc.allocationSize = mem_reqs.size; + + mem_alloc.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, mem_props, &mem_alloc.memoryTypeIndex); + assert(!err); /* allocate memory */ err = vkAllocMemory(demo->device, &mem_alloc, &tex_obj->mem); @@ -735,7 +765,7 @@ static void demo_prepare_vertices(struct demo *demo) .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, .pNext = NULL, .allocationSize = 0, - .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memoryTypeIndex = 0, }; VkMemoryRequirements mem_reqs; VkResult U_ASSERT_ONLY err; @@ -749,7 +779,12 @@ static void demo_prepare_vertices(struct demo *demo) err = vkGetObjectMemoryRequirements(demo->device, VK_OBJECT_TYPE_BUFFER, demo->vertices.buf, &mem_reqs); - mem_alloc.allocationSize = mem_reqs.size; + mem_alloc.allocationSize = mem_reqs.size; + err = memory_type_from_properties(demo, + mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &mem_alloc.memoryTypeIndex); + assert(!err); err = vkAllocMemory(demo->device, &mem_alloc, &demo->vertices.mem); assert(!err); @@ -1472,6 +1507,9 @@ static void demo_init_vk(struct demo *demo) // for now hardcode format till get WSI support demo->format = VK_FORMAT_B8G8R8A8_UNORM; + // Get Memory information and properties + err = vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); + assert(!err); } static void demo_init_connection(struct demo *demo) diff --git a/demos/vulkaninfo.c b/demos/vulkaninfo.c index 7ca85d94..44377205 100644 --- a/demos/vulkaninfo.c +++ b/demos/vulkaninfo.c @@ -696,7 +696,17 @@ static void app_gpu_dump_memory_props(const struct app_gpu *gpu) const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; printf("VkPhysicalDeviceMemoryProperties\n"); - printf("\tsupportsMigration = %u\n", props->supportsMigration); + printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); + for (uint32_t i = 0; i < props->memoryTypeCount; i++) { + printf("\tmemoryTypes[%u] : \n", i); + printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); + printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); + } + printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); + for (uint32_t i = 0; i < props->memoryHeapCount; i++) { + printf("\tmemoryHeaps[%u] : \n", i); + printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); + } } static void app_gpu_dump(const struct app_gpu *gpu) diff --git a/include/vulkan.h b/include/vulkan.h index 874caf42..2ed6096c 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -33,7 +33,7 @@ #include "vk_platform.h" // Vulkan API version supported by this file -#define VK_API_VERSION VK_MAKE_VERSION(0, 111, 0) +#define VK_API_VERSION VK_MAKE_VERSION(0, 115, 0) #ifdef __cplusplus extern "C" @@ -101,10 +101,11 @@ VK_DEFINE_NONDISP_SUBCLASS_HANDLE(VkRenderPass, VkNonDispatchable) #define VK_MAX_PHYSICAL_DEVICE_NAME 256 #define VK_MAX_EXTENSION_NAME 256 - -#define VK_LOD_CLAMP_NONE MAX_FLOAT -#define VK_LAST_MIP_LEVEL UINT32_MAX -#define VK_LAST_ARRAY_SLICE UINT32_MAX +#define VK_MAX_MEMORY_TYPES 32 +#define VK_MAX_MEMORY_HEAPS 16 +#define VK_LOD_CLAMP_NONE MAX_FLOAT +#define VK_LAST_MIP_LEVEL UINT32_MAX +#define VK_LAST_ARRAY_SLICE UINT32_MAX #define VK_WHOLE_SIZE UINT64_MAX @@ -1308,9 +1309,23 @@ typedef struct VkPhysicalDeviceQueueProperties_ bool32_t supportsTimestamps; } VkPhysicalDeviceQueueProperties; +typedef struct VkMemoryType_ +{ + VkMemoryPropertyFlags propertyFlags; // Memory properties of this memory type + uint32_t heapIndex; // Index of the memory heap allocations of this memory type are taken from +} VkMemoryType; + +typedef struct VkMemoryHeap_ +{ + VkDeviceSize size; // Available memory in the heap +} VkMemoryHeap; + typedef struct VkPhysicalDeviceMemoryProperties_ { - bool32_t supportsMigration; + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; } VkPhysicalDeviceMemoryProperties; typedef struct VkMemoryAllocInfo_ @@ -1318,18 +1333,9 @@ typedef struct VkMemoryAllocInfo_ VkStructureType sType; // Must be VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO const void* pNext; // Pointer to next structure VkDeviceSize allocationSize; // Size of memory allocation - VkMemoryPropertyFlags memProps; // Memory property flags + uint32_t memoryTypeIndex; // Index of the memory type to allocate from } VkMemoryAllocInfo; -typedef struct VkMemoryRequirements_ -{ - VkDeviceSize size; // Specified in bytes - VkDeviceSize alignment; // Specified in bytes - VkDeviceSize granularity; // Granularity at which memory can be bound to resource sub-ranges specified in bytes (usually the page size) - VkMemoryPropertyFlags memPropsAllowed; // Allowed memory property flags - VkMemoryPropertyFlags memPropsRequired; // Required memory property flags -} VkMemoryRequirements; - typedef struct VkMappedMemoryRange_ { VkStructureType sType; // Must be VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE @@ -1339,6 +1345,14 @@ typedef struct VkMappedMemoryRange_ VkDeviceSize size; // Size of the range within the mapped memory } VkMappedMemoryRange; +typedef struct VkMemoryRequirements_ +{ + VkDeviceSize size; // Specified in bytes + VkDeviceSize alignment; // Specified in bytes + VkDeviceSize granularity; // Granularity at which memory can be bound to resource sub-ranges specified in bytes (usually the page size) + uint32_t memoryTypeBits; // Bitfield of the allowed memory type indices into memoryTypes[] for this object +} VkMemoryRequirements; + typedef struct VkFormatProperties_ { VkFormatFeatureFlags linearTilingFeatures; // Format features in case of linear tiling diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index 789899ab..6b5ead3a 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -58,6 +58,7 @@ static std::unordered_map<void *, struct devExts> deviceExtMap; static std::unordered_map<void *, layer_data *> layer_data_map; static device_table_map mem_tracker_device_table_map; static instance_table_map mem_tracker_instance_table_map; +static VkPhysicalDeviceMemoryProperties memProps; // TODO : This can be much smarter, using separate locks for separate global data static int globalLockInitialized = 0; @@ -828,6 +829,9 @@ static void init_mem_tracker( loader_platform_thread_create_mutex(&globalLock); globalLockInitialized = 1; } + + // Zero out memory property data + memset(&memProps, 0, sizeof(VkPhysicalDeviceMemoryProperties)); } // hook DestroyInstance to remove tableInstanceMap entry @@ -947,10 +951,20 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice( return result; } -struct extProps { - uint32_t version; - const char * const name; -}; +VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceMemoryProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties *pMemoryProperties) +{ + VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(mem_tracker_instance_table_map, physicalDevice); + VkResult result = pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties); + if (result == VK_SUCCESS) { + // copy mem props to local var... + memcpy(&memProps, pMemoryProperties, sizeof(VkPhysicalDeviceMemoryProperties)); + } + return result; +} + + #define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2 static const VkExtensionProperties mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = { { @@ -1113,7 +1127,8 @@ VK_LAYER_EXPORT VkResult VKAPI vkMapMemory( // TODO : Track when memory is mapped loader_platform_thread_lock_mutex(&globalLock); MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(mem); - if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) { + if ((memProps.memoryTypes[pMemObj->allocInfo.memoryTypeIndex].propertyFlags & + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) { log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_STATE, "MEM", "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %p", (void*)mem); } @@ -2306,6 +2321,8 @@ VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr( return (void *) vkDestroyInstance; if (!strcmp(funcName, "vkCreateInstance")) return (void*) vkCreateInstance; + if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties")) + return (void*) vkGetPhysicalDeviceMemoryProperties; if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionCount")) return (void*) vkGetGlobalExtensionCount; if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionProperties")) diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index 8fa33ceb..f77bd47d 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -2346,12 +2346,6 @@ void PreAllocMemory( "vkAllocMemory parameter, VkStructureType pAllocInfo->sType, is unrecognized enumerator"); return; } - if(!ValidateEnumerator((VkMemoryPropertyFlagBits)pAllocInfo->memProps)) - { - std::string reason = "vkAllocMemory parameter, VkMemoryPropertyFlags pAllocInfo->memProps, is " + EnumeratorString((VkMemoryPropertyFlagBits)pAllocInfo->memProps); - log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", reason.c_str()); - return; - } } void PostAllocMemory( @@ -2878,18 +2872,6 @@ void PostGetObjectMemoryRequirements( "vkGetObjectMemoryRequirements parameter, VkMemoryRequirements* pMemoryRequirements, is null pointer"); return; } - if(!ValidateEnumerator((VkMemoryPropertyFlagBits)pMemoryRequirements->memPropsAllowed)) - { - std::string reason = "vkGetObjectMemoryRequirements parameter, VkMemoryPropertyFlags pMemoryRequirements->memPropsAllowed, is " + EnumeratorString((VkMemoryPropertyFlagBits)pMemoryRequirements->memPropsAllowed); - log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", reason.c_str()); - return; - } - if(!ValidateEnumerator((VkMemoryPropertyFlagBits)pMemoryRequirements->memPropsRequired)) - { - std::string reason = "vkGetObjectMemoryRequirements parameter, VkMemoryPropertyFlags pMemoryRequirements->memPropsRequired, is " + EnumeratorString((VkMemoryPropertyFlagBits)pMemoryRequirements->memPropsRequired); - log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", reason.c_str()); - return; - } if(result != VK_SUCCESS) { |
