Commit Graph

2024 Commits

Author SHA1 Message Date
Benjamin Otte
c79ec355af gsk: Catch values < 0 before bad things happen
In particular, catch radius values being < 0 by return_if_fail()ing in
the rendernode creation code, and by erroring out in the rendernode
parser.

I try too much dumb stuff in the node editor.
2023-07-03 22:02:44 +02:00
Matthias Clasen
0ae541671d gsk: Plug a memory leak in mask node fallback
We were forgetting to free the mask pattern.
Found by asan.
2023-06-27 21:54:15 -04:00
Matthias Clasen
ef0d6c7290 gsk: Plug a memory leak in the gl renderer
Found by asan.
2023-06-27 21:52:08 -04:00
Matthias Clasen
16e46a73f3 Plug a memory leak in gsk_render_node_serialize
This was introduced in 0d6a6a5997 with named
textures.
2023-06-27 21:43:17 -04:00
Matthias Clasen
51e440fa03 Merge branch 'fix-asan-ifunc' into 'main'
Fix fp16 with asan

See merge request GNOME/gtk!6153
2023-06-27 19:55:28 +00:00
Matthias Clasen
d82fb6f20a Fix fp16 with asan
The IFUNC resolvers that we are using here get
run early, before asan had a chance to set up its
plumbing, and therefore things go badly if they
are compiled with asan. Turning it off makes things
work again.

The gcc bug tracking this problem:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110442

Thanks to Jakub Jelinek and Florian Weimer for
analyzing this and recommending the workaround.
2023-06-27 15:17:56 -04:00
Matthias Clasen
44de6a6cbe Merge branch 'wip/sadiq/fix-use-after-free' into 'main'
gldriver: Fix a possible use-after-free

See merge request GNOME/gtk!6151
2023-06-27 18:46:28 +00:00
Mohammed Sadiq
64e27cd87d gldriver: Fix a possible use-after-free
g_hash_table_insert() frees the given key if it already exists
in the hashtable.  But since we use the same pointer in the
following line, it will result in use-after-free.

So instead, insert the key only if it doesn't exist.
2023-06-27 22:45:07 +05:30
Benjamin Otte
6c85ed1ba1 vulkan: Generate vertex array headers from shaders
The script is pretty dumb but it does its job.
2023-06-27 07:11:48 +02:00
Benjamin Otte
2e58274f23 vulkan: Rename crossfade => cross-fade
Preparation for the future.
2023-06-27 06:46:57 +02:00
Benjamin Otte
4ade0afe03 vulkan: Rename blendmode to blend-mode
Preparation for future changes, nothing to see here.
2023-06-27 06:46:57 +02:00
Benjamin Otte
684a015c98 vulkan: Add a pipeline cache
Make the display handle the cache, because we only need one.

We store the cache in
  $CACHE_DIR/gtk-4.0/vulkan-pipeline-cache/$UUID.$VERSION
so we regenerate caches for each different device (different UUID) and
each different driver version.

We also keep track of the etag of the cache file, so if 2 different
applications update the cache, we can detect that.
Vulkan allows merging caches, so the 2nd app reloads the new cache file
and merges it into its cache before saving.
2023-06-26 20:28:11 +02:00
Benjamin Otte
169355f771 vulkan: Rebuild the precompiled shaders
We forgot that with all the changes.
2023-06-20 20:17:06 +02:00
Benjamin Otte
299c6a3d6f vulkan: Take offscreen fromat from context
We want to create offscreens in compatible formats, and in particular we
want to ideally use the same format as rendering would use.
2023-06-20 20:15:12 +02:00
Benjamin Otte
17698bfd2e vulkan: Use 3 descriptor sets, not 3 bindings
It turns out variable length is only supported for the last binding in
a set, not for every binding.
So we need to create one set for each of our arrays.

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004 ] Object 0: handle = 0x33a9f10, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xd3f353a | vkCreateDescriptorSetLayout(): pBindings[0] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT but 0 is the largest value of all the bindings. The Vulkan spec states: If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, then all other elements of VkDescriptorSetLayoutCreateInfo::pBindings must have a smaller value of binding (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004)
2023-06-20 20:15:12 +02:00
Benjamin Otte
377592cb62 vulkan: Use the right flags
Somebody (me) had flipped the 2 flags in commit ba28971a18:

[ VUID-vkCmdCopyBufferToImage-srcBuffer-00174 ] Object 0: handle = 0x3cfaac0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x430000000043, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xe1b276a1 | Invalid usage flag for VkBuffer 0x430000000043[] used by vkCmdCopyBufferToImage. In this case, VkBuffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT set during creation. The Vulkan spec states: srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdCopyBufferToImage-srcBuffer-00174)
2023-06-20 20:15:12 +02:00
Benjamin Otte
0a5e5023a8 vulkan: Remove unused declaration from shader 2023-06-20 20:15:12 +02:00
Benjamin Otte
aa6c670f15 vulkan: Add support for high bit depth 2023-06-19 15:08:00 +02:00
Benjamin Otte
746d0d8fde vulkan: Don't create unnecessary render passes
Pass the render pass to the pipeline creation function instead of
creating an extra one just for pipeline creation.
2023-06-19 15:08:00 +02:00
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
d61737ac7a vulkan: Add format fallback
When a GdkMemoryFormat isn't supported, pick close formats that have a
higher chance of being supported.
Make sure this works recursively and the whole loop always ends up at
R8G8B8A8_UNORM because that one is mandatory.

Roughly, follow these rules:
1. Drop the unpremultiplied
2. Expand channels to include all of RGBA
3. pick swizzle that is RGBA
4. pick next largest depth
5. pick R8G8B8A8_UNORM
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
eb3ccfb404 vulkan: Remove gsk_vulkan_image_new_for_framebuffer()
Use gsk_vulkan_image_new_for_offscreen() instead, it does the same thing
pretty much.
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
dae1e2b117 vulkan: Create the view in vulkan_image_new()
All callers want it created anyway.

Plus, we can consolidate things in future commits.
2023-06-19 15:08:00 +02:00
Benjamin Otte
63edecd857 vulkan: Make gsk_renderer_realize() work with NULL surface
Pretty much copy what GL does and just use the default display to create
GPU-related resources without the need for a display.

This also adds gdk_display_create_vulkan_context() but I've
kept it private because the Vulkan API is generally considered in flux,
in particular with our pending attempts to redo how renderers work.
2023-06-19 14:13:03 +02:00
Benjamin Otte
515e1642a4 vulkan: Actually reset the buffer size
Fixes a bug introduced in d1135f9e3c.

Luckily the buffer was large enough that all my testing didn't catch it
because it took a few minutes to overflow.
2023-06-19 14:13:03 +02:00
Benjamin Otte
177ee89b99 vulkan: Renaming fix
This rename was a long time ago...
2023-06-19 14:13:03 +02:00
Benjamin Otte
090cd2238a gdk: Replace prefers_high_depth with depth
Now that we track depth, we can also pass it into the GDK frame code.

For now it's just passed along, code acts the same as with
prefers_high_depth.
2023-06-18 14:28:39 +02:00
Benjamin Otte
8b8dfcdfb4 rendernode: Change to gsk_render_node_get_preferred_depth()
Instead of just tracking preferred_high_depth(), track the actual depth
we'd like to have.
2023-06-18 14:26:18 +02:00
Benjamin Otte
9015ed1c43 memoryformat: Add gdk_memory_format_get_depth()
Replace gdk_memory_format_prefers_high_depth with the more generic
gdk_memory_format_get_depth() that returns the depth of the individual
channels.

Also make the GL renderer use that to pick the generic F16 format
instead of immediately going for F32 when uploading textures.
2023-06-18 14:26:18 +02:00
Benjamin Otte
9836389fde vulkan: Repurpose debug flags for image uploads
Now that we don't use the old environment variables anymore to force
staging buffer/image uploads, we don't need them.

However, we do autodetect the fast path for avoiding a staging buffer
now, and we might want to be able to turn that off for testing.

So add GSK_DEBUG=staging that does exactly that.
2023-06-14 03:34:07 +02:00
Benjamin Otte
7f26f5a160 vulkan: Remove gsk_vulkan_image_new_from_data()
This is unused now that all the code uses map/unmap.

The only thing that map/unmap doesn't do that the old code did, was use
a staging image instead as alternative to a staging buffer for image
uploads.

However, that code is not necessary for anything, so I'm sure we can do
without.
2023-06-14 03:34:07 +02:00
Benjamin Otte
6a009b7182 vulkan: Add upload fastpath
If the memory heap that the GPU uses allows CPU access
(which is the case on basically every integrated GPU, including phones),
we can avoid a staging buffer and write directly into the image memory.

Check for this case and do that automatically.

Unfortunately we need to change the image format we use from
VK_IMAGE_TILING_OPTIMAL to VK_IMAGE_TILING_LINEAR, I haven't found a way
around that yet.
2023-06-14 03:34:07 +02:00
Benjamin Otte
17dd100f43 vulkan: Add gsk_vulkan_memory_can_map()
.. nd use it to assert memory is mappable when mapping it.
2023-06-14 03:34:07 +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
c27e412ff1 vulkan: Use new upload method for texture uploads
gsk_vulkan_image_new_from_texture() now uses the direct copy via
gdk_texture_downloader_download_into().
2023-06-14 03:34:07 +02:00
Benjamin Otte
0c72f19cb1 vulkan: Add a new way to upload data into images
As an alternative to gsk_vulkan_image_new_from_data() that
takes a given data and creates an image from it, add a 3 step process:
  gsk_vulkan_image_new_for_upload()
  gsk_vulkan_image_map_memory()
  /* put data into memory */
  gsk_vulkan_image_unmap_memory()

The benefit of this approach is that it potentially avoids a copy;
instead of creating a buffer to pass and writing the data into it before
then memcpy()ing it into the image, the data can be written straight
into image memory.

So far, only the staging buffer upload is implemented.

There are also no users, those come in the next commit(s).
2023-06-14 03:34:07 +02:00
Benjamin Otte
cb4e92946b vulkan: Move some code
Add gsk_vulkan_image_new_from_texture() and use it.

Also rewrite the actual code from using Cairo surfaces to using
GdkTextureDownloader.
2023-06-14 03:34:07 +02:00
Benjamin Otte
e7c86f4608 vulkan: Constify upload function 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
82ba8c848b vulkan: Handle empty rects in intersects_rect()
Apart from the none case, this was already handled, so we just check if
the rect is empty now.
2023-06-11 03:15:08 +02:00
Matthias Clasen
5f02631812 gsk: Fully free mask nodes
We were forgetting to chain up in finalize.  Oops
2023-06-09 22:40:38 -04:00
Matthias Clasen
c8133ecb50 gsk: Plug a memory leak 2023-06-09 22:40:38 -04:00
Benjamin Otte
2883f4b7a2 vulkan: Antialiasing for linear gradients
Shaders are complicated now...
2023-06-08 22:16:18 +02:00