From 4b2b239550ac8f042ab12a9e23dff83b623c88aa Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 14 May 2023 04:12:14 +0200 Subject: [PATCH] vulkan: Only draw one rect Instead of emitting the render commands once per rectangle of the clip region, just emit them once with the region's extents. This is generally faster because it emits fewer commands to the GPU, even though it may touch significantly more pixels. For a proper method, we'd need to record the commands per clip rectangle instead of emitting all of them all the time. --- gsk/vulkan/gskvulkanrenderpass.c | 59 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c index 4004570029..223ee00e78 100644 --- a/gsk/vulkan/gskvulkanrenderpass.c +++ b/gsk/vulkan/gskvulkanrenderpass.c @@ -2410,7 +2410,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, VkPipelineLayout pipeline_layout, VkCommandBuffer command_buffer) { - guint i; + cairo_rectangle_int_t rect; vkCmdSetViewport (command_buffer, 0, @@ -2424,38 +2424,33 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, .maxDepth = 1 }); - for (i = 0; i < cairo_region_num_rectangles (self->clip); i++) - { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (self->clip, i, &rect); - - vkCmdSetScissor (command_buffer, - 0, - 1, - &(VkRect2D) { - { rect.x, rect.y }, - { rect.width, rect.height } - }); - - vkCmdBeginRenderPass (command_buffer, - &(VkRenderPassBeginInfo) { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = self->render_pass, - .framebuffer = gsk_vulkan_render_get_framebuffer (render, self->target), - .renderArea = { - { rect.x, rect.y }, - { rect.width, rect.height } - }, - .clearValueCount = 1, - .pClearValues = (VkClearValue [1]) { - { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } } - } + cairo_region_get_extents (self->clip, &rect); + + vkCmdSetScissor (command_buffer, + 0, + 1, + &(VkRect2D) { + { rect.x, rect.y }, + { rect.width, rect.height } + }); + + vkCmdBeginRenderPass (command_buffer, + &(VkRenderPassBeginInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = self->render_pass, + .framebuffer = gsk_vulkan_render_get_framebuffer (render, self->target), + .renderArea = { + { rect.x, rect.y }, + { rect.width, rect.height } }, - VK_SUBPASS_CONTENTS_INLINE); + .clearValueCount = 1, + .pClearValues = (VkClearValue [1]) { + { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } } + } + }, + VK_SUBPASS_CONTENTS_INLINE); - gsk_vulkan_render_pass_draw_rect (self, render, pipeline_layout, command_buffer); + gsk_vulkan_render_pass_draw_rect (self, render, pipeline_layout, command_buffer); - vkCmdEndRenderPass (command_buffer); - } + vkCmdEndRenderPass (command_buffer); } -- 2.30.2