From 98c88780bca31dfa637937ef92b8730dcb044ec8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 3 Nov 2023 02:48:06 +0100 Subject: [PATCH] gpu: Set max samplers/buffers based on features If we run older code, we don't have enough samplers and buffers available. So make sure to reflect that. --- gsk/gpu/gskvulkandevice.c | 72 +++++++++++++++++++------ gsk/gpu/gskvulkandeviceprivate.h | 4 +- gsk/gpu/gskvulkanframe.c | 91 ++++++++++++++++++++++---------- 3 files changed, 123 insertions(+), 44 deletions(-) diff --git a/gsk/gpu/gskvulkandevice.c b/gsk/gpu/gskvulkandevice.c index b7d1d6744e..87913fba55 100644 --- a/gsk/gpu/gskvulkandevice.c +++ b/gsk/gpu/gskvulkandevice.c @@ -10,8 +10,6 @@ #include "gdk/gdkdisplayprivate.h" #include "gdk/gdkvulkancontextprivate.h" -#define DESCRIPTOR_POOL_MAXITEMS 50000 - struct _GskVulkanDevice { GskGpuDevice parent_instance; @@ -20,6 +18,7 @@ struct _GskVulkanDevice GskVulkanAllocator *external_allocator; GdkVulkanFeatures features; + guint max_immutable_samplers; guint max_samplers; guint max_buffers; @@ -468,7 +467,7 @@ gsk_vulkan_device_init (GskVulkanDevice *self) } static void -gsk_vulkan_device_setup (GskVulkanDevice *self) +gsk_vulkan_device_create_vk_objects (GskVulkanDevice *self) { GdkDisplay *display; @@ -484,11 +483,46 @@ gsk_vulkan_device_setup (GskVulkanDevice *self) &self->vk_command_pool); } +static void +gsk_vulkan_device_setup (GskVulkanDevice *self, + GdkDisplay *display) +{ + VkPhysicalDeviceVulkan12Properties vk12_props = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, + }; + VkPhysicalDeviceProperties2 vk_props = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &vk12_props + }; + + vkGetPhysicalDeviceProperties2 (display->vk_physical_device, &vk_props); + /* These numbers can be improved in the shader sources by adding more + * entries to the big switch() statements */ + self->max_immutable_samplers = 8; + if (!gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_DYNAMIC_INDEXING)) + { + self->max_buffers = 8; + self->max_samplers = 8; + } + else if (gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING)) + { + self->max_buffers = vk12_props.maxPerStageDescriptorUpdateAfterBindUniformBuffers; + self->max_samplers = vk12_props.maxPerStageDescriptorUpdateAfterBindSampledImages; + } + else + { + self->max_buffers = vk_props.properties.limits.maxPerStageDescriptorUniformBuffers; + self->max_samplers = vk_props.properties.limits.maxPerStageDescriptorSampledImages; + } + gsk_gpu_device_setup (GSK_GPU_DEVICE (self), + display, + vk_props.properties.limits.maxImageDimension2D); +} + GskGpuDevice * gsk_vulkan_device_get_for_display (GdkDisplay *display, GError **error) { - VkPhysicalDeviceProperties vk_props; GskVulkanDevice *self; self = g_object_get_data (G_OBJECT (display), "-gsk-vulkan-device"); @@ -500,14 +534,10 @@ gsk_vulkan_device_get_for_display (GdkDisplay *display, self = g_object_new (GSK_TYPE_VULKAN_DEVICE, NULL); self->features = display->vulkan_features; - self->max_samplers = DESCRIPTOR_POOL_MAXITEMS; - self->max_buffers = DESCRIPTOR_POOL_MAXITEMS; - vkGetPhysicalDeviceProperties (display->vk_physical_device, &vk_props); - gsk_gpu_device_setup (GSK_GPU_DEVICE (self), - display, - vk_props.limits.maxImageDimension2D); - gsk_vulkan_device_setup (self); + gsk_vulkan_device_setup (self, display); + + gsk_vulkan_device_create_vk_objects (self); g_object_set_data (G_OBJECT (display), "-gsk-vulkan-device", self); @@ -515,9 +545,21 @@ gsk_vulkan_device_get_for_display (GdkDisplay *display, } gsize -gsk_vulkan_device_get_max_descriptors (GskVulkanDevice *self) +gsk_vulkan_device_get_max_immutable_samplers (GskVulkanDevice *self) { - return DESCRIPTOR_POOL_MAXITEMS; + return self->max_immutable_samplers; +} + +gsize +gsk_vulkan_device_get_max_samplers (GskVulkanDevice *self) +{ + return self->max_samplers; +} + +gsize +gsk_vulkan_device_get_max_buffers (GskVulkanDevice *self) +{ + return self->max_buffers; } gboolean @@ -1006,9 +1048,9 @@ gsk_vulkan_device_acquire_pipeline_layout (GskVulkanDevice *self, immutable_samplers = fallback; n_immutable_samplers = 1; } - n_samplers = MIN (n_samplers, 8); + n_samplers = MAX (n_samplers, 8); g_assert (n_samplers <= self->max_samplers); - n_buffers = MIN (n_buffers, 8); + n_buffers = MAX (n_buffers, 8); g_assert (n_buffers <= self->max_buffers); setup.n_samplers = MIN (2 << g_bit_nth_msf (n_samplers - 1, -1), self->max_samplers); setup.n_buffers = MIN (2 << g_bit_nth_msf (n_buffers - 1, -1), self->max_buffers); diff --git a/gsk/gpu/gskvulkandeviceprivate.h b/gsk/gpu/gskvulkandeviceprivate.h index 3197dbd1f3..c7f7270110 100644 --- a/gsk/gpu/gskvulkandeviceprivate.h +++ b/gsk/gpu/gskvulkandeviceprivate.h @@ -28,7 +28,9 @@ typedef struct _GskVulkanPipelineLayout GskVulkanPipelineLayout; GskGpuDevice * gsk_vulkan_device_get_for_display (GdkDisplay *display, GError **error); -gsize gsk_vulkan_device_get_max_descriptors (GskVulkanDevice *self) G_GNUC_PURE; +gsize gsk_vulkan_device_get_max_immutable_samplers (GskVulkanDevice *self); +gsize gsk_vulkan_device_get_max_samplers (GskVulkanDevice *self); +gsize gsk_vulkan_device_get_max_buffers (GskVulkanDevice *self); gboolean gsk_vulkan_device_has_feature (GskVulkanDevice *self, GdkVulkanFeatures feature) G_GNUC_PURE; diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index 26623ac746..79f35e530a 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -47,6 +47,9 @@ struct _GskVulkanFrame VkFence vk_fence; VkCommandBuffer vk_command_buffer; VkDescriptorPool vk_descriptor_pool; + gsize pool_n_sets; + gsize pool_n_samplers; + gsize pool_n_buffers; }; struct _GskVulkanFrameClass @@ -95,27 +98,6 @@ gsk_vulkan_frame_setup (GskGpuFrame *frame) }, NULL, &self->vk_fence); - - GSK_VK_CHECK (vkCreateDescriptorPool, vk_device, - &(VkDescriptorPoolCreateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, - .maxSets = GSK_VULKAN_N_DESCRIPTOR_SETS, - .poolSizeCount = GSK_VULKAN_N_DESCRIPTOR_SETS, - .pPoolSizes = (VkDescriptorPoolSize[GSK_VULKAN_N_DESCRIPTOR_SETS]) { - { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = gsk_vulkan_device_get_max_descriptors (device), - }, - { - .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = gsk_vulkan_device_get_max_descriptors (device), - } - } - }, - NULL, - &self->vk_descriptor_pool); - } static void @@ -141,9 +123,12 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame) GSK_VK_CHECK (vkResetCommandBuffer, self->vk_command_buffer, 0); - GSK_VK_CHECK (vkResetDescriptorPool, vk_device, - self->vk_descriptor_pool, - 0); + if (self->vk_descriptor_pool != VK_NULL_HANDLE) + { + GSK_VK_CHECK (vkResetDescriptorPool, vk_device, + self->vk_descriptor_pool, + 0); + } gsk_samplers_set_size (&self->immutable_samplers, 0); gsk_descriptor_image_infos_set_size (&self->descriptor_immutable_images, 0); gsk_descriptor_image_infos_set_size (&self->descriptor_images, 0); @@ -200,7 +185,6 @@ gsk_vulkan_frame_add_image (GskVulkanFrame *self, else { result = gsk_descriptor_image_infos_get_size (&self->descriptor_images); - g_assert (result < gsk_vulkan_device_get_max_descriptors (device)); result = result << 1; gsk_descriptor_image_infos_append (&self->descriptor_images, @@ -239,10 +223,54 @@ gsk_vulkan_frame_prepare_descriptor_sets (GskVulkanFrame *self) VkWriteDescriptorSet write_descriptor_sets[GSK_VULKAN_N_DESCRIPTOR_SETS + 1]; gsize n_descriptor_sets; VkDescriptorSet descriptor_sets[GSK_VULKAN_N_DESCRIPTOR_SETS]; + gsize n_samplers, n_buffers; device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self))); vk_device = gsk_vulkan_device_get_vk_device (device); + n_samplers = gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) * 3 + + gsk_descriptor_image_infos_get_size (&self->descriptor_images); + n_buffers = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers); + + if (n_samplers > self->pool_n_samplers || + n_buffers > self->pool_n_buffers) + { + if (self->vk_descriptor_pool != VK_NULL_HANDLE) + { + vkDestroyDescriptorPool (vk_device, + self->vk_descriptor_pool, + NULL); + self->vk_descriptor_pool = VK_NULL_HANDLE; + } + if (n_samplers > self->pool_n_samplers) + self->pool_n_samplers = 2 << g_bit_nth_msf (n_samplers - 1, -1); + if (n_buffers > self->pool_n_buffers) + self->pool_n_buffers = 2 << g_bit_nth_msf (n_buffers - 1, -1); + } + + if (self->vk_descriptor_pool == VK_NULL_HANDLE) + { + GSK_VK_CHECK (vkCreateDescriptorPool, vk_device, + &(VkDescriptorPoolCreateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + .maxSets = self->pool_n_sets, + .poolSizeCount = 2, + .pPoolSizes = (VkDescriptorPoolSize[2]) { + { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = self->pool_n_samplers, + }, + { + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = self->pool_n_buffers, + } + } + }, + NULL, + &self->vk_descriptor_pool); + } + GSK_VK_CHECK (vkAllocateDescriptorSets, vk_device, &(VkDescriptorSetAllocateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -404,9 +432,12 @@ gsk_vulkan_frame_finalize (GObject *object) vk_device = gsk_vulkan_device_get_vk_device (device); vk_command_pool = gsk_vulkan_device_get_vk_command_pool (device); - vkDestroyDescriptorPool (vk_device, - self->vk_descriptor_pool, - NULL); + if (self->vk_descriptor_pool != VK_NULL_HANDLE) + { + vkDestroyDescriptorPool (vk_device, + self->vk_descriptor_pool, + NULL); + } gsk_samplers_clear (&self->immutable_samplers); gsk_descriptor_image_infos_clear (&self->descriptor_immutable_images); gsk_descriptor_image_infos_clear (&self->descriptor_images); @@ -447,6 +478,10 @@ gsk_vulkan_frame_init (GskVulkanFrame *self) gsk_descriptor_image_infos_init (&self->descriptor_immutable_images); gsk_descriptor_image_infos_init (&self->descriptor_images); gsk_descriptor_buffer_infos_init (&self->descriptor_buffers); + + self->pool_n_sets = 4; + self->pool_n_samplers = 8; + self->pool_n_buffers = 8; } VkFence