From 0f1b0393066c40393a9b65aa38b831229b1a749f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 20 May 2023 02:56:02 +0200 Subject: [PATCH] vulkan: Implement bindless texture rendering Instead of having a descriptor set per operation, we just have one descriptor set and bind all our images into it. Then the shaders get to use an index into the large texture array instead. Getting this to work - because it's a Vulkan extension that needs to be manually enabled, even though it's officially part of Vulkan 1.2 - is insane. --- gdk/gdkvulkancontext.c | 25 ++- gsk/vulkan/gskvulkanblendmodepipeline.c | 18 ++ .../gskvulkanblendmodepipelineprivate.h | 2 + gsk/vulkan/gskvulkanblurpipeline.c | 9 + gsk/vulkan/gskvulkanblurpipelineprivate.h | 1 + gsk/vulkan/gskvulkancolortextpipeline.c | 10 + .../gskvulkancolortextpipelineprivate.h | 1 + gsk/vulkan/gskvulkancrossfadepipeline.c | 18 ++ .../gskvulkancrossfadepipelineprivate.h | 2 + gsk/vulkan/gskvulkaneffectpipeline.c | 9 + gsk/vulkan/gskvulkaneffectpipelineprivate.h | 1 + gsk/vulkan/gskvulkanrender.c | 211 ++++++------------ gsk/vulkan/gskvulkanrenderpass.c | 102 ++------- gsk/vulkan/gskvulkanrenderprivate.h | 4 +- gsk/vulkan/gskvulkantextpipeline.c | 10 + gsk/vulkan/gskvulkantextpipelineprivate.h | 1 + gsk/vulkan/gskvulkantexturepipeline.c | 9 + gsk/vulkan/gskvulkantexturepipelineprivate.h | 1 + gsk/vulkan/resources/blendmode.frag | 12 +- gsk/vulkan/resources/blendmode.vert | 11 +- gsk/vulkan/resources/blur.frag | 6 +- gsk/vulkan/resources/blur.vert | 4 +- gsk/vulkan/resources/color-matrix.frag | 6 +- gsk/vulkan/resources/color-matrix.vert | 3 + gsk/vulkan/resources/common.frag.glsl | 2 + gsk/vulkan/resources/crossfade.frag | 12 +- gsk/vulkan/resources/crossfade.vert | 11 +- gsk/vulkan/resources/mask.frag | 6 +- gsk/vulkan/resources/mask.vert | 4 +- gsk/vulkan/resources/meson.build | 1 + gsk/vulkan/resources/texture.frag | 6 +- gsk/vulkan/resources/texture.vert | 3 + 32 files changed, 256 insertions(+), 265 deletions(-) create mode 100644 gsk/vulkan/resources/common.frag.glsl diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index eb9b8ad83a..93bf2ce917 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -1053,26 +1053,30 @@ gdk_display_create_vulkan_device (GdkDisplay *display, device_extensions = g_ptr_array_new (); g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME); + g_ptr_array_add (device_extensions, (gpointer) VK_KHR_MAINTENANCE_3_EXTENSION_NAME); + g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); if (has_incremental_present) g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); GDK_DISPLAY_DEBUG (display, VULKAN, "Using Vulkan device %u, queue %u", i, j); if (GDK_VK_CHECK (vkCreateDevice, devices[i], &(VkDeviceCreateInfo) { - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - NULL, - 0, - 1, - &(VkDeviceQueueCreateInfo) { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &(VkDeviceQueueCreateInfo) { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .queueFamilyIndex = j, .queueCount = 1, .pQueuePriorities = (float []) { 1.0f }, }, - 0, - NULL, - device_extensions->len, - (const char * const *) device_extensions->pdata + .enabledExtensionCount = device_extensions->len, + .ppEnabledExtensionNames = (const char * const *) device_extensions->pdata, + .pNext = &(VkPhysicalDeviceDescriptorIndexingFeatures) { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + .descriptorBindingPartiallyBound = VK_TRUE, + .descriptorBindingVariableDescriptorCount = VK_TRUE, + .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, + } }, NULL, &display->vk_device) != VK_SUCCESS) @@ -1144,6 +1148,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display, used_extensions = g_ptr_array_new (); g_ptr_array_add (used_extensions, (gpointer) VK_KHR_SURFACE_EXTENSION_NAME); + g_ptr_array_add (used_extensions, (gpointer) VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); g_ptr_array_add (used_extensions, (gpointer) GDK_DISPLAY_GET_CLASS (display)->vk_extension_name); for (i = 0; i < n_extensions; i++) @@ -1215,7 +1220,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display, .enabledLayerCount = used_layers->len, .ppEnabledLayerNames = (const char * const *) used_layers->pdata, .enabledExtensionCount = used_extensions->len, - .ppEnabledExtensionNames = (const char * const *) used_extensions->pdata + .ppEnabledExtensionNames = (const char * const *) used_extensions->pdata, }, NULL, &display->vk_instance); diff --git a/gsk/vulkan/gskvulkanblendmodepipeline.c b/gsk/vulkan/gskvulkanblendmodepipeline.c index bbd649701d..e9ea9c2dc7 100644 --- a/gsk/vulkan/gskvulkanblendmodepipeline.c +++ b/gsk/vulkan/gskvulkanblendmodepipeline.c @@ -14,6 +14,8 @@ struct _GskVulkanBlendModeInstance float rect[4]; float start_tex_rect[4]; float end_tex_rect[4]; + guint32 start_tex_id; + guint32 end_tex_id; guint32 blend_mode; }; @@ -52,6 +54,18 @@ gsk_vulkan_blend_mode_pipeline_get_input_state_create_info (GskVulkanPipeline *s .location = 3, .binding = 0, .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, start_tex_id), + }, + { + .location = 4, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, end_tex_id), + }, + { + .location = 5, + .binding = 0, + .format = VK_FORMAT_R32_UINT, .offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, blend_mode), } }; @@ -101,6 +115,8 @@ gsk_vulkan_blend_mode_pipeline_new (GdkVulkanContext *context, void gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline *pipeline, guchar *data, + guint32 start_tex_id, + guint32 end_tex_id, const graphene_point_t *offset, const graphene_rect_t *bounds, const graphene_rect_t *start_tex_rect, @@ -124,6 +140,8 @@ gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline * instance->end_tex_rect[2] = end_tex_rect->size.width; instance->end_tex_rect[3] = end_tex_rect->size.height; + instance->start_tex_id = start_tex_id; + instance->end_tex_id = end_tex_id; instance->blend_mode = blend_mode; } diff --git a/gsk/vulkan/gskvulkanblendmodepipelineprivate.h b/gsk/vulkan/gskvulkanblendmodepipelineprivate.h index 00d28994f8..94d565d975 100644 --- a/gsk/vulkan/gskvulkanblendmodepipelineprivate.h +++ b/gsk/vulkan/gskvulkanblendmodepipelineprivate.h @@ -20,6 +20,8 @@ GskVulkanPipeline * gsk_vulkan_blend_mode_pipeline_new (GdkVulka void gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline *pipeline, guchar *data, + guint32 start_tex_id, + guint32 end_tex_id, const graphene_point_t *offset, const graphene_rect_t *bounds, const graphene_rect_t *start_bounds, diff --git a/gsk/vulkan/gskvulkanblurpipeline.c b/gsk/vulkan/gskvulkanblurpipeline.c index 48705a92ac..462d8c5045 100644 --- a/gsk/vulkan/gskvulkanblurpipeline.c +++ b/gsk/vulkan/gskvulkanblurpipeline.c @@ -14,6 +14,7 @@ struct _GskVulkanBlurInstance float rect[4]; float tex_rect[4]; float blur_radius; + guint32 tex_id; }; G_DEFINE_TYPE (GskVulkanBlurPipeline, gsk_vulkan_blur_pipeline, GSK_TYPE_VULKAN_PIPELINE) @@ -46,6 +47,12 @@ gsk_vulkan_blur_pipeline_get_input_state_create_info (GskVulkanPipeline *self) .binding = 0, .format = VK_FORMAT_R32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, blur_radius), + }, + { + .location = 3, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, tex_id), } }; static const VkPipelineVertexInputStateCreateInfo info = { @@ -94,6 +101,7 @@ gsk_vulkan_blur_pipeline_new (GdkVulkanContext *context, void gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect, @@ -110,6 +118,7 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, instance->tex_rect[2] = tex_rect->size.width; instance->tex_rect[3] = tex_rect->size.height; instance->blur_radius = blur_radius; + instance->tex_id = tex_id; } gsize diff --git a/gsk/vulkan/gskvulkanblurpipelineprivate.h b/gsk/vulkan/gskvulkanblurpipelineprivate.h index 278c8a8b5c..5e7435aba6 100644 --- a/gsk/vulkan/gskvulkanblurpipelineprivate.h +++ b/gsk/vulkan/gskvulkanblurpipelineprivate.h @@ -19,6 +19,7 @@ GskVulkanPipeline * gsk_vulkan_blur_pipeline_new (GdkVulka void gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect, diff --git a/gsk/vulkan/gskvulkancolortextpipeline.c b/gsk/vulkan/gskvulkancolortextpipeline.c index 2922c06a7f..1a8515b942 100644 --- a/gsk/vulkan/gskvulkancolortextpipeline.c +++ b/gsk/vulkan/gskvulkancolortextpipeline.c @@ -13,6 +13,7 @@ struct _GskVulkanColorTextInstance { float rect[4]; float tex_rect[4]; + guint32 tex_id; }; G_DEFINE_TYPE (GskVulkanColorTextPipeline, gsk_vulkan_color_text_pipeline, GSK_TYPE_VULKAN_PIPELINE) @@ -40,6 +41,12 @@ gsk_vulkan_color_text_pipeline_get_input_state_create_info (GskVulkanPipeline *s .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_rect), }, + { + .location = 2, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_id), + } }; static const VkPipelineVertexInputStateCreateInfo info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, @@ -89,6 +96,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline * guchar *data, GskVulkanRenderer *renderer, const graphene_rect_t *rect, + guint tex_id, PangoFont *font, guint total_glyphs, const PangoGlyphInfo *glyphs, @@ -133,6 +141,8 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline * instance->tex_rect[2] = glyph->tw; instance->tex_rect[3] = glyph->th; + instance->tex_id = tex_id; + count++; } x_position += gi->geometry.width; diff --git a/gsk/vulkan/gskvulkancolortextpipelineprivate.h b/gsk/vulkan/gskvulkancolortextpipelineprivate.h index c5670ea22c..0094398785 100644 --- a/gsk/vulkan/gskvulkancolortextpipelineprivate.h +++ b/gsk/vulkan/gskvulkancolortextpipelineprivate.h @@ -22,6 +22,7 @@ void gsk_vulkan_color_text_pipeline_collect_vertex_data (Gs guchar *data, GskVulkanRenderer *renderer, const graphene_rect_t *rect, + guint tex_id, PangoFont *font, guint total_glyphs, const PangoGlyphInfo *glyphs, diff --git a/gsk/vulkan/gskvulkancrossfadepipeline.c b/gsk/vulkan/gskvulkancrossfadepipeline.c index bdcf07acb9..9763aa762f 100644 --- a/gsk/vulkan/gskvulkancrossfadepipeline.c +++ b/gsk/vulkan/gskvulkancrossfadepipeline.c @@ -14,6 +14,8 @@ struct _GskVulkanCrossFadeInstance float rect[4]; float start_tex_rect[4]; float end_tex_rect[4]; + float start_tex_id; + float end_tex_id; float progress; }; @@ -51,6 +53,18 @@ gsk_vulkan_cross_fade_pipeline_get_input_state_create_info (GskVulkanPipeline *s { .location = 3, .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_id), + }, + { + .location = 4, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_id), + }, + { + .location = 5, + .binding = 0, .format = VK_FORMAT_R32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, progress), } @@ -101,6 +115,8 @@ gsk_vulkan_cross_fade_pipeline_new (GdkVulkanContext *context, void gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline *pipeline, guchar *data, + guint32 start_tex_id, + guint32 end_tex_id, const graphene_point_t *offset, const graphene_rect_t *bounds, const graphene_rect_t *start_tex_rect, @@ -124,6 +140,8 @@ gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline * instance->end_tex_rect[2] = end_tex_rect->size.width; instance->end_tex_rect[3] = end_tex_rect->size.height; + instance->start_tex_id = start_tex_id; + instance->end_tex_id = end_tex_id; instance->progress = progress; } diff --git a/gsk/vulkan/gskvulkancrossfadepipelineprivate.h b/gsk/vulkan/gskvulkancrossfadepipelineprivate.h index 7b8b6d8f96..f4249318cc 100644 --- a/gsk/vulkan/gskvulkancrossfadepipelineprivate.h +++ b/gsk/vulkan/gskvulkancrossfadepipelineprivate.h @@ -19,6 +19,8 @@ GskVulkanPipeline * gsk_vulkan_cross_fade_pipeline_new (GdkVulka void gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline *pipeline, guchar *data, + guint32 start_tex_id, + guint32 end_tex_id, const graphene_point_t *offset, const graphene_rect_t *bounds, const graphene_rect_t *start_bounds, diff --git a/gsk/vulkan/gskvulkaneffectpipeline.c b/gsk/vulkan/gskvulkaneffectpipeline.c index 3faf769276..578a47d44c 100644 --- a/gsk/vulkan/gskvulkaneffectpipeline.c +++ b/gsk/vulkan/gskvulkaneffectpipeline.c @@ -15,6 +15,7 @@ struct _GskVulkanEffectInstance float tex_rect[4]; float color_matrix[16]; float color_offset[4]; + guint32 tex_id; }; G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE) @@ -71,6 +72,12 @@ gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self) .binding = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_offset), + }, + { + .location = 7, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, tex_id), } }; static const VkPipelineVertexInputStateCreateInfo info = { @@ -119,6 +126,7 @@ gsk_vulkan_effect_pipeline_new (GdkVulkanContext *context, void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect, @@ -137,6 +145,7 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin instance->tex_rect[3] = tex_rect->size.height; graphene_matrix_to_float (color_matrix, instance->color_matrix); graphene_vec4_to_float (color_offset, instance->color_offset); + instance->tex_id = tex_id; } gsize diff --git a/gsk/vulkan/gskvulkaneffectpipelineprivate.h b/gsk/vulkan/gskvulkaneffectpipelineprivate.h index ecd1df2667..f7239386bd 100644 --- a/gsk/vulkan/gskvulkaneffectpipelineprivate.h +++ b/gsk/vulkan/gskvulkaneffectpipelineprivate.h @@ -19,6 +19,7 @@ GskVulkanPipeline * gsk_vulkan_effect_pipeline_new (GdkVulk void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect, diff --git a/gsk/vulkan/gskvulkanrender.c b/gsk/vulkan/gskvulkanrender.c index 333941a681..441e0f6a6b 100644 --- a/gsk/vulkan/gskvulkanrender.c +++ b/gsk/vulkan/gskvulkanrender.c @@ -23,8 +23,15 @@ #include "gskvulkantexturepipelineprivate.h" #include "gskvulkanpushconstantsprivate.h" -#define DESCRIPTOR_POOL_MAXSETS 128 -#define DESCRIPTOR_POOL_MAXSETS_INCREASE 128 +#define DESCRIPTOR_POOL_MAXITEMS 50000 + +#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 1024 +#define GDK_ARRAY_NO_MEMSET 1 +#include "gdk/gdkarrayimpl.c" struct _GskVulkanRender { @@ -43,11 +50,9 @@ struct _GskVulkanRender VkPipelineLayout pipeline_layout; GskVulkanUploader *uploader; - GHashTable *descriptor_set_indexes; + GskDescriptorImageInfos descriptor_image_infos; VkDescriptorPool descriptor_pool; - uint32_t descriptor_pool_maxsets; - VkDescriptorSet *descriptor_sets; - gsize n_descriptor_sets; + VkDescriptorSet descriptor_set; GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES]; GskVulkanImage *target; @@ -103,9 +108,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self, } } -static guint desc_set_index_hash (gconstpointer v); -static gboolean desc_set_index_equal (gconstpointer v1, gconstpointer v2); - GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer, GdkVulkanContext *context) @@ -118,7 +120,7 @@ gsk_vulkan_render_new (GskRenderer *renderer, self->vulkan = context; self->renderer = renderer; self->framebuffers = g_hash_table_new (g_direct_hash, g_direct_equal); - self->descriptor_set_indexes = g_hash_table_new_full (desc_set_index_hash, desc_set_index_equal, NULL, g_free); + gsk_descriptor_image_infos_init (&self->descriptor_image_infos); device = gdk_vulkan_context_get_device (self->vulkan); @@ -131,16 +133,16 @@ gsk_vulkan_render_new (GskRenderer *renderer, NULL, &self->fence); - self->descriptor_pool_maxsets = DESCRIPTOR_POOL_MAXSETS; GSK_VK_CHECK (vkCreateDescriptorPool, device, &(VkDescriptorPoolCreateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = self->descriptor_pool_maxsets, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + .maxSets = 1, .poolSizeCount = 1, .pPoolSizes = (VkDescriptorPoolSize[1]) { { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = self->descriptor_pool_maxsets + .descriptorCount = DESCRIPTOR_POOL_MAXITEMS } } }, @@ -191,13 +193,23 @@ gsk_vulkan_render_new (GskRenderer *renderer, &(VkDescriptorSetLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .bindingCount = 1, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, .pBindings = (VkDescriptorSetLayoutBinding[1]) { { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = 1, + .descriptorCount = DESCRIPTOR_POOL_MAXITEMS, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT } + }, + .pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .bindingCount = 1, + .pBindingFlags = &(VkDescriptorBindingFlags) { + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT + | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT + | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + }, } }, NULL, @@ -206,9 +218,8 @@ gsk_vulkan_render_new (GskRenderer *renderer, GSK_VK_CHECK (vkCreatePipelineLayout, device, &(VkPipelineLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 2, - .pSetLayouts = (VkDescriptorSetLayout[2]) { - self->descriptor_set_layout, + .setLayoutCount = 1, + .pSetLayouts = (VkDescriptorSetLayout[1]) { self->descriptor_set_layout }, .pushConstantRangeCount = gsk_vulkan_push_constants_get_range_count (), @@ -425,35 +436,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, } VkDescriptorSet -gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self, - gsize id) +gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self) { - g_assert (id < self->n_descriptor_sets); - - return self->descriptor_sets[id]; -} - -typedef struct { - gsize index; - GskVulkanImage *image; - gboolean repeat; -} HashDescriptorSetIndexEntry; - -static guint -desc_set_index_hash (gconstpointer v) -{ - const HashDescriptorSetIndexEntry *e = v; - - return GPOINTER_TO_UINT (e->image) + e->repeat; -} - -static gboolean -desc_set_index_equal (gconstpointer v1, gconstpointer v2) -{ - const HashDescriptorSetIndexEntry *e1 = v1; - const HashDescriptorSetIndexEntry *e2 = v2; - - return e1->image == e2->image && e1->repeat == e2->repeat; + return self->descriptor_set; } gsize @@ -461,35 +446,26 @@ gsk_vulkan_render_reserve_descriptor_set (GskVulkanRender *self, GskVulkanImage *source, gboolean repeat) { - HashDescriptorSetIndexEntry lookup; - HashDescriptorSetIndexEntry *entry; - - g_assert (source != NULL); - - lookup.image = source; - lookup.repeat = repeat; + VkDescriptorImageInfo info = { + .sampler = repeat ? self->repeating_sampler : self->sampler, + .imageView = gsk_vulkan_image_get_image_view (source), + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + }; + gsize result; - entry = g_hash_table_lookup (self->descriptor_set_indexes, &lookup); - if (entry) - return entry->index; + result = gsk_descriptor_image_infos_get_size (&self->descriptor_image_infos); + gsk_descriptor_image_infos_append (&self->descriptor_image_infos, &info); - entry = g_new (HashDescriptorSetIndexEntry, 1); - entry->image = source; - entry->repeat = repeat; - entry->index = g_hash_table_size (self->descriptor_set_indexes); - g_hash_table_add (self->descriptor_set_indexes, entry); + g_assert (result < DESCRIPTOR_POOL_MAXITEMS); - return entry->index; + return result; } static void gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self) { - GHashTableIter iter; - gpointer key; VkDevice device; GList *l; - guint i, needed_sets; device = gdk_vulkan_context_get_device (self->vulkan); @@ -499,88 +475,39 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self) gsk_vulkan_render_pass_reserve_descriptor_sets (pass, self); } - needed_sets = g_hash_table_size (self->descriptor_set_indexes); - if (needed_sets == 0) + if (gsk_descriptor_image_infos_get_size (&self->descriptor_image_infos) == 0) return; - if (needed_sets > self->n_descriptor_sets) - { - if (needed_sets > self->descriptor_pool_maxsets) - { - guint added_sets = needed_sets - self->descriptor_pool_maxsets; - added_sets = added_sets + DESCRIPTOR_POOL_MAXSETS_INCREASE - 1; - added_sets -= added_sets % DESCRIPTOR_POOL_MAXSETS_INCREASE; - - vkDestroyDescriptorPool (device, - self->descriptor_pool, - NULL); - self->descriptor_pool_maxsets += added_sets; - GSK_VK_CHECK (vkCreateDescriptorPool, device, - &(VkDescriptorPoolCreateInfo) { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = self->descriptor_pool_maxsets, - .poolSizeCount = 1, - .pPoolSizes = (VkDescriptorPoolSize[1]) { - { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = self->descriptor_pool_maxsets - } - } - }, - NULL, - &self->descriptor_pool); - } - else - { - GSK_VK_CHECK (vkResetDescriptorPool, device, - self->descriptor_pool, - 0); - } - - self->n_descriptor_sets = needed_sets; - self->descriptor_sets = g_renew (VkDescriptorSet, self->descriptor_sets, needed_sets); - } - - VkDescriptorSetLayout *layouts = g_newa (VkDescriptorSetLayout, needed_sets); - for (i = 0; i < needed_sets; i++) - layouts[i] = self->descriptor_set_layout; - GSK_VK_CHECK (vkAllocateDescriptorSets, device, &(VkDescriptorSetAllocateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorPool = self->descriptor_pool, - .descriptorSetCount = needed_sets, - .pSetLayouts = layouts + .descriptorSetCount = 1, + .pSetLayouts = &self->descriptor_set_layout, + .pNext = &(VkDescriptorSetVariableDescriptorCountAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + .descriptorSetCount = 1, + .pDescriptorCounts = (uint32_t[1]) { + gsk_descriptor_image_infos_get_size (&self->descriptor_image_infos) + } + } }, - self->descriptor_sets); - - g_hash_table_iter_init (&iter, self->descriptor_set_indexes); - while (g_hash_table_iter_next (&iter, &key, NULL)) - { - HashDescriptorSetIndexEntry *entry = key; - GskVulkanImage *image = entry->image; - gsize id = entry->index; - gboolean repeat = entry->repeat; - - vkUpdateDescriptorSets (device, - 1, - (VkWriteDescriptorSet[1]) { - { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = self->descriptor_sets[id], - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &(VkDescriptorImageInfo) { - .sampler = repeat ? self->repeating_sampler : self->sampler, - .imageView = gsk_vulkan_image_get_image_view (image), - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - } - } - }, - 0, NULL); - } + &self->descriptor_set); + + vkUpdateDescriptorSets (device, + 1, + (VkWriteDescriptorSet[1]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = self->descriptor_set, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_image_infos), + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_image_infos) + } + }, + 0, NULL); } void @@ -670,10 +597,10 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self) gsk_vulkan_command_pool_reset (self->command_pool); - g_hash_table_remove_all (self->descriptor_set_indexes); GSK_VK_CHECK (vkResetDescriptorPool, device, self->descriptor_pool, 0); + gsk_descriptor_image_infos_set_size (&self->descriptor_image_infos, 0); g_list_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free); self->render_passes = NULL; @@ -715,6 +642,7 @@ gsk_vulkan_render_free (GskVulkanRender *self) g_clear_pointer (&self->uploader, gsk_vulkan_uploader_free); + vkDestroyPipelineLayout (device, self->pipeline_layout, NULL); @@ -726,8 +654,7 @@ gsk_vulkan_render_free (GskVulkanRender *self) vkDestroyDescriptorPool (device, self->descriptor_pool, NULL); - g_free (self->descriptor_sets); - g_hash_table_unref (self->descriptor_set_indexes); + gsk_descriptor_image_infos_clear (&self->descriptor_image_infos); vkDestroyDescriptorSetLayout (device, self->descriptor_set_layout, diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c index 674ae1b14b..975dc0cbff 100644 --- a/gsk/vulkan/gskvulkanrenderpass.c +++ b/gsk/vulkan/gskvulkanrenderpass.c @@ -1798,6 +1798,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_TEXTURE: gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, &op->render.offset, &op->render.node->bounds, &op->render.source_rect); @@ -1806,6 +1807,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_REPEAT: gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, &op->render.offset, &op->render.node->bounds, &op->render.source_rect); @@ -1816,6 +1818,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, data + op->text.vertex_offset, GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), &op->text.node->bounds, + op->text.descriptor_set_index, (PangoFont *)gsk_text_node_get_font (op->text.node), gsk_text_node_get_num_glyphs (op->text.node), gsk_text_node_get_glyphs (op->text.node, NULL), @@ -1834,6 +1837,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, data + op->text.vertex_offset, GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), &op->text.node->bounds, + op->text.descriptor_set_index, (PangoFont *)gsk_text_node_get_font (op->text.node), gsk_text_node_get_num_glyphs (op->text.node), gsk_text_node_get_glyphs (op->text.node, NULL), @@ -1882,6 +1886,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, &op->render.offset, &op->render.node->bounds, &op->render.source_rect, @@ -1893,6 +1898,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_BLUR: gsk_vulkan_blur_pipeline_collect_vertex_data (GSK_VULKAN_BLUR_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, &op->render.offset, &op->render.node->bounds, &op->render.source_rect, @@ -1902,6 +1908,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_COLOR_MATRIX: gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, &op->render.offset, &op->render.node->bounds, &op->render.source_rect, @@ -1945,6 +1952,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_CROSS_FADE: gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GSK_VULKAN_CROSS_FADE_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, + op->render.descriptor_set_index2, &op->render.offset, &op->render.node->bounds, &op->render.source_rect, @@ -1955,6 +1964,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_BLEND_MODE: gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_MODE_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, + op->render.descriptor_set_index, + op->render.descriptor_set_index2, &op->render.offset, &op->render.node->bounds, &op->render.source_rect, @@ -2111,17 +2122,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 1, - (VkDescriptorSet[1]) { - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index) - }, - 0, - NULL); - gsk_vulkan_texture_pipeline_draw (GSK_VULKAN_TEXTURE_PIPELINE (current_pipeline), command_buffer, op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2137,17 +2137,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 1, - (VkDescriptorSet[1]) { - gsk_vulkan_render_get_descriptor_set (render, op->text.descriptor_set_index) - }, - 0, - NULL); - gsk_vulkan_text_pipeline_draw (GSK_VULKAN_TEXT_PIPELINE (current_pipeline), command_buffer, op->text.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2163,17 +2152,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 1, - (VkDescriptorSet[1]) { - gsk_vulkan_render_get_descriptor_set (render, op->text.descriptor_set_index) - }, - 0, - NULL); - gsk_vulkan_color_text_pipeline_draw (GSK_VULKAN_COLOR_TEXT_PIPELINE (current_pipeline), command_buffer, op->text.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2192,17 +2170,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 1, - (VkDescriptorSet[1]) { - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index) - }, - 0, - NULL); - gsk_vulkan_effect_pipeline_draw (GSK_VULKAN_EFFECT_PIPELINE (current_pipeline), command_buffer, op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2220,17 +2187,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 1, - (VkDescriptorSet[1]) { - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index) - }, - 0, - NULL); - gsk_vulkan_blur_pipeline_draw (GSK_VULKAN_BLUR_PIPELINE (current_pipeline), command_buffer, op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2331,18 +2287,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 2, - (VkDescriptorSet[2]) { - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index), - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index2) - }, - 0, - NULL); - gsk_vulkan_cross_fade_pipeline_draw (GSK_VULKAN_CROSS_FADE_PIPELINE (current_pipeline), command_buffer, op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2360,18 +2304,6 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); } - vkCmdBindDescriptorSets (command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout, - 0, - 2, - (VkDescriptorSet[2]) { - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index), - gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index2) - }, - 0, - NULL); - gsk_vulkan_blend_mode_pipeline_draw (GSK_VULKAN_BLEND_MODE_PIPELINE (current_pipeline), command_buffer, op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (current_pipeline), @@ -2391,6 +2323,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, VkPipelineLayout pipeline_layout, VkCommandBuffer command_buffer) { + VkDescriptorSet descriptor_set; cairo_rectangle_int_t rect; vkCmdSetViewport (command_buffer, @@ -2423,6 +2356,17 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, }, VK_SUBPASS_CONTENTS_INLINE); + descriptor_set = gsk_vulkan_render_get_descriptor_set (render); + if (descriptor_set) + vkCmdBindDescriptorSets (command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_layout, + 0, + 1, + &descriptor_set, + 0, + NULL); + gsk_vulkan_render_pass_draw_rect (self, render, pipeline_layout, command_buffer); vkCmdEndRenderPass (command_buffer); diff --git a/gsk/vulkan/gskvulkanrenderprivate.h b/gsk/vulkan/gskvulkanrenderprivate.h index 1f7a23db38..457c587e5b 100644 --- a/gsk/vulkan/gskvulkanrenderprivate.h +++ b/gsk/vulkan/gskvulkanrenderprivate.h @@ -76,11 +76,11 @@ void gsk_vulkan_render_upload (GskVulk GskVulkanPipeline * gsk_vulkan_render_get_pipeline (GskVulkanRender *self, GskVulkanPipelineType pipeline_type); -VkDescriptorSet gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self, - gsize id); gsize gsk_vulkan_render_reserve_descriptor_set (GskVulkanRender *self, GskVulkanImage *source, gboolean repeat); +VkDescriptorSet gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self); + void gsk_vulkan_render_draw (GskVulkanRender *self); void gsk_vulkan_render_submit (GskVulkanRender *self); diff --git a/gsk/vulkan/gskvulkantextpipeline.c b/gsk/vulkan/gskvulkantextpipeline.c index 0e817da8c0..ed810b7f68 100644 --- a/gsk/vulkan/gskvulkantextpipeline.c +++ b/gsk/vulkan/gskvulkantextpipeline.c @@ -14,6 +14,7 @@ struct _GskVulkanTextInstance float rect[4]; float tex_rect[4]; float color[4]; + guint32 tex_id; }; G_DEFINE_TYPE (GskVulkanTextPipeline, gsk_vulkan_text_pipeline, GSK_TYPE_VULKAN_PIPELINE) @@ -46,6 +47,12 @@ gsk_vulkan_text_pipeline_get_input_state_create_info (GskVulkanPipeline *self) .binding = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanTextInstance, color), + }, + { + .location = 3, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanTextInstance, tex_id), } }; static const VkPipelineVertexInputStateCreateInfo info = { @@ -96,6 +103,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline, guchar *data, GskVulkanRenderer *renderer, const graphene_rect_t *rect, + guint tex_id, PangoFont *font, guint total_glyphs, const PangoGlyphInfo *glyphs, @@ -146,6 +154,8 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline, instance->color[2] = color->blue; instance->color[3] = color->alpha; + instance->tex_id = tex_id; + count++; } x_position += gi->geometry.width; diff --git a/gsk/vulkan/gskvulkantextpipelineprivate.h b/gsk/vulkan/gskvulkantextpipelineprivate.h index c434fa1aef..8f05e43500 100644 --- a/gsk/vulkan/gskvulkantextpipelineprivate.h +++ b/gsk/vulkan/gskvulkantextpipelineprivate.h @@ -22,6 +22,7 @@ void gsk_vulkan_text_pipeline_collect_vertex_data (GskVulka guchar *data, GskVulkanRenderer *renderer, const graphene_rect_t *rect, + guint32 tex_id, PangoFont *font, guint total_glyphs, const PangoGlyphInfo *glyphs, diff --git a/gsk/vulkan/gskvulkantexturepipeline.c b/gsk/vulkan/gskvulkantexturepipeline.c index 437eeeda39..dc01cca9c3 100644 --- a/gsk/vulkan/gskvulkantexturepipeline.c +++ b/gsk/vulkan/gskvulkantexturepipeline.c @@ -13,6 +13,7 @@ struct _GskVulkanTextureInstance { float rect[4]; float tex_rect[4]; + guint32 tex_id; }; G_DEFINE_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK_TYPE_VULKAN_PIPELINE) @@ -39,6 +40,12 @@ gsk_vulkan_texture_pipeline_get_input_state_create_info (GskVulkanPipeline *self .binding = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_rect), + }, + { + .location = 2, + .binding = 0, + .format = VK_FORMAT_R32_UINT, + .offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_id), } }; static const VkPipelineVertexInputStateCreateInfo info = { @@ -87,6 +94,7 @@ gsk_vulkan_texture_pipeline_new (GdkVulkanContext *context, void gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect) @@ -101,6 +109,7 @@ gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipel instance->tex_rect[1] = tex_rect->origin.y; instance->tex_rect[2] = tex_rect->size.width; instance->tex_rect[3] = tex_rect->size.height; + instance->tex_id = tex_id; } gsize diff --git a/gsk/vulkan/gskvulkantexturepipelineprivate.h b/gsk/vulkan/gskvulkantexturepipelineprivate.h index a188a56f91..d837e4d9d2 100644 --- a/gsk/vulkan/gskvulkantexturepipelineprivate.h +++ b/gsk/vulkan/gskvulkantexturepipelineprivate.h @@ -19,6 +19,7 @@ GskVulkanPipeline * gsk_vulkan_texture_pipeline_new (GdkVulk void gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipeline, guchar *data, + guint32 tex_id, const graphene_point_t *offset, const graphene_rect_t *rect, const graphene_rect_t *tex_rect); diff --git a/gsk/vulkan/resources/blendmode.frag b/gsk/vulkan/resources/blendmode.frag index a8b23e9891..ad1d9c98b3 100644 --- a/gsk/vulkan/resources/blendmode.frag +++ b/gsk/vulkan/resources/blendmode.frag @@ -1,14 +1,14 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in vec2 inStartTexCoord; layout(location = 2) in vec2 inEndTexCoord; -layout(location = 3) flat in uint inBlendMode; - -layout(set = 0, binding = 0) uniform sampler2D startTexture; -layout(set = 1, binding = 0) uniform sampler2D endTexture; +layout(location = 3) flat in uint inStartTexId; +layout(location = 4) flat in uint inEndTexId; +layout(location = 5) flat in uint inBlendMode; layout(location = 0) out vec4 outColor; @@ -271,8 +271,8 @@ luminosity (vec4 Cs, vec4 Cb) void main() { - vec4 source = texture (startTexture, inStartTexCoord); - vec4 backdrop = texture (endTexture, inEndTexCoord); + vec4 source = texture (textures[inStartTexId], inStartTexCoord); + vec4 backdrop = texture (textures[inEndTexId], inEndTexCoord); vec4 result; if (inBlendMode == 0) diff --git a/gsk/vulkan/resources/blendmode.vert b/gsk/vulkan/resources/blendmode.vert index b4c890302a..e0c13a5fe2 100644 --- a/gsk/vulkan/resources/blendmode.vert +++ b/gsk/vulkan/resources/blendmode.vert @@ -5,12 +5,16 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inStartTexRect; layout(location = 2) in vec4 inEndTexRect; -layout(location = 3) in uint inBlendMode; +layout(location = 3) in uint inStartTexId; +layout(location = 4) in uint inEndTexId; +layout(location = 5) in uint inBlendMode; layout(location = 0) out vec2 outPos; layout(location = 1) out vec2 outStartTexCoord; layout(location = 2) out vec2 outEndTexCoord; -layout(location = 3) flat out uint outBlendMode; +layout(location = 3) flat out uint outStartTexId; +layout(location = 4) flat out uint outEndTexId; +layout(location = 5) flat out uint outBlendMode; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -35,6 +39,7 @@ void main() { outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex]; outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex]; - + outStartTexId = inStartTexId; + outEndTexId = inEndTexId; outBlendMode = inBlendMode; } diff --git a/gsk/vulkan/resources/blur.frag b/gsk/vulkan/resources/blur.frag index 2dd584b0c6..c67063bb8c 100644 --- a/gsk/vulkan/resources/blur.frag +++ b/gsk/vulkan/resources/blur.frag @@ -1,13 +1,13 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in flat vec2 inSize; layout(location = 2) in vec2 inTexCoord; layout(location = 3) in float inRadius; - -layout(set = 0, binding = 0) uniform sampler2D inTexture; +layout(location = 4) in flat uint inTexId; layout(location = 0) out vec4 color; @@ -38,7 +38,7 @@ vec4 blur_pixel (in vec2 uv) float fx = Gaussian (inRadius, float(x) - float(half_samples_x)); float offset_x = float(x - half_samples_x) * pixel_size_x; total += fx * fy; - ret += texture(inTexture, uv + vec2(offset_x, offset_y)) * fx * fy; + ret += texture(textures[inTexId], uv + vec2(offset_x, offset_y)) * fx * fy; } } return ret / total; diff --git a/gsk/vulkan/resources/blur.vert b/gsk/vulkan/resources/blur.vert index 7ba6046852..5a5fd6cbce 100644 --- a/gsk/vulkan/resources/blur.vert +++ b/gsk/vulkan/resources/blur.vert @@ -6,11 +6,13 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inTexRect; layout(location = 2) in float inRadius; +layout(location = 3) in uint inTexId; layout(location = 0) out vec2 outPos; layout(location = 1) out flat vec2 outSize; layout(location = 2) out vec2 outTexCoord; layout(location = 3) out flat float outRadius; +layout(location = 4) out flat uint outTexId; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -32,6 +34,6 @@ void main() { texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy, inTexRect.zw * texrect.zw); outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex]; - + outTexId = inTexId; outRadius = inRadius; } diff --git a/gsk/vulkan/resources/color-matrix.frag b/gsk/vulkan/resources/color-matrix.frag index 8787eb443f..ebed0638af 100644 --- a/gsk/vulkan/resources/color-matrix.frag +++ b/gsk/vulkan/resources/color-matrix.frag @@ -1,13 +1,13 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in vec2 inTexCoord; layout(location = 2) in flat mat4 inColorMatrix; layout(location = 6) in flat vec4 inColorOffset; - -layout(set = 0, binding = 0) uniform sampler2D inTexture; +layout(location = 7) in flat uint inTexId; layout(location = 0) out vec4 color; @@ -29,5 +29,5 @@ color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset) void main() { - color = clip (inPos, color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset)); + color = clip (inPos, color_matrix (texture (textures[inTexId], inTexCoord), inColorMatrix, inColorOffset)); } diff --git a/gsk/vulkan/resources/color-matrix.vert b/gsk/vulkan/resources/color-matrix.vert index 99487c9063..8f92fff231 100644 --- a/gsk/vulkan/resources/color-matrix.vert +++ b/gsk/vulkan/resources/color-matrix.vert @@ -6,11 +6,13 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inTexRect; layout(location = 2) in mat4 inColorMatrix; layout(location = 6) in vec4 inColorOffset; +layout(location = 7) in uint inTexId; layout(location = 0) out vec2 outPos; layout(location = 1) out vec2 outTexCoord; layout(location = 2) out flat mat4 outColorMatrix; layout(location = 6) out flat vec4 outColorOffset; +layout(location = 7) out flat uint outTexId; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -31,6 +33,7 @@ void main() { texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy, inTexRect.zw * texrect.zw); outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex]; + outTexId = inTexId; outColorMatrix = inColorMatrix; outColorOffset = inColorOffset; } diff --git a/gsk/vulkan/resources/common.frag.glsl b/gsk/vulkan/resources/common.frag.glsl new file mode 100644 index 0000000000..239691d7be --- /dev/null +++ b/gsk/vulkan/resources/common.frag.glsl @@ -0,0 +1,2 @@ + +layout(set = 0, binding = 0) uniform sampler2D textures[50000]; diff --git a/gsk/vulkan/resources/crossfade.frag b/gsk/vulkan/resources/crossfade.frag index 8293b1d5d8..4136637346 100644 --- a/gsk/vulkan/resources/crossfade.frag +++ b/gsk/vulkan/resources/crossfade.frag @@ -1,21 +1,21 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in vec2 inStartTexCoord; layout(location = 2) in vec2 inEndTexCoord; -layout(location = 3) in float inProgress; - -layout(set = 0, binding = 0) uniform sampler2D startTexture; -layout(set = 1, binding = 0) uniform sampler2D endTexture; +layout(location = 3) flat in uint inStartTexId; +layout(location = 4) flat in uint inEndTexId; +layout(location = 5) in float inProgress; layout(location = 0) out vec4 color; void main() { - vec4 start = texture (startTexture, inStartTexCoord); - vec4 end = texture (endTexture, inEndTexCoord); + vec4 start = texture (textures[inStartTexId], inStartTexCoord); + vec4 end = texture (textures[inEndTexId], inEndTexCoord); color = clip (inPos, mix (start, end, inProgress)); } diff --git a/gsk/vulkan/resources/crossfade.vert b/gsk/vulkan/resources/crossfade.vert index eb7a00767a..ff3e73b6df 100644 --- a/gsk/vulkan/resources/crossfade.vert +++ b/gsk/vulkan/resources/crossfade.vert @@ -5,12 +5,16 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inStartTexRect; layout(location = 2) in vec4 inEndTexRect; -layout(location = 3) in float inProgress; +layout(location = 3) in uint inStartTexId; +layout(location = 4) in uint inEndTexId; +layout(location = 5) in float inProgress; layout(location = 0) out vec2 outPos; layout(location = 1) out vec2 outStartTexCoord; layout(location = 2) out vec2 outEndTexCoord; -layout(location = 3) out float outProgress; +layout(location = 3) flat out uint outStartTexId; +layout(location = 4) flat out uint outEndTexId; +layout(location = 5) flat out float outProgress; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -35,6 +39,7 @@ void main() { outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex]; outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex]; - + outStartTexId = inStartTexId; + outEndTexId = inEndTexId; outProgress = inProgress; } diff --git a/gsk/vulkan/resources/mask.frag b/gsk/vulkan/resources/mask.frag index 81f6833ef2..08d3ec5770 100644 --- a/gsk/vulkan/resources/mask.frag +++ b/gsk/vulkan/resources/mask.frag @@ -1,16 +1,16 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in vec2 inTexCoord; layout(location = 2) in vec4 inColor; - -layout(set = 0, binding = 0) uniform sampler2D inTexture; +layout(location = 3) flat in uint inTexId; layout(location = 0) out vec4 color; void main() { - color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * texture(inTexture, inTexCoord).a); + color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * texture(textures[inTexId], inTexCoord).a); } diff --git a/gsk/vulkan/resources/mask.vert b/gsk/vulkan/resources/mask.vert index 1406bfd1d1..09bc2a9909 100644 --- a/gsk/vulkan/resources/mask.vert +++ b/gsk/vulkan/resources/mask.vert @@ -5,10 +5,12 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inTexRect; layout(location = 2) in vec4 inColor; +layout(location = 3) in uint inTexId; layout(location = 0) out vec2 outPos; layout(location = 1) out vec2 outTexCoord; layout(location = 2) out flat vec4 outColor; +layout(location = 3) out flat uint outTexId; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -29,6 +31,6 @@ void main() { texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy, inTexRect.zw * texrect.zw); outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex]; - + outTexId = inTexId; outColor = inColor; } diff --git a/gsk/vulkan/resources/meson.build b/gsk/vulkan/resources/meson.build index 46a065ad09..6eb9057ce8 100644 --- a/gsk/vulkan/resources/meson.build +++ b/gsk/vulkan/resources/meson.build @@ -1,6 +1,7 @@ gsk_private_vulkan_include_shaders = [ 'clip.frag.glsl', 'clip.vert.glsl', + 'common.frag.glsl', 'common.vert.glsl', 'constants.glsl', 'rect.glsl', diff --git a/gsk/vulkan/resources/texture.frag b/gsk/vulkan/resources/texture.frag index 557a63746a..eaaba70fbd 100644 --- a/gsk/vulkan/resources/texture.frag +++ b/gsk/vulkan/resources/texture.frag @@ -1,18 +1,18 @@ #version 420 core +#include "common.frag.glsl" #include "clip.frag.glsl" #include "rect.frag.glsl" layout(location = 0) in vec2 inPos; layout(location = 1) in Rect inRect; layout(location = 2) in vec2 inTexCoord; - -layout(set = 0, binding = 0) uniform sampler2D inTexture; +layout(location = 3) flat in uint inTexId; layout(location = 0) out vec4 color; void main() { float alpha = rect_coverage (inRect, inPos); - color = clip_scaled (inPos, texture (inTexture, inTexCoord) * alpha); + color = clip_scaled (inPos, texture (textures[inTexId], inTexCoord) * alpha); } diff --git a/gsk/vulkan/resources/texture.vert b/gsk/vulkan/resources/texture.vert index 49d30e2e47..69d5a4937d 100644 --- a/gsk/vulkan/resources/texture.vert +++ b/gsk/vulkan/resources/texture.vert @@ -5,10 +5,12 @@ layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inTexRect; +layout(location = 2) in uint inTexId; layout(location = 0) out vec2 outPos; layout(location = 1) out flat Rect outRect; layout(location = 2) out vec2 outTexCoord; +layout(location = 3) out flat uint outTexId; void main() { Rect r = rect_from_gsk (inRect); @@ -17,4 +19,5 @@ void main() { outPos = pos; outRect = r; outTexCoord = scale_tex_coord (pos, r, inTexRect); + outTexId = inTexId; } -- 2.30.2