Commit Graph

78644 Commits

Author SHA1 Message Date
Benjamin Otte
1923cad9f7 gpu: Add Vulkan feature flags for more advanced features
Code continues if those features aren't available, buit is probably
broken.
2024-01-04 14:54:20 +01:00
Benjamin Otte
9349ba8330 gpu: Update shader code for different buffer/sampler sizes
Use specialization constants for that.
2024-01-04 14:54:20 +01:00
Benjamin Otte
0c72233a9d gpu: Make PipelineLayout objects do more things
Let the objects track the number of samplers or buffers needed.

This is a required step for making Vulkan work with less featureful
(read: mobile) implementations.
2024-01-04 14:54:20 +01:00
Benjamin Otte
9733b8d4e1 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-04 14:54:20 +01:00
Benjamin Otte
4d9ff5e46a gpu: Add support for dmabuf import to GL 2024-01-04 14:54:19 +01:00
Benjamin Otte
9cf776d02e 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-04 14:54:19 +01:00
Benjamin Otte
55dbbabd0c gpu: Add importing of GL textures to the GL renderer
syncing with the GLsync is kind of a hack (because we just do it on
import), but it works.
2024-01-04 14:54:19 +01:00
Benjamin Otte
46baaa9337 gpu: Add support for texture-scale nodes
This adds GSK_GPU_IMAGE_CAN_MIPMAP and GSK_GPU_IMAGE_MIPMAP flags and
support to ensure_image() and image creation functions for creating a
mipmapped image.

Mipmaps are created using the new mipmap op that uses
glGenerateMipmap() on GL and equivalent blit ops on Vulkan.

This is then used to ensure the image is mipmapped when rendering it
with a texture-scale node.
2024-01-04 14:54:19 +01:00
Benjamin Otte
697f2b8e95 gpu: Add blitting support
Add GSK_GPU_IMAGE_NO_BLIT flag for textures that can't be blitted from.

Use a blit op to do image copies otherwise.
2024-01-04 14:54:19 +01:00
Benjamin Otte
9af809a7ff testsuite: Add a test to check scaling behavior
Various GL texture formats do not support linear scaling or mipmap
generation.

Add a test that checks this.
2024-01-04 14:54:19 +01:00
Benjamin Otte
2e25936383 testsuite: Update memorytexture text to use new renderers
1. Refactor checks for GL support

2. Add NGL and Vulkan
2024-01-04 01:36:13 +01:00
Benjamin Otte
7652dbcacf 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-04 01:36:13 +01:00
Benjamin Otte
8df8e1283f 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-04 01:36:13 +01:00
Benjamin Otte
2199822d5f gpu: Add dmabuf import for Vulkan
This now uses all the previously added features to allow displaying YUV
images.

Also add a utility function that turns an image into a toggle ref for a
texture. This makes sure that reffing the image also refs the texture
and that ensures that textures stay alive as long as the image is in
use.
2024-01-04 01:36:13 +01:00
Benjamin Otte
16a3a04405 vulkan: Add support for enumerating dmabuf formats
This code does not add a downloader, so we do not claim support for all
the new formats.

It just queries the formats. But this can be used to import dmabufs
directly into the Vulkaan renderer.
2024-01-04 01:36:13 +01:00
Benjamin Otte
f21938cae6 gpu: Handle flags for images
For now, the flags are just there because, and nobody uses them yet.
The only flag is EXTERNAL, which for now I'm using for YUV buffers,
though it's a bit undefined what that means.
2024-01-04 01:36:12 +01:00
Benjamin Otte
2cb06f212b gpu: Add a mipmap sampler
It's not used yet, but the sampler infrastructure needs to be expanded,
so I decided to split this out to easier find regressions.
2024-01-04 01:36:12 +01:00
Benjamin Otte
18e39f86b6 gpu: Add support for immutable samplers to Vulkan
Images can now have samplers - meaning they must be rendered with that
sampler. It also means that sampler must be handled as an immutable
sampler in descriptorsets.
These samplers can be created with a samplerYcbcrConversion, so code has
been added to pass that conversion when creating the imageview.

Also add code to GskVulkanFrame to track immutable samplers.

Nobody is making use of this yet.
2024-01-04 01:36:12 +01:00
Benjamin Otte
f13f70a448 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-04 01:36:12 +01:00
Benjamin Otte
faf24c4bfe 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-04 01:36:12 +01:00
Benjamin Otte
894db4d96e gpu: Add a cache for YcbcrConversions
We index them only by VkFormat for now because we don't have another
differentiator.

It's unused so far.
2024-01-04 01:36:12 +01:00
Benjamin Otte
d6593f3a3b gpu: Add an "external" allocator to Vulkan
The allocator is supposed to be used with externally allocated vkMemory
objects that are meant to be freed normally - in particular dmabufs.
2024-01-04 01:36:12 +01:00
Benjamin Otte
3f42d92eaf gpu: Add GdkDisplay::vulkan_features
use it to collect the optional features we are interested in and turn
them on only if available.

For now we add the dmabuf features, but we don't use them yet.
2024-01-04 01:36:12 +01:00
Benjamin Otte
33d531b417 gpu: Create Vulkan samplers on-demand 2024-01-04 01:36:12 +01:00
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