]> git.tdb.fi Git - libs/gl.git/commitdiff
Treat clear() with null parameter as invalidate
authorMikko Rasa <tdb@tdb.fi>
Fri, 19 Nov 2021 22:36:52 +0000 (00:36 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 19 Nov 2021 23:04:35 +0000 (01:04 +0200)
Also use it in Sequence for postprocessor render targets, since
postprocessors are supposed to render the entire screen.

source/backends/opengl/commands_backend.cpp
source/backends/vulkan/commands_backend.cpp
source/backends/vulkan/commands_backend.h
source/backends/vulkan/framebuffer_backend.cpp
source/backends/vulkan/pipelinecache.cpp
source/backends/vulkan/pipelinecache.h
source/backends/vulkan/pipelinestate_backend.cpp
source/render/renderer.h
source/render/sequence.cpp

index 62d952e091a557c56f8a9d3856fbba65d3277ee2..1ec19c13d63b7e908a2f90ddbcdbada8bcfd4363 100644 (file)
@@ -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();
index 0134474b932d060e6a97eb8a4bd6d97f1fb0eadb..684f0a476b723172b5ea7bcfe190ad9c465bf7bd 100644 (file)
@@ -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();
index 8632ca7c2648e355091faccd69c75cc3aa6c33dc..4de712f57092947409fb554826139e9300ee4198 100644 (file)
@@ -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);
index 5b83c3db6b67e8be5c65acd31225ec64d8ec6ebf..96653fe1d084444b625297cd9651ff2dea0f8b90 100644 (file)
@@ -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;
index e24c72dbba4944dc6f3180b61af8557f6ac0a8ec..3f8e55008223484036b3e5c4760ae5c5bd09d047 100644 (file)
@@ -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<uint8_t>(is_cleared | (to_present*2)));
+       uint64_t key = hash<64>(static_cast<uint8_t>(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<VkFormat>(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);
index cb14d1ef50391cd570ed59093dab0038e9dc8597..1017a93ff6b63ed7bef01dc01190dab04024afc3 100644 (file)
@@ -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);
 };
index f25dd2117fcc20baf0919dd875e908ca62a6b0be..080a4a5d8590c52491fdbf5a5671709b32fd1c7c 100644 (file)
@@ -113,7 +113,7 @@ void VulkanPipelineState::fill_creation_info(vector<char> &buffer) const
        const PipelineState &self = *static_cast<const PipelineState *>(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)
index ffaa917dd4f5b8dd772ba5ce008c7f9d1fc372f7..1cbcdc60546b93f0cccc2db6ee5cb95a27107b39 100644 (file)
@@ -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 &);
index 74b8bc3b0b4fe9a6835d9f5fab5326dddcc62fe3..b11d4b1c9f037aafbfe49eaebe2d76c1920d5511 100644 (file)
@@ -154,6 +154,7 @@ void Sequence::render(Renderer &renderer, Tag tag) const
                {
                        unsigned j = i%2;
                        renderer.set_framebuffer(i+1<postproc.size() ? &target[1-j]->get_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);