diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index d23ff8cd3e..6f57c1d8c9 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -315,6 +315,7 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, } pipeline_info[GSK_VULKAN_N_PIPELINES] = { { "blit", gsk_vulkan_blend_pipeline_new }, { "color", gsk_vulkan_color_pipeline_new }, + { "color-clip", gsk_vulkan_color_pipeline_new }, { "color-clip-rounded", gsk_vulkan_color_pipeline_new } }; diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 21a5cb9c88..0721e9a74a 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -129,6 +129,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, case GSK_COLOR_NODE: if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) pipeline_type = GSK_VULKAN_PIPELINE_COLOR; + else if (constants->clip.type == GSK_VULKAN_CLIP_RECT) + pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP; else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR) pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED; else @@ -551,7 +553,9 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, for (step = 1; step + i < self->render_ops->len; step++) { - if (g_array_index (self->render_ops, GskVulkanOp, i + step).type != GSK_VULKAN_OP_COLOR) + GskVulkanOp *cmp = &g_array_index (self->render_ops, GskVulkanOp, i + step); + if (cmp->type != GSK_VULKAN_OP_COLOR || + cmp->render.pipeline != current_pipeline) break; } current_draw_index += gsk_vulkan_color_pipeline_draw (GSK_VULKAN_COLOR_PIPELINE (current_pipeline), diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index c5f7379daf..f707c2a736 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -12,6 +12,7 @@ G_BEGIN_DECLS typedef enum { GSK_VULKAN_PIPELINE_BLIT, GSK_VULKAN_PIPELINE_COLOR, + GSK_VULKAN_PIPELINE_COLOR_CLIP, GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED, /* add more */ GSK_VULKAN_N_PIPELINES diff --git a/gsk/resources/vulkan/color-clip.frag.glsl b/gsk/resources/vulkan/color-clip.frag.glsl new file mode 100644 index 0000000000..218ee854eb --- /dev/null +++ b/gsk/resources/vulkan/color-clip.frag.glsl @@ -0,0 +1,10 @@ +#version 420 core + +layout(location = 0) in vec4 inColor; + +layout(location = 0) out vec4 color; + +void main() +{ + color = vec4(inColor.rgb * inColor.a, inColor.a); +} diff --git a/gsk/resources/vulkan/color-clip.frag.spv b/gsk/resources/vulkan/color-clip.frag.spv new file mode 100644 index 0000000000..29bbae9dfd Binary files /dev/null and b/gsk/resources/vulkan/color-clip.frag.spv differ diff --git a/gsk/resources/vulkan/color-clip.vert.glsl b/gsk/resources/vulkan/color-clip.vert.glsl new file mode 100644 index 0000000000..b89321759f --- /dev/null +++ b/gsk/resources/vulkan/color-clip.vert.glsl @@ -0,0 +1,42 @@ +#version 420 core + +layout(location = 0) in vec4 inRect; +layout(location = 1) in vec4 inColor; + +layout(push_constant) uniform PushConstants { + mat4 mvp; + vec4 clip_bounds; + vec4 clip_widths; + vec4 clip_heights; +} push; + +out gl_PerVertex { + vec4 gl_Position; +}; + +layout(location = 0) out vec4 outColor; + +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) }; + +vec4 intersect(vec4 a, vec4 b) +{ + a = vec4(a.xy, a.xy + a.zw); + b = vec4(b.xy, b.xy + b.zw); + vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw)); + if (any (greaterThanEqual (result.xy, result.zw))) + return vec4(0.0,0.0,0.0,0.0); + return vec4(result.xy, result.zw - result.xy); +} + +void main() { + vec4 rect = intersect(inRect, push.clip_bounds); + + vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex]; + gl_Position = push.mvp * vec4 (pos, 0.0, 1.0); + outColor = inColor; +} diff --git a/gsk/resources/vulkan/color-clip.vert.spv b/gsk/resources/vulkan/color-clip.vert.spv new file mode 100644 index 0000000000..0089004dcf Binary files /dev/null and b/gsk/resources/vulkan/color-clip.vert.spv differ diff --git a/gsk/resources/vulkan/color.frag.spv b/gsk/resources/vulkan/color.frag.spv index 98c661da19..29bbae9dfd 100644 Binary files a/gsk/resources/vulkan/color.frag.spv and b/gsk/resources/vulkan/color.frag.spv differ