1/**************************************************************************/
2/* render_forward_mobile.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef RENDER_FORWARD_MOBILE_H
32#define RENDER_FORWARD_MOBILE_H
33
34#include "core/templates/paged_allocator.h"
35#include "servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h"
36#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
37#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
38#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
39
40#define RB_SCOPE_MOBILE SNAME("mobile")
41
42namespace RendererSceneRenderImplementation {
43
44class RenderForwardMobile : public RendererSceneRenderRD {
45 friend SceneShaderForwardMobile;
46
47protected:
48 struct GeometryInstanceSurfaceDataCache;
49
50private:
51 static RenderForwardMobile *singleton;
52
53 /* Scene Shader */
54
55 enum {
56 SCENE_UNIFORM_SET = 0,
57 RENDER_PASS_UNIFORM_SET = 1,
58 TRANSFORMS_UNIFORM_SET = 2,
59 MATERIAL_UNIFORM_SET = 3,
60 };
61
62 const int SAMPLERS_BINDING_FIRST_INDEX = 15;
63
64 enum {
65
66 SPEC_CONSTANT_USING_PROJECTOR = 0,
67 SPEC_CONSTANT_USING_SOFT_SHADOWS = 1,
68 SPEC_CONSTANT_USING_DIRECTIONAL_SOFT_SHADOWS = 2,
69
70 SPEC_CONSTANT_SOFT_SHADOW_SAMPLES = 3,
71 SPEC_CONSTANT_PENUMBRA_SHADOW_SAMPLES = 4,
72 SPEC_CONSTANT_DIRECTIONAL_SOFT_SHADOW_SAMPLES = 5,
73 SPEC_CONSTANT_DIRECTIONAL_PENUMBRA_SHADOW_SAMPLES = 6,
74
75 SPEC_CONSTANT_DECAL_USE_MIPMAPS = 7,
76 SPEC_CONSTANT_PROJECTOR_USE_MIPMAPS = 8,
77
78 SPEC_CONSTANT_DISABLE_OMNI_LIGHTS = 9,
79 SPEC_CONSTANT_DISABLE_SPOT_LIGHTS = 10,
80 SPEC_CONSTANT_DISABLE_REFLECTION_PROBES = 11,
81 SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS = 12,
82
83 SPEC_CONSTANT_DISABLE_DECALS = 13,
84 SPEC_CONSTANT_DISABLE_FOG = 14,
85
86 };
87
88 enum {
89 MAX_LIGHTMAPS = 8,
90 MAX_RDL_CULL = 8, // maximum number of reflection probes, decals or lights we can cull per geometry instance
91 INSTANCE_DATA_BUFFER_MIN_SIZE = 4096
92 };
93
94 enum RenderListType {
95 RENDER_LIST_OPAQUE, //used for opaque objects
96 RENDER_LIST_ALPHA, //used for transparent objects
97 RENDER_LIST_SECONDARY, //used for shadows and other objects
98 RENDER_LIST_MAX
99 };
100
101 /* Scene Shader */
102
103 SceneShaderForwardMobile scene_shader;
104
105 /* Render Buffer */
106
107 class RenderBufferDataForwardMobile : public RenderBufferCustomDataRD {
108 GDCLASS(RenderBufferDataForwardMobile, RenderBufferCustomDataRD);
109
110 public:
111 // We can have:
112 // - 4 subpasses combining the full render cycle
113 // - 3 subpasses + 1 normal pass for tonemapping/glow/dof/etc (using fb for 2D buffer)
114 // - 2 subpasses + 1 normal pass for transparent + 1 normal pass for tonemapping/glow/dof/etc (using fb for 2D buffer)
115 enum FramebufferConfigType {
116 FB_CONFIG_ONE_PASS, // Single pass frame buffer for alpha pass
117 FB_CONFIG_TWO_SUBPASSES, // Opaque + Sky sub pass
118 FB_CONFIG_THREE_SUBPASSES, // Opaque + Sky + Alpha sub pass
119 FB_CONFIG_FOUR_SUBPASSES, // Opaque + Sky + Alpha sub pass + Tonemap pass
120 FB_CONFIG_MAX
121 };
122
123 RID get_color_fbs(FramebufferConfigType p_config_type);
124 virtual void free_data() override;
125 virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
126
127 private:
128 RenderSceneBuffersRD *render_buffers = nullptr;
129 };
130
131 virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) override;
132
133 /* Rendering */
134
135 enum PassMode {
136 PASS_MODE_COLOR,
137 // PASS_MODE_COLOR_SPECULAR,
138 PASS_MODE_COLOR_TRANSPARENT,
139 PASS_MODE_SHADOW,
140 PASS_MODE_SHADOW_DP,
141 // PASS_MODE_DEPTH,
142 // PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
143 // PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI,
144 PASS_MODE_DEPTH_MATERIAL,
145 // PASS_MODE_SDF,
146 };
147
148 struct RenderElementInfo;
149
150 struct RenderListParameters {
151 GeometryInstanceSurfaceDataCache **elements = nullptr;
152 RenderElementInfo *element_info = nullptr;
153 int element_count = 0;
154 bool reverse_cull = false;
155 PassMode pass_mode = PASS_MODE_COLOR;
156 // bool no_gi = false;
157 uint32_t view_count = 1;
158 RID render_pass_uniform_set;
159 bool force_wireframe = false;
160 Vector2 uv_offset;
161 uint32_t spec_constant_base_flags = 0;
162 float lod_distance_multiplier = 0.0;
163 float screen_mesh_lod_threshold = 0.0;
164 RD::FramebufferFormatID framebuffer_format = 0;
165 uint32_t element_offset = 0;
166 uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
167 uint32_t subpass = 0;
168
169 RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
170 elements = p_elements;
171 element_info = p_element_info;
172 element_count = p_element_count;
173 reverse_cull = p_reverse_cull;
174 pass_mode = p_pass_mode;
175 // no_gi = p_no_gi;
176 view_count = p_view_count;
177 render_pass_uniform_set = p_render_pass_uniform_set;
178 force_wireframe = p_force_wireframe;
179 uv_offset = p_uv_offset;
180 lod_distance_multiplier = p_lod_distance_multiplier;
181 screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
182 element_offset = p_element_offset;
183 barrier = p_barrier;
184 spec_constant_base_flags = p_spec_constant_base_flags;
185 }
186 };
187
188 /* Render shadows */
189
190 void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
191 void _render_shadow_begin();
192 void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
193 void _render_shadow_process();
194 void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
195
196 /* Render Scene */
197
198 RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0);
199 void _pre_opaque_render(RenderDataRD *p_render_data);
200
201 uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
202
203 void _update_render_base_uniform_set();
204
205 void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append = false);
206 void _fill_element_info(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1);
207 // void _update_instance_data_buffer(RenderListType p_render_list);
208
209 void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
210 void _setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
211
212 RID render_base_uniform_set;
213 LocalVector<RID> render_pass_uniform_sets;
214
215 /* Light map */
216
217 struct LightmapData {
218 float normal_xform[12];
219 float pad[3];
220 float exposure_normalization;
221 };
222
223 struct LightmapCaptureData {
224 float sh[9 * 4];
225 };
226
227 /* Scene state */
228
229 struct SceneState {
230 LocalVector<RID> uniform_buffers;
231
232 // !BAS! We need to change lightmaps, we're not going to do this with a buffer but pushing the used lightmap in
233 LightmapData lightmaps[MAX_LIGHTMAPS];
234 RID lightmap_ids[MAX_LIGHTMAPS];
235 bool lightmap_has_sh[MAX_LIGHTMAPS];
236 uint32_t lightmaps_used = 0;
237 uint32_t max_lightmaps;
238 RID lightmap_buffer;
239
240 LightmapCaptureData *lightmap_captures = nullptr;
241 uint32_t max_lightmap_captures;
242 RID lightmap_capture_buffer;
243
244 bool used_screen_texture = false;
245 bool used_normal_texture = false;
246 bool used_depth_texture = false;
247 bool used_sss = false;
248
249 struct ShadowPass {
250 uint32_t element_from;
251 uint32_t element_count;
252 bool flip_cull;
253 PassMode pass_mode;
254
255 RID rp_uniform_set;
256 Plane camera_plane;
257 float lod_distance_multiplier;
258 float screen_mesh_lod_threshold;
259
260 RID framebuffer;
261 RD::InitialAction initial_depth_action;
262 RD::FinalAction final_depth_action;
263 Rect2i rect;
264 };
265
266 LocalVector<ShadowPass> shadow_passes;
267 } scene_state;
268
269 /* Render List */
270
271 // !BAS! Render list can probably be reused between clustered and mobile?
272 struct RenderList {
273 LocalVector<GeometryInstanceSurfaceDataCache *> elements;
274 LocalVector<RenderElementInfo> element_info;
275
276 void clear() {
277 elements.clear();
278 element_info.clear();
279 }
280
281 //should eventually be replaced by radix
282
283 struct SortByKey {
284 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
285 return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
286 }
287 };
288
289 void sort_by_key() {
290 SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
291 sorter.sort(elements.ptr(), elements.size());
292 }
293
294 void sort_by_key_range(uint32_t p_from, uint32_t p_size) {
295 SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
296 sorter.sort(elements.ptr() + p_from, p_size);
297 }
298
299 struct SortByDepth {
300 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
301 return (A->owner->depth < B->owner->depth);
302 }
303 };
304
305 void sort_by_depth() { //used for shadows
306
307 SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter;
308 sorter.sort(elements.ptr(), elements.size());
309 }
310
311 struct SortByReverseDepthAndPriority {
312 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
313 return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
314 }
315 };
316
317 void sort_by_reverse_depth_and_priority() { //used for alpha
318
319 SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
320 sorter.sort(elements.ptr(), elements.size());
321 }
322
323 _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) {
324 elements.push_back(p_element);
325 }
326 };
327
328 struct RenderElementInfo {
329 uint32_t uses_lightmap : 1;
330 uint32_t lod_index : 8;
331 uint32_t reserved : 23;
332 };
333
334 template <PassMode p_pass_mode>
335 _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
336
337 void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
338
339 LocalVector<RD::DrawListID> thread_draw_lists;
340 void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
341 void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
342
343 uint32_t render_list_thread_threshold = 500;
344
345 RenderList render_list[RENDER_LIST_MAX];
346
347protected:
348 /* setup */
349 virtual void _update_shader_quality_settings() override;
350
351 virtual float _render_buffers_get_luminance_multiplier() override;
352 virtual RD::DataFormat _render_buffers_get_color_format() override;
353 virtual bool _render_buffers_can_be_storage() override;
354
355 virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
356 virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
357
358 virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override{};
359 virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override{};
360 virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override{};
361
362 virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override{};
363 virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override{};
364
365 /* Geometry instance */
366
367 class GeometryInstanceForwardMobile;
368
369 // When changing any of these enums, remember to change the corresponding enums in the shader files as well.
370 enum {
371 INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4,
372 INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5,
373 INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 6,
374 INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 7,
375 INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 8,
376 INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 9,
377 INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 10,
378 INSTANCE_DATA_FLAG_PARTICLES = 1 << 11,
379 INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
380 INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
381 INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
382 INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
383 INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
384 INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
385 };
386
387 struct GeometryInstanceLightmapSH {
388 Color sh[9];
389 };
390
391 // Cached data for drawing surfaces
392 struct GeometryInstanceSurfaceDataCache {
393 enum {
394 FLAG_PASS_DEPTH = 1,
395 FLAG_PASS_OPAQUE = 2,
396 FLAG_PASS_ALPHA = 4,
397 FLAG_PASS_SHADOW = 8,
398 FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
399 FLAG_USES_SUBSURFACE_SCATTERING = 2048,
400 FLAG_USES_SCREEN_TEXTURE = 4096,
401 FLAG_USES_DEPTH_TEXTURE = 8192,
402 FLAG_USES_NORMAL_TEXTURE = 16384,
403 FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
404 FLAG_USES_PARTICLE_TRAILS = 65536,
405 };
406
407 union {
408 struct {
409 // !BAS! CHECK BITS!!!
410
411 uint64_t surface_index : 10;
412 uint64_t geometry_id : 32;
413 uint64_t material_id_low : 16;
414
415 uint64_t material_id_hi : 16;
416 uint64_t shader_id : 32;
417 uint64_t uses_lightmap : 4; // sort by lightmap id here, not whether its yes/no (is 4 bits enough?)
418 uint64_t depth_layer : 4;
419 uint64_t priority : 8;
420
421 // uint64_t lod_index : 8; // no need to sort on LOD
422 // uint64_t uses_forward_gi : 1; // no GI here, remove
423 };
424 struct {
425 uint64_t sort_key1;
426 uint64_t sort_key2;
427 };
428 } sort;
429
430 RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
431 uint32_t flags = 0;
432 uint32_t surface_index = 0;
433 uint32_t lod_index = 0;
434
435 void *surface = nullptr;
436 RID material_uniform_set;
437 SceneShaderForwardMobile::ShaderData *shader = nullptr;
438 SceneShaderForwardMobile::MaterialData *material = nullptr;
439
440 void *surface_shadow = nullptr;
441 RID material_uniform_set_shadow;
442 SceneShaderForwardMobile::ShaderData *shader_shadow = nullptr;
443
444 GeometryInstanceSurfaceDataCache *next = nullptr;
445 GeometryInstanceForwardMobile *owner = nullptr;
446 };
447
448 class GeometryInstanceForwardMobile : public RenderGeometryInstanceBase {
449 public:
450 // this structure maps to our push constant in our shader and is populated right before our draw call
451 struct PushConstant {
452 float transform[16];
453 uint32_t flags;
454 uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
455 uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
456 uint32_t layer_mask = 1;
457 float lightmap_uv_scale[4]; // doubles as uv_offset when needed
458 uint32_t reflection_probes[2]; // packed reflection probes
459 uint32_t omni_lights[2]; // packed omni lights
460 uint32_t spot_lights[2]; // packed spot lights
461 uint32_t decals[2]; // packed spot lights
462 };
463
464 // PushConstant push_constant; // we populate this from our instance data
465
466 //used during rendering
467 RID transforms_uniform_set;
468 bool use_projector = false;
469 bool use_soft_shadow = false;
470 bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform
471 uint32_t instance_count = 0;
472 uint32_t trail_steps = 1;
473
474 // lightmap
475 uint32_t gi_offset_cache = 0; // !BAS! Should rename this to lightmap_offset_cache, in forward clustered this was shared between gi and lightmap
476 RID lightmap_instance;
477 Rect2 lightmap_uv_scale;
478 uint32_t lightmap_slice_index;
479 GeometryInstanceLightmapSH *lightmap_sh = nullptr;
480
481 // culled light info
482 uint32_t reflection_probe_count = 0;
483 RendererRD::ForwardID reflection_probes[MAX_RDL_CULL];
484 uint32_t omni_light_count = 0;
485 RendererRD::ForwardID omni_lights[MAX_RDL_CULL];
486 uint32_t spot_light_count = 0;
487 RendererRD::ForwardID spot_lights[MAX_RDL_CULL];
488 uint32_t decals_count = 0;
489 RendererRD::ForwardID decals[MAX_RDL_CULL];
490
491 GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
492
493 // do we use this?
494 SelfList<GeometryInstanceForwardMobile> dirty_list_element;
495
496 GeometryInstanceForwardMobile() :
497 dirty_list_element(this) {}
498
499 virtual void _mark_dirty() override;
500
501 virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
502 virtual void set_lightmap_capture(const Color *p_sh9) override;
503
504 virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override;
505 virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override;
506 virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override;
507 virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {}
508
509 virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override;
510 };
511
512 /* Rendering */
513
514 virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
515
516 virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override;
517 virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
518 virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) override;
519 virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override;
520
521 /* Forward ID */
522
523 class ForwardIDStorageMobile : public RendererRD::ForwardIDStorage {
524 public:
525 struct ForwardIDAllocator {
526 LocalVector<bool> allocations;
527 LocalVector<uint8_t> map;
528 };
529
530 ForwardIDAllocator forward_id_allocators[RendererRD::FORWARD_ID_MAX];
531
532 public:
533 virtual RendererRD::ForwardID allocate_forward_id(RendererRD::ForwardIDType p_type) override;
534 virtual void free_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id) override;
535 virtual void map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) override;
536 virtual bool uses_forward_ids() const override { return true; }
537
538 void fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance);
539 };
540
541 ForwardIDStorageMobile *forward_id_storage_mobile = nullptr;
542
543 virtual RendererRD::ForwardIDStorage *create_forward_id_storage() override {
544 forward_id_storage_mobile = memnew(ForwardIDStorageMobile);
545 return forward_id_storage_mobile;
546 }
547
548public:
549 static RenderForwardMobile *get_singleton() { return singleton; }
550
551 virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override;
552
553 /* SDFGI UPDATE */
554
555 virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
556 virtual int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override { return 0; }
557 virtual AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return AABB(); }
558 virtual uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override { return 0; }
559
560 /* GEOMETRY INSTANCE */
561
562 static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
563 static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
564
565 SelfList<GeometryInstanceForwardMobile>::List geometry_instance_dirty_list;
566
567 PagedAllocator<GeometryInstanceForwardMobile> geometry_instance_alloc;
568 PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
569 PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
570
571 void _geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
572 void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh);
573 void _geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
574 void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance);
575 void _update_dirty_geometry_instances();
576
577 virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override;
578 virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override;
579
580 virtual uint32_t geometry_instance_get_pair_mask() override;
581
582 virtual bool free(RID p_rid) override;
583
584 virtual void base_uniforms_changed() override;
585
586 virtual bool is_dynamic_gi_supported() const override;
587 virtual bool is_volumetric_supported() const override;
588 virtual uint32_t get_max_elements() const override;
589
590 RenderForwardMobile();
591 ~RenderForwardMobile();
592};
593} // namespace RendererSceneRenderImplementation
594
595#endif // RENDER_FORWARD_MOBILE_H
596