vulkan: Make RenderOps into proper structs
This MR introduces GskVulkanOp
as its own struct that describes an operation performed on the GPU.
It promotes the previous private struct of the GskVulkanRenderPass
into its own class-based object (like GtkCssValue
) and generalizes it, so it can take over all functionality that performs operations on the GPU. Everything apart from allocation, especially every vkCmd*()
now goes through ops. It replaces:
-
GskVulkanPipeline
objects - each shader is now invoked via a custom op. -
GskVulkanUploader
- that previous side channel used for uploads is now integrated via upload ops -
gsk_vulkan_image_download()
- a download op replaces this -
GskVulkanGlyphCache
now uploads its glyphs via upload ops - offscreens are managed via renderpass ops that begin/end renderpasses
Ops are now all part of the same list. This list gets simply appended to when parsing the rendernode tree. Once all ops have been recorded, the ops are reordered so that uploads happen first, then offscreens and the main image gets drawn last. This way, sources for later operations are created as early as possible. It is possible to get output about this by using the new GSK_DEBUG=verbose
which will dump all ops for every frame before and after reordering.
Example of `GSK_DEBUG=verbose`
This is the output for the first frame of the mask demo:It shows very well how the glyph (and fallback shadow) uploads are moved to the front, followed by the offscreens, which are no longer nested.
start of frame:
begin-render-pass 628x429
0 0 628 429 scissor
push-constants
upload-cairo 628x429
-1 0 630 430 texture 628x429
14 12 600 400 / 8 8 0 0 outset-shadow
push-constants
14 12 600 8 color rgb(246,245,244)
14 20 600 392 clear rgb(246,245,244)
push-constants
push-constants
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (2 stops)
end-render-pass 600x329
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
begin-render-pass 422x198
0 0 422 198 scissor
push-constants
push-constants
upload-glyph 0 0 98 195 glyph 965 @ 0,975586
3,93391e-06 3 98 197 glyph rgb(0,0,0)
upload-glyph 98 0 138 197 glyph 966 @ 0,975586
132 0 139 199 glyph rgb(0,0,0)
upload-glyph 236 0 143 200 glyph 967 @ 0,975586
288 0 144 202 glyph rgb(0,0,0)
push-constants
end-render-pass 422x198
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (8 stops)
end-render-pass 600x329
0 0 600 329 mask 84,7344 76,1484 421,745 197,205 inverted-alpha
end-render-pass 600x329
14 49 600 329 mask 14 49 600 329 inverted-luminance
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (2 stops)
end-render-pass 600x329
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
begin-render-pass 422x198
0 0 422 198 scissor
push-constants
push-constants
3,93391e-06 3 98 197 glyph rgb(0,0,0)
132 0 139 199 glyph rgb(0,0,0)
288 0 144 202 glyph rgb(0,0,0)
push-constants
end-render-pass 422x198
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (8 stops)
end-render-pass 600x329
0 0 600 329 mask 84,7344 76,1484 421,745 197,205 alpha
end-render-pass 600x329
14 49 600 329 mask 14 49 600 329 luminance
push-constants
26 393 576 4 color rgb(225,222,219)
push-constants
26 393 576 4 / 2 border rgb(225,222,219) 1
push-constants
26 393 289 4 color rgb(53,132,228)
push-constants
26 393 289 4 / 2 border rgb(53,132,228) 1
upload-cairo 26x26
301 383 26 26 texture 26x26
push-constants
305 386 18 18 linear-gradient (2 stops)
push-constants
304 385 20 20 / 10 border rgb(205,199,194) 1
14 12 8 37 color rgb(223,220,216)
606 12 8 37 color rgb(223,220,216)
22 12 584 37 clear rgb(223,220,216)
14 12 600 36 linear-gradient (2 stops)
14 12 600 37 border rgb(191,184,177) 0 0 1 0
upload-glyph 379 0 16 15 glyph 48 @ 1
270 23 14 13 glyph rgb(46,52,54)
upload-glyph 395 0 12 14 glyph 68 @ 1
283 25 10 12 glyph rgb(46,52,54)
upload-glyph 407 0 11 14 glyph 86 @ 1
292 25 9 12 glyph rgb(46,52,54)
upload-glyph 418 0 13 16 glyph 78 @ 1
300 22 11 14 glyph rgb(46,52,54)
upload-glyph 431 0 4 4 glyph 3 @ 1
308 34 2 2 glyph rgb(46,52,54)
upload-glyph 435 0 14 15 glyph 49 @ 1
313 23 12 13 glyph rgb(46,52,54)
upload-glyph 449 0 13 14 glyph 82 @ 1
324 25 11 12 glyph rgb(46,52,54)
upload-glyph 462 0 13 17 glyph 71 @ 1
333 22 11 15 glyph rgb(46,52,54)
upload-glyph 475 0 13 14 glyph 72 @ 1
342 25 11 12 glyph rgb(46,52,54)
351 25 9 12 glyph rgb(46,52,54)
upload-texture 16x16
588 22 16 16 color-matrix
push-constants
end-render-pass 628x429
after sort:
upload-glyph 0 0 98 195 glyph 965 @ 0,975586
upload-glyph 98 0 138 197 glyph 966 @ 0,975586
upload-glyph 236 0 143 200 glyph 967 @ 0,975586
upload-cairo 628x429
upload-cairo 26x26
upload-glyph 379 0 16 15 glyph 48 @ 1
upload-glyph 395 0 12 14 glyph 68 @ 1
upload-glyph 407 0 11 14 glyph 86 @ 1
upload-glyph 418 0 13 16 glyph 78 @ 1
upload-glyph 431 0 4 4 glyph 3 @ 1
upload-glyph 435 0 14 15 glyph 49 @ 1
upload-glyph 449 0 13 14 glyph 82 @ 1
upload-glyph 462 0 13 17 glyph 71 @ 1
upload-glyph 475 0 13 14 glyph 72 @ 1
upload-texture 16x16
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (8 stops)
end-render-pass 600x329
begin-render-pass 422x198
0 0 422 198 scissor
push-constants
push-constants
3,93391e-06 3 98 197 glyph rgb(0,0,0)
132 0 139 199 glyph rgb(0,0,0)
288 0 144 202 glyph rgb(0,0,0)
push-constants
end-render-pass 422x198
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 mask 84,7344 76,1484 421,745 197,205 alpha
end-render-pass 600x329
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (2 stops)
end-render-pass 600x329
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (8 stops)
end-render-pass 600x329
begin-render-pass 422x198
0 0 422 198 scissor
push-constants
push-constants
3,93391e-06 3 98 197 glyph rgb(0,0,0)
132 0 139 199 glyph rgb(0,0,0)
288 0 144 202 glyph rgb(0,0,0)
push-constants
end-render-pass 422x198
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 mask 84,7344 76,1484 421,745 197,205 inverted-alpha
end-render-pass 600x329
begin-render-pass 600x329
0 0 600 329 scissor
push-constants
0 0 600 329 linear-gradient (2 stops)
end-render-pass 600x329
begin-render-pass 628x429
0 0 628 429 scissor
push-constants
-1 0 630 430 texture 628x429
14 12 600 400 / 8 8 0 0 outset-shadow
push-constants
14 12 600 8 color rgb(246,245,244)
14 20 600 392 clear rgb(246,245,244)
push-constants
push-constants
14 49 600 329 mask 14 49 600 329 inverted-luminance
14 49 600 329 mask 14 49 600 329 luminance
push-constants
26 393 576 4 color rgb(225,222,219)
push-constants
26 393 576 4 / 2 border rgb(225,222,219) 1
push-constants
26 393 289 4 color rgb(53,132,228)
push-constants
26 393 289 4 / 2 border rgb(53,132,228) 1
301 383 26 26 texture 26x26
push-constants
305 386 18 18 linear-gradient (2 stops)
push-constants
304 385 20 20 / 10 border rgb(205,199,194) 1
14 12 8 37 color rgb(223,220,216)
606 12 8 37 color rgb(223,220,216)
22 12 584 37 clear rgb(223,220,216)
14 12 600 36 linear-gradient (2 stops)
14 12 600 37 border rgb(191,184,177) 0 0 1 0
270 23 14 13 glyph rgb(46,52,54)
283 25 10 12 glyph rgb(46,52,54)
292 25 9 12 glyph rgb(46,52,54)
300 22 11 14 glyph rgb(46,52,54)
308 34 2 2 glyph rgb(46,52,54)
313 23 12 13 glyph rgb(46,52,54)
324 25 11 12 glyph rgb(46,52,54)
333 22 11 15 glyph rgb(46,52,54)
342 25 11 12 glyph rgb(46,52,54)
351 25 9 12 glyph rgb(46,52,54)
588 22 16 16 color-matrix
push-constants
end-render-pass 628x429
As part of the rework a few performance improvements and features happened that are mixed into the commits:
- The mask node is now implemented.
- A clear operation was added that uses
vkCmdClearAttachments()
for large rectangles. This is specifically targeted at the initial background fill of windows or view widgets and goes through a lot of pain to deal with rounded corners. It improves performance of Intel GPUs by ~50%. - Memory barriers are (well, should be, it's hard to test) properly implemented.
- Lifetime management API for images, buffers etc got removed as they can be handled entirely by the ops.
- Renderpass compatibility is properly respected. In general, the validation layers shouldn't complain anymore. If you get validation errors, file a bug.