diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2019-08-07 15:14:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-07 15:14:35 +0200 |
commit | 7b514d920dbcb2a6f4317c0e95f0884abde58342 (patch) | |
tree | bc033b93081ccc7a3f809666778b3247cf94c627 | |
parent | ca05613aed241898cd716c10529920b5f5ca0313 (diff) | |
parent | b24b3497d60a41d654510cc0504b34e56d20c99f (diff) |
Merge pull request #31099 from Chaosus/shader_local_const
Implemented local shader constants
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 60 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 62 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 34 | ||||
-rw-r--r-- | servers/visual/shader_language.h | 19 |
4 files changed, 112 insertions, 63 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 25bab0e97a..935cb32fda 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -449,7 +449,9 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node; StringBuffer<> declaration; - + if (var_dec_node->is_const) { + declaration += "const "; + } declaration += _prestr(var_dec_node->precision); declaration += _typestr(var_dec_node->datatype); @@ -512,14 +514,16 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener } break; case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *var_dec_node = (SL::ArrayDeclarationNode *)p_node; + SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node; StringBuffer<> declaration; + if (arr_dec_node->is_const) { + declaration += "const "; + } + declaration += _prestr(arr_dec_node->precision); + declaration += _typestr(arr_dec_node->datatype); - declaration += _prestr(var_dec_node->precision); - declaration += _typestr(var_dec_node->datatype); - - for (int i = 0; i < var_dec_node->declarations.size(); i++) { + for (int i = 0; i < arr_dec_node->declarations.size(); i++) { if (i > 0) { declaration += ","; @@ -527,20 +531,20 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener declaration += " "; - declaration += _mkid(var_dec_node->declarations[i].name); + declaration += _mkid(arr_dec_node->declarations[i].name); declaration += "["; - declaration += itos(var_dec_node->declarations[i].size); + declaration += itos(arr_dec_node->declarations[i].size); declaration += "]"; - int sz = var_dec_node->declarations[i].initializer.size(); + int sz = arr_dec_node->declarations[i].initializer.size(); if (sz > 0) { declaration += "="; - declaration += _typestr(var_dec_node->datatype); + declaration += _typestr(arr_dec_node->datatype); declaration += "["; declaration += itos(sz); declaration += "]"; declaration += "("; for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(var_dec_node->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + declaration += _dump_node_code(arr_dec_node->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (j != sz - 1) { declaration += ", "; } @@ -552,46 +556,46 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener code += declaration.as_string(); } break; case SL::Node::TYPE_ARRAY: { - SL::ArrayNode *var_node = (SL::ArrayNode *)p_node; + SL::ArrayNode *arr_node = (SL::ArrayNode *)p_node; - if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) { - *p_actions.write_flag_pointers[var_node->name] = true; + if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) { + *p_actions.write_flag_pointers[arr_node->name] = true; } - if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) { - String define = p_default_actions.usage_defines[var_node->name]; + if (p_default_actions.usage_defines.has(arr_node->name) && !used_name_defines.has(arr_node->name)) { + String define = p_default_actions.usage_defines[arr_node->name]; if (define.begins_with("@")) { define = p_default_actions.usage_defines[define.substr(1, define.length())]; } r_gen_code.custom_defines.push_back(define.utf8()); - used_name_defines.insert(var_node->name); + used_name_defines.insert(arr_node->name); } - if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) { - *p_actions.usage_flag_pointers[var_node->name] = true; - used_flag_pointers.insert(var_node->name); + if (p_actions.usage_flag_pointers.has(arr_node->name) && !used_flag_pointers.has(arr_node->name)) { + *p_actions.usage_flag_pointers[arr_node->name] = true; + used_flag_pointers.insert(arr_node->name); } - if (p_default_actions.renames.has(var_node->name)) { - code += p_default_actions.renames[var_node->name]; + if (p_default_actions.renames.has(arr_node->name)) { + code += p_default_actions.renames[arr_node->name]; } else { - code += _mkid(var_node->name); + code += _mkid(arr_node->name); } - if (var_node->call_expression != NULL) { + if (arr_node->call_expression != NULL) { code += "."; - code += _dump_node_code(var_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); } - if (var_node->index_expression != NULL) { + if (arr_node->index_expression != NULL) { code += "["; - code += _dump_node_code(var_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(arr_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "]"; } - if (var_node->name == time_name) { + if (arr_node->name == time_name) { if (current_func_name == vertex_name) { r_gen_code.uses_vertex_time = true; } diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index f826bdf5a2..d48ee7709c 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -555,7 +555,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener case SL::Node::TYPE_VARIABLE_DECLARATION: { SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node; - String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype); + String declaration; + if (vdnode->is_const) { + declaration += "const "; + } + declaration += _prestr(vdnode->precision); + declaration += _typestr(vdnode->datatype); for (int i = 0; i < vdnode->declarations.size(); i++) { if (i > 0) { declaration += ","; @@ -609,29 +614,34 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } break; case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *vdnode = (SL::ArrayDeclarationNode *)p_node; + SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node; - String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype); - for (int i = 0; i < vdnode->declarations.size(); i++) { + String declaration; + if (adnode->is_const) { + declaration += "const "; + } + declaration += _prestr(adnode->precision); + declaration += _typestr(adnode->datatype); + for (int i = 0; i < adnode->declarations.size(); i++) { if (i > 0) { declaration += ","; } else { declaration += " "; } - declaration += _mkid(vdnode->declarations[i].name); + declaration += _mkid(adnode->declarations[i].name); declaration += "["; - declaration += itos(vdnode->declarations[i].size); + declaration += itos(adnode->declarations[i].size); declaration += "]"; - int sz = vdnode->declarations[i].initializer.size(); + int sz = adnode->declarations[i].initializer.size(); if (sz > 0) { declaration += "="; - declaration += _typestr(vdnode->datatype); + declaration += _typestr(adnode->datatype); declaration += "["; declaration += itos(sz); declaration += "]"; declaration += "("; for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(vdnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (j != sz - 1) { declaration += ", "; } @@ -643,43 +653,43 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener code += declaration; } break; case SL::Node::TYPE_ARRAY: { - SL::ArrayNode *vnode = (SL::ArrayNode *)p_node; + SL::ArrayNode *anode = (SL::ArrayNode *)p_node; - if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) { - *p_actions.write_flag_pointers[vnode->name] = true; + if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) { + *p_actions.write_flag_pointers[anode->name] = true; } - if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) { - String define = p_default_actions.usage_defines[vnode->name]; + if (p_default_actions.usage_defines.has(anode->name) && !used_name_defines.has(anode->name)) { + String define = p_default_actions.usage_defines[anode->name]; if (define.begins_with("@")) { define = p_default_actions.usage_defines[define.substr(1, define.length())]; } r_gen_code.defines.push_back(define.utf8()); - used_name_defines.insert(vnode->name); + used_name_defines.insert(anode->name); } - if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) { - *p_actions.usage_flag_pointers[vnode->name] = true; - used_flag_pointers.insert(vnode->name); + if (p_actions.usage_flag_pointers.has(anode->name) && !used_flag_pointers.has(anode->name)) { + *p_actions.usage_flag_pointers[anode->name] = true; + used_flag_pointers.insert(anode->name); } - if (p_default_actions.renames.has(vnode->name)) - code = p_default_actions.renames[vnode->name]; + if (p_default_actions.renames.has(anode->name)) + code = p_default_actions.renames[anode->name]; else - code = _mkid(vnode->name); + code = _mkid(anode->name); - if (vnode->call_expression != NULL) { + if (anode->call_expression != NULL) { code += "."; - code += _dump_node_code(vnode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); } - if (vnode->index_expression != NULL) { + if (anode->index_expression != NULL) { code += "["; - code += _dump_node_code(vnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "]"; } - if (vnode->name == time_name) { + if (anode->name == time_name) { if (current_func_name == vertex_name) { r_gen_code.uses_vertex_time = true; } diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 25973aa295..5c28705192 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -860,7 +860,7 @@ void ShaderLanguage::clear() { } } -bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, int *r_array_size) { +bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size) { if (p_builtin_types.has(p_identifier)) { @@ -882,6 +882,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String if (r_data_type) { *r_data_type = p_block->variables[p_identifier].type; } + if (r_is_const) { + *r_is_const = p_block->variables[p_identifier].is_const; + } if (r_array_size) { *r_array_size = p_block->variables[p_identifier].array_size; } @@ -2735,7 +2738,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return false; } - if (shader->constants.has(var->name)) { + if (shader->constants.has(var->name) || var->is_const) { if (r_message) *r_message = RTR("Constants cannot be modified."); return false; @@ -2745,6 +2748,15 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return true; } } else if (p_node->type == Node::TYPE_ARRAY) { + + ArrayNode *arr = static_cast<ArrayNode *>(p_node); + + if (arr->is_const) { + if (r_message) + *r_message = RTR("Constants cannot be modified."); + return false; + } + return true; } @@ -2931,9 +2943,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons DataType data_type; IdentifierType ident_type; + bool is_const = false; int array_size = 0; - if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type, &array_size)) { + if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size)) { _set_error("Unknown identifier in expression: " + String(identifier)); return NULL; } @@ -2996,6 +3009,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons arrname->datatype_cache = data_type; arrname->index_expression = index_expression; arrname->call_expression = call_expression; + arrname->is_const = is_const; expr = arrname; } else { @@ -3003,6 +3017,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons VariableNode *varname = alloc_node<VariableNode>(); varname->name = identifier; varname->datatype_cache = data_type; + varname->is_const = is_const; expr = varname; } } @@ -3770,7 +3785,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui return OK; - } else if (is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) { + } else if (tk.type == TK_CONST || is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) { + + bool is_const = false; + + if (tk.type == TK_CONST) { + is_const = true; + tk = _get_token(); + } + DataPrecision precision = PRECISION_DEFAULT; if (is_token_precision(tk.type)) { precision = get_token_precision(tk.type); @@ -3810,6 +3833,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui var.precision = precision; var.line = tk_line; var.array_size = 0; + var.is_const = is_const; tk = _get_token(); @@ -3819,6 +3843,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>(); node->datatype = type; node->precision = precision; + node->is_const = is_const; vardecl = (Node *)node; ArrayDeclarationNode::Declaration decl; @@ -4004,6 +4029,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); node->datatype = type; node->precision = precision; + node->is_const = is_const; vardecl = (Node *)node; VariableDeclarationNode::Declaration decl; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 8253bce468..36c691c3ae 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -330,15 +330,18 @@ public: DataType datatype_cache; StringName name; virtual DataType get_datatype() const { return datatype_cache; } + bool is_const; VariableNode() : Node(TYPE_VARIABLE), - datatype_cache(TYPE_VOID) {} + datatype_cache(TYPE_VOID), + is_const(false) {} }; struct VariableDeclarationNode : public Node { DataPrecision precision; DataType datatype; + bool is_const; struct Declaration { StringName name; @@ -351,7 +354,8 @@ public: VariableDeclarationNode() : Node(TYPE_VARIABLE_DECLARATION), precision(PRECISION_DEFAULT), - datatype(TYPE_VOID) {} + datatype(TYPE_VOID), + is_const(false) {} }; struct ArrayNode : public Node { @@ -359,6 +363,7 @@ public: StringName name; Node *index_expression; Node *call_expression; + bool is_const; virtual DataType get_datatype() const { return datatype_cache; } @@ -366,12 +371,14 @@ public: Node(TYPE_ARRAY), datatype_cache(TYPE_VOID), index_expression(NULL), - call_expression(NULL) {} + call_expression(NULL), + is_const(false) {} }; struct ArrayDeclarationNode : public Node { DataPrecision precision; DataType datatype; + bool is_const; struct Declaration { StringName name; @@ -385,7 +392,8 @@ public: ArrayDeclarationNode() : Node(TYPE_ARRAY_DECLARATION), precision(PRECISION_DEFAULT), - datatype(TYPE_VOID) {} + datatype(TYPE_VOID), + is_const(false) {} }; struct ConstantNode : public Node { @@ -417,6 +425,7 @@ public: DataPrecision precision; int line; //for completion int array_size; + bool is_const; }; Map<StringName, Variable> variables; @@ -683,7 +692,7 @@ private: IDENTIFIER_CONSTANT, }; - bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL, int *r_array_size = NULL); + bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL, bool *r_is_const = NULL, int *r_array_size = NULL); bool _is_operator_assign(Operator p_op) const; bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); |