vulkan: Implement direct upload for the cairo op
authorBenjamin Otte <otte@redhat.com>
Tue, 11 Jul 2023 13:14:22 +0000 (15:14 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 16 Jul 2023 10:13:00 +0000 (12:13 +0200)
gsk/vulkan/gskvulkanimage.c
gsk/vulkan/gskvulkanimageprivate.h
gsk/vulkan/gskvulkanuploadcairoop.c

index 78246e5675f5f553574ec699053aae9d59d32fd8..7b67b50caf301e77cc36c83b019f0ff30d16c27a 100644 (file)
@@ -822,13 +822,22 @@ gsk_vulkan_image_unmap_memory_indirect (GskVulkanImage    *self,
                                          VK_ACCESS_SHADER_READ_BIT);
 }
 
+static gboolean
+gsk_vulkan_image_can_map (GskVulkanImage *self)
+{
+  if (GSK_DEBUG_CHECK (STAGING))
+    return FALSE;
+
+  return gsk_vulkan_memory_can_map (self->memory, TRUE);
+}
+
 void
 gsk_vulkan_image_map_memory (GskVulkanImage    *self,
                              GskVulkanUploader *uploader,
                              GskVulkanMapMode   mode,
                              GskVulkanImageMap *map)
 {
-  if (!GSK_DEBUG_CHECK (STAGING) && gsk_vulkan_memory_can_map (self->memory, TRUE))
+  if (gsk_vulkan_image_can_map (self))
     gsk_vulkan_image_map_memory_direct (self, uploader, mode, map);
   else
     gsk_vulkan_image_map_memory_indirect (self, uploader, mode, map);
@@ -845,6 +854,39 @@ gsk_vulkan_image_unmap_memory (GskVulkanImage    *self,
     gsk_vulkan_image_unmap_memory_direct (self, uploader, map);
 }
 
+guchar *
+gsk_vulkan_image_try_map (GskVulkanImage *self,
+                          gsize          *out_stride)
+{
+  VkImageSubresource image_res;
+  VkSubresourceLayout image_layout;
+  guchar *result;
+
+  if (!gsk_vulkan_image_can_map (self))
+    return NULL;
+
+  result = gsk_vulkan_memory_map (self->memory);
+  if (result == NULL)
+    return NULL;
+
+  image_res.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+  image_res.mipLevel = 0;
+  image_res.arrayLayer = 0;
+
+  vkGetImageSubresourceLayout (gdk_vulkan_context_get_device (self->vulkan),
+                               self->vk_image, &image_res, &image_layout);
+
+  *out_stride = image_layout.rowPitch;
+
+  return result + image_layout.offset;
+}
+
+void
+gsk_vulkan_image_unmap (GskVulkanImage *self)
+{
+  gsk_vulkan_memory_unmap (self->memory);
+}
+
 GskVulkanImage *
 gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
                                     VkImage           image,
index aab02c0ac87c21234963a57ef65a0dfd79eb0f4d..f7741b3c81e7d788244ef1ee9458eb38405cba7c 100644 (file)
@@ -76,6 +76,9 @@ void                    gsk_vulkan_image_map_memory                     (GskVulk
 void                    gsk_vulkan_image_unmap_memory                   (GskVulkanImage         *self,
                                                                          GskVulkanUploader      *uploader,
                                                                          GskVulkanImageMap      *map);
+guchar *                gsk_vulkan_image_try_map                        (GskVulkanImage         *self,
+                                                                         gsize                  *out_stride);
+void                    gsk_vulkan_image_unmap                          (GskVulkanImage         *self);
 
 gsize                   gsk_vulkan_image_get_width                      (GskVulkanImage         *self);
 gsize                   gsk_vulkan_image_get_height                     (GskVulkanImage         *self);
index 9e99c9e7b2c5c20033280a942d8e2651518e2159..e636012f8d1ce540c19bd8e423aa94742a179d81 100644 (file)
@@ -108,72 +108,85 @@ gsk_vulkan_upload_cairo_op_command (GskVulkanOp      *op,
   gsize stride;
   guchar *data;
 
-  stride = gsk_vulkan_image_get_width (self->image) * 
-    gdk_memory_format_bytes_per_pixel (gsk_vulkan_image_get_format (self->image));
-  self->buffer = gsk_vulkan_buffer_new_map (gsk_vulkan_render_get_context (render),
-                                            gsk_vulkan_image_get_height (self->image) * stride,
-                                            GSK_VULKAN_WRITE);
-  data = gsk_vulkan_buffer_map (self->buffer);
-
-  gsk_vulkan_upload_cairo_op_draw (self, data, stride);
-
-  gsk_vulkan_buffer_unmap (self->buffer);
-
-  vkCmdPipelineBarrier (command_buffer,
-                        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
-                        VK_PIPELINE_STAGE_TRANSFER_BIT,
-                        0,
-                        0, NULL,
-                        1, &(VkBufferMemoryBarrier) {
-                            .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
-                            .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT,
-                            .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
-                            .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-                            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-                            .buffer = gsk_vulkan_buffer_get_buffer (self->buffer),
-                            .offset = 0,
-                            .size = VK_WHOLE_SIZE,
-                        },
-                        1, &(VkImageMemoryBarrier) {
-                            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-                            .srcAccessMask = gsk_vulkan_image_get_vk_access (self->image),
-                            .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
-                            .oldLayout = gsk_vulkan_image_get_vk_image_layout (self->image),
-                            .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                            .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-                            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-                            .image = gsk_vulkan_image_get_vk_image (self->image),
-                            .subresourceRange = {
-                              .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                              .baseMipLevel = 0,
-                              .levelCount = 1,
-                              .baseArrayLayer = 0,
-                              .layerCount = 1
+  data = gsk_vulkan_image_try_map (self->image, &stride);
+  if (data)
+    {
+      gsk_vulkan_upload_cairo_op_draw (self, data, stride);
+
+      gsk_vulkan_image_unmap (self->image);
+    }
+  else
+    {
+      stride = gsk_vulkan_image_get_width (self->image) * 
+        gdk_memory_format_bytes_per_pixel (gsk_vulkan_image_get_format (self->image));
+      self->buffer = gsk_vulkan_buffer_new_map (gsk_vulkan_render_get_context (render),
+                                                gsk_vulkan_image_get_height (self->image) * stride,
+                                                GSK_VULKAN_WRITE);
+      data = gsk_vulkan_buffer_map (self->buffer);
+
+      gsk_vulkan_upload_cairo_op_draw (self, data, stride);
+
+      gsk_vulkan_buffer_unmap (self->buffer);
+
+      vkCmdPipelineBarrier (command_buffer,
+                            VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                            VK_PIPELINE_STAGE_TRANSFER_BIT,
+                            0,
+                            0, NULL,
+                            1, &(VkBufferMemoryBarrier) {
+                                .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
+                                .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT,
+                                .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
+                                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+                                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+                                .buffer = gsk_vulkan_buffer_get_buffer (self->buffer),
+                                .offset = 0,
+                                .size = VK_WHOLE_SIZE,
                             },
-                        });
-
-  vkCmdCopyBufferToImage (command_buffer,
-                          gsk_vulkan_buffer_get_buffer (self->buffer),
-                          gsk_vulkan_image_get_vk_image (self->image),
-                          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                          1,
-                          (VkBufferImageCopy[1]) {
-                               {
-                                   .bufferOffset = 0,
-                                   .imageSubresource = {
-                                       .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                       .mipLevel = 0,
-                                       .baseArrayLayer = 0,
-                                       .layerCount = 1
-                                   },
-                                   .imageOffset = { 0, 0, 0 },
-                                   .imageExtent = {
-                                       .width = gsk_vulkan_image_get_width (self->image),
-                                       .height = gsk_vulkan_image_get_height (self->image),
-                                       .depth = 1
+                            1, &(VkImageMemoryBarrier) {
+                                .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+                                .srcAccessMask = gsk_vulkan_image_get_vk_access (self->image),
+                                .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
+                                .oldLayout = gsk_vulkan_image_get_vk_image_layout (self->image),
+                                .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+                                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+                                .image = gsk_vulkan_image_get_vk_image (self->image),
+                                .subresourceRange = {
+                                  .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                  .baseMipLevel = 0,
+                                  .levelCount = 1,
+                                  .baseArrayLayer = 0,
+                                  .layerCount = 1
+                                },
+                            });
+      gsk_vulkan_image_set_vk_image_layout (self->image,
+                                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                            VK_ACCESS_TRANSFER_WRITE_BIT);
+
+      vkCmdCopyBufferToImage (command_buffer,
+                              gsk_vulkan_buffer_get_buffer (self->buffer),
+                              gsk_vulkan_image_get_vk_image (self->image),
+                              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                              1,
+                              (VkBufferImageCopy[1]) {
+                                   {
+                                       .bufferOffset = 0,
+                                       .imageSubresource = {
+                                           .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                                           .mipLevel = 0,
+                                           .baseArrayLayer = 0,
+                                           .layerCount = 1
+                                       },
+                                       .imageOffset = { 0, 0, 0 },
+                                       .imageExtent = {
+                                           .width = gsk_vulkan_image_get_width (self->image),
+                                           .height = gsk_vulkan_image_get_height (self->image),
+                                           .depth = 1
+                                       }
                                    }
-                               }
-                          });
+                              });
+    }
 
   vkCmdPipelineBarrier (command_buffer,
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
@@ -183,9 +196,9 @@ gsk_vulkan_upload_cairo_op_command (GskVulkanOp      *op,
                         0, NULL,
                         1, &(VkImageMemoryBarrier) {
                             .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-                            .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
+                            .srcAccessMask = gsk_vulkan_image_get_vk_access (self->image),
                             .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
-                            .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                            .oldLayout = gsk_vulkan_image_get_vk_image_layout (self->image),
                             .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                             .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                             .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,