From 48e1d48e7fe1161002d0ac11d84389b0721ff01f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 11 Jul 2023 09:35:01 +0200 Subject: [PATCH] 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. --- gsk/vulkan/gskvulkanimage.c | 23 +++++- gsk/vulkan/gskvulkanimageprivate.h | 7 +- gsk/vulkan/gskvulkanrender.c | 6 ++ gsk/vulkan/gskvulkanrenderprivate.h | 1 + gsk/vulkan/gskvulkanuploadcairoop.c | 113 ++++++++++++++++++++++++++-- 5 files changed, 140 insertions(+), 10 deletions(-) diff --git a/gsk/vulkan/gskvulkanimage.c b/gsk/vulkan/gskvulkanimage.c index ee82252a5a..78246e5675 100644 --- a/gsk/vulkan/gskvulkanimage.c +++ b/gsk/vulkan/gskvulkanimage.c @@ -1091,7 +1091,7 @@ gsk_vulkan_image_get_height (GskVulkanImage *self) } VkImage -gsk_vulkan_image_get_image (GskVulkanImage *self) +gsk_vulkan_image_get_vk_image (GskVulkanImage *self) { return self->vk_image; } @@ -1102,6 +1102,27 @@ gsk_vulkan_image_get_image_view (GskVulkanImage *self) return self->vk_image_view; } +VkImageLayout +gsk_vulkan_image_get_vk_image_layout (GskVulkanImage *self) +{ + return self->vk_image_layout; +} + +VkAccessFlags +gsk_vulkan_image_get_vk_access (GskVulkanImage *self) +{ + return self->vk_access; +} + +void +gsk_vulkan_image_set_vk_image_layout (GskVulkanImage *self, + VkImageLayout image_layout, + VkAccessFlags access) +{ + self->vk_image_layout = image_layout; + self->vk_access = access; +} + VkFormat gsk_vulkan_image_get_vk_format (GskVulkanImage *self) { diff --git a/gsk/vulkan/gskvulkanimageprivate.h b/gsk/vulkan/gskvulkanimageprivate.h index 828b008e26..aab02c0ac8 100644 --- a/gsk/vulkan/gskvulkanimageprivate.h +++ b/gsk/vulkan/gskvulkanimageprivate.h @@ -79,7 +79,12 @@ void gsk_vulkan_image_unmap_memory (GskVulk gsize gsk_vulkan_image_get_width (GskVulkanImage *self); gsize gsk_vulkan_image_get_height (GskVulkanImage *self); -VkImage gsk_vulkan_image_get_image (GskVulkanImage *self); +VkImageLayout gsk_vulkan_image_get_vk_image_layout (GskVulkanImage *self); +VkAccessFlags gsk_vulkan_image_get_vk_access (GskVulkanImage *self); +void gsk_vulkan_image_set_vk_image_layout (GskVulkanImage *self, + VkImageLayout image_layout, + VkAccessFlags access); +VkImage gsk_vulkan_image_get_vk_image (GskVulkanImage *self); VkImageView gsk_vulkan_image_get_image_view (GskVulkanImage *self); VkFormat gsk_vulkan_image_get_vk_format (GskVulkanImage *self); GdkMemoryFormat gsk_vulkan_image_get_format (GskVulkanImage *self); diff --git a/gsk/vulkan/gskvulkanrender.c b/gsk/vulkan/gskvulkanrender.c index df1948b805..a4137ec34a 100644 --- a/gsk/vulkan/gskvulkanrender.c +++ b/gsk/vulkan/gskvulkanrender.c @@ -1144,6 +1144,12 @@ gsk_vulkan_render_get_renderer (GskVulkanRender *self) return self->renderer; } +GdkVulkanContext * +gsk_vulkan_render_get_context (GskVulkanRender *self) +{ + return self->vulkan; +} + gpointer gsk_vulkan_render_alloc_op (GskVulkanRender *self, gsize size) diff --git a/gsk/vulkan/gskvulkanrenderprivate.h b/gsk/vulkan/gskvulkanrenderprivate.h index 814c828864..eb96de005a 100644 --- a/gsk/vulkan/gskvulkanrenderprivate.h +++ b/gsk/vulkan/gskvulkanrenderprivate.h @@ -27,6 +27,7 @@ void gsk_vulkan_render_reset (GskVulk GskRenderNode *node); GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self); +GdkVulkanContext * gsk_vulkan_render_get_context (GskVulkanRender *self); void gsk_vulkan_render_upload (GskVulkanRender *self); diff --git a/gsk/vulkan/gskvulkanuploadcairoop.c b/gsk/vulkan/gskvulkanuploadcairoop.c index ca83a68b9e..9e99c9e7b2 100644 --- a/gsk/vulkan/gskvulkanuploadcairoop.c +++ b/gsk/vulkan/gskvulkanuploadcairoop.c @@ -4,6 +4,8 @@ #include "gskvulkanprivate.h" +#include "gdk/gdkmemoryformatprivate.h" + typedef struct _GskVulkanUploadCairoOp GskVulkanUploadCairoOp; struct _GskVulkanUploadCairoOp @@ -13,6 +15,8 @@ struct _GskVulkanUploadCairoOp GskVulkanImage *image; GskRenderNode *node; graphene_rect_t viewport; + + GskVulkanBuffer *buffer; }; static void @@ -22,6 +26,8 @@ gsk_vulkan_upload_cairo_op_finish (GskVulkanOp *op) g_object_unref (self->image); gsk_render_node_unref (self->node); + + g_clear_pointer (&self->buffer, gsk_vulkan_buffer_free); } static void @@ -71,14 +77,6 @@ static void gsk_vulkan_upload_cairo_op_upload (GskVulkanOp *op, GskVulkanUploader *uploader) { - GskVulkanUploadCairoOp *self = (GskVulkanUploadCairoOp *) op; - GskVulkanImageMap map; - - gsk_vulkan_image_map_memory (self->image, uploader, GSK_VULKAN_WRITE, &map); - - gsk_vulkan_upload_cairo_op_draw (self, map.data, map.stride); - - gsk_vulkan_image_unmap_memory (self->image, uploader, &map); } static gsize @@ -106,6 +104,105 @@ gsk_vulkan_upload_cairo_op_command (GskVulkanOp *op, VkPipelineLayout pipeline_layout, VkCommandBuffer command_buffer) { + GskVulkanUploadCairoOp *self = (GskVulkanUploadCairoOp *) 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 + }, + }); + + 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, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, + 0, NULL, + 0, NULL, + 1, &(VkImageMemoryBarrier) { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_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_SHADER_READ_ONLY_OPTIMAL, + VK_ACCESS_SHADER_READ_BIT); + return op->next; } -- 2.30.2