Skip to content

vulkan: Make RenderOps into proper structs

Benjamin Otte requested to merge wip/otte/vulkan-for-main into main

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:

  1. GskVulkanPipeline objects - each shader is now invoked via a custom op.
  2. GskVulkanUploader - that previous side channel used for uploads is now integrated via upload ops
  3. gsk_vulkan_image_download() - a download op replaces this
  4. GskVulkanGlyphCache now uploads its glyphs via upload ops
  5. 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:

image 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:

  1. The mask node is now implemented.
  2. 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%.
  3. Memory barriers are (well, should be, it's hard to test) properly implemented.
  4. Lifetime management API for images, buffers etc got removed as they can be handled entirely by the ops.
  5. Renderpass compatibility is properly respected. In general, the validation layers shouldn't complain anymore. If you get validation errors, file a bug.
Edited by Benjamin Otte

Merge request reports