Commit Graph

78620 Commits

Author SHA1 Message Date
Benjamin Otte
89b1a0a10b gpu: Make Vulkan image formats check use newer functions
This is just an update of all vkGetFoo() calls to use vkGetFoo2().
2024-01-04 01:36:12 +01:00
Benjamin Otte
6e76e8b56e gpu: Move caching to the upload_texture() function
So when uploading a texture, we will automatically put it into the cache
now.
2024-01-04 01:36:11 +01:00
Benjamin Otte
f4879a0f2e gpu: Factor out uploading textures into a vfunc
This way GL and Vulkan can run custom code to import GL textures and
dmabufs.

This function also decides if and how to cache the textures it creates.
2024-01-04 01:36:11 +01:00
Benjamin Otte
cfb2a31382 gpu: Apply clip to ubershader bounds
Fixes excessive bounds when using the ubershader for huge nodes
contained inside clip nodes.
2024-01-04 01:36:11 +01:00
Benjamin Otte
40797e146d gpu: Fail to create images that are too big
It's up to the renderers to handle the NULL return value.
2024-01-04 01:36:11 +01:00
Benjamin Otte
5e6517a43f gpu: Allow texture uploads to fail
The main reason here is that we want to not fail when the texture size
is larger than the supported GpuImage size.

When that happens, for now we just fallback slowly - ulitmately to
drawing with Cairo, which is going to be clipped.
2024-01-04 01:36:11 +01:00
Benjamin Otte
095b798e8c gpu: Add render_texture() fallback impl for huge sizes
This copies over the GLRenderer approach of step-by-step filling a
memorytexture.

It just adds some extra niceties by respecting the best format.
2024-01-04 01:36:11 +01:00
Benjamin Otte
d259b5a8cc gpu: Add gsk_gpu_device_get_max_image_size()
... and initialize it properly.
2024-01-04 01:36:11 +01:00
Benjamin Otte
3c11c703e6 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-04 01:36:11 +01:00
Benjamin Otte
78113ac63c 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-04 01:36:11 +01:00
Benjamin Otte
e9f5328010 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-04 01:36:11 +01:00
Benjamin Otte
463cd55395 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-04 01:36:10 +01:00
Benjamin Otte
ebf291eb2d gpu: Don't try to be smart
Don't try to use all those fancy GL features like glMapBuffer() and
such. Just malloc() some buffer memory and glBufferSubData() it later.

That works everywhere and is faster than (almost?) any combination of
fancy new buffer APIs. And yes I'm frustrated because I played with
those flags and none of them were better than this.

Doubles the framerate on my discrete AMD GPU.
2024-01-04 01:36:10 +01:00
Benjamin Otte
e54ff3110b gpu: Use GL_STREAM_DRAW for the push constants buffer
This seems to hit a bunch of optimizations and makes push constants
slightly faster.
2024-01-04 01:36:10 +01:00
Benjamin Otte
84505db614 gpu: Merge ops on GL, too
Just like on Vulkan, try to minimize the glDrawArrays() calls by merging
adjacent ops.
2024-01-04 01:36:10 +01:00
Benjamin Otte
5e95af0c4c gpu: Refactor image handling
Introduce a new GskGpuImageDescriptors object that tracks descriptors
for a set of images that can be managed by the GPU.
Then have each GskGpuShaderOp just reference the descriptors object they are
using, so that the coe can set things up properly.

To reference an image, the ops now just reference their descriptor -
which is the uint32 we've been sending to the shaders since forever.
2024-01-04 01:36:10 +01:00
Benjamin Otte
ee89451a78 gpu: Add atlas support
... and use it for glyphs.
2024-01-04 01:36:10 +01:00
Benjamin Otte
998ede9e87 gpu: Add a GL optimization
Use glDrawArraysInstancedBaseInstance() to draw. (Yay for GL naming.)
That allows setting up the offset in the vertex array without having to
glVertexAttribPointer() everything again.

However, this is only supported since GL 4.2 and not at all in stock GLES,
so we need to have code that can work without it.
Fortunately, it is mandatory in Vulkan, so every recent GPU supports it.
And if that GPU has a proper driver, it will also expose the GL extension
for it.
(Hint: You can check https://opengles.gpuinfo.org/listextensions.php for
how many proper drivers exist outside of Mesa.)
2024-01-04 01:36:10 +01:00
Benjamin Otte
9fe0eab943 gpu: Make border shader usable for inset/outset
... and use it for those when unblurred.
2024-01-04 01:36:10 +01:00
Benjamin Otte
f0835717b9 gpu: Add GSK_GPU_SKIP env var
The env var allows skipping various optimizations in the GPU shader.

This is useful for testing during development when trying to figure
out how to make a renderer as fast as possible.

We could also use it to enable/disable optimizations depending on GL
version or so, but I didn't think about that too much yet.
2024-01-04 01:36:10 +01:00
Benjamin Otte
33f02a6365 gpu: Copy the clear trick from the Vulkan shader
When drawing opaque color regions that are large enough, use
vkCmdClearAttachments()/glClear() instead of a shader. This speeds up
background rendering on particular on older GPUs.

See the commit messages of
  bb2cd7225e
  ce042f7ba1
  0edd7547c1
for a further discussion of performance impacts.
2024-01-04 01:36:09 +01:00
Benjamin Otte
0d39299337 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-04 01:36:09 +01:00
Benjamin Otte
144303afe6 gpu: Implement blur nodes
With the work already done with shadow nodes, this one was easy.
2024-01-04 01:36:09 +01:00
Benjamin Otte
3e2a93352f gpu: Implement shadow nodes 2024-01-04 01:36:09 +01:00
Benjamin Otte
4f3c3a05c9 gpu: Change sorting for ops
The previous algorithm would reverse the order of subpasses, whcih leads
to unexpected behavior if dependent subpasses are not added as children
of a subpass, but just as a previous subpass - like when a subpass is
used multiple times later.

An example for this is a shadow node with multiple shadows - the source
of the shadow is used by the multiple shadows.

So ensure that adjacent subpasses stay in the same order.
2024-01-04 01:36:09 +01:00
Benjamin Otte
733f936350 gpu: Add a "transparent" sampler
This is using the equivalent of EXTEND_NONE, but I wasn't sure what to
call it.

It's unused atm.
2024-01-04 01:36:09 +01:00
Benjamin Otte
cee93a5dc8 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-04 01:36:09 +01:00
Benjamin Otte
c5dac3298f gpu: Add support for mask patterns 2024-01-04 01:36:09 +01:00
Benjamin Otte
7917b08320 gpu: Add support for cross-fades 2024-01-04 01:36:09 +01:00
Benjamin Otte
83a411890f 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-04 01:36:09 +01:00
Benjamin Otte
4473f5d439 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-04 01:36:08 +01:00
Benjamin Otte
da29dd3fbb 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-04 01:36:08 +01:00
Benjamin Otte
655dcba6ae 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-04 01:36:08 +01:00
Benjamin Otte
c459184b64 gpu: Round offscreens to pixel boundaries
Instead of strictly rounding to the given clip rectangle, increase the
rectangle to the next pixel boundary.

Also add docs that the clip_bounds do not influence the actual size of
the returned image.
2024-01-04 01:36:08 +01:00
Benjamin Otte
275aa1b549 gpu: Add GskGpuPatternWriter
It's just an object that encapsulates everything needed to create (the
data for) a pattern op.

It also clarifies which code does what, because now the NodeProcessor
and the PatternWriter are 2 different things.
2024-01-04 01:36:08 +01:00
Benjamin Otte
1fa8ce7226 gpu: Make shader image access a vfunc
That allows shaders to handle textures differently.

In particularly, it will allow the pattern shader to take a huge amount
of textures.
2024-01-04 01:36:08 +01:00
Benjamin Otte
c94f900946 gpu: Add clip pattern
So now we can clip inside an opacity node without needing fallback.
2024-01-04 01:36:08 +01:00
Benjamin Otte
41a6237799 gpu: Passthrough subsurface nodes
We don't support subsurfaces for now, so we can just ignore the nodes.
2024-01-04 01:36:08 +01:00
Benjamin Otte
5d73d7073c gpu: Add support for debug nodes
Passthrough is always easy.
2024-01-04 01:36:08 +01:00
Benjamin Otte
b06610e614 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-04 01:36:08 +01:00
Benjamin Otte
1757934582 gpu: Handle nested buffer writes
when doing get_node_as_image(), that may spawn a new buffer writer that
writes into the samme buffer when rendering an offscreen with patterns.

So as a more or less hacky workaround, we now abort the current buffer
write and restart it once we've created the image.
2024-01-04 01:36:07 +01:00
Benjamin Otte
c34b2df412 gpu: Implement conic gradients 2024-01-04 01:36:07 +01:00
Benjamin Otte
59ad96bc30 gpu: Add radial gradients 2024-01-04 01:36:07 +01:00
Benjamin Otte
248a24aa63 gpu: Add linear gradients to pattern shader
This copy/pastes the gist of the Vulkan gradient renderer.
2024-01-04 01:36:07 +01:00
Benjamin Otte
5d5e63eb1d gpu: Add glyphs support
This is very rudimentary, but it's a step in the direction of getting
text going.

There's lots of things missing still.
2024-01-04 01:36:07 +01:00
Benjamin Otte
14081c2c59 gpu: Add a utility function for colors in patterns
... and use it.
2024-01-04 01:36:07 +01:00
Benjamin Otte
3744cf5b8b gpu: Add color-matrix handling to pattern shader 2024-01-04 01:36:07 +01:00
Benjamin Otte
3ba82ab8aa gpu: Make pattern creation always succeed
If creation fails, create an offscreen image instead and draw that as a
texture.

Because offscreens basically always succeed, we can pretty much assume
success everywhere - apart from pattern creation functions that also
create images, because they can run out of shader space.
2024-01-04 01:36:07 +01:00
Benjamin Otte
4b024a8a9e gpu: Have a get_node_as_pattern() function
... and use it to replace all the individual parts of code that get the
node as a pattern.
2024-01-04 01:36:07 +01:00
Benjamin Otte
a354fadd32 gpu: Add a texture pattern
Needs a lot of infrastructure for handling images, but we're handling
images now.
2024-01-04 01:36:06 +01:00