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)
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++)
.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);
float rect[4];
float start_tex_rect[4];
float end_tex_rect[4];
+ guint32 start_tex_id;
+ guint32 end_tex_id;
guint32 blend_mode;
};
.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),
}
};
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,
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;
}
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,
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)
.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 = {
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,
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
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,
{
float rect[4];
float tex_rect[4];
+ guint32 tex_id;
};
G_DEFINE_TYPE (GskVulkanColorTextPipeline, gsk_vulkan_color_text_pipeline, GSK_TYPE_VULKAN_PIPELINE)
.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,
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
+ guint tex_id,
PangoFont *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
instance->tex_rect[2] = glyph->tw;
instance->tex_rect[3] = glyph->th;
+ instance->tex_id = tex_id;
+
count++;
}
x_position += gi->geometry.width;
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
+ guint tex_id,
PangoFont *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
float rect[4];
float start_tex_rect[4];
float end_tex_rect[4];
+ float start_tex_id;
+ float end_tex_id;
float progress;
};
{
.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),
}
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,
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;
}
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,
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)
.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 = {
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,
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
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,
#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
{
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;
}
}
-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)
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);
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
}
}
},
&(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,
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 (),
}
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
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);
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
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;
g_clear_pointer (&self->uploader, gsk_vulkan_uploader_free);
+
vkDestroyPipelineLayout (device,
self->pipeline_layout,
NULL);
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,
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);
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);
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),
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),
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,
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,
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,
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,
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,
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),
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),
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),
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),
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),
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),
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),
VkPipelineLayout pipeline_layout,
VkCommandBuffer command_buffer)
{
+ VkDescriptorSet descriptor_set;
cairo_rectangle_int_t rect;
vkCmdSetViewport (command_buffer,
},
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);
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);
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)
.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 = {
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
+ guint tex_id,
PangoFont *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
instance->color[2] = color->blue;
instance->color[3] = color->alpha;
+ instance->tex_id = tex_id;
+
count++;
}
x_position += gi->geometry.width;
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
+ guint32 tex_id,
PangoFont *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
{
float rect[4];
float tex_rect[4];
+ guint32 tex_id;
};
G_DEFINE_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK_TYPE_VULKAN_PIPELINE)
.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 = {
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)
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
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);
#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;
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)
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),
outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
-
+ outStartTexId = inStartTexId;
+ outEndTexId = inEndTexId;
outBlendMode = inBlendMode;
}
#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;
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;
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),
texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
inTexRect.zw * texrect.zw);
outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-
+ outTexId = inTexId;
outRadius = inRadius;
}
#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;
void main()
{
- color = clip (inPos, color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset));
+ color = clip (inPos, color_matrix (texture (textures[inTexId], inTexCoord), inColorMatrix, inColorOffset));
}
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),
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;
}
--- /dev/null
+
+layout(set = 0, binding = 0) uniform sampler2D textures[50000];
#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));
}
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),
outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
-
+ outStartTexId = inStartTexId;
+ outEndTexId = inEndTexId;
outProgress = inProgress;
}
#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);
}
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),
texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
inTexRect.zw * texrect.zw);
outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-
+ outTexId = inTexId;
outColor = inColor;
}
gsk_private_vulkan_include_shaders = [
'clip.frag.glsl',
'clip.vert.glsl',
+ 'common.frag.glsl',
'common.vert.glsl',
'constants.glsl',
'rect.glsl',
#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);
}
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);
outPos = pos;
outRect = r;
outTexCoord = scale_tex_coord (pos, r, inTexRect);
+ outTexId = inTexId;
}