diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index ecf1553efa3..7a2863f4822 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -234,6 +234,7 @@ set(VULKAN_SRC vulkan/vk_image_view.cc vulkan/vk_immediate.cc vulkan/vk_index_buffer.cc + vulkan/vk_memory_pool.cc vulkan/vk_memory_layout.cc vulkan/vk_pipeline_pool.cc vulkan/vk_pixel_buffer.cc @@ -283,6 +284,7 @@ set(VULKAN_SRC vulkan/vk_immediate.hh vulkan/vk_index_buffer.hh vulkan/vk_memory.hh + vulkan/vk_memory_pool.hh vulkan/vk_memory_layout.hh vulkan/vk_pipeline_pool.hh vulkan/vk_pixel_buffer.hh diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index defea647f15..93af8fb5ca0 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -85,14 +85,11 @@ bool VKBuffer::create(size_t size_in_bytes, if (export_memory) { create_info.pNext = &external_memory_create_info; -#ifdef _WIN32 - external_memory_create_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; -#else - external_memory_create_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; -#endif + external_memory_create_info.handleTypes = vk_external_memory_handle_type(); + /* Dedicated allocation for zero offset. */ vma_create_info.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - vma_create_info.pool = device.vma_pools.external_memory; + vma_create_info.pool = device.vma_pools.external_memory_pixel_buffer.pool; } const bool use_descriptor_buffer = device.extensions_get().descriptor_buffer; diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index b9b81469ffa..1ac0758d744 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -89,7 +89,7 @@ void VKDevice::deinit() pipelines.write_to_disk(); pipelines.free_data(); descriptor_set_layouts_.deinit(); - vmaDestroyPool(mem_allocator_, vma_pools.external_memory); + vma_pools.deinit(*this); vmaDestroyAllocator(mem_allocator_); mem_allocator_ = VK_NULL_HANDLE; @@ -285,49 +285,8 @@ void VKDevice::init_memory_allocator() if (!extensions_.external_memory) { return; } - /* External memory pool */ - /* Initialize a dummy image create info to find the memory type index that will be used for - * allocating. */ - VkExternalMemoryHandleTypeFlags vk_external_memory_handle_type = 0; -#ifdef _WIN32 - vk_external_memory_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; -#else - vk_external_memory_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; -#endif - VkExternalMemoryImageCreateInfo external_image_create_info = { - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - nullptr, - vk_external_memory_handle_type}; - VkImageCreateInfo image_create_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - &external_image_create_info, - 0, - VK_IMAGE_TYPE_2D, - VK_FORMAT_R8G8B8A8_UNORM, - {1024, 1024, 1}, - 1, - 1, - VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT | - VK_IMAGE_USAGE_SAMPLED_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, - nullptr, - VK_IMAGE_LAYOUT_UNDEFINED}; - VmaAllocationCreateInfo allocation_create_info = {}; - allocation_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO; - uint32_t memory_type_index; - vmaFindMemoryTypeIndexForImageInfo( - mem_allocator_, &image_create_info, &allocation_create_info, &memory_type_index); - vma_pools.external_memory_info.handleTypes = vk_external_memory_handle_type; - VmaPoolCreateInfo pool_create_info = {}; - pool_create_info.memoryTypeIndex = memory_type_index; - pool_create_info.pMemoryAllocateNext = &vma_pools.external_memory_info; - pool_create_info.priority = 1.0f; - vmaCreatePool(mem_allocator_, &pool_create_info, &vma_pools.external_memory); + vma_pools.init(*this); } void VKDevice::init_dummy_buffer() diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index 2c6a83becab..ca9d140857e 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -22,6 +22,7 @@ #include "vk_debug.hh" #include "vk_descriptor_pools.hh" #include "vk_descriptor_set_layouts.hh" +#include "vk_memory_pool.hh" #include "vk_pipeline_pool.hh" #include "vk_resource_pool.hh" #include "vk_samplers.hh" @@ -247,13 +248,7 @@ class VKDevice : public NonCopyable { } functions; - struct { - /* NOTE: This attribute needs to be kept alive as it will be read by VMA when allocating from - * `external_memory` pool. */ - VkExportMemoryAllocateInfoKHR external_memory_info = { - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR}; - VmaPool external_memory = VK_NULL_HANDLE; - } vma_pools; + VKMemoryPools vma_pools; const char *extension_name_get(int index) const { @@ -317,7 +312,7 @@ class VKDevice : public NonCopyable { return vk_queue_family_; } - VmaAllocator mem_allocator_get() const + inline VmaAllocator mem_allocator_get() const { return mem_allocator_; } diff --git a/source/blender/gpu/vulkan/vk_memory_pool.cc b/source/blender/gpu/vulkan/vk_memory_pool.cc new file mode 100644 index 00000000000..6d1a6b3334c --- /dev/null +++ b/source/blender/gpu/vulkan/vk_memory_pool.cc @@ -0,0 +1,102 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#include "vk_memory_pool.hh" + +#include "vk_device.hh" + +namespace blender::gpu { + +void VKMemoryPools::init(VKDevice &device) +{ + init_external_memory_image(device); + init_external_memory_pixel_buffer(device); +} + +void VKMemoryPools::init_external_memory_image(VKDevice &device) +{ + VkExternalMemoryImageCreateInfo external_image_create_info = { + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + nullptr, + vk_external_memory_handle_type()}; + VkImageCreateInfo image_create_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + &external_image_create_info, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R8G8B8A8_UNORM, + {1024, 1024, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + nullptr, + VK_IMAGE_LAYOUT_UNDEFINED}; + VmaAllocationCreateInfo allocation_create_info = {}; + allocation_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO; + uint32_t memory_type_index; + vmaFindMemoryTypeIndexForImageInfo( + device.mem_allocator_get(), &image_create_info, &allocation_create_info, &memory_type_index); + + external_memory_image.info.handleTypes = vk_external_memory_handle_type(); + VmaPoolCreateInfo pool_create_info = {}; + pool_create_info.memoryTypeIndex = memory_type_index; + pool_create_info.pMemoryAllocateNext = &external_memory_image.info; + pool_create_info.priority = 1.0f; + vmaCreatePool(device.mem_allocator_get(), &pool_create_info, &external_memory_image.pool); +} + +void VKMemoryPools::init_external_memory_pixel_buffer(VKDevice &device) +{ + VkExternalMemoryBufferCreateInfo external_buffer_create_info = { + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + nullptr, + vk_external_memory_handle_type()}; + VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + &external_buffer_create_info, + 0, + 1024, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + nullptr}; + VmaAllocationCreateInfo allocation_create_info = {}; + allocation_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO; + uint32_t memory_type_index; + vmaFindMemoryTypeIndexForBufferInfo(device.mem_allocator_get(), + &buffer_create_info, + &allocation_create_info, + &memory_type_index); + + external_memory_pixel_buffer.info.handleTypes = vk_external_memory_handle_type(); + VmaPoolCreateInfo pool_create_info = {}; + pool_create_info.memoryTypeIndex = memory_type_index; + pool_create_info.pMemoryAllocateNext = &external_memory_pixel_buffer.info; + pool_create_info.priority = 1.0f; + vmaCreatePool(device.mem_allocator_get(), &pool_create_info, &external_memory_pixel_buffer.pool); +} + +void VKMemoryPools::deinit(VKDevice &device) +{ + external_memory_image.deinit(device); + external_memory_pixel_buffer.deinit(device); +} + +void VKMemoryPool::deinit(VKDevice &device) +{ + vmaDestroyPool(device.mem_allocator_get(), pool); +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_memory_pool.hh b/source/blender/gpu/vulkan/vk_memory_pool.hh new file mode 100644 index 00000000000..83d9e645849 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_memory_pool.hh @@ -0,0 +1,49 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "vk_common.hh" + +namespace blender::gpu { +class VKDevice; + +constexpr VkExternalMemoryHandleTypeFlags vk_external_memory_handle_type() +{ +#ifdef _WIN32 + return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; +#else + return VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; +#endif +} + +/** + * VMA related data for a memory pool. + */ +struct VKMemoryPool { + /* NOTE: This attribute needs to be kept alive as it will be read by VMA when allocating inside + * the pool. */ + VkExportMemoryAllocateInfoKHR info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR}; + VmaPool pool = VK_NULL_HANDLE; + + void deinit(VKDevice &device); +}; + +struct VKMemoryPools { + VKMemoryPool external_memory_image = {}; + VKMemoryPool external_memory_pixel_buffer = {}; + + void init(VKDevice &device); + void deinit(VKDevice &device); + + private: + void init_external_memory_image(VKDevice &device); + void init_external_memory_pixel_buffer(VKDevice &device); +}; + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index b64ff8e46f5..6c4c27ebabf 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -711,12 +711,8 @@ bool VKTexture::allocate() if (bool(texture_usage & GPU_TEXTURE_USAGE_MEMORY_EXPORT)) { image_info.pNext = &external_memory_create_info; -#ifdef _WIN32 - external_memory_create_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; -#else - external_memory_create_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; -#endif - allocCreateInfo.pool = device.vma_pools.external_memory; + external_memory_create_info.handleTypes = vk_external_memory_handle_type(); + allocCreateInfo.pool = device.vma_pools.external_memory_image.pool; } result = vmaCreateImage(device.mem_allocator_get(), &image_info,