deferred_renderer.hpp 8.24 KB
Newer Older
1
2
3
4
5
#pragma once

#include <mirrage/renderer/camera_comp.hpp>
#include <mirrage/renderer/gbuffer.hpp>
#include <mirrage/renderer/model.hpp>
6
#include <mirrage/renderer/render_pass.hpp>
7
8
9
10
11

#include <mirrage/graphic/context.hpp>
#include <mirrage/graphic/device.hpp>
#include <mirrage/graphic/profiler.hpp>

12
#include <mirrage/utils/min_max.hpp>
13

14
15
#include <glm/gtx/quaternion.hpp>
#include <glm/vec3.hpp>
16
17
18
#include <vulkan/vulkan.hpp>


19
namespace mirrage {
20
21
22
	namespace ecs {
		class Entity_manager;
	}
23
	class Engine;
24
} // namespace mirrage
25

26
namespace mirrage::renderer {
27
28
29
30

	class Deferred_renderer_factory;
	class Deferred_renderer;

31

32
	struct Renderer_settings {
33
		int shadowmap_resolution = 2048;
Florian Oetke's avatar
Florian Oetke committed
34
35
		int shadow_quality       = 99; // 0 = lowest

36
37
		bool gi                        = true;
		bool gi_highres                = true;
Florian Oetke's avatar
Florian Oetke committed
38
		bool gi_shadows                = false;
39
40
		int  gi_diffuse_mip_level      = 1;
		int  gi_min_mip_level          = 0;
41
42
		int  gi_samples                = 32;
		int  gi_lowres_samples         = 128;
43
44
45
46
47
48
		int  gi_low_quality_mip_levels = 0;

		bool  tonemapping           = true;
		float exposure_override     = 0.f;
		float min_display_luminance = 2.f;
		float max_display_luminance = 150.0f;
Florian Oetke's avatar
Florian Oetke committed
49

50
51
52
		bool ssao  = true;
		bool bloom = true;

53
		float background_intensity = 0.f;
54

55
		bool dynamic_shadows = false;
56
		int  debug_gi_layer  = -1;
57
		bool debug_geometry  = true;
58
	};
59

60
#ifdef sf2_structDef
Florian Oetke's avatar
Florian Oetke committed
61
	sf2_structDef(Renderer_settings, shadowmap_resolution, shadow_quality, gi, dynamic_shadows);
62
63
64
65
66
67
68
69
70
71
#endif

	struct Global_uniforms {
		glm::mat4 view_proj_mat;
		glm::mat4 view_mat;
		glm::mat4 proj_mat;
		glm::mat4 inv_view_mat;
		glm::mat4 inv_proj_mat;
		glm::vec4 eye_pos;
		glm::vec4 proj_planes; //< near, far, fov horizontal, fov vertical
72
		glm::vec4 time;        //< time, sin(time), delta_time
73
		glm::vec4 proj_info;
74
75
76
	};


77
	template <class T, class... Args>
78
79
	auto make_pass_factory(Args&&... args)
	{
80
		return std::unique_ptr<Render_pass_factory>(new T(std::forward<Args>(args)...));
81
82
83
84
85
	}


	// shared among all Deferred_renderers in all screens
	class Deferred_renderer_factory {
86
	  public:
87
88
89
		Deferred_renderer_factory(Engine&          engine,
		                          graphic::Window& window,
		                          std::vector<std::unique_ptr<Render_pass_factory>>);
90
		~Deferred_renderer_factory();
91

92
		auto create_renderer(ecs::Entity_manager&) -> std::unique_ptr<Deferred_renderer>;
93
94
95
96

		void queue_commands(vk::CommandBuffer);
		auto queue_temporary_command_buffer() -> vk::CommandBuffer;

Florian Oetke's avatar
Florian Oetke committed
97
98
		auto create_compute_command_buffer() -> vk::UniqueCommandBuffer;

99
100
101
		auto model_material_sampler() const noexcept { return *_model_material_sampler; }
		auto model_descriptor_set_layout() const noexcept { return *_model_desc_set_layout; }

Florian Oetke's avatar
Florian Oetke committed
102
103
		auto compute_queue() const noexcept { return _compute_queue; }

104
105
106
		void finish_frame();

		auto settings() const -> auto& { return *_settings; }
Florian Oetke's avatar
Florian Oetke committed
107
108
		void settings(const Renderer_settings& s, bool apply = true);
		void save_settings();
109
110
111

	  private:
		friend class Deferred_renderer;
112
		struct Asset_loaders;
113
		using Pass_factories = std::vector<std::unique_ptr<Render_pass_factory>>;
114
		using Settings_ptr   = asset::Ptr<Renderer_settings>;
115

116
		Engine&                         _engine;
117
		asset::Asset_manager&           _assets;
Florian Oetke's avatar
Florian Oetke committed
118
119
120
121
		Settings_ptr                    _settings;
		Pass_factories                  _pass_factories;
		graphic::Window&                _window;
		graphic::Device_ptr             _device;
122
		graphic::Swapchain&             _swapchain;
Florian Oetke's avatar
Florian Oetke committed
123
124
125
126
		std::uint32_t                   _draw_queue_family;
		std::uint32_t                   _compute_queue_family;
		vk::Queue                       _draw_queue;
		vk::Queue                       _compute_queue;
Florian Oetke's avatar
Florian Oetke committed
127
128
129
		vk::UniqueSemaphore             _image_acquired;
		vk::UniqueSemaphore             _image_presented;
		graphic::Command_buffer_pool    _command_buffer_pool;
Florian Oetke's avatar
Florian Oetke committed
130
		graphic::Command_buffer_pool    _compute_command_buffer_pool;
Florian Oetke's avatar
Florian Oetke committed
131
132
133
134
		util::maybe<std::size_t>        _aquired_swapchain_image;
		std::vector<vk::CommandBuffer>  _queued_commands;
		std::vector<Deferred_renderer*> _renderer_instances;
		bool                            _recreation_pending = false;
135
136
137
		vk::UniqueSampler               _model_material_sampler;
		vk::UniqueDescriptorSetLayout   _model_desc_set_layout;
		std::unique_ptr<Asset_loaders>  _asset_loaders;
138

139
		void _present();
140
141
142
143
144
		auto _rank_device(vk::PhysicalDevice, util::maybe<std::uint32_t> gqueue) -> int;
		auto _init_device(vk::PhysicalDevice, util::maybe<std::uint32_t> gqueue)
		        -> graphic::Device_create_info;

		auto _aquire_next_image() -> std::size_t;
145
146
	};

147

148
	class Deferred_renderer {
149
150
	  public:
		Deferred_renderer(Deferred_renderer_factory&,
151
		                  std::vector<std::unique_ptr<Render_pass_factory>>&,
152
		                  ecs::Entity_manager&,
153
		                  Engine&);
Florian Oetke's avatar
Florian Oetke committed
154
155
		Deferred_renderer(const Deferred_renderer&) = delete;
		auto operator=(const Deferred_renderer&) -> Deferred_renderer& = delete;
156
		~Deferred_renderer();
157

Florian Oetke's avatar
Florian Oetke committed
158
159
		void recreate();

160
161
162
163
164
		void update(util::Time dt);
		void draw();

		void shrink_to_fit();

Florian Oetke's avatar
Florian Oetke committed
165
166
		auto gbuffer() noexcept -> auto& { return *_gbuffer; }
		auto gbuffer() const noexcept -> auto& { return *_gbuffer; }
167
		auto global_uniforms() const noexcept -> auto& { return _global_uniforms; }
168
		auto global_uniforms_layout() const noexcept { return *_global_uniform_descriptor_set_layout; }
169

170
		auto asset_manager() noexcept -> auto& { return _factory->_assets; }
Florian Oetke's avatar
Florian Oetke committed
171
172
173
		auto device() noexcept -> auto& { return *_factory->_device; }
		auto window() noexcept -> auto& { return _factory->_window; }
		auto swapchain() noexcept -> auto& { return _factory->_swapchain; }
Florian Oetke's avatar
Florian Oetke committed
174
175
176
177
178
		auto queue_family() const noexcept { return _factory->_draw_queue_family; }
		auto compute_queue_family() const noexcept { return _factory->_compute_queue_family; }

		auto compute_queue() const noexcept { return _factory->compute_queue(); }
		auto create_compute_command_buffer() { return _factory->create_compute_command_buffer(); }
179

180
		auto create_descriptor_set(vk::DescriptorSetLayout, std::int32_t bindings) -> graphic::DescriptorSet;
181
182
		auto descriptor_pool() noexcept -> auto& { return _descriptor_set_pool; }

183
184
185
		auto noise_descriptor_set_layout() const noexcept { return *_noise_descriptor_set_layout; }
		auto noise_descriptor_set() const noexcept { return *_noise_descriptor_set; }

186
187
188
		auto model_material_sampler() const noexcept { return _factory->model_material_sampler(); }
		auto model_descriptor_set_layout() const noexcept { return _factory->model_descriptor_set_layout(); }

189
190
		auto active_camera() noexcept -> util::maybe<Camera_state&>;

Florian Oetke's avatar
Florian Oetke committed
191
192
		auto settings() const -> auto& { return _factory->settings(); }
		void save_settings() { _factory->save_settings(); }
193
		void settings(const Renderer_settings& s, bool apply = true) { _factory->settings(s, apply); }
Florian Oetke's avatar
Florian Oetke committed
194

195
196
197
198
199
200
201
202
		void debug_draw(const std::vector<Debug_geometry>& lines)
		{
			if(_factory->settings().debug_geometry) {
				auto& queue = _frame_data.debug_geometry_queue;
				queue.insert(queue.end(), lines.begin(), lines.end());
			}
		}

203
204
205
206
207

		auto profiler() const noexcept -> auto& { return _profiler; }
		auto profiler() noexcept -> auto& { return _profiler; }

	  private:
208
209
		friend class Deferred_renderer_factory;

210
		Engine*                    _engine;
Florian Oetke's avatar
Florian Oetke committed
211
212
		Deferred_renderer_factory* _factory;
		ecs::Entity_manager*       _entity_manager;
213
214
		graphic::Descriptor_pool   _descriptor_set_pool;

Florian Oetke's avatar
Florian Oetke committed
215
216
217
		std::unique_ptr<GBuffer> _gbuffer;
		Global_uniforms          _global_uniforms;
		graphic::Profiler        _profiler;
218
219
220
		float                    _time_acc      = 0.f;
		float                    _delta_time    = 0.f;
		std::uint32_t            _frame_counter = 0;
221
222

		vk::UniqueDescriptorSetLayout _global_uniform_descriptor_set_layout;
223
		graphic::DescriptorSet        _global_uniform_descriptor_set;
224
225
		graphic::Dynamic_buffer       _global_uniform_buffer;

226
227
228
		graphic::Texture_ptr                 _blue_noise;
		vk::UniqueSampler                    _noise_sampler;
		graphic::Image_descriptor_set_layout _noise_descriptor_set_layout;
229
		graphic::DescriptorSet               _noise_descriptor_set;
230

231
		std::vector<std::unique_ptr<Render_pass>> _passes;
232

Florian Oetke's avatar
Florian Oetke committed
233
		Camera_comp::Pool*        _cameras;
234
		util::maybe<Camera_state> _active_camera;
235
		Frame_data                _frame_data;
236
237
238
239

		void _write_global_uniform_descriptor_set();
		void _update_global_uniforms(vk::CommandBuffer, const Camera_state& camera);
	};
240
} // namespace mirrage::renderer