diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shader_compiler_rd.cpp')
-rw-r--r-- | servers/rendering/renderer_rd/shader_compiler_rd.cpp | 101 |
1 files changed, 65 insertions, 36 deletions
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 056c8113a7..7deedb80c3 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -369,17 +369,24 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S ERR_FAIL_COND(fidx == -1); + Vector<StringName> uses_functions; + for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - if (added.has(E->get())) { + uses_functions.push_back(E->get()); + } + uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < uses_functions.size(); k++) { + if (added.has(uses_functions[k])) { continue; //was added already } - _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, added); + _dump_function_deps(p_node, uses_functions[k], p_func_code, r_to_add, added); SL::FunctionNode *fnode = nullptr; for (int i = 0; i < p_node->functions.size(); i++) { - if (p_node->functions[i].name == E->get()) { + if (p_node->functions[i].name == uses_functions[k]) { fnode = p_node->functions[i].function; break; } @@ -427,9 +434,9 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S header += ")\n"; r_to_add += header; - r_to_add += p_func_code[E->get()]; + r_to_add += p_func_code[uses_functions[k]]; - added.insert(E->get()); + added.insert(uses_functions[k]); } } @@ -581,63 +588,74 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uniform_defines.resize(max_uniforms); bool uses_uniforms = false; + Vector<StringName> uniform_names; + for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { + uniform_names.push_back(E->key()); + } + + uniform_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < uniform_names.size(); k++) { + StringName uniform_name = uniform_names[k]; + const SL::ShaderNode::Uniform &uniform = pnode->uniforms[uniform_name]; + String ucode; - if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { + if (uniform.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { //insert, but don't generate any code. - p_actions.uniforms->insert(E->key(), E->get()); + p_actions.uniforms->insert(uniform_name, uniform); continue; //instances are indexed directly, dont need index uniforms } - if (SL::is_sampler_type(E->get().type)) { - ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + E->get().texture_order) + ") uniform "; + if (SL::is_sampler_type(uniform.type)) { + ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_order) + ") uniform "; } - bool is_buffer_global = !SL::is_sampler_type(E->get().type) && E->get().scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; + bool is_buffer_global = !SL::is_sampler_type(uniform.type) && uniform.scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; if (is_buffer_global) { //this is an integer to index the global table ucode += _typestr(ShaderLanguage::TYPE_UINT); } else { - ucode += _prestr(E->get().precision); - ucode += _typestr(E->get().type); + ucode += _prestr(uniform.precision); + ucode += _typestr(uniform.type); } - ucode += " " + _mkid(E->key()); + ucode += " " + _mkid(uniform_name); ucode += ";\n"; - if (SL::is_sampler_type(E->get().type)) { + if (SL::is_sampler_type(uniform.type)) { for (int j = 0; j < STAGE_MAX; j++) { r_gen_code.stage_globals[j] += ucode; } GeneratedCode::Texture texture; - texture.name = E->key(); - texture.hint = E->get().hint; - texture.type = E->get().type; - texture.filter = E->get().filter; - texture.repeat = E->get().repeat; - texture.global = E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL; + texture.name = uniform_name; + texture.hint = uniform.hint; + texture.type = uniform.type; + texture.filter = uniform.filter; + texture.repeat = uniform.repeat; + texture.global = uniform.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL; if (texture.global) { r_gen_code.uses_global_textures = true; } - r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; + r_gen_code.texture_uniforms.write[uniform.texture_order] = texture; } else { if (!uses_uniforms) { uses_uniforms = true; } - uniform_defines.write[E->get().order] = ucode; + uniform_defines.write[uniform.order] = ucode; if (is_buffer_global) { //globals are indices into the global table - uniform_sizes.write[E->get().order] = _get_datatype_size(ShaderLanguage::TYPE_UINT); - uniform_alignments.write[E->get().order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT); + uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT); + uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT); } else { - uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type); - uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type); + uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type); + uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type); } } - p_actions.uniforms->insert(E->key(), E->get()); + p_actions.uniforms->insert(uniform_name, uniform); } for (int i = 0; i < max_uniforms; i++) { @@ -704,21 +722,32 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light; + Vector<StringName> varying_names; + for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { - if (E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { - var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(E->key(), E->get())); - fragment_varyings.insert(E->key()); + varying_names.push_back(E->key()); + } + + varying_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < varying_names.size(); k++) { + StringName varying_name = varying_names[k]; + const SL::ShaderNode::Varying &varying = pnode->varyings[varying_name]; + + if (varying.stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || varying.stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { + var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(varying_name, varying)); + fragment_varyings.insert(varying_name); continue; } String vcode; - String interp_mode = _interpstr(E->get().interpolation); - vcode += _prestr(E->get().precision); - vcode += _typestr(E->get().type); - vcode += " " + _mkid(E->key()); - if (E->get().array_size > 0) { + String interp_mode = _interpstr(varying.interpolation); + vcode += _prestr(varying.precision); + vcode += _typestr(varying.type); + vcode += " " + _mkid(varying_name); + if (varying.array_size > 0) { vcode += "["; - vcode += itos(E->get().array_size); + vcode += itos(varying.array_size); vcode += "]"; } vcode += ";\n"; |