Commit Graph

75 Commits

Author SHA1 Message Date
Benjamin Otte
2ad11e12d4 vulkan: Plug a memleak
Yay, we no longer leak swapchain images
2023-07-31 16:51:03 +02:00
Benjamin Otte
1bd820fc60 vulkan: Clean up renderpass/offscreen creation
Instead of scale and whatnot, pass:
1. The image size
2. The viewport to map to that image size
and compute everything else from there.

In particular, we set the Vulkan viewport to the image dimensions
instead of the viewport size.

All of this makes things a lot simpler while keeping the required
functionality.
2023-07-22 23:30:15 +02:00
Benjamin Otte
cd84f5a56e vulkan: Split renderpass op into 2
Add an explicit begin() and an end() op. For now, this looks like
overkill, but it allows doing renderpasses with custom ops that are not
meant to render a rendernode.

Examples for this are pre/postprocessing passes or 2-pass blur.
2023-07-19 21:30:35 +02:00
Benjamin Otte
11a0646281 vulkan: Pass rectangles where no regions are used
The API was using regions because it always had. But all the code ever
did was get the extents of the region.

So simplify everything by using rectangles everywhere.
2023-07-19 21:30:35 +02:00
Benjamin Otte
492507af11 vulkan: Stop keeping the context around
These days, we can query it with gsk_vulkan_render_get_context().

Makes quite a few functions require one less argument.
And it also makes the GskVulkanRenderPass empty. Gotta figure out what
to do with it.
2023-07-19 21:30:35 +02:00
Benjamin Otte
413d3819cf vulkan: Free storage buffer when disposing render object
This caused a lot of leaked memory on the GPU when rendering textures.
(Read: inside node-editor)
2023-07-19 21:30:35 +02:00
Benjamin Otte
e7549f3359 vulkan: Redo barriers
We now store all the relevant state of the image inside the VulkanImage
struct, so we can delay barriers for as long as possible.

Whenever we want to use an image, we call the new
gsk_vulkan_image_transition() and it will add a barrier to the desired
state if one is necessary.
2023-07-16 13:16:43 +02:00
Benjamin Otte
a8ff291a12 vulkan: Make clip type an enum
and add gsk_vulkan_shader_op_alloc() that sets it properly.
2023-07-16 13:16:43 +02:00
Benjamin Otte
f366ccc0b2 vulkan: Introduce GskVulkanShaderOp
It's the new base class for shaders now.

We're doing deep inheritance now, woohoo!

Also, port all the shader ops to it.
2023-07-16 13:16:43 +02:00
Benjamin Otte
ca69fd2b7a vulkan: Remove GskVulkanUploader
... and all the remaining functions still using it.

It's all unused and has been replaced by upload and download ops.

With this change, all GPU operations now go via GskVulkanOp.command()
and no more side channels exist.
2023-07-16 13:16:43 +02:00
Benjamin Otte
db2029d931 vulkan: Add GskVulkanDownloadOp
This op queues a download of an image. The image will only be available
once the commands finished executing, so it requires waiting for the
render to finish, which makes the API a bit awkward.

Included is also a download_png_op() useful for debugging.
2023-07-16 13:16:43 +02:00
Benjamin Otte
6f2fd001a0 vulkan: Properly update image layouts
The render pass ops were not updating the image's layout to the final
layout when a render pass ends.

Fix that.

Also make the layouts explicit arguments to the render pass op.
2023-07-16 13:16:43 +02:00
Benjamin Otte
3327a6ba08 vulkan: Simplify render API
Merge reset() and draw() into a single render() function.

Also clean up some naming on the way.
2023-07-16 13:16:43 +02:00
Benjamin Otte
4954e6962f vulkan: Remove the VulkanOp.upload() vfunc
It's not used anymore.
2023-07-16 13:16:43 +02:00
Benjamin Otte
93db1cc89e vulkan: Add an UploadGlyphOp
Now all the uploads have their own op.
2023-07-16 13:16:43 +02:00
Benjamin Otte
af817a3362 vulkan: Merge function into only caller
The renderpass reshuffling means we can move a bunch of functions now.

This is one of them.
2023-07-16 13:16:43 +02:00
Benjamin Otte
48e1d48e7f vulkan: Upload cairo images "directly"
Instead of using the upload vfunc and going via the code in
GskVulkanImage, copy/paste the relevant code into the command() vfunc.

This is meant to achieve multiple things:
1. Get rid of GskVulkanUploader and its own command buffer and general
   non-integration with operations.
2. Get rid of GskVulkanOp:upload()
3. Get the upload/download code machinery for GskVulkanImage and put it
   with the actual operations.

The current code can't do direct upload/download, that will follow in a
future commit.
2023-07-16 12:13:00 +02:00
Benjamin Otte
6f76c37fed vulkan: Emit a renderpass op
... instead of doing the equivalent things manually by creating a
RenderPass and calling the relevant functions.

Now all renderpass operations are indeed stored in ops.

Also reshuffle the command emission code, because we no longer need to
emit the ops for the base renderpass.

As a result we only submit a single command buffer containing all the
render passes instead of once per render pass.
We also bind vertex buffers and descriptor sets only once now at the
start instead of once per renderpass.
2023-07-16 12:13:00 +02:00
Benjamin Otte
cc5cab65a1 vulkan: Sort the ops
Use the OpClass.stage to order operations:

1. Put upload ops first
   This way we can ensure they are executed first.
2. Move subpasses for offscreens in front of the pass using them.
2023-07-16 12:13:00 +02:00
Benjamin Otte
f3823eff87 vulkan: Store a pointer to the first op
This is not yet useful, but will be soon.
2023-07-16 12:13:00 +02:00
Benjamin Otte
13d6e691c2 vulkan: Indent verbose prints again
This feature was lost when refactoring, restore it.
2023-07-16 12:13:00 +02:00
Benjamin Otte
2aba50efa0 vulkan: Move the render ops to the Render
This is a massive refactoring because it collects all the renderops
of all renderpasses into one long array in the Render object.

Lots of code in there is still flaky and needs cleanup. That will
follow in further commits.

Other than that it does work fine though.
2023-07-16 12:13:00 +02:00
Benjamin Otte
d7764cc6b3 vulkan: Bind descriptor sets early
Simplfies the code and doesn't change anything.
2023-07-16 12:13:00 +02:00
Benjamin Otte
a6b2bcbf24 vulkan: Remove unused arguments from Op vfuncs
Makes code a lot simpler.
2023-07-16 12:13:00 +02:00
Benjamin Otte
7fa159e94a vulkan: Cache VkRenderPasses in render object
Instead of recreating the same renderpass object in every frame and for
every offscreen, just reuse it.

Technically, we can save this per-renderer or even per-display (it
should really be cached by VkDevice), but we have no infrastructure for
that.
2023-07-16 12:13:00 +02:00
Benjamin Otte
05c9f3442c vulkan: Rename function
The function name gsk_vulkan_render_get_pipeline() had been used for
GskVulkanPipeline. Since those are gone now, we can use that name for
VkPipelines.
2023-07-16 12:13:00 +02:00
Benjamin Otte
70c9521cae vulkan: Put the vertex buffer into the render object
Renderpasses get recreated every frame, but we keep render objects
around. So if we keep the vertex buffer in the render object, we can
also keep it around and just reuse it.

Also, we only need one buffer for all the render passes, which is
another bonus.

The initial buffer size is chosen at 128kB. Maximized Nautilus,
gnome-text-editor with an open file and widget-factory take ~100kB when
doing a full redraw. Other apps are between 30-50kB usually.

So I chose a value that is not too big, but catches ~90% of cases.
2023-07-16 12:13:00 +02:00
Benjamin Otte
6363f27f95 vulkan: Don't intern strings
Interning strings is slow, especially if we can instead do direct
pointer compares.

Also refactor the pipeline lookup code a bit to make use of the
refactored code.
2023-07-16 12:13:00 +02:00
Benjamin Otte
d669e3ab6a vulkan: Remove all the semaphores
They aren't necessary with just one queue.
2023-07-16 12:13:00 +02:00
Benjamin Otte
5707551b79 vulkan: Remove unused stuff from render object
Neither cleanup images nor multiple renderpasses are used anymore since
both of those are now handled inside the render ops.
2023-07-16 12:13:00 +02:00
Benjamin Otte
a7c247bccd vulkan: Pass the node when setting up
Remove the function to add a node from both the GskVulkanRender and the
GskVulkanRenderPass.

That means they are both now meant to draw exactly one node.
2023-07-16 12:13:00 +02:00
Benjamin Otte
d86d4c5597 vulkan: Add infrastructure for printing ops
... and add a GSK_DEBUG=verbose setting making use of it.
2023-07-16 12:13:00 +02:00
Benjamin Otte
143ca0e17d vulkan: Remove GskVulkanPipeline
Pipelines are handled differently now.
2023-07-16 12:13:00 +02:00
Benjamin Otte
58c318a4dc vulkan: Add gskvulkanprivate.h
It's the new place for all the common stuff.

Because the old place is about to go away.
2023-07-16 12:13:00 +02:00
Benjamin Otte
210cb3eecd vulkan: Turn push constants into an op
This removes the last remaining original op from the gskvulkanrenderpass.c,
so that file got some cleanup, too.
2023-07-16 12:13:00 +02:00
Benjamin Otte
6e6fa3daed vulkan: Make glyphs use new node ops
This is a rudimentary - but working - port.
Glyph uploads are still using the old machinery, a bunch of functions
still exist that probably aren't necessary anymore and each glyph emits
its own node.

This will need to be improved in further commits.
2023-07-16 12:13:00 +02:00
Benjamin Otte
5e72914c48 vulkan: Port linear gradient to new ops
This was the last user of GskVulkanOpRender, so delete that one, too.
2023-07-16 12:12:36 +02:00
Benjamin Otte
f3aab662c3 vulkan: Make border shader use new ops 2023-07-16 12:12:36 +02:00
Benjamin Otte
c598fa9147 vulkan: Add a blur op and use it
This removes the last old user of offscreens, so those functions are now
gone, too.
2023-07-16 12:12:36 +02:00
Benjamin Otte
b2296a1918 vulkan: Port inset and outset shadow to new ops 2023-07-16 12:12:36 +02:00
Benjamin Otte
594595d9cd vulkan: Port blend mode to new ops 2023-07-16 12:12:36 +02:00
Benjamin Otte
9ac36aeb42 vulkan: Add cross-fade op
The benefit here is that we can now properly cross-fade when one of
start/end is fully clipped out by just replacing it with an opacity op
for the other.

This was not possible with the old way we did things.
2023-07-16 12:12:36 +02:00
Benjamin Otte
99085605a8 vulkan: Convert color op to new method
This is a straightforward and simple port.
2023-07-16 12:12:36 +02:00
Benjamin Otte
9da1055575 vulkan: Create pipeline differently for ops
Instead of creating a pipeline GObject, just ask for the VkPipeline.

And instead of having the Op handle it, just let the renderpass look
up/create the relevant pipeline while creating commands so that it can
insert vkCmdBindPipeline calls as-needed.
2023-07-16 12:12:36 +02:00
Benjamin Otte
b049990356 Revert "vulkan: Always render clip extents"
This reverts commit 0f184d3270.

The renderer is good enough to make use of the clip region.

Or rather: If it isn't, the renderpass should take care of that, not the
render object.
2023-07-16 12:12:36 +02:00
Benjamin Otte
8207c548cc vulkan: Combine textures and samplers again
This reverts most of commit f420c143e0
again because it turns out GPUs like combined images and samplers.

But: The one thing we don't revert is allowing the C code to select any
combination of sampler and image:
gsk_vulkan_render_get_image_descriptor() now takes a 2nd argument
specifying the sampler.

This allows the same flexibility as before, we just combine things
early.

This change was inspired by
https://developer.nvidia.com/blog/vulkan-dos-donts/
2023-07-16 12:12:36 +02:00
Benjamin Otte
0946b0b333 vulkan: Split out a function
Making that function externally usable allows having render passes
managed externally.

Also remove a nonexisting function from the header.
2023-07-16 12:12:36 +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
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