Files
Vulkan-Samples/framework/rendering/postprocessing_pass.h
T
2025-09-04 10:54:47 +08:00

208 lines
6.2 KiB
C++

/* 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 <functional>
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<void()>;
// 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<core::Sampler> 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 <typename Self>
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<Self &>(*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<Self &>(*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<Self &>(*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<Self &>(*this);
}
/**
* @brief Returns the vkb::PostProcessingPipeline that is the parent of this pass.
*/
inline PostProcessingPipeline &get_parent() const
{
return *parent;
}
};
} // namespace vkb