1/**************************************************************************/
2/* material_storage.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 MATERIAL_STORAGE_GLES3_H
32#define MATERIAL_STORAGE_GLES3_H
33
34#ifdef GLES3_ENABLED
35
36#include "core/templates/local_vector.h"
37#include "core/templates/rid_owner.h"
38#include "core/templates/self_list.h"
39#include "servers/rendering/renderer_compositor.h"
40#include "servers/rendering/shader_compiler.h"
41#include "servers/rendering/shader_language.h"
42#include "servers/rendering/storage/material_storage.h"
43#include "servers/rendering/storage/utilities.h"
44
45#include "drivers/gles3/shaders/canvas.glsl.gen.h"
46#include "drivers/gles3/shaders/cubemap_filter.glsl.gen.h"
47#include "drivers/gles3/shaders/particles.glsl.gen.h"
48#include "drivers/gles3/shaders/scene.glsl.gen.h"
49#include "drivers/gles3/shaders/sky.glsl.gen.h"
50
51namespace GLES3 {
52
53/* Shader Structs */
54
55struct ShaderData {
56 String path;
57 HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
58 HashMap<StringName, HashMap<int, RID>> default_texture_params;
59
60 virtual void set_path_hint(const String &p_hint);
61 virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index);
62 virtual Variant get_default_parameter(const StringName &p_parameter) const;
63 virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const;
64 virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
65 virtual bool is_parameter_texture(const StringName &p_param) const;
66
67 virtual void set_code(const String &p_Code) = 0;
68 virtual bool is_animated() const = 0;
69 virtual bool casts_shadows() const = 0;
70 virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); }
71
72 virtual ~ShaderData() {}
73};
74
75typedef ShaderData *(*ShaderDataRequestFunction)();
76
77struct Material;
78
79struct Shader {
80 ShaderData *data = nullptr;
81 String code;
82 String path_hint;
83 RS::ShaderMode mode;
84 HashMap<StringName, HashMap<int, RID>> default_texture_parameter;
85 HashSet<Material *> owners;
86};
87
88/* Material structs */
89
90struct MaterialData {
91 void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size);
92 void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
93
94 virtual void set_render_priority(int p_priority) = 0;
95 virtual void set_next_pass(RID p_pass) = 0;
96 virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
97 virtual void bind_uniforms() = 0;
98 virtual ~MaterialData();
99
100 // Used internally by all Materials
101 void update_parameters_internal(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, bool p_is_3d_shader_type);
102
103protected:
104 Vector<uint8_t> ubo_data;
105 GLuint uniform_buffer = GLuint(0);
106 Vector<RID> texture_cache;
107
108private:
109 friend class MaterialStorage;
110 RID self;
111 List<RID>::Element *global_buffer_E = nullptr;
112 List<RID>::Element *global_texture_E = nullptr;
113 uint64_t global_textures_pass = 0;
114 HashMap<StringName, uint64_t> used_global_textures;
115};
116
117typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
118
119struct Material {
120 RID self;
121 MaterialData *data = nullptr;
122 Shader *shader = nullptr;
123 //shortcut to shader data and type
124 RS::ShaderMode shader_mode = RS::SHADER_MAX;
125 uint32_t shader_id = 0;
126 bool uniform_dirty = false;
127 bool texture_dirty = false;
128 HashMap<StringName, Variant> params;
129 int32_t priority = 0;
130 RID next_pass;
131 SelfList<Material> update_element;
132
133 Dependency dependency;
134
135 Material() :
136 update_element(this) {}
137};
138
139/* CanvasItem Materials */
140
141struct CanvasShaderData : public ShaderData {
142 enum BlendMode { //used internally
143 BLEND_MODE_MIX,
144 BLEND_MODE_ADD,
145 BLEND_MODE_SUB,
146 BLEND_MODE_MUL,
147 BLEND_MODE_PMALPHA,
148 BLEND_MODE_DISABLED,
149 BLEND_MODE_LCD,
150 };
151
152 bool valid;
153 RID version;
154 BlendMode blend_mode = BLEND_MODE_MIX;
155
156 Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
157
158 Vector<uint32_t> ubo_offsets;
159 uint32_t ubo_size;
160
161 String code;
162
163 bool uses_screen_texture = false;
164 bool uses_screen_texture_mipmaps = false;
165 bool uses_sdf = false;
166 bool uses_time = false;
167
168 virtual void set_code(const String &p_Code);
169 virtual bool is_animated() const;
170 virtual bool casts_shadows() const;
171 virtual RS::ShaderNativeSourceCode get_native_source_code() const;
172
173 CanvasShaderData();
174 virtual ~CanvasShaderData();
175};
176
177ShaderData *_create_canvas_shader_func();
178
179struct CanvasMaterialData : public MaterialData {
180 CanvasShaderData *shader_data = nullptr;
181
182 virtual void set_render_priority(int p_priority) {}
183 virtual void set_next_pass(RID p_pass) {}
184 virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
185 virtual void bind_uniforms();
186 virtual ~CanvasMaterialData();
187};
188
189MaterialData *_create_canvas_material_func(ShaderData *p_shader);
190
191/* Sky Materials */
192
193struct SkyShaderData : public ShaderData {
194 bool valid;
195 RID version;
196
197 Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
198
199 Vector<uint32_t> ubo_offsets;
200 uint32_t ubo_size;
201
202 String code;
203
204 bool uses_time;
205 bool uses_position;
206 bool uses_half_res;
207 bool uses_quarter_res;
208 bool uses_light;
209
210 virtual void set_code(const String &p_Code);
211 virtual bool is_animated() const;
212 virtual bool casts_shadows() const;
213 virtual RS::ShaderNativeSourceCode get_native_source_code() const;
214 SkyShaderData();
215 virtual ~SkyShaderData();
216};
217
218ShaderData *_create_sky_shader_func();
219
220struct SkyMaterialData : public MaterialData {
221 SkyShaderData *shader_data = nullptr;
222 bool uniform_set_updated = false;
223
224 virtual void set_render_priority(int p_priority) {}
225 virtual void set_next_pass(RID p_pass) {}
226 virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
227 virtual void bind_uniforms();
228 virtual ~SkyMaterialData();
229};
230
231MaterialData *_create_sky_material_func(ShaderData *p_shader);
232
233/* Scene Materials */
234
235struct SceneShaderData : public ShaderData {
236 enum BlendMode { //used internally
237 BLEND_MODE_MIX,
238 BLEND_MODE_ADD,
239 BLEND_MODE_SUB,
240 BLEND_MODE_MUL,
241 BLEND_MODE_ALPHA_TO_COVERAGE
242 };
243
244 enum DepthDraw {
245 DEPTH_DRAW_DISABLED,
246 DEPTH_DRAW_OPAQUE,
247 DEPTH_DRAW_ALWAYS
248 };
249
250 enum DepthTest {
251 DEPTH_TEST_DISABLED,
252 DEPTH_TEST_ENABLED
253 };
254
255 enum Cull {
256 CULL_DISABLED,
257 CULL_FRONT,
258 CULL_BACK
259 };
260
261 enum AlphaAntiAliasing {
262 ALPHA_ANTIALIASING_OFF,
263 ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
264 ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
265 };
266
267 bool valid;
268 RID version;
269
270 Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
271
272 Vector<uint32_t> ubo_offsets;
273 uint32_t ubo_size;
274
275 String code;
276
277 BlendMode blend_mode;
278 AlphaAntiAliasing alpha_antialiasing_mode;
279 DepthDraw depth_draw;
280 DepthTest depth_test;
281 Cull cull_mode;
282
283 bool uses_point_size;
284 bool uses_alpha;
285 bool uses_blend_alpha;
286 bool uses_alpha_clip;
287 bool uses_depth_prepass_alpha;
288 bool uses_discard;
289 bool uses_roughness;
290 bool uses_normal;
291 bool uses_particle_trails;
292 bool wireframe;
293
294 bool unshaded;
295 bool uses_vertex;
296 bool uses_position;
297 bool uses_sss;
298 bool uses_transmittance;
299 bool uses_screen_texture;
300 bool uses_screen_texture_mipmaps;
301 bool uses_depth_texture;
302 bool uses_normal_texture;
303 bool uses_time;
304 bool uses_vertex_time;
305 bool uses_fragment_time;
306 bool writes_modelview_or_projection;
307 bool uses_world_coordinates;
308 bool uses_tangent;
309 bool uses_color;
310 bool uses_uv;
311 bool uses_uv2;
312 bool uses_custom0;
313 bool uses_custom1;
314 bool uses_custom2;
315 bool uses_custom3;
316 bool uses_bones;
317 bool uses_weights;
318
319 uint32_t vertex_input_mask = 0;
320
321 uint64_t last_pass = 0;
322 uint32_t index = 0;
323
324 virtual void set_code(const String &p_Code);
325 virtual bool is_animated() const;
326 virtual bool casts_shadows() const;
327 virtual RS::ShaderNativeSourceCode get_native_source_code() const;
328
329 SceneShaderData();
330 virtual ~SceneShaderData();
331};
332
333ShaderData *_create_scene_shader_func();
334
335struct SceneMaterialData : public MaterialData {
336 SceneShaderData *shader_data = nullptr;
337 uint64_t last_pass = 0;
338 uint32_t index = 0;
339 RID next_pass;
340 uint8_t priority = 0;
341 virtual void set_render_priority(int p_priority);
342 virtual void set_next_pass(RID p_pass);
343 virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
344 virtual void bind_uniforms();
345 virtual ~SceneMaterialData();
346};
347
348MaterialData *_create_scene_material_func(ShaderData *p_shader);
349
350/* Particle Shader */
351
352enum {
353 PARTICLES_MAX_USERDATAS = 6
354};
355
356struct ParticlesShaderData : public ShaderData {
357 bool valid = false;
358 RID version;
359 bool uses_collision = false;
360
361 Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
362
363 Vector<uint32_t> ubo_offsets;
364 uint32_t ubo_size = 0;
365
366 String code;
367
368 bool uses_time = false;
369
370 bool userdatas_used[PARTICLES_MAX_USERDATAS] = {};
371 uint32_t userdata_count = 0;
372
373 virtual void set_code(const String &p_Code);
374 virtual bool is_animated() const;
375 virtual bool casts_shadows() const;
376 virtual RS::ShaderNativeSourceCode get_native_source_code() const;
377
378 ParticlesShaderData() {}
379 virtual ~ParticlesShaderData();
380};
381
382ShaderData *_create_particles_shader_func();
383
384struct ParticleProcessMaterialData : public MaterialData {
385 ParticlesShaderData *shader_data = nullptr;
386 RID uniform_set;
387
388 virtual void set_render_priority(int p_priority) {}
389 virtual void set_next_pass(RID p_pass) {}
390 virtual void update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
391 virtual void bind_uniforms();
392 virtual ~ParticleProcessMaterialData();
393};
394
395MaterialData *_create_particles_material_func(ShaderData *p_shader);
396
397/* Global shader uniform structs */
398struct GlobalShaderUniforms {
399 enum {
400 BUFFER_DIRTY_REGION_SIZE = 1024
401 };
402 struct Variable {
403 HashSet<RID> texture_materials; // materials using this
404
405 RS::GlobalShaderParameterType type;
406 Variant value;
407 Variant override;
408 int32_t buffer_index; //for vectors
409 int32_t buffer_elements; //for vectors
410 };
411
412 HashMap<StringName, Variable> variables;
413
414 struct Value {
415 float x;
416 float y;
417 float z;
418 float w;
419 };
420
421 struct ValueInt {
422 int32_t x;
423 int32_t y;
424 int32_t z;
425 int32_t w;
426 };
427
428 struct ValueUInt {
429 uint32_t x;
430 uint32_t y;
431 uint32_t z;
432 uint32_t w;
433 };
434
435 struct ValueUsage {
436 uint32_t elements = 0;
437 };
438
439 List<RID> materials_using_buffer;
440 List<RID> materials_using_texture;
441
442 GLuint buffer = GLuint(0);
443 Value *buffer_values = nullptr;
444 ValueUsage *buffer_usage = nullptr;
445 bool *buffer_dirty_regions = nullptr;
446 uint32_t buffer_dirty_region_count = 0;
447
448 uint32_t buffer_size;
449
450 bool must_update_texture_materials = false;
451 bool must_update_buffer_materials = false;
452
453 HashMap<RID, int32_t> instance_buffer_pos;
454};
455
456class MaterialStorage : public RendererMaterialStorage {
457private:
458 friend struct MaterialData;
459 static MaterialStorage *singleton;
460
461 /* GLOBAL SHADER UNIFORM API */
462
463 GlobalShaderUniforms global_shader_uniforms;
464
465 int32_t _global_shader_uniform_allocate(uint32_t p_elements);
466 void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value);
467 void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements);
468
469 /* SHADER API */
470
471 ShaderDataRequestFunction shader_data_request_func[RS::SHADER_MAX];
472 mutable RID_Owner<Shader, true> shader_owner;
473
474 /* MATERIAL API */
475 MaterialDataRequestFunction material_data_request_func[RS::SHADER_MAX];
476 mutable RID_Owner<Material, true> material_owner;
477
478 SelfList<Material>::List material_update_list;
479
480public:
481 static MaterialStorage *get_singleton();
482
483 MaterialStorage();
484 virtual ~MaterialStorage();
485
486 static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
487 p_array[0] = p_mtx.basis.rows[0][0];
488 p_array[1] = p_mtx.basis.rows[1][0];
489 p_array[2] = p_mtx.basis.rows[2][0];
490 p_array[3] = 0;
491 p_array[4] = p_mtx.basis.rows[0][1];
492 p_array[5] = p_mtx.basis.rows[1][1];
493 p_array[6] = p_mtx.basis.rows[2][1];
494 p_array[7] = 0;
495 p_array[8] = p_mtx.basis.rows[0][2];
496 p_array[9] = p_mtx.basis.rows[1][2];
497 p_array[10] = p_mtx.basis.rows[2][2];
498 p_array[11] = 0;
499 p_array[12] = p_mtx.origin.x;
500 p_array[13] = p_mtx.origin.y;
501 p_array[14] = p_mtx.origin.z;
502 p_array[15] = 1;
503 }
504
505 static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
506 p_array[0] = p_mtx.rows[0][0];
507 p_array[1] = p_mtx.rows[1][0];
508 p_array[2] = p_mtx.rows[2][0];
509 p_array[3] = 0;
510 p_array[4] = p_mtx.rows[0][1];
511 p_array[5] = p_mtx.rows[1][1];
512 p_array[6] = p_mtx.rows[2][1];
513 p_array[7] = 0;
514 p_array[8] = p_mtx.rows[0][2];
515 p_array[9] = p_mtx.rows[1][2];
516 p_array[10] = p_mtx.rows[2][2];
517 p_array[11] = 0;
518 }
519
520 static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) {
521 for (int i = 0; i < 4; i++) {
522 for (int j = 0; j < 4; j++) {
523 p_array[i * 4 + j] = p_mtx.columns[i][j];
524 }
525 }
526 }
527
528 struct Shaders {
529 CanvasShaderGLES3 canvas_shader;
530 SkyShaderGLES3 sky_shader;
531 SceneShaderGLES3 scene_shader;
532 CubemapFilterShaderGLES3 cubemap_filter_shader;
533 ParticlesShaderGLES3 particles_process_shader;
534
535 ShaderCompiler compiler_canvas;
536 ShaderCompiler compiler_scene;
537 ShaderCompiler compiler_particles;
538 ShaderCompiler compiler_sky;
539 } shaders;
540
541 /* GLOBAL SHADER UNIFORM API */
542
543 void _update_global_shader_uniforms();
544
545 virtual void global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) override;
546 virtual void global_shader_parameter_remove(const StringName &p_name) override;
547 virtual Vector<StringName> global_shader_parameter_get_list() const override;
548
549 virtual void global_shader_parameter_set(const StringName &p_name, const Variant &p_value) override;
550 virtual void global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) override;
551 virtual Variant global_shader_parameter_get(const StringName &p_name) const override;
552 virtual RS::GlobalShaderParameterType global_shader_parameter_get_type(const StringName &p_name) const override;
553 RS::GlobalShaderParameterType global_shader_parameter_get_type_internal(const StringName &p_name) const;
554
555 virtual void global_shader_parameters_load_settings(bool p_load_textures = true) override;
556 virtual void global_shader_parameters_clear() override;
557
558 virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override;
559 virtual void global_shader_parameters_instance_free(RID p_instance) override;
560 virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override;
561
562 GLuint global_shader_parameters_get_uniform_buffer() const;
563
564 /* SHADER API */
565
566 Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
567 bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
568
569 void _shader_make_dirty(Shader *p_shader);
570
571 virtual RID shader_allocate() override;
572 virtual void shader_initialize(RID p_rid) override;
573 virtual void shader_free(RID p_rid) override;
574
575 virtual void shader_set_code(RID p_shader, const String &p_code) override;
576 virtual void shader_set_path_hint(RID p_shader, const String &p_path) override;
577 virtual String shader_get_code(RID p_shader) const override;
578 virtual void get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
579
580 virtual void shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
581 virtual RID shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const override;
582 virtual Variant shader_get_parameter_default(RID p_shader, const StringName &p_name) const override;
583
584 virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override;
585
586 /* MATERIAL API */
587
588 Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
589 bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
590
591 void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
592 void _update_queued_materials();
593
594 virtual RID material_allocate() override;
595 virtual void material_initialize(RID p_rid) override;
596 virtual void material_free(RID p_rid) override;
597
598 virtual void material_set_shader(RID p_material, RID p_shader) override;
599
600 virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
601 virtual Variant material_get_param(RID p_material, const StringName &p_param) const override;
602
603 virtual void material_set_next_pass(RID p_material, RID p_next_material) override;
604 virtual void material_set_render_priority(RID p_material, int priority) override;
605
606 virtual bool material_is_animated(RID p_material) override;
607 virtual bool material_casts_shadows(RID p_material) override;
608
609 virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
610
611 virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override;
612
613 _FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
614 Material *material = material_owner.get_or_null(p_material);
615 return material->shader_id;
616 }
617
618 _FORCE_INLINE_ MaterialData *material_get_data(RID p_material, RS::ShaderMode p_shader_mode) {
619 Material *material = material_owner.get_or_null(p_material);
620 if (!material || material->shader_mode != p_shader_mode) {
621 return nullptr;
622 } else {
623 return material->data;
624 }
625 }
626};
627
628} // namespace GLES3
629
630#endif // GLES3_ENABLED
631
632#endif // MATERIAL_STORAGE_GLES3_H
633