Files
2025-09-04 10:54:47 +08:00

133 lines
3.5 KiB
C++

/* Copyright (c) 2019-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.
*/
#include "render_pipeline.h"
#include "scene_graph/components/camera.h"
#include "scene_graph/components/image.h"
#include "scene_graph/components/material.h"
#include "scene_graph/components/mesh.h"
#include "scene_graph/components/pbr_material.h"
#include "scene_graph/components/sampler.h"
#include "scene_graph/components/sub_mesh.h"
#include "scene_graph/components/texture.h"
#include "scene_graph/node.h"
namespace vkb
{
RenderPipeline::RenderPipeline(std::vector<std::unique_ptr<vkb::rendering::SubpassC>> &&subpasses_) :
subpasses{std::move(subpasses_)}
{
prepare();
// Default load/store for swapchain
load_store[0].load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
load_store[0].store_op = VK_ATTACHMENT_STORE_OP_STORE;
// Default load/store for depth attachment
load_store[1].load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
load_store[1].store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;
// Default clear value
clear_value[0].color = {0.0f, 0.0f, 0.0f, 1.0f};
clear_value[1].depthStencil = {0.0f, ~0U};
}
void RenderPipeline::prepare()
{
for (auto &subpass : subpasses)
{
subpass->prepare();
}
}
void RenderPipeline::add_subpass(std::unique_ptr<vkb::rendering::SubpassC> &&subpass)
{
subpass->prepare();
subpasses.emplace_back(std::move(subpass));
}
std::vector<std::unique_ptr<vkb::rendering::SubpassC>> &RenderPipeline::get_subpasses()
{
return subpasses;
}
const std::vector<LoadStoreInfo> &RenderPipeline::get_load_store() const
{
return load_store;
}
void RenderPipeline::set_load_store(const std::vector<LoadStoreInfo> &ls)
{
load_store = ls;
}
const std::vector<VkClearValue> &RenderPipeline::get_clear_value() const
{
return clear_value;
}
void RenderPipeline::set_clear_value(const std::vector<VkClearValue> &cv)
{
clear_value = cv;
}
void RenderPipeline::draw(vkb::core::CommandBufferC &command_buffer, RenderTarget &render_target, VkSubpassContents contents)
{
assert(!subpasses.empty() && "Render pipeline should contain at least one sub-pass");
// Pad clear values if they're less than render target attachments
while (clear_value.size() < render_target.get_attachments().size())
{
clear_value.push_back({0.0f, 0.0f, 0.0f, 1.0f});
}
for (size_t i = 0; i < subpasses.size(); ++i)
{
active_subpass_index = i;
auto &subpass = subpasses[i];
subpass->update_render_target_attachments(render_target);
if (i == 0)
{
command_buffer.begin_render_pass(render_target, load_store, clear_value, subpasses, contents);
}
else
{
command_buffer.next_subpass();
}
if (subpass->get_debug_name().empty())
{
subpass->set_debug_name(fmt::format("RP subpass #{}", i));
}
ScopedDebugLabel subpass_debug_label{command_buffer, subpass->get_debug_name().c_str()};
subpass->draw(command_buffer);
}
active_subpass_index = 0;
}
std::unique_ptr<vkb::rendering::SubpassC> &RenderPipeline::get_active_subpass()
{
return subpasses[active_subpass_index];
}
} // namespace vkb