forked from GPUOpen-LibrariesAndSDKs/Vulkan-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultithreading_render_passes.h
181 lines (136 loc) · 5.8 KB
/
multithreading_render_passes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* Copyright (c) 2023, 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 <ctpl_stl.h>
#include "core/command_buffer.h"
#include "rendering/render_pipeline.h"
#include "rendering/subpasses/forward_subpass.h"
#include "scene_graph/components/camera.h"
#include "vulkan_sample.h"
struct alignas(16) ShadowUniform
{
glm::mat4 shadowmap_projection_matrix; // Projection matrix used to render shadowmap
};
/**
* @brief Multithreading with Render Passes
* This sample shows performance improvement when using multithreading with
* multiple render passes and primary level command buffers.
*/
class MultithreadingRenderPasses : public vkb::VulkanSample
{
public:
enum class MultithreadingMode
{
None = 0,
PrimaryCommandBuffers = 1,
SecondaryCommandBuffers = 2,
};
MultithreadingRenderPasses();
virtual ~MultithreadingRenderPasses() = default;
virtual bool prepare(vkb::Platform &platform) override;
virtual void update(float delta_time) override;
void draw_gui() override;
/**
* @brief This subpass is responsible for rendering a shadowmap
*/
class ShadowSubpass : public vkb::GeometrySubpass
{
public:
ShadowSubpass(vkb::RenderContext &render_context,
vkb::ShaderSource &&vertex_source,
vkb::ShaderSource &&fragment_source,
vkb::sg::Scene &scene,
vkb::sg::Camera &camera);
protected:
virtual void prepare_pipeline_state(vkb::CommandBuffer &command_buffer, VkFrontFace front_face, bool double_sided_material) override;
virtual vkb::PipelineLayout &prepare_pipeline_layout(vkb::CommandBuffer &command_buffer, const std::vector<vkb::ShaderModule *> &shader_modules) override;
virtual void prepare_push_constants(vkb::CommandBuffer &command_buffer, vkb::sg::SubMesh &sub_mesh) override;
};
/**
* @brief This subpass is responsible for rendering a Scene
* It implements a custom draw function which passes shadowmap and light matrix
*/
class MainSubpass : public vkb::ForwardSubpass
{
public:
MainSubpass(vkb::RenderContext &render_context,
vkb::ShaderSource &&vertex_source,
vkb::ShaderSource &&fragment_source,
vkb::sg::Scene &scene,
vkb::sg::Camera &camera,
vkb::sg::Camera &shadowmap_camera,
std::vector<std::unique_ptr<vkb::RenderTarget>> &shadow_render_targets);
virtual void prepare() override;
virtual void draw(vkb::CommandBuffer &command_buffer) override;
private:
std::unique_ptr<vkb::core::Sampler> shadowmap_sampler{};
vkb::sg::Camera &shadowmap_camera;
std::vector<std::unique_ptr<vkb::RenderTarget>> &shadow_render_targets;
};
private:
virtual void prepare_render_context() override;
std::unique_ptr<vkb::RenderTarget> create_shadow_render_target(uint32_t size);
/**
* @return Shadow render pass which should run first
*/
std::unique_ptr<vkb::RenderPipeline> create_shadow_renderpass();
/**
* @return Main render pass which should run second
*/
std::unique_ptr<vkb::RenderPipeline> create_main_renderpass();
const uint32_t SHADOWMAP_RESOLUTION{1024};
std::vector<std::unique_ptr<vkb::RenderTarget>> shadow_render_targets;
/**
* @brief Pipeline for shadowmap rendering
*/
std::unique_ptr<vkb::RenderPipeline> shadow_render_pipeline{};
/**
* @brief Pipeline which uses shadowmap
*/
std::unique_ptr<vkb::RenderPipeline> main_render_pipeline{};
/**
* @brief Subpass for shadowmap rendering
*/
ShadowSubpass *shadow_subpass{};
/**
* @brief Camera for shadowmap rendering (view from the light source)
*/
vkb::sg::Camera *shadowmap_camera{};
/**
* @brief Main camera for scene rendering
*/
vkb::sg::Camera *camera{};
ctpl::thread_pool thread_pool;
uint32_t swapchain_attachment_index{0};
uint32_t depth_attachment_index{1};
uint32_t shadowmap_attachment_index{0};
int multithreading_mode{0};
/**
* @brief Record drawing commands using the chosen strategy
* @param main_command_buffer Already allocated command buffer for the main pass
* @return Single or multiple recorded command buffers
*/
std::vector<vkb::CommandBuffer *> record_command_buffers(vkb::CommandBuffer &main_command_buffer);
void record_separate_primary_command_buffers(std::vector<vkb::CommandBuffer *> &command_buffers, vkb::CommandBuffer &main_command_buffer);
void record_separate_secondary_command_buffers(std::vector<vkb::CommandBuffer *> &command_buffers, vkb::CommandBuffer &main_command_buffer);
void record_main_pass_image_memory_barriers(vkb::CommandBuffer &command_buffer);
void record_shadow_pass_image_memory_barrier(vkb::CommandBuffer &command_buffer);
void record_present_image_memory_barrier(vkb::CommandBuffer &command_buffer);
void draw_shadow_pass(vkb::CommandBuffer &command_buffer);
void draw_main_pass(vkb::CommandBuffer &command_buffer);
};
std::unique_ptr<vkb::VulkanSample> create_multithreading_render_passes();