vulkan: Remove GskVulkanUploader

... and all the remaining functions still using it.

It's all unused and has been replaced by upload and download ops.

With this change, all GPU operations now go via GskVulkanOp.command()
and no more side channels exist.
This commit is contained in:
Benjamin Otte
2023-07-15 02:05:24 +02:00
parent db2029d931
commit ca69fd2b7a
4 changed files with 0 additions and 510 deletions

View File

@@ -8,26 +8,8 @@
#include "gdk/gdkmemoryformatprivate.h"
#include "gskrendernodeprivate.h"
#include <string.h>
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)
{

View File

@@ -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);

View File

@@ -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,

View File

@@ -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