mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-04 17:50:18 +00:00
Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Fancy gradients See merge request GNOME/gtk!6073
This commit is contained in:
commit
83efe2b66c
@ -64,6 +64,13 @@ gsk_vulkan_buffer_new (GdkVulkanContext *context,
|
||||
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
}
|
||||
|
||||
GskVulkanBuffer *
|
||||
gsk_vulkan_buffer_new_storage (GdkVulkanContext *context,
|
||||
gsize size)
|
||||
{
|
||||
return gsk_vulkan_buffer_new_internal (context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
GskVulkanBuffer *
|
||||
gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
|
||||
gsize size)
|
||||
|
@ -8,6 +8,8 @@ typedef struct _GskVulkanBuffer GskVulkanBuffer;
|
||||
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new (GdkVulkanContext *context,
|
||||
gsize size);
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new_storage (GdkVulkanContext *context,
|
||||
gsize size);
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
|
||||
gsize size);
|
||||
GskVulkanBuffer * gsk_vulkan_buffer_new_download (GdkVulkanContext *context,
|
||||
|
@ -15,9 +15,8 @@ struct _GskVulkanLinearGradientInstance
|
||||
float start[2];
|
||||
float end[2];
|
||||
gint32 repeating;
|
||||
gint32 offset;
|
||||
gint32 stop_count;
|
||||
float offsets[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS];
|
||||
float colors[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS][4];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
|
||||
@ -61,67 +60,13 @@ gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeli
|
||||
.location = 4,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offset),
|
||||
},
|
||||
{
|
||||
.location = 5,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets),
|
||||
},
|
||||
{
|
||||
.location = 6,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets) + sizeof (float) * 4,
|
||||
},
|
||||
{
|
||||
.location = 7,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[0]),
|
||||
},
|
||||
{
|
||||
.location = 8,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[1]),
|
||||
},
|
||||
{
|
||||
.location = 9,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[2]),
|
||||
},
|
||||
{
|
||||
.location = 10,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[3]),
|
||||
},
|
||||
{
|
||||
.location = 11,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[4]),
|
||||
},
|
||||
{
|
||||
.location = 12,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[5]),
|
||||
},
|
||||
{
|
||||
.location = 13,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[6]),
|
||||
},
|
||||
{
|
||||
.location = 14,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[7]),
|
||||
.format = VK_FORMAT_R32_SINT,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
|
||||
}
|
||||
};
|
||||
static const VkPipelineVertexInputStateCreateInfo info = {
|
||||
@ -169,23 +114,17 @@ gsk_vulkan_linear_gradient_pipeline_new (GdkVulkanContext *context,
|
||||
|
||||
void
|
||||
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradientPipeline *pipeline,
|
||||
guchar *data,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
gboolean repeating,
|
||||
gsize n_stops,
|
||||
const GskColorStop *stops)
|
||||
guchar *data,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
gboolean repeating,
|
||||
gsize gradient_offset,
|
||||
gsize n_stops)
|
||||
{
|
||||
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
|
||||
gsize i;
|
||||
|
||||
if (n_stops > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
|
||||
{
|
||||
g_warning ("Only %u color stops supported.", GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
|
||||
n_stops = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS;
|
||||
}
|
||||
instance->rect[0] = rect->origin.x + offset->x;
|
||||
instance->rect[1] = rect->origin.y + offset->y;
|
||||
instance->rect[2] = rect->size.width;
|
||||
@ -195,15 +134,8 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
|
||||
instance->end[0] = end->x + offset->x;
|
||||
instance->end[1] = end->y + offset->y;
|
||||
instance->repeating = repeating;
|
||||
instance->offset = gradient_offset;
|
||||
instance->stop_count = n_stops;
|
||||
for (i = 0; i < n_stops; i++)
|
||||
{
|
||||
instance->offsets[i] = stops[i].offset;
|
||||
instance->colors[i][0] = stops[i].color.red;
|
||||
instance->colors[i][1] = stops[i].color.green;
|
||||
instance->colors[i][2] = stops[i].color.blue;
|
||||
instance->colors[i][3] = stops[i].color.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
gsize
|
||||
|
@ -28,8 +28,8 @@ void gsk_vulkan_linear_gradient_pipeline_collect_vertex_data
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
gboolean repeating,
|
||||
gsize n_stops,
|
||||
const GskColorStop *stops);
|
||||
gsize gradient_offset,
|
||||
gsize n_stops);
|
||||
gsize gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline*pipeline,
|
||||
VkCommandBuffer command_buffer,
|
||||
gsize offset,
|
||||
|
@ -33,6 +33,14 @@
|
||||
#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 1024
|
||||
#define GDK_ARRAY_NO_MEMSET 1
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
struct _GskVulkanRender
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
@ -52,6 +60,7 @@ struct _GskVulkanRender
|
||||
|
||||
GskDescriptorImageInfos descriptor_images;
|
||||
GskDescriptorImageInfos descriptor_samplers;
|
||||
GskDescriptorBufferInfos descriptor_buffers;
|
||||
VkDescriptorPool descriptor_pool;
|
||||
VkDescriptorSet descriptor_set;
|
||||
GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
|
||||
@ -59,6 +68,9 @@ struct _GskVulkanRender
|
||||
GskVulkanImage *target;
|
||||
|
||||
VkSampler samplers[3];
|
||||
GskVulkanBuffer *storage_buffer;
|
||||
guchar *storage_buffer_memory;
|
||||
gsize storage_buffer_used;
|
||||
|
||||
GList *render_passes;
|
||||
GSList *cleanup_images;
|
||||
@ -122,6 +134,7 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
self->framebuffers = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
gsk_descriptor_image_infos_init (&self->descriptor_images);
|
||||
gsk_descriptor_image_infos_init (&self->descriptor_samplers);
|
||||
gsk_descriptor_buffer_infos_init (&self->descriptor_buffers);
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
@ -139,8 +152,8 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
||||
.maxSets = 1,
|
||||
.poolSizeCount = 2,
|
||||
.pPoolSizes = (VkDescriptorPoolSize[2]) {
|
||||
.poolSizeCount = 3,
|
||||
.pPoolSizes = (VkDescriptorPoolSize[3]) {
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS
|
||||
@ -148,6 +161,10 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS
|
||||
},
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -197,9 +214,9 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
|
||||
&(VkDescriptorSetLayoutCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = 2,
|
||||
.bindingCount = 3,
|
||||
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
||||
.pBindings = (VkDescriptorSetLayoutBinding[2]) {
|
||||
.pBindings = (VkDescriptorSetLayoutBinding[3]) {
|
||||
{
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
@ -211,12 +228,21 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
}
|
||||
},
|
||||
{
|
||||
.binding = 2,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
},
|
||||
},
|
||||
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
.bindingCount = 2,
|
||||
.pBindingFlags = (VkDescriptorBindingFlags[2]) {
|
||||
.bindingCount = 3,
|
||||
.pBindingFlags = (VkDescriptorBindingFlags[3]) {
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
|
||||
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
|
||||
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
|
||||
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
|
||||
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
|
||||
@ -520,10 +546,81 @@ gsk_vulkan_render_get_image_descriptor (GskVulkanRender *self,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_render_ensure_storage_buffer (GskVulkanRender *self)
|
||||
{
|
||||
if (self->storage_buffer_memory != NULL)
|
||||
return;
|
||||
|
||||
if (self->storage_buffer == NULL)
|
||||
{
|
||||
self->storage_buffer = gsk_vulkan_buffer_new_storage (self->vulkan,
|
||||
/* random */
|
||||
sizeof (float) * 1024 * 1024);
|
||||
}
|
||||
|
||||
self->storage_buffer_memory = gsk_vulkan_buffer_map (self->storage_buffer);
|
||||
|
||||
if (gsk_vulkan_render_get_buffer_descriptor (self, self->storage_buffer) != 0)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_vulkan_render_get_buffer_descriptor (GskVulkanRender *self,
|
||||
GskVulkanBuffer *buffer)
|
||||
{
|
||||
gsize result;
|
||||
|
||||
gsk_vulkan_render_ensure_storage_buffer (self);
|
||||
|
||||
result = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers);
|
||||
gsk_descriptor_buffer_infos_append (&self->descriptor_buffers,
|
||||
&(VkDescriptorBufferInfo) {
|
||||
.buffer = gsk_vulkan_buffer_get_buffer (buffer),
|
||||
.offset = 0,
|
||||
.range = VK_WHOLE_SIZE
|
||||
});
|
||||
|
||||
g_assert (result < DESCRIPTOR_POOL_MAXITEMS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline gsize
|
||||
round_up (gsize number, gsize divisor)
|
||||
{
|
||||
return (number + divisor - 1) / divisor * divisor;
|
||||
}
|
||||
|
||||
guchar *
|
||||
gsk_vulkan_render_get_buffer_memory (GskVulkanRender *self,
|
||||
gsize size,
|
||||
gsize alignment,
|
||||
gsize *out_offset)
|
||||
{
|
||||
guchar *result;
|
||||
|
||||
g_assert (alignment >= sizeof (float));
|
||||
|
||||
gsk_vulkan_render_ensure_storage_buffer (self);
|
||||
|
||||
self->storage_buffer_used = round_up (self->storage_buffer_used, alignment);
|
||||
result = self->storage_buffer_memory + self->storage_buffer_used;
|
||||
*out_offset = self->storage_buffer_used / sizeof (float);
|
||||
|
||||
self->storage_buffer_used += size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
|
||||
{
|
||||
VkDevice device;
|
||||
VkWriteDescriptorSet descriptor_sets[3];
|
||||
gsize n_descriptor_sets;
|
||||
GList *l;
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
@ -535,9 +632,16 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
|
||||
}
|
||||
|
||||
if (gsk_descriptor_image_infos_get_size (&self->descriptor_samplers) == 0 &&
|
||||
gsk_descriptor_image_infos_get_size (&self->descriptor_images) == 0)
|
||||
gsk_descriptor_image_infos_get_size (&self->descriptor_images) == 0 &&
|
||||
gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) == 0)
|
||||
return;
|
||||
|
||||
if (self->storage_buffer_memory)
|
||||
{
|
||||
gsk_vulkan_buffer_unmap (self->storage_buffer);
|
||||
self->storage_buffer_memory = NULL;
|
||||
}
|
||||
|
||||
GSK_VK_CHECK (vkAllocateDescriptorSets, device,
|
||||
&(VkDescriptorSetAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
@ -550,33 +654,53 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
|
||||
.pDescriptorCounts = (uint32_t[1]) {
|
||||
gsk_descriptor_image_infos_get_size (&self->descriptor_images)
|
||||
+ gsk_descriptor_image_infos_get_size (&self->descriptor_samplers)
|
||||
+ gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)
|
||||
}
|
||||
}
|
||||
},
|
||||
&self->descriptor_set);
|
||||
|
||||
n_descriptor_sets = 0;
|
||||
if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) > 0)
|
||||
{
|
||||
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->descriptor_set,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_images)
|
||||
};
|
||||
}
|
||||
if (gsk_descriptor_image_infos_get_size (&self->descriptor_samplers) > 0)
|
||||
{
|
||||
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->descriptor_set,
|
||||
.dstBinding = 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_samplers),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_samplers)
|
||||
};
|
||||
}
|
||||
if (gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) > 0)
|
||||
{
|
||||
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->descriptor_set,
|
||||
.dstBinding = 2,
|
||||
.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 (device,
|
||||
2,
|
||||
(VkWriteDescriptorSet[2]) {
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->descriptor_set,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_images)
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = self->descriptor_set,
|
||||
.dstBinding = 1,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_samplers),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = gsk_descriptor_image_infos_get_data (&self->descriptor_samplers)
|
||||
}
|
||||
},
|
||||
n_descriptor_sets,
|
||||
descriptor_sets,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
@ -672,6 +796,7 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
|
||||
0);
|
||||
gsk_descriptor_image_infos_set_size (&self->descriptor_images, 0);
|
||||
gsk_descriptor_image_infos_set_size (&self->descriptor_samplers, 0);
|
||||
gsk_descriptor_buffer_infos_set_size (&self->descriptor_buffers, 0);
|
||||
|
||||
g_list_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
|
||||
self->render_passes = NULL;
|
||||
@ -727,6 +852,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
NULL);
|
||||
gsk_descriptor_image_infos_clear (&self->descriptor_images);
|
||||
gsk_descriptor_image_infos_clear (&self->descriptor_samplers);
|
||||
gsk_descriptor_buffer_infos_clear (&self->descriptor_buffers);
|
||||
|
||||
vkDestroyDescriptorSetLayout (device,
|
||||
self->descriptor_set_layout,
|
||||
|
@ -77,6 +77,7 @@ struct _GskVulkanOpRender
|
||||
gsize vertex_offset; /* offset into vertex buffer */
|
||||
guint32 image_descriptor[2]; /* index into descriptor for the (image, sampler) */
|
||||
guint32 image_descriptor2[2]; /* index into descriptor for the 2nd image (if relevant) */
|
||||
gsize buffer_offset; /* offset into buffer */
|
||||
graphene_rect_t source_rect; /* area that source maps to */
|
||||
graphene_rect_t source2_rect; /* area that source2 maps to */
|
||||
};
|
||||
@ -406,10 +407,10 @@ gsk_vulkan_render_pass_add_color_node (GskVulkanRenderPass *self,
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_vulkan_render_pass_add_repeating_linear_gradient_node (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
const GskVulkanParseState *state,
|
||||
GskRenderNode *node)
|
||||
gsk_vulkan_render_pass_add_linear_gradient_node (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
const GskVulkanParseState *state,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskVulkanPipelineType pipeline_type;
|
||||
GskVulkanOp op = {
|
||||
@ -418,11 +419,6 @@ gsk_vulkan_render_pass_add_repeating_linear_gradient_node (GskVulkanRenderPass
|
||||
.render.offset = state->offset,
|
||||
};
|
||||
|
||||
if (gsk_linear_gradient_node_get_n_color_stops (node) > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
|
||||
FALLBACK ("Linear gradient with %zu color stops, hardcoded limit is %u",
|
||||
gsk_linear_gradient_node_get_n_color_stops (node),
|
||||
GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
|
||||
|
||||
if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT;
|
||||
else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
|
||||
@ -1138,8 +1134,8 @@ static const GskVulkanRenderPassNodeFunc nodes_vtable[N_RENDER_NODES] = {
|
||||
[GSK_CONTAINER_NODE] = gsk_vulkan_render_pass_add_container_node,
|
||||
[GSK_CAIRO_NODE] = gsk_vulkan_render_pass_add_cairo_node,
|
||||
[GSK_COLOR_NODE] = gsk_vulkan_render_pass_add_color_node,
|
||||
[GSK_LINEAR_GRADIENT_NODE] = gsk_vulkan_render_pass_add_repeating_linear_gradient_node,
|
||||
[GSK_REPEATING_LINEAR_GRADIENT_NODE] = gsk_vulkan_render_pass_add_repeating_linear_gradient_node,
|
||||
[GSK_LINEAR_GRADIENT_NODE] = gsk_vulkan_render_pass_add_linear_gradient_node,
|
||||
[GSK_REPEATING_LINEAR_GRADIENT_NODE] = gsk_vulkan_render_pass_add_linear_gradient_node,
|
||||
[GSK_RADIAL_GRADIENT_NODE] = NULL,
|
||||
[GSK_REPEATING_RADIAL_GRADIENT_NODE] = NULL,
|
||||
[GSK_CONIC_GRADIENT_NODE] = NULL,
|
||||
@ -1896,8 +1892,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
gsk_linear_gradient_node_get_start (op->render.node),
|
||||
gsk_linear_gradient_node_get_end (op->render.node),
|
||||
gsk_render_node_get_node_type (op->render.node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
|
||||
gsk_linear_gradient_node_get_n_color_stops (op->render.node),
|
||||
gsk_linear_gradient_node_get_color_stops (op->render.node, NULL));
|
||||
op->render.buffer_offset,
|
||||
gsk_linear_gradient_node_get_n_color_stops (op->render.node));
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_OPACITY:
|
||||
@ -2125,11 +2121,25 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
{
|
||||
gsize n_stops = gsk_linear_gradient_node_get_n_color_stops (op->render.node);
|
||||
guchar *mem;
|
||||
|
||||
mem = gsk_vulkan_render_get_buffer_memory (render,
|
||||
n_stops * sizeof (GskColorStop),
|
||||
G_ALIGNOF (GskColorStop),
|
||||
&op->render.buffer_offset);
|
||||
memcpy (mem,
|
||||
gsk_linear_gradient_node_get_color_stops (op->render.node, NULL),
|
||||
n_stops * sizeof (GskColorStop));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
|
||||
case GSK_VULKAN_OP_COLOR:
|
||||
case GSK_VULKAN_OP_LINEAR_GRADIENT:
|
||||
case GSK_VULKAN_OP_BORDER:
|
||||
case GSK_VULKAN_OP_INSET_SHADOW:
|
||||
case GSK_VULKAN_OP_OUTSET_SHADOW:
|
||||
|
@ -86,6 +86,12 @@ gsize gsk_vulkan_render_get_sampler_descriptor (GskVulk
|
||||
GskVulkanRenderSampler render_sampler);
|
||||
gsize gsk_vulkan_render_get_image_descriptor (GskVulkanRender *self,
|
||||
GskVulkanImage *source);
|
||||
gsize gsk_vulkan_render_get_buffer_descriptor (GskVulkanRender *self,
|
||||
GskVulkanBuffer *buffer);
|
||||
guchar * gsk_vulkan_render_get_buffer_memory (GskVulkanRender *self,
|
||||
gsize size,
|
||||
gsize alignment,
|
||||
gsize *out_offset);
|
||||
VkDescriptorSet gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self);
|
||||
|
||||
void gsk_vulkan_render_draw (GskVulkanRender *self);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.vert.glsl"
|
||||
#include "rect.vert.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.frag.glsl"
|
||||
#include "rounded-rect.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
#include "rounded-rect.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.vert.glsl"
|
||||
#include "rect.vert.glsl"
|
||||
|
@ -1,6 +1,10 @@
|
||||
|
||||
layout(set = 0, binding = 0) uniform texture2D textures[50000];
|
||||
layout(set = 0, binding = 1) uniform sampler samplers[50000];
|
||||
layout(set = 0, binding = 2) readonly buffer FloatBuffers {
|
||||
float floats[];
|
||||
} buffers[50000];
|
||||
|
||||
#define get_sampler(id) sampler2D(textures[id.x], samplers[id.y])
|
||||
#define get_buffer(id) buffers[id]
|
||||
#define get_float(id) get_buffer(0).floats[id]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.vert.glsl"
|
||||
#include "rect.vert.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.frag.glsl"
|
||||
#include "rounded-rect.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
|
||||
|
@ -1,36 +1,128 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
vec4 color;
|
||||
};
|
||||
#include "rect.frag.glsl"
|
||||
|
||||
layout(location = 0) in vec2 inPos;
|
||||
layout(location = 1) in float inGradientPos;
|
||||
layout(location = 2) in flat int inRepeating;
|
||||
layout(location = 3) in flat int inStopCount;
|
||||
layout(location = 4) in flat ColorStop inStops[8];
|
||||
layout(location = 1) in flat Rect inRect;
|
||||
layout(location = 2) in float inGradientPos;
|
||||
layout(location = 3) in flat int inRepeating;
|
||||
layout(location = 4) in flat int inStopOffset;
|
||||
layout(location = 5) in flat int inStopCount;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
float
|
||||
get_offset (int i)
|
||||
{
|
||||
return get_float (inStopOffset + i * 5);
|
||||
}
|
||||
|
||||
vec4
|
||||
get_color (int i)
|
||||
{
|
||||
i = clamp (i, 0, inStopCount - 1);
|
||||
return color = vec4 (get_float (inStopOffset + i * 5 + 1),
|
||||
get_float (inStopOffset + i * 5 + 2),
|
||||
get_float (inStopOffset + i * 5 + 3),
|
||||
get_float (inStopOffset + i * 5 + 4));
|
||||
}
|
||||
|
||||
vec4
|
||||
get_color_for_range_unscaled (float start,
|
||||
float end)
|
||||
{
|
||||
vec4 result = vec4 (0);
|
||||
float offset;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < inStopCount; i++)
|
||||
{
|
||||
offset = get_offset (i);
|
||||
if (offset >= start)
|
||||
break;
|
||||
}
|
||||
if (i == inStopCount)
|
||||
offset = 1;
|
||||
|
||||
float last_offset = i > 0 ? get_offset (i - 1) : 0;
|
||||
vec4 last_color = get_color (i - 1);
|
||||
vec4 color = get_color (i);
|
||||
if (last_offset < start)
|
||||
{
|
||||
last_color = mix (last_color, color, (start - last_offset) / (offset - last_offset));
|
||||
last_offset = start;
|
||||
}
|
||||
if (end <= start)
|
||||
return last_color;
|
||||
|
||||
for (; i < inStopCount; i++)
|
||||
{
|
||||
offset = get_offset (i);
|
||||
color = get_color (i);
|
||||
if (offset >= end)
|
||||
break;
|
||||
result += 0.5 * (color + last_color) * (offset - last_offset);
|
||||
last_offset = offset;
|
||||
last_color = color;
|
||||
}
|
||||
if (i == inStopCount)
|
||||
{
|
||||
offset = 1;
|
||||
color = get_color (i);
|
||||
}
|
||||
if (offset > end)
|
||||
{
|
||||
color = mix (last_color, color, (end - last_offset) / (offset - last_offset));
|
||||
offset = end;
|
||||
}
|
||||
result += 0.5 * (color + last_color) * (offset - last_offset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4
|
||||
get_color_for_range (float start,
|
||||
float end)
|
||||
{
|
||||
return get_color_for_range_unscaled (start, end) / (end - start);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float pos;
|
||||
if (inRepeating != 0)
|
||||
pos = fract (inGradientPos);
|
||||
else
|
||||
pos = clamp (inGradientPos, 0, 1);
|
||||
vec4 c;
|
||||
float pos_start, pos_end;
|
||||
float dPos = 0.5 * abs (fwidth (inGradientPos));
|
||||
|
||||
vec4 color = inStops[0].color;
|
||||
int n = clamp (inStopCount, 2, 8);
|
||||
for (int i = 1; i < n; i++)
|
||||
if (inRepeating != 0)
|
||||
{
|
||||
if (inStops[i].offset > inStops[i-1].offset)
|
||||
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
|
||||
pos_start = inGradientPos - dPos;
|
||||
pos_end = inGradientPos + dPos;
|
||||
if (floor (pos_end) > floor (pos_start))
|
||||
{
|
||||
float fract_end = fract(pos_end);
|
||||
float fract_start = fract(pos_start);
|
||||
float n = floor (pos_end) - floor (pos_start);
|
||||
if (fract_end > fract_start + 0.01)
|
||||
c = get_color_for_range_unscaled (fract_start, fract_end);
|
||||
else if (fract_start > fract_end + 0.01)
|
||||
c = -get_color_for_range_unscaled (fract_end, fract_start);
|
||||
c += get_color_for_range_unscaled (0.0, 1.0) * n;
|
||||
c /= pos_end - pos_start;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = get_color_for_range (fract (pos_start), fract (pos_end));
|
||||
}
|
||||
}
|
||||
|
||||
//outColor = vec4(pos, pos, pos, 1.0);
|
||||
outColor = clip (inPos, color);
|
||||
else
|
||||
{
|
||||
pos_start = clamp (inGradientPos - dPos, 0, 1);
|
||||
pos_end = clamp (inGradientPos + dPos, 0, 1);
|
||||
c = get_color_for_range (pos_start, pos_end);
|
||||
}
|
||||
|
||||
float alpha = c.a * rect_coverage (inRect, inPos);
|
||||
color = clip_scaled (inPos, vec4(c.rgb, 1) * alpha);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
#include "common.vert.glsl"
|
||||
#include "rect.vert.glsl"
|
||||
|
||||
struct ColorStop {
|
||||
float offset;
|
||||
@ -11,62 +12,32 @@ layout(location = 0) in vec4 inRect;
|
||||
layout(location = 1) in vec2 inStart;
|
||||
layout(location = 2) in vec2 inEnd;
|
||||
layout(location = 3) in int inRepeating;
|
||||
layout(location = 4) in int inStopCount;
|
||||
layout(location = 5) in vec4 inOffsets0;
|
||||
layout(location = 6) in vec4 inOffsets1;
|
||||
layout(location = 7) in vec4 inColors0;
|
||||
layout(location = 8) in vec4 inColors1;
|
||||
layout(location = 9) in vec4 inColors2;
|
||||
layout(location = 10) in vec4 inColors3;
|
||||
layout(location = 11) in vec4 inColors4;
|
||||
layout(location = 12) in vec4 inColors5;
|
||||
layout(location = 13) in vec4 inColors6;
|
||||
layout(location = 14) in vec4 inColors7;
|
||||
layout(location = 4) in int inStopOffset;
|
||||
layout(location = 5) in int inStopCount;
|
||||
|
||||
layout(location = 0) out vec2 outPos;
|
||||
layout(location = 1) out float outGradientPos;
|
||||
layout(location = 2) out flat int outRepeating;
|
||||
layout(location = 3) out flat int outStopCount;
|
||||
layout(location = 4) out flat ColorStop outStops[8];
|
||||
|
||||
vec2 offsets[6] = { vec2(0.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0) };
|
||||
layout(location = 1) out flat Rect outRect;
|
||||
layout(location = 2) out float outGradientPos;
|
||||
layout(location = 3) out flat int outRepeating;
|
||||
layout(location = 4) out flat int outStopOffset;
|
||||
layout(location = 5) out flat int outStopCount;
|
||||
|
||||
float
|
||||
get_gradient_pos (vec2 pos)
|
||||
{
|
||||
pos = pos - inStart;
|
||||
vec2 grad = inEnd - inStart;
|
||||
pos = pos - inStart * push.scale;
|
||||
vec2 grad = (inEnd - inStart) * push.scale;
|
||||
|
||||
return dot (pos, grad) / dot (grad, grad);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 rect = clip (inRect);
|
||||
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
|
||||
gl_Position = push.mvp * vec4 (push.scale * pos, 0.0, 1.0);
|
||||
Rect r = rect_from_gsk (inRect);
|
||||
vec2 pos = set_position_from_rect (r);
|
||||
outPos = pos;
|
||||
outRect = r;
|
||||
outGradientPos = get_gradient_pos (pos);
|
||||
outRepeating = inRepeating;
|
||||
outStopOffset = inStopOffset;
|
||||
outStopCount = inStopCount;
|
||||
outStops[0].offset = inOffsets0[0];
|
||||
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
|
||||
outStops[1].offset = inOffsets0[1];
|
||||
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
|
||||
outStops[2].offset = inOffsets0[2];
|
||||
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
|
||||
outStops[3].offset = inOffsets0[3];
|
||||
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
|
||||
outStops[4].offset = inOffsets1[0];
|
||||
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
|
||||
outStops[5].offset = inOffsets1[1];
|
||||
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
|
||||
outStops[6].offset = inOffsets1[2];
|
||||
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
|
||||
outStops[7].offset = inOffsets1[3];
|
||||
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.frag.glsl"
|
||||
#include "rounded-rect.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "clip.vert.glsl"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.frag.glsl"
|
||||
#include "clip.frag.glsl"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 420 core
|
||||
#version 450
|
||||
|
||||
#include "common.vert.glsl"
|
||||
#include "rect.vert.glsl"
|
||||
|
9
testsuite/gsk/compare/repeating-gradient-scaled.node
Normal file
9
testsuite/gsk/compare/repeating-gradient-scaled.node
Normal file
@ -0,0 +1,9 @@
|
||||
transform {
|
||||
transform: scale(10);
|
||||
child: repeating-linear-gradient {
|
||||
bounds: 0 0 5 5;
|
||||
start: 0 0;
|
||||
end: 0 1;
|
||||
stops: 0 white, 0.5 white, 0.5 black, 1 black;
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/repeating-gradient-scaled.png
Normal file
BIN
testsuite/gsk/compare/repeating-gradient-scaled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 166 B |
@ -80,6 +80,7 @@ compare_render_tests = [
|
||||
'repeat-empty-child-bounds',
|
||||
'repeat-negative-coords',
|
||||
'repeat-texture',
|
||||
'repeating-gradient-scaled',
|
||||
'scale-textures-negative-ngl',
|
||||
'scale-up-down',
|
||||
'scaled-cairo',
|
||||
|
Loading…
Reference in New Issue
Block a user