diff --git a/gsk/vulkan/gskvulkanimage.c b/gsk/vulkan/gskvulkanimage.c index 6cf0c742ba..a473e1a744 100644 --- a/gsk/vulkan/gskvulkanimage.c +++ b/gsk/vulkan/gskvulkanimage.c @@ -8,26 +8,8 @@ #include "gdk/gdkmemoryformatprivate.h" -#include "gskrendernodeprivate.h" - #include -struct _GskVulkanUploader -{ - GdkVulkanContext *vulkan; - - GskVulkanCommandPool *command_pool; - - GArray *before_buffer_barriers; - GArray *before_image_barriers; - VkCommandBuffer copy_buffer; - GArray *after_buffer_barriers; - GArray *after_image_barriers; - - GSList *staging_image_free_list; - GSList *staging_buffer_free_list; -}; - struct _GskVulkanImage { GObject parent_instance; @@ -51,159 +33,6 @@ struct _GskVulkanImage G_DEFINE_TYPE (GskVulkanImage, gsk_vulkan_image, G_TYPE_OBJECT) -GskVulkanUploader * -gsk_vulkan_uploader_new (GdkVulkanContext *context, - GskVulkanCommandPool *command_pool) -{ - GskVulkanUploader *self; - - self = g_new0 (GskVulkanUploader, 1); - - self->vulkan = g_object_ref (context); - self->command_pool = command_pool; - - self->before_buffer_barriers = g_array_new (FALSE, FALSE, sizeof (VkBufferMemoryBarrier)); - self->after_buffer_barriers = g_array_new (FALSE, FALSE, sizeof (VkBufferMemoryBarrier)); - - self->before_image_barriers = g_array_new (FALSE, FALSE, sizeof (VkImageMemoryBarrier)); - self->after_image_barriers = g_array_new (FALSE, FALSE, sizeof (VkImageMemoryBarrier)); - - return self; -} - -void -gsk_vulkan_uploader_free (GskVulkanUploader *self) -{ - gsk_vulkan_uploader_reset (self); - - g_array_unref (self->after_buffer_barriers); - g_array_unref (self->before_buffer_barriers); - g_array_unref (self->after_image_barriers); - g_array_unref (self->before_image_barriers); - - g_object_unref (self->vulkan); - - g_free (self); -} - -static void -gsk_vulkan_uploader_add_image_barrier (GskVulkanUploader *self, - gboolean after, - GskVulkanImage *image, - VkImageLayout new_layout, - VkAccessFlags new_access) -{ - GArray *array; - VkImageMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = image->vk_access, - .dstAccessMask = new_access, - .oldLayout = image->vk_image_layout, - .newLayout = new_layout, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = image->vk_image, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1 - } - }; - - if (after) - array = self->after_image_barriers; - else - array = self->before_image_barriers; - - g_array_append_val (array, barrier); - - image->vk_image_layout = new_layout; - image->vk_access = new_access; -} - -static void -gsk_vulkan_uploader_add_buffer_barrier (GskVulkanUploader *self, - gboolean after, - const VkBufferMemoryBarrier *barrier) -{ - GArray *array; - - if (after) - array = self->after_buffer_barriers; - else - array = self->before_buffer_barriers; - - g_array_append_val (array, *barrier); -} - -static VkCommandBuffer -gsk_vulkan_uploader_get_copy_buffer (GskVulkanUploader *self) -{ - if (self->copy_buffer == VK_NULL_HANDLE) - self->copy_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool); - - return self->copy_buffer; -} - -void -gsk_vulkan_uploader_upload (GskVulkanUploader *self) -{ - VkPipelineStageFlagBits host_and_transfer_bits = VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT; - - if (self->before_buffer_barriers->len > 0 || self->before_image_barriers->len > 0) - { - VkCommandBuffer command_buffer; - - command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool); - vkCmdPipelineBarrier (command_buffer, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | host_and_transfer_bits, - VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, NULL, - self->before_buffer_barriers->len, (VkBufferMemoryBarrier *) self->before_buffer_barriers->data, - self->before_image_barriers->len, (VkImageMemoryBarrier *) self->before_image_barriers->data); - gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, 0, NULL, 0, NULL, VK_NULL_HANDLE); - g_array_set_size (self->before_buffer_barriers, 0); - g_array_set_size (self->before_image_barriers, 0); - } - - /* append these to existing buffer */ - if (self->after_buffer_barriers->len > 0 || self->after_image_barriers->len > 0) - { - VkCommandBuffer command_buffer = gsk_vulkan_uploader_get_copy_buffer (self); - vkCmdPipelineBarrier (command_buffer, - host_and_transfer_bits, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, - 0, NULL, - self->after_buffer_barriers->len, (VkBufferMemoryBarrier *) self->after_buffer_barriers->data, - self->after_image_barriers->len, (VkImageMemoryBarrier *) self->after_image_barriers->data); - g_array_set_size (self->after_buffer_barriers, 0); - g_array_set_size (self->after_image_barriers, 0); - } - - if (self->copy_buffer != VK_NULL_HANDLE) - { - gsk_vulkan_command_pool_submit_buffer (self->command_pool, self->copy_buffer, 0, NULL, 0, NULL, VK_NULL_HANDLE); - self->copy_buffer = VK_NULL_HANDLE; - } -} - -void -gsk_vulkan_uploader_reset (GskVulkanUploader *self) -{ - g_array_set_size (self->before_image_barriers, 0); - self->copy_buffer = VK_NULL_HANDLE; - g_array_set_size (self->after_image_barriers, 0); - - g_slist_free_full (self->staging_image_free_list, g_object_unref); - self->staging_image_free_list = NULL; - g_slist_free_full (self->staging_buffer_free_list, (GDestroyNotify) gsk_vulkan_buffer_free); - self->staging_buffer_free_list = NULL; -} - typedef struct _GskMemoryFormatInfo GskMemoryFormatInfo; struct _GskMemoryFormatInfo @@ -632,175 +461,6 @@ gsk_vulkan_image_new_for_upload (GdkVulkanContext *context, return self; } -static void -gsk_vulkan_image_map_memory_direct (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanMapMode mode, - GskVulkanImageMap *map) -{ - VkImageSubresource image_res; - VkSubresourceLayout image_layout; - - if (self->vk_image_layout != VK_IMAGE_LAYOUT_PREINITIALIZED) - { - gsk_vulkan_uploader_add_image_barrier (uploader, - FALSE, - self, - VK_IMAGE_LAYOUT_GENERAL, - (mode & GSK_VULKAN_READ ? VK_ACCESS_MEMORY_READ_BIT : 0) | - (mode & GSK_VULKAN_WRITE ? VK_ACCESS_MEMORY_WRITE_BIT : 0)); - - if (mode & GSK_VULKAN_READ) - { - gsk_vulkan_uploader_upload (uploader); - GSK_VK_CHECK (vkQueueWaitIdle, gdk_vulkan_context_get_queue (self->vulkan)); - } - } - - 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); - - map->mode = mode; - map->staging_buffer = NULL; - map->data = gsk_vulkan_memory_map (self->memory) + image_layout.offset; - map->stride = image_layout.rowPitch; -} - -static void -gsk_vulkan_image_unmap_memory_direct (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanImageMap *map) -{ - gsk_vulkan_memory_unmap (self->memory); - - gsk_vulkan_uploader_add_image_barrier (uploader, - TRUE, - self, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_ACCESS_SHADER_READ_BIT); -} - -static void -gsk_vulkan_image_map_memory_indirect (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanMapMode mode, - GskVulkanImageMap *map) -{ - map->mode = mode; - map->stride = self->width * gdk_memory_format_bytes_per_pixel (self->format); - map->staging_buffer = gsk_vulkan_buffer_new_map (uploader->vulkan, self->height * map->stride, mode); - - if (self->vk_image_layout != VK_IMAGE_LAYOUT_PREINITIALIZED) - { - if (mode & GSK_VULKAN_READ) - { - gsk_vulkan_uploader_add_image_barrier (uploader, - FALSE, - self, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_ACCESS_TRANSFER_READ_BIT); - - vkCmdCopyImageToBuffer (gsk_vulkan_uploader_get_copy_buffer (uploader), - self->vk_image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - gsk_vulkan_buffer_get_buffer (map->staging_buffer), - 1, - (VkBufferImageCopy[1]) { - { - .bufferOffset = 0, - .imageSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1 - }, - .imageOffset = { 0, 0, 0 }, - .imageExtent = { - .width = self->width, - .height = self->height, - .depth = 1 - } - } - }); - - gsk_vulkan_uploader_upload (uploader); - GSK_VK_CHECK (vkQueueWaitIdle, gdk_vulkan_context_get_queue (self->vulkan)); - } - } - - map->data = gsk_vulkan_buffer_map (map->staging_buffer); -} - -static void -gsk_vulkan_image_unmap_memory_indirect (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanImageMap *map) -{ - gsk_vulkan_buffer_unmap (map->staging_buffer); - - if (map->mode & GSK_VULKAN_WRITE) - { - gsk_vulkan_uploader_add_buffer_barrier (uploader, - FALSE, - &(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 (map->staging_buffer), - .offset = 0, - .size = VK_WHOLE_SIZE, - }); - - gsk_vulkan_uploader_add_image_barrier (uploader, - FALSE, - self, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_ACCESS_TRANSFER_WRITE_BIT); - - vkCmdCopyBufferToImage (gsk_vulkan_uploader_get_copy_buffer (uploader), - gsk_vulkan_buffer_get_buffer (map->staging_buffer), - self->vk_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 = self->width, - .height = self->height, - .depth = 1 - } - } - }); - - uploader->staging_buffer_free_list = g_slist_prepend (uploader->staging_buffer_free_list, - map->staging_buffer); - } - else - { - gsk_vulkan_buffer_free (map->staging_buffer); - } - - gsk_vulkan_uploader_add_image_barrier (uploader, - TRUE, - self, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_ACCESS_SHADER_READ_BIT); -} - static gboolean gsk_vulkan_image_can_map (GskVulkanImage *self) { @@ -810,29 +470,6 @@ gsk_vulkan_image_can_map (GskVulkanImage *self) 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_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); -} - -void -gsk_vulkan_image_unmap_memory (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanImageMap *map) -{ - if (map->staging_buffer) - gsk_vulkan_image_unmap_memory_indirect (self, uploader, map); - else - gsk_vulkan_image_unmap_memory_direct (self, uploader, map); -} - guchar * gsk_vulkan_image_try_map (GskVulkanImage *self, gsize *out_stride) @@ -939,104 +576,6 @@ gsk_vulkan_image_new_for_offscreen (GdkVulkanContext *context, return self; } -GdkTexture * -gsk_vulkan_image_download (GskVulkanImage *self, - GskVulkanUploader *uploader) -{ - GskVulkanImageMap map; - GdkTexture *texture; - GBytes *bytes; - - gsk_vulkan_image_map_memory (self, uploader, GSK_VULKAN_READ, &map); - bytes = g_bytes_new (map.data, map.stride * self->height); - texture = gdk_memory_texture_new (self->width, self->height, - self->format, - bytes, - map.stride); - g_bytes_unref (bytes); - gsk_vulkan_image_unmap_memory (self, uploader, &map); - - return texture; -} - -void -gsk_vulkan_image_upload_regions (GskVulkanImage *self, - GskVulkanUploader *uploader, - guint num_regions, - GskImageRegion *regions) -{ - GskVulkanBuffer *staging; - guchar *mem; - guchar *m; - gsize size; - gsize offset; - VkBufferImageCopy *bufferImageCopy; - - size = 0; - for (int i = 0; i < num_regions; i++) - size += regions[i].width * regions[i].height * 4; - - staging = gsk_vulkan_buffer_new_map (uploader->vulkan, size, GSK_VULKAN_WRITE); - mem = gsk_vulkan_buffer_map (staging); - - bufferImageCopy = alloca (sizeof (VkBufferImageCopy) * num_regions); - memset (bufferImageCopy, 0, sizeof (VkBufferImageCopy) * num_regions); - - offset = 0; - for (int i = 0; i < num_regions; i++) - { - m = mem + offset; - if (regions[i].stride == regions[i].width * 4) - { - memcpy (m, regions[i].data, regions[i].stride * regions[i].height); - } - else - { - for (gsize r = 0; r < regions[i].height; r++) - memcpy (m + r * regions[i].width * 4, regions[i].data + r * regions[i].stride, regions[i].width * 4); - } - - bufferImageCopy[i].bufferOffset = offset; - bufferImageCopy[i].bufferRowLength = regions[i].width; - bufferImageCopy[i].bufferImageHeight = regions[i].height; - bufferImageCopy[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferImageCopy[i].imageSubresource.mipLevel = 0; - bufferImageCopy[i].imageSubresource.baseArrayLayer = 0; - bufferImageCopy[i].imageSubresource.layerCount = 1; - bufferImageCopy[i].imageOffset.x = regions[i].x; - bufferImageCopy[i].imageOffset.y = regions[i].y; - bufferImageCopy[i].imageOffset.z = 0; - bufferImageCopy[i].imageExtent.width = regions[i].width; - bufferImageCopy[i].imageExtent.height = regions[i].height; - bufferImageCopy[i].imageExtent.depth = 1; - - offset += regions[i].width * regions[i].height * 4; - } - - gsk_vulkan_buffer_unmap (staging); - - gsk_vulkan_uploader_add_image_barrier (uploader, - FALSE, - self, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_ACCESS_TRANSFER_WRITE_BIT); - - vkCmdCopyBufferToImage (gsk_vulkan_uploader_get_copy_buffer (uploader), - gsk_vulkan_buffer_get_buffer (staging), - self->vk_image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - num_regions, - bufferImageCopy); - - gsk_vulkan_uploader_add_image_barrier (uploader, - TRUE, - self, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_ACCESS_SHADER_READ_BIT); - - uploader->staging_buffer_free_list = g_slist_prepend (uploader->staging_buffer_free_list, staging); -} - static void gsk_vulkan_image_finalize (GObject *object) { diff --git a/gsk/vulkan/gskvulkanimageprivate.h b/gsk/vulkan/gskvulkanimageprivate.h index aca603a096..9f712b71bf 100644 --- a/gsk/vulkan/gskvulkanimageprivate.h +++ b/gsk/vulkan/gskvulkanimageprivate.h @@ -8,38 +8,16 @@ G_BEGIN_DECLS -typedef struct _GskVulkanUploader GskVulkanUploader; - #define GSK_TYPE_VULKAN_IMAGE (gsk_vulkan_image_get_type ()) G_DECLARE_FINAL_TYPE (GskVulkanImage, gsk_vulkan_image, GSK, VULKAN_IMAGE, GObject) -GskVulkanUploader * gsk_vulkan_uploader_new (GdkVulkanContext *context, - GskVulkanCommandPool *command_pool); -void gsk_vulkan_uploader_free (GskVulkanUploader *self); - -void gsk_vulkan_uploader_reset (GskVulkanUploader *self); -void gsk_vulkan_uploader_upload (GskVulkanUploader *self); - GskVulkanImage * gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context, VkImage image, VkFormat format, gsize width, gsize height); -typedef struct { - guchar *data; - gsize width; - gsize height; - gsize stride; - gsize x; - gsize y; -} GskImageRegion; - -void gsk_vulkan_image_upload_regions (GskVulkanImage *image, - GskVulkanUploader *uploader, - guint num_regions, - GskImageRegion *regions); GskVulkanImage * gsk_vulkan_image_new_for_atlas (GdkVulkanContext *context, gsize width, gsize height); @@ -48,9 +26,6 @@ GskVulkanImage * gsk_vulkan_image_new_for_offscreen (GdkVulk gsize width, gsize height); -GdkTexture * gsk_vulkan_image_download (GskVulkanImage *self, - GskVulkanUploader *uploader); - typedef struct _GskVulkanImageMap GskVulkanImageMap; struct _GskVulkanImageMap @@ -67,13 +42,6 @@ GskVulkanImage * gsk_vulkan_image_new_for_upload (GdkVulk GdkMemoryFormat format, gsize width, gsize height); -void gsk_vulkan_image_map_memory (GskVulkanImage *self, - GskVulkanUploader *uploader, - GskVulkanMapMode mode, - GskVulkanImageMap *map); -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); diff --git a/gsk/vulkan/gskvulkanrender.c b/gsk/vulkan/gskvulkanrender.c index e70bd813e1..20cfd59b3e 100644 --- a/gsk/vulkan/gskvulkanrender.c +++ b/gsk/vulkan/gskvulkanrender.c @@ -60,7 +60,6 @@ struct _GskVulkanRender GskVulkanRenderOps render_ops; GskVulkanOp *first_op; - GskVulkanUploader *uploader; GskDescriptorImageInfos descriptor_images; GskDescriptorBufferInfos descriptor_buffers; @@ -360,7 +359,6 @@ gsk_vulkan_render_new (GskRenderer *renderer, gsk_vulkan_render_ops_init (&self->render_ops); - self->uploader = gsk_vulkan_uploader_new (self->vulkan, self->command_pool); self->pipeline_cache = g_hash_table_new (pipeline_cache_key_hash, pipeline_cache_key_equal); self->render_pass_cache = g_hash_table_new (render_pass_cache_key_hash, render_pass_cache_key_equal); @@ -952,17 +950,6 @@ gsk_vulkan_render_submit (GskVulkanRender *self) #endif } -GdkTexture * -gsk_vulkan_render_download_target (GskVulkanRender *self) -{ - GdkTexture *texture; - - texture = gsk_vulkan_image_download (self->target, self->uploader); - gsk_vulkan_uploader_reset (self->uploader); - - return texture; -} - static void gsk_vulkan_render_cleanup (GskVulkanRender *self) { @@ -989,8 +976,6 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self) } gsk_vulkan_render_ops_set_size (&self->render_ops, 0); - gsk_vulkan_uploader_reset (self->uploader); - gsk_vulkan_command_pool_reset (self->command_pool); GSK_VK_CHECK (vkResetDescriptorPool, device, @@ -1034,7 +1019,6 @@ gsk_vulkan_render_free (GskVulkanRender *self) g_hash_table_unref (self->render_pass_cache); gsk_vulkan_render_ops_clear (&self->render_ops); - g_clear_pointer (&self->uploader, gsk_vulkan_uploader_free); vkDestroyPipelineLayout (device, diff --git a/gsk/vulkan/gskvulkanrenderprivate.h b/gsk/vulkan/gskvulkanrenderprivate.h index c9322edd9a..506e717c99 100644 --- a/gsk/vulkan/gskvulkanrenderprivate.h +++ b/gsk/vulkan/gskvulkanrenderprivate.h @@ -60,7 +60,6 @@ guchar * gsk_vulkan_render_get_buffer_memory (GskVulk gsize alignment, gsize *out_offset); -GdkTexture * gsk_vulkan_render_download_target (GskVulkanRender *self); VkFence gsk_vulkan_render_get_fence (GskVulkanRender *self); G_END_DECLS