/* Copyright (c) 2020-2025, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 the "License"; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "core/command_buffer.h" #include "render_context.h" #include "render_target.h" #include namespace vkb { class PostProcessingPipeline; /** * @brief The base of all types of passes in a vkb::PostProcessingPipeline. */ class PostProcessingPassBase { friend class PostProcessingPipeline; public: PostProcessingPassBase(PostProcessingPipeline *parent); PostProcessingPassBase(const PostProcessingPassBase &to_copy) = delete; PostProcessingPassBase &operator=(const PostProcessingPassBase &to_copy) = delete; PostProcessingPassBase(PostProcessingPassBase &&to_move) = default; PostProcessingPassBase &operator=(PostProcessingPassBase &&to_move) = default; virtual ~PostProcessingPassBase() = default; protected: /** * @brief Prepares this pass, recording commands into the given command buffer. * @remarks Passes that that do not explicitly have a vkb::RenderTarget set will render * to default_render_target. */ virtual void prepare(vkb::core::CommandBufferC &command_buffer, RenderTarget &default_render_target) { prepared = true; } /** * @brief Runs this pass, recording commands into the given command buffer. * @remarks Passes that that do not explicitly have a vkb::RenderTarget set will render * to default_render_target. */ virtual void draw(vkb::core::CommandBufferC &command_buffer, RenderTarget &default_render_target) {} /** * @brief A functor ran in the context of this renderpass. * @see set_pre_draw_func(), set_post_draw_func() */ using HookFunc = std::function; // NOTE: Protected members are exposed via getters and setters in PostProcessingPass<> PostProcessingPipeline *parent{nullptr}; bool prepared{false}; std::string debug_name{}; RenderTarget *render_target{nullptr}; std::shared_ptr default_sampler{}; HookFunc pre_draw{}; HookFunc post_draw{}; /** * @brief Returns the parent's render context. */ RenderContext &get_render_context() const; /** * @brief Returns the parent's fullscreen triangle vertex shader source. */ ShaderSource &get_triangle_vs() const; struct BarrierInfo { VkPipelineStageFlags pipeline_stage; // Pipeline stage of this pass' inputs/outputs VkAccessFlags image_read_access; // Access mask for images read from this pass VkAccessFlags image_write_access; // Access mask for images written to by this pass }; /** * @brief Returns information that can be used to setup memory barriers of images * that are produced (e.g. image stores, color attachment output) by this pass. */ virtual BarrierInfo get_src_barrier_info() const = 0; /** * @brief Returns information that can be used to setup memory barriers of images * that are consumed (e.g. image loads, texture sampling) by this pass. */ virtual BarrierInfo get_dst_barrier_info() const = 0; /** * @brief Convenience function that calls get_src_barrier_info() on the previous pass of the pipeline, * if any, or returns the specified default if this is the first pass in the pipeline. */ BarrierInfo get_predecessor_src_barrier_info(BarrierInfo fallback = {}) const; }; /** * @brief CRTP base of all types of passes in a vkb::PostProcessingPipeline. */ template class PostProcessingPass : public PostProcessingPassBase { public: using PostProcessingPassBase::PostProcessingPassBase; PostProcessingPass(const PostProcessingPass &to_copy) = delete; PostProcessingPass &operator=(const PostProcessingPass &to_copy) = delete; PostProcessingPass(PostProcessingPass &&to_move) = default; PostProcessingPass &operator=(PostProcessingPass &&to_move) = default; virtual ~PostProcessingPass() = default; /** * @brief Sets a functor that, if non-null, will be invoked before draw()ing this pass. * @remarks The function is invoked after ending the previous RenderPass, and before beginning this one. */ inline Self &set_pre_draw_func(HookFunc &&new_func) { pre_draw = std::move(new_func); return static_cast(*this); } /** * @brief Sets a functor that, if non-null, will be invoked after draw()ing this pass. * @remarks The function after drawing the last subpass, and before ending this RenderPass. */ inline Self &set_post_draw_func(HookFunc &&new_func) { post_draw = std::move(new_func); return static_cast(*this); } /** * @brief Render target to output to. * If set, this pass will output to the given render target instead of the one passed to draw(). */ inline RenderTarget *get_render_target() const { return render_target; } /** * @brief Render target to output to. * If set, this pass will output to the given render target instead of the one passed to draw(). * @param new_render_target the new render target to output too */ inline Self &set_render_target(RenderTarget *new_render_target) { render_target = new_render_target; return static_cast(*this); } /** * @brief Returns the the debug name of this pass. */ inline const std::string &get_debug_name() const { return debug_name; } /** * @brief Sets the debug name of this pass. */ inline Self &set_debug_name(const std::string &new_debug_name) { debug_name = new_debug_name; return static_cast(*this); } /** * @brief Returns the vkb::PostProcessingPipeline that is the parent of this pass. */ inline PostProcessingPipeline &get_parent() const { return *parent; } }; } // namespace vkb