vulkan: Add offscreen and color-matrix op
authorBenjamin Otte <otte@redhat.com>
Sun, 25 Jun 2023 21:04:43 +0000 (23:04 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 16 Jul 2023 10:12:36 +0000 (12:12 +0200)
.. and use them for color-matrix operations.

gsk/meson.build
gsk/vulkan/gskvulkancolormatrixop.c [new file with mode: 0644]
gsk/vulkan/gskvulkancolormatrixopprivate.h [new file with mode: 0644]
gsk/vulkan/gskvulkanoffscreenop.c [new file with mode: 0644]
gsk/vulkan/gskvulkanoffscreenopprivate.h [new file with mode: 0644]
gsk/vulkan/gskvulkanrenderpass.c

index b24108c6b2f5f53f27a3c60e5215645f3c7b09fa..fd201a583f446ce6abd691a3d026e69ad01dc285 100644 (file)
@@ -114,6 +114,7 @@ if have_vulkan
     'vulkan/gskvulkanbuffer.c',
     'vulkan/gskvulkanclip.c',
     'vulkan/gskvulkancolorpipeline.c',
+    'vulkan/gskvulkancolormatrixop.c',
     'vulkan/gskvulkancolortextpipeline.c',
     'vulkan/gskvulkancommandpool.c',
     'vulkan/gskvulkancrossfadepipeline.c',
@@ -122,6 +123,7 @@ if have_vulkan
     'vulkan/gskvulkanimage.c',
     'vulkan/gskvulkanlineargradientpipeline.c',
     'vulkan/gskvulkanmemory.c',
+    'vulkan/gskvulkanoffscreenop.c',
     'vulkan/gskvulkanop.c',
     'vulkan/gskvulkanpipeline.c',
     'vulkan/gskvulkanpushconstants.c',
diff --git a/gsk/vulkan/gskvulkancolormatrixop.c b/gsk/vulkan/gskvulkancolormatrixop.c
new file mode 100644 (file)
index 0000000..87edc24
--- /dev/null
@@ -0,0 +1,153 @@
+#include "config.h"
+
+#include "gskvulkancolormatrixopprivate.h"
+
+#include "gskvulkaneffectpipelineprivate.h"
+
+typedef struct _GskVulkanColorMatrixOp GskVulkanColorMatrixOp;
+
+struct _GskVulkanColorMatrixOp
+{
+  GskVulkanOp op;
+
+  GskVulkanImage *image;
+  graphene_matrix_t color_matrix;
+  graphene_vec4_t color_offset;
+  graphene_rect_t rect;
+  graphene_rect_t tex_rect;
+
+  guint32 image_descriptor;
+  guint32 sampler_descriptor;
+  GskVulkanPipeline *pipeline;
+  gsize vertex_offset;
+};
+
+static void
+gsk_vulkan_color_matrix_op_finish (GskVulkanOp *op)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  g_object_unref (self->image);
+}
+
+static void
+gsk_vulkan_color_matrix_op_upload (GskVulkanOp           *op,
+                                   GskVulkanRenderPass   *pass,
+                                   GskVulkanRender       *render,
+                                   GskVulkanUploader     *uploader,
+                                   const graphene_rect_t *clip,
+                                   const graphene_vec2_t *scale)
+{
+}
+
+static inline gsize
+round_up (gsize number, gsize divisor)
+{
+  return (number + divisor - 1) / divisor * divisor;
+}
+
+static gsize
+gsk_vulkan_color_matrix_op_count_vertex_data (GskVulkanOp *op,
+                                              gsize        n_bytes)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+  gsize vertex_stride;
+
+  vertex_stride = gsk_vulkan_pipeline_get_vertex_stride (self->pipeline);
+  n_bytes = round_up (n_bytes, vertex_stride);
+  self->vertex_offset = n_bytes;
+  n_bytes += vertex_stride;
+  return n_bytes;
+}
+
+static void
+gsk_vulkan_color_matrix_op_collect_vertex_data (GskVulkanOp         *op,
+                                           GskVulkanRenderPass *pass,
+                                           GskVulkanRender     *render,
+                                           guchar              *data)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (self->pipeline),
+                                                  data + self->vertex_offset,
+                                                  (guint32[2]) {
+                                                   self->image_descriptor,
+                                                   self->sampler_descriptor,
+                                                  },
+                                                  graphene_point_zero (),
+                                                  &self->rect,
+                                                  &self->tex_rect,
+                                                  &self->color_matrix,
+                                                  &self->color_offset);
+}
+
+static void
+gsk_vulkan_color_matrix_op_reserve_descriptor_sets (GskVulkanOp     *op,
+                                                    GskVulkanRender *render)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  self->image_descriptor = gsk_vulkan_render_get_image_descriptor (render, self->image);
+  self->sampler_descriptor = gsk_vulkan_render_get_sampler_descriptor (render, GSK_VULKAN_SAMPLER_DEFAULT);
+}
+
+static GskVulkanPipeline *
+gsk_vulkan_color_matrix_op_get_pipeline (GskVulkanOp *op)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  return self->pipeline;
+}
+
+static void
+gsk_vulkan_color_matrix_op_command (GskVulkanOp      *op,
+                                    GskVulkanRender *render,
+                                    VkPipelineLayout  pipeline_layout,
+                                    VkCommandBuffer   command_buffer)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  gsk_vulkan_effect_pipeline_draw (GSK_VULKAN_EFFECT_PIPELINE (self->pipeline),
+                                   command_buffer,
+                                   self->vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (self->pipeline),
+                                   1);
+}
+
+static const GskVulkanOpClass GSK_VULKAN_COLOR_MATRIX_OP_CLASS = {
+  GSK_VULKAN_OP_SIZE (GskVulkanColorMatrixOp),
+  gsk_vulkan_color_matrix_op_finish,
+  gsk_vulkan_color_matrix_op_upload,
+  gsk_vulkan_color_matrix_op_count_vertex_data,
+  gsk_vulkan_color_matrix_op_collect_vertex_data,
+  gsk_vulkan_color_matrix_op_reserve_descriptor_sets,
+  gsk_vulkan_color_matrix_op_get_pipeline,
+  gsk_vulkan_color_matrix_op_command
+};
+
+gsize
+gsk_vulkan_color_matrix_op_size (void)
+{
+  return GSK_VULKAN_COLOR_MATRIX_OP_CLASS.size;
+}
+
+void
+gsk_vulkan_color_matrix_op_init (GskVulkanOp             *op,
+                                 GskVulkanPipeline       *pipeline,
+                                 GskVulkanImage          *image,
+                                 const graphene_rect_t   *rect,
+                                 const graphene_point_t  *offset,
+                                 const graphene_rect_t   *tex_rect,
+                                 const graphene_matrix_t *color_matrix,
+                                 const graphene_vec4_t   *color_offset)
+{
+  GskVulkanColorMatrixOp *self = (GskVulkanColorMatrixOp *) op;
+
+  gsk_vulkan_op_init (op, &GSK_VULKAN_COLOR_MATRIX_OP_CLASS);
+
+  self->pipeline = pipeline;
+  self->image = g_object_ref (image);
+  graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
+  gsk_vulkan_normalize_tex_coords (&self->tex_rect, rect, tex_rect);
+  self->color_matrix = *color_matrix;
+  self->color_offset = *color_offset;
+}
diff --git a/gsk/vulkan/gskvulkancolormatrixopprivate.h b/gsk/vulkan/gskvulkancolormatrixopprivate.h
new file mode 100644 (file)
index 0000000..3e6f104
--- /dev/null
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+gsize                   gsk_vulkan_color_matrix_op_size                 (void) G_GNUC_CONST;
+
+void                    gsk_vulkan_color_matrix_op_init                 (GskVulkanOp                    *op,
+                                                                         GskVulkanPipeline              *pipeline,
+                                                                         GskVulkanImage                 *image,
+                                                                         const graphene_rect_t          *rect,
+                                                                         const graphene_point_t         *offset,
+                                                                         const graphene_rect_t          *tex_rect,
+                                                                         const graphene_matrix_t        *color_matrix,
+                                                                         const graphene_vec4_t          *color_offset);
+
+
+G_END_DECLS
+
diff --git a/gsk/vulkan/gskvulkanoffscreenop.c b/gsk/vulkan/gskvulkanoffscreenop.c
new file mode 100644 (file)
index 0000000..2b5c982
--- /dev/null
@@ -0,0 +1,145 @@
+#include "config.h"
+
+#include "gskvulkanoffscreenopprivate.h"
+
+#include "gskrendernodeprivate.h"
+
+#include "gdk/gdkvulkancontextprivate.h"
+
+typedef struct _GskVulkanOffscreenOp GskVulkanOffscreenOp;
+
+struct _GskVulkanOffscreenOp
+{
+  GskVulkanOp op;
+
+  GskVulkanImage *image;
+  GskVulkanRenderPass *render_pass;
+};
+
+static void
+gsk_vulkan_offscreen_op_finish (GskVulkanOp *op)
+{
+  GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
+
+  g_object_unref (self->image);
+  gsk_vulkan_render_pass_free (self->render_pass);
+}
+
+static void
+gsk_vulkan_offscreen_op_upload (GskVulkanOp           *op,
+                                GskVulkanRenderPass   *pass,
+                                GskVulkanRender       *render,
+                                GskVulkanUploader     *uploader,
+                                const graphene_rect_t *clip,
+                                const graphene_vec2_t *scale)
+{
+  GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
+
+  gsk_vulkan_render_pass_upload (self->render_pass, render, uploader);
+}
+
+static gsize
+gsk_vulkan_offscreen_op_count_vertex_data (GskVulkanOp *op,
+                                           gsize        n_bytes)
+{
+  return n_bytes;
+}
+
+static void
+gsk_vulkan_offscreen_op_collect_vertex_data (GskVulkanOp         *op,
+                                             GskVulkanRenderPass *pass,
+                                             GskVulkanRender     *render,
+                                             guchar              *data)
+{
+}
+
+static void
+gsk_vulkan_offscreen_op_reserve_descriptor_sets (GskVulkanOp     *op,
+                                                 GskVulkanRender *render)
+{
+  GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
+
+  gsk_vulkan_render_pass_reserve_descriptor_sets (self->render_pass, render);
+}
+
+static GskVulkanPipeline *
+gsk_vulkan_offscreen_op_get_pipeline (GskVulkanOp *op)
+{
+  return NULL;
+}
+
+static void
+gsk_vulkan_offscreen_op_command (GskVulkanOp      *op,
+                                 GskVulkanRender  *render,
+                                 VkPipelineLayout  pipeline_layout,
+                                 VkCommandBuffer   command_buffer)
+{
+  GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
+
+  gsk_vulkan_render_draw_pass (render, self->render_pass, VK_NULL_HANDLE);
+}
+
+static const GskVulkanOpClass GSK_VULKAN_OFFSCREEN_OP_CLASS = {
+  GSK_VULKAN_OP_SIZE (GskVulkanOffscreenOp),
+  gsk_vulkan_offscreen_op_finish,
+  gsk_vulkan_offscreen_op_upload,
+  gsk_vulkan_offscreen_op_count_vertex_data,
+  gsk_vulkan_offscreen_op_collect_vertex_data,
+  gsk_vulkan_offscreen_op_reserve_descriptor_sets,
+  gsk_vulkan_offscreen_op_get_pipeline,
+  gsk_vulkan_offscreen_op_command
+};
+
+gsize
+gsk_vulkan_offscreen_op_size (void)
+{
+  return GSK_VULKAN_OFFSCREEN_OP_CLASS.size;
+}
+
+GskVulkanImage *
+gsk_vulkan_offscreen_op_init (GskVulkanOp           *op,
+                              GdkVulkanContext      *context,
+                              GskVulkanRender       *render,
+                              const graphene_vec2_t *scale,
+                              const graphene_rect_t *viewport,
+                              VkSemaphore            signal_semaphore,
+                              GskRenderNode         *node)
+{
+  GskVulkanOffscreenOp *self = (GskVulkanOffscreenOp *) op;
+  graphene_rect_t view;
+  cairo_region_t *clip;
+  float scale_x, scale_y;
+
+  scale_x = graphene_vec2_get_x (scale);
+  scale_y = graphene_vec2_get_y (scale);
+  view = GRAPHENE_RECT_INIT (scale_x * viewport->origin.x,
+                             scale_y * viewport->origin.y,
+                             ceil (scale_x * viewport->size.width),
+                             ceil (scale_y * viewport->size.height));
+
+  gsk_vulkan_op_init (op, &GSK_VULKAN_OFFSCREEN_OP_CLASS);
+
+  self->image = gsk_vulkan_image_new_for_offscreen (context,
+                                                    gdk_vulkan_context_get_offscreen_format (context,
+                                                        gsk_render_node_get_preferred_depth (node)),
+                                                    view.size.width, view.size.height);
+
+  clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
+                                          0, 0,
+                                          gsk_vulkan_image_get_width (self->image),
+                                          gsk_vulkan_image_get_height (self->image)
+                                        });
+
+  self->render_pass = gsk_vulkan_render_pass_new (context,
+                                                  self->image,
+                                                  scale,
+                                                  &view,
+                                                  clip,
+                                                  signal_semaphore);
+
+  cairo_region_destroy (clip);
+
+  gsk_vulkan_render_pass_add (self->render_pass, render, node);
+
+  return self->image;
+}
diff --git a/gsk/vulkan/gskvulkanoffscreenopprivate.h b/gsk/vulkan/gskvulkanoffscreenopprivate.h
new file mode 100644 (file)
index 0000000..16687ea
--- /dev/null
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+gsize                   gsk_vulkan_offscreen_op_size                    (void) G_GNUC_CONST;
+
+GskVulkanImage *        gsk_vulkan_offscreen_op_init                    (GskVulkanOp                    *op,
+                                                                         GdkVulkanContext               *context,
+                                                                         GskVulkanRender                *render,
+                                                                         const graphene_vec2_t          *scale,
+                                                                         const graphene_rect_t          *viewport,
+                                                                         VkSemaphore                     signal_semaphore,
+                                                                         GskRenderNode                  *node);
+
+G_END_DECLS
+
index 7885a3329c84931beb4237f0434037c2b235f058..6c12861bcb735f28b1b47d523b4fd3e9d8c59c6c 100644 (file)
@@ -14,6 +14,7 @@
 #include "gskvulkanborderpipelineprivate.h"
 #include "gskvulkanboxshadowpipelineprivate.h"
 #include "gskvulkanclipprivate.h"
+#include "gskvulkancolormatrixopprivate.h"
 #include "gskvulkancolorpipelineprivate.h"
 #include "gskvulkancolortextpipelineprivate.h"
 #include "gskvulkancrossfadepipelineprivate.h"
@@ -24,6 +25,7 @@
 #include "gskvulkantextpipelineprivate.h"
 #include "gskvulkantexturepipelineprivate.h"
 #include "gskvulkanimageprivate.h"
+#include "gskvulkanoffscreenopprivate.h"
 #include "gskvulkanpushconstantsprivate.h"
 #include "gskvulkanscissoropprivate.h"
 #include "gskvulkantextureopprivate.h"
@@ -58,7 +60,6 @@ typedef enum {
   GSK_VULKAN_OP_LINEAR_GRADIENT,
   GSK_VULKAN_OP_OPACITY,
   GSK_VULKAN_OP_BLUR,
-  GSK_VULKAN_OP_COLOR_MATRIX,
   GSK_VULKAN_OP_BORDER,
   GSK_VULKAN_OP_INSET_SHADOW,
   GSK_VULKAN_OP_OUTSET_SHADOW,
@@ -365,6 +366,73 @@ gsk_vulkan_render_pass_get_pipeline (GskVulkanRenderPass   *self,
                                          self->render_pass);
 }
 
+static GskVulkanImage *
+gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass       *self,
+                                          GskVulkanRender           *render,
+                                          const GskVulkanParseState *state,
+                                          GskRenderNode             *node,
+                                          graphene_rect_t           *tex_bounds)
+{
+  VkSemaphore semaphore;
+  GskVulkanImage *result;
+
+  switch ((guint) gsk_render_node_get_node_type (node))
+    {
+    case GSK_TEXTURE_NODE:
+      {
+        GdkTexture *texture = gsk_texture_node_get_texture (node);
+        GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
+        result = gsk_vulkan_renderer_get_texture_image (renderer, texture);
+        if (result == NULL)
+          {
+            result = gsk_vulkan_upload_op_init_texture (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_upload_op_size ()),
+                                                        self->vulkan,
+                                                        texture);
+            gsk_vulkan_renderer_add_texture_image (renderer, texture, result);
+          }
+
+        *tex_bounds = node->bounds;
+        return result;
+      }
+
+    default:
+      {
+        graphene_rect_t clipped;
+
+        graphene_rect_offset_r (&state->clip.rect.bounds, - state->offset.x, - state->offset.y, &clipped);
+        graphene_rect_intersection (&clipped, &node->bounds, &clipped);
+
+        if (clipped.size.width == 0 || clipped.size.height == 0)
+          return NULL;
+
+        /* assuming the unclipped bounds should go to texture coordinates 0..1,
+         * calculate the coordinates for the clipped texture size
+         */
+        *tex_bounds = clipped;
+
+        vkCreateSemaphore (gdk_vulkan_context_get_device (self->vulkan),
+                           &(VkSemaphoreCreateInfo) {
+                             VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+                             NULL,
+                             0
+                           },
+                           NULL,
+                           &semaphore);
+        g_array_append_val (self->wait_semaphores, semaphore);
+
+        result = gsk_vulkan_offscreen_op_init (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_offscreen_op_size ()),
+                                               self->vulkan,
+                                               render,
+                                               &state->scale,
+                                               &clipped,
+                                               semaphore,
+                                               node);
+
+        return result;
+      }
+   }
+}
+
 static void
 gsk_vulkan_render_pass_add_node (GskVulkanRenderPass       *self,
                                  GskVulkanRender           *render,
@@ -859,11 +927,16 @@ gsk_vulkan_render_pass_add_color_matrix_node (GskVulkanRenderPass       *self,
                                               GskRenderNode             *node)
 {
   GskVulkanPipelineType pipeline_type;
-  GskVulkanOpRender op = {
-    .type = GSK_VULKAN_OP_COLOR_MATRIX,
-    .node = node,
-    .offset = state->offset,
-  };
+  GskVulkanImage *image;
+  graphene_rect_t tex_rect;
+
+  image = gsk_vulkan_render_pass_get_node_as_image (self,
+                                                    render,
+                                                    state,
+                                                    gsk_color_matrix_node_get_child (node),
+                                                    &tex_rect);
+  if (image == NULL)
+    return TRUE;
 
   if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
     pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
@@ -872,8 +945,14 @@ gsk_vulkan_render_pass_add_color_matrix_node (GskVulkanRenderPass       *self,
   else
     pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
 
-  op.pipeline = gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type);
-  gsk_vulkan_render_pass_add_op (self, (GskVulkanOp *) &op);
+  gsk_vulkan_color_matrix_op_init (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_color_matrix_op_size ()),
+                                   gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type),
+                                   image,
+                                   &node->bounds,
+                                   &state->offset,
+                                   &tex_rect,
+                                   gsk_color_matrix_node_get_color_matrix (node),
+                                   gsk_color_matrix_node_get_color_offset (node));
 
   return TRUE;
 }
@@ -1743,23 +1822,6 @@ gsk_vulkan_render_op_upload (GskVulkanOp           *op_,
           }
           break;
 
-        case GSK_VULKAN_OP_COLOR_MATRIX:
-          {
-            GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node);
-            graphene_rect_t tex_bounds;
-
-            op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
-                                                                            render,
-                                                                            uploader,
-                                                                            child,
-                                                                            scale,
-                                                                            clip,
-                                                                            &op->render.offset,
-                                                                            &tex_bounds);
-            gsk_vulkan_normalize_tex_coords (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
-          }
-          break;
-
         case GSK_VULKAN_OP_CROSS_FADE:
           {
             GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->render.node);
@@ -1882,7 +1944,6 @@ gsk_vulkan_render_op_count_vertex_data (GskVulkanOp *op_,
         case GSK_VULKAN_OP_COLOR:
         case GSK_VULKAN_OP_LINEAR_GRADIENT:
         case GSK_VULKAN_OP_OPACITY:
-        case GSK_VULKAN_OP_COLOR_MATRIX:
         case GSK_VULKAN_OP_BLUR:
         case GSK_VULKAN_OP_BORDER:
         case GSK_VULKAN_OP_INSET_SHADOW:
@@ -2051,17 +2112,6 @@ gsk_vulkan_render_op_collect_vertex_data (GskVulkanOp         *op_,
                                                         gsk_blur_node_get_radius (op->render.node));
           break;
 
-        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.image_descriptor,
-                                                          &op->render.offset,
-                                                          &op->render.node->bounds,
-                                                          &op->render.source_rect,
-                                                          gsk_color_matrix_node_get_color_matrix (op->render.node),
-                                                          gsk_color_matrix_node_get_color_offset (op->render.node));
-          break;
-
         case GSK_VULKAN_OP_BORDER:
           gsk_vulkan_border_pipeline_collect_vertex_data (GSK_VULKAN_BORDER_PIPELINE (op->render.pipeline),
                                                           data + op->render.vertex_offset,
@@ -2196,7 +2246,6 @@ gsk_vulkan_render_op_reserve_descriptor_sets (GskVulkanOp     *op_,
         case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
         case GSK_VULKAN_OP_OPACITY:
         case GSK_VULKAN_OP_BLUR:
-        case GSK_VULKAN_OP_COLOR_MATRIX:
           if (op->render.source)
             {
               op->render.image_descriptor[0] = gsk_vulkan_render_get_image_descriptor (render, op->render.source);
@@ -2310,7 +2359,6 @@ gsk_vulkan_render_op_get_pipeline (GskVulkanOp *op_)
     case GSK_VULKAN_OP_COLOR:
     case GSK_VULKAN_OP_LINEAR_GRADIENT:
     case GSK_VULKAN_OP_OPACITY:
-    case GSK_VULKAN_OP_COLOR_MATRIX:
     case GSK_VULKAN_OP_BLUR:
     case GSK_VULKAN_OP_BORDER:
     case GSK_VULKAN_OP_INSET_SHADOW:
@@ -2369,7 +2417,6 @@ gsk_vulkan_render_op_command (GskVulkanOp      *op_,
           break;
 
         case GSK_VULKAN_OP_OPACITY:
-        case GSK_VULKAN_OP_COLOR_MATRIX:
           if (!op->render.source)
             break;
           gsk_vulkan_effect_pipeline_draw (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline),