Vulkan: Add Memory Pool for External Pixel Buffers
Adds a separate memory pool for creating external pixel buffers. Previous the memory type of images was used, but could not be compatible. Pull Request: https://projects.blender.org/blender/blender/pulls/146078
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
102
source/blender/gpu/vulkan/vk_memory_pool.cc
Normal file
102
source/blender/gpu/vulkan/vk_memory_pool.cc
Normal file
@@ -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
|
||||
49
source/blender/gpu/vulkan/vk_memory_pool.hh
Normal file
49
source/blender/gpu/vulkan/vk_memory_pool.hh
Normal file
@@ -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
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user