summaryrefslogtreecommitdiff
path: root/gsk/vulkan/resources
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-05-07 01:06:52 +0200
committerBenjamin Otte <otte@redhat.com>2023-05-17 02:25:32 +0200
commit53c04ca39ce4dc5f34f8d84ffccbf3f839cff830 (patch)
tree8d6e0f7bb904a9cc051d86337cb52ea34262dc6f /gsk/vulkan/resources
parent0e5d48ea39530188cab6c3cc6d490f7acca368b4 (diff)
downloadgtk+-53c04ca39ce4dc5f34f8d84ffccbf3f839cff830.tar.gz
vulkan: Start rework on shaders to allow antialiased drawing
This introduces the rect object and adds a rect_distance() and rect_coverage() function. _distance() returns the signed distance tp the rectangle. _coverage() returns the coverage of a pixel centered at that position. Note that the pixel size is computed using dFdx/dFdy.
Diffstat (limited to 'gsk/vulkan/resources')
-rw-r--r--gsk/vulkan/resources/clip.vert.glsl31
-rw-r--r--gsk/vulkan/resources/color.frag7
-rw-r--r--gsk/vulkan/resources/color.vert9
-rw-r--r--gsk/vulkan/resources/meson.build3
-rw-r--r--gsk/vulkan/resources/rect.frag.glsl16
-rw-r--r--gsk/vulkan/resources/rect.glsl46
-rw-r--r--gsk/vulkan/resources/rect.vert.glsl6
7 files changed, 111 insertions, 7 deletions
diff --git a/gsk/vulkan/resources/clip.vert.glsl b/gsk/vulkan/resources/clip.vert.glsl
index 0dce1a0fb7..ae5c75a39d 100644
--- a/gsk/vulkan/resources/clip.vert.glsl
+++ b/gsk/vulkan/resources/clip.vert.glsl
@@ -1,4 +1,5 @@
#include "constants.glsl"
+#include "rect.vert.glsl"
#ifndef _CLIP_
#define _CLIP_
@@ -14,21 +15,47 @@ vec4 intersect(vec4 a, vec4 b)
}
#ifdef CLIP_ROUNDED_RECT
-vec4 clip(vec4 rect)
+
+vec4
+clip(vec4 rect)
{
/* rounded corner clipping is done in fragment shader */
return intersect(rect, push.clip_bounds);
}
+
+Rect
+clip_rect (vec4 xywh)
+{
+ /* rounded corner clipping is done in fragment shader */
+ return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds)));
+}
+
#elif defined(CLIP_RECT)
-vec4 clip(vec4 rect)
+
+vec4
+clip(vec4 rect)
{
return intersect(rect, push.clip_bounds);
}
+
+Rect
+clip_rect (vec4 xywh)
+{
+ return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds)));
+}
+
#elif defined(CLIP_NONE)
vec4 clip(vec4 rect)
{
return rect;
}
+
+Rect
+clip_rect (vec4 xywh)
+{
+ return rect_from_gsk (xywh);
+}
+
#else
#error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT"
#endif
diff --git a/gsk/vulkan/resources/color.frag b/gsk/vulkan/resources/color.frag
index 6b299dffd0..1f988b6517 100644
--- a/gsk/vulkan/resources/color.frag
+++ b/gsk/vulkan/resources/color.frag
@@ -1,13 +1,16 @@
#version 420 core
#include "clip.frag.glsl"
+#include "rect.frag.glsl"
layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec4 inColor;
+layout(location = 1) in Rect inRect;
+layout(location = 2) in vec4 inColor;
layout(location = 0) out vec4 color;
void main()
{
- color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a));
+ float alpha = inColor.a * rect_coverage (inRect, inPos);
+ color = clip (inPos, vec4(inColor.rgb, 1) * alpha);
}
diff --git a/gsk/vulkan/resources/color.vert b/gsk/vulkan/resources/color.vert
index 1e1618aef9..7601b7d82a 100644
--- a/gsk/vulkan/resources/color.vert
+++ b/gsk/vulkan/resources/color.vert
@@ -1,12 +1,14 @@
#version 420 core
#include "clip.vert.glsl"
+#include "rect.vert.glsl"
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inColor;
layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec4 outColor;
+layout(location = 1) out flat Rect outRect;
+layout(location = 2) out flat vec4 outColor;
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
@@ -16,10 +18,11 @@ vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 1.0) };
void main() {
- vec4 rect = clip (inRect);
+ Rect rect = rect_to_int (clip_rect (inRect));
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ vec2 pos = mix (rect.bounds.xy, rect.bounds.zw, offsets[gl_VertexIndex]);
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outPos = pos;
+ outRect = rect_from_gsk (inRect);
outColor = inColor;
}
diff --git a/gsk/vulkan/resources/meson.build b/gsk/vulkan/resources/meson.build
index 86e98acb9e..802f391b4d 100644
--- a/gsk/vulkan/resources/meson.build
+++ b/gsk/vulkan/resources/meson.build
@@ -2,6 +2,9 @@ gsk_private_vulkan_include_shaders = [
'clip.frag.glsl',
'clip.vert.glsl',
'constants.glsl',
+ 'rect.glsl',
+ 'rect.frag.glsl',
+ 'rect.vert.glsl',
'rounded-rect.glsl',
]
diff --git a/gsk/vulkan/resources/rect.frag.glsl b/gsk/vulkan/resources/rect.frag.glsl
new file mode 100644
index 0000000000..73e9db9fd5
--- /dev/null
+++ b/gsk/vulkan/resources/rect.frag.glsl
@@ -0,0 +1,16 @@
+#ifndef _RECT_FRAG_
+#define _RECT_FRAG_
+
+#include "rect.glsl"
+
+float
+rect_coverage (Rect r, vec2 p)
+{
+ vec2 dFdp = abs(fwidth (p));
+ Rect prect = Rect(vec4(p - 0.5 * dFdp, p + 0.5 * dFdp));
+ Rect coverect = rect_intersect (r, prect);
+ vec2 coverage = rect_size(coverect) / dFdp;
+ return coverage.x * coverage.y;
+}
+
+#endif
diff --git a/gsk/vulkan/resources/rect.glsl b/gsk/vulkan/resources/rect.glsl
new file mode 100644
index 0000000000..ba07a05a98
--- /dev/null
+++ b/gsk/vulkan/resources/rect.glsl
@@ -0,0 +1,46 @@
+#ifndef _RECT_
+#define _RECT_
+
+struct Rect
+{
+ /* x,y and y,w make up the 2 points of this rect,
+ note that this is not containing width or height */
+ vec4 bounds;
+};
+
+Rect
+rect_from_gsk (vec4 xywh)
+{
+ return Rect(xywh.xyxy + vec4(0,0,xywh.zw));
+}
+
+float
+rect_distance (Rect r, vec2 p)
+{
+ vec4 distance = (r.bounds - p.xyxy) * vec4(1.0, 1.0, -1.0, -1.0);
+ vec2 max2 = max (distance.xy, distance.zw);
+ return length (max (max2, 0)) + min (max(max2.x, max2.y), 0);
+}
+
+vec2
+rect_size (Rect r)
+{
+ return r.bounds.zw - r.bounds.xy;
+}
+
+Rect
+rect_to_int (Rect r)
+{
+ return Rect (vec4 (floor(r.bounds.xy), ceil (r.bounds.zw)));
+}
+
+Rect
+rect_intersect (Rect a, Rect b)
+{
+ vec4 result = vec4(max(a.bounds.xy, b.bounds.xy), min(a.bounds.zw, b.bounds.zw));
+ if (any (greaterThanEqual (result.xy, result.zw)))
+ return Rect (vec4(0.0));
+ return Rect(result);
+}
+
+#endif
diff --git a/gsk/vulkan/resources/rect.vert.glsl b/gsk/vulkan/resources/rect.vert.glsl
new file mode 100644
index 0000000000..e6f90b8dd1
--- /dev/null
+++ b/gsk/vulkan/resources/rect.vert.glsl
@@ -0,0 +1,6 @@
+#ifndef _RECT_VERT_
+#define _RECT_VERT_
+
+#include "rect.glsl"
+
+#endif