From cdb216f4e4096dd45973cb9fd3b9b00d50789e35 Mon Sep 17 00:00:00 2001 From: reduz Date: Tue, 5 Jan 2021 20:01:50 -0300 Subject: [PATCH] Added ability to visualize native shaders --- ...editor_native_shader_source_visualizer.cpp | 72 +++++++++++ .../editor_native_shader_source_visualizer.h | 50 ++++++++ editor/editor_node.cpp | 3 + editor/editor_node.h | 3 + scene/main/canvas_item.h | 2 +- scene/resources/material.cpp | 19 +++ scene/resources/material.h | 7 +- scene/resources/particles_material.h | 2 +- scene/resources/sky_material.h | 6 +- .../renderer_rd/renderer_canvas_render_rd.cpp | 5 + .../renderer_rd/renderer_canvas_render_rd.h | 2 + .../renderer_scene_render_forward.cpp | 6 + .../renderer_scene_render_forward.h | 2 + .../renderer_rd/renderer_scene_render_rd.cpp | 6 + .../renderer_rd/renderer_scene_render_rd.h | 1 + .../renderer_rd/renderer_storage_rd.cpp | 13 ++ .../renderer_rd/renderer_storage_rd.h | 6 + servers/rendering/renderer_rd/shader_rd.cpp | 121 ++++++++++++++++++ servers/rendering/renderer_rd/shader_rd.h | 3 + servers/rendering/renderer_storage.h | 2 + servers/rendering/rendering_server_default.h | 2 + servers/rendering/rendering_server_wrap_mt.h | 2 + servers/rendering_server.h | 13 ++ 23 files changed, 342 insertions(+), 6 deletions(-) create mode 100644 editor/editor_native_shader_source_visualizer.cpp create mode 100644 editor/editor_native_shader_source_visualizer.h diff --git a/editor/editor_native_shader_source_visualizer.cpp b/editor/editor_native_shader_source_visualizer.cpp new file mode 100644 index 00000000000..ed2692190cb --- /dev/null +++ b/editor/editor_native_shader_source_visualizer.cpp @@ -0,0 +1,72 @@ +/*************************************************************************/ +/* editor_native_shader_source_visualizer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_native_shader_source_visualizer.h" + +#include "scene/gui/text_edit.h" + +void EditorNativeShaderSourceVisualizer::_inspect_shader(RID p_shader) { + if (versions) { + memdelete(versions); + versions = nullptr; + } + + RS::ShaderNativeSourceCode nsc = RS::get_singleton()->shader_get_native_source_code(p_shader); + + versions = memnew(TabContainer); + versions->set_v_size_flags(Control::SIZE_EXPAND_FILL); + versions->set_h_size_flags(Control::SIZE_EXPAND_FILL); + for (int i = 0; i < nsc.versions.size(); i++) { + TabContainer *vtab = memnew(TabContainer); + vtab->set_name("Version " + itos(i)); + vtab->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vtab->set_h_size_flags(Control::SIZE_EXPAND_FILL); + versions->add_child(vtab); + for (int j = 0; j < nsc.versions[i].stages.size(); j++) { + TextEdit *vtext = memnew(TextEdit); + vtext->set_readonly(true); + vtext->set_name(nsc.versions[i].stages[j].name); + vtext->set_text(nsc.versions[i].stages[j].code); + vtext->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vtext->set_h_size_flags(Control::SIZE_EXPAND_FILL); + vtab->add_child(vtext); + } + } + add_child(versions); + popup_centered_ratio(); +} + +void EditorNativeShaderSourceVisualizer::_bind_methods() { + ClassDB::bind_method("_inspect_shader", &EditorNativeShaderSourceVisualizer::_inspect_shader); +} +EditorNativeShaderSourceVisualizer::EditorNativeShaderSourceVisualizer() { + add_to_group("_native_shader_source_visualizer"); + set_title(TTR("Native Shader Source Inspector")); +} diff --git a/editor/editor_native_shader_source_visualizer.h b/editor/editor_native_shader_source_visualizer.h new file mode 100644 index 00000000000..72a2f8baae2 --- /dev/null +++ b/editor/editor_native_shader_source_visualizer.h @@ -0,0 +1,50 @@ +/*************************************************************************/ +/* editor_native_shader_source_visualizer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H +#define EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/tab_container.h" + +class EditorNativeShaderSourceVisualizer : public AcceptDialog { + GDCLASS(EditorNativeShaderSourceVisualizer, AcceptDialog) + TabContainer *versions = nullptr; + + void _inspect_shader(RID p_shader); + +protected: + static void _bind_methods(); + +public: + EditorNativeShaderSourceVisualizer(); +}; + +#endif // EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 72d9aacef3c..1cdff65545f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6528,6 +6528,9 @@ EditorNode::EditorNode() { center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized)); + native_shader_source_visualizer = memnew(EditorNativeShaderSourceVisualizer); + gui_base->add_child(native_shader_source_visualizer); + orphan_resources = memnew(OrphanResourcesDialog); gui_base->add_child(orphan_resources); diff --git a/editor/editor_node.h b/editor/editor_node.h index 0ef2e8cbfcd..6e05fc7703f 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -34,6 +34,7 @@ #include "editor/editor_data.h" #include "editor/editor_export.h" #include "editor/editor_folding.h" +#include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_run.h" #include "editor/inspector_dock.h" #include "editor/property_editor.h" @@ -323,6 +324,8 @@ private: String current_path; MenuButton *update_spinner; + EditorNativeShaderSourceVisualizer *native_shader_source_visualizer; + String defer_load_scene; Node *_last_instanced_scene; diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 04e5fda9197..64eb3f4e0aa 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -149,7 +149,7 @@ public: static void finish_shaders(); static void flush_changes(); - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index a5ec9fcba54..445c0d96776 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -36,6 +36,7 @@ #include "editor/editor_settings.h" #endif +#include "scene/main/scene_tree.h" #include "scene/scene_string_names.h" void Material::set_next_pass(const Ref &p_pass) { @@ -80,6 +81,14 @@ void Material::_validate_property(PropertyInfo &property) const { } } +void Material::inspect_native_shader_code() { + SceneTree *st = Object::cast_to(OS::get_singleton()->get_main_loop()); + RID shader = get_shader_rid(); + if (st && shader.is_valid()) { + st->call_group("_native_shader_source_visualizer", "_inspect_shader", shader); + } +} + void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass); ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass); @@ -87,6 +96,9 @@ void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority); ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority); + ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Material::inspect_native_shader_code); + ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); @@ -260,6 +272,13 @@ Shader::Mode ShaderMaterial::get_shader_mode() const { return Shader::MODE_SPATIAL; } } +RID ShaderMaterial::get_shader_rid() const { + if (shader.is_valid()) { + return shader->get_rid(); + } else { + return RID(); + } +} ShaderMaterial::ShaderMaterial() { } diff --git a/scene/resources/material.h b/scene/resources/material.h index a2183a65e44..0048b43c8bf 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -47,6 +47,8 @@ class Material : public Resource { Ref next_pass; int render_priority; + void inspect_native_shader_code(); + protected: _FORCE_INLINE_ RID _get_material() const { return material; } static void _bind_methods(); @@ -66,6 +68,7 @@ public: int get_render_priority() const; virtual RID get_rid() const override; + virtual RID get_shader_rid() const = 0; virtual Shader::Mode get_shader_mode() const = 0; Material(); @@ -100,6 +103,8 @@ public: virtual Shader::Mode get_shader_mode() const override; + virtual RID get_shader_rid() const override; + ShaderMaterial(); ~ShaderMaterial(); }; @@ -736,7 +741,7 @@ public: static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false); - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index e699a8fb6d0..49b48a01b7e 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -340,7 +340,7 @@ public: void set_sub_emitter_keep_velocity(bool p_enable); bool get_sub_emitter_keep_velocity() const; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; virtual Shader::Mode get_shader_mode() const override; diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 6f9dfbee4a1..8fe015519db 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -89,7 +89,7 @@ public: float get_sun_curve() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; ProceduralSkyMaterial(); ~ProceduralSkyMaterial(); @@ -114,7 +114,7 @@ public: Ref get_panorama() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; PanoramaSkyMaterial(); ~PanoramaSkyMaterial(); @@ -180,7 +180,7 @@ public: Ref get_night_sky() const; virtual Shader::Mode get_shader_mode() const override; - RID get_shader_rid() const; + virtual RID get_shader_rid() const override; PhysicalSkyMaterial(); ~PhysicalSkyMaterial(); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 05ffc0086dd..5b3c3c703fc 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2239,6 +2239,11 @@ Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringNa return Variant(); } +RS::ShaderNativeSourceCode RendererCanvasRenderRD::ShaderData::get_native_source_code() const { + RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton; + return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version); +} + RendererCanvasRenderRD::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 545eeaa1064..cb947d71803 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -188,6 +188,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ShaderData(); virtual ~ShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index c0939f23eff..1d07741296b 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -394,6 +394,12 @@ Variant RendererSceneRenderForward::ShaderData::get_default_parameter(const Stri return Variant(); } +RS::ShaderNativeSourceCode RendererSceneRenderForward::ShaderData::get_native_source_code() const { + RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton; + + return scene_singleton->shader.scene_shader.version_get_native_source_code(version); +} + RendererSceneRenderForward::ShaderData::ShaderData() { valid = false; uses_screen_texture = false; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h index 8a6f268c467..3b5a5ad96fc 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -169,6 +169,8 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ShaderData(); virtual ~ShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index dad08179e71..188bcde8d77 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2674,6 +2674,12 @@ Variant RendererSceneRenderRD::SkyShaderData::get_default_parameter(const String return Variant(); } +RS::ShaderNativeSourceCode RendererSceneRenderRD::SkyShaderData::get_native_source_code() const { + RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton; + + return scene_singleton->sky_shader.shader.version_get_native_source_code(version); +} + RendererSceneRenderRD::SkyShaderData::SkyShaderData() { valid = false; } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index f81a35f0257..3f9c117602c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -233,6 +233,7 @@ private: virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; SkyShaderData(); virtual ~SkyShaderData(); }; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index bf7237cad02..1ffc024d427 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -1499,6 +1499,15 @@ void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_typ shader_data_request_func[p_shader_type] = p_function; } +RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID p_shader) const { + Shader *shader = shader_owner.getornull(p_shader); + ERR_FAIL_COND_V(!shader, RS::ShaderNativeSourceCode()); + if (shader->data) { + return shader->data->get_native_source_code(); + } + return RS::ShaderNativeSourceCode(); +} + /* COMMON MATERIAL API */ RID RendererStorageRD::material_create() { @@ -4823,6 +4832,10 @@ Variant RendererStorageRD::ParticlesShaderData::get_default_parameter(const Stri return Variant(); } +RS::ShaderNativeSourceCode RendererStorageRD::ParticlesShaderData::get_native_source_code() const { + return base_singleton->particles_shader.shader.version_get_native_source_code(version); +} + RendererStorageRD::ParticlesShaderData::ParticlesShaderData() { valid = false; } diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index bd27936e38c..5ef73f0db85 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -127,6 +127,8 @@ public: virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; + virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } + virtual ~ShaderData() {} }; @@ -840,6 +842,8 @@ private: virtual bool is_animated() const; virtual bool casts_shadows() const; virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + ParticlesShaderData(); virtual ~ParticlesShaderData(); }; @@ -1339,6 +1343,8 @@ public: Variant shader_get_param_default(RID p_shader, const StringName &p_param) const; void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function); + virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const; + /* COMMON MATERIAL API */ RID material_create(); diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index e955cead05c..2ae22a8a384 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -351,6 +351,127 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } } +RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_version) { + Version *version = version_owner.getornull(p_version); + RS::ShaderNativeSourceCode source_code; + ERR_FAIL_COND_V(!version, source_code); + + source_code.versions.resize(variant_defines.size()); + + for (int i = 0; i < source_code.versions.size(); i++) { + if (!is_compute) { + //vertex stage + + StringBuilder builder; + + builder.append(vertex_codev.get_data()); // version info (if exists) + builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); + builder.append(variant_defines[i].get_data()); + + for (int j = 0; j < version->custom_defines.size(); j++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(vertex_code0.get_data()); //first part of vertex + + builder.append(version->uniforms.get_data()); //uniforms (same for vertex and fragment) + + builder.append(vertex_code1.get_data()); //second part of vertex + + builder.append(version->vertex_globals.get_data()); // vertex globals + + builder.append(vertex_code2.get_data()); //third part of vertex + + builder.append(version->vertex_code.get_data()); // code + + builder.append(vertex_code3.get_data()); //fourth of vertex + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "vertex"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + + if (!is_compute) { + //fragment stage + + StringBuilder builder; + + builder.append(fragment_codev.get_data()); // version info (if exists) + builder.append("\n"); //make sure defines begin at newline + + builder.append(general_defines.get_data()); + builder.append(variant_defines[i].get_data()); + for (int j = 0; j < version->custom_defines.size(); j++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(fragment_code0.get_data()); //first part of fragment + + builder.append(version->uniforms.get_data()); //uniforms (same for fragment and fragment) + + builder.append(fragment_code1.get_data()); //first part of fragment + + builder.append(version->fragment_globals.get_data()); // fragment globals + + builder.append(fragment_code2.get_data()); //third part of fragment + + builder.append(version->fragment_light.get_data()); // fragment light + + builder.append(fragment_code3.get_data()); //fourth part of fragment + + builder.append(version->fragment_code.get_data()); // fragment code + + builder.append(fragment_code4.get_data()); //fourth part of fragment + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "fragment"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + + if (is_compute) { + //compute stage + + StringBuilder builder; + + builder.append(compute_codev.get_data()); // version info (if exists) + builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); + builder.append(variant_defines[i].get_data()); + + for (int j = 0; j < version->custom_defines.size(); j++) { + builder.append(version->custom_defines[j].get_data()); + } + + builder.append(compute_code0.get_data()); //first part of compute + + builder.append(version->uniforms.get_data()); //uniforms (same for compute and fragment) + + builder.append(compute_code1.get_data()); //second part of compute + + builder.append(version->compute_globals.get_data()); // compute globals + + builder.append(compute_code2.get_data()); //third part of compute + + builder.append(version->compute_code.get_data()); // code + + builder.append(compute_code3.get_data()); //fourth of compute + + RS::ShaderNativeSourceCode::Version::Stage stage; + stage.name = "compute"; + stage.code = builder.as_string(); + + source_code.versions.write[i].stages.push_back(stage); + } + } + + return source_code; +} + void ShaderRD::_compile_version(Version *p_version) { _clear_version(p_version); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index a80d08050a6..a3474c6f93c 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -36,6 +36,7 @@ #include "core/templates/map.h" #include "core/templates/rid_owner.h" #include "core/variant/variant.h" +#include "servers/rendering_server.h" #include /** @@ -133,6 +134,8 @@ public: void set_variant_enabled(int p_variant, bool p_enabled); bool is_variant_enabled(int p_variant) const; + RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version); + void initialize(const Vector &p_variant_defines, const String &p_general_defines = ""); virtual ~ShaderRD(); }; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 3e53f7130a0..64c23c78032 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -179,6 +179,8 @@ public: virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0; + virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0; + /* COMMON MATERIAL API */ virtual RID material_create() = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 3ccb5c4bbc8..71f459f34a7 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -219,6 +219,8 @@ public: BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &) BIND2RC(Variant, shader_get_param_default, RID, const StringName &) + BIND1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) + /* COMMON MATERIAL API */ BIND0R(RID, material_create) diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 29ee846f319..3db90c32dfc 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -129,6 +129,8 @@ public: FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) + FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) + /* COMMON MATERIAL API */ FUNCRID(material) diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 5481079694c..74bdb344bd7 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -179,6 +179,19 @@ public: virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0; virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0; + struct ShaderNativeSourceCode { + struct Version { + struct Stage { + String name; + String code; + }; + Vector stages; + }; + Vector versions; + }; + + virtual ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0; + /* COMMON MATERIAL API */ enum {