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.
This commit is contained in:
Benjamin Otte 2023-11-03 02:48:06 +01:00
parent 7dcb7d7d0f
commit 98c88780bc
3 changed files with 123 additions and 44 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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