[gtk+/wip/otte/vulkan: 6/28] vulkan: Upload image data directly
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/vulkan: 6/28] vulkan: Upload image data directly
- Date: Fri, 9 Dec 2016 06:27:33 +0000 (UTC)
commit 6e420ce2ca456be480cb3e65480c2bcfce9777a0
Author: Benjamin Otte <otte redhat com>
Date: Tue Dec 6 23:29:38 2016 +0100
vulkan: Upload image data directly
Instead of using a staging iamge, we require the final image to be
linearly allocated and have host-visible memory.
This improves performance quite a bit.
The old code is still there and can be enabled with a simple change
to a #define in gskvulkanimage.h
gsk/gskvulkanimage.c | 124 +++++++++++++++++++++++++++++++++----------
gsk/gskvulkanimageprivate.h | 8 +++
2 files changed, 104 insertions(+), 28 deletions(-)
---
diff --git a/gsk/gskvulkanimage.c b/gsk/gskvulkanimage.c
index c8777f7..edfb24a 100644
--- a/gsk/gskvulkanimage.c
+++ b/gsk/gskvulkanimage.c
@@ -65,27 +65,19 @@ gsk_vulkan_image_new (GdkVulkanContext *context,
return self;
}
-static GskVulkanImage *
-gsk_vulkan_image_new_staging (GdkVulkanContext *context,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+static void
+gsk_vulkan_image_upload_data (GskVulkanImage *self,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize data_stride)
{
VkMemoryRequirements requirements;
- GskVulkanImage *self;
- guchar *mem;
gsize mem_stride;
-
- self = gsk_vulkan_image_new (context,
- width,
- height,
- VK_IMAGE_TILING_LINEAR,
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+ guchar *mem;
mem_stride = width * 4;
- vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (context),
+ vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (self->vulkan),
self->vk_image,
&requirements);
if (mem_stride % requirements.alignment != 0)
@@ -93,21 +85,19 @@ gsk_vulkan_image_new_staging (GdkVulkanContext *context,
mem = gsk_vulkan_memory_map (self->memory);
- if (stride == width * 4 && stride == mem_stride)
+ if (data_stride == width * 4 && data_stride == mem_stride)
{
- memcpy (mem, data, width * height * 4);
+ memcpy (mem, data, data_stride * height);
}
else
{
for (gsize i = 0; i < height; i++)
{
- memcpy (mem + i * mem_stride, data + i * stride, width * 4);
+ memcpy (mem + i * mem_stride, data + i * data_stride, width * 4);
}
}
gsk_vulkan_memory_unmap (self->memory);
-
- return self;
}
static void
@@ -138,16 +128,23 @@ gsk_vulkan_image_ensure_view (GskVulkanImage *self)
}
GskVulkanImage *
-gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
- VkCommandBuffer command_buffer,
- guchar *data,
- gsize width,
- gsize height,
- gsize stride)
+gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
{
GskVulkanImage *self, *staging;
- staging = gsk_vulkan_image_new_staging (context, data, width, height, stride);
+ staging = gsk_vulkan_image_new (context,
+ width,
+ height,
+ VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+
+ gsk_vulkan_image_upload_data (staging, data, width, height, stride);
self = gsk_vulkan_image_new (context,
width,
@@ -253,6 +250,7 @@ gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
}
});
+ /* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
gsk_vulkan_image_free (staging);
gsk_vulkan_image_ensure_view (self);
@@ -260,6 +258,76 @@ gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
return self;
}
+GskVulkanImage *
+gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
+{
+ GskVulkanImage *self;
+
+ self = gsk_vulkan_image_new (context,
+ width,
+ height,
+ VK_IMAGE_TILING_LINEAR,
+ VK_IMAGE_USAGE_SAMPLED_BIT,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+
+ gsk_vulkan_image_upload_data (self, data, width, height, stride);
+
+ vkCmdPipelineBarrier (command_buffer,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ 0,
+ 0, NULL,
+ 0, NULL,
+ 1, (VkImageMemoryBarrier[1]) {
+ {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT,
+ .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
+ .oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED,
+ .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = self->vk_image,
+ .subresourceRange = {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1
+ }
+ }
+ });
+
+ gsk_vulkan_image_ensure_view (self);
+
+ return self;
+}
+
+GskVulkanImage *
+gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
+ VkCommandBuffer command_buffer,
+ guchar *data,
+ gsize width,
+ gsize height,
+ gsize stride)
+{
+ switch (GSK_VULKAN_UPLOAD_IMAGE_DEFAULT)
+ {
+ default:
+ g_assert_not_reached ();
+ /* fall through */
+ case GSK_VULKAN_UPLOAD_DIRECTLY:
+ return gsk_vulkan_image_new_from_data_directly (context, command_buffer, data, width, height, stride);
+ case GSK_VULKAN_UPLOAD_VIA_STAGING_IMAGE:
+ return gsk_vulkan_image_new_from_data_via_staging_image (context, command_buffer, data, width, height,
stride);
+ }
+}
+
void
gsk_vulkan_image_free (GskVulkanImage *self)
{
diff --git a/gsk/gskvulkanimageprivate.h b/gsk/gskvulkanimageprivate.h
index 57686ea..7c089c2 100644
--- a/gsk/gskvulkanimageprivate.h
+++ b/gsk/gskvulkanimageprivate.h
@@ -5,6 +5,14 @@
G_BEGIN_DECLS
+/* Modify here for benchmarking */
+#define GSK_VULKAN_UPLOAD_IMAGE_DEFAULT GSK_VULKAN_UPLOAD_DIRECTLY
+
+typedef enum {
+ GSK_VULKAN_UPLOAD_DIRECTLY,
+ GSK_VULKAN_UPLOAD_VIA_STAGING_IMAGE
+} GstkVulkanImageUpload;
+
typedef struct _GskVulkanImage GskVulkanImage;
GskVulkanImage * gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]