diff --git a/gsk/gskvulkancrossfadepipeline.c b/gsk/gskvulkancrossfadepipeline.c new file mode 100644 index 0000000000..a0de8c3d56 --- /dev/null +++ b/gsk/gskvulkancrossfadepipeline.c @@ -0,0 +1,146 @@ +#include "config.h" + +#include "gskvulkancrossfadepipelineprivate.h" + +struct _GskVulkanCrossFadePipeline +{ + GObject parent_instance; +}; + +typedef struct _GskVulkanCrossFadeInstance GskVulkanCrossFadeInstance; + +struct _GskVulkanCrossFadeInstance +{ + float rect[4]; + float start_tex_rect[4]; + float end_tex_rect[4]; + float progress; +}; + +G_DEFINE_TYPE (GskVulkanCrossFadePipeline, gsk_vulkan_cross_fade_pipeline, GSK_TYPE_VULKAN_PIPELINE) + +static const VkPipelineVertexInputStateCreateInfo * +gsk_vulkan_cross_fade_pipeline_get_input_state_create_info (GskVulkanPipeline *self) +{ + static const VkVertexInputBindingDescription vertexBindingDescriptions[] = { + { + .binding = 0, + .stride = sizeof (GskVulkanCrossFadeInstance), + .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE + } + }; + static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = 0, + }, + { + .location = 1, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_rect), + }, + { + .location = 2, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_rect), + }, + { + .location = 3, + .binding = 0, + .format = VK_FORMAT_R32_SFLOAT, + .offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, progress), + } + }; + static const VkPipelineVertexInputStateCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions), + .pVertexBindingDescriptions = vertexBindingDescriptions, + .vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription), + .pVertexAttributeDescriptions = vertexInputAttributeDescription + }; + + return &info; +} + +static void +gsk_vulkan_cross_fade_pipeline_finalize (GObject *gobject) +{ + //GskVulkanCrossFadePipeline *self = GSK_VULKAN_BLUR_PIPELINE (gobject); + + G_OBJECT_CLASS (gsk_vulkan_cross_fade_pipeline_parent_class)->finalize (gobject); +} + +static void +gsk_vulkan_cross_fade_pipeline_class_init (GskVulkanCrossFadePipelineClass *klass) +{ + GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass); + + G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_cross_fade_pipeline_finalize; + + pipeline_class->get_input_state_create_info = gsk_vulkan_cross_fade_pipeline_get_input_state_create_info; +} + +static void +gsk_vulkan_cross_fade_pipeline_init (GskVulkanCrossFadePipeline *self) +{ +} + +GskVulkanPipeline * +gsk_vulkan_cross_fade_pipeline_new (GdkVulkanContext *context, + VkPipelineLayout layout, + const char *shader_name, + VkRenderPass render_pass) +{ + return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_CROSS_FADE_PIPELINE, context, layout, shader_name, render_pass); +} + +gsize +gsk_vulkan_cross_fade_pipeline_count_vertex_data (GskVulkanCrossFadePipeline *pipeline) +{ + return sizeof (GskVulkanCrossFadeInstance); +} + +void +gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline *pipeline, + guchar *data, + const graphene_rect_t *bounds, + const graphene_rect_t *start_bounds, + const graphene_rect_t *end_bounds, + double progress) +{ + GskVulkanCrossFadeInstance *instance = (GskVulkanCrossFadeInstance *) data; + + instance->rect[0] = bounds->origin.x; + instance->rect[1] = bounds->origin.y; + instance->rect[2] = bounds->size.width; + instance->rect[3] = bounds->size.height; + + instance->start_tex_rect[0] = (bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; + instance->start_tex_rect[1] = (bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; + instance->start_tex_rect[2] = (bounds->size.width + bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; + instance->start_tex_rect[3] = (bounds->size.height + bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; + + instance->end_tex_rect[0] = (bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; + instance->end_tex_rect[1] = (bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; + instance->end_tex_rect[2] = (bounds->size.width + bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; + instance->end_tex_rect[3] = (bounds->size.height + bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; + + instance->progress = progress; +} + +gsize +gsk_vulkan_cross_fade_pipeline_draw (GskVulkanCrossFadePipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands) +{ + vkCmdDraw (command_buffer, + 6, n_commands, + 0, offset); + + return n_commands; +} diff --git a/gsk/gskvulkancrossfadepipelineprivate.h b/gsk/gskvulkancrossfadepipelineprivate.h new file mode 100644 index 0000000000..da5e820365 --- /dev/null +++ b/gsk/gskvulkancrossfadepipelineprivate.h @@ -0,0 +1,35 @@ +#ifndef __GSK_VULKAN_CROSS_FADE_PIPELINE_PRIVATE_H__ +#define __GSK_VULKAN_CROSS_FADE_PIPELINE_PRIVATE_H__ + +#include + +#include "gskvulkanpipelineprivate.h" + +G_BEGIN_DECLS + +typedef struct _GskVulkanCrossFadePipelineLayout GskVulkanCrossFadePipelineLayout; + +#define GSK_TYPE_VULKAN_CROSS_FADE_PIPELINE (gsk_vulkan_cross_fade_pipeline_get_type ()) + +G_DECLARE_FINAL_TYPE (GskVulkanCrossFadePipeline, gsk_vulkan_cross_fade_pipeline, GSK, VULKAN_CROSS_FADE_PIPELINE, GskVulkanPipeline) + +GskVulkanPipeline * gsk_vulkan_cross_fade_pipeline_new (GdkVulkanContext *context, + VkPipelineLayout layout, + const char *shader_name, + VkRenderPass render_pass); + +gsize gsk_vulkan_cross_fade_pipeline_count_vertex_data (GskVulkanCrossFadePipeline *pipeline); +void gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline *pipeline, + guchar *data, + const graphene_rect_t *bounds, + const graphene_rect_t *start_bounds, + const graphene_rect_t *end_bounds, + double progress); +gsize gsk_vulkan_cross_fade_pipeline_draw (GskVulkanCrossFadePipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands); + +G_END_DECLS + +#endif /* __GSK_VULKAN_CROSS_FADE_PIPELINE_PRIVATE_H__ */ diff --git a/gsk/gskvulkanpipelineprivate.h b/gsk/gskvulkanpipelineprivate.h index 33660e1ecc..cd41f822b3 100644 --- a/gsk/gskvulkanpipelineprivate.h +++ b/gsk/gskvulkanpipelineprivate.h @@ -32,7 +32,6 @@ gsk_vulkan_handle_result (VkResult res, #define GSK_VK_CHECK(func, ...) gsk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func)) - GskVulkanPipeline * gsk_vulkan_pipeline_new (GType pipeline_type, GdkVulkanContext *context, VkPipelineLayout layout, diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index e21bef67f2..06b622db59 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -16,6 +16,7 @@ #include "gskvulkanboxshadowpipelineprivate.h" #include "gskvulkancolorpipelineprivate.h" #include "gskvulkancolortextpipelineprivate.h" +#include "gskvulkancrossfadepipelineprivate.h" #include "gskvulkaneffectpipelineprivate.h" #include "gskvulkanlineargradientpipelineprivate.h" #include "gskvulkantextpipelineprivate.h" @@ -388,6 +389,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, { "blend", 1, gsk_vulkan_color_text_pipeline_new }, { "blend-clip", 1, gsk_vulkan_color_text_pipeline_new }, { "blend-clip-rounded", 1, gsk_vulkan_color_text_pipeline_new }, + { "crossfade", 2, gsk_vulkan_cross_fade_pipeline_new }, + { "crossfade-clip", 2, gsk_vulkan_cross_fade_pipeline_new }, + { "crossfade-clip-rounded", 2, gsk_vulkan_cross_fade_pipeline_new }, }; g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL); diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 9fe3764323..866a4eaa73 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -13,6 +13,7 @@ #include "gskvulkanclipprivate.h" #include "gskvulkancolorpipelineprivate.h" #include "gskvulkancolortextpipelineprivate.h" +#include "gskvulkancrossfadepipelineprivate.h" #include "gskvulkaneffectpipelineprivate.h" #include "gskvulkanlineargradientpipelineprivate.h" #include "gskvulkantextpipelineprivate.h" @@ -26,6 +27,7 @@ typedef union _GskVulkanOp GskVulkanOp; typedef struct _GskVulkanOpRender GskVulkanOpRender; typedef struct _GskVulkanOpText GskVulkanOpText; +typedef struct _GskVulkanOpCrossFade GskVulkanOpCrossFade; typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants; typedef enum { @@ -35,8 +37,6 @@ typedef enum { GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP, GSK_VULKAN_OP_SURFACE, GSK_VULKAN_OP_TEXTURE, - GSK_VULKAN_OP_TEXT, - GSK_VULKAN_OP_COLOR_TEXT, GSK_VULKAN_OP_COLOR, GSK_VULKAN_OP_LINEAR_GRADIENT, GSK_VULKAN_OP_OPACITY, @@ -45,8 +45,13 @@ typedef enum { GSK_VULKAN_OP_BORDER, GSK_VULKAN_OP_INSET_SHADOW, GSK_VULKAN_OP_OUTSET_SHADOW, + /* GskVulkanOpText */ + GSK_VULKAN_OP_TEXT, + GSK_VULKAN_OP_COLOR_TEXT, + /* GskVulkanOpCrossFade */ + GSK_VULKAN_OP_CROSS_FADE, /* GskVulkanOpPushConstants */ - GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS + GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS, } GskVulkanOpType; struct _GskVulkanOpRender @@ -76,6 +81,20 @@ struct _GskVulkanOpText guint num_glyphs; /* number of *non-empty* glyphs (== instances) we render */ }; +struct _GskVulkanOpCrossFade +{ + GskVulkanOpType type; + GskRenderNode *node; /* node that's the source of this op */ + GskVulkanPipeline *pipeline; /* pipeline to use */ + GskRoundedRect clip; /* clip rect (or random memory if not relevant) */ + GskVulkanImage *start; /* source images to render */ + GskVulkanImage *end; + gsize vertex_offset; /* offset into vertex buffer */ + gsize vertex_count; /* number of vertices */ + gsize descriptor_set_start; /* indices into descriptor sets array */ + gsize descriptor_set_end; +}; + struct _GskVulkanOpPushConstants { GskVulkanOpType type; @@ -87,8 +106,9 @@ union _GskVulkanOp { GskVulkanOpType type; GskVulkanOpRender render; - GskVulkanOpPushConstants constants; GskVulkanOpText text; + GskVulkanOpCrossFade crossfade; + GskVulkanOpPushConstants constants; }; struct _GskVulkanRenderPass @@ -161,10 +181,23 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, case GSK_REPEAT_NODE: case GSK_SHADOW_NODE: case GSK_BLEND_NODE: - case GSK_CROSS_FADE_NODE: default: FALLBACK ("Unsupported node '%s'\n", node->node_class->type_name); + case GSK_CROSS_FADE_NODE: + if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) + pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE; + else if (constants->clip.type == GSK_VULKAN_CLIP_RECT) + pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP; + else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR) + pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP_ROUNDED; + else + FALLBACK ("Cross fade nodes can't deal with clip type %u\n", constants->clip.type); + op.type = GSK_VULKAN_OP_CROSS_FADE; + op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type); + g_array_append_val (self->render_ops, op); + return; + case GSK_INSET_SHADOW_NODE: if (gsk_inset_shadow_node_get_blur_radius (node) > 0) FALLBACK ("Blur support not implemented for inset shadows\n"); @@ -707,6 +740,24 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, } break; + case GSK_VULKAN_OP_CROSS_FADE: + { + GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->crossfade.node); + GskRenderNode *end = gsk_cross_fade_node_get_end_child (op->crossfade.node); + + op->crossfade.start = gsk_vulkan_render_pass_get_node_as_texture (self, + render, + uploader, + start, + &start->bounds); + op->crossfade.end = gsk_vulkan_render_pass_get_node_as_texture (self, + render, + uploader, + end, + &end->bounds); + } + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_COLOR: @@ -787,6 +838,11 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) n_bytes += op->render.vertex_count; break; + case GSK_VULKAN_OP_CROSS_FADE: + op->crossfade.vertex_count = gsk_vulkan_cross_fade_pipeline_count_vertex_data (GSK_VULKAN_CROSS_FADE_PIPELINE (op->crossfade.pipeline)); + n_bytes += op->crossfade.vertex_count; + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: @@ -977,6 +1033,22 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, } break; + case GSK_VULKAN_OP_CROSS_FADE: + { + GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->crossfade.node); + GskRenderNode *end = gsk_cross_fade_node_get_end_child (op->crossfade.node); + + op->crossfade.vertex_offset = offset + n_bytes; + gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GSK_VULKAN_CROSS_FADE_PIPELINE (op->crossfade.pipeline), + data + n_bytes + offset, + &op->crossfade.node->bounds, + &start->bounds, + &end->bounds, + gsk_cross_fade_node_get_progress (op->crossfade.node)); + n_bytes += op->crossfade.vertex_count; + } + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: @@ -1017,6 +1089,12 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, case GSK_VULKAN_OP_COLOR_TEXT: op->text.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->text.source); break; + + case GSK_VULKAN_OP_CROSS_FADE: + op->crossfade.descriptor_set_start = gsk_vulkan_render_reserve_descriptor_set (render, op->crossfade.start); + op->crossfade.descriptor_set_end = gsk_vulkan_render_reserve_descriptor_set (render, op->crossfade.end); + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_COLOR: @@ -1320,6 +1398,40 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, pipeline_layout[i]); break; + case GSK_VULKAN_OP_CROSS_FADE: + if (current_pipeline != op->crossfade.pipeline) + { + current_pipeline = op->crossfade.pipeline; + vkCmdBindPipeline (command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + gsk_vulkan_pipeline_get_pipeline (current_pipeline)); + vkCmdBindVertexBuffers (command_buffer, + 0, + 1, + (VkBuffer[1]) { + gsk_vulkan_buffer_get_buffer (vertex_buffer) + }, + (VkDeviceSize[1]) { op->crossfade.vertex_offset }); + current_draw_index = 0; + } + + vkCmdBindDescriptorSets (command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + gsk_vulkan_pipeline_get_pipeline_layout (current_pipeline), + 0, + 2, + (VkDescriptorSet[2]) { + gsk_vulkan_render_get_descriptor_set (render, op->crossfade.descriptor_set_start), + gsk_vulkan_render_get_descriptor_set (render, op->crossfade.descriptor_set_end) + }, + 0, + NULL); + + current_draw_index += gsk_vulkan_cross_fade_pipeline_draw (GSK_VULKAN_CROSS_FADE_PIPELINE (current_pipeline), + command_buffer, + current_draw_index, 1); + break; + default: g_assert_not_reached (); break; diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index f372282d25..6739bb5941 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -40,6 +40,9 @@ typedef enum { GSK_VULKAN_PIPELINE_COLOR_TEXT, GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP, GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP_ROUNDED, + GSK_VULKAN_PIPELINE_CROSS_FADE, + GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP, + GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP_ROUNDED, /* add more */ GSK_VULKAN_N_PIPELINES } GskVulkanPipelineType; diff --git a/gsk/meson.build b/gsk/meson.build index cd18151287..072c140da3 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -62,6 +62,7 @@ if have_vulkan 'gskvulkanclip.c', 'gskvulkancolorpipeline.c', 'gskvulkancolortextpipeline.c', + 'gskvulkancrossfadepipeline.c', 'gskvulkancommandpool.c', 'gskvulkaneffectpipeline.c', 'gskvulkanglyphcache.c', diff --git a/gsk/resources/vulkan/crossfade-clip-rounded.frag.spv b/gsk/resources/vulkan/crossfade-clip-rounded.frag.spv new file mode 100644 index 0000000000..58eb4f78d8 Binary files /dev/null and b/gsk/resources/vulkan/crossfade-clip-rounded.frag.spv differ diff --git a/gsk/resources/vulkan/crossfade-clip-rounded.vert.spv b/gsk/resources/vulkan/crossfade-clip-rounded.vert.spv new file mode 100644 index 0000000000..9ed91e1326 Binary files /dev/null and b/gsk/resources/vulkan/crossfade-clip-rounded.vert.spv differ diff --git a/gsk/resources/vulkan/crossfade-clip.frag.spv b/gsk/resources/vulkan/crossfade-clip.frag.spv new file mode 100644 index 0000000000..76fa8b02dc Binary files /dev/null and b/gsk/resources/vulkan/crossfade-clip.frag.spv differ diff --git a/gsk/resources/vulkan/crossfade-clip.vert.spv b/gsk/resources/vulkan/crossfade-clip.vert.spv new file mode 100644 index 0000000000..9ed91e1326 Binary files /dev/null and b/gsk/resources/vulkan/crossfade-clip.vert.spv differ diff --git a/gsk/resources/vulkan/crossfade-rect.vert.spv b/gsk/resources/vulkan/crossfade-rect.vert.spv new file mode 100644 index 0000000000..9ed91e1326 Binary files /dev/null and b/gsk/resources/vulkan/crossfade-rect.vert.spv differ diff --git a/gsk/resources/vulkan/crossfade.frag b/gsk/resources/vulkan/crossfade.frag new file mode 100644 index 0000000000..8293b1d5d8 --- /dev/null +++ b/gsk/resources/vulkan/crossfade.frag @@ -0,0 +1,21 @@ +#version 420 core + +#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 = 0) out vec4 color; + +void main() +{ + vec4 start = texture (startTexture, inStartTexCoord); + vec4 end = texture (endTexture, inEndTexCoord); + + color = clip (inPos, mix (start, end, inProgress)); +} diff --git a/gsk/resources/vulkan/crossfade.frag.spv b/gsk/resources/vulkan/crossfade.frag.spv new file mode 100644 index 0000000000..76fa8b02dc Binary files /dev/null and b/gsk/resources/vulkan/crossfade.frag.spv differ diff --git a/gsk/resources/vulkan/crossfade.vert b/gsk/resources/vulkan/crossfade.vert new file mode 100644 index 0000000000..53cb15d012 --- /dev/null +++ b/gsk/resources/vulkan/crossfade.vert @@ -0,0 +1,44 @@ +#version 420 core + +#include "clip.vert.glsl" + +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 = 0) out vec2 outPos; +layout(location = 1) out vec2 outStartTexCoord; +layout(location = 2) out vec2 outEndTexCoord; +layout(location = 3) out float outProgress; + +out gl_PerVertex { + vec4 gl_Position; +}; + +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) }; + +void main() { + vec4 rect = clip (inRect); + vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex]; + gl_Position = push.mvp * vec4 (pos, 0.0, 1.0); + + outPos = pos; + + vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw, + rect.zw / inRect.zw); + vec4 starttexrect = vec4(inStartTexRect.xy + inStartTexRect.zw * texrect.xy, + inStartTexRect.zw * texrect.zw); + vec4 endtexrect = vec4(inEndTexRect.xy + inEndTexRect.zw * texrect.xy, + inEndTexRect.zw * texrect.zw); + + outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex]; + outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex]; + + outProgress = inProgress; +} diff --git a/gsk/resources/vulkan/crossfade.vert.spv b/gsk/resources/vulkan/crossfade.vert.spv new file mode 100644 index 0000000000..c062edb2af Binary files /dev/null and b/gsk/resources/vulkan/crossfade.vert.spv differ diff --git a/gsk/resources/vulkan/meson.build b/gsk/resources/vulkan/meson.build index 1007858525..6e61885e65 100644 --- a/gsk/resources/vulkan/meson.build +++ b/gsk/resources/vulkan/meson.build @@ -12,6 +12,7 @@ gsk_private_vulkan_fragment_shaders = [ 'border.frag', 'color.frag', 'color-matrix.frag', + 'crossfade.frag', 'inset-shadow.frag', 'linear.frag', 'mask.frag', @@ -24,6 +25,7 @@ gsk_private_vulkan_vertex_shaders = [ 'border.vert', 'color.vert', 'color-matrix.vert', + 'crossfade.vert', 'inset-shadow.vert', 'linear.vert', 'mask.vert',