diff --git a/include/render/vulkan.h b/include/render/vulkan.h index e06dc3be8..733bc26e8 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -193,6 +193,7 @@ struct wlr_vk_render_format_setup { struct wl_list link; // wlr_vk_renderer.render_format_setups const struct wlr_vk_format *render_format; // used in renderpass bool has_blending_buffer; + bool clear_on_load; VkRenderPass render_pass; VkPipeline output_pipe; @@ -311,7 +312,7 @@ struct wlr_vk_texture_view { struct wlr_vk_render_format_setup *find_or_create_render_setup( struct wlr_vk_renderer *renderer, const struct wlr_vk_format *format, - bool has_blending_buffer); + bool has_blending_buffer, bool clear_on_load); struct wlr_vk_pipeline *setup_get_or_create_pipeline( struct wlr_vk_render_format_setup *setup, const struct wlr_vk_pipeline_key *key); @@ -350,7 +351,7 @@ struct wlr_vk_render_pass { }; struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_buffer *buffer); + struct wlr_vk_render_buffer *buffer, const struct wlr_render_color *clear_color); // Suballocates a buffer span with the given size that can be mapped // and used as staging buffer. The allocation is implicitly released when the diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 9cbb3156a..4f3032808 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -650,7 +650,7 @@ static const struct wlr_render_pass_impl render_pass_impl = { }; struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_buffer *buffer) { + struct wlr_vk_render_buffer *buffer, const struct wlr_render_color *clear_color) { struct wlr_vk_render_pass *pass = calloc(1, sizeof(*pass)); if (pass == NULL) { return NULL; @@ -662,7 +662,7 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend bool has_blending_buffer = buffer->blend_image != VK_NULL_HANDLE; struct wlr_vk_render_format_setup *render_setup = find_or_create_render_setup( - renderer, buffer->fmt, has_blending_buffer); + renderer, buffer->fmt, has_blending_buffer, clear_color != NULL); if (render_setup == NULL) { free(pass); return NULL; @@ -697,6 +697,17 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend VkRect2D rect = { .extent = { width, height } }; VkImageView attachments[2] = {0}; uint32_t attachment_count = 0; + VkClearValue clear_values[2] = { 0 }; + if (clear_color) { + clear_values[0] = clear_values[1] = (VkClearValue){ + .color.float32 = { + color_to_linear(clear_color->r), + color_to_linear(clear_color->g), + color_to_linear(clear_color->b), + clear_color->a, + } + }; + } if (buffer->blend_image_view != VK_NULL_HANDLE) { attachments[attachment_count++] = buffer->blend_image_view; @@ -714,7 +725,8 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend .renderArea = rect, .renderPass = render_setup->render_pass, .framebuffer = framebuffer->vk, - .clearValueCount = 0, + .clearValueCount = clear_color ? attachment_count : 0, + .pClearValues = clear_values, }; vkCmdBeginRenderPass(cb->vk, &rp_info, VK_SUBPASS_CONTENTS_INLINE); diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 4cfccd5f8..1578ffbcf 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -1287,18 +1287,15 @@ static struct wlr_render_pass *vulkan_begin_buffer_pass(struct wlr_renderer *wlr } } - struct wlr_vk_render_pass *render_pass = vulkan_begin_render_pass(renderer, render_buffer); + const struct wlr_render_color *clear_color = NULL; + if (options->clear_buffer) { + clear_color = &options->clear_color; + } + + struct wlr_vk_render_pass *render_pass = vulkan_begin_render_pass(renderer, render_buffer, clear_color); if (render_pass == NULL) { return NULL; } - // TODO: switch to using `VkRenderPassBeginInfo.pClearValues` - if (options->clear_buffer) { - wlr_render_pass_add_rect(&render_pass->base, &(struct wlr_render_rect_options){ - .box = { .width = buffer->width, .height = buffer->height }, - .color = options->clear_color, - .blend_mode = WLR_RENDER_BLEND_MODE_NONE, - }); - } return &render_pass->base; } @@ -1869,10 +1866,10 @@ static bool init_static_render_data(struct wlr_vk_renderer *renderer) { struct wlr_vk_render_format_setup *find_or_create_render_setup( struct wlr_vk_renderer *renderer, const struct wlr_vk_format *format, - bool has_blending_buffer) { + bool has_blending_buffer, bool clear_on_load) { struct wlr_vk_render_format_setup *setup; wl_list_for_each(setup, &renderer->render_format_setups, link) { - if (setup->render_format == format && setup->has_blending_buffer == has_blending_buffer) { + if (setup->render_format == format && setup->has_blending_buffer == has_blending_buffer && setup->clear_on_load == clear_on_load) { return setup; } } @@ -1885,19 +1882,21 @@ struct wlr_vk_render_format_setup *find_or_create_render_setup( setup->render_format = format; setup->has_blending_buffer = has_blending_buffer; + setup->clear_on_load = clear_on_load; setup->renderer = renderer; wl_list_init(&setup->pipelines); wl_list_init(&setup->framebuffers); VkDevice dev = renderer->dev->dev; VkResult res; + VkAttachmentLoadOp load_op = clear_on_load ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; if (has_blending_buffer) { VkAttachmentDescription attachments[2] = { { .format = VK_FORMAT_R16G16B16A16_SFLOAT, .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = load_op, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -1907,7 +1906,7 @@ struct wlr_vk_render_format_setup *find_or_create_render_setup( { .format = format->vk, .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = load_op, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, @@ -2013,7 +2012,7 @@ struct wlr_vk_render_format_setup *find_or_create_render_setup( VkAttachmentDescription attachment = { .format = format->vk_srgb, .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .loadOp = load_op, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,