From c72588748b404a121aa97788212cc18100f4da3a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 11 Jul 2023 15:14:22 +0200 Subject: [PATCH] vulkan: Implement direct upload for the cairo op --- gsk/vulkan/gskvulkanimage.c | 44 ++++++++- gsk/vulkan/gskvulkanimageprivate.h | 3 + gsk/vulkan/gskvulkanuploadcairoop.c | 145 +++++++++++++++------------- 3 files changed, 125 insertions(+), 67 deletions(-) diff --git a/gsk/vulkan/gskvulkanimage.c b/gsk/vulkan/gskvulkanimage.c index 78246e5675..7b67b50caf 100644 --- a/gsk/vulkan/gskvulkanimage.c +++ b/gsk/vulkan/gskvulkanimage.c @@ -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, diff --git a/gsk/vulkan/gskvulkanimageprivate.h b/gsk/vulkan/gskvulkanimageprivate.h index aab02c0ac8..f7741b3c81 100644 --- a/gsk/vulkan/gskvulkanimageprivate.h +++ b/gsk/vulkan/gskvulkanimageprivate.h @@ -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); diff --git a/gsk/vulkan/gskvulkanuploadcairoop.c b/gsk/vulkan/gskvulkanuploadcairoop.c index 9e99c9e7b2..e636012f8d 100644 --- a/gsk/vulkan/gskvulkanuploadcairoop.c +++ b/gsk/vulkan/gskvulkanuploadcairoop.c @@ -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, -- 2.30.2