From 6c94d7f06a92ad9a029572749b95324d1922b0f2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 3 Sep 2017 09:54:47 -0400 Subject: [PATCH] wip: vulkan blur support nonworking --- gsk/gskvulkanblurpipeline.c | 129 ++++++++++++++++++ gsk/gskvulkanblurpipelineprivate.h | 32 +++++ gsk/gskvulkanrender.c | 4 + gsk/gskvulkanrenderpass.c | 78 +++++++++++ gsk/gskvulkanrenderprivate.h | 3 + gsk/meson.build | 1 + .../vulkan/blur-clip-rounded.frag.spv | Bin 0 -> 10828 bytes .../vulkan/blur-clip-rounded.vert.spv | Bin 0 -> 3916 bytes gsk/resources/vulkan/blur-clip.frag.spv | Bin 0 -> 4008 bytes gsk/resources/vulkan/blur-clip.vert.spv | Bin 0 -> 3916 bytes gsk/resources/vulkan/blur.frag | 52 +++++++ gsk/resources/vulkan/blur.frag.glsl | 13 ++ gsk/resources/vulkan/blur.frag.spv | Bin 0 -> 4008 bytes gsk/resources/vulkan/blur.vert | 30 ++++ gsk/resources/vulkan/blur.vert.glsl | 30 ++++ gsk/resources/vulkan/blur.vert.spv | Bin 0 -> 2184 bytes gsk/resources/vulkan/meson.build | 2 + 17 files changed, 374 insertions(+) create mode 100644 gsk/gskvulkanblurpipeline.c create mode 100644 gsk/gskvulkanblurpipelineprivate.h create mode 100644 gsk/resources/vulkan/blur-clip-rounded.frag.spv create mode 100644 gsk/resources/vulkan/blur-clip-rounded.vert.spv create mode 100644 gsk/resources/vulkan/blur-clip.frag.spv create mode 100644 gsk/resources/vulkan/blur-clip.vert.spv create mode 100644 gsk/resources/vulkan/blur.frag create mode 100644 gsk/resources/vulkan/blur.frag.glsl create mode 100644 gsk/resources/vulkan/blur.frag.spv create mode 100644 gsk/resources/vulkan/blur.vert create mode 100644 gsk/resources/vulkan/blur.vert.glsl create mode 100644 gsk/resources/vulkan/blur.vert.spv diff --git a/gsk/gskvulkanblurpipeline.c b/gsk/gskvulkanblurpipeline.c new file mode 100644 index 0000000000..779bf81ec0 --- /dev/null +++ b/gsk/gskvulkanblurpipeline.c @@ -0,0 +1,129 @@ +#include "config.h" + +#include "gskvulkanblurpipelineprivate.h" + +struct _GskVulkanBlurPipeline +{ + GObject parent_instance; +}; + +typedef struct _GskVulkanBlurInstance GskVulkanBlurInstance; + +struct _GskVulkanBlurInstance +{ + float rect[4]; + float tex_rect[4]; + float blur_radius; +}; + +G_DEFINE_TYPE (GskVulkanBlurPipeline, gsk_vulkan_blur_pipeline, GSK_TYPE_VULKAN_PIPELINE) + +static const VkPipelineVertexInputStateCreateInfo * +gsk_vulkan_blur_pipeline_get_input_state_create_info (GskVulkanPipeline *self) +{ + static const VkVertexInputBindingDescription vertexBindingDescriptions[] = { + { + .binding = 0, + .stride = sizeof (GskVulkanBlurInstance), + .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 (GskVulkanBlurInstance, tex_rect), + }, + { + .location = 2, + .binding = 0, + .format = VK_FORMAT_R32_SFLOAT, + .offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, blur_radius), + } + }; + 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_blur_pipeline_finalize (GObject *gobject) +{ + //GskVulkanBlurPipeline *self = GSK_VULKAN_BLUR_PIPELINE (gobject); + + G_OBJECT_CLASS (gsk_vulkan_blur_pipeline_parent_class)->finalize (gobject); +} + +static void +gsk_vulkan_blur_pipeline_class_init (GskVulkanBlurPipelineClass *klass) +{ + GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass); + + G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_blur_pipeline_finalize; + + pipeline_class->get_input_state_create_info = gsk_vulkan_blur_pipeline_get_input_state_create_info; +} + +static void +gsk_vulkan_blur_pipeline_init (GskVulkanBlurPipeline *self) +{ +} + +GskVulkanPipeline * +gsk_vulkan_blur_pipeline_new (GskVulkanPipelineLayout *layout, + const char *shader_name, + VkRenderPass render_pass) +{ + return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_BLUR_PIPELINE, layout, shader_name, render_pass); +} + +gsize +gsk_vulkan_blur_pipeline_count_vertex_data (GskVulkanBlurPipeline *pipeline) +{ + return sizeof (GskVulkanBlurInstance); +} + +void +gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect, + double blur_radius) +{ + GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) data; + + instance->rect[0] = rect->origin.x; + instance->rect[1] = rect->origin.y; + instance->rect[2] = rect->size.width; + instance->rect[3] = rect->size.height; + instance->tex_rect[0] = 0.0; + instance->tex_rect[1] = 0.0; + instance->tex_rect[2] = 1.0; + instance->tex_rect[3] = 1.0; + instance->blur_radius = blur_radius; +} + +gsize +gsk_vulkan_blur_pipeline_draw (GskVulkanBlurPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands) +{ + vkCmdDraw (command_buffer, + 6, n_commands, + 0, offset); + + return n_commands; +} diff --git a/gsk/gskvulkanblurpipelineprivate.h b/gsk/gskvulkanblurpipelineprivate.h new file mode 100644 index 0000000000..44b139d4bf --- /dev/null +++ b/gsk/gskvulkanblurpipelineprivate.h @@ -0,0 +1,32 @@ +#ifndef __GSK_VULKAN_BLUR_PIPELINE_PRIVATE_H__ +#define __GSK_VULKAN_BLUR_PIPELINE_PRIVATE_H__ + +#include + +#include "gskvulkanpipelineprivate.h" + +G_BEGIN_DECLS + +typedef struct _GskVulkanBlurPipelineLayout GskVulkanBlurPipelineLayout; + +#define GSK_TYPE_VULKAN_BLUR_PIPELINE (gsk_vulkan_blur_pipeline_get_type ()) + +G_DECLARE_FINAL_TYPE (GskVulkanBlurPipeline, gsk_vulkan_blur_pipeline, GSK, VULKAN_BLUR_PIPELINE, GskVulkanPipeline) + +GskVulkanPipeline * gsk_vulkan_blur_pipeline_new (GskVulkanPipelineLayout *layout, + const char *shader_name, + VkRenderPass render_pass); + +gsize gsk_vulkan_blur_pipeline_count_vertex_data (GskVulkanBlurPipeline *pipeline); +void gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect, + double radius); +gsize gsk_vulkan_blur_pipeline_draw (GskVulkanBlurPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands); + +G_END_DECLS + +#endif /* __GSK_VULKAN_BLUR_PIPELINE_PRIVATE_H__ */ diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index cf98e184e0..4da8e48566 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -11,6 +11,7 @@ #include "gskvulkanrenderpassprivate.h" #include "gskvulkanblendpipelineprivate.h" +#include "gskvulkanblurpipelineprivate.h" #include "gskvulkanborderpipelineprivate.h" #include "gskvulkanboxshadowpipelineprivate.h" #include "gskvulkancolorpipelineprivate.h" @@ -340,6 +341,9 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, { "outset-shadow", gsk_vulkan_box_shadow_pipeline_new }, { "outset-shadow-clip", gsk_vulkan_box_shadow_pipeline_new }, { "outset-shadow-clip-rounded", gsk_vulkan_box_shadow_pipeline_new }, + { "blur", gsk_vulkan_blur_pipeline_new }, + { "blur-clip", gsk_vulkan_blur_pipeline_new }, + { "blur-clip-rounded", gsk_vulkan_blur_pipeline_new }, }; g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL); diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index b5bab5f39e..f3b2b0cb92 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -7,6 +7,7 @@ #include "gskrenderer.h" #include "gskroundedrectprivate.h" #include "gskvulkanblendpipelineprivate.h" +#include "gskvulkanblurpipelineprivate.h" #include "gskvulkanborderpipelineprivate.h" #include "gskvulkanboxshadowpipelineprivate.h" #include "gskvulkanclipprivate.h" @@ -31,6 +32,7 @@ typedef enum { GSK_VULKAN_OP_COLOR, 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, @@ -231,6 +233,20 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, g_array_append_val (self->render_ops, op); return; + case GSK_BLUR_NODE: + if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) + pipeline_type = GSK_VULKAN_PIPELINE_BLUR; + else if (constants->clip.type == GSK_VULKAN_CLIP_RECT) + pipeline_type = GSK_VULKAN_PIPELINE_BLUR_CLIP; + else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR) + pipeline_type = GSK_VULKAN_PIPELINE_BLUR_CLIP_ROUNDED; + else + FALLBACK ("Blur nodes can't deal with clip type %u\n", constants->clip.type); + op.type = GSK_VULKAN_OP_BLUR; + op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type); + g_array_append_val (self->render_ops, op); + return; + case GSK_COLOR_MATRIX_NODE: if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX; @@ -543,6 +559,18 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, } break; + case GSK_VULKAN_OP_BLUR: + { + GskRenderNode *child = gsk_blur_node_get_child (op->render.node); + + op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, + render, + uploader, + child, + &child->bounds); + } + break; + case GSK_VULKAN_OP_COLOR_MATRIX: { GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node); @@ -607,6 +635,11 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) n_bytes += op->render.vertex_count; break; + case GSK_VULKAN_OP_BLUR: + op->render.vertex_count = gsk_vulkan_blur_pipeline_count_vertex_data (GSK_VULKAN_BLUR_PIPELINE (op->render.pipeline)); + n_bytes += op->render.vertex_count; + break; + case GSK_VULKAN_OP_BORDER: op->render.vertex_count = gsk_vulkan_border_pipeline_count_vertex_data (GSK_VULKAN_BORDER_PIPELINE (op->render.pipeline)); n_bytes += op->render.vertex_count; @@ -707,6 +740,17 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, } break; + case GSK_VULKAN_OP_BLUR: + { + op->render.vertex_offset = offset + n_bytes; + gsk_vulkan_blur_pipeline_collect_vertex_data (GSK_VULKAN_BLUR_PIPELINE (op->render.pipeline), + data + n_bytes + offset, + &op->render.node->bounds, + gsk_blur_node_get_radius (op->render.node)); + n_bytes += op->render.vertex_count; + } + break; + case GSK_VULKAN_OP_COLOR_MATRIX: { op->render.vertex_offset = offset + n_bytes; @@ -792,6 +836,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, case GSK_VULKAN_OP_SURFACE: case GSK_VULKAN_OP_TEXTURE: case GSK_VULKAN_OP_OPACITY: + case GSK_VULKAN_OP_BLUR: case GSK_VULKAN_OP_COLOR_MATRIX: op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source); break; @@ -899,6 +944,39 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, current_draw_index, 1); break; + case GSK_VULKAN_OP_BLUR: + if (current_pipeline != op->render.pipeline) + { + current_pipeline = op->render.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->render.vertex_offset }); + current_draw_index = 0; + } + + vkCmdBindDescriptorSets (command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + gsk_vulkan_pipeline_layout_get_pipeline_layout (layout), + 0, + 1, + (VkDescriptorSet[1]) { + gsk_vulkan_render_get_descriptor_set (render, op->render.descriptor_set_index) + }, + 0, + NULL); + + current_draw_index += gsk_vulkan_blur_pipeline_draw (GSK_VULKAN_BLUR_PIPELINE (current_pipeline), + command_buffer, + current_draw_index, 1); + break; + case GSK_VULKAN_OP_COLOR: if (current_pipeline != op->render.pipeline) { diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index 29860f086e..4c01e82e9a 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -31,6 +31,9 @@ typedef enum { GSK_VULKAN_PIPELINE_OUTSET_SHADOW, GSK_VULKAN_PIPELINE_OUTSET_SHADOW_CLIP, GSK_VULKAN_PIPELINE_OUTSET_SHADOW_CLIP_ROUNDED, + GSK_VULKAN_PIPELINE_BLUR, + GSK_VULKAN_PIPELINE_BLUR_CLIP, + GSK_VULKAN_PIPELINE_BLUR_CLIP_ROUNDED, /* add more */ GSK_VULKAN_N_PIPELINES } GskVulkanPipelineType; diff --git a/gsk/meson.build b/gsk/meson.build index 83be577f1f..7725171ae9 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -50,6 +50,7 @@ gsk_private_vulkan_compiled_shaders = [] if have_vulkan gsk_private_sources += files([ 'gskvulkanblendpipeline.c', + 'gskvulkanblurpipeline.c', 'gskvulkanborderpipeline.c', 'gskvulkanboxshadowpipeline.c', 'gskvulkanbuffer.c', diff --git a/gsk/resources/vulkan/blur-clip-rounded.frag.spv b/gsk/resources/vulkan/blur-clip-rounded.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..42cb7c53a9fb2c056dd464468e621b9a4d9346b9 GIT binary patch literal 10828 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 literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/blur-clip-rounded.vert.spv b/gsk/resources/vulkan/blur-clip-rounded.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..eab7f32cabe52f17a92ac03f22f4bd0e984e3134 GIT binary patch literal 3916 zcmZ9OX?Ijb5QZ;ghOjTPs)&iWARwZ$iU^1}AkhR++>JwKl3Yw?;>;v~D~N!*;EH_q zclfvTc#a;Q=guv2r8%!%@7qD)<5X3~quR{>^3njlfc}FsTd-R|W?w z14o8OrlyA5oeLB7;fb_SAFidX`ba08sp~ht;FmT=CZ=mehcX_;y~{~&vY0*6MyK9t zlV#J)=#G6NNy_ZMkhLn%w(>KXT~3xWk4&UfnR}*{I2&gn1rz?IWG!=ZbhKUXv@^at zTW?QK;8CVm<{FxAj~{L}+MQ|xuLQM}>6ppn%oM!qXYbr^_)K%UQEUIF+n-E7m)1Jt z>b+UK9nbXfdO9|qrOs-op--_VQ^v>S)mC*f=jm;H3SK;uca=6yW~cOw);t^Elbn+` zJ@35iPRAyOPuE+W`uSsxTK#yyu>c@5#=+6wO@zUR<+Ix#thQ zk__hPrylFmUV}A{xeu(x-}A~#ppXB~XI2ya)V3hE)kQx(?(MqV9Ct9A!~Cn^E1CO% zV@u9gVe7LVzM9z>HTPV@?3((%ocsGxGv0X}aBQU}WA6lNB7E+`PLhiU!sl+7nm(be z&$)VN_h8Gr+JdYOd*~kKFh*$WyNZ(@XZGv^%-WuPD_yZKCqUFTJD0L=iR<=y1E)H} zTm@ebxWN ze9gT2%YC!q{|UBtqW=colW)~{W3Mp#*3^uZU(L0s^%~rv|L4rsTFv=&X5%B@_c?bj z^U3`^=wtj(xothJ%l%En`Y+gXK&;De=GrdalK19)IE?udrOa$D-?!gDYYFamCb)g` zn;b+X_w@fE9KPe-`1x)Y7VJgX zzN;n7@s4(58|yyK_X1<$zWZ`b-QoGew;#Lcdmmg)IEua-;YHv3;c6n@M%?KGXy(!< z`u`wyA8>^B5OyDMpU^g88}A71VQe-1;_fzMo6{V|=wolK(X}|^7Hs<#{n(1FCLHDr z-$$^EzT4nx!cp{n6khb*4p$Sm_v0}%bLkUjdK}wY9HBjdtyb*E4!H4-@Y{*4R_w0} z;cCKR-picLxAPh>mp*X^uVY(_BeXZL)r<}8O>E;Gp}mEzreECO+t}tbhcWut6ZPUZ zcsbm$6vQ`p8Mb{~!5rV+G3?#~PjepUABP*~8_`$p-;uM-?}8c_1>rxD>-w8ZzL&oo Q?lB1#1M|3M-D=kTFR(8v7ytkO literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/blur-clip.frag.spv b/gsk/resources/vulkan/blur-clip.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..b9864ccbe5ac101ad03b7950145c53702da3227c GIT binary patch literal 4008 zcmZ9O_j6QL6vrR13B9)v6ukeso(e|0Z!u z;Op_V>-i*ZMzj|8W}UCr0>*U{ef zL<=4SS4Kzc#m3E~&RKBGrL2D$do;0g(Qr$iJ;>G_0Z-MLAh#{5g5&bJ;zXla z$t?WW=Ug%uae0VW(BGEKNRo4;QmGZDaz4hF-RJ8T{O$j6d-MZ%s97I7QYqIP`EtYB z?d&b@x;|b7PsKU6&c^W7O0!(3KjNLsguf9N8e{S^lYFN=;m3;cwXvjha<7N*RrW+h z{p{s?u0gCLwijy=SHN9UFu{H!#=G?2M`y9$j@a`KWbV?I;I>D1TL*RxaH?=$zqLgf z&Kkz`WjN0%Hm zs{T1>eezwLeQs)-r_UJg5b7GU7;FuB#kwm}&U1BvSEA*tvjJ@UT7=bS&5an-5c%E| z`*w06eml0y_#J4^V9kwWsdpmA1X)g854aPtj(NM#=E+-Ey$5jx+=smoSw`0mrM%}l zjzrOKeIf27$Xelir*(7uRdmm9+#L7Ku7FqbPGua%d9F$tB zorh16Rfzm)IN#%QMBWv+FRB8PIBH>I!DIaG33|Q_oVol##PTO}5 zy*!8Qebx5zJo*CSvX>Xp`qkk)m$0o7diesjTpwaD#m^(wGFLm~zKCsZIQL7~a-o+m zW6NcGc?InJcy?z{tnK_6A9{He+g=)@&lqP|KI~t>cK^`JBDP$%m!n|$(93Jsa-o;b zxtuk9!!g8t0*#29(^lp9B^qwfOTZ1fGpz4V>pFTe`)1R}4vrXkaju-8p&@Be@r z#=nl3BOhYkz_uqL=1pwl^ zO`^@$CujaSwE5>#?C*zI9qQe|-i?HMcd_Lr5$oxbv)*2``TNk}KJQ?AX0dN{5Aj`x ZK;G}&l#^HdyCeS|Vy=GwzKH$%@-M$&V3Gg; literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/blur-clip.vert.spv b/gsk/resources/vulkan/blur-clip.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..eab7f32cabe52f17a92ac03f22f4bd0e984e3134 GIT binary patch literal 3916 zcmZ9OX?Ijb5QZ;ghOjTPs)&iWARwZ$iU^1}AkhR++>JwKl3Yw?;>;v~D~N!*;EH_q zclfvTc#a;Q=guv2r8%!%@7qD)<5X3~quR{>^3njlfc}FsTd-R|W?w z14o8OrlyA5oeLB7;fb_SAFidX`ba08sp~ht;FmT=CZ=mehcX_;y~{~&vY0*6MyK9t zlV#J)=#G6NNy_ZMkhLn%w(>KXT~3xWk4&UfnR}*{I2&gn1rz?IWG!=ZbhKUXv@^at zTW?QK;8CVm<{FxAj~{L}+MQ|xuLQM}>6ppn%oM!qXYbr^_)K%UQEUIF+n-E7m)1Jt z>b+UK9nbXfdO9|qrOs-op--_VQ^v>S)mC*f=jm;H3SK;uca=6yW~cOw);t^Elbn+` zJ@35iPRAyOPuE+W`uSsxTK#yyu>c@5#=+6wO@zUR<+Ix#thQ zk__hPrylFmUV}A{xeu(x-}A~#ppXB~XI2ya)V3hE)kQx(?(MqV9Ct9A!~Cn^E1CO% zV@u9gVe7LVzM9z>HTPV@?3((%ocsGxGv0X}aBQU}WA6lNB7E+`PLhiU!sl+7nm(be z&$)VN_h8Gr+JdYOd*~kKFh*$WyNZ(@XZGv^%-WuPD_yZKCqUFTJD0L=iR<=y1E)H} zTm@ebxWN ze9gT2%YC!q{|UBtqW=colW)~{W3Mp#*3^uZU(L0s^%~rv|L4rsTFv=&X5%B@_c?bj z^U3`^=wtj(xothJ%l%En`Y+gXK&;De=GrdalK19)IE?udrOa$D-?!gDYYFamCb)g` zn;b+X_w@fE9KPe-`1x)Y7VJgX zzN;n7@s4(58|yyK_X1<$zWZ`b-QoGew;#Lcdmmg)IEua-;YHv3;c6n@M%?KGXy(!< z`u`wyA8>^B5OyDMpU^g88}A71VQe-1;_fzMo6{V|=wolK(X}|^7Hs<#{n(1FCLHDr z-$$^EzT4nx!cp{n6khb*4p$Sm_v0}%bLkUjdK}wY9HBjdtyb*E4!H4-@Y{*4R_w0} z;cCKR-picLxAPh>mp*X^uVY(_BeXZL)r<}8O>E;Gp}mEzreECO+t}tbhcWut6ZPUZ zcsbm$6vQ`p8Mb{~!5rV+G3?#~PjepUABP*~8_`$p-;uM-?}8c_1>rxD>-w8ZzL&oo Q?lB1#1M|3M-D=kTFR(8v7ytkO literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/blur.frag b/gsk/resources/vulkan/blur.frag new file mode 100644 index 0000000000..85db0293f4 --- /dev/null +++ b/gsk/resources/vulkan/blur.frag @@ -0,0 +1,52 @@ +#version 420 core + +#include "clip.frag.glsl" + +layout(location = 0) in vec2 inPos; +layout(location = 1) in vec2 inTexCoord; +layout(location = 2) in float inRadius; + +layout(set = 0, binding = 0) uniform sampler2D inTexture; + +layout(location = 0) out vec4 color; + +const int c_samplesX = 15; // must be odd +const int c_samplesY = 15; // must be odd +const float c_textureSize = 512.0; + +const int c_halfSamplesX = c_samplesX / 2; +const int c_halfSamplesY = c_samplesY / 2; +const float c_pixelSize = (1.0 / c_textureSize); + +float Gaussian (float sigma, float x) +{ + return exp(-(x*x) / (2.0 * sigma*sigma)); +} + +vec3 BlurredPixel (in vec2 uv) +{ + float c_sigmaX = inRadius; + float c_sigmaY = inRadius; + float total = 0.0; + vec3 ret = vec3(0); + + for (int iy = 0; iy < c_samplesY; ++iy) + { + float fy = Gaussian (c_sigmaY, float(iy) - float(c_halfSamplesY)); + float offsety = float(iy-c_halfSamplesY) * c_pixelSize; + for (int ix = 0; ix < c_samplesX; ++ix) + { + float fx = Gaussian (c_sigmaX, float(ix) - float(c_halfSamplesX)); + float offsetx = float(ix-c_halfSamplesX) * c_pixelSize; + total += fx * fy; + ret += texture(inTexture, uv + vec2(offsetx, offsety)).rgb * fx*fy; + } + } + return ret / total; +} + +void main() +{ +// color = clip (inPos, vec4(BlurredPixel (inTexCoord), 1.0)); + color = clip (inPos, vec4(1.0, 0.0, 0.0, 1.0)); +} diff --git a/gsk/resources/vulkan/blur.frag.glsl b/gsk/resources/vulkan/blur.frag.glsl new file mode 100644 index 0000000000..528db202b0 --- /dev/null +++ b/gsk/resources/vulkan/blur.frag.glsl @@ -0,0 +1,13 @@ +#version 420 core + +#include "clip.frag.glsl" + +layout(location = 0) in vec2 inPos; +layout(location = 1) in float inRadius; + +layout(location = 0) out vec4 color; + +void main() +{ + color = clip (inPos, vec4(1, 0, 0, 0)); +} diff --git a/gsk/resources/vulkan/blur.frag.spv b/gsk/resources/vulkan/blur.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..b9864ccbe5ac101ad03b7950145c53702da3227c GIT binary patch literal 4008 zcmZ9O_j6QL6vrR13B9)v6ukeso(e|0Z!u z;Op_V>-i*ZMzj|8W}UCr0>*U{ef zL<=4SS4Kzc#m3E~&RKBGrL2D$do;0g(Qr$iJ;>G_0Z-MLAh#{5g5&bJ;zXla z$t?WW=Ug%uae0VW(BGEKNRo4;QmGZDaz4hF-RJ8T{O$j6d-MZ%s97I7QYqIP`EtYB z?d&b@x;|b7PsKU6&c^W7O0!(3KjNLsguf9N8e{S^lYFN=;m3;cwXvjha<7N*RrW+h z{p{s?u0gCLwijy=SHN9UFu{H!#=G?2M`y9$j@a`KWbV?I;I>D1TL*RxaH?=$zqLgf z&Kkz`WjN0%Hm zs{T1>eezwLeQs)-r_UJg5b7GU7;FuB#kwm}&U1BvSEA*tvjJ@UT7=bS&5an-5c%E| z`*w06eml0y_#J4^V9kwWsdpmA1X)g854aPtj(NM#=E+-Ey$5jx+=smoSw`0mrM%}l zjzrOKeIf27$Xelir*(7uRdmm9+#L7Ku7FqbPGua%d9F$tB zorh16Rfzm)IN#%QMBWv+FRB8PIBH>I!DIaG33|Q_oVol##PTO}5 zy*!8Qebx5zJo*CSvX>Xp`qkk)m$0o7diesjTpwaD#m^(wGFLm~zKCsZIQL7~a-o+m zW6NcGc?InJcy?z{tnK_6A9{He+g=)@&lqP|KI~t>cK^`JBDP$%m!n|$(93Jsa-o;b zxtuk9!!g8t0*#29(^lp9B^qwfOTZ1fGpz4V>pFTe`)1R}4vrXkaju-8p&@Be@r z#=nl3BOhYkz_uqL=1pwl^ zO`^@$CujaSwE5>#?C*zI9qQe|-i?HMcd_Lr5$oxbv)*2``TNk}KJQ?AX0dN{5Aj`x ZK;G}&l#^HdyCeS|Vy=GwzKH$%@-M$&V3Gg; literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/blur.vert b/gsk/resources/vulkan/blur.vert new file mode 100644 index 0000000000..f50ca37980 --- /dev/null +++ b/gsk/resources/vulkan/blur.vert @@ -0,0 +1,30 @@ +#version 420 core + +#include "clip.vert.glsl" + +layout(location = 0) in vec4 inRect; +layout(location = 1) in float inRadius; + +layout(location = 0) out vec2 outPos; +layout(location = 1) out flat float outRadius; + +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; + outRadius = inRadius; +} + diff --git a/gsk/resources/vulkan/blur.vert.glsl b/gsk/resources/vulkan/blur.vert.glsl new file mode 100644 index 0000000000..f50ca37980 --- /dev/null +++ b/gsk/resources/vulkan/blur.vert.glsl @@ -0,0 +1,30 @@ +#version 420 core + +#include "clip.vert.glsl" + +layout(location = 0) in vec4 inRect; +layout(location = 1) in float inRadius; + +layout(location = 0) out vec2 outPos; +layout(location = 1) out flat float outRadius; + +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; + outRadius = inRadius; +} + diff --git a/gsk/resources/vulkan/blur.vert.spv b/gsk/resources/vulkan/blur.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..6f4cd276a0c67789a4f2de0c54895594cf647d63 GIT binary patch literal 2184 zcmZ9N+foxj5QYbma8g7>4qA#qP(ct;If@{N7|>J^vC7*RlZ9+m*rc)>#5=w40elA^ z(i<)RZ?Xeh4%Kx3e;=l2rWaD3likL2=%?T0O?wTRPGMs%nJ%ky`49Q|FsjTiE-eso z#iVQ?F$0QXr6ngNKft~tnUyR`b|rg~w~~~8I;DRpF>U%xE?>+Y9OUx5#d4!j45P0# zuUPW~uUPS$UODnlJ>q&2aeh#)wJOPgj3SbIXH3R+RId4r>C>adb?rw?pEO0KEWRdP zKROD%D75(Ye}2y32ZuI;{H$=J)GVDyXLOD!aGl&Pd)DJx@uSy_ytDnF;++xGWu7WV ze8FqBU4mlUJT|_1=tq7%ur;|a7P%|Zg;rSIsRvDS0T_Qx5mSYEKR^Da+CCUgC@yi!U9Q|_ci~dup&CIub*!b9oSkCY8kSb7PLiMPRJtC`1 zIx87fJpF>1*{pu|NW&o$!o9H#Pkg^L@zfd?rjM+IH5=mr*~Huu<}S#AqyC^YKKS(* zGy8DlqlYA{Io&I{*ClX>iy4+}%(s^=W<&^%7{`sq7~XMXvcYYx*Y#KMygW(HmUBiWpr{BgYx^GH4RekRS^!I2B* zyM*H|sJSFzjR`MHlgoRKt15HkICxigRW@&npSobaH#qiv9^2%CUrDp4%YPkXdL|#t zoDxHPF19%relWA@{QI&yB+d_JcHx%w?#vfwV3G4%4BsEMm_`0R(u>2{1fG;V72{21 zGhe*%hH}Z7knn!^vN2v$b$oXv{2jzHJHnY*{;F z=V?bavrI4a3MS6=@kTa%;MCEM|H|am-Dhgju>Q PO)cVX#{6IL*wpw3Ayl6H literal 0 HcmV?d00001 diff --git a/gsk/resources/vulkan/meson.build b/gsk/resources/vulkan/meson.build index 8595ccf605..bdca123ed6 100644 --- a/gsk/resources/vulkan/meson.build +++ b/gsk/resources/vulkan/meson.build @@ -8,6 +8,7 @@ gsk_private_vulkan_fragment_shaders = [ 'blend.frag', + 'blur.frag', 'border.frag', 'color.frag', 'color-matrix.frag', @@ -18,6 +19,7 @@ gsk_private_vulkan_fragment_shaders = [ gsk_private_vulkan_vertex_shaders = [ 'blend.vert', + 'blur.vert', 'border.vert', 'color.vert', 'color-matrix.vert',