From d21ac8017832af5891eded648fdacf0dc071568d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 00:12:13 +0200 Subject: [PATCH 1/6] gpu: Simplify a function Now that we only ever use 2 images max per shader due to the removal of the ubershader, we can just hardcode it in the function. --- gsk/gpu/gskgpunodeprocessor.c | 92 +++++++++++++++++------------------ 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 2ae86aa948d..17be0ef8c09 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -302,30 +302,20 @@ gsk_gpu_node_processor_add_image (GskGpuNodeProcessor *self, } static void -gsk_gpu_node_processor_add_images (GskGpuNodeProcessor *self, - gsize n_images, - GskGpuImage **images, - GskGpuSampler *samplers, - guint32 *out_descriptors) +gsk_gpu_node_processor_add_two_images (GskGpuNodeProcessor *self, + GskGpuImage *image1, + GskGpuSampler sampler1, + GskGpuImage *image2, + GskGpuSampler sampler2, + guint32 *out_descriptors) { GskGpuDescriptors *desc; - gsize i; - - g_assert (n_images > 0); - /* note: This will infloop if more images are requested than can fit into an empty descriptors, - * so don't do that. */ do { - out_descriptors[0] = gsk_gpu_node_processor_add_image (self, images[0], samplers[0]); + out_descriptors[0] = gsk_gpu_node_processor_add_image (self, image1, sampler1); desc = self->desc; - - for (i = 1; i < n_images; i++) - { - out_descriptors[i] = gsk_gpu_node_processor_add_image (self, images[i], samplers[i]); - if (desc != self->desc) - break; - } + out_descriptors[1] = gsk_gpu_node_processor_add_image (self, image2, sampler2); } while (desc != self->desc); } @@ -1079,11 +1069,12 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel (float[4]) { 1, 1, 1, 1 }); gsk_gpu_node_processor_finish_draw (&other, mask_image); - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { child_image, mask_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + child_image, + GSK_GPU_SAMPLER_DEFAULT, + mask_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_node_processor_sync_globals (self, 0); gsk_gpu_mask_op (self->frame, @@ -2609,11 +2600,12 @@ gsk_gpu_node_processor_add_blend_node (GskGpuNodeProcessor *self, top_rect = *graphene_rect_zero (); } - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { bottom_image, top_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + bottom_image, + GSK_GPU_SAMPLER_DEFAULT, + top_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_blend_mode_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), @@ -2686,11 +2678,12 @@ gsk_gpu_node_processor_add_cross_fade_node (GskGpuNodeProcessor *self, return; } - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { start_image, end_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + start_image, + GSK_GPU_SAMPLER_DEFAULT, + end_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_cross_fade_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), @@ -2766,11 +2759,12 @@ gsk_gpu_node_processor_add_mask_node (GskGpuNodeProcessor *self, g_object_unref (mask_image); return; } - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { source_image, mask_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + source_image, + GSK_GPU_SAMPLER_DEFAULT, + mask_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_mask_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds), @@ -3215,11 +3209,12 @@ gsk_gpu_node_processor_add_fill_node (GskGpuNodeProcessor *self, if (source_image == NULL) return; - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { source_image, mask_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + source_image, + GSK_GPU_SAMPLER_DEFAULT, + mask_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_mask_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &clip_bounds), @@ -3312,11 +3307,12 @@ gsk_gpu_node_processor_add_stroke_node (GskGpuNodeProcessor *self, if (source_image == NULL) return; - gsk_gpu_node_processor_add_images (self, - 2, - (GskGpuImage *[2]) { source_image, mask_image }, - (GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT }, - descriptors); + gsk_gpu_node_processor_add_two_images (self, + source_image, + GSK_GPU_SAMPLER_DEFAULT, + mask_image, + GSK_GPU_SAMPLER_DEFAULT, + descriptors); gsk_gpu_mask_op (self->frame, gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &clip_bounds), -- GitLab From 3cf5e8cf4e405cfc2ed97fddaee6afc5f4ad27c6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 20:15:26 +0200 Subject: [PATCH 2/6] gpu: Move gc calls further to the edges of the function Make the function look like that: 1. handle special case 2. maybe GC 3. draw 4. queue next gc 5. cleanup This seems like the sanest approach to avoid gc() collecting things necessary for drawing in the future. And I need to refactor stuff, so having it out of the way is a good idea. --- gsk/gpu/gskgpurenderer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gsk/gpu/gskgpurenderer.c b/gsk/gpu/gskgpurenderer.c index 1ec4bbd0daf..abef2819acf 100644 --- a/gsk/gpu/gskgpurenderer.c +++ b/gsk/gpu/gskgpurenderer.c @@ -416,12 +416,12 @@ gsk_gpu_renderer_render (GskRenderer *renderer, return; } + gsk_gpu_device_maybe_gc (priv->device); + depth = gsk_render_node_get_preferred_depth (root); gdk_draw_context_begin_frame_full (priv->context, depth, region); - gsk_gpu_device_maybe_gc (priv->device); - gsk_gpu_renderer_make_current (self); backbuffer = GSK_GPU_RENDERER_GET_CLASS (self)->get_backbuffer (self); @@ -443,10 +443,10 @@ gsk_gpu_renderer_render (GskRenderer *renderer, ), NULL); - gsk_gpu_device_queue_gc (priv->device); - gdk_draw_context_end_frame (priv->context); + gsk_gpu_device_queue_gc (priv->device); + g_clear_pointer (&render_region, cairo_region_destroy); } -- GitLab From 15804906701194bb70371722c561bc2a9aac8b26 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 21:05:23 +0200 Subject: [PATCH 3/6] gpu: add gsk_gpu_frame_begin/end() These are just factoring out gdk_draw_context_begin/end_frame() so I can add one tiny thing there later. And I did both even though I only need one, because it felt wrong to just do one. --- gsk/gpu/gskgpuframe.c | 35 +++++++++++++++++++++++++++++++++++ gsk/gpu/gskgpuframeprivate.h | 13 +++++++++++++ gsk/gpu/gskgpurenderer.c | 8 ++++---- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index fddfdeccbd5..2e902bba882 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -16,6 +16,7 @@ #include "gskrendererprivate.h" #include "gdk/gdkdmabufdownloaderprivate.h" +#include "gdk/gdkdrawcontextprivate.h" #include "gdk/gdktexturedownloaderprivate.h" #define DEFAULT_VERTEX_BUFFER_SIZE 128 * 1024 @@ -75,6 +76,22 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self) priv->last_op = NULL; } +static void +gsk_gpu_frame_default_begin (GskGpuFrame *self, + GdkDrawContext *context, + GdkMemoryDepth depth, + const cairo_region_t *region) +{ + gdk_draw_context_begin_frame_full (context, depth, region); +} + +static void +gsk_gpu_frame_default_end (GskGpuFrame *self, + GdkDrawContext *context) +{ + gdk_draw_context_end_frame (context); +} + static void gsk_gpu_frame_cleanup (GskGpuFrame *self) { @@ -126,6 +143,8 @@ gsk_gpu_frame_class_init (GskGpuFrameClass *klass) klass->setup = gsk_gpu_frame_default_setup; klass->cleanup = gsk_gpu_frame_default_cleanup; + klass->begin = gsk_gpu_frame_default_begin; + klass->end = gsk_gpu_frame_default_end; klass->upload_texture = gsk_gpu_frame_default_upload_texture; object_class->dispose = gsk_gpu_frame_dispose; @@ -156,6 +175,22 @@ gsk_gpu_frame_setup (GskGpuFrame *self, GSK_GPU_FRAME_GET_CLASS (self)->setup (self); } +void +gsk_gpu_frame_begin (GskGpuFrame *self, + GdkDrawContext *context, + GdkMemoryDepth depth, + const cairo_region_t *region) +{ + GSK_GPU_FRAME_GET_CLASS (self)->begin (self, context, depth, region); +} + +void +gsk_gpu_frame_end (GskGpuFrame *self, + GdkDrawContext *context) +{ + GSK_GPU_FRAME_GET_CLASS (self)->end (self, context); +} + GskGpuDevice * gsk_gpu_frame_get_device (GskGpuFrame *self) { diff --git a/gsk/gpu/gskgpuframeprivate.h b/gsk/gpu/gskgpuframeprivate.h index 90a7eef2b62..2a65ab6e45d 100644 --- a/gsk/gpu/gskgpuframeprivate.h +++ b/gsk/gpu/gskgpuframeprivate.h @@ -27,6 +27,12 @@ struct _GskGpuFrameClass void (* wait) (GskGpuFrame *self); void (* setup) (GskGpuFrame *self); void (* cleanup) (GskGpuFrame *self); + void (* begin) (GskGpuFrame *self, + GdkDrawContext *context, + GdkMemoryDepth depth, + const cairo_region_t *region); + void (* end) (GskGpuFrame *self, + GdkDrawContext *context); GskGpuImage * (* upload_texture) (GskGpuFrame *self, gboolean with_mipmap, GdkTexture *texture); @@ -48,6 +54,13 @@ void gsk_gpu_frame_setup (GskGpuF GskGpuDevice *device, GskGpuOptimizations optimizations); +void gsk_gpu_frame_begin (GskGpuFrame *self, + GdkDrawContext *context, + GdkMemoryDepth depth, + const cairo_region_t *region); +void gsk_gpu_frame_end (GskGpuFrame *self, + GdkDrawContext *context); + GdkDrawContext * gsk_gpu_frame_get_context (GskGpuFrame *self) G_GNUC_PURE; GskGpuDevice * gsk_gpu_frame_get_device (GskGpuFrame *self) G_GNUC_PURE; gint64 gsk_gpu_frame_get_timestamp (GskGpuFrame *self) G_GNUC_PURE; diff --git a/gsk/gpu/gskgpurenderer.c b/gsk/gpu/gskgpurenderer.c index abef2819acf..2e35bb5d2f0 100644 --- a/gsk/gpu/gskgpurenderer.c +++ b/gsk/gpu/gskgpurenderer.c @@ -419,16 +419,16 @@ gsk_gpu_renderer_render (GskRenderer *renderer, gsk_gpu_device_maybe_gc (priv->device); depth = gsk_render_node_get_preferred_depth (root); + frame = gsk_gpu_renderer_get_frame (self); + scale = gsk_gpu_renderer_get_scale (self); - gdk_draw_context_begin_frame_full (priv->context, depth, region); + gsk_gpu_frame_begin (frame, priv->context, depth, region); gsk_gpu_renderer_make_current (self); backbuffer = GSK_GPU_RENDERER_GET_CLASS (self)->get_backbuffer (self); - frame = gsk_gpu_renderer_get_frame (self); render_region = get_render_region (self); - scale = gsk_gpu_renderer_get_scale (self); gsk_gpu_frame_render (frame, g_get_monotonic_time (), @@ -443,7 +443,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer, ), NULL); - gdk_draw_context_end_frame (priv->context); + gsk_gpu_frame_end (frame, priv->context); gsk_gpu_device_queue_gc (priv->device); -- GitLab From 4966f8cdf8234b3e1a9cf23534e581797d806a04 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 22:13:04 +0200 Subject: [PATCH 4/6] vulkan: Add an acquire semaphore to frames Vulkan requires us waiting on the image acquired from vkAcquireNextImageKHR() before we start rendering to it, as that function is allowed to return images that are still in use by the compositor. Because of that requirement, vkAcquireNextImageKHR() requires a semaphore or fence to be passed that it can signal once it's done. We now use a side channel to begin_frame() - calling set_draw_semaphore() - to pass that semaphore so that the vkAcquireNextImageKHR() call inside begin_frame() can use it, and then we can wait on it later when we submit. And yes, this is insanely convoluted, the Vulkan developers should totally have thought about GTK's internal designs before coming up with that idea. --- gdk/gdkvulkancontext.c | 33 ++++++++++++++++++++++++++++++++- gdk/gdkvulkancontextprivate.h | 3 +++ gsk/gpu/gskvulkanframe.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 9f536c6bfc2..ec721d53a15 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -80,6 +80,8 @@ struct _GdkVulkanContextPrivate { guint n_images; VkImage *images; cairo_region_t **regions; + + VkSemaphore draw_semaphore; #endif guint32 draw_index; @@ -638,6 +640,8 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, VkResult acquire_result; guint i; + g_assert (priv->draw_semaphore != NULL); + color_state = gdk_surface_get_color_state (surface); depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (color_state)); @@ -670,7 +674,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, acquire_result = GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context), priv->swapchain, UINT64_MAX, - VK_NULL_HANDLE, + priv->draw_semaphore, VK_NULL_HANDLE, &priv->draw_index); if ((acquire_result == VK_ERROR_OUT_OF_DATE_KHR) || @@ -690,6 +694,8 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, break; } + priv->draw_semaphore = NULL; + cairo_region_union (region, priv->regions[priv->draw_index]); if (priv->current_depth == GDK_MEMORY_U8_SRGB) @@ -1367,6 +1373,31 @@ gdk_vulkan_context_get_draw_index (GdkVulkanContext *context) return priv->draw_index; } +/** + * gdk_vulkan_context_set_draw_semaphore: + * @context: a `GdkVulkanContext` + * @semaphore: a `VkSemaphore` + * + * Sets the Vulkan semaphore that will be used in the immediately following + * gdk_draw_context_begin_frame() call. + * This is essentially an extra argument for that call, but without extending the + * arguments of that generic function with Vulkan-specific things. + * + * This function must be called or begin_frame() will abort. + */ +void +gdk_vulkan_context_set_draw_semaphore (GdkVulkanContext *context, + VkSemaphore semaphore) +{ + GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context); + + g_return_if_fail (GDK_IS_VULKAN_CONTEXT (context)); + g_return_if_fail (!gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context))); + g_return_if_fail (priv->draw_semaphore == NULL); + + priv->draw_semaphore = semaphore; +} + static gboolean gdk_display_create_vulkan_device (GdkDisplay *display, GError **error) diff --git a/gdk/gdkvulkancontextprivate.h b/gdk/gdkvulkancontextprivate.h index c98771eb8f0..c0ad9578982 100644 --- a/gdk/gdkvulkancontextprivate.h +++ b/gdk/gdkvulkancontextprivate.h @@ -100,6 +100,9 @@ VkImage gdk_vulkan_context_get_image (GdkVulk guint id); uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context); +void gdk_vulkan_context_set_draw_semaphore (GdkVulkanContext *context, + VkSemaphore semaphore); + #else /* !GDK_RENDERING_VULKAN */ diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index 52a0cab80ec..733065decd6 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -46,6 +46,7 @@ struct _GskVulkanFrame { GskGpuFrame parent_instance; + VkSemaphore vk_acquire_semaphore; VkFence vk_fence; VkCommandBuffer vk_command_buffer; VkDescriptorPool vk_descriptor_pool; @@ -111,6 +112,13 @@ gsk_vulkan_frame_setup (GskGpuFrame *frame) }, &self->vk_command_buffer); + GDK_VK_CHECK (vkCreateSemaphore, vk_device, + &(VkSemaphoreCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + }, + NULL, + &self->vk_acquire_semaphore); + GSK_VK_CHECK (vkCreateFence, vk_device, &(VkFenceCreateInfo) { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, @@ -155,6 +163,18 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame) GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->cleanup (frame); } +static void +gsk_vulkan_frame_begin (GskGpuFrame *frame, + GdkDrawContext *context, + GdkMemoryDepth depth, + const cairo_region_t *region) +{ + GskVulkanFrame *self = GSK_VULKAN_FRAME (frame); + + gdk_vulkan_context_set_draw_semaphore (GDK_VULKAN_CONTEXT (context), self->vk_acquire_semaphore); + GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->begin (frame, context, depth, region); +} + static GskGpuImage * gsk_vulkan_frame_upload_texture (GskGpuFrame *frame, gboolean with_mipmap, @@ -373,6 +393,13 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame, gsk_pipeline_stages_init (&semaphores.wait_stages); gsk_semaphores_init (&semaphores.signal_semaphores); + if (pass_type == GSK_RENDER_PASS_PRESENT) + { + gsk_vulkan_semaphores_add_wait (&semaphores, + self->vk_acquire_semaphore, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + } + state.vk_command_buffer = self->vk_command_buffer; state.vk_render_pass = VK_NULL_HANDLE; state.vk_format = VK_FORMAT_UNDEFINED; @@ -433,6 +460,9 @@ gsk_vulkan_frame_finalize (GObject *object) vkFreeCommandBuffers (vk_device, vk_command_pool, 1, &self->vk_command_buffer); + vkDestroySemaphore (vk_device, + self->vk_acquire_semaphore, + NULL); vkDestroyFence (vk_device, self->vk_fence, NULL); @@ -450,6 +480,7 @@ gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass) gpu_frame_class->wait = gsk_vulkan_frame_wait; gpu_frame_class->setup = gsk_vulkan_frame_setup; gpu_frame_class->cleanup = gsk_vulkan_frame_cleanup; + gpu_frame_class->begin = gsk_vulkan_frame_begin; gpu_frame_class->upload_texture = gsk_vulkan_frame_upload_texture; gpu_frame_class->create_descriptors = gsk_vulkan_frame_create_descriptors; gpu_frame_class->create_vertex_buffer = gsk_vulkan_frame_create_vertex_buffer; -- GitLab From ad218f0786674163410e74f3003d416f50b50f3b Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 22:17:05 +0200 Subject: [PATCH 5/6] gpu: Pass the pass to frame_submit() We will need that in the next commit. --- gsk/gpu/gskglframe.c | 7 ++++--- gsk/gpu/gskgpuframe.c | 10 +++++++--- gsk/gpu/gskgpuframeprivate.h | 1 + gsk/gpu/gskvulkanframe.c | 7 ++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/gsk/gpu/gskglframe.c b/gsk/gpu/gskglframe.c index a9939785ddb..eb4d2ca3866 100644 --- a/gsk/gpu/gskglframe.c +++ b/gsk/gpu/gskglframe.c @@ -169,9 +169,10 @@ gsk_gl_frame_create_storage_buffer (GskGpuFrame *frame, } static void -gsk_gl_frame_submit (GskGpuFrame *frame, - GskGpuBuffer *vertex_buffer, - GskGpuOp *op) +gsk_gl_frame_submit (GskGpuFrame *frame, + GskRenderPassType pass_type, + GskGpuBuffer *vertex_buffer, + GskGpuOp *op) { GskGLFrame *self = GSK_GL_FRAME (frame); GskGLCommandState state = { 0, }; diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index 2e902bba882..beb7a981e50 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -638,7 +638,8 @@ gsk_gpu_frame_record (GskGpuFrame *self, } static void -gsk_gpu_frame_submit (GskGpuFrame *self) +gsk_gpu_frame_submit (GskGpuFrame *self, + GskRenderPassType pass_type) { GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); @@ -662,6 +663,7 @@ gsk_gpu_frame_submit (GskGpuFrame *self) } GSK_GPU_FRAME_GET_CLASS (self)->submit (self, + pass_type, priv->vertex_buffer, priv->first_op); } @@ -676,11 +678,13 @@ gsk_gpu_frame_render (GskGpuFrame *self, const graphene_rect_t *viewport, GdkTexture **texture) { + GskRenderPassType pass_type = texture ? GSK_RENDER_PASS_EXPORT : GSK_RENDER_PASS_PRESENT; + gsk_gpu_frame_cleanup (self); gsk_gpu_frame_record (self, timestamp, target, target_color_state, region, node, viewport, texture); - gsk_gpu_frame_submit (self); + gsk_gpu_frame_submit (self, pass_type); } typedef struct _Download Download; @@ -745,6 +749,6 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self, .stride = stride }, sizeof (Download))); - gsk_gpu_frame_submit (self); + gsk_gpu_frame_submit (self, GSK_RENDER_PASS_EXPORT); g_object_unref (image); } diff --git a/gsk/gpu/gskgpuframeprivate.h b/gsk/gpu/gskgpuframeprivate.h index 2a65ab6e45d..9d120d68cf7 100644 --- a/gsk/gpu/gskgpuframeprivate.h +++ b/gsk/gpu/gskgpuframeprivate.h @@ -42,6 +42,7 @@ struct _GskGpuFrameClass GskGpuBuffer * (* create_storage_buffer) (GskGpuFrame *self, gsize size); void (* submit) (GskGpuFrame *self, + GskRenderPassType pass_type, GskGpuBuffer *vertex_buffer, GskGpuOp *op); }; diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index 733065decd6..266d7845058 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -361,9 +361,10 @@ gsk_vulkan_frame_create_storage_buffer (GskGpuFrame *frame, } static void -gsk_vulkan_frame_submit (GskGpuFrame *frame, - GskGpuBuffer *vertex_buffer, - GskGpuOp *op) +gsk_vulkan_frame_submit (GskGpuFrame *frame, + GskRenderPassType pass_type, + GskGpuBuffer *vertex_buffer, + GskGpuOp *op) { GskVulkanFrame *self = GSK_VULKAN_FRAME (frame); GskVulkanSemaphores semaphores; -- GitLab From 300639e537716ed4323c5ecf06e1655014b109e8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 17 Jul 2024 22:18:08 +0200 Subject: [PATCH 6/6] vulkan: Use right check for waiting on external image semaphore Commit 3aa6c27c264 changed the initial layout of imported dmabuf images, but did not adapt this check. --- gsk/gpu/gskvulkanimage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsk/gpu/gskvulkanimage.c b/gsk/gpu/gskvulkanimage.c index 5e28b8fa767..c11d326e31f 100644 --- a/gsk/gpu/gskvulkanimage.c +++ b/gsk/gpu/gskvulkanimage.c @@ -1440,7 +1440,7 @@ gsk_vulkan_image_transition (GskVulkanImage *self, self->vk_access == access) return; - if (self->vk_pipeline_stage == VK_IMAGE_LAYOUT_UNDEFINED && + if (self->vk_pipeline_stage == VK_IMAGE_LAYOUT_GENERAL && self->vk_semaphore) { gsk_vulkan_semaphores_add_wait (semaphores, self->vk_semaphore, stage); -- GitLab