From 7d9ced5311855deefef42b8a9e40d152755225cb Mon Sep 17 00:00:00 2001 From: Chaosus Date: Wed, 11 Sep 2024 16:29:02 +0300 Subject: [PATCH] Fix shader crash when using unary minus in expression --- servers/rendering/shader_compiler.cpp | 30 +++++++++++++-------------- servers/rendering/shader_compiler.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 43703f86566..29183eac6f4 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -185,7 +185,7 @@ static String f2sp0(float p_float) { return num; } -static String get_constant_text(SL::DataType p_type, const Vector &p_values) { +static String get_constant_text(SL::DataType p_type, const Vector &p_values, bool p_is_op) { switch (p_type) { case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false"; @@ -205,7 +205,7 @@ static String get_constant_text(SL::DataType p_type, const Vector &p } case SL::TYPE_INT: - return itos(p_values[0].sint); + return itos(p_is_op ? Math::abs(p_values[0].sint) : p_values[0].sint); // To prevent writing unary minus twice in operator expression parsing. case SL::TYPE_IVEC2: case SL::TYPE_IVEC3: case SL::TYPE_IVEC4: { @@ -238,7 +238,7 @@ static String get_constant_text(SL::DataType p_type, const Vector &p return text; } break; case SL::TYPE_FLOAT: - return f2sp0(p_values[0].real); + return f2sp0(p_is_op ? Math::abs(p_values[0].real) : p_values[0].real); // To prevent writing unary minus twice in operator expression parsing. case SL::TYPE_VEC2: case SL::TYPE_VEC3: case SL::TYPE_VEC4: { @@ -446,7 +446,7 @@ static String _get_global_shader_uniform_from_type_and_index(const String &p_buf } } -String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) { +String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope, bool p_is_op) { String code; switch (p_node->type) { @@ -1090,7 +1090,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene SL::ConstantNode *cnode = (SL::ConstantNode *)p_node; if (cnode->array_size == 0) { - return get_constant_text(cnode->datatype, cnode->values); + return get_constant_text(cnode->datatype, cnode->values, p_is_op); } else { if (cnode->get_datatype() == SL::TYPE_STRUCT) { code += _mkid(cnode->struct_name); @@ -1128,18 +1128,18 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene case SL::OP_ASSIGN_BIT_AND: case SL::OP_ASSIGN_BIT_OR: case SL::OP_ASSIGN_BIT_XOR: - code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true, true, true) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); break; case SL::OP_BIT_INVERT: case SL::OP_NEGATE: case SL::OP_NOT: case SL::OP_DECREMENT: case SL::OP_INCREMENT: - code = _opstr(onode->op) + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code = _opstr(onode->op) + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); break; case SL::OP_POST_DECREMENT: case SL::OP_POST_INCREMENT: - code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op); + code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true) + _opstr(onode->op); break; case SL::OP_CALL: case SL::OP_STRUCT: @@ -1235,7 +1235,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } } - String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); if (is_texture_func && i == 1) { // If we're doing a texture lookup we need to check our texture argument StringName texture_uniform; @@ -1352,19 +1352,19 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } } break; case SL::OP_INDEX: { - code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); code += "["; - code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); code += "]"; } break; case SL::OP_SELECT_IF: { code += "("; - code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); code += "?"; - code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); code += ":"; - code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); code += ")"; } break; @@ -1376,7 +1376,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (p_use_scope) { code += "("; } - code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + " " + _opstr(onode->op) + " " + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + " " + _opstr(onode->op) + " " + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning, true, true); if (p_use_scope) { code += ")"; } diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h index 66106d7eb73..bf0cfd70321 100644 --- a/servers/rendering/shader_compiler.h +++ b/servers/rendering/shader_compiler.h @@ -109,7 +109,7 @@ private: String _get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat); void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const HashMap &p_func_code, String &r_to_add, HashSet &added); - String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true); + String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true, bool p_is_op = false); const ShaderLanguage::ShaderNode *shader = nullptr; const ShaderLanguage::FunctionNode *function = nullptr;