Commit Graph

59 Commits

Author SHA1 Message Date
Benjamin Otte
1723ab34e1 gpu: Setup attribute locations
Make the generator generate calls for the correct glBindAttribLocation()
calls.

Usually this was done correctly, but we can't rely on it. So do it
explicitly.
2024-01-07 07:22:53 +01:00
Benjamin Otte
48c1f5fd27 gpu: Add supersampling for gradients
Unless GSK_GPU_SKIP=gradients is given, we sample every point 4x instead
of 1x. That makes the shader run slower (by roughly a factor of 2.5x)
but it improves quality quite a bit.
2024-01-07 07:22:53 +01:00
Benjamin Otte
6e4a526ddf gpu: Add a blend mode shader
I'm a bit unsure about using the zero rect in the fallback situtation
where one image doesn't exist, but it seems to work.

This removes the last pattern-only rendernode and with that the last
fallback usage with disabled ubershader.
2024-01-07 07:22:53 +01:00
Benjamin Otte
d11886e7ac gpu: Use variations in the blur shader
Have one variation for colorizing to a shadow color and another
variation that just blurs.
2024-01-07 07:22:53 +01:00
Benjamin Otte
177b19a2da gpu: Use variations in the straight-alpha shader
This way we can toggle opacity handling on/off.

THe shader slowly turns into a fancy texture op - but I don't want to
rename it to "fancytexture" just yet.
2024-01-07 07:22:53 +01:00
Benjamin Otte
f943469fc9 gpu: Use variations for radial gradients 2024-01-07 07:22:53 +01:00
Benjamin Otte
59d062cb3d gpu: Use variations for the mask mode 2024-01-07 07:22:53 +01:00
Benjamin Otte
8032e30a76 gpu: Make linear gradients use variations 2024-01-07 07:22:53 +01:00
Benjamin Otte
2e81e4d452 gpu: Make box shadow shader use variations
Use it do differentiate between inset and outset shadows.
2024-01-07 07:22:53 +01:00
Benjamin Otte
d900407a18 gpu: Introduce the concept of "variation"
A variation is a #define/specialization constant that every shader can
use to specialize itself as it sees fit.

This commit adds the infrastrcture, future commits will add
implementations.
2024-01-07 07:22:53 +01:00
Benjamin Otte
b9651606d3 gpu: Add a cross-fade shader 2024-01-07 07:22:53 +01:00
Benjamin Otte
9947760d87 gpu: Handle alpha in image_op() wrapper
There are various places where the alpha is implicitly assumed to be
handled, so just handle it.

As a bonus, this simplifies a bunch of code and makes the texture node
rendering work with alpha.
2024-01-07 07:22:53 +01:00
Benjamin Otte
493b83ff24 gpu: Optimize box-shadow shader
Like in the border shader, don't draw the (potentially large for the
window's shadow) inside part that is transparent.
2024-01-07 07:22:53 +01:00
Benjamin Otte
69c8278558 gpu: Add a radial gradient shader
This is mainly copy/paste, so now this almost identical gradient code
exists 3 times.
That's kinda suboptimal.
2024-01-07 07:22:53 +01:00
Benjamin Otte
0e9b967bf9 gpu: Add a conic gradient shader 2024-01-07 07:22:53 +01:00
Benjamin Otte
8361949ba1 gpu: Handle >7 color stops
If there are more than 7 color stops, we can split the gradient into
multiple gradients with color stops like so:
  0, 1, 2, 3, 4, 5, transparent
  transparent, 6, 7, 8, 9, 10, transparent
  ...
  transparent, n-2, n-1, n
and use the new BLEND_ADD to draw them on top of each other.

Adapt the testcae that tests this to use colors that work with the fancy
algorithm we use now, so that BLEND_ADD and transitions to transparent
do not cause issues.
2024-01-07 07:22:52 +01:00
Benjamin Otte
8372bc00bd gpu: Make the ubershader use the correct coordinates
Instead of scaled coordinates, use the unscaled ones.

This ensure that gradients get computed correctly as they are not safe
against nonorthogonal transforms - like scales with different scale
factors.
2024-01-07 07:22:52 +01:00
Benjamin Otte
a031011e5e gpu: Add a linear-gradient shader
The shader can only deal with up to 7 color stops - but that's good
enough for the real world.

Plus, we have the uber shader.

And if that fails, we can still fall back to Cairo.

The code also doesn't handle repeating linear gradients yet.
2024-01-07 07:22:52 +01:00
Benjamin Otte
bd901896ee gpu: Add a mask shader
This shader can take over from the ubershader. And it can be used
instead of launching the ubershader when no offscreens are necessary.

Also includes an optimization that uses the colorize shader when
appropriate.
2024-01-07 07:22:52 +01:00
Benjamin Otte
d8a0cd24d7 gpu: Add support for blend modes 2024-01-07 07:22:52 +01:00
Benjamin Otte
1b38cbd410 gpu: Handle storage buffers via descriptors
This makes the (currently single) storage buffer handled by
GskGpuDescriptors.
A side effect is that we now have support for multiple buffers in place.
We just have to use it.

Mixed into this commit is a complete rework of the pattern writer.
Instead of writing straight into the buffer (complete with repeatedly
backtracking when we have to do offscreens), write into a temporary
buffer and copy into the storage buffer on committing.
2024-01-07 07:22:52 +01:00
Benjamin Otte
42d89a0ff1 gpu: Add a color matrix shader
This allows avoiding the uber shader in 2 important cases:

1. opacity - and Adwaita uses that a lot
2. color-matrix - it's used for symbolic icons
2024-01-07 07:22:52 +01:00
Benjamin Otte
a06cd6a821 gpu: Make the uber shader handle affine transforms
Fixes the last (non-blur) Nautilus offscreens in Nautilus.
2024-01-07 07:22:52 +01:00
Benjamin Otte
c5a01cd14b gpu: Make the texture ladder handle 32 textures
So now we can put more textures in one descriptor set even if dynamic
indexing isn't supported.
2024-01-07 07:22:52 +01:00
Benjamin Otte
719ff9eca9 gpu: Require Vulkan 1.2 shaders for dynamic indexing
Shader compilers struggle with compiling code that indexes texture
arrays by indexes, so keep the fallback shaders simple and don't do that
there.

There's not much of a performance difference anyway between those two
methods.
2024-01-07 07:22:52 +01:00
Benjamin Otte
78a7127b96 gpu: Handle missing support nor nonuniform texture accesses
We compile custom shaders for Vulkan 1.0 that don't require the
extension.

We  also ensure that our accesses are uniform by only executing one
shader at a time.
2024-01-07 07:22:51 +01:00
Benjamin Otte
94063cbe92 gpu: Change the meson code for how SPIR-V is built
This does the same thing, but in a way that's a bit more flexible.
And it prepares the next commit...
2024-01-07 07:22:51 +01:00
Benjamin Otte
95e36af46b gpu: Update shader code for different buffer/sampler sizes
Use specialization constants for that.
2024-01-07 07:22:51 +01:00
Benjamin Otte
a301f18ebf gpu: Track position fwidth explicitly
This is relevant went encountering repeat nodes, where the repeat cutoff
will make the fwidth of the position go wild otherwise.

Gradients require more work now, because we need to compute offsets
twice - once for the pixel, once for the offst.
2024-01-07 07:22:51 +01:00
Benjamin Otte
ef20b706e2 gpu: Prepare GL rendering for samplerExternalEOS
Carry an n_external_textures variable around when selecting programs and
compile different programs for different amounts of external textures.

For now, this code is unused, but dmabufs will need it.
2024-01-07 07:22:51 +01:00
Benjamin Otte
b4a1ed2a70 gpu: Add straight alpha support
Add a GSK_GPU_IMAGE_STRAIGHT_ALPHA and use it for images that have
straight alpha.
Make sure those images get passed through a premultiplying pass with
the new straight alpha shader.

Also remove the old Postprocess flags from the Vulkan image that were a
leftover from copying that code from the old Vulkan renderer.
2024-01-07 07:22:51 +01:00
Benjamin Otte
f05a8927f3 gpu: Work around Ycbcr not working with dynamically uniform indices
There's a well hidden line in the spec that says in
https://registry.khronos.org/vulkan/specs/1.3/html/chap15.html#interfaces-resources-descset

  If the combined image sampler enables sampler Y′CBCR conversion,
  it **must** be indexed only by constant integral expressions when
  aggregated into arrays in shader code, irrespective of the
  shaderSampledImageArrayDynamicIndexing feature.

So we'll use the same trick that we use for old GL here and do an
if dance that gives us dynamically uniform expressions.
2024-01-07 07:22:51 +01:00
Benjamin Otte
bf39fa3b3b gpu: Hook up immutable samplers to shaders
Define an array with a compile-time-constant variable size for the
immutable samplers.

A bunch of work is necessary to ensure that at least one element is in
the sampler array, because the GLSL code
  sampler2D immutable_textures[0];
is invalid.
2024-01-07 07:22:51 +01:00
Benjamin Otte
d2229e2aed gpu: Add GskVulkanPipelineLayout
This allows having different layouts sothat we can support immutable
samplers, whcih are required for multiplane and YUV formats.

We don't use them yet.
2024-01-07 07:22:51 +01:00
Benjamin Otte
334e380d31 gpu: Handle overlapping rounded rect corners
Have a fallback in place for the most egregious abuses of rounded
corners, like
  0 0 50 50 / 50 0
and the like.

Fixes obscure border colors.
2024-01-07 07:22:51 +01:00
Benjamin Otte
d8db673fb7 gpu: Add a box shadow shader
Code was inspired mainly by
  https://madebyevan.com/shaders/fast-rounded-rectangle-shadows/
and
  https://pcwalton.github.io/_posts/2015-12-21-drawing-css-box-shadows-in-webrender.html

So far the results aren't cached, that's the task of future commits.
2024-01-07 07:22:51 +01:00
Benjamin Otte
268ad54c6a gpu: Add a rounded color shader
There's multiple uses I want it for:

1. Generating the box-shadow area for blurring
2. Generating masks for rounded-rect masking
3. Optimizing the common use case of rounded-clip + color

Only the last one is implemented in this commit.
2024-01-07 07:22:50 +01:00
Benjamin Otte
64a67ac3a8 gpu: Turn globals into macros
This way, we can be more flexible in refactoring how we handle globals
(guess what we're gonna do next).
2024-01-07 07:22:50 +01:00
Benjamin Otte
8271687ef6 gpu: Make border shader usable for inset/outset
... and use it for those when unblurred.
2024-01-07 07:22:50 +01:00
Benjamin Otte
48012a1ce4 gpu: Add a color shader
We don't want to use the pattern shader for simple colors, slow GPUs do
not like this at all.
2024-01-07 07:22:50 +01:00
Benjamin Otte
23c1ec07e7 gpu: Implement shadow nodes 2024-01-07 07:22:50 +01:00
Benjamin Otte
43d0b0fb3c gpu: Turn off optimizing in glslc
The code generated by glslc -O is optimized worse by Mesa than
code generated unoptimized.

So generate unoptimized code until somebody figures out what's going
wrong here.
2024-01-07 07:22:50 +01:00
Benjamin Otte
d47c8613b0 gpu: Add support for mask patterns 2024-01-07 07:22:50 +01:00
Benjamin Otte
e01311a565 gpu: Add support for cross-fades 2024-01-07 07:22:50 +01:00
Benjamin Otte
0876089f8f gpu: Add repeat nodes
They're done using the pattern shader.

The pattern shader now gained a stack where vec4's can be pushed and
popped back later, which allows storing the position before computing
the new position inside the repeat node's child.
2024-01-07 07:22:50 +01:00
Benjamin Otte
b7a8c2207e gpu: Introduce gsk_texture() shader function/macro
Due to GLES and old GL not allowing non-constant texture array
lookups,we need to turn the array lookup into a big switch statementin
those versions, and that requires putting the texture() call into that
switch.

But with that trick, we can use texture IDs in GLSL.
2024-01-07 07:22:50 +01:00
Benjamin Otte
5ab8fde0bc gpu: Add colorize shader
... and use it for glyphs.

The name is a slight variation of the "coloring" name from the GL
renderer.
The functionality is exactly what the "glyph" shader from the Vulkan
renderer does.
2024-01-07 07:22:50 +01:00
Benjamin Otte
d1d1af1a62 gpu: Improve conic gradient rendering
1. Compute the fwidth() twice with offset offsets
   That way, we avoid glitches at the boundary between 0.0 and 1.0,
   because by offsetting it by 0.5, that boundary goes away.
   Then we take the min() of both which gives us the one we care about.

2. Set the gradient to repeating
   By doing that, we don't get values at the 0.0/1.0 boundary clamped,
   but things smoothly transition.
   This smoothes the line at that boundary and makes it look just like
   every other line.
2024-01-07 07:22:50 +01:00
Benjamin Otte
a9b8551e70 gpu: Add clip pattern
So now we can clip inside an opacity node without needing fallback.
2024-01-07 07:22:50 +01:00
Benjamin Otte
3efe1bef93 gpu: Add a border shader
Pretty much a copy of the Vulkan border shader.

A notable change is that the input arguments are changed, because GL
gets confused if you put a mat4 at the end.
2024-01-07 07:22:50 +01:00