diff --git a/gsk/gpu/gskgpuglobalsop.c b/gsk/gpu/gskgpuglobalsop.c index 848463ab42..6e49d6be13 100644 --- a/gsk/gpu/gskgpuglobalsop.c +++ b/gsk/gpu/gskgpuglobalsop.c @@ -8,6 +8,7 @@ #ifdef GDK_RENDERING_VULKAN #include "gskvulkandeviceprivate.h" #include "gskvulkanframeprivate.h" +#include "gskvulkandescriptorsprivate.h" #endif typedef struct _GskGpuGlobalsOp GskGpuGlobalsOp; @@ -43,8 +44,7 @@ gsk_gpu_globals_op_vk_command (GskGpuOp *op, GskGpuGlobalsOp *self = (GskGpuGlobalsOp *) op; vkCmdPushConstants (state->vk_command_buffer, - gsk_vulkan_device_get_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), - gsk_vulkan_frame_get_pipeline_layout (GSK_VULKAN_FRAME (frame))), + gsk_vulkan_descriptors_get_vk_pipeline_layout (state->desc), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof (self->instance), diff --git a/gsk/gpu/gskgpuopprivate.h b/gsk/gpu/gskgpuopprivate.h index 3bf98710ad..cd8c083003 100644 --- a/gsk/gpu/gskgpuopprivate.h +++ b/gsk/gpu/gskgpuopprivate.h @@ -37,6 +37,8 @@ struct _GskVulkanCommandState VkRenderPass vk_render_pass; VkFormat vk_format; VkCommandBuffer vk_command_buffer; + + GskVulkanDescriptors *desc; }; #endif diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index b03c7bcf92..747ed26b6d 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -35,6 +35,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, { GskGpuShaderOp *self = (GskGpuShaderOp *) op; GskGpuShaderOpClass *shader_op_class = (GskGpuShaderOpClass *) op->op_class; + GskVulkanDescriptors *desc; GskGpuOp *next; gsize i, n; @@ -45,12 +46,19 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, else n = 1; i = 1; + desc = GSK_VULKAN_DESCRIPTORS (self->desc); + if (desc && state->desc != desc) + { + gsk_vulkan_descriptors_bind (desc, state->vk_command_buffer); + state->desc = desc; + } for (next = op->next; next && i < n; next = next->next) { GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next; if (next->op_class != op->op_class || + next_shader->desc != self->desc || next_shader->vertex_offset != self->vertex_offset + i * shader_op_class->vertex_size) break; @@ -60,7 +68,7 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, vkCmdBindPipeline (state->vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, gsk_vulkan_device_get_vk_pipeline (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), - gsk_vulkan_frame_get_pipeline_layout (GSK_VULKAN_FRAME (frame)), + gsk_vulkan_descriptors_get_pipeline_layout (desc), shader_op_class, self->clip, state->vk_format, diff --git a/gsk/gpu/gskgputypesprivate.h b/gsk/gpu/gskgputypesprivate.h index 1e7a6460fe..9dd45d1974 100644 --- a/gsk/gpu/gskgputypesprivate.h +++ b/gsk/gpu/gskgputypesprivate.h @@ -16,6 +16,7 @@ typedef struct _GskGpuOp GskGpuOp; typedef struct _GskGpuOpClass GskGpuOpClass; typedef struct _GskGpuShaderOp GskGpuShaderOp; typedef struct _GskGpuShaderOpClass GskGpuShaderOpClass; +typedef struct _GskVulkanDescriptors GskVulkanDescriptors; typedef enum { GSK_GPU_IMAGE_EXTERNAL = (1 << 0), diff --git a/gsk/gpu/gskvulkandescriptors.c b/gsk/gpu/gskvulkandescriptors.c index 8c91a1333b..2e99c0804d 100644 --- a/gsk/gpu/gskvulkandescriptors.c +++ b/gsk/gpu/gskvulkandescriptors.c @@ -2,14 +2,47 @@ #include "gskvulkandescriptorsprivate.h" +#include "gskvulkanbufferprivate.h" #include "gskvulkanframeprivate.h" #include "gskvulkanimageprivate.h" +#define GDK_ARRAY_NAME gsk_descriptor_image_infos +#define GDK_ARRAY_TYPE_NAME GskDescriptorImageInfos +#define GDK_ARRAY_ELEMENT_TYPE VkDescriptorImageInfo +#define GDK_ARRAY_BY_VALUE 1 +#define GDK_ARRAY_PREALLOC 128 +#define GDK_ARRAY_NO_MEMSET 1 +#include "gdk/gdkarrayimpl.c" + +#define GDK_ARRAY_NAME gsk_descriptor_buffer_infos +#define GDK_ARRAY_TYPE_NAME GskDescriptorBufferInfos +#define GDK_ARRAY_ELEMENT_TYPE VkDescriptorBufferInfo +#define GDK_ARRAY_BY_VALUE 1 +#define GDK_ARRAY_PREALLOC 32 +#define GDK_ARRAY_NO_MEMSET 1 +#include "gdk/gdkarrayimpl.c" + +#define GDK_ARRAY_NAME gsk_samplers +#define GDK_ARRAY_TYPE_NAME GskSamplers +#define GDK_ARRAY_ELEMENT_TYPE VkSampler +#define GDK_ARRAY_PREALLOC 32 +#define GDK_ARRAY_NO_MEMSET 1 +#include "gdk/gdkarrayimpl.c" + struct _GskVulkanDescriptors { GskGpuDescriptors parent_instance; - GskVulkanFrame *frame; /* no reference, the frame owns us */ + GskVulkanDevice *device; + + GskVulkanPipelineLayout *pipeline_layout; + + GskSamplers immutable_samplers; + GskDescriptorImageInfos descriptor_immutable_images; + GskDescriptorImageInfos descriptor_images; + GskDescriptorBufferInfos descriptor_buffers; + + VkDescriptorSet descriptor_sets[GSK_VULKAN_N_DESCRIPTOR_SETS]; }; G_DEFINE_TYPE (GskVulkanDescriptors, gsk_vulkan_descriptors, GSK_TYPE_GPU_DESCRIPTORS) @@ -21,15 +54,71 @@ gsk_vulkan_descriptors_add_image (GskGpuDescriptors *desc, guint32 *out_descriptor) { GskVulkanDescriptors *self = GSK_VULKAN_DESCRIPTORS (desc); + GskVulkanImage *vulkan_image = GSK_VULKAN_IMAGE (image); + VkSampler vk_sampler; + guint32 result; - *out_descriptor = gsk_vulkan_frame_add_image (self->frame, image, sampler); + vk_sampler = gsk_vulkan_image_get_vk_sampler (vulkan_image); + + if (vk_sampler) + { + if (gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) >= + gsk_vulkan_device_get_max_immutable_samplers (self->device)) + return FALSE; + + result = gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) << 1 | 1; + + gsk_samplers_append (&self->immutable_samplers, vk_sampler); + gsk_descriptor_image_infos_append (&self->descriptor_immutable_images, + &(VkDescriptorImageInfo) { + .imageView = gsk_vulkan_image_get_vk_image_view (vulkan_image), + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + }); + } + else + { + if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) >= + gsk_vulkan_device_get_max_samplers (self->device)) + return FALSE; + + result = gsk_descriptor_image_infos_get_size (&self->descriptor_images) << 1; + + gsk_descriptor_image_infos_append (&self->descriptor_images, + &(VkDescriptorImageInfo) { + .sampler = gsk_vulkan_device_get_vk_sampler (self->device, sampler), + .imageView = gsk_vulkan_image_get_vk_image_view (vulkan_image), + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + }); + } + + *out_descriptor = result; return TRUE; } +static void +gsk_vulkan_descriptors_finalize (GObject *object) +{ + GskVulkanDescriptors *self = GSK_VULKAN_DESCRIPTORS (object); + + gsk_samplers_clear (&self->immutable_samplers); + gsk_descriptor_image_infos_clear (&self->descriptor_immutable_images); + gsk_descriptor_image_infos_clear (&self->descriptor_images); + gsk_descriptor_buffer_infos_clear (&self->descriptor_buffers); + + gsk_vulkan_device_release_pipeline_layout (self->device, self->pipeline_layout); + + g_object_unref (self->device); + + G_OBJECT_CLASS (gsk_vulkan_descriptors_parent_class)->finalize (object); +} + static void gsk_vulkan_descriptors_class_init (GskVulkanDescriptorsClass *klass) { GskGpuDescriptorsClass *descriptors_class = GSK_GPU_DESCRIPTORS_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gsk_vulkan_descriptors_finalize; descriptors_class->add_image = gsk_vulkan_descriptors_add_image; } @@ -37,18 +126,55 @@ gsk_vulkan_descriptors_class_init (GskVulkanDescriptorsClass *klass) static void gsk_vulkan_descriptors_init (GskVulkanDescriptors *self) { + gsk_samplers_init (&self->immutable_samplers); + 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); } -GskGpuDescriptors * -gsk_vulkan_descriptors_new (GskVulkanFrame *frame) +GskVulkanDescriptors * +gsk_vulkan_descriptors_new (GskVulkanDevice *device) { GskVulkanDescriptors *self; self = g_object_new (GSK_TYPE_VULKAN_DESCRIPTORS, NULL); - self->frame = frame; + self->device = g_object_ref (device); - return GSK_GPU_DESCRIPTORS (self); + return self; +} + +gboolean +gsk_vulkan_descriptors_is_full (GskVulkanDescriptors *self) +{ + return gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) >= gsk_vulkan_device_get_max_immutable_samplers (self->device) || + gsk_descriptor_image_infos_get_size (&self->descriptor_images) >= gsk_vulkan_device_get_max_samplers (self->device) || + gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) >= gsk_vulkan_device_get_max_buffers (self->device); +} + +gsize +gsk_vulkan_descriptors_get_n_images (GskVulkanDescriptors *self) +{ + return gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) + + gsk_descriptor_image_infos_get_size (&self->descriptor_images); +} + +gsize +gsk_vulkan_descriptors_get_n_buffers (GskVulkanDescriptors *self) +{ + return gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers); +} + +GskVulkanPipelineLayout * +gsk_vulkan_descriptors_get_pipeline_layout (GskVulkanDescriptors *self) +{ + return self->pipeline_layout; +} + +VkPipelineLayout +gsk_vulkan_descriptors_get_vk_pipeline_layout (GskVulkanDescriptors *self) +{ + return gsk_vulkan_device_get_vk_pipeline_layout (self->device, self->pipeline_layout); } void @@ -67,3 +193,114 @@ gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self, VK_ACCESS_SHADER_READ_BIT); } } + +void +gsk_vulkan_descriptors_prepare (GskVulkanDescriptors *self, + VkDescriptorPool vk_descriptor_pool) +{ + VkWriteDescriptorSet write_descriptor_sets[GSK_VULKAN_N_DESCRIPTOR_SETS + 1]; + gsize n_descriptor_sets; + VkDevice vk_device; + + vk_device = gsk_vulkan_device_get_vk_device (self->device); + + self->pipeline_layout = gsk_vulkan_device_acquire_pipeline_layout (self->device, + gsk_samplers_get_data (&self->immutable_samplers), + gsk_samplers_get_size (&self->immutable_samplers), + gsk_descriptor_image_infos_get_size (&self->descriptor_images), + gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)); + + GSK_VK_CHECK (vkAllocateDescriptorSets, vk_device, + &(VkDescriptorSetAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = vk_descriptor_pool, + .descriptorSetCount = GSK_VULKAN_N_DESCRIPTOR_SETS, + .pSetLayouts = (VkDescriptorSetLayout[GSK_VULKAN_N_DESCRIPTOR_SETS]) { + gsk_vulkan_device_get_vk_image_set_layout (self->device, self->pipeline_layout), + gsk_vulkan_device_get_vk_buffer_set_layout (self->device, self->pipeline_layout), + }, + .pNext = &(VkDescriptorSetVariableDescriptorCountAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + .descriptorSetCount = GSK_VULKAN_N_DESCRIPTOR_SETS, + .pDescriptorCounts = (uint32_t[GSK_VULKAN_N_DESCRIPTOR_SETS]) { + gsk_descriptor_image_infos_get_size (&self->descriptor_images), + gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) + } + } + }, + self->descriptor_sets); + + n_descriptor_sets = 0; + if (gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) > 0) + { + write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = self->descriptor_sets[GSK_VULKAN_IMAGE_SET_LAYOUT], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images), + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_immutable_images) + }; + } + if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) > 0) + { + write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = self->descriptor_sets[GSK_VULKAN_IMAGE_SET_LAYOUT], + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images), + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_images) + }; + } + if (gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) > 0) + { + write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = self->descriptor_sets[GSK_VULKAN_BUFFER_SET_LAYOUT], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers), + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .pBufferInfo = gsk_descriptor_buffer_infos_get_data (&self->descriptor_buffers) + }; + } + + vkUpdateDescriptorSets (vk_device, + n_descriptor_sets, + write_descriptor_sets, + 0, NULL); +} + +guint32 +gsk_vulkan_descriptors_get_buffer_descriptor (GskVulkanDescriptors *self, + GskGpuBuffer *buffer) +{ + guint32 result; + + result = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers); + gsk_descriptor_buffer_infos_append (&self->descriptor_buffers, + &(VkDescriptorBufferInfo) { + .buffer = gsk_vulkan_buffer_get_vk_buffer (GSK_VULKAN_BUFFER (buffer)), + .offset = 0, + .range = VK_WHOLE_SIZE + }); + + return result; +} + +void +gsk_vulkan_descriptors_bind (GskVulkanDescriptors *self, + VkCommandBuffer vk_command_buffer) +{ + vkCmdBindDescriptorSets (vk_command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + gsk_vulkan_device_get_vk_pipeline_layout (self->device, self->pipeline_layout), + 0, + G_N_ELEMENTS (self->descriptor_sets), + self->descriptor_sets, + 0, + NULL); +} diff --git a/gsk/gpu/gskvulkandescriptorsprivate.h b/gsk/gpu/gskvulkandescriptorsprivate.h index 3b48af9c73..964620e817 100644 --- a/gsk/gpu/gskvulkandescriptorsprivate.h +++ b/gsk/gpu/gskvulkandescriptorsprivate.h @@ -10,10 +10,25 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GskVulkanDescriptors, gsk_vulkan_descriptors, GSK, VULKAN_DESCRIPTORS, GskGpuDescriptors) -GskGpuDescriptors * gsk_vulkan_descriptors_new (GskVulkanFrame *frame); +GskVulkanDescriptors * gsk_vulkan_descriptors_new (GskVulkanDevice *device); + +gboolean gsk_vulkan_descriptors_is_full (GskVulkanDescriptors *self); +gsize gsk_vulkan_descriptors_get_n_images (GskVulkanDescriptors *self); +gsize gsk_vulkan_descriptors_get_n_buffers (GskVulkanDescriptors *self); +GskVulkanPipelineLayout * gsk_vulkan_descriptors_get_pipeline_layout + (GskVulkanDescriptors *self); +VkPipelineLayout gsk_vulkan_descriptors_get_vk_pipeline_layout + (GskVulkanDescriptors *self); +guint32 gsk_vulkan_descriptors_get_buffer_descriptor + (GskVulkanDescriptors *self, + GskGpuBuffer *buffer); void gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self, VkCommandBuffer command_buffer); +void gsk_vulkan_descriptors_prepare (GskVulkanDescriptors *self, + VkDescriptorPool vk_descriptor_pool); +void gsk_vulkan_descriptors_bind (GskVulkanDescriptors *self, + VkCommandBuffer vk_command_buffer); G_END_DECLS diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index ce6fd8b5a8..a04c3e34a6 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -11,26 +11,10 @@ #include "gdk/gdkdisplayprivate.h" #include "gdk/gdkdmabuftextureprivate.h" -#define GDK_ARRAY_NAME gsk_descriptor_image_infos -#define GDK_ARRAY_TYPE_NAME GskDescriptorImageInfos -#define GDK_ARRAY_ELEMENT_TYPE VkDescriptorImageInfo -#define GDK_ARRAY_BY_VALUE 1 -#define GDK_ARRAY_PREALLOC 128 -#define GDK_ARRAY_NO_MEMSET 1 -#include "gdk/gdkarrayimpl.c" - -#define GDK_ARRAY_NAME gsk_descriptor_buffer_infos -#define GDK_ARRAY_TYPE_NAME GskDescriptorBufferInfos -#define GDK_ARRAY_ELEMENT_TYPE VkDescriptorBufferInfo -#define GDK_ARRAY_BY_VALUE 1 -#define GDK_ARRAY_PREALLOC 32 -#define GDK_ARRAY_NO_MEMSET 1 -#include "gdk/gdkarrayimpl.c" - -#define GDK_ARRAY_NAME gsk_samplers -#define GDK_ARRAY_TYPE_NAME GskSamplers -#define GDK_ARRAY_ELEMENT_TYPE VkSampler -#define GDK_ARRAY_PREALLOC 32 +#define GDK_ARRAY_NAME gsk_descriptors +#define GDK_ARRAY_TYPE_NAME GskDescriptors +#define GDK_ARRAY_ELEMENT_TYPE GskVulkanDescriptors * +#define GDK_ARRAY_FREE_FUNC g_object_unref #define GDK_ARRAY_NO_MEMSET 1 #include "gdk/gdkarrayimpl.c" @@ -38,17 +22,14 @@ struct _GskVulkanFrame { GskGpuFrame parent_instance; - GskVulkanPipelineLayout *pipeline_layout; - GskSamplers immutable_samplers; - GskDescriptorImageInfos descriptor_immutable_images; - GskDescriptorImageInfos descriptor_images; - GskDescriptorBufferInfos descriptor_buffers; - VkFence vk_fence; VkCommandBuffer vk_command_buffer; VkDescriptorPool vk_descriptor_pool; + + GskDescriptors descriptors; + gsize pool_n_sets; - gsize pool_n_samplers; + gsize pool_n_images; gsize pool_n_buffers; }; @@ -129,13 +110,8 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame) 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); - gsk_descriptor_buffer_infos_set_size (&self->descriptor_buffers, 0); - gsk_vulkan_device_release_pipeline_layout (device, self->pipeline_layout); - self->pipeline_layout = NULL; + gsk_descriptors_set_size (&self->descriptors, 0); GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->cleanup (frame); } @@ -158,81 +134,33 @@ gsk_vulkan_frame_upload_texture (GskGpuFrame *frame, return GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->upload_texture (frame, with_mipmap, texture); } -guint32 -gsk_vulkan_frame_add_image (GskVulkanFrame *self, - GskGpuImage *image, - GskGpuSampler sampler) -{ - GskVulkanImage *vulkan_image = GSK_VULKAN_IMAGE (image); - GskVulkanDevice *device; - VkSampler vk_sampler; - guint32 result; - - device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self))); - vk_sampler = gsk_vulkan_image_get_vk_sampler (vulkan_image); - - if (vk_sampler) - { - result = gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) << 1 | 1; - - gsk_samplers_append (&self->immutable_samplers, vk_sampler); - gsk_descriptor_image_infos_append (&self->descriptor_immutable_images, - &(VkDescriptorImageInfo) { - .imageView = gsk_vulkan_image_get_vk_image_view (vulkan_image), - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - }); - } - else - { - result = gsk_descriptor_image_infos_get_size (&self->descriptor_images); - result = result << 1; - - gsk_descriptor_image_infos_append (&self->descriptor_images, - &(VkDescriptorImageInfo) { - .sampler = gsk_vulkan_device_get_vk_sampler (device, sampler), - .imageView = gsk_vulkan_image_get_vk_image_view (vulkan_image), - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - }); - } - - return result; -} - -static guint32 -gsk_vulkan_frame_get_buffer_descriptor (GskVulkanFrame *self, - GskGpuBuffer *buffer) -{ - guint32 result; - - result = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers); - gsk_descriptor_buffer_infos_append (&self->descriptor_buffers, - &(VkDescriptorBufferInfo) { - .buffer = gsk_vulkan_buffer_get_vk_buffer (GSK_VULKAN_BUFFER (buffer)), - .offset = 0, - .range = VK_WHOLE_SIZE - }); - - return result; -} - static void -gsk_vulkan_frame_prepare_descriptor_sets (GskVulkanFrame *self) +gsk_vulkan_frame_prepare_descriptors (GskVulkanFrame *self, + GskGpuBuffer *storage_buffer) { GskVulkanDevice *device; VkDevice vk_device; - 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; + gsize i, n_images, 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); + n_images = 0; + n_buffers = 0; + for (i = 0; i < gsk_descriptors_get_size (&self->descriptors); i++) + { + GskVulkanDescriptors *desc = gsk_descriptors_get (&self->descriptors, i); + if (storage_buffer) + { + G_GNUC_UNUSED guint32 descriptor; + descriptor = gsk_vulkan_descriptors_get_buffer_descriptor (desc, storage_buffer); + g_assert (descriptor == 0); + } + n_images += gsk_vulkan_descriptors_get_n_images (desc); + n_buffers += gsk_vulkan_descriptors_get_n_buffers (desc); + } - if (n_samplers > self->pool_n_samplers || + if (n_images > self->pool_n_images || n_buffers > self->pool_n_buffers) { if (self->vk_descriptor_pool != VK_NULL_HANDLE) @@ -242,8 +170,8 @@ gsk_vulkan_frame_prepare_descriptor_sets (GskVulkanFrame *self) 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_images > self->pool_n_images) + self->pool_n_images = 2 << g_bit_nth_msf (n_images - 1, -1); if (n_buffers > self->pool_n_buffers) self->pool_n_buffers = 2 << g_bit_nth_msf (n_buffers - 1, -1); } @@ -259,7 +187,7 @@ gsk_vulkan_frame_prepare_descriptor_sets (GskVulkanFrame *self) .pPoolSizes = (VkDescriptorPoolSize[2]) { { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = self->pool_n_samplers, + .descriptorCount = self->pool_n_images, }, { .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -271,84 +199,24 @@ gsk_vulkan_frame_prepare_descriptor_sets (GskVulkanFrame *self) &self->vk_descriptor_pool); } - GSK_VK_CHECK (vkAllocateDescriptorSets, vk_device, - &(VkDescriptorSetAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = self->vk_descriptor_pool, - .descriptorSetCount = GSK_VULKAN_N_DESCRIPTOR_SETS, - .pSetLayouts = (VkDescriptorSetLayout[GSK_VULKAN_N_DESCRIPTOR_SETS]) { - gsk_vulkan_device_get_vk_image_set_layout (device, self->pipeline_layout), - gsk_vulkan_device_get_vk_buffer_set_layout (device, self->pipeline_layout), - }, - .pNext = &(VkDescriptorSetVariableDescriptorCountAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - .descriptorSetCount = GSK_VULKAN_N_DESCRIPTOR_SETS, - .pDescriptorCounts = (uint32_t[GSK_VULKAN_N_DESCRIPTOR_SETS]) { - MAX (1, gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) + - gsk_descriptor_image_infos_get_size (&self->descriptor_images)), - MAX (1, gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)) - } - } - }, - descriptor_sets); - - n_descriptor_sets = 0; - if (gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images) > 0) + for (i = 0; i < gsk_descriptors_get_size (&self->descriptors); i++) { - write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = descriptor_sets[GSK_VULKAN_IMAGE_SET_LAYOUT], - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_immutable_images), - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_immutable_images) - }; - } - if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) > 0) - { - write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = descriptor_sets[GSK_VULKAN_IMAGE_SET_LAYOUT], - .dstBinding = 1, - .dstArrayElement = 0, - .descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images), - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_images) - }; - } - if (gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) > 0) - { - write_descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = descriptor_sets[GSK_VULKAN_BUFFER_SET_LAYOUT], - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers), - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .pBufferInfo = gsk_descriptor_buffer_infos_get_data (&self->descriptor_buffers) - }; - } + GskVulkanDescriptors *desc = gsk_descriptors_get (&self->descriptors, i); - vkUpdateDescriptorSets (vk_device, - n_descriptor_sets, - write_descriptor_sets, - 0, NULL); - - vkCmdBindDescriptorSets (self->vk_command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - gsk_vulkan_device_get_vk_pipeline_layout (device, self->pipeline_layout), - 0, - GSK_VULKAN_N_DESCRIPTOR_SETS, - descriptor_sets, - 0, - NULL); + gsk_vulkan_descriptors_prepare (desc, self->vk_descriptor_pool); + } } static GskGpuDescriptors * gsk_vulkan_frame_create_descriptors (GskGpuFrame *frame) { - return GSK_GPU_DESCRIPTORS (gsk_vulkan_descriptors_new (GSK_VULKAN_FRAME (frame))); + GskVulkanFrame *self = GSK_VULKAN_FRAME (frame); + GskVulkanDescriptors *desc; + + desc = gsk_vulkan_descriptors_new (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame))); + gsk_descriptors_append (&self->descriptors, desc); + + return GSK_GPU_DESCRIPTORS (g_object_ref (desc)); } static GskGpuBuffer * @@ -374,18 +242,7 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame, GskVulkanFrame *self = GSK_VULKAN_FRAME (frame); GskVulkanCommandState state; - if (storage_buffer) - { - G_GNUC_UNUSED guint32 descriptor; - descriptor = gsk_vulkan_frame_get_buffer_descriptor (self, storage_buffer); - g_assert (descriptor == 0); - } - - self->pipeline_layout = gsk_vulkan_device_acquire_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), - gsk_samplers_get_data (&self->immutable_samplers), - gsk_samplers_get_size (&self->immutable_samplers), - gsk_descriptor_image_infos_get_size (&self->descriptor_images), - gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)); + gsk_vulkan_frame_prepare_descriptors (self, storage_buffer); GSK_VK_CHECK (vkBeginCommandBuffer, self->vk_command_buffer, &(VkCommandBufferBeginInfo) { @@ -393,8 +250,6 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, }); - gsk_vulkan_frame_prepare_descriptor_sets (self); - if (vertex_buffer) vkCmdBindVertexBuffers (self->vk_command_buffer, 0, @@ -407,6 +262,8 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame, state.vk_command_buffer = self->vk_command_buffer; state.vk_render_pass = VK_NULL_HANDLE; state.vk_format = VK_FORMAT_UNDEFINED; + state.desc = gsk_descriptors_get (&self->descriptors, 0); + gsk_vulkan_descriptors_bind (gsk_descriptors_get (&self->descriptors, 0), state.vk_command_buffer); while (op) { @@ -443,10 +300,7 @@ gsk_vulkan_frame_finalize (GObject *object) 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); - gsk_descriptor_buffer_infos_clear (&self->descriptor_buffers); + gsk_descriptors_clear (&self->descriptors); vkFreeCommandBuffers (vk_device, vk_command_pool, @@ -479,13 +333,10 @@ gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass) static void gsk_vulkan_frame_init (GskVulkanFrame *self) { - gsk_samplers_init (&self->immutable_samplers); - 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); + gsk_descriptors_init (&self->descriptors); self->pool_n_sets = 4; - self->pool_n_samplers = 8; + self->pool_n_images = 8; self->pool_n_buffers = 8; } @@ -495,9 +346,3 @@ gsk_vulkan_frame_get_vk_fence (GskVulkanFrame *self) return self->vk_fence; } -GskVulkanPipelineLayout * -gsk_vulkan_frame_get_pipeline_layout (GskVulkanFrame *self) -{ - return self->pipeline_layout; -} - diff --git a/gsk/gpu/gskvulkanframeprivate.h b/gsk/gpu/gskvulkanframeprivate.h index dbffcae7e1..0fddb83d9d 100644 --- a/gsk/gpu/gskvulkanframeprivate.h +++ b/gsk/gpu/gskvulkanframeprivate.h @@ -11,11 +11,6 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GskVulkanFrame, gsk_vulkan_frame, GSK, VULKAN_FRAME, GskGpuFrame) VkFence gsk_vulkan_frame_get_vk_fence (GskVulkanFrame *self) G_GNUC_PURE; -GskVulkanPipelineLayout * - gsk_vulkan_frame_get_pipeline_layout (GskVulkanFrame *self); -guint32 gsk_vulkan_frame_add_image (GskVulkanFrame *self, - GskGpuImage *image, - GskGpuSampler sampler); G_END_DECLS