vulkan: Split renderpass op into 2

Add an explicit begin() and an end() op. For now, this looks like
overkill, but it allows doing renderpasses with custom ops that are not
meant to render a rendernode.

Examples for this are pre/postprocessing passes or 2-pass blur.
This commit is contained in:
Benjamin Otte 2023-07-19 00:31:48 +02:00
parent 4311d17cb1
commit cd84f5a56e
3 changed files with 75 additions and 49 deletions

View File

@ -491,19 +491,32 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
GskVulkanDownloadFunc download_func, GskVulkanDownloadFunc download_func,
gpointer download_data) gpointer download_data)
{ {
GskVulkanRenderPass *render_pass;
graphene_vec2_t scale; graphene_vec2_t scale;
cairo_rectangle_int_t extents; cairo_rectangle_int_t extents;
graphene_vec2_init (&scale, self->scale, self->scale); graphene_vec2_init (&scale, self->scale, self->scale);
cairo_region_get_extents (self->clip, &extents); cairo_region_get_extents (self->clip, &extents);
gsk_vulkan_render_pass_op (self, gsk_vulkan_render_pass_begin_op (self,
g_object_ref (self->target), g_object_ref (self->target),
&extents, &extents,
&self->viewport.size,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
render_pass = gsk_vulkan_render_pass_new ();
gsk_vulkan_render_pass_add (render_pass,
self,
&scale, &scale,
&self->viewport, &self->viewport,
node, &extents,
VK_IMAGE_LAYOUT_UNDEFINED, node);
gsk_vulkan_render_pass_free (render_pass);
gsk_vulkan_render_pass_end_op (self,
g_object_ref (self->target),
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
if (download_func) if (download_func)

View File

@ -241,41 +241,35 @@ static const GskVulkanOpClass GSK_VULKAN_RENDER_PASS_END_OP_CLASS = {
}; };
void void
gsk_vulkan_render_pass_op (GskVulkanRender *render, gsk_vulkan_render_pass_begin_op (GskVulkanRender *render,
GskVulkanImage *image, GskVulkanImage *image,
cairo_rectangle_int_t *area, const cairo_rectangle_int_t *area,
const graphene_vec2_t *scale, const graphene_size_t *viewport_size,
const graphene_rect_t *viewport,
GskRenderNode *node,
VkImageLayout initial_layout, VkImageLayout initial_layout,
VkImageLayout final_layout) VkImageLayout final_layout)
{ {
GskVulkanRenderPassOp *self; GskVulkanRenderPassOp *self;
GskVulkanRenderPassEndOp *end;
GskVulkanRenderPass *render_pass;
self = (GskVulkanRenderPassOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_OP_CLASS); self = (GskVulkanRenderPassOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_OP_CLASS);
self->image = image; self->image = g_object_ref (image);
self->initial_layout = initial_layout; self->initial_layout = initial_layout;
self->final_layout = final_layout; self->final_layout = final_layout;
self->area = *area; self->area = *area;
self->viewport_size = viewport->size; self->viewport_size = *viewport_size;
}
render_pass = gsk_vulkan_render_pass_new (); void
/* This invalidates the self pointer */ gsk_vulkan_render_pass_end_op (GskVulkanRender *render,
gsk_vulkan_render_pass_add (render_pass, GskVulkanImage *image,
render, VkImageLayout final_layout)
scale, {
viewport, GskVulkanRenderPassEndOp *self;
area,
node);
gsk_vulkan_render_pass_free (render_pass);
end = (GskVulkanRenderPassEndOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_END_OP_CLASS); self = (GskVulkanRenderPassEndOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_RENDER_PASS_END_OP_CLASS);
end->image = g_object_ref (image); self->image = g_object_ref (image);
end->final_layout = final_layout; self->final_layout = final_layout;
} }
GskVulkanImage * GskVulkanImage *
@ -284,6 +278,7 @@ gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
const graphene_rect_t *viewport, const graphene_rect_t *viewport,
GskRenderNode *node) GskRenderNode *node)
{ {
GskVulkanRenderPass *render_pass;
GdkVulkanContext *context; GdkVulkanContext *context;
graphene_rect_t view; graphene_rect_t view;
GskVulkanImage *image; GskVulkanImage *image;
@ -302,18 +297,33 @@ gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
gsk_render_node_get_preferred_depth (node)), gsk_render_node_get_preferred_depth (node)),
view.size.width, view.size.height); view.size.width, view.size.height);
gsk_vulkan_render_pass_op (render, gsk_vulkan_render_pass_begin_op (render,
image, image,
&(cairo_rectangle_int_t) { &(cairo_rectangle_int_t) {
0, 0, 0, 0,
gsk_vulkan_image_get_width (image), gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image) gsk_vulkan_image_get_height (image)
}, },
scale, &viewport->size,
&view,
node,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
render_pass = gsk_vulkan_render_pass_new ();
gsk_vulkan_render_pass_add (render_pass,
render,
scale,
viewport,
&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (image),
gsk_vulkan_image_get_height (image)
},
node);
gsk_vulkan_render_pass_free (render_pass);
gsk_vulkan_render_pass_end_op (render,
image,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
return image; return image;
} }

View File

@ -4,14 +4,17 @@
G_BEGIN_DECLS G_BEGIN_DECLS
void gsk_vulkan_render_pass_op (GskVulkanRender *render,
void gsk_vulkan_render_pass_begin_op (GskVulkanRender *render,
GskVulkanImage *image, GskVulkanImage *image,
cairo_rectangle_int_t *area, const cairo_rectangle_int_t *area,
const graphene_vec2_t *scale, const graphene_size_t *viewport_size,
const graphene_rect_t *viewport,
GskRenderNode *node,
VkImageLayout initial_layout, VkImageLayout initial_layout,
VkImageLayout final_layout); VkImageLayout final_layout);
void gsk_vulkan_render_pass_end_op (GskVulkanRender *render,
GskVulkanImage *image,
VkImageLayout final_layout);
GskVulkanImage * gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render, GskVulkanImage * gsk_vulkan_render_pass_op_offscreen (GskVulkanRender *render,
const graphene_vec2_t *scale, const graphene_vec2_t *scale,
const graphene_rect_t *viewport, const graphene_rect_t *viewport,