diff --git a/src/allocator.cpp b/src/allocator.cpp index 42464633c..64a3b0348 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -248,7 +248,8 @@ void UnlockedPoolAllocator::fastFree(void* ptr) #if NCNN_VULKAN VkAllocator::VkAllocator(const VulkanDevice* _vkdev) : vkdev(_vkdev) { - memory_type_index = (uint32_t)-1; + buffer_memory_type_index = (uint32_t)-1; + image_memory_type_index = (uint32_t)-1; mappable = false; coherent = false; } @@ -330,7 +331,7 @@ VkBuffer VkAllocator::create_buffer(size_t size, VkBufferUsageFlags usage) return buffer; } -VkDeviceMemory VkAllocator::allocate_memory(size_t size) +VkDeviceMemory VkAllocator::allocate_memory(size_t size, uint32_t memory_type_index) { VkMemoryAllocateInfo memoryAllocateInfo; memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -349,7 +350,7 @@ VkDeviceMemory VkAllocator::allocate_memory(size_t size) return memory; } -VkDeviceMemory VkAllocator::allocate_dedicated_memory(size_t size, VkImage image, VkBuffer buffer) +VkDeviceMemory VkAllocator::allocate_dedicated_memory(size_t size, uint32_t memory_type_index, VkImage image, VkBuffer buffer) { VkMemoryAllocateInfo memoryAllocateInfo; memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -583,24 +584,24 @@ VkBufferMemory* VkBlobAllocator::fastMalloc(size_t size) vkGetBufferMemoryRequirements(vkdev->vkdevice(), block->buffer, &memoryRequirements); // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (buffer_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(buffer_memory_type_index); + coherent = vkdev->is_coherent(buffer_memory_type_index); } - block->memory = allocate_memory(memoryRequirements.size); + block->memory = allocate_memory(memoryRequirements.size, buffer_memory_type_index); // ignore memoryRequirements.alignment as we always bind at zero offset vkBindBufferMemory(vkdev->vkdevice(), block->buffer, block->memory, 0); @@ -862,28 +863,28 @@ VkImageMemory* VkBlobAllocator::fastMalloc(int dims, int w, int h, int c, size_t } // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (image_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(image_memory_type_index); + coherent = vkdev->is_coherent(image_memory_type_index); } // create new block size_t new_block_size = std::max(block_size, aligned_size); // bind at memory offset - ptr->memory = allocate_memory(new_block_size); + ptr->memory = allocate_memory(new_block_size, image_memory_type_index); ptr->bind_offset = 0; ptr->bind_capacity = aligned_size; @@ -1138,24 +1139,24 @@ VkBufferMemory* VkWeightAllocator::fastMalloc(size_t size) if (dedicatedAllocation) { // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (buffer_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(buffer_memory_type_index); + coherent = vkdev->is_coherent(buffer_memory_type_index); } - block->memory = allocate_dedicated_memory(memoryRequirements2.memoryRequirements.size, 0, block->buffer); + block->memory = allocate_dedicated_memory(memoryRequirements2.memoryRequirements.size, buffer_memory_type_index, 0, block->buffer); // ignore memoryRequirements2.memoryRequirements.alignment as we always bind at zero offset vkBindBufferMemory(vkdev->vkdevice(), block->buffer, block->memory, 0); @@ -1187,24 +1188,24 @@ VkBufferMemory* VkWeightAllocator::fastMalloc(size_t size) vkGetBufferMemoryRequirements(vkdev->vkdevice(), block->buffer, &memoryRequirements); // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (buffer_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(buffer_memory_type_index); + coherent = vkdev->is_coherent(buffer_memory_type_index); } - block->memory = allocate_memory(memoryRequirements.size); + block->memory = allocate_memory(memoryRequirements.size, buffer_memory_type_index); // ignore memoryRequirements.alignment as we always bind at zero offset vkBindBufferMemory(vkdev->vkdevice(), block->buffer, block->memory, 0); @@ -1355,25 +1356,25 @@ VkImageMemory* VkWeightAllocator::fastMalloc(int dims, int w, int h, int c, size if (dedicatedAllocation) { // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (image_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements2.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(image_memory_type_index); + coherent = vkdev->is_coherent(image_memory_type_index); } // bind memory - ptr->memory = allocate_dedicated_memory(memoryRequirements2.memoryRequirements.size, ptr->image, 0); + ptr->memory = allocate_dedicated_memory(memoryRequirements2.memoryRequirements.size, image_memory_type_index, ptr->image, 0); ptr->bind_offset = 0; ptr->bind_capacity = memoryRequirements2.memoryRequirements.size; @@ -1449,28 +1450,28 @@ VkImageMemory* VkWeightAllocator::fastMalloc(int dims, int w, int h, int c, size } // setup memory type and alignment - if (memory_type_index == (uint32_t)-1) + if (image_memory_type_index == (uint32_t)-1) { if (vkdev->info.type == 1) { // integrated gpu, prefer unified memory - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } else { // discrete gpu, device local - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + image_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } - mappable = vkdev->is_mappable(memory_type_index); - coherent = vkdev->is_coherent(memory_type_index); + mappable = vkdev->is_mappable(image_memory_type_index); + coherent = vkdev->is_coherent(image_memory_type_index); } // create new block size_t new_block_size = std::max(block_size, aligned_size); // bind at memory offset - ptr->memory = allocate_memory(new_block_size); + ptr->memory = allocate_memory(new_block_size, image_memory_type_index); ptr->bind_offset = 0; ptr->bind_capacity = aligned_size; @@ -1579,12 +1580,12 @@ VkBufferMemory* VkStagingAllocator::fastMalloc(size_t size) vkGetBufferMemoryRequirements(vkdev->vkdevice(), ptr->buffer, &memoryRequirements); // setup memory type - if (memory_type_index == (uint32_t)-1) + if (buffer_memory_type_index == (uint32_t)-1) { - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } - ptr->memory = allocate_memory(memoryRequirements.size); + ptr->memory = allocate_memory(memoryRequirements.size, buffer_memory_type_index); // ignore memoryRequirements.alignment as we always bind at zero offset vkBindBufferMemory(vkdev->vkdevice(), ptr->buffer, ptr->memory, 0); @@ -1691,12 +1692,12 @@ VkBufferMemory* VkWeightStagingAllocator::fastMalloc(size_t size) vkGetBufferMemoryRequirements(vkdev->vkdevice(), ptr->buffer, &memoryRequirements); // setup memory type - if (memory_type_index == (uint32_t)-1) + if (buffer_memory_type_index == (uint32_t)-1) { - memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + buffer_memory_type_index = vkdev->find_memory_index(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } - ptr->memory = allocate_memory(memoryRequirements.size); + ptr->memory = allocate_memory(memoryRequirements.size, buffer_memory_type_index); // ignore memoryRequirements.alignment as we always bind at zero offset vkBindBufferMemory(vkdev->vkdevice(), ptr->buffer, ptr->memory, 0); @@ -1783,9 +1784,9 @@ VkImageMemory* VkAndroidHardwareBufferImageAllocator::fastMalloc(int /*dims*/, i } // setup memory type - if (memory_type_index == (uint32_t)-1) + if (image_memory_type_index == (uint32_t)-1) { - memory_type_index = vkdev->find_memory_index(bufferProperties.memoryTypeBits, 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + image_memory_type_index = vkdev->find_memory_index(bufferProperties.memoryTypeBits, 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } VkImportAndroidHardwareBufferInfoANDROID importAndroidHardwareBufferInfo; @@ -1803,7 +1804,7 @@ VkImageMemory* VkAndroidHardwareBufferImageAllocator::fastMalloc(int /*dims*/, i memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memoryAllocateInfo.pNext = &memoryDedicatedAllocateInfo; memoryAllocateInfo.allocationSize = bufferProperties.allocationSize; - memoryAllocateInfo.memoryTypeIndex = memory_type_index; + memoryAllocateInfo.memoryTypeIndex = image_memory_type_index; VkDeviceMemory memory = 0; ret = vkAllocateMemory(vkdev->vkdevice(), &memoryAllocateInfo, 0, &memory); diff --git a/src/allocator.h b/src/allocator.h index 9a1807002..3e1afc7d6 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -249,14 +249,15 @@ public: public: const VulkanDevice* vkdev; - uint32_t memory_type_index; + uint32_t buffer_memory_type_index; + uint32_t image_memory_type_index; bool mappable; bool coherent; protected: VkBuffer create_buffer(size_t size, VkBufferUsageFlags usage); - VkDeviceMemory allocate_memory(size_t size); - VkDeviceMemory allocate_dedicated_memory(size_t size, VkImage image, VkBuffer buffer); + VkDeviceMemory allocate_memory(size_t size, uint32_t memory_type_index); + VkDeviceMemory allocate_dedicated_memory(size_t size, uint32_t memory_type_index, VkImage image, VkBuffer buffer); VkImage create_image(VkImageType type, int width, int height, int depth, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage); VkImageView create_imageview(VkImageViewType type, VkImage image, VkFormat format);