|
@@ -30,146 +30,83 @@
|
|
|
|
|
|
#include "shader_rd.h"
|
|
#include "shader_rd.h"
|
|
|
|
|
|
-#include "core/string/string_builder.h"
|
|
|
|
#include "renderer_compositor_rd.h"
|
|
#include "renderer_compositor_rd.h"
|
|
#include "servers/rendering/rendering_device.h"
|
|
#include "servers/rendering/rendering_device.h"
|
|
|
|
|
|
-void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) {
|
|
|
|
- name = p_name;
|
|
|
|
- //split vertex and shader code (thank you, shader compiler programmers from you know what company).
|
|
|
|
- if (p_vertex_code) {
|
|
|
|
- String defines_tag = "\nVERSION_DEFINES";
|
|
|
|
- String globals_tag = "\nVERTEX_SHADER_GLOBALS";
|
|
|
|
- String material_tag = "\nMATERIAL_UNIFORMS";
|
|
|
|
- String code_tag = "\nVERTEX_SHADER_CODE";
|
|
|
|
- String code = p_vertex_code;
|
|
|
|
-
|
|
|
|
- int cpos = code.find(defines_tag);
|
|
|
|
- if (cpos != -1) {
|
|
|
|
- vertex_codev = code.substr(0, cpos).ascii();
|
|
|
|
- code = code.substr(cpos + defines_tag.length(), code.length());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- cpos = code.find(material_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- vertex_code0 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- vertex_code0 = code.substr(0, cpos).ascii();
|
|
|
|
- code = code.substr(cpos + material_tag.length(), code.length());
|
|
|
|
-
|
|
|
|
- cpos = code.find(globals_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- vertex_code1 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- vertex_code1 = code.substr(0, cpos).ascii();
|
|
|
|
- String code2 = code.substr(cpos + globals_tag.length(), code.length());
|
|
|
|
-
|
|
|
|
- cpos = code2.find(code_tag);
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- vertex_code2 = code2.ascii();
|
|
|
|
- } else {
|
|
|
|
- vertex_code2 = code2.substr(0, cpos).ascii();
|
|
|
|
- vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii();
|
|
|
|
|
|
+void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
|
|
|
|
+ Vector<String> lines = String(p_code).split("\n");
|
|
|
|
+
|
|
|
|
+ String text;
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < lines.size(); i++) {
|
|
|
|
+ String l = lines[i];
|
|
|
|
+ bool push_chunk = false;
|
|
|
|
+
|
|
|
|
+ StageTemplate::Chunk chunk;
|
|
|
|
+
|
|
|
|
+ if (l.begins_with("#VERSION_DEFINES")) {
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_VERSION_DEFINES;
|
|
|
|
+ push_chunk = true;
|
|
|
|
+ } else if (l.begins_with("#GLOBALS")) {
|
|
|
|
+ switch (p_stage_type) {
|
|
|
|
+ case STAGE_TYPE_VERTEX:
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_VERTEX_GLOBALS;
|
|
|
|
+ break;
|
|
|
|
+ case STAGE_TYPE_FRAGMENT:
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS;
|
|
|
|
+ break;
|
|
|
|
+ case STAGE_TYPE_COMPUTE:
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_COMPUTE_GLOBALS;
|
|
|
|
+ break;
|
|
|
|
+ default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if (p_fragment_code) {
|
|
|
|
- String defines_tag = "\nVERSION_DEFINES";
|
|
|
|
- String globals_tag = "\nFRAGMENT_SHADER_GLOBALS";
|
|
|
|
- String material_tag = "\nMATERIAL_UNIFORMS";
|
|
|
|
- String code_tag = "\nFRAGMENT_SHADER_CODE";
|
|
|
|
- String light_code_tag = "\nLIGHT_SHADER_CODE";
|
|
|
|
- String code = p_fragment_code;
|
|
|
|
-
|
|
|
|
- int cpos = code.find(defines_tag);
|
|
|
|
- if (cpos != -1) {
|
|
|
|
- fragment_codev = code.substr(0, cpos).ascii();
|
|
|
|
- code = code.substr(cpos + defines_tag.length(), code.length());
|
|
|
|
|
|
+ push_chunk = true;
|
|
|
|
+ } else if (l.begins_with("#MATERIAL_UNIFORMS")) {
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS;
|
|
|
|
+ push_chunk = true;
|
|
|
|
+ } else if (l.begins_with("#CODE")) {
|
|
|
|
+ chunk.type = StageTemplate::Chunk::TYPE_CODE;
|
|
|
|
+ push_chunk = true;
|
|
|
|
+ chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper();
|
|
|
|
+ } else {
|
|
|
|
+ text += l + "\n";
|
|
}
|
|
}
|
|
|
|
|
|
- cpos = code.find(material_tag);
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- fragment_code0 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- fragment_code0 = code.substr(0, cpos).ascii();
|
|
|
|
- //print_line("CODE0:\n"+String(fragment_code0.get_data()));
|
|
|
|
- code = code.substr(cpos + material_tag.length(), code.length());
|
|
|
|
- cpos = code.find(globals_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- fragment_code1 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- fragment_code1 = code.substr(0, cpos).ascii();
|
|
|
|
- //print_line("CODE1:\n"+String(fragment_code1.get_data()));
|
|
|
|
-
|
|
|
|
- String code2 = code.substr(cpos + globals_tag.length(), code.length());
|
|
|
|
- cpos = code2.find(light_code_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- fragment_code2 = code2.ascii();
|
|
|
|
- } else {
|
|
|
|
- fragment_code2 = code2.substr(0, cpos).ascii();
|
|
|
|
- //print_line("CODE2:\n"+String(fragment_code2.get_data()));
|
|
|
|
-
|
|
|
|
- String code3 = code2.substr(cpos + light_code_tag.length(), code2.length());
|
|
|
|
-
|
|
|
|
- cpos = code3.find(code_tag);
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- fragment_code3 = code3.ascii();
|
|
|
|
- } else {
|
|
|
|
- fragment_code3 = code3.substr(0, cpos).ascii();
|
|
|
|
- //print_line("CODE3:\n"+String(fragment_code3.get_data()));
|
|
|
|
- fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii();
|
|
|
|
- //print_line("CODE4:\n"+String(fragment_code4.get_data()));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (push_chunk) {
|
|
|
|
+ if (text != String()) {
|
|
|
|
+ StageTemplate::Chunk text_chunk;
|
|
|
|
+ text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
|
|
|
|
+ text_chunk.text = text.utf8();
|
|
|
|
+ stage_templates[p_stage_type].chunks.push_back(text_chunk);
|
|
|
|
+ text = String();
|
|
}
|
|
}
|
|
|
|
+ stage_templates[p_stage_type].chunks.push_back(chunk);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (text != String()) {
|
|
|
|
+ StageTemplate::Chunk text_chunk;
|
|
|
|
+ text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
|
|
|
|
+ text_chunk.text = text.utf8();
|
|
|
|
+ stage_templates[p_stage_type].chunks.push_back(text_chunk);
|
|
|
|
+ text = String();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) {
|
|
|
|
+ name = p_name;
|
|
if (p_compute_code) {
|
|
if (p_compute_code) {
|
|
|
|
+ _add_stage(p_compute_code, STAGE_TYPE_COMPUTE);
|
|
is_compute = true;
|
|
is_compute = true;
|
|
-
|
|
|
|
- String defines_tag = "\nVERSION_DEFINES";
|
|
|
|
- String globals_tag = "\nCOMPUTE_SHADER_GLOBALS";
|
|
|
|
- String material_tag = "\nMATERIAL_UNIFORMS";
|
|
|
|
- String code_tag = "\nCOMPUTE_SHADER_CODE";
|
|
|
|
- String code = p_compute_code;
|
|
|
|
-
|
|
|
|
- int cpos = code.find(defines_tag);
|
|
|
|
- if (cpos != -1) {
|
|
|
|
- compute_codev = code.substr(0, cpos).ascii();
|
|
|
|
- code = code.substr(cpos + defines_tag.length(), code.length());
|
|
|
|
|
|
+ } else {
|
|
|
|
+ is_compute = false;
|
|
|
|
+ if (p_vertex_code) {
|
|
|
|
+ _add_stage(p_vertex_code, STAGE_TYPE_VERTEX);
|
|
}
|
|
}
|
|
-
|
|
|
|
- cpos = code.find(material_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- compute_code0 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- compute_code0 = code.substr(0, cpos).ascii();
|
|
|
|
- code = code.substr(cpos + material_tag.length(), code.length());
|
|
|
|
-
|
|
|
|
- cpos = code.find(globals_tag);
|
|
|
|
-
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- compute_code1 = code.ascii();
|
|
|
|
- } else {
|
|
|
|
- compute_code1 = code.substr(0, cpos).ascii();
|
|
|
|
- String code2 = code.substr(cpos + globals_tag.length(), code.length());
|
|
|
|
-
|
|
|
|
- cpos = code2.find(code_tag);
|
|
|
|
- if (cpos == -1) {
|
|
|
|
- compute_code2 = code2.ascii();
|
|
|
|
- } else {
|
|
|
|
- compute_code2 = code2.substr(0, cpos).ascii();
|
|
|
|
- compute_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (p_fragment_code) {
|
|
|
|
+ _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -198,6 +135,49 @@ void ShaderRD::_clear_version(Version *p_version) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template) {
|
|
|
|
+ for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
|
|
|
|
+ const StageTemplate::Chunk &chunk = p_template.chunks[i];
|
|
|
|
+ switch (chunk.type) {
|
|
|
|
+ case StageTemplate::Chunk::TYPE_VERSION_DEFINES: {
|
|
|
|
+ builder.append("\n"); //make sure defines begin at newline
|
|
|
|
+ builder.append(general_defines.get_data());
|
|
|
|
+ builder.append(variant_defines[p_variant].get_data());
|
|
|
|
+ for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
|
|
|
+ builder.append(p_version->custom_defines[j].get_data());
|
|
|
|
+ }
|
|
|
|
+ builder.append("\n"); //make sure defines begin at newline
|
|
|
|
+ if (p_version->uniforms.size()) {
|
|
|
|
+ builder.append("#define MATERIAL_UNIFORMS_USED\n");
|
|
|
|
+ }
|
|
|
|
+ for (Map<StringName, CharString>::Element *E = p_version->code_sections.front(); E; E = E->next()) {
|
|
|
|
+ builder.append(String("#define ") + String(E->key()) + "_CODE_USED\n");
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: {
|
|
|
|
+ builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_VERTEX_GLOBALS: {
|
|
|
|
+ builder.append(p_version->vertex_globals.get_data()); // vertex globals
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS: {
|
|
|
|
+ builder.append(p_version->fragment_globals.get_data()); // fragment globals
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_COMPUTE_GLOBALS: {
|
|
|
|
+ builder.append(p_version->compute_globals.get_data()); // compute globals
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_CODE: {
|
|
|
|
+ if (p_version->code_sections.has(chunk.code)) {
|
|
|
|
+ builder.append(p_version->code_sections[chunk.code].get_data());
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+ case StageTemplate::Chunk::TYPE_TEXT: {
|
|
|
|
+ builder.append(chunk.text.get_data());
|
|
|
|
+ } break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
|
void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
|
if (!variants_enabled[p_variant]) {
|
|
if (!variants_enabled[p_variant]) {
|
|
return; //variant is disabled, return
|
|
return; //variant is disabled, return
|
|
@@ -214,29 +194,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
|
//vertex stage
|
|
//vertex stage
|
|
|
|
|
|
StringBuilder builder;
|
|
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[p_variant].get_data());
|
|
|
|
-
|
|
|
|
- for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
|
|
|
- builder.append(p_version->custom_defines[j].get_data());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- builder.append(vertex_code0.get_data()); //first part of vertex
|
|
|
|
-
|
|
|
|
- builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)
|
|
|
|
-
|
|
|
|
- builder.append(vertex_code1.get_data()); //second part of vertex
|
|
|
|
-
|
|
|
|
- builder.append(p_version->vertex_globals.get_data()); // vertex globals
|
|
|
|
-
|
|
|
|
- builder.append(vertex_code2.get_data()); //third part of vertex
|
|
|
|
-
|
|
|
|
- builder.append(p_version->vertex_code.get_data()); // code
|
|
|
|
-
|
|
|
|
- builder.append(vertex_code3.get_data()); //fourth of vertex
|
|
|
|
|
|
+ _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX]);
|
|
|
|
|
|
current_source = builder.as_string();
|
|
current_source = builder.as_string();
|
|
RD::ShaderStageData stage;
|
|
RD::ShaderStageData stage;
|
|
@@ -254,33 +212,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
|
current_stage = RD::SHADER_STAGE_FRAGMENT;
|
|
current_stage = RD::SHADER_STAGE_FRAGMENT;
|
|
|
|
|
|
StringBuilder builder;
|
|
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[p_variant].get_data());
|
|
|
|
- for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
|
|
|
- builder.append(p_version->custom_defines[j].get_data());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- builder.append(fragment_code0.get_data()); //first part of fragment
|
|
|
|
-
|
|
|
|
- builder.append(p_version->uniforms.get_data()); //uniforms (same for fragment and fragment)
|
|
|
|
-
|
|
|
|
- builder.append(fragment_code1.get_data()); //first part of fragment
|
|
|
|
-
|
|
|
|
- builder.append(p_version->fragment_globals.get_data()); // fragment globals
|
|
|
|
-
|
|
|
|
- builder.append(fragment_code2.get_data()); //third part of fragment
|
|
|
|
-
|
|
|
|
- builder.append(p_version->fragment_light.get_data()); // fragment light
|
|
|
|
-
|
|
|
|
- builder.append(fragment_code3.get_data()); //fourth part of fragment
|
|
|
|
-
|
|
|
|
- builder.append(p_version->fragment_code.get_data()); // fragment code
|
|
|
|
-
|
|
|
|
- builder.append(fragment_code4.get_data()); //fourth part of fragment
|
|
|
|
|
|
+ _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT]);
|
|
|
|
|
|
current_source = builder.as_string();
|
|
current_source = builder.as_string();
|
|
RD::ShaderStageData stage;
|
|
RD::ShaderStageData stage;
|
|
@@ -298,30 +230,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
|
|
current_stage = RD::SHADER_STAGE_COMPUTE;
|
|
current_stage = RD::SHADER_STAGE_COMPUTE;
|
|
|
|
|
|
StringBuilder builder;
|
|
StringBuilder builder;
|
|
-
|
|
|
|
- builder.append(compute_codev.get_data()); // version info (if exists)
|
|
|
|
- builder.append("\n"); //make sure defines begin at newline
|
|
|
|
- builder.append(base_compute_defines.get_data());
|
|
|
|
- builder.append(general_defines.get_data());
|
|
|
|
- builder.append(variant_defines[p_variant].get_data());
|
|
|
|
-
|
|
|
|
- for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
|
|
|
- builder.append(p_version->custom_defines[j].get_data());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- builder.append(compute_code0.get_data()); //first part of compute
|
|
|
|
-
|
|
|
|
- builder.append(p_version->uniforms.get_data()); //uniforms (same for compute and fragment)
|
|
|
|
-
|
|
|
|
- builder.append(compute_code1.get_data()); //second part of compute
|
|
|
|
-
|
|
|
|
- builder.append(p_version->compute_globals.get_data()); // compute globals
|
|
|
|
-
|
|
|
|
- builder.append(compute_code2.get_data()); //third part of compute
|
|
|
|
-
|
|
|
|
- builder.append(p_version->compute_code.get_data()); // code
|
|
|
|
-
|
|
|
|
- builder.append(compute_code3.get_data()); //fourth of compute
|
|
|
|
|
|
+ _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_COMPUTE]);
|
|
|
|
|
|
current_source = builder.as_string();
|
|
current_source = builder.as_string();
|
|
RD::ShaderStageData stage;
|
|
RD::ShaderStageData stage;
|
|
@@ -364,29 +273,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio
|
|
//vertex stage
|
|
//vertex stage
|
|
|
|
|
|
StringBuilder builder;
|
|
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
|
|
|
|
|
|
+ _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_VERTEX]);
|
|
|
|
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
stage.name = "vertex";
|
|
stage.name = "vertex";
|
|
@@ -399,32 +286,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio
|
|
//fragment stage
|
|
//fragment stage
|
|
|
|
|
|
StringBuilder builder;
|
|
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
|
|
|
|
|
|
+ _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_FRAGMENT]);
|
|
|
|
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
stage.name = "fragment";
|
|
stage.name = "fragment";
|
|
@@ -437,30 +299,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio
|
|
//compute stage
|
|
//compute stage
|
|
|
|
|
|
StringBuilder builder;
|
|
StringBuilder builder;
|
|
-
|
|
|
|
- builder.append(compute_codev.get_data()); // version info (if exists)
|
|
|
|
- builder.append("\n"); //make sure defines begin at newline
|
|
|
|
- builder.append(base_compute_defines.get_data());
|
|
|
|
- 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
|
|
|
|
|
|
+ _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_COMPUTE]);
|
|
|
|
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
RS::ShaderNativeSourceCode::Version::Stage stage;
|
|
stage.name = "compute";
|
|
stage.name = "compute";
|
|
@@ -518,17 +357,18 @@ void ShaderRD::_compile_version(Version *p_version) {
|
|
p_version->valid = true;
|
|
p_version->valid = true;
|
|
}
|
|
}
|
|
|
|
|
|
-void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines) {
|
|
|
|
|
|
+void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) {
|
|
ERR_FAIL_COND(is_compute);
|
|
ERR_FAIL_COND(is_compute);
|
|
|
|
|
|
Version *version = version_owner.getornull(p_version);
|
|
Version *version = version_owner.getornull(p_version);
|
|
ERR_FAIL_COND(!version);
|
|
ERR_FAIL_COND(!version);
|
|
version->vertex_globals = p_vertex_globals.utf8();
|
|
version->vertex_globals = p_vertex_globals.utf8();
|
|
- version->vertex_code = p_vertex_code.utf8();
|
|
|
|
- version->fragment_light = p_fragment_light.utf8();
|
|
|
|
version->fragment_globals = p_fragment_globals.utf8();
|
|
version->fragment_globals = p_fragment_globals.utf8();
|
|
- version->fragment_code = p_fragment_code.utf8();
|
|
|
|
version->uniforms = p_uniforms.utf8();
|
|
version->uniforms = p_uniforms.utf8();
|
|
|
|
+ version->code_sections.clear();
|
|
|
|
+ for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) {
|
|
|
|
+ version->code_sections[StringName(E->key().to_upper())] = E->get().utf8();
|
|
|
|
+ }
|
|
|
|
|
|
version->custom_defines.clear();
|
|
version->custom_defines.clear();
|
|
for (int i = 0; i < p_custom_defines.size(); i++) {
|
|
for (int i = 0; i < p_custom_defines.size(); i++) {
|
|
@@ -542,15 +382,20 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void ShaderRD::version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines) {
|
|
|
|
|
|
+void ShaderRD::version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines) {
|
|
ERR_FAIL_COND(!is_compute);
|
|
ERR_FAIL_COND(!is_compute);
|
|
|
|
|
|
Version *version = version_owner.getornull(p_version);
|
|
Version *version = version_owner.getornull(p_version);
|
|
ERR_FAIL_COND(!version);
|
|
ERR_FAIL_COND(!version);
|
|
|
|
+
|
|
version->compute_globals = p_compute_globals.utf8();
|
|
version->compute_globals = p_compute_globals.utf8();
|
|
- version->compute_code = p_compute_code.utf8();
|
|
|
|
version->uniforms = p_uniforms.utf8();
|
|
version->uniforms = p_uniforms.utf8();
|
|
|
|
|
|
|
|
+ version->code_sections.clear();
|
|
|
|
+ for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) {
|
|
|
|
+ version->code_sections[StringName(E->key().to_upper())] = E->get().utf8();
|
|
|
|
+ }
|
|
|
|
+
|
|
version->custom_defines.clear();
|
|
version->custom_defines.clear();
|
|
for (int i = 0; i < p_custom_defines.size(); i++) {
|
|
for (int i = 0; i < p_custom_defines.size(); i++) {
|
|
version->custom_defines.push_back(p_custom_defines[i].utf8());
|
|
version->custom_defines.push_back(p_custom_defines[i].utf8());
|