Commit Graph

144 Commits

Author SHA1 Message Date
Benjamin Otte
35b09c727a vulkan: Put the framebuffer in the renderpass
... instead of having fancy caching.

That caching is complicated and it's not necessary.
2023-06-19 15:08:00 +02:00
Benjamin Otte
c35f491795 vulkan: Store the VkFormat in GskVulkanImage
... and use that info when creating renderpasses.
2023-06-19 15:08:00 +02:00
Benjamin Otte
5b64ca7e0a vulkan: Pick high depth texture for high depth nodes
If a node has a higher depth, pick the RGBA format that has that depth
as the texture format we're renderig to with render_texture().

Support for adapting the swapchain is not part of this.
2023-06-19 15:08:00 +02:00
Benjamin Otte
ba28971a18 vulkan: Allow mapping images as "read" and/or "write"
This way, we unify the code paths for memory access to textures.

We also technically gain the ability to modify images, though I have no
use case for this.
2023-06-19 15:08:00 +02:00
Benjamin Otte
7b4846bc25 vulkan: Pass format to offscreen creation function
That way, the offscreen can create images of different types.

Its not used in this commit, but will come in handy when we want to
support high bit depth.
2023-06-19 15:08:00 +02:00
Benjamin Otte
e4c37ceb34 vulkan: Allow uploading in different formats
This requires quite some code because Vulkan may not support all the
formats and then we need to detect that and fallback properly.
2023-06-19 15:08:00 +02:00
Benjamin Otte
49c2c2da1a vulkan: Use map/unmap for fallback images 2023-06-14 03:34:07 +02:00
Benjamin Otte
f88b1cef21 vulkan: Render fallback into vulkan memory
Use the new map/unmap image upload method for Cairo node drawing:
1. map() the memory
2. create an image surface or that memory
3. draw to that image surface
4. success

There's no longer a need for Cairo to allocate image memory.
2023-06-14 03:34:07 +02:00
Benjamin Otte
9df935591c vulkan: Handle new nodes being added correctly
When nodes are added, nothing was warning us that we need to bump
N_RENDER_NODES.

Make sure that that's no longer necessary by refactoring the code to
remove the define.
2023-06-11 03:54:50 +02:00
Benjamin Otte
1f8045ddbe vulkan: Do intersection check for every node
This is more expensive, but it finds more cases, and in particular it
catches corner cases like empty nodes or fully clipped nodes that might
otherwise make the kernel throw signals in our direction.
2023-06-11 03:54:50 +02:00
Benjamin Otte
e3cc3f7841 vulkan: Make gradient shader use buffers
This allows putting any number of color stops into the buffer, so
fallbacks with too many stops are no longer necessary.
2023-06-08 21:53:06 +02:00
Benjamin Otte
f1b1aacc34 vulkan: Stop differentiating rounded from cicular corners
Our shaders can handle both, so don'ttry to tell them apart anymore.

Removes a lot of unnecessary fallbacks.
2023-06-04 19:42:01 +02:00
Benjamin Otte
e7201968d6 vulkan: Cleanup: Initialize constants at the top 2023-06-04 19:42:01 +02:00
Benjamin Otte
67f2ad817e vulkan: Add support for texture-scale nodes 2023-06-04 19:42:01 +02:00
Benjamin Otte
f420c143e0 vulkan: Split textures and samplers
The idea here is that we can do more complex combinations and use that
to support texture-scale nodes or use fancy texture formats (suc as
YUV).

I'm not sure this is actually necessary, but for now it gives more
flexibility.
2023-06-04 19:42:01 +02:00
Benjamin Otte
1cf6dfab2f vulkan: Add a hackish way to handle empty children
For blend and crossfade nodes, one of the children may exist and
influence the rendering, while the other does not.

Previously, we would skip the node, which would cause the required
rendering to not happen. We now send a valid texture id for the
invalid offscreen, thereby actually rendering the required parts.

Fixes the blend-invisible-child compare test

Current state for compare tests:
Ok:                 397
Expected Fail:      0
Fail:               26
Unexpected Pass:    0
Skipped:            2
Timeout:            0
2023-06-04 19:42:01 +02:00
Benjamin Otte
330a8b1cdb vulkan: Convert blend shader
Same work as crossfade shader pretty much.
2023-06-04 19:42:01 +02:00
Benjamin Otte
8d19db6732 vulkan: Update the cross-fade shader
This also fixes it rendering weird things when the bounds of start and
end node don't match.
2023-06-04 19:42:01 +02:00
Benjamin Otte
0f1b039306 vulkan: Implement bindless texture rendering
Instead of having a descriptor set per operation, we just have one
descriptor set and bind all our images into it.

Then the shaders get to use an index into the large texture array
instead.

Getting this to work - because it's a Vulkan extension that needs to be
manually enabled, even though it's officially part of Vulkan 1.2 - is
insane.
2023-06-04 19:42:01 +02:00
Benjamin Otte
b791aa0301 vulkan: Clip using scissors
If we have a rectangular clip without transforms, we can use
scissoring. This works particularly well because it allows intersecting
rounded rectangles with regular rectangles in all cases:
Use the scissor rect for the rectangle and the normal clipping code for
the rounded rectangle.
2023-06-04 19:42:01 +02:00
Benjamin Otte
7fd94c1828 vulkan: Make scissoring an explicit operation
The idea is to use it for clip nodes when they are integer-aligned.

To do that, we need to track the scissor rect in the parse state, so we
do that, too.

Also move the viewport offset out of the projection matrix, as it is
part of the transform between clip and scissor, so it needs to live in
the offset.
2023-06-04 19:42:01 +02:00
Benjamin Otte
dd4c1167b2 vulkan: Remove unneeded struct member
We can use gsk_vulkan_pipeline_get_vertex_stride() whenever we need that
value.
2023-06-04 19:42:01 +02:00
Benjamin Otte
d411912396 vulkan: Bind vertex buffers only once
We can index into the same buffer from every pipeline due to the aligned
buffer writes (see previous commit).

So we do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte
0e93ad8671 vulkan: Align vertex data
We align the data to a multiple of vertex stride, that way we use more
memory, but we could compute an offset into the vertex buffer without
changing the offset.
2023-06-04 19:42:01 +02:00
Benjamin Otte
d98991a0ad vulkan: Set offsets when counting
We can set the vertex offset while counting the data, this gets rid of
the need of passing all the counting machinery into the actual data
collection code.
2023-06-04 19:42:01 +02:00
Benjamin Otte
1f7dcc1286 vulkan: Simplify switch statement
All branches do the same thing now, so pull them all into the same
branch.
2023-06-04 19:42:01 +02:00
Benjamin Otte
328cdf7b2a vulkan: Simplify collect_vertex_data()
We don't have any size arguments to it, so don't use them.
2023-06-04 19:42:01 +02:00
Benjamin Otte
79a227bc64 vulkan: Remove a function from pipeline impls
That function is available already in the structs we feed to Vulkan.

Store it from there and reuse it.
2023-06-04 19:42:01 +02:00
Benjamin Otte
0fee26252c vulkan: Don't draw fully clipped nodes
... if they are container nodes. Other nodes will get culled by the
vertex shader.
2023-06-04 19:42:01 +02:00
Benjamin Otte
d48b6b9ad5 vulkan: Add optimization for transforms
When attempting a complex transform, check if the clip can be ignored
and do that if possible.

That way we don't cause fallbacks when transforming the clip is too
complex.
2023-06-04 19:42:01 +02:00
Benjamin Otte
d4618ea8a6 vulkan: Don't crash with overly large nodes
... when these nodes are used as children of a complex transform nodes
and we lose the clip.
2023-06-04 19:42:01 +02:00
Benjamin Otte
7f5504bea4 vulkan: Set the initial clip rect
Instead of rendering unclipped, set the clip region to the extents of
the current clip region.
2023-06-04 19:42:01 +02:00
Benjamin Otte
4b2b239550 vulkan: Only draw one rect
Instead of emitting the render commands once per rectangle of the clip
region, just emit them once with the region's extents.

This is generally faster because it emits fewer commands to the GPU,
even though it may touch significantly more pixels.

For a proper method, we'd need to record the commands per clip rectangle
instead of emitting all of them all the time.
2023-06-04 19:42:01 +02:00
Benjamin Otte
52eefdb7d9 vulkan: Only use a single pipeline layout
There's no need to use 3 different ones when they are compatible.
2023-06-04 19:42:01 +02:00
Benjamin Otte
8561ff37c4 vulkan: Use scale factor for offscreens and fallbacks
Previously, we just used the defaultscale factor, but now that we're
having it available in push constants, we can read it back for creating
offscreens and rendering fallbacks.

So do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte
a09580b9ef vulkan: Split scale from matrix
Now, the scale is no longer part of the matrix. This allows shaders to
transform points by the scale which increases accuracy for antialiasing.
2023-06-04 19:42:01 +02:00
Benjamin Otte
0511227379 vulkan: Keep the modelview as a GskTransform
This allows doing more optimized math on it.
2023-06-04 19:42:01 +02:00
Benjamin Otte
4183ce0b52 vulkan: Split modelview and projection
This is adding extra work, but the benefits should become visible
in future commits.
2023-06-04 19:42:01 +02:00
Benjamin Otte
57222cc64c vulkan: Add scale to push constants
This way, it can be pushed to the shaders
2023-06-04 19:42:01 +02:00
Benjamin Otte
b3c1284382 vulkan: Move scale into the state object 2023-06-04 19:42:01 +02:00
Benjamin Otte
b02e054592 vulkan: Add offset to the Vulkan clip checks
This was forgotten when tracking the offset was added, so code was
actually selecting the wrong shaders.
2023-06-04 19:42:01 +02:00
Benjamin Otte
870ee06d1f vulkan: Move offset into the state object 2023-06-04 19:42:01 +02:00
Benjamin Otte
8d586be693 vulkan: Add a new GskVulkanParseState
It's a 1:1 replacement for GskVulkanPushConstants, just without the
indirection through a different file.

GskVulkanPushConstants as a struct is gone now.
The file still exists to handle the push_constants operation.
2023-06-04 19:42:01 +02:00
Benjamin Otte
94ab11b999 vulkan: Don't store push constants in RenderOp
Instead, only store the values that are needed.
2023-06-04 19:42:01 +02:00
Benjamin Otte
9b1dcd3872 vulkan: Split out gsk_vulkan_render_pass_append_push_constants()
Simplifies the code and makes future refactoring easier
2023-06-04 19:42:01 +02:00
Benjamin Otte
c37171f4d6 vulkan: Pass values to push directly
Don't require a GskVulkanPushConstants there.
2023-06-04 19:42:01 +02:00
Benjamin Otte
186e056c56 vulkan: Handle clip properly for offscreens
This was broken in the last commit.
2023-06-04 19:42:01 +02:00
Benjamin Otte
d8b9c3ae96 vulkan: Track offset in the renderpass
This avoids emitting lots of push constant updates as most of the
transforms we have are simple translations to adjust drawing for the
next widget.
2023-06-04 19:42:01 +02:00
Benjamin Otte
5de6f12e88 vulkan: Pass scale to offscreens
Create offscreens with enough pixels for the given scale and ensure
the scale is passed on.

This improves text rendering on offscreens quite a bit.
2023-06-04 19:42:01 +02:00
Benjamin Otte
5422c12577 vulkan: Clean up scale handling
1. Use a graphene_vec2_t
2. Ensure it's always positive
3. Don't break with fallback

The scale value is nothing more than an indication of how many pixels to
assume per unit of a node.
2023-06-04 19:42:01 +02:00
Benjamin Otte
bb145b9bc1 vulkan: Fix typo 2023-06-04 19:42:01 +02:00
Benjamin Otte
a55fda0b49 vulkan: Don't store unused matrices
We can compute it when needed, so do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte
5b93a32f90 vulkan: Remove unneeded argument
The initial matrix can be computed as needed, so we don't need to
precompute it.
2023-06-04 19:42:01 +02:00
Benjamin Otte
495ee1be3d vulkan: Don't explode without vertex data
If no buffer has any vertex data (read: if nothing gets drawn), don't
try to allocate a 0 bytes buffer.
2023-06-04 19:42:01 +02:00
Benjamin Otte
7f1bd1f047 vulkan: Handle empty child bounds in repeat node
Also add test to the testsuite for it.
2023-06-04 19:42:01 +02:00
Benjamin Otte
da147dca92 vulkan: Fix repeat nodes 2023-06-04 19:42:01 +02:00
Benjamin Otte
8ba5ff98aa vulkan: Don't transform the viewport rect
We don't want to render the offscreen trnsformed, we want to render it
as-is.

We lose the correct scale factor, but that requires some separate work,
so for now it gets a bit blurry on hidpi.
2023-06-04 19:42:01 +02:00
Benjamin Otte
34f4493c36 vulkan: Make quarks global variables
I don't want to ensure there's a RenderPass available everywhere and
recreate the quarks in each, I just want to use them.
2023-06-04 19:42:01 +02:00
Benjamin Otte
314923d4b5 vulkan: Split out a function
We can now create offscreens explicitly.
2023-06-04 19:42:00 +02:00
Benjamin Otte
d2f45dae96 vulkan: offscreens are used as color attachments
... so set the corresponding flag.

Also name the function "new_for_offscreen()" because thats what this
function is about, "texture" is ambiguous.
2023-06-04 19:42:00 +02:00
Benjamin Otte
0e31cf9542 vulkan: compute new modelview directly
no need to go through a GskTransform
2023-06-04 19:42:00 +02:00
Benjamin Otte
2b0ad09423 vulkan: Make projection matrix match GL
Vulkan has a different initial coordinate system to GL.

GL:
(-1, 1, -1) +------+.
            |`.    | `.
            |  `·--|---·
            |   :  |   :
            +------+.  :
             `. :    `.:
               `·------· (1, -1, 1)

Vulkan:
(-1, -1, 0) +------+.
            |`.    | `.
            |  `·--|---·
            |   :  |   :
            +------+.  :
             `. :    `.:
               `·------· (1, 1, 1)

so adjust the near and far plane we pass to
graphene_matrix_init_ortho() to make it end up with the same
projection as the GL renderer.
2023-05-16 18:53:27 +02:00
Benjamin Otte
f99ecd3739 vulkan: Compute offscreen texture coords properly
Most of the time we want to compute them based on the child node we
render to the offscreen, but not always.
For blend and cross-fade nodes, they need to be computed based on the
node's bounds.

Fixes widget-factory page fade animation weirdly resizing the fading
pages.
2023-05-02 19:44:06 +02:00
Georges Basile Stavracas Neto
db1d278100 gsk/vulkan/renderpass: Don't scale scissor and render area
The rects passed to the clip region are in buffer coordinates, and
must not be scaled. Consider the following scenario: Wayland, with
a 1024x768@2 window. That gives us a 2048x1536 raw image. To setup
the Vulkan render pass code, we'd scale 2048x1536 *again*, to an
unreasonable 4196x3072, which is (1) incorrect and (2) really
incorrect and (3) can lead to crashes at best, full GPU resets
at worst - and a GPU reset is incredibly not fun!

Now that we pass the right clip regions at the right coordinates
at all times, remove the extra scaling from the render pass.
2023-04-03 10:59:45 -03:00
Georges Basile Stavracas Neto
ee1730dd49 gsk/vulkan/renderpass: Update scales from transform node
Retrieve the scale from the transform node, and store it as long
as the transform node is being visited. This applies the proper
scale to text nodes.
2023-04-01 14:47:29 -03:00
Georges Basile Stavracas Neto
e0aaf9bc83 gsk/vulkan/renderpass: Refactor scale
Instead of tracking a single scale, track x and y scales separately.
Factor out gsk_vulkan_render_pass_new() into a private function that
receives both scales, and pass 'scale_factor' for both.
2023-04-01 14:46:56 -03:00
Georges Basile Stavracas Neto
b1a8c0e686 gsk/vulkan/renderpass: Factor out node implementations
This is mostly a cosmetic change, and the goal is twofold:

 1. Make it easier to spot unimplemented render node types; and
 2. Prepare for a small rework

The implementation for each node now lives in specific functions,
like the GL renderer; unlike the GL renderer, however, we use a
node type vtable to map GskRenderNodeType → implementation. Render
node without an implementation map to NULL, and use the fallback
implementation. Render nodes that fail any check and return FALSE
also use fallback implementation.
2023-03-31 14:00:33 -03:00
Matthias Clasen
9f88dba162 gsk: Stop using g_slice 2023-03-14 14:56:42 -04:00
Matthias Clasen
0d58e5365d gsk: Introduce mask nodes
Add GskMaskNode, and support it in the render node
parser, in the inspector and in GtkSnapshot.

The rendering is just fallback for now.

Based on old work by Timm Bäder.
2023-02-12 08:35:25 -05:00
Matthias Clasen
b937c19dd4 gsk: Introduce GskTextureScaleNode 2023-02-11 15:09:38 -05:00
Matthias Clasen
9818ec4ad9 gsk: Use the new debug macros 2022-09-23 18:11:48 -04:00
TestingPlant
1c587c7d7f vulkan: Set initial layout to undefined
Having the initial layout set to VK_IMAGE_LAYOUT_GENERAL causes issues
when going from the final layout to the initial layout since the image
layout is expected to be the general layout. Setting the initial layout
to undefined doesn't have this restriction.
2022-05-08 05:39:36 +00:00
Benjamin Otte
91932ada63 vulkan: Handle simple transforms in the clipping code
Requires pushing the GskTransform into the clipping code so that we
can actually look at its category.
2021-03-05 19:36:36 -05:00
Matthias Clasen
dbb264dfc9 vulkan: Add visible fallback rendering
Hook up the "Show fallback rendering" switch for Vulkan.

This brings home the sobering truth that the Vulkan renderer
is doing *all* fallback, since we switched from offset nodes
to transform nodes.
2021-03-05 18:42:04 -05:00
Benjamin Otte
55a242bd81 gsk: Add GskConicGradientNode 2020-12-03 00:47:54 +01:00
Benjamin Otte
f2284ff40f rendernode: Rename all gsk_render_node_peek_*() functions
Those are getters, they should be gsk_render_node_get_*() functions.
2020-11-17 19:04:39 +01:00
Timm Bäder
f456438051 vulkan: Remove double initialization
Clang said:

../gsk/vulkan/gskvulkanrenderpass.c:250:5: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
    .render.node = node
    ^~~~~~~~~~~~~~~~~~~
../gsk/vulkan/gskvulkanrenderpass.c:249:13: note: previous initialization is here
    .type = GSK_VULKAN_OP_FALLBACK,
            ^~~~~~~~~~~~~~~~~~~~~~
2020-10-14 15:06:12 -04:00
Alexander Larsson
4d697283ae Support GLShaderNode in backends
For vulkan/broadway this just means to ignore it, but for the gl
backend we support (with up to 4 texture inputs, which is similar to
what shadertoy does, so should be widely supported).
2020-09-29 09:51:16 +02:00
Matthias Clasen
0c6226c20b gsk: Add a radial gradient node
Only a fallback implementation for now.

Fixes #2262
2020-09-18 15:38:55 +02:00
Benjamin Otte
d7266b25ba Replace "gint" with "int" 2020-07-25 00:47:36 +02:00
Emmanuele Bassi
d701a89281 Turn GskRenderNode into a derivable type
Language bindings—especially ones based on introspection—cannot deal
with custom type hiearchies. Luckily for us, GType has a derivable type
with low overhead: GTypeInstance.

By turning GskRenderNode into a GTypeInstance, and creating derived
types for each class of node, we can provide an introspectable API to
our non-C API consumers, with no functional change to the C API itself.
2020-04-08 15:40:15 +01:00
Matthias Clasen
e296c6a356 gsk: Store color bit info in text nodes
Keep the 'has color glyphs' info in text nodes,
instead of determining it over and over in both
the vulkan and gl backends.
2019-10-11 16:15:14 -04:00
Georges Basile Stavracas Neto
a2b49322fb vulkan/renderpass: Use GENERAL for initial layout
UNDEFINED initial layouts may not preserve the contents
of the attachment after transitioning the layout. We want
them to be preserved because we do partial rendering.

Use GENERAL as the initial layout for render passes.
2019-10-05 12:13:22 -03:00
Matthias Clasen
5c9643b6eb vulkan: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
2019-07-28 16:42:52 -04:00
Benjamin Otte
a1d08b4b52 rendernode: Take a graphene_point_t for the offset
... instead of 2 floats.
2019-05-21 06:43:59 +02:00
Benjamin Otte
3a3c2d14ab rendernode: Make the transform node take a GskTransform
This is an attempt to push GskTransform deeper into the stack.
2019-03-04 23:15:07 +01:00
Benjamin Otte
6a4bf2b993 gsk: Remove offset nodes
They were a neat idea while they lasted. But now, it's time for
categorized transform nodes, where matrices with
GSK_MATRIX_CATEGORY_2D_TRANSLATE are the exact replacement.

Renderers have not been adapted for this purpose, so they (continue to)
run slow paths.
2019-02-21 19:47:28 +01:00
Benjamin Otte
359bc7695c build: Reintroduce warning flags from autotools
Some of the flags got lost in the meson transition or were demoted from
error flags to warning flags.
This commit reintroduces them.

It also includes fixes for the code that had warnings with those flags.
The big one being -Wshadow.
2019-01-22 04:33:12 +01:00
Benjamin Otte
b49dccb86d rendernode: Remove gsk_render_node_set_name()
And of course, gsk_render_node_get_name() is gone, too.
The replacement is of course debug nodes.

As a side effect, GskRenderNode is now *really* immutable.
2018-04-24 04:06:58 +02:00
Benjamin Otte
49f9d2108d gsk: Add GskDebugNode 2018-04-24 04:06:58 +02:00
Benjamin Otte
ce743f28a1 rendernode: Add an offset node
This is a special case of the transform node that does a 2D translation.

The implementation in the Vulkan and GL renderers is crude and just does
the same as the transform node.

Nothing uses that node yet.
2018-03-26 18:16:36 +02:00
Benjamin Otte
f680d5d130 vulkan: Remove special case for Cairo surfaces
This is in preparation for the next commits which switch Cairo nodes to
recording surfaces.
2018-03-24 21:57:20 +01:00
Matthias Clasen
c56419818f gsk: make logging per-renderer
Add a setter for per-renderer debug flags, and use
them where possible. Some places don't have easy access
to a renderer, so this is not complete.
Also, use g_message instead of g_print throughout.
2018-01-14 17:05:04 -05:00
Matthias Clasen
3771c95c72 gsk: Move Vulkan sources to a subdirectory
Following what was already done for GL.
2018-01-06 09:36:55 -05:00