Implemented local shader constants

This commit is contained in:
Yuri Roubinski 2019-08-05 10:35:53 +03:00
parent 7d5ad99cde
commit b24b3497d6
4 changed files with 112 additions and 63 deletions

View File

@ -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; SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node;
StringBuffer<> declaration; StringBuffer<> declaration;
if (var_dec_node->is_const) {
declaration += "const ";
}
declaration += _prestr(var_dec_node->precision); declaration += _prestr(var_dec_node->precision);
declaration += _typestr(var_dec_node->datatype); declaration += _typestr(var_dec_node->datatype);
@ -512,14 +514,16 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break; } break;
case SL::Node::TYPE_ARRAY_DECLARATION: { 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; 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); for (int i = 0; i < arr_dec_node->declarations.size(); i++) {
declaration += _typestr(var_dec_node->datatype);
for (int i = 0; i < var_dec_node->declarations.size(); i++) {
if (i > 0) { if (i > 0) {
declaration += ","; declaration += ",";
@ -527,20 +531,20 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
declaration += " "; declaration += " ";
declaration += _mkid(var_dec_node->declarations[i].name); declaration += _mkid(arr_dec_node->declarations[i].name);
declaration += "["; declaration += "[";
declaration += itos(var_dec_node->declarations[i].size); declaration += itos(arr_dec_node->declarations[i].size);
declaration += "]"; declaration += "]";
int sz = var_dec_node->declarations[i].initializer.size(); int sz = arr_dec_node->declarations[i].initializer.size();
if (sz > 0) { if (sz > 0) {
declaration += "="; declaration += "=";
declaration += _typestr(var_dec_node->datatype); declaration += _typestr(arr_dec_node->datatype);
declaration += "["; declaration += "[";
declaration += itos(sz); declaration += itos(sz);
declaration += "]"; declaration += "]";
declaration += "("; declaration += "(";
for (int j = 0; j < sz; j++) { 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) { if (j != sz - 1) {
declaration += ", "; declaration += ", ";
} }
@ -552,46 +556,46 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += declaration.as_string(); code += declaration.as_string();
} break; } break;
case SL::Node::TYPE_ARRAY: { 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)) { if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) {
*p_actions.write_flag_pointers[var_node->name] = true; *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)) { if (p_default_actions.usage_defines.has(arr_node->name) && !used_name_defines.has(arr_node->name)) {
String define = p_default_actions.usage_defines[var_node->name]; String define = p_default_actions.usage_defines[arr_node->name];
if (define.begins_with("@")) { if (define.begins_with("@")) {
define = p_default_actions.usage_defines[define.substr(1, define.length())]; define = p_default_actions.usage_defines[define.substr(1, define.length())];
} }
r_gen_code.custom_defines.push_back(define.utf8()); 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)) { if (p_actions.usage_flag_pointers.has(arr_node->name) && !used_flag_pointers.has(arr_node->name)) {
*p_actions.usage_flag_pointers[var_node->name] = true; *p_actions.usage_flag_pointers[arr_node->name] = true;
used_flag_pointers.insert(var_node->name); used_flag_pointers.insert(arr_node->name);
} }
if (p_default_actions.renames.has(var_node->name)) { if (p_default_actions.renames.has(arr_node->name)) {
code += p_default_actions.renames[var_node->name]; code += p_default_actions.renames[arr_node->name];
} else { } 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 += ".";
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 += "[";
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 += "]"; code += "]";
} }
if (var_node->name == time_name) { if (arr_node->name == time_name) {
if (current_func_name == vertex_name) { if (current_func_name == vertex_name) {
r_gen_code.uses_vertex_time = true; r_gen_code.uses_vertex_time = true;
} }

View File

@ -555,7 +555,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::Node::TYPE_VARIABLE_DECLARATION: { case SL::Node::TYPE_VARIABLE_DECLARATION: {
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node; 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++) { for (int i = 0; i < vdnode->declarations.size(); i++) {
if (i > 0) { if (i > 0) {
declaration += ","; declaration += ",";
@ -609,29 +614,34 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break; } break;
case SL::Node::TYPE_ARRAY_DECLARATION: { 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); String declaration;
for (int i = 0; i < vdnode->declarations.size(); i++) { 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) { if (i > 0) {
declaration += ","; declaration += ",";
} else { } else {
declaration += " "; declaration += " ";
} }
declaration += _mkid(vdnode->declarations[i].name); declaration += _mkid(adnode->declarations[i].name);
declaration += "["; declaration += "[";
declaration += itos(vdnode->declarations[i].size); declaration += itos(adnode->declarations[i].size);
declaration += "]"; declaration += "]";
int sz = vdnode->declarations[i].initializer.size(); int sz = adnode->declarations[i].initializer.size();
if (sz > 0) { if (sz > 0) {
declaration += "="; declaration += "=";
declaration += _typestr(vdnode->datatype); declaration += _typestr(adnode->datatype);
declaration += "["; declaration += "[";
declaration += itos(sz); declaration += itos(sz);
declaration += "]"; declaration += "]";
declaration += "("; declaration += "(";
for (int j = 0; j < sz; j++) { 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) { if (j != sz - 1) {
declaration += ", "; declaration += ", ";
} }
@ -643,43 +653,43 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += declaration; code += declaration;
} break; } break;
case SL::Node::TYPE_ARRAY: { 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)) { if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) {
*p_actions.write_flag_pointers[vnode->name] = true; *p_actions.write_flag_pointers[anode->name] = true;
} }
if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) { if (p_default_actions.usage_defines.has(anode->name) && !used_name_defines.has(anode->name)) {
String define = p_default_actions.usage_defines[vnode->name]; String define = p_default_actions.usage_defines[anode->name];
if (define.begins_with("@")) { if (define.begins_with("@")) {
define = p_default_actions.usage_defines[define.substr(1, define.length())]; define = p_default_actions.usage_defines[define.substr(1, define.length())];
} }
r_gen_code.defines.push_back(define.utf8()); 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)) { if (p_actions.usage_flag_pointers.has(anode->name) && !used_flag_pointers.has(anode->name)) {
*p_actions.usage_flag_pointers[vnode->name] = true; *p_actions.usage_flag_pointers[anode->name] = true;
used_flag_pointers.insert(vnode->name); used_flag_pointers.insert(anode->name);
} }
if (p_default_actions.renames.has(vnode->name)) if (p_default_actions.renames.has(anode->name))
code = p_default_actions.renames[vnode->name]; code = p_default_actions.renames[anode->name];
else else
code = _mkid(vnode->name); code = _mkid(anode->name);
if (vnode->call_expression != NULL) { if (anode->call_expression != NULL) {
code += "."; 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 += "[";
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 += "]"; code += "]";
} }
if (vnode->name == time_name) { if (anode->name == time_name) {
if (current_func_name == vertex_name) { if (current_func_name == vertex_name) {
r_gen_code.uses_vertex_time = true; r_gen_code.uses_vertex_time = true;
} }

View File

@ -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)) { 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) { if (r_data_type) {
*r_data_type = p_block->variables[p_identifier].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) { if (r_array_size) {
*r_array_size = p_block->variables[p_identifier].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; return false;
} }
if (shader->constants.has(var->name)) { if (shader->constants.has(var->name) || var->is_const) {
if (r_message) if (r_message)
*r_message = RTR("Constants cannot be modified."); *r_message = RTR("Constants cannot be modified.");
return false; return false;
@ -2745,6 +2748,15 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return true; return true;
} }
} else if (p_node->type == Node::TYPE_ARRAY) { } 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; return true;
} }
@ -2931,9 +2943,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
DataType data_type; DataType data_type;
IdentifierType ident_type; IdentifierType ident_type;
bool is_const = false;
int array_size = 0; 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)); _set_error("Unknown identifier in expression: " + String(identifier));
return NULL; return NULL;
} }
@ -2996,6 +3009,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
arrname->datatype_cache = data_type; arrname->datatype_cache = data_type;
arrname->index_expression = index_expression; arrname->index_expression = index_expression;
arrname->call_expression = call_expression; arrname->call_expression = call_expression;
arrname->is_const = is_const;
expr = arrname; expr = arrname;
} else { } else {
@ -3003,6 +3017,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
VariableNode *varname = alloc_node<VariableNode>(); VariableNode *varname = alloc_node<VariableNode>();
varname->name = identifier; varname->name = identifier;
varname->datatype_cache = data_type; varname->datatype_cache = data_type;
varname->is_const = is_const;
expr = varname; expr = varname;
} }
} }
@ -3770,7 +3785,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return OK; 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; DataPrecision precision = PRECISION_DEFAULT;
if (is_token_precision(tk.type)) { if (is_token_precision(tk.type)) {
precision = get_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.precision = precision;
var.line = tk_line; var.line = tk_line;
var.array_size = 0; var.array_size = 0;
var.is_const = is_const;
tk = _get_token(); tk = _get_token();
@ -3819,6 +3843,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>(); ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>();
node->datatype = type; node->datatype = type;
node->precision = precision; node->precision = precision;
node->is_const = is_const;
vardecl = (Node *)node; vardecl = (Node *)node;
ArrayDeclarationNode::Declaration decl; ArrayDeclarationNode::Declaration decl;
@ -4004,6 +4029,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
node->datatype = type; node->datatype = type;
node->precision = precision; node->precision = precision;
node->is_const = is_const;
vardecl = (Node *)node; vardecl = (Node *)node;
VariableDeclarationNode::Declaration decl; VariableDeclarationNode::Declaration decl;

View File

@ -330,15 +330,18 @@ public:
DataType datatype_cache; DataType datatype_cache;
StringName name; StringName name;
virtual DataType get_datatype() const { return datatype_cache; } virtual DataType get_datatype() const { return datatype_cache; }
bool is_const;
VariableNode() : VariableNode() :
Node(TYPE_VARIABLE), Node(TYPE_VARIABLE),
datatype_cache(TYPE_VOID) {} datatype_cache(TYPE_VOID),
is_const(false) {}
}; };
struct VariableDeclarationNode : public Node { struct VariableDeclarationNode : public Node {
DataPrecision precision; DataPrecision precision;
DataType datatype; DataType datatype;
bool is_const;
struct Declaration { struct Declaration {
StringName name; StringName name;
@ -351,7 +354,8 @@ public:
VariableDeclarationNode() : VariableDeclarationNode() :
Node(TYPE_VARIABLE_DECLARATION), Node(TYPE_VARIABLE_DECLARATION),
precision(PRECISION_DEFAULT), precision(PRECISION_DEFAULT),
datatype(TYPE_VOID) {} datatype(TYPE_VOID),
is_const(false) {}
}; };
struct ArrayNode : public Node { struct ArrayNode : public Node {
@ -359,6 +363,7 @@ public:
StringName name; StringName name;
Node *index_expression; Node *index_expression;
Node *call_expression; Node *call_expression;
bool is_const;
virtual DataType get_datatype() const { return datatype_cache; } virtual DataType get_datatype() const { return datatype_cache; }
@ -366,12 +371,14 @@ public:
Node(TYPE_ARRAY), Node(TYPE_ARRAY),
datatype_cache(TYPE_VOID), datatype_cache(TYPE_VOID),
index_expression(NULL), index_expression(NULL),
call_expression(NULL) {} call_expression(NULL),
is_const(false) {}
}; };
struct ArrayDeclarationNode : public Node { struct ArrayDeclarationNode : public Node {
DataPrecision precision; DataPrecision precision;
DataType datatype; DataType datatype;
bool is_const;
struct Declaration { struct Declaration {
StringName name; StringName name;
@ -385,7 +392,8 @@ public:
ArrayDeclarationNode() : ArrayDeclarationNode() :
Node(TYPE_ARRAY_DECLARATION), Node(TYPE_ARRAY_DECLARATION),
precision(PRECISION_DEFAULT), precision(PRECISION_DEFAULT),
datatype(TYPE_VOID) {} datatype(TYPE_VOID),
is_const(false) {}
}; };
struct ConstantNode : public Node { struct ConstantNode : public Node {
@ -417,6 +425,7 @@ public:
DataPrecision precision; DataPrecision precision;
int line; //for completion int line; //for completion
int array_size; int array_size;
bool is_const;
}; };
Map<StringName, Variable> variables; Map<StringName, Variable> variables;
@ -683,7 +692,7 @@ private:
IDENTIFIER_CONSTANT, 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 _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_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); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL);