mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-12 11:50:21 +00:00
vulkan: Add GskVulkanUploader
It's the thing that makes sure pixels end up on the GPU.
This commit is contained in:
parent
85559d1fd9
commit
7b9ace488b
@ -8,6 +8,16 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _GskVulkanUploader
|
||||
{
|
||||
GdkVulkanContext *vulkan;
|
||||
|
||||
GskVulkanCommandPool *command_pool;
|
||||
|
||||
GSList *staging_image_free_list;
|
||||
GSList *staging_buffer_free_list;
|
||||
};
|
||||
|
||||
struct _GskVulkanImage
|
||||
{
|
||||
GObject parent_instance;
|
||||
@ -24,6 +34,39 @@ 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_slice_new0 (GskVulkanUploader);
|
||||
|
||||
self->vulkan = g_object_ref (context);
|
||||
self->command_pool = command_pool;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_uploader_free (GskVulkanUploader *self)
|
||||
{
|
||||
gsk_vulkan_uploader_reset (self);
|
||||
|
||||
g_object_unref (self->vulkan);
|
||||
|
||||
g_slice_free (GskVulkanUploader, self);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_uploader_reset (GskVulkanUploader *self)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static GskVulkanImage *
|
||||
gsk_vulkan_image_new (GdkVulkanContext *context,
|
||||
gsize width,
|
||||
@ -139,19 +182,18 @@ gsk_vulkan_image_ensure_view (GskVulkanImage *self,
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context,
|
||||
GskVulkanCommandPool *command_pool,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
gsk_vulkan_image_new_from_data_via_staging_buffer (GskVulkanUploader *uploader,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
{
|
||||
GskVulkanImage *self;
|
||||
GskVulkanBuffer *staging;
|
||||
VkCommandBuffer command_buffer;
|
||||
guchar *mem;
|
||||
|
||||
staging = gsk_vulkan_buffer_new_staging (context, width * height * 4);
|
||||
staging = gsk_vulkan_buffer_new_staging (uploader->vulkan, width * height * 4);
|
||||
mem = gsk_vulkan_buffer_map (staging);
|
||||
|
||||
if (stride == width * 4)
|
||||
@ -168,14 +210,14 @@ gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context
|
||||
|
||||
gsk_vulkan_buffer_unmap (staging);
|
||||
|
||||
self = gsk_vulkan_image_new (context,
|
||||
self = gsk_vulkan_image_new (uploader->vulkan,
|
||||
width,
|
||||
height,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (uploader->command_pool);
|
||||
|
||||
vkCmdPipelineBarrier (command_buffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
@ -252,10 +294,9 @@ gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context
|
||||
}
|
||||
});
|
||||
|
||||
gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
gsk_vulkan_command_pool_submit_buffer (uploader->command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
|
||||
/* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
|
||||
gsk_vulkan_buffer_free (staging);
|
||||
uploader->staging_buffer_free_list = g_slist_prepend (uploader->staging_buffer_free_list, staging);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
|
||||
@ -263,17 +304,16 @@ gsk_vulkan_image_new_from_data_via_staging_buffer (GdkVulkanContext *context
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
|
||||
GskVulkanCommandPool *command_pool,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
gsk_vulkan_image_new_from_data_via_staging_image (GskVulkanUploader *uploader,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
{
|
||||
GskVulkanImage *self, *staging;
|
||||
VkCommandBuffer command_buffer;
|
||||
|
||||
staging = gsk_vulkan_image_new (context,
|
||||
staging = gsk_vulkan_image_new (uploader->vulkan,
|
||||
width,
|
||||
height,
|
||||
VK_IMAGE_TILING_LINEAR,
|
||||
@ -282,14 +322,14 @@ gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
|
||||
|
||||
gsk_vulkan_image_upload_data (staging, data, width, height, stride);
|
||||
|
||||
self = gsk_vulkan_image_new (context,
|
||||
self = gsk_vulkan_image_new (uploader->vulkan,
|
||||
width,
|
||||
height,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (uploader->command_pool);
|
||||
|
||||
vkCmdPipelineBarrier (command_buffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
@ -388,10 +428,9 @@ gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
|
||||
}
|
||||
});
|
||||
|
||||
gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
gsk_vulkan_command_pool_submit_buffer (uploader->command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
|
||||
/* XXX: Is this okay or do we need to keep the staging image around until the commands execute */
|
||||
g_object_unref (staging);
|
||||
uploader->staging_image_free_list = g_slist_prepend (uploader->staging_image_free_list, staging);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
|
||||
@ -399,19 +438,18 @@ gsk_vulkan_image_new_from_data_via_staging_image (GdkVulkanContext *context,
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
|
||||
GskVulkanCommandPool *command_pool,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
gsk_vulkan_image_new_from_data_directly (GskVulkanUploader *uploader,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
{
|
||||
VkCommandBuffer command_buffer;
|
||||
GskVulkanImage *self;
|
||||
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (command_pool);
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (uploader->command_pool);
|
||||
|
||||
self = gsk_vulkan_image_new (context,
|
||||
self = gsk_vulkan_image_new (uploader->vulkan,
|
||||
width,
|
||||
height,
|
||||
VK_IMAGE_TILING_LINEAR,
|
||||
@ -446,7 +484,7 @@ gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
|
||||
}
|
||||
});
|
||||
|
||||
gsk_vulkan_command_pool_submit_buffer (command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
gsk_vulkan_command_pool_submit_buffer (uploader->command_pool, command_buffer, VK_NULL_HANDLE);
|
||||
|
||||
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
|
||||
@ -454,19 +492,18 @@ gsk_vulkan_image_new_from_data_directly (GdkVulkanContext *context,
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
|
||||
GskVulkanCommandPool *command_pool,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
gsk_vulkan_image_new_from_data (GskVulkanUploader *uploader,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize stride)
|
||||
{
|
||||
if (GSK_RENDER_MODE_CHECK (STAGING_BUFFER))
|
||||
return gsk_vulkan_image_new_from_data_via_staging_buffer (context, command_pool, data, width, height, stride);
|
||||
return gsk_vulkan_image_new_from_data_via_staging_buffer (uploader, data, width, height, stride);
|
||||
if (GSK_RENDER_MODE_CHECK (STAGING_IMAGE))
|
||||
return gsk_vulkan_image_new_from_data_via_staging_image (context, command_pool, data, width, height, stride);
|
||||
return gsk_vulkan_image_new_from_data_via_staging_image (uploader, data, width, height, stride);
|
||||
else
|
||||
return gsk_vulkan_image_new_from_data_directly (context, command_pool, data, width, height, stride);
|
||||
return gsk_vulkan_image_new_from_data_directly (uploader, data, width, height, stride);
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
|
@ -7,17 +7,24 @@
|
||||
|
||||
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);
|
||||
|
||||
GskVulkanImage * gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
|
||||
VkImage image,
|
||||
VkFormat format,
|
||||
gsize width,
|
||||
gsize height);
|
||||
GskVulkanImage * gsk_vulkan_image_new_from_data (GdkVulkanContext *context,
|
||||
GskVulkanCommandPool *pool,
|
||||
GskVulkanImage * gsk_vulkan_image_new_from_data (GskVulkanUploader *uploader,
|
||||
guchar *data,
|
||||
gsize width,
|
||||
gsize height,
|
||||
|
@ -29,6 +29,7 @@ struct _GskVulkanRender
|
||||
VkFence fence;
|
||||
VkRenderPass render_pass;
|
||||
GskVulkanPipelineLayout *layout;
|
||||
GskVulkanUploader *uploader;
|
||||
|
||||
GHashTable *descriptor_set_indexes;
|
||||
VkDescriptorPool descriptor_pool;
|
||||
@ -155,6 +156,8 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
|
||||
self->layout = gsk_vulkan_pipeline_layout_new (self->vulkan);
|
||||
|
||||
self->uploader = gsk_vulkan_uploader_new (self->vulkan, self->command_pool);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -235,7 +238,7 @@ gsk_vulkan_render_upload (GskVulkanRender *self)
|
||||
|
||||
for (l = self->render_passes; l; l = l->next)
|
||||
{
|
||||
gsk_vulkan_render_pass_upload (l->data, self, self->command_pool);
|
||||
gsk_vulkan_render_pass_upload (l->data, self, self->uploader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,6 +518,8 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
|
||||
1,
|
||||
&self->fence);
|
||||
|
||||
gsk_vulkan_uploader_reset (self->uploader);
|
||||
|
||||
gsk_vulkan_command_pool_reset (self->command_pool);
|
||||
|
||||
g_hash_table_remove_all (self->descriptor_set_indexes);
|
||||
@ -556,6 +561,8 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
for (i = 0; i < GSK_VULKAN_N_PIPELINES; i++)
|
||||
g_clear_object (&self->pipelines[i]);
|
||||
|
||||
g_clear_pointer (&self->uploader, gsk_vulkan_uploader_free);
|
||||
|
||||
g_clear_pointer (&self->layout, gsk_vulkan_pipeline_layout_unref);
|
||||
|
||||
vkDestroyRenderPass (device,
|
||||
|
@ -269,9 +269,9 @@ gsk_vulkan_renderer_clear_texture (gpointer p)
|
||||
}
|
||||
|
||||
GskVulkanImage *
|
||||
gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
GskTexture *texture,
|
||||
GskVulkanCommandPool *command_pool)
|
||||
gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
GskTexture *texture,
|
||||
GskVulkanUploader *uploader)
|
||||
{
|
||||
GskVulkanTextureData *data;
|
||||
cairo_surface_t *surface;
|
||||
@ -282,8 +282,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
return g_object_ref (data->image);
|
||||
|
||||
surface = gsk_texture_download (texture);
|
||||
image = gsk_vulkan_image_new_from_data (self->vulkan,
|
||||
command_pool,
|
||||
image = gsk_vulkan_image_new_from_data (uploader,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
|
@ -23,7 +23,7 @@ GType gsk_vulkan_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GskVulkanImage * gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
|
||||
GskTexture *texture,
|
||||
GskVulkanCommandPool *command_pool);
|
||||
GskVulkanUploader *uploader);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -176,7 +176,7 @@ static void
|
||||
gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
GskVulkanOpRender *op,
|
||||
GskVulkanRender *render,
|
||||
GskVulkanCommandPool *command_pool)
|
||||
GskVulkanUploader *uploader)
|
||||
{
|
||||
graphene_rect_t bounds;
|
||||
cairo_surface_t *surface;
|
||||
@ -194,8 +194,7 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
op->source = gsk_vulkan_image_new_from_data (self->vulkan,
|
||||
command_pool,
|
||||
op->source = gsk_vulkan_image_new_from_data (uploader,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
@ -209,7 +208,7 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
void
|
||||
gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
GskVulkanCommandPool *command_pool)
|
||||
GskVulkanUploader *uploader)
|
||||
{
|
||||
GskVulkanOp *op;
|
||||
guint i;
|
||||
@ -221,14 +220,13 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
switch (op->type)
|
||||
{
|
||||
case GSK_VULKAN_OP_FALLBACK:
|
||||
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, command_pool);
|
||||
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader);
|
||||
break;
|
||||
|
||||
case GSK_VULKAN_OP_SURFACE:
|
||||
{
|
||||
cairo_surface_t *surface = gsk_cairo_node_get_surface (op->render.node);
|
||||
op->render.source = gsk_vulkan_image_new_from_data (self->vulkan,
|
||||
command_pool,
|
||||
op->render.source = gsk_vulkan_image_new_from_data (uploader,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
@ -241,7 +239,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
{
|
||||
op->render.source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)),
|
||||
gsk_texture_node_get_texture (op->render.node),
|
||||
command_pool);
|
||||
uploader);
|
||||
gsk_vulkan_render_add_cleanup_image (render, op->render.source);
|
||||
}
|
||||
break;
|
||||
|
@ -21,7 +21,7 @@ void gsk_vulkan_render_pass_add (GskVulk
|
||||
|
||||
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||
GskVulkanRender *render,
|
||||
GskVulkanCommandPool *command_pool);
|
||||
GskVulkanUploader *uploader);
|
||||
|
||||
gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self);
|
||||
gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
|
||||
|
Loading…
Reference in New Issue
Block a user