init
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
/* 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/sampled_image.h"
|
||||
#include "postprocessing_pass.h"
|
||||
#include "render_pipeline.h"
|
||||
#include "subpass.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
/**
|
||||
* @brief An utility struct for hashing pairs.
|
||||
*/
|
||||
struct PairHasher
|
||||
{
|
||||
template <typename TPair>
|
||||
size_t operator()(const TPair &pair) const
|
||||
{
|
||||
std::hash<decltype(pair.first)> hash1{};
|
||||
std::hash<decltype(pair.second)> hash2{};
|
||||
return hash1(pair.first) * 43 + pair.second;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Maps in-shader binding names to indices into a RenderTarget's attachments.
|
||||
*/
|
||||
using AttachmentMap = std::unordered_map<std::string, uint32_t>;
|
||||
|
||||
/**
|
||||
* @brief Maps in-shader binding names to the core::SampledImage to bind.
|
||||
*/
|
||||
using SampledMap = std::unordered_map<std::string, core::SampledImage>;
|
||||
|
||||
/**
|
||||
* @brief Maps in-shader binding names to the core::ImageView to bind for storage images.
|
||||
*/
|
||||
using StorageImageMap = std::unordered_map<std::string, const core::ImageView *>;
|
||||
|
||||
/**
|
||||
* @brief A list of indices into a RenderTarget's attachments.
|
||||
*/
|
||||
using AttachmentList = std::vector<uint32_t>;
|
||||
|
||||
/**
|
||||
* @brief A set of indices into a RenderTarget's attachments.
|
||||
*/
|
||||
using AttachmentSet = std::unordered_set<uint32_t>;
|
||||
|
||||
class PostProcessingRenderPass;
|
||||
|
||||
/**
|
||||
* @brief A single step of a vkb::PostProcessingRenderPass.
|
||||
*/
|
||||
class PostProcessingSubpass : public vkb::rendering::SubpassC
|
||||
{
|
||||
public:
|
||||
PostProcessingSubpass(PostProcessingRenderPass *parent, RenderContext &render_context, ShaderSource &&triangle_vs,
|
||||
ShaderSource &&fs, ShaderVariant &&fs_variant = {});
|
||||
|
||||
PostProcessingSubpass(const PostProcessingSubpass &to_copy) = delete;
|
||||
PostProcessingSubpass &operator=(const PostProcessingSubpass &to_copy) = delete;
|
||||
|
||||
PostProcessingSubpass(PostProcessingSubpass &&to_move);
|
||||
PostProcessingSubpass &operator=(PostProcessingSubpass &&to_move) = delete;
|
||||
|
||||
~PostProcessingSubpass() = default;
|
||||
|
||||
/**
|
||||
* @brief Maps the names of input attachments in the shader to indices into the render target's images.
|
||||
* These are given as `subpassInput`s to the subpass, at set 0; they are bound automatically according to their name.
|
||||
*/
|
||||
inline const AttachmentMap &get_input_attachments() const
|
||||
{
|
||||
return input_attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Maps the names of samplers in the shader to vkb::core::SampledImage.
|
||||
* These are given as samplers to the subpass, at set 0; they are bound automatically according to their name.
|
||||
* @remarks PostProcessingPipeline::get_sampler() is used as the default sampler if none is specified.
|
||||
* The RenderTarget for the current PostProcessingSubpass is used if none is specified for attachment images.
|
||||
*/
|
||||
inline const SampledMap &get_sampled_images() const
|
||||
{
|
||||
return sampled_images;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Maps the names of storage images in the shader to vkb::core::ImageView.
|
||||
* These are given as image2D[Array] to the subpass, at set 0; they are bound automatically according to their name.
|
||||
*/
|
||||
inline const StorageImageMap &get_storage_images() const
|
||||
{
|
||||
return storage_images;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the shader variant used for this postprocess' fragment shader.
|
||||
*/
|
||||
inline ShaderVariant &get_fs_variant()
|
||||
{
|
||||
return fs_variant;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the shader variant that will be used for this postprocess' fragment shader.
|
||||
*/
|
||||
inline PostProcessingSubpass &set_fs_variant(ShaderVariant &&new_variant)
|
||||
{
|
||||
fs_variant = std::move(new_variant);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes the debug name of this Subpass.
|
||||
*/
|
||||
inline PostProcessingSubpass &set_debug_name(const std::string &name)
|
||||
{
|
||||
Subpass::set_debug_name(name);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes (or adds) the input attachment at name for this step.
|
||||
*/
|
||||
PostProcessingSubpass &bind_input_attachment(const std::string &name, uint32_t new_input_attachment);
|
||||
|
||||
/**
|
||||
* @brief Changes (or adds) the sampled image at name for this step.
|
||||
* @remarks If no RenderTarget is specifically set for the core::SampledImage,
|
||||
* it will default to sample in the RenderTarget currently bound for drawing in the parent PostProcessingRenderpass.
|
||||
*/
|
||||
PostProcessingSubpass &bind_sampled_image(const std::string &name, core::SampledImage &&new_image);
|
||||
|
||||
/**
|
||||
* @brief Changes (or adds) the storage image at name for this step.
|
||||
*/
|
||||
PostProcessingSubpass &bind_storage_image(const std::string &name, const core::ImageView &new_image);
|
||||
|
||||
/**
|
||||
* @brief Removes the sampled image at name for this step.
|
||||
*/
|
||||
void unbind_sampled_image(const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Set the constants that are pushed before each fullscreen draw.
|
||||
*/
|
||||
PostProcessingSubpass &set_push_constants(const std::vector<uint8_t> &data);
|
||||
|
||||
/**
|
||||
* @brief Set the constants that are pushed before each fullscreen draw.
|
||||
*/
|
||||
template <typename T>
|
||||
inline PostProcessingSubpass &set_push_constants(const T &data)
|
||||
{
|
||||
push_constants_data.reserve(sizeof(data));
|
||||
auto data_ptr = reinterpret_cast<const uint8_t *>(&data);
|
||||
push_constants_data.assign(data_ptr, data_ptr + sizeof(data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A functor used to draw the primitives for a post-processing step.
|
||||
* @see default_draw_func()
|
||||
*/
|
||||
using DrawFunc = std::function<void(vkb::core::CommandBufferC &command_buffer, RenderTarget &render_target)>;
|
||||
|
||||
/**
|
||||
* @brief Sets the function used to draw this postprocessing step.
|
||||
* @see default_draw_func()
|
||||
*/
|
||||
PostProcessingSubpass &set_draw_func(DrawFunc &&new_func);
|
||||
|
||||
/**
|
||||
* @brief The default function used to draw a step; it draws 1 instance with 3 vertices.
|
||||
*/
|
||||
static void default_draw_func(vkb::core::CommandBufferC &command_buffer, vkb::RenderTarget &render_target);
|
||||
|
||||
private:
|
||||
PostProcessingRenderPass *parent;
|
||||
|
||||
ShaderVariant fs_variant{};
|
||||
|
||||
AttachmentMap input_attachments{};
|
||||
SampledMap sampled_images{};
|
||||
StorageImageMap storage_images{};
|
||||
|
||||
std::vector<uint8_t> push_constants_data{};
|
||||
|
||||
DrawFunc draw_func{&PostProcessingSubpass::default_draw_func};
|
||||
|
||||
void prepare() override;
|
||||
void draw(vkb::core::CommandBufferC &command_buffer) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A collection of vkb::PostProcessingSubpass that are run as a single renderpass.
|
||||
*/
|
||||
class PostProcessingRenderPass : public PostProcessingPass<PostProcessingRenderPass>
|
||||
{
|
||||
public:
|
||||
friend class PostProcessingSubpass;
|
||||
|
||||
PostProcessingRenderPass(PostProcessingPipeline *parent, std::unique_ptr<core::Sampler> &&default_sampler = nullptr);
|
||||
|
||||
PostProcessingRenderPass(const PostProcessingRenderPass &to_copy) = delete;
|
||||
PostProcessingRenderPass &operator=(const PostProcessingRenderPass &to_copy) = delete;
|
||||
|
||||
PostProcessingRenderPass(PostProcessingRenderPass &&to_move) = default;
|
||||
PostProcessingRenderPass &operator=(PostProcessingRenderPass &&to_move) = default;
|
||||
|
||||
void draw(vkb::core::CommandBufferC &command_buffer, RenderTarget &default_render_target) override;
|
||||
|
||||
/**
|
||||
* @brief Gets the step at the given index.
|
||||
*/
|
||||
inline PostProcessingSubpass &get_subpass(size_t index)
|
||||
{
|
||||
assert(index < pipeline.get_subpasses().size());
|
||||
return *dynamic_cast<PostProcessingSubpass *>(pipeline.get_subpasses()[index].get());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs a new PostProcessingSubpass and adds it to the tail of the pipeline.
|
||||
* @remarks `this`, the render context and the vertex shader source are passed automatically before `args`.
|
||||
* @returns The inserted step.
|
||||
*/
|
||||
template <typename... ConstructorArgs>
|
||||
PostProcessingSubpass &add_subpass(ConstructorArgs &&...args)
|
||||
{
|
||||
ShaderSource vs_copy = get_triangle_vs();
|
||||
auto new_subpass = std::make_unique<PostProcessingSubpass>(this, get_render_context(), std::move(vs_copy), std::forward<ConstructorArgs>(args)...);
|
||||
auto &new_subpass_ref = *new_subpass;
|
||||
|
||||
pipeline.add_subpass(std::move(new_subpass));
|
||||
|
||||
return new_subpass_ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the uniform data to be bound at set 0, binding 0.
|
||||
*/
|
||||
template <typename T>
|
||||
inline PostProcessingRenderPass &set_uniform_data(const T &data)
|
||||
{
|
||||
uniform_data.reserve(sizeof(data));
|
||||
auto data_ptr = reinterpret_cast<const uint8_t *>(&data);
|
||||
uniform_data.assign(data_ptr, data_ptr + sizeof(data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc set_uniform_data(const T&)
|
||||
*/
|
||||
inline PostProcessingRenderPass &set_uniform_data(const std::vector<uint8_t> &data)
|
||||
{
|
||||
uniform_data = data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// An attachment sampled from a rendertarget
|
||||
using SampledAttachmentSet = std::unordered_set<std::pair<RenderTarget *, uint32_t>, PairHasher>;
|
||||
|
||||
/**
|
||||
* @brief Transition input, sampled and output attachments as appropriate.
|
||||
* @remarks If a RenderTarget is not explicitly set for this pass, fallback_render_target is used.
|
||||
*/
|
||||
void transition_attachments(const AttachmentSet &input_attachments,
|
||||
const SampledAttachmentSet &sampled_attachments,
|
||||
const AttachmentSet &output_attachments,
|
||||
vkb::core::CommandBufferC &command_buffer,
|
||||
RenderTarget &fallback_render_target);
|
||||
|
||||
/**
|
||||
* @brief Select appropriate load/store operations for each buffer of render_target,
|
||||
* according to the subpass inputs/sampled inputs/subpass outputs of all steps
|
||||
* in the pipeline.
|
||||
* @remarks If a RenderTarget is not explicitly set for this pass, fallback_render_target is used.
|
||||
*/
|
||||
void update_load_stores(const AttachmentSet &input_attachments,
|
||||
const SampledAttachmentSet &sampled_attachments,
|
||||
const AttachmentSet &output_attachments,
|
||||
const RenderTarget &fallback_render_target);
|
||||
|
||||
/**
|
||||
* @brief Transition images and prepare load/stores before draw()ing.
|
||||
*/
|
||||
void prepare_draw(vkb::core::CommandBufferC &command_buffer, RenderTarget &fallback_render_target);
|
||||
|
||||
BarrierInfo get_src_barrier_info() const override;
|
||||
BarrierInfo get_dst_barrier_info() const override;
|
||||
|
||||
RenderPipeline pipeline{};
|
||||
std::unique_ptr<core::Sampler> default_sampler{};
|
||||
std::unique_ptr<core::Sampler> default_sampler_nearest{};
|
||||
RenderTarget *draw_render_target{nullptr};
|
||||
std::vector<LoadStoreInfo> load_stores{};
|
||||
bool load_stores_dirty{true};
|
||||
std::vector<uint8_t> uniform_data{};
|
||||
std::shared_ptr<BufferAllocationC> uniform_buffer_alloc{};
|
||||
};
|
||||
|
||||
} // namespace vkb
|
||||
Reference in New Issue
Block a user