diff options
| author | Robin Kertels <robin.kertels@gmail.com> | 2022-10-07 23:48:11 +0200 |
|---|---|---|
| committer | Robin Kertels <robin.kertels@gmail.com> | 2022-10-23 03:21:29 +0200 |
| commit | 1ba58e83cafaeefee8cb968ad6789ac7d3fc3060 (patch) | |
| tree | 5e8f241dfdb98584b211344608c5b00aa334b8d9 /Source/Core/VideoBackends/Vulkan/VKTexture.cpp | |
| parent | 0e1b7a7b352d62507917df1c3ee31b653650f02f (diff) | |
VideoBackends:Vulkan: Use VMA for stream buffer
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/VKTexture.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/VKTexture.cpp | 127 |
1 files changed, 44 insertions, 83 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp index 54360a6c79..412deaf5f9 100644 --- a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp @@ -26,10 +26,10 @@ namespace Vulkan { -VKTexture::VKTexture(const TextureConfig& tex_config, VkDeviceMemory device_memory, VkImage image, +VKTexture::VKTexture(const TextureConfig& tex_config, VmaAllocation alloc, VkImage image, std::string_view name, VkImageLayout layout /* = VK_IMAGE_LAYOUT_UNDEFINED */, ComputeImageLayout compute_layout /* = ComputeImageLayout::Undefined */) - : AbstractTexture(tex_config), m_device_memory(device_memory), m_image(image), m_layout(layout), + : AbstractTexture(tex_config), m_alloc(alloc), m_image(image), m_layout(layout), m_compute_layout(compute_layout), m_name(name) { if (!m_name.empty() && g_ActiveConfig.backend_info.bSupportsSettingObjectNames) @@ -49,10 +49,9 @@ VKTexture::~VKTexture() g_command_buffer_mgr->DeferImageViewDestruction(m_view); // If we don't have device memory allocated, the image is not owned by us (e.g. swapchain) - if (m_device_memory != VK_NULL_HANDLE) + if (m_alloc != VK_NULL_HANDLE) { - g_command_buffer_mgr->DeferImageDestruction(m_image); - g_command_buffer_mgr->DeferDeviceMemoryDestruction(m_device_memory); + g_command_buffer_mgr->DeferImageDestruction(m_image, m_alloc); } } @@ -85,46 +84,28 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config, st nullptr, VK_IMAGE_LAYOUT_UNDEFINED}; - VkImage image = VK_NULL_HANDLE; - VkResult res = vkCreateImage(g_vulkan_context->GetDevice(), &image_info, nullptr, &image); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateImage failed: "); - return nullptr; - } - - // Allocate memory to back this texture, we want device local memory in this case - VkMemoryRequirements memory_requirements; - vkGetImageMemoryRequirements(g_vulkan_context->GetDevice(), image, &memory_requirements); - - VkMemoryAllocateInfo memory_info = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr, memory_requirements.size, - g_vulkan_context - ->GetMemoryType(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - false) - .value_or(0)}; + VmaAllocationCreateInfo alloc_create_info = {}; + alloc_create_info.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT; + alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + alloc_create_info.pool = VK_NULL_HANDLE; + alloc_create_info.pUserData = nullptr; + alloc_create_info.priority = + tex_config.IsComputeImage() || tex_config.IsRenderTarget() ? 1.0 : 0.0; + alloc_create_info.requiredFlags = 0; + alloc_create_info.preferredFlags = 0; - VkDeviceMemory device_memory; - res = vkAllocateMemory(g_vulkan_context->GetDevice(), &memory_info, nullptr, &device_memory); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkAllocateMemory failed: "); - vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr); - return nullptr; - } - - res = vkBindImageMemory(g_vulkan_context->GetDevice(), image, device_memory, 0); + VkImage image = VK_NULL_HANDLE; + VmaAllocation alloc = VK_NULL_HANDLE; + VkResult res = vmaCreateImage(g_vulkan_context->GetMemoryAllocator(), &image_info, + &alloc_create_info, &image, &alloc, nullptr); if (res != VK_SUCCESS) { - LOG_VULKAN_ERROR(res, "vkBindImageMemory failed: "); - vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr); - vkFreeMemory(g_vulkan_context->GetDevice(), device_memory, nullptr); + LOG_VULKAN_ERROR(res, "vmaCreateImage failed: "); return nullptr; } - std::unique_ptr<VKTexture> texture = - std::make_unique<VKTexture>(tex_config, device_memory, image, name, VK_IMAGE_LAYOUT_UNDEFINED, - ComputeImageLayout::Undefined); + std::unique_ptr<VKTexture> texture = std::make_unique<VKTexture>( + tex_config, alloc, image, name, VK_IMAGE_LAYOUT_UNDEFINED, ComputeImageLayout::Undefined); if (!texture->CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY)) return nullptr; @@ -135,7 +116,7 @@ std::unique_ptr<VKTexture> VKTexture::CreateAdopted(const TextureConfig& tex_con VkImageViewType view_type, VkImageLayout layout) { std::unique_ptr<VKTexture> texture = std::make_unique<VKTexture>( - tex_config, VkDeviceMemory(VK_NULL_HANDLE), image, "", layout, ComputeImageLayout::Undefined); + tex_config, VmaAllocation(VK_NULL_HANDLE), image, "", layout, ComputeImageLayout::Undefined); if (!texture->CreateView(view_type)) return nullptr; @@ -701,9 +682,9 @@ void VKTexture::TransitionToLayout(VkCommandBuffer command_buffer, VKStagingTexture::VKStagingTexture(PrivateTag, StagingTextureType type, const TextureConfig& config, std::unique_ptr<StagingBuffer> buffer, VkImage linear_image, - VkDeviceMemory linear_image_memory) + VmaAllocation linear_image_alloc) : AbstractStagingTexture(type, config), m_staging_buffer(std::move(buffer)), - m_linear_image(linear_image), m_linear_image_memory(linear_image_memory) + m_linear_image(linear_image), m_linear_image_alloc(linear_image_alloc) { } @@ -711,8 +692,7 @@ VKStagingTexture::~VKStagingTexture() { if (m_linear_image != VK_NULL_HANDLE) { - g_command_buffer_mgr->DeferImageDestruction(m_linear_image); - g_command_buffer_mgr->DeferDeviceMemoryDestruction(m_linear_image_memory); + g_command_buffer_mgr->DeferImageDestruction(m_linear_image, m_linear_image_alloc); } } @@ -751,18 +731,17 @@ std::unique_ptr<VKStagingTexture> VKStagingTexture::Create(StagingTextureType ty // Linear image VkImage linear_image = VK_NULL_HANDLE; - VkDeviceMemory linear_image_device_memory = VK_NULL_HANDLE; + VmaAllocation linear_image_alloc = VK_NULL_HANDLE; if (DriverDetails::HasBug(DriverDetails::BUG_SLOW_OPTIMAL_IMAGE_TO_BUFFER_COPY) && type == StagingTextureType::Readback && config.samples == 1) { - std::tie(linear_image, linear_image_device_memory) = CreateLinearImage(type, config); + std::tie(linear_image, linear_image_alloc) = CreateLinearImage(type, config); } std::unique_ptr<StagingBuffer> staging_buffer = std::make_unique<StagingBuffer>(buffer_type, buffer, alloc, buffer_size, map_ptr); - std::unique_ptr<VKStagingTexture> staging_tex = - std::make_unique<VKStagingTexture>(PrivateTag{}, type, config, std::move(staging_buffer), - linear_image, linear_image_device_memory); + std::unique_ptr<VKStagingTexture> staging_tex = std::make_unique<VKStagingTexture>( + PrivateTag{}, type, config, std::move(staging_buffer), linear_image, linear_image_alloc); // Use persistent mapping. if (!staging_tex->m_staging_buffer->Map()) @@ -772,8 +751,8 @@ std::unique_ptr<VKStagingTexture> VKStagingTexture::Create(StagingTextureType ty return staging_tex; } -std::pair<VkImage, VkDeviceMemory> VKStagingTexture::CreateLinearImage(StagingTextureType type, - const TextureConfig& config) +std::pair<VkImage, VmaAllocation> VKStagingTexture::CreateLinearImage(StagingTextureType type, + const TextureConfig& config) { // Create a intermediate texture with linear tiling VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -802,43 +781,25 @@ std::pair<VkImage, VkDeviceMemory> VKStagingTexture::CreateLinearImage(StagingTe return std::make_pair(VK_NULL_HANDLE, VK_NULL_HANDLE); } - VkImage image; - res = vkCreateImage(g_vulkan_context->GetDevice(), &image_info, nullptr, &image); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateImage failed: "); - return std::make_pair(VK_NULL_HANDLE, VK_NULL_HANDLE); - } - - // Allocate memory to back this texture, we want device local memory in this case - VkMemoryRequirements memory_requirements; - vkGetImageMemoryRequirements(g_vulkan_context->GetDevice(), image, &memory_requirements); - - VkMemoryAllocateInfo memory_info = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr, memory_requirements.size, - g_vulkan_context - ->GetMemoryType(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - false) - .value_or(0)}; + VmaAllocationCreateInfo alloc_create_info = {}; + alloc_create_info.flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT; + alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + alloc_create_info.pool = VK_NULL_HANDLE; + alloc_create_info.pUserData = nullptr; + alloc_create_info.priority = 0.0; + alloc_create_info.requiredFlags = 0; + alloc_create_info.preferredFlags = 0; - VkDeviceMemory device_memory; - res = vkAllocateMemory(g_vulkan_context->GetDevice(), &memory_info, nullptr, &device_memory); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkAllocateMemory failed: "); - vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr); - return std::make_pair(VK_NULL_HANDLE, VK_NULL_HANDLE); - } - - res = vkBindImageMemory(g_vulkan_context->GetDevice(), image, device_memory, 0); + VkImage image; + VmaAllocation alloc; + res = vmaCreateImage(g_vulkan_context->GetMemoryAllocator(), &image_info, &alloc_create_info, + &image, &alloc, nullptr); if (res != VK_SUCCESS) { - LOG_VULKAN_ERROR(res, "vkBindImageMemory failed: "); - vkDestroyImage(g_vulkan_context->GetDevice(), image, nullptr); - vkFreeMemory(g_vulkan_context->GetDevice(), device_memory, nullptr); + LOG_VULKAN_ERROR(res, "vmaCreateImage failed: "); return std::make_pair(VK_NULL_HANDLE, VK_NULL_HANDLE); } - return std::make_pair(image, device_memory); + return std::make_pair(image, alloc); } void VKStagingTexture::CopyFromTexture(const AbstractTexture* src, |
