diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 026c3660f90..ae15191dd42 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -1522,6 +1522,9 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie create_info.usage = p_usage; create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + VmaMemoryUsage vma_usage = VMA_MEMORY_USAGE_UNKNOWN; + uint32_t vma_flags_to_remove = 0; + VmaAllocationCreateInfo alloc_create_info = {}; switch (p_allocation_type) { case MEMORY_ALLOCATION_TYPE_CPU: { @@ -1531,15 +1534,19 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie // Looks like a staging buffer: CPU maps, writes sequentially, then GPU copies to VRAM. alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + vma_flags_to_remove |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; } if (is_dst && !is_src) { // Looks like a readback buffer: GPU copies from VRAM, then CPU maps and reads. alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + vma_flags_to_remove |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; } + vma_usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; alloc_create_info.requiredFlags = (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } break; case MEMORY_ALLOCATION_TYPE_GPU: { + vma_usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; alloc_create_info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; if (p_size <= SMALL_ALLOCATION_MAX_SIZE) { uint32_t mem_type_index = 0; @@ -1553,12 +1560,19 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie VmaAllocation allocation = nullptr; VmaAllocationInfo alloc_info = {}; - VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer); - ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); - err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info); - ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); - err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, nullptr); - ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) { + alloc_create_info.preferredFlags &= ~vma_flags_to_remove; + alloc_create_info.usage = vma_usage; + VkResult err = vmaCreateBuffer(allocator, &create_info, &alloc_create_info, &vk_buffer, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + } else { + VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, nullptr); + ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + "."); + } // Bookkeep. BufferInfo *buf_info = VersatileResource::allocate(resources_allocator); @@ -1593,8 +1607,12 @@ void RenderingDeviceDriverVulkan::buffer_free(BufferID p_buffer) { vkDestroyBufferView(vk_device, buf_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW)); } - vkDestroyBuffer(vk_device, buf_info->vk_buffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); - vmaFreeMemory(allocator, buf_info->allocation.handle); + if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) { + vmaDestroyBuffer(allocator, buf_info->vk_buffer, buf_info->allocation.handle); + } else { + vkDestroyBuffer(vk_device, buf_info->vk_buffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); + vmaFreeMemory(allocator, buf_info->allocation.handle); + } VersatileResource::free(resources_allocator, buf_info); } @@ -1808,12 +1826,18 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & VmaAllocation allocation = nullptr; VmaAllocationInfo alloc_info = {}; - VkResult err = vkCreateImage(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE), &vk_image); - ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + "."); - err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info); - ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + "."); - err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, nullptr); - ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + "."); + if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) { + alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + VkResult err = vmaCreateImage(allocator, &create_info, &alloc_create_info, &vk_image, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, TextureID(), "vmaCreateImage failed with error " + itos(err) + "."); + } else { + VkResult err = vkCreateImage(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE), &vk_image); + ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + "."); + err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info); + ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + "."); + err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, nullptr); + ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + "."); + } // Create view. @@ -1845,10 +1869,15 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat & } VkImageView vk_image_view = VK_NULL_HANDLE; - err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view); + VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view); if (err) { - vkDestroyImage(vk_device, vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE)); - vmaFreeMemory(allocator, allocation); + if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) { + vmaDestroyImage(allocator, vk_image, allocation); + } else { + vkDestroyImage(vk_device, vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE)); + vmaFreeMemory(allocator, allocation); + } + ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + "."); } @@ -2023,8 +2052,12 @@ void RenderingDeviceDriverVulkan::texture_free(TextureID p_texture) { TextureInfo *tex_info = (TextureInfo *)p_texture.id; vkDestroyImageView(vk_device, tex_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW)); if (tex_info->allocation.handle) { - vkDestroyImage(vk_device, tex_info->vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); - vmaFreeMemory(allocator, tex_info->allocation.handle); + if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) { + vmaDestroyImage(allocator, tex_info->vk_view_create_info.image, tex_info->allocation.handle); + } else { + vkDestroyImage(vk_device, tex_info->vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER)); + vmaFreeMemory(allocator, tex_info->allocation.handle); + } } VersatileResource::free(resources_allocator, tex_info); }