[gtk+] vulkan: Make the effect renderer take matrix + offset



commit 1aa0f79e8bc58d2182a2cff4cbc65f543966c908
Author: Benjamin Otte <otte redhat com>
Date:   Sat Dec 31 13:24:21 2016 +0100

    vulkan: Make the effect renderer take matrix + offset
    
    This is in preparation for the new color matrix node.
    
    I don't think keeping support for a separate opacity shader is worth it.

 gsk/gskvulkaneffectpipeline.c                      |   35 +++++++++++++++++--
 gsk/gskvulkaneffectpipelineprivate.h               |    3 +-
 gsk/gskvulkanrender.c                              |    6 ++--
 gsk/gskvulkanrenderpass.c                          |   19 ++++++++--
 gsk/gskvulkanrenderprivate.h                       |    6 ++--
 ...ag.glsl => color-matrix-clip-rounded.frag.glsl} |   24 ++++++++++---
 .../vulkan/color-matrix-clip-rounded.frag.spv      |  Bin 0 -> 6588 bytes
 ...rt.glsl => color-matrix-clip-rounded.vert.glsl} |   13 ++++---
 .../vulkan/color-matrix-clip-rounded.vert.spv      |  Bin 0 -> 5292 bytes
 gsk/resources/vulkan/color-matrix-clip.frag.glsl   |   31 +++++++++++++++++
 gsk/resources/vulkan/color-matrix-clip.frag.spv    |  Bin 0 -> 2160 bytes
 ...-clip.vert.glsl => color-matrix-clip.vert.glsl} |    9 +++--
 gsk/resources/vulkan/color-matrix-clip.vert.spv    |  Bin 0 -> 4956 bytes
 gsk/resources/vulkan/color-matrix.frag.glsl        |   31 +++++++++++++++++
 gsk/resources/vulkan/color-matrix.frag.spv         |  Bin 0 -> 2160 bytes
 .../{opacity.vert.glsl => color-matrix.vert.glsl}  |    9 +++--
 gsk/resources/vulkan/color-matrix.vert.spv         |  Bin 0 -> 2316 bytes
 gsk/resources/vulkan/opacity-clip-rounded.frag.spv |  Bin 5584 -> 0 bytes
 gsk/resources/vulkan/opacity-clip-rounded.vert.spv |  Bin 5124 -> 0 bytes
 gsk/resources/vulkan/opacity-clip.frag.glsl        |   19 -----------
 gsk/resources/vulkan/opacity-clip.frag.spv         |  Bin 1068 -> 0 bytes
 gsk/resources/vulkan/opacity-clip.vert.spv         |  Bin 4788 -> 0 bytes
 gsk/resources/vulkan/opacity.frag.glsl             |   19 -----------
 gsk/resources/vulkan/opacity.frag.spv              |  Bin 1068 -> 0 bytes
 gsk/resources/vulkan/opacity.vert.spv              |  Bin 2148 -> 0 bytes
 25 files changed, 154 insertions(+), 70 deletions(-)
---
diff --git a/gsk/gskvulkaneffectpipeline.c b/gsk/gskvulkaneffectpipeline.c
index 249185c..8572da5 100644
--- a/gsk/gskvulkaneffectpipeline.c
+++ b/gsk/gskvulkaneffectpipeline.c
@@ -13,7 +13,8 @@ struct _GskVulkanEffectInstance
 {
   float rect[4];
   float tex_rect[4];
-  float value;
+  float color_matrix[16];
+  float color_offset[4];
 };
 
 G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE)
@@ -45,7 +46,31 @@ gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
           .location = 2,
           .binding = 0,
           .format = VK_FORMAT_R32G32B32A32_SFLOAT,
-          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, value),
+          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix),
+      },
+      {
+          .location = 3,
+          .binding = 0,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 4,
+      },
+      {
+          .location = 4,
+          .binding = 0,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 8,
+      },
+      {
+          .location = 5,
+          .binding = 0,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 12,
+      },
+      {
+          .location = 6,
+          .binding = 0,
+          .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+          .offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_offset),
       }
   };
   static const VkPipelineVertexInputStateCreateInfo info = {
@@ -100,7 +125,8 @@ void
 gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline,
                                                 guchar                  *data,
                                                 const graphene_rect_t   *rect,
-                                                float                    value)
+                                                const graphene_matrix_t *color_matrix,
+                                                const graphene_vec4_t   *color_offset)
 {
   GskVulkanEffectInstance *instance = (GskVulkanEffectInstance *) data;
 
@@ -112,7 +138,8 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin
   instance->tex_rect[1] = 0.0;
   instance->tex_rect[2] = 1.0;
   instance->tex_rect[3] = 1.0;
-  instance->value = value;
+  graphene_matrix_to_float (color_matrix, instance->color_matrix);
+  graphene_vec4_to_float (color_offset, instance->color_offset);
 }
 
 gsize
diff --git a/gsk/gskvulkaneffectpipelineprivate.h b/gsk/gskvulkaneffectpipelineprivate.h
index 9a82c02..d2bff81 100644
--- a/gsk/gskvulkaneffectpipelineprivate.h
+++ b/gsk/gskvulkaneffectpipelineprivate.h
@@ -21,7 +21,8 @@ gsize                   gsk_vulkan_effect_pipeline_count_vertex_data    (GskVulk
 void                    gsk_vulkan_effect_pipeline_collect_vertex_data  (GskVulkanEffectPipeline        
*pipeline,
                                                                          guchar                         
*data,
                                                                          const graphene_rect_t          
*rect,
-                                                                         float                           
value);
+                                                                         const graphene_matrix_t        
*color_matrix,
+                                                                         const graphene_vec4_t          
*color_offset);
 gsize                   gsk_vulkan_effect_pipeline_draw                 (GskVulkanEffectPipeline        
*pipeline,
                                                                          VkCommandBuffer                 
command_buffer,
                                                                          gsize                           
offset,
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 81bc319..35e2dce 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -321,9 +321,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender       *self,
     { "linear", gsk_vulkan_linear_gradient_pipeline_new },
     { "linear-clip", gsk_vulkan_linear_gradient_pipeline_new },
     { "linear-clip-rounded", gsk_vulkan_linear_gradient_pipeline_new },
-    { "opacity", gsk_vulkan_effect_pipeline_new },
-    { "opacity-clip", gsk_vulkan_effect_pipeline_new },
-    { "opacity-clip-rounded", gsk_vulkan_effect_pipeline_new }
+    { "color-matrix", gsk_vulkan_effect_pipeline_new },
+    { "color-matrix-clip", gsk_vulkan_effect_pipeline_new },
+    { "color-matrix-clip-rounded", gsk_vulkan_effect_pipeline_new }
   };
 
   g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 70f1de3..b005607 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -171,11 +171,11 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
 
     case GSK_OPACITY_NODE:
       if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
-        pipeline_type = GSK_VULKAN_PIPELINE_OPACITY;
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
       else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
-        pipeline_type = GSK_VULKAN_PIPELINE_OPACITY_CLIP;
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP;
       else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
-        pipeline_type = GSK_VULKAN_PIPELINE_OPACITY_CLIP_ROUNDED;
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
       else
         FALLBACK ("Opacity nodes can't deal with clip type %u\n", constants->clip.type);
       op.type = GSK_VULKAN_OP_OPACITY;
@@ -554,11 +554,22 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
 
         case GSK_VULKAN_OP_OPACITY:
           {
+            graphene_matrix_t color_matrix;
+            graphene_vec4_t color_offset;
+            graphene_matrix_init_from_float (&color_matrix,
+                                             (float[16]) {
+                                                 1.0, 0.0, 0.0, 0.0,         
+                                                 0.0, 1.0, 0.0, 0.0,         
+                                                 0.0, 0.0, 1.0, 0.0,         
+                                                 0.0, 0.0, 0.0, gsk_opacity_node_get_opacity 
(op->render.node)
+                                             });
+            graphene_vec4_init (&color_offset, 0.0, 0.0, 0.0, 0.0);
             op->render.vertex_offset = offset + n_bytes;
             gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline),
                                                             data + n_bytes + offset,
                                                             &op->render.node->bounds,
-                                                            gsk_opacity_node_get_opacity (op->render.node));
+                                                            &color_matrix,
+                                                            &color_offset);
             n_bytes += op->render.vertex_count;
           }
           break;
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index 6de38d2..cffce7f 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -17,9 +17,9 @@ typedef enum {
   GSK_VULKAN_PIPELINE_LINEAR_GRADIENT,
   GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP,
   GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED,
-  GSK_VULKAN_PIPELINE_OPACITY,
-  GSK_VULKAN_PIPELINE_OPACITY_CLIP,
-  GSK_VULKAN_PIPELINE_OPACITY_CLIP_ROUNDED,
+  GSK_VULKAN_PIPELINE_COLOR_MATRIX,
+  GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP,
+  GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED,
   /* add more */
   GSK_VULKAN_N_PIPELINES
 } GskVulkanPipelineType;
diff --git a/gsk/resources/vulkan/opacity-clip-rounded.frag.glsl 
b/gsk/resources/vulkan/color-matrix-clip-rounded.frag.glsl
similarity index 75%
rename from gsk/resources/vulkan/opacity-clip-rounded.frag.glsl
rename to gsk/resources/vulkan/color-matrix-clip-rounded.frag.glsl
index 91c1e54..c0e42ca 100644
--- a/gsk/resources/vulkan/opacity-clip-rounded.frag.glsl
+++ b/gsk/resources/vulkan/color-matrix-clip-rounded.frag.glsl
@@ -7,9 +7,10 @@ struct RoundedRect {
 
 layout(location = 0) in vec2 inPos;
 layout(location = 1) in vec2 inTexCoord;
-layout(location = 2) in flat float inOpacity;
-layout(location = 3) in flat vec4 inClipBounds;
-layout(location = 4) in flat vec4 inClipWidths;
+layout(location = 2) in flat vec4 inClipBounds;
+layout(location = 3) in flat vec4 inClipWidths;
+layout(location = 4) in flat mat4 inColorMatrix;
+layout(location = 8) in flat vec4 inColorOffset;
 
 layout(set = 0, binding = 0) uniform sampler2D inTexture;
 
@@ -51,14 +52,25 @@ float clip(vec2 pos, RoundedRect r) {
 }
 
 vec4
-opacity (vec4 color, float value)
+color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
 {
-  return color * value;
+  /* unpremultiply */
+  if (color.a != 0.0)
+    color.rgb /= color.a;
+
+  color = color_matrix * color + color_offset;
+  color = clamp(color, 0.0, 1.0);
+
+  /* premultiply */
+  if (color.a != 0.0)
+    color.rgb *= color.a;
+
+  return color;
 }
 
 void main()
 {
   RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
 
-  color = opacity (texture (inTexture, inTexCoord), inOpacity) * clip (inPos, r);
+  color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset) * clip (inPos, r);
 }
diff --git a/gsk/resources/vulkan/color-matrix-clip-rounded.frag.spv 
b/gsk/resources/vulkan/color-matrix-clip-rounded.frag.spv
new file mode 100644
index 0000000..f4c753a
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix-clip-rounded.frag.spv differ
diff --git a/gsk/resources/vulkan/opacity-clip-rounded.vert.glsl 
b/gsk/resources/vulkan/color-matrix-clip-rounded.vert.glsl
similarity index 79%
rename from gsk/resources/vulkan/opacity-clip-rounded.vert.glsl
rename to gsk/resources/vulkan/color-matrix-clip-rounded.vert.glsl
index 5f0b898..2875e63 100644
--- a/gsk/resources/vulkan/opacity-clip-rounded.vert.glsl
+++ b/gsk/resources/vulkan/color-matrix-clip-rounded.vert.glsl
@@ -2,7 +2,8 @@
 
 layout(location = 0) in vec4 inRect;
 layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in float inOpacity;
+layout(location = 2) in mat4 inColorMatrix;
+layout(location = 6) in vec4 inColorOffset;
 
 layout(push_constant) uniform PushConstants {
     mat4 mvp;
@@ -13,9 +14,10 @@ layout(push_constant) uniform PushConstants {
 
 layout(location = 0) out vec2 outPos;
 layout(location = 1) out vec2 outTexCoord;
-layout(location = 2) out flat float outOpacity;
-layout(location = 3) out flat vec4 outClipBounds;
-layout(location = 4) out flat vec4 outClipWidths;
+layout(location = 2) out flat vec4 outClipBounds;
+layout(location = 3) out flat vec4 outClipWidths;
+layout(location = 4) out flat mat4 outColorMatrix;
+layout(location = 8) out flat vec4 outColorOffset;
 
 out gl_PerVertex {
   vec4 gl_Position;
@@ -52,5 +54,6 @@ void main() {
   texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
                  inTexRect.zw * texrect.zw);
   outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-  outOpacity = inOpacity;
+  outColorMatrix = inColorMatrix;
+  outColorOffset = inColorOffset;
 }
diff --git a/gsk/resources/vulkan/color-matrix-clip-rounded.vert.spv 
b/gsk/resources/vulkan/color-matrix-clip-rounded.vert.spv
new file mode 100644
index 0000000..49271e4
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix-clip-rounded.vert.spv differ
diff --git a/gsk/resources/vulkan/color-matrix-clip.frag.glsl 
b/gsk/resources/vulkan/color-matrix-clip.frag.glsl
new file mode 100644
index 0000000..21a324e
--- /dev/null
+++ b/gsk/resources/vulkan/color-matrix-clip.frag.glsl
@@ -0,0 +1,31 @@
+#version 420 core
+
+layout(location = 0) in vec2 inTexCoord;
+layout(location = 1) in flat mat4 inColorMatrix;
+layout(location = 5) in flat vec4 inColorOffset;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+vec4
+color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
+{
+  /* unpremultiply */
+  if (color.a != 0.0)
+    color.rgb /= color.a;
+
+  color = color_matrix * color + color_offset;
+  color = clamp(color, 0.0, 1.0);
+
+  /* premultiply */
+  if (color.a != 0.0)
+    color.rgb *= color.a;
+
+  return color;
+}
+
+void main()
+{
+  color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset);
+}
diff --git a/gsk/resources/vulkan/color-matrix-clip.frag.spv b/gsk/resources/vulkan/color-matrix-clip.frag.spv
new file mode 100644
index 0000000..266c877
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix-clip.frag.spv differ
diff --git a/gsk/resources/vulkan/opacity-clip.vert.glsl b/gsk/resources/vulkan/color-matrix-clip.vert.glsl
similarity index 83%
rename from gsk/resources/vulkan/opacity-clip.vert.glsl
rename to gsk/resources/vulkan/color-matrix-clip.vert.glsl
index 4cf0f13..94d4ef8 100644
--- a/gsk/resources/vulkan/opacity-clip.vert.glsl
+++ b/gsk/resources/vulkan/color-matrix-clip.vert.glsl
@@ -2,7 +2,8 @@
 
 layout(location = 0) in vec4 inRect;
 layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in float inOpacity;
+layout(location = 2) in mat4 inColorMatrix;
+layout(location = 6) in vec4 inColorOffset;
 
 layout(push_constant) uniform PushConstants {
     mat4 mvp;
@@ -12,7 +13,8 @@ layout(push_constant) uniform PushConstants {
 } push;
 
 layout(location = 0) out vec2 outTexCoord;
-layout(location = 1) out flat float outOpacity;
+layout(location = 1) out flat mat4 outColorMatrix;
+layout(location = 5) out flat vec4 outColorOffset;
 
 out gl_PerVertex {
   vec4 gl_Position;
@@ -45,5 +47,6 @@ void main() {
   texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
                  inTexRect.zw * texrect.zw);
   outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-  outOpacity = inOpacity;
+  outColorMatrix = inColorMatrix;
+  outColorOffset = inColorOffset;
 }
diff --git a/gsk/resources/vulkan/color-matrix-clip.vert.spv b/gsk/resources/vulkan/color-matrix-clip.vert.spv
new file mode 100644
index 0000000..6648e24
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix-clip.vert.spv differ
diff --git a/gsk/resources/vulkan/color-matrix.frag.glsl b/gsk/resources/vulkan/color-matrix.frag.glsl
new file mode 100644
index 0000000..21a324e
--- /dev/null
+++ b/gsk/resources/vulkan/color-matrix.frag.glsl
@@ -0,0 +1,31 @@
+#version 420 core
+
+layout(location = 0) in vec2 inTexCoord;
+layout(location = 1) in flat mat4 inColorMatrix;
+layout(location = 5) in flat vec4 inColorOffset;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+vec4
+color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
+{
+  /* unpremultiply */
+  if (color.a != 0.0)
+    color.rgb /= color.a;
+
+  color = color_matrix * color + color_offset;
+  color = clamp(color, 0.0, 1.0);
+
+  /* premultiply */
+  if (color.a != 0.0)
+    color.rgb *= color.a;
+
+  return color;
+}
+
+void main()
+{
+  color = color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset);
+}
diff --git a/gsk/resources/vulkan/color-matrix.frag.spv b/gsk/resources/vulkan/color-matrix.frag.spv
new file mode 100644
index 0000000..266c877
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix.frag.spv differ
diff --git a/gsk/resources/vulkan/opacity.vert.glsl b/gsk/resources/vulkan/color-matrix.vert.glsl
similarity index 74%
rename from gsk/resources/vulkan/opacity.vert.glsl
rename to gsk/resources/vulkan/color-matrix.vert.glsl
index 7e12d41..20b3bbd 100644
--- a/gsk/resources/vulkan/opacity.vert.glsl
+++ b/gsk/resources/vulkan/color-matrix.vert.glsl
@@ -2,7 +2,8 @@
 
 layout(location = 0) in vec4 inRect;
 layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in float inOpacity;
+layout(location = 2) in mat4 inColorMatrix;
+layout(location = 6) in vec4 inColorOffset;
 
 layout(push_constant) uniform PushConstants {
     mat4 mvp;
@@ -12,7 +13,8 @@ layout(push_constant) uniform PushConstants {
 } push;
 
 layout(location = 0) out vec2 outTexCoord;
-layout(location = 1) out flat float outOpacity;
+layout(location = 1) out flat mat4 outColorMatrix;
+layout(location = 5) out flat vec4 outColorOffset;
 
 out gl_PerVertex {
   vec4 gl_Position;
@@ -30,5 +32,6 @@ void main() {
   gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
 
   outTexCoord = inTexRect.xy + inTexRect.zw * offsets[gl_VertexIndex];
-  outOpacity = inOpacity;
+  outColorMatrix = inColorMatrix;
+  outColorOffset = inColorOffset;
 }
diff --git a/gsk/resources/vulkan/color-matrix.vert.spv b/gsk/resources/vulkan/color-matrix.vert.spv
new file mode 100644
index 0000000..2985b74
Binary files /dev/null and b/gsk/resources/vulkan/color-matrix.vert.spv differ


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]