vulkan: Properly update image layouts
authorBenjamin Otte <otte@redhat.com>
Fri, 14 Jul 2023 21:05:19 +0000 (23:05 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 16 Jul 2023 11:16:43 +0000 (13:16 +0200)
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.

gsk/vulkan/gskvulkanrender.c
gsk/vulkan/gskvulkanrenderpassop.c
gsk/vulkan/gskvulkanrenderpassopprivate.h

index 155ad9dba1c6051dbe38ed4716c5bed6cd692a39..17cd2daf5a527d3d38dc8b9fe83b6321890022e2 100644 (file)
@@ -498,7 +498,9 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
                              self->clip,
                              &scale,
                              &self->viewport,
-                             node, TRUE);
+                             node,
+                             VK_IMAGE_LAYOUT_UNDEFINED,
+                             VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
 
   gsk_vulkan_render_seal_ops (self);
   gsk_vulkan_render_verbose_print (self, "start of frame");
index c2f8c8b4543a1a80e8d02c69ebe64b459a633767..895c19cb21949ea443c0a23bef4e9da569167b9b 100644 (file)
@@ -158,6 +158,7 @@ struct _GskVulkanRenderPassEndOp
   GskVulkanOp op;
 
   GskVulkanImage *image;
+  VkImageLayout final_layout;
 };
 
 static void
@@ -206,8 +207,13 @@ gsk_vulkan_render_pass_end_op_command (GskVulkanOp      *op,
                                        VkPipelineLayout  pipeline_layout,
                                        VkCommandBuffer   command_buffer)
 {
+  GskVulkanRenderPassEndOp *self = (GskVulkanRenderPassEndOp *) op;
+
   vkCmdEndRenderPass (command_buffer);
 
+  gsk_vulkan_image_set_vk_image_layout (self->image,
+                                        self->final_layout,
+                                        gsk_vulkan_image_get_vk_access (self->image));
   return op->next;
 }
 
@@ -232,7 +238,8 @@ gsk_vulkan_render_pass_op (GskVulkanRender       *render,
                            const graphene_vec2_t *scale,
                            const graphene_rect_t *viewport,
                            GskRenderNode         *node,
-                           gboolean               is_root)
+                           VkImageLayout          initial_layout,
+                           VkImageLayout          final_layout)
 {
   GskVulkanRenderPassOp *self;
   GskVulkanRenderPassEndOp *end;
@@ -240,9 +247,8 @@ gsk_vulkan_render_pass_op (GskVulkanRender       *render,
   self = (GskVulkanRenderPassOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_OP_CLASS);
 
   self->image = image;
-  self->initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
-  self->final_layout = is_root ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
-                               :VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+  self->initial_layout = initial_layout;
+  self->final_layout = final_layout;
   cairo_region_get_extents (clip, &self->area);
   self->viewport_size = viewport->size;
 
@@ -260,6 +266,7 @@ gsk_vulkan_render_pass_op (GskVulkanRender       *render,
   end = (GskVulkanRenderPassEndOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_END_OP_CLASS);
 
   end->image = g_object_ref (image);
+  end->final_layout = final_layout;
 }
 
 GskVulkanImage *
@@ -299,7 +306,8 @@ gsk_vulkan_render_pass_op_offscreen (GskVulkanRender       *render,
                              scale,
                              &view,
                              node,
-                             FALSE);
+                             VK_IMAGE_LAYOUT_UNDEFINED,
+                             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 
   cairo_region_destroy (clip);
 
index 313e99d05bf92a7dc94d05d56c19bf218defdc40..7765a9f2112034652eb16cdd854d0e5facf4e4d9 100644 (file)
@@ -11,7 +11,8 @@ void                    gsk_vulkan_render_pass_op                       (GskVulk
                                                                          const graphene_vec2_t          *scale,
                                                                          const graphene_rect_t          *viewport,
                                                                          GskRenderNode                  *node,
-                                                                         gboolean                        is_root);
+                                                                         VkImageLayout                   initial_layout,
+                                                                         VkImageLayout                   final_layout);
 GskVulkanImage *        gsk_vulkan_render_pass_op_offscreen             (GskVulkanRender                *render,
                                                                          GdkVulkanContext               *context,
                                                                          const graphene_vec2_t          *scale,