Commit Graph

3122 Commits

Author SHA1 Message Date
Simon McVittie
214f5a6f98 gskpathop: Introduce a type to represent an aligned graphene_point_t
When we allocate a graphene_point_t on the stack, there's no guarantee
that it will be aligned at an 8-byte boundary, which is an assumption
made by gsk_pathop_encode() (which wants to use the lowest 3 bits to
encode the operation). In the places where it matters, force the
points on the stack and embedded in structs to be nicely aligned.

By using a distinct type for this (a union with a suitable size and
alignment), we ensure that the compiler will warn or error whenever we
can't prove that a particular point is, in fact, suitably aligned.
We can go from a `GskAlignedPoint *` to a `graphene_point_t *`
(which is always valid, because the `GskAlignedPoint` is aligned)
via &aligned_points[0].pt, but we cannot go back the other way
(which is not always valid, because the `graphene_point_t` is not
necessarily aligned nicely) without a cast.

In practice, it seems that a graphene_point_t on x86_64 *is* usually
placed at an 8-byte boundary, but this is not the case on 32-bit
architectures or on s390x.

In many cases we can avoid needing an explicit reference to the more
complicated type by making use of a transparent union. There's already
at least one transparent union in GSK's public API, so it's presumably
portable enough to match GTK's requirements.

Increasing the alignment of GskAlignedPoint also requires adjusting how
a GskStandardContour is allocated and initialized. This data structure
allocates extra memory to hold an array of GskAlignedPoint outside the
bounds of the struct itself, and that array now needs to be aligned
suitably. Previously the array started with at next byte after the
flexible array of gskpathop, but the alignment of a gskpathop is only
4 bytes on 32-bit architectures, so depending on the number of gskpathop
in the trailing flexible array, that pointer might be an unsuitable
location to allocate a GskAlignedPoint.

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6395
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-28 17:31:41 +01:00
Simon McVittie
660c6c8d6f gsk, testsuite: Avoid undefined behaviour in half_to_float_one()
Similar to the previous commit, to avoid undefined behaviour we need
to avoid evaluating out-of-bounds shifts, even if their result is going
to ignored by being multiplied by 0 later.

Detected by running a subset of the test suite with
-Dsanitize=address,undefined on x86_64.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-27 20:22:09 +01:00
Simon McVittie
ad679187d3 gsk, testsuite: Avoid undefined behaviour in float_to_half_one()
If, for example, e == 0, it is undefined behaviour to compute an
expression involving an out-of-range shift by (125 - e), even if the
result is in fact irrelevant because it's going to be multiplied by 0.

This was already fixed for the memorytexture test in
commit 5d1b839 "testsuite: Fix another ubsan warning", so use the
implementation from that test everywhere. It's in the header as an
inline function to keep the linking of the relevant tests simple:
its only caller in production code is fp16.c, so there will be no
duplication outside the test suite.

Detected by running a subset of the test suite with
-Dsanitize=address,undefined on x86_64.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-27 20:22:09 +01:00
Matthias Clasen
e2d337740f gpu: Don't mess up color states
When uploading textures, we were unintentionally converting to
srgb. Avoid that, so that yuv data survives unmolested.
2024-07-26 17:34:48 -04:00
Matthias Clasen
150f57f706 gpu: Fix the cicp conversion
The fragment shader was mixing up pixel and color variables.
And the compilers don't have 'uninitialized variable' warnings :(
2024-07-26 07:24:48 -04:00
Matthias Clasen
33131ad24d gpu: Fix the cicp conversion shader for ngl
The compiler was unhappy with using signed labels with an unsigned
variable in a switch. Talk about being picky.
2024-07-26 07:23:18 -04:00
Matthias Clasen
d53b3f9941 gpu: More debug spew
Print out the direction of the cicp conversion.
2024-07-26 07:22:45 -04:00
Benjamin Otte
6f9a70bd4e gpu: Add a version of a function
With the changes in !7473 we now use sampler2D arguments in functions.
However, when there's a function we call with a samplerExternalOES -
which means we need to overload it with that shader variant.
2024-07-25 18:53:55 +02:00
Benjamin Otte
de1dfb99bc gpu: Add shader name to error message
When a shader cant be compiled, we produce a long error dump, but
nowhere did we mention the actual shader.

Fix that.
2024-07-25 18:53:55 +02:00
Benjamin Otte
1f3c88b995 build: Skip vulkan parts in generated GLSL
Make the #include parsing script able to skip a predefined list of terms
with #ifdef

Put "VULKAN" in that list to skip the vulkan parts.
2024-07-25 17:32:19 +02:00
Benjamin Otte
5e7f227d92 gpu: Don't run long loops in shaders
If the border radius is too big, take bigger steps when computing the
shadow.

I randomly chose 8 because that looked good and was fast enough.
2024-07-25 17:32:19 +02:00
Matthias Clasen
d8775d0194 gsk: Make shader matrices match
We were using slightly different numbers here, which isn't good.

The matrices in gdkcolordefs.h are tested in the colorstate-internal
tests, so they are at least properly inverse, and the products match.

It would be better to generate the glsl definitions, somehow.
2024-07-24 16:45:21 -06:00
Matthias Clasen
e415ec9ca5 gsk: Use the cicp convert shader
When we the image color state is not a default one, use the cicp
convert op to convert it to the ccs. And when the target color
state is a non-default one, use the shader in the reverse direction.
2024-07-24 08:16:08 -06:00
Matthias Clasen
226652edb0 gsk: Add a cicp convert shader
This shader receives cicp parameters via uniforms, and converts
the texture data from or to the output colorstate. It computes
the matrix in the vertex shader, and then picks the eotf/oetf
according to the cicp parameters in the fragment shader.
2024-07-24 08:16:08 -06:00
Benjamin Otte
293d2fd19f gpu: Use correct shader clip mode for glyph nodes
We were passing the wrong rect to the clip mode computation, resulting
in a rounded rect every time, even though it should pretty much always
be unclipped.

The visual results are unaffected, because the clip sent to the shader
was still correct.
2024-07-23 10:03:11 +02:00
Benjamin Otte
40e25218e2 gpu: Compile with AMD's compiler, too
Apparently AMD's GLSL compiler doesn't like our #if statements. Turn
them into simple #ifdefs and compute them in the preamble instead.
2024-07-22 19:40:24 +02:00
Benjamin Otte
9e27acb0a6 gpu: Allocate Vulkan descriptor pools dynamically
Instead of allocating one large descriptor pool and hoping we never run
out of descriptors, allocate small ones dynamically, so we know we never
run out.

Test incldued, though the test doesn't fail in CI, because llvmpipe
doesn't care about pool size limits. It does fail on my AMD though.

A fun side note about that test is that the GL renderer handles it best
in normal operationbecause it caches offscreens per node and we draw the
same node repeatedly.
But, the replay test expands them to duplicated unique nodes, and then
the GL renderer runs out of command queue length, so I had to disable
the test on it.
2024-07-22 19:40:24 +02:00
Benjamin Otte
67b9fb43d0 gpu: Completely revamp YCbCr handling
There is now a GskGpuYcbcr struct that maintains all the Vulkan
machinery related to YCbCrConversions.
It's a GskGpuCached, so it will make itself go away when it is no longer
used, ie a video stopped playing.
2024-07-22 19:40:24 +02:00
Benjamin Otte
762b981dfe gpu: Make the device queryable from the cache
That's needed in cached subclasses during destruction, when they want to
destroy system resources.
2024-07-22 19:40:24 +02:00
Benjamin Otte
5e027ae5d9 gpu: Allow creating GskGpuCached objects externally
Export the GskGpuCached and GskGpuCachedClass objects in the header, and
make gsk_gpu_cached_new() available.
2024-07-22 19:40:24 +02:00
Benjamin Otte
7dd3680d7d gpu: Refactor code a bit
Turn the 2 ways to construct cached items into 2 constructors.

Useful for next commit.
2024-07-22 19:40:24 +02:00
Benjamin Otte
14a7b4b4b4 vulkan: Remove unused features
Now that we don't use the fancy features anymore, we don't need to
enable them.
And that also means we don't need an env var to disable it for testing.
2024-07-22 19:40:24 +02:00
Benjamin Otte
f5096fd11a vulkan: No need for different shaders anymore
Now that we don't do fancy texture stuff anymore, we don't need fancy
shaders either, so we can just compile against Vulkan 1.0 again.

And that means we need no fallback shaders for Vulkan 1.0 anymore.
2024-07-22 19:40:24 +02:00
Benjamin Otte
9c5ac13301 gpu: Remove now unused variables
No need to track them anymore.
2024-07-22 19:40:24 +02:00
Benjamin Otte
ecc33d6e62 gpu: Add the same cache as the GL shader uses
This avoids unnecessary rebinds of textures.

I can't really measure a performance change with it though.
2024-07-22 19:40:24 +02:00
Benjamin Otte
03c34021af gpu: Completely revamp descriptor set handling
Instead of trying to cram all descriptors into one large array and only
binding it at the start, we now keep 1 descriptor set per image+sampler
combo and just rebind it every time we switch textures.

This is the very dumb solution that essentially maps to what GL does,
but the performance impact is negligible compared to the complicated
dance we were attempting before.
2024-07-22 19:40:24 +02:00
Benjamin Otte
1b2156493b gpu: Remove descriptors
They are no longer a thing with the new way we manage textures.
2024-07-22 19:40:24 +02:00
Benjamin Otte
7b76170f46 gpu: Flip the big switch
Rewrite all shaders to use 2 predefined samplers called GSK_TEXTURE0 and
GSK_TEXTURE1 instead of wrapper functions.

On GL and Vulkan compat mode, these map directly to samplers.
On Vulkan proper, they map to 2 indices into the texture array, like
before.

From now on, the old nvidia GPUs - ie the 3xx drivers - should start
working again.

Fixes: #6564
Fixes: #6574
Fixes: #6654
2024-07-22 19:40:14 +02:00
Benjamin Otte
8109e8e3b6 gpu: Add GskGpuShaderFlags
This is just blowing up GskGpuShaderClip to hold more information so
that we don't need even more specialization constants.
2024-07-22 18:37:07 +02:00
Benjamin Otte
163278af0d gpu: Add infrastructure to write texture vertex data
This allows GskGpuFrame implementations to store data per vertex
attribute.

This is just the plumbing, no actual implementation is done in this
commit.
2024-07-22 18:37:07 +02:00
Benjamin Otte
677b6c1a81 gpu: Force new descriptors every time
This guarantees that the images get ID 0 and 1 (on GL), which is going
to be quite important for the next steps.

Just for funsies, here's fps numbers on my desktop for this change:
NGL     1500 => 1400
Vulkan  2650 => 2250
2024-07-22 18:37:07 +02:00
Benjamin Otte
1331a10e88 gpu: Remove buffer handling
We don't use buffers atm, and if we want to bring them back later, we
can just look at reverting this commit.

And it's in the way while refactoring.
2024-07-22 18:37:07 +02:00
Benjamin Otte
dc9f0869b1 gpu: Pass used images to shader ops
This by itself is just more work refcounting all those images, but
there's actually a goal here, that will become visible in future
commits.

But this is split out for correctness and benchmarking purposes (the
overhead from refcounting seems to be negligible on my computer).
2024-07-22 18:37:07 +02:00
Benjamin Otte
ea6253c1df gpu: Add a member in ShaderOpClass for number of textures
This just puts the number from the header into a strcut where it can be
accessed.
2024-07-22 18:37:07 +02:00
Benjamin Otte
b481fd854f gpu: Encode number of textures use in every shader
Just define GSK_N_TEXTURES in every glsl file, extract that #define in
the python parser and emit a static const uint variable
"{shader_name}_n_textures" in the generated header.
2024-07-22 18:37:07 +02:00
Benjamin Otte
68baa93460 gpu: Use GskGpuShaderImage for blur ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
52db54e803 gpu: Use GskGpuShaderImage for crossfade ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
71e412e8f8 gpu: Use GskGpuShaderImage for convert ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
9644fc2e8f gpu: Use GskGpuShaderImage for mask ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
0795d86df7 gpu: Use GskGpuShaderImage for colormatrix ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
21988ea700 gpu: Use GskGpuShaderImage for blendmode ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
23081d2bc4 gpu: Use GskGpuShaderImage for texture ops 2024-07-22 18:37:07 +02:00
Benjamin Otte
b1e441d18a gpu: Introduce GskGpuShaderImage
It's a struct collecting all relevant info for a texture passed to a
shader.

The ultimate goal is to get rid of the descriptors and let ops
manage them on thir own.
2024-07-22 18:37:07 +02:00
Benjamin Otte
4639b3bc4c gpu: Make cache keep track of time
If GskGpuCache has an idea of what time it is, cached items can use that
time to update their last-use time instead of having to carry it around
throught function calls everywhere.
2024-07-22 17:10:37 +02:00
Benjamin Otte
821eb92dfb gpu: Handle corner-case
Port an optimization of the GL renderer where it fast-paths crossfades
with progress <= 0 and >=1 - which should really never happen because
nobody should emit them in the first place, but oh well.
2024-07-22 17:10:37 +02:00
Benjamin Otte
0370043775 gpu: Add missing string
This made debug output kinda not so good.
2024-07-22 17:10:37 +02:00
Benjamin Otte
82bcc05ca1 gpu: Move code around
Move the atlas code to the top of the file, so that other code can use
it.

No functional changes.
2024-07-22 17:10:37 +02:00
Benjamin Otte
c1e008fa86 gpu: Improve cache stats printing
We no longer hardcode the few different classes we have, but generically
walk over all classes.

As a side effect we now get new classes added to stats automatically.

The content itself did not change.
2024-07-22 02:03:00 +02:00
Benjamin Otte
c47a3c54fd vulkan: Make images track the device
Now that the cache is a separate object, there are no longer cyclic
uncollectable references, so images can use the device like everyone
else.
2024-07-22 01:28:40 +02:00
Benjamin Otte
3bc1e0534f gpu: Clean up headers
After the device/cache split, this was forgotten.
2024-07-22 01:28:40 +02:00