mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
vulkan: Implement crossfade
This is the first shader using two textures. It almost works.
This commit is contained in:
parent
8ad0539cf7
commit
a75d995bd4
146
gsk/gskvulkancrossfadepipeline.c
Normal file
146
gsk/gskvulkancrossfadepipeline.c
Normal file
@ -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;
|
||||||
|
}
|
35
gsk/gskvulkancrossfadepipelineprivate.h
Normal file
35
gsk/gskvulkancrossfadepipelineprivate.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __GSK_VULKAN_CROSS_FADE_PIPELINE_PRIVATE_H__
|
||||||
|
#define __GSK_VULKAN_CROSS_FADE_PIPELINE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <graphene.h>
|
||||||
|
|
||||||
|
#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__ */
|
@ -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))
|
#define GSK_VK_CHECK(func, ...) gsk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
|
||||||
|
|
||||||
|
|
||||||
GskVulkanPipeline * gsk_vulkan_pipeline_new (GType pipeline_type,
|
GskVulkanPipeline * gsk_vulkan_pipeline_new (GType pipeline_type,
|
||||||
GdkVulkanContext *context,
|
GdkVulkanContext *context,
|
||||||
VkPipelineLayout layout,
|
VkPipelineLayout layout,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "gskvulkanboxshadowpipelineprivate.h"
|
#include "gskvulkanboxshadowpipelineprivate.h"
|
||||||
#include "gskvulkancolorpipelineprivate.h"
|
#include "gskvulkancolorpipelineprivate.h"
|
||||||
#include "gskvulkancolortextpipelineprivate.h"
|
#include "gskvulkancolortextpipelineprivate.h"
|
||||||
|
#include "gskvulkancrossfadepipelineprivate.h"
|
||||||
#include "gskvulkaneffectpipelineprivate.h"
|
#include "gskvulkaneffectpipelineprivate.h"
|
||||||
#include "gskvulkanlineargradientpipelineprivate.h"
|
#include "gskvulkanlineargradientpipelineprivate.h"
|
||||||
#include "gskvulkantextpipelineprivate.h"
|
#include "gskvulkantextpipelineprivate.h"
|
||||||
@ -388,6 +389,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
|
|||||||
{ "blend", 1, gsk_vulkan_color_text_pipeline_new },
|
{ "blend", 1, gsk_vulkan_color_text_pipeline_new },
|
||||||
{ "blend-clip", 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 },
|
{ "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);
|
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "gskvulkanclipprivate.h"
|
#include "gskvulkanclipprivate.h"
|
||||||
#include "gskvulkancolorpipelineprivate.h"
|
#include "gskvulkancolorpipelineprivate.h"
|
||||||
#include "gskvulkancolortextpipelineprivate.h"
|
#include "gskvulkancolortextpipelineprivate.h"
|
||||||
|
#include "gskvulkancrossfadepipelineprivate.h"
|
||||||
#include "gskvulkaneffectpipelineprivate.h"
|
#include "gskvulkaneffectpipelineprivate.h"
|
||||||
#include "gskvulkanlineargradientpipelineprivate.h"
|
#include "gskvulkanlineargradientpipelineprivate.h"
|
||||||
#include "gskvulkantextpipelineprivate.h"
|
#include "gskvulkantextpipelineprivate.h"
|
||||||
@ -26,6 +27,7 @@
|
|||||||
typedef union _GskVulkanOp GskVulkanOp;
|
typedef union _GskVulkanOp GskVulkanOp;
|
||||||
typedef struct _GskVulkanOpRender GskVulkanOpRender;
|
typedef struct _GskVulkanOpRender GskVulkanOpRender;
|
||||||
typedef struct _GskVulkanOpText GskVulkanOpText;
|
typedef struct _GskVulkanOpText GskVulkanOpText;
|
||||||
|
typedef struct _GskVulkanOpCrossFade GskVulkanOpCrossFade;
|
||||||
typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants;
|
typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -35,8 +37,6 @@ typedef enum {
|
|||||||
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
|
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
|
||||||
GSK_VULKAN_OP_SURFACE,
|
GSK_VULKAN_OP_SURFACE,
|
||||||
GSK_VULKAN_OP_TEXTURE,
|
GSK_VULKAN_OP_TEXTURE,
|
||||||
GSK_VULKAN_OP_TEXT,
|
|
||||||
GSK_VULKAN_OP_COLOR_TEXT,
|
|
||||||
GSK_VULKAN_OP_COLOR,
|
GSK_VULKAN_OP_COLOR,
|
||||||
GSK_VULKAN_OP_LINEAR_GRADIENT,
|
GSK_VULKAN_OP_LINEAR_GRADIENT,
|
||||||
GSK_VULKAN_OP_OPACITY,
|
GSK_VULKAN_OP_OPACITY,
|
||||||
@ -45,8 +45,13 @@ typedef enum {
|
|||||||
GSK_VULKAN_OP_BORDER,
|
GSK_VULKAN_OP_BORDER,
|
||||||
GSK_VULKAN_OP_INSET_SHADOW,
|
GSK_VULKAN_OP_INSET_SHADOW,
|
||||||
GSK_VULKAN_OP_OUTSET_SHADOW,
|
GSK_VULKAN_OP_OUTSET_SHADOW,
|
||||||
|
/* GskVulkanOpText */
|
||||||
|
GSK_VULKAN_OP_TEXT,
|
||||||
|
GSK_VULKAN_OP_COLOR_TEXT,
|
||||||
|
/* GskVulkanOpCrossFade */
|
||||||
|
GSK_VULKAN_OP_CROSS_FADE,
|
||||||
/* GskVulkanOpPushConstants */
|
/* GskVulkanOpPushConstants */
|
||||||
GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS
|
GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS,
|
||||||
} GskVulkanOpType;
|
} GskVulkanOpType;
|
||||||
|
|
||||||
struct _GskVulkanOpRender
|
struct _GskVulkanOpRender
|
||||||
@ -76,6 +81,20 @@ struct _GskVulkanOpText
|
|||||||
guint num_glyphs; /* number of *non-empty* glyphs (== instances) we render */
|
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
|
struct _GskVulkanOpPushConstants
|
||||||
{
|
{
|
||||||
GskVulkanOpType type;
|
GskVulkanOpType type;
|
||||||
@ -87,8 +106,9 @@ union _GskVulkanOp
|
|||||||
{
|
{
|
||||||
GskVulkanOpType type;
|
GskVulkanOpType type;
|
||||||
GskVulkanOpRender render;
|
GskVulkanOpRender render;
|
||||||
GskVulkanOpPushConstants constants;
|
|
||||||
GskVulkanOpText text;
|
GskVulkanOpText text;
|
||||||
|
GskVulkanOpCrossFade crossfade;
|
||||||
|
GskVulkanOpPushConstants constants;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GskVulkanRenderPass
|
struct _GskVulkanRenderPass
|
||||||
@ -161,10 +181,23 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
case GSK_REPEAT_NODE:
|
case GSK_REPEAT_NODE:
|
||||||
case GSK_SHADOW_NODE:
|
case GSK_SHADOW_NODE:
|
||||||
case GSK_BLEND_NODE:
|
case GSK_BLEND_NODE:
|
||||||
case GSK_CROSS_FADE_NODE:
|
|
||||||
default:
|
default:
|
||||||
FALLBACK ("Unsupported node '%s'\n", node->node_class->type_name);
|
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:
|
case GSK_INSET_SHADOW_NODE:
|
||||||
if (gsk_inset_shadow_node_get_blur_radius (node) > 0)
|
if (gsk_inset_shadow_node_get_blur_radius (node) > 0)
|
||||||
FALLBACK ("Blur support not implemented for inset shadows\n");
|
FALLBACK ("Blur support not implemented for inset shadows\n");
|
||||||
@ -707,6 +740,24 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
case GSK_VULKAN_OP_COLOR:
|
case GSK_VULKAN_OP_COLOR:
|
||||||
@ -787,6 +838,11 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
|||||||
n_bytes += op->render.vertex_count;
|
n_bytes += op->render.vertex_count;
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
||||||
@ -977,6 +1033,22 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
|
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:
|
case GSK_VULKAN_OP_COLOR_TEXT:
|
||||||
op->text.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->text.source);
|
op->text.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->text.source);
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
case GSK_VULKAN_OP_COLOR:
|
case GSK_VULKAN_OP_COLOR:
|
||||||
@ -1320,6 +1398,40 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
|
|||||||
pipeline_layout[i]);
|
pipeline_layout[i]);
|
||||||
break;
|
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:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
|
@ -40,6 +40,9 @@ typedef enum {
|
|||||||
GSK_VULKAN_PIPELINE_COLOR_TEXT,
|
GSK_VULKAN_PIPELINE_COLOR_TEXT,
|
||||||
GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP,
|
GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP,
|
||||||
GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP_ROUNDED,
|
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 */
|
/* add more */
|
||||||
GSK_VULKAN_N_PIPELINES
|
GSK_VULKAN_N_PIPELINES
|
||||||
} GskVulkanPipelineType;
|
} GskVulkanPipelineType;
|
||||||
|
@ -62,6 +62,7 @@ if have_vulkan
|
|||||||
'gskvulkanclip.c',
|
'gskvulkanclip.c',
|
||||||
'gskvulkancolorpipeline.c',
|
'gskvulkancolorpipeline.c',
|
||||||
'gskvulkancolortextpipeline.c',
|
'gskvulkancolortextpipeline.c',
|
||||||
|
'gskvulkancrossfadepipeline.c',
|
||||||
'gskvulkancommandpool.c',
|
'gskvulkancommandpool.c',
|
||||||
'gskvulkaneffectpipeline.c',
|
'gskvulkaneffectpipeline.c',
|
||||||
'gskvulkanglyphcache.c',
|
'gskvulkanglyphcache.c',
|
||||||
|
BIN
gsk/resources/vulkan/crossfade-clip-rounded.frag.spv
Normal file
BIN
gsk/resources/vulkan/crossfade-clip-rounded.frag.spv
Normal file
Binary file not shown.
BIN
gsk/resources/vulkan/crossfade-clip-rounded.vert.spv
Normal file
BIN
gsk/resources/vulkan/crossfade-clip-rounded.vert.spv
Normal file
Binary file not shown.
BIN
gsk/resources/vulkan/crossfade-clip.frag.spv
Normal file
BIN
gsk/resources/vulkan/crossfade-clip.frag.spv
Normal file
Binary file not shown.
BIN
gsk/resources/vulkan/crossfade-clip.vert.spv
Normal file
BIN
gsk/resources/vulkan/crossfade-clip.vert.spv
Normal file
Binary file not shown.
BIN
gsk/resources/vulkan/crossfade-rect.vert.spv
Normal file
BIN
gsk/resources/vulkan/crossfade-rect.vert.spv
Normal file
Binary file not shown.
21
gsk/resources/vulkan/crossfade.frag
Normal file
21
gsk/resources/vulkan/crossfade.frag
Normal file
@ -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));
|
||||||
|
}
|
BIN
gsk/resources/vulkan/crossfade.frag.spv
Normal file
BIN
gsk/resources/vulkan/crossfade.frag.spv
Normal file
Binary file not shown.
44
gsk/resources/vulkan/crossfade.vert
Normal file
44
gsk/resources/vulkan/crossfade.vert
Normal file
@ -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;
|
||||||
|
}
|
BIN
gsk/resources/vulkan/crossfade.vert.spv
Normal file
BIN
gsk/resources/vulkan/crossfade.vert.spv
Normal file
Binary file not shown.
@ -12,6 +12,7 @@ gsk_private_vulkan_fragment_shaders = [
|
|||||||
'border.frag',
|
'border.frag',
|
||||||
'color.frag',
|
'color.frag',
|
||||||
'color-matrix.frag',
|
'color-matrix.frag',
|
||||||
|
'crossfade.frag',
|
||||||
'inset-shadow.frag',
|
'inset-shadow.frag',
|
||||||
'linear.frag',
|
'linear.frag',
|
||||||
'mask.frag',
|
'mask.frag',
|
||||||
@ -24,6 +25,7 @@ gsk_private_vulkan_vertex_shaders = [
|
|||||||
'border.vert',
|
'border.vert',
|
||||||
'color.vert',
|
'color.vert',
|
||||||
'color-matrix.vert',
|
'color-matrix.vert',
|
||||||
|
'crossfade.vert',
|
||||||
'inset-shadow.vert',
|
'inset-shadow.vert',
|
||||||
'linear.vert',
|
'linear.vert',
|
||||||
'mask.vert',
|
'mask.vert',
|
||||||
|
Loading…
Reference in New Issue
Block a user