vulkan: Change the allocator querying API

The old API was awkward in that it didn't allow access to the proper
memory type index and was prone to misuse in codepaths when importing
memory instead of allocating it.

Change that.

The old way now requires more code and a local variable, but importing
memory is a lot more straightforward.

And I don't have to spend days tracking down a leak on Windows.
This commit is contained in:
Benjamin Otte
2024-11-08 03:04:53 +01:00
parent 641b8c9cd0
commit 9ae76f6e69
4 changed files with 48 additions and 22 deletions

View File

@@ -74,6 +74,7 @@ gsk_vulkan_buffer_new_internal (GskVulkanDevice *device,
{
VkMemoryRequirements requirements;
GskVulkanBuffer *self;
gsize memory_index;
self = g_object_new (GSK_TYPE_VULKAN_BUFFER, NULL);
@@ -94,11 +95,14 @@ gsk_vulkan_buffer_new_internal (GskVulkanDevice *device,
self->vk_buffer,
&requirements);
self->allocator = gsk_vulkan_device_find_allocator (device,
requirements.memoryTypeBits,
GSK_VULKAN_MEMORY_MAPPABLE,
GSK_VULKAN_MEMORY_MAPPABLE |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
memory_index = gsk_vulkan_device_find_allocator (device,
requirements.memoryTypeBits,
GSK_VULKAN_MEMORY_MAPPABLE,
GSK_VULKAN_MEMORY_MAPPABLE |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
self->allocator = gsk_vulkan_device_get_allocator (device, memory_index);
gsk_vulkan_allocator_ref (self->allocator);
gsk_vulkan_alloc (self->allocator,
requirements.size,
requirements.alignment,

View File

@@ -1033,16 +1033,20 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
return vk_pipeline;
}
static GskVulkanAllocator *
GskVulkanAllocator *
gsk_vulkan_device_get_allocator (GskVulkanDevice *self,
gsize index,
const VkMemoryType *type)
gsize index)
{
if (self->allocators[index] == NULL)
{
VkPhysicalDeviceMemoryProperties properties;
vkGetPhysicalDeviceMemoryProperties (gsk_vulkan_device_get_vk_physical_device (self),
&properties);
self->allocators[index] = gsk_vulkan_direct_allocator_new (gsk_vulkan_device_get_vk_device (self),
index,
type);
&properties.memoryTypes[index]);
self->allocators[index] = gsk_vulkan_buddy_allocator_new (self->allocators[index],
1024 * 1024);
//allocators[index] = gsk_vulkan_stats_allocator_new (allocators[index]);
@@ -1053,11 +1057,11 @@ gsk_vulkan_device_get_allocator (GskVulkanDevice *self,
/* following code found in
* https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceMemoryProperties.html */
GskVulkanAllocator *
gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
uint32_t allowed_types,
VkMemoryPropertyFlags required_flags,
VkMemoryPropertyFlags desired_flags)
gsize
gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
uint32_t allowed_types,
VkMemoryPropertyFlags required_flags,
VkMemoryPropertyFlags desired_flags)
{
VkPhysicalDeviceMemoryProperties properties;
uint32_t i, found;
@@ -1085,7 +1089,7 @@ gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
g_assert (found < properties.memoryTypeCount);
return gsk_vulkan_allocator_ref (gsk_vulkan_device_get_allocator (self, found, &properties.memoryTypes[found]));
return found;
}
GskVulkanAllocator *

View File

@@ -67,10 +67,14 @@ VkPipeline gsk_vulkan_device_get_vk_pipeline (GskVulk
VkRenderPass render_pass);
GskVulkanAllocator * gsk_vulkan_device_get_external_allocator (GskVulkanDevice *self);
GskVulkanAllocator * gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
GskVulkanAllocator * gsk_vulkan_device_get_allocator (GskVulkanDevice *self,
gsize index);
gsize gsk_vulkan_device_find_allocator (GskVulkanDevice *self,
uint32_t allowed_types,
VkMemoryPropertyFlags required_flags,
VkMemoryPropertyFlags desired_flags);
static inline VkResult
gsk_vulkan_handle_result (VkResult res,
const char *called_function)

View File

@@ -266,6 +266,7 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
GskGpuImageFlags flags;
VkFormat vk_format, vk_srgb_format;
VkComponentMapping vk_components;
gsize memory_index;
g_assert (width > 0 && height > 0);
@@ -387,10 +388,13 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
self->vk_image,
&requirements);
self->allocator = gsk_vulkan_device_find_allocator (device,
requirements.memoryTypeBits,
0,
tiling == VK_IMAGE_TILING_LINEAR ? GSK_VULKAN_MEMORY_MAPPABLE : 0);
memory_index = gsk_vulkan_device_find_allocator (device,
requirements.memoryTypeBits,
0,
tiling == VK_IMAGE_TILING_LINEAR ? GSK_VULKAN_MEMORY_MAPPABLE : 0);
self->allocator = gsk_vulkan_device_get_allocator (device, memory_index);
gsk_vulkan_allocator_ref (self->allocator);
gsk_vulkan_alloc (self->allocator,
requirements.size,
requirements.alignment,
@@ -677,6 +681,7 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
VkFormat vk_format, vk_srgb_format;
VkComponentMapping vk_components;
VkMemoryRequirements requirements;
gsize memory_index;
GskVulkanImage *self;
VkResult res;
gsize n_modifiers;
@@ -810,6 +815,10 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
self->vk_image,
&requirements);
memory_index = gsk_vulkan_device_find_allocator (device,
requirements.memoryTypeBits,
0,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
self->allocator = gsk_vulkan_device_get_external_allocator (device);
gsk_vulkan_allocator_ref (self->allocator);
@@ -822,7 +831,7 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
&(VkMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = requirements.size,
.memoryTypeIndex = g_bit_nth_lsf (requirements.memoryTypeBits, -1),
.memoryTypeIndex = memory_index,
.pNext = &(VkExportMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
@@ -995,6 +1004,7 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
VkMemoryRequirements2 requirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
};
gsize memory_index;
GSK_VK_CHECK (func_vkGetMemoryFdPropertiesKHR, vk_device,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
@@ -1038,6 +1048,10 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
}
}
memory_index = gsk_vulkan_device_find_allocator (device,
fd_props.memoryTypeBits,
0,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
gsk_vulkan_alloc (self->allocator,
requirements.memoryRequirements.size,
requirements.memoryRequirements.alignment,
@@ -1046,7 +1060,7 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
&(VkMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = requirements.memoryRequirements.size,
.memoryTypeIndex = g_bit_nth_lsf (fd_props.memoryTypeBits, -1),
.memoryTypeIndex = memory_index,
.pNext = &(VkImportMemoryFdInfoKHR) {
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,