From 0bcebf9930e4baada774a16c0e7637a22a410bb4 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 20 Nov 2021 00:36:52 +0200 Subject: [PATCH] Treat clear() with null parameter as invalidate Also use it in Sequence for postprocessor render targets, since postprocessors are supposed to render the entire screen. --- source/backends/opengl/commands_backend.cpp | 3 +++ source/backends/vulkan/commands_backend.cpp | 8 ++++---- source/backends/vulkan/commands_backend.h | 2 +- source/backends/vulkan/framebuffer_backend.cpp | 2 +- source/backends/vulkan/pipelinecache.cpp | 8 ++++---- source/backends/vulkan/pipelinecache.h | 2 +- source/backends/vulkan/pipelinestate_backend.cpp | 2 +- source/render/renderer.h | 5 ++++- source/render/sequence.cpp | 1 + 9 files changed, 20 insertions(+), 13 deletions(-) diff --git a/source/backends/opengl/commands_backend.cpp b/source/backends/opengl/commands_backend.cpp index 62d952e0..1ec19c13 100644 --- a/source/backends/opengl/commands_backend.cpp +++ b/source/backends/opengl/commands_backend.cpp @@ -36,6 +36,9 @@ void OpenGLCommands::clear(const ClearValue *values) if(!target) throw invalid_operation("OpenGLCommands::clear"); + if(!values) + return; + static Require _req(MSP_clear_buffer); pipeline_state->apply(); diff --git a/source/backends/vulkan/commands_backend.cpp b/source/backends/vulkan/commands_backend.cpp index 0134474b..684f0a47 100644 --- a/source/backends/vulkan/commands_backend.cpp +++ b/source/backends/vulkan/commands_backend.cpp @@ -55,7 +55,7 @@ void VulkanCommands::begin_buffer() vk.BeginCommandBuffer(current_buffer, begin_info); } -void VulkanCommands::begin_render_pass(const ClearValue *clear_values) +void VulkanCommands::begin_render_pass(bool clear, const ClearValue *clear_values) { const Framebuffer *target = pipeline_state->get_framebuffer(); if(!target) @@ -69,7 +69,7 @@ void VulkanCommands::begin_render_pass(const ClearValue *clear_values) device.get_transfer_queue().dispatch_transfers(current_buffer); // TODO Use proper value for to_present - render_pass = device.get_pipeline_cache().get_render_pass(target->get_format(), clear_values, true); + VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(target->get_format(), clear, !clear_values, true); target->refresh(); @@ -194,7 +194,7 @@ void VulkanCommands::clear(const ClearValue *values) if(render_pass) throw invalid_operation("VulkanCommands::clear"); - begin_render_pass(values); + begin_render_pass(true, values); } void VulkanCommands::draw(const Batch &batch) @@ -210,7 +210,7 @@ void VulkanCommands::draw_instanced(const Batch &batch, unsigned count) const VulkanFunctions &vk = device.get_functions(); if(!render_pass) - begin_render_pass(0); + begin_render_pass(false, 0); pipeline_state->apply(current_buffer); unsigned first_index = batch.get_offset()/batch.get_index_size(); diff --git a/source/backends/vulkan/commands_backend.h b/source/backends/vulkan/commands_backend.h index 8632ca7c..4de712f5 100644 --- a/source/backends/vulkan/commands_backend.h +++ b/source/backends/vulkan/commands_backend.h @@ -43,7 +43,7 @@ protected: ~VulkanCommands(); void begin_buffer(); - void begin_render_pass(const ClearValue *); + void begin_render_pass(bool, const ClearValue *); void end_render_pass(); void begin_frame(unsigned); diff --git a/source/backends/vulkan/framebuffer_backend.cpp b/source/backends/vulkan/framebuffer_backend.cpp index 5b83c3db..96653fe1 100644 --- a/source/backends/vulkan/framebuffer_backend.cpp +++ b/source/backends/vulkan/framebuffer_backend.cpp @@ -65,7 +65,7 @@ void VulkanFramebuffer::update(unsigned) const vk_attachments[i++] = a.tex->view_handle; } - VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false); + VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(self.format, false, false, false); VkFramebufferCreateInfo framebuffer_info = { }; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; diff --git a/source/backends/vulkan/pipelinecache.cpp b/source/backends/vulkan/pipelinecache.cpp index e24c72db..3f8e5500 100644 --- a/source/backends/vulkan/pipelinecache.cpp +++ b/source/backends/vulkan/pipelinecache.cpp @@ -44,11 +44,11 @@ PipelineCache::~PipelineCache() vk.DestroyDescriptorPool(descriptor_pool); } -VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool is_cleared, bool to_present) +VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool clear, bool discard, bool to_present) { const VulkanFunctions &vk = device.get_functions(); - uint64_t key = hash<64>(static_cast(is_cleared | (to_present*2))); + uint64_t key = hash<64>(static_cast(clear | (discard*2) | (to_present*4))); for(FrameAttachment a: format) key = hash_update<64>(key, a); @@ -69,11 +69,11 @@ VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool is_c { attachments[i].format = static_cast(get_vulkan_pixelformat(get_attachment_pixelformat(a))); attachments[i].samples = vk_samples; - attachments[i].loadOp = (is_cleared ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD); + attachments[i].loadOp = (clear ? discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD); attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[i].initialLayout = (is_cleared ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + attachments[i].initialLayout = (clear ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); attachments[i].finalLayout = (to_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); unsigned attach_pt = get_attach_point(a); diff --git a/source/backends/vulkan/pipelinecache.h b/source/backends/vulkan/pipelinecache.h index cb14d1ef..1017a93f 100644 --- a/source/backends/vulkan/pipelinecache.h +++ b/source/backends/vulkan/pipelinecache.h @@ -26,7 +26,7 @@ public: PipelineCache(PipelineCache &&); ~PipelineCache(); - VkRenderPass get_render_pass(const FrameFormat &, bool, bool); + VkRenderPass get_render_pass(const FrameFormat &, bool, bool, bool); VkPipeline get_pipeline(const PipelineState &); VkDescriptorSet get_descriptor_set(const PipelineState &, unsigned); }; diff --git a/source/backends/vulkan/pipelinestate_backend.cpp b/source/backends/vulkan/pipelinestate_backend.cpp index f25dd211..080a4a5d 100644 --- a/source/backends/vulkan/pipelinestate_backend.cpp +++ b/source/backends/vulkan/pipelinestate_backend.cpp @@ -113,7 +113,7 @@ void VulkanPipelineState::fill_creation_info(vector &buffer) const const PipelineState &self = *static_cast(this); const FrameFormat &format = self.framebuffer->get_format(); - VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(format, false, false); + VkRenderPass render_pass = device.get_pipeline_cache().get_render_pass(format, false, false, false); unsigned n_color_attachments = 0; for(FrameAttachment a: format) diff --git a/source/render/renderer.h b/source/render/renderer.h index ffaa917d..1cbcdc60 100644 --- a/source/render/renderer.h +++ b/source/render/renderer.h @@ -177,7 +177,10 @@ public: void set_object_lod_bias(unsigned); unsigned get_object_lod_bias() const { return get_state().object_lod_bias; } - void clear(const ClearValue *); + /** Clears framebuffer contents. If values is not null, it must contain one + element for each attachment. Otherwise the framebuffer contents are + discarded and become undefined. */ + void clear(const ClearValue *values); /** Draws a batch of primitives. A shader must be active. */ void draw(const Batch &); diff --git a/source/render/sequence.cpp b/source/render/sequence.cpp index 74b8bc3b..b11d4b1c 100644 --- a/source/render/sequence.cpp +++ b/source/render/sequence.cpp @@ -154,6 +154,7 @@ void Sequence::render(Renderer &renderer, Tag tag) const { unsigned j = i%2; renderer.set_framebuffer(i+1get_framebuffer() : out_fbo); + renderer.clear(0); const Texture2D &color = target[j]->get_target_texture(COLOR_ATTACHMENT); const Texture2D &depth = target[j]->get_target_texture(DEPTH_ATTACHMENT); postproc[i]->render(renderer, color, depth); -- 2.45.2