Merge pull request #48075 from lyuma/varying_fragment_to_light_3.4
This commit is contained in:
commit
330ddc37b6
9 changed files with 1393 additions and 209 deletions
|
@ -1574,6 +1574,9 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
|
|||
pi.name = E->get();
|
||||
|
||||
switch (u.type) {
|
||||
case ShaderLanguage::TYPE_STRUCT: {
|
||||
pi.type = Variant::ARRAY;
|
||||
} break;
|
||||
case ShaderLanguage::TYPE_VOID: {
|
||||
pi.type = Variant::NIL;
|
||||
} break;
|
||||
|
|
|
@ -210,7 +210,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
|
|||
}
|
||||
}
|
||||
|
||||
void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) {
|
||||
void ShaderCompilerGLES2::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) {
|
||||
int fidx = -1;
|
||||
|
||||
for (int i = 0; i < p_node->functions.size(); i++) {
|
||||
|
@ -243,22 +243,22 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
|
|||
r_to_add += "\n";
|
||||
|
||||
StringBuffer<128> header;
|
||||
|
||||
header += _typestr(fnode->return_type);
|
||||
header += " ";
|
||||
header += _mkid(fnode->name);
|
||||
header += "(";
|
||||
if (fnode->return_type == SL::TYPE_STRUCT) {
|
||||
header += _mkid(fnode->return_struct_name) + " " + _mkid(fnode->name) + "(";
|
||||
} else {
|
||||
header += _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";
|
||||
}
|
||||
|
||||
for (int i = 0; i < fnode->arguments.size(); i++) {
|
||||
if (i > 0) {
|
||||
header += ", ";
|
||||
}
|
||||
|
||||
header += _qualstr(fnode->arguments[i].qualifier);
|
||||
header += _prestr(fnode->arguments[i].precision);
|
||||
header += _typestr(fnode->arguments[i].type);
|
||||
header += " ";
|
||||
header += _mkid(fnode->arguments[i].name);
|
||||
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
||||
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
||||
} else {
|
||||
header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
header += ")\n";
|
||||
|
@ -269,7 +269,7 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
|
|||
}
|
||||
}
|
||||
|
||||
String ShaderCompilerGLES2::_dump_node_code(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 ShaderCompilerGLES2::_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) {
|
||||
StringBuilder code;
|
||||
|
||||
switch (p_node->type) {
|
||||
|
@ -311,6 +311,40 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
StringBuilder vertex_global;
|
||||
StringBuilder fragment_global;
|
||||
|
||||
// structs
|
||||
|
||||
for (int i = 0; i < snode->vstructs.size(); i++) {
|
||||
SL::StructNode *st = snode->vstructs[i].shader_struct;
|
||||
String struct_code;
|
||||
|
||||
struct_code += "struct ";
|
||||
struct_code += _mkid(snode->vstructs[i].name);
|
||||
struct_code += " ";
|
||||
struct_code += "{\n";
|
||||
for (int j = 0; j < st->members.size(); j++) {
|
||||
SL::MemberNode *m = st->members[j];
|
||||
if (m->datatype == SL::TYPE_STRUCT) {
|
||||
struct_code += _mkid(m->struct_name);
|
||||
} else {
|
||||
struct_code += _prestr(m->precision);
|
||||
struct_code += _typestr(m->datatype);
|
||||
}
|
||||
struct_code += " ";
|
||||
struct_code += m->name;
|
||||
if (m->array_size > 0) {
|
||||
struct_code += "[";
|
||||
struct_code += itos(m->array_size);
|
||||
struct_code += "]";
|
||||
}
|
||||
struct_code += ";\n";
|
||||
}
|
||||
struct_code += "}";
|
||||
struct_code += ";\n";
|
||||
|
||||
vertex_global += struct_code;
|
||||
fragment_global += struct_code;
|
||||
}
|
||||
|
||||
// uniforms
|
||||
|
||||
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) {
|
||||
|
@ -344,7 +378,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
// varyings
|
||||
|
||||
List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light;
|
||||
|
||||
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = snode->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());
|
||||
continue;
|
||||
}
|
||||
StringBuffer<> varying_code;
|
||||
|
||||
varying_code += "varying ";
|
||||
|
@ -365,13 +406,32 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
fragment_global += final_code;
|
||||
}
|
||||
|
||||
if (var_frag_to_light.size() > 0) {
|
||||
String gcode = "\n\nstruct {\n";
|
||||
for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) {
|
||||
gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first);
|
||||
if (E->get().second.array_size > 0) {
|
||||
gcode += "[";
|
||||
gcode += itos(E->get().second.array_size);
|
||||
gcode += "]";
|
||||
}
|
||||
gcode += ";\n";
|
||||
}
|
||||
gcode += "} frag_to_light;\n";
|
||||
r_gen_code.fragment_global += gcode;
|
||||
}
|
||||
|
||||
// constants
|
||||
|
||||
for (int i = 0; i < snode->vconstants.size(); i++) {
|
||||
String gcode;
|
||||
gcode += "const ";
|
||||
gcode += _prestr(snode->vconstants[i].precision);
|
||||
gcode += _typestr(snode->vconstants[i].type);
|
||||
if (snode->vconstants[i].type == SL::TYPE_STRUCT) {
|
||||
gcode += _mkid(snode->vconstants[i].type_str);
|
||||
} else {
|
||||
gcode += _prestr(snode->vconstants[i].precision);
|
||||
gcode += _typestr(snode->vconstants[i].type);
|
||||
}
|
||||
gcode += " " + _mkid(String(snode->vconstants[i].name));
|
||||
gcode += "=";
|
||||
gcode += _dump_node_code(snode->vconstants[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
|
@ -386,8 +446,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
for (int i = 0; i < snode->functions.size(); i++) {
|
||||
SL::FunctionNode *fnode = snode->functions[i].function;
|
||||
function = fnode;
|
||||
current_func_name = fnode->name;
|
||||
function_code[fnode->name] = _dump_node_code(fnode->body, 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
function = nullptr;
|
||||
}
|
||||
|
||||
Set<StringName> added_vertex;
|
||||
|
@ -396,6 +458,8 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
for (int i = 0; i < snode->functions.size(); i++) {
|
||||
SL::FunctionNode *fnode = snode->functions[i].function;
|
||||
|
||||
function = fnode;
|
||||
|
||||
current_func_name = fnode->name;
|
||||
|
||||
if (fnode->name == vertex_name) {
|
||||
|
@ -410,13 +474,16 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
_dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment);
|
||||
r_gen_code.light = function_code[light_name];
|
||||
}
|
||||
|
||||
function = nullptr;
|
||||
}
|
||||
|
||||
r_gen_code.vertex_global = vertex_global.as_string();
|
||||
r_gen_code.fragment_global = fragment_global.as_string();
|
||||
|
||||
} break;
|
||||
|
||||
case SL::Node::TYPE_STRUCT: {
|
||||
} break;
|
||||
case SL::Node::TYPE_FUNCTION: {
|
||||
} break;
|
||||
|
||||
|
@ -453,8 +520,12 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
if (var_dec_node->is_const) {
|
||||
declaration += "const ";
|
||||
}
|
||||
declaration += _prestr(var_dec_node->precision);
|
||||
declaration += _typestr(var_dec_node->datatype);
|
||||
if (var_dec_node->datatype == SL::TYPE_STRUCT) {
|
||||
declaration += _mkid(var_dec_node->struct_name);
|
||||
} else {
|
||||
declaration += _prestr(var_dec_node->precision);
|
||||
declaration += _typestr(var_dec_node->datatype);
|
||||
}
|
||||
|
||||
for (int i = 0; i < var_dec_node->declarations.size(); i++) {
|
||||
if (i > 0) {
|
||||
|
@ -476,6 +547,19 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
case SL::Node::TYPE_VARIABLE: {
|
||||
SL::VariableNode *var_node = (SL::VariableNode *)p_node;
|
||||
bool use_fragment_varying = false;
|
||||
|
||||
if (current_func_name != vertex_name) {
|
||||
if (p_assigning) {
|
||||
if (shader->varyings.has(var_node->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
} else {
|
||||
if (fragment_varyings.has(var_node->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) {
|
||||
*p_actions.write_flag_pointers[var_node->name] = true;
|
||||
|
@ -502,6 +586,8 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
if (p_default_actions.renames.has(var_node->name)) {
|
||||
code += p_default_actions.renames[var_node->name];
|
||||
} else if (use_fragment_varying) {
|
||||
code += "frag_to_light." + _mkid(var_node->name);
|
||||
} else {
|
||||
code += _mkid(var_node->name);
|
||||
}
|
||||
|
@ -515,13 +601,36 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
}
|
||||
}
|
||||
} break;
|
||||
case SL::Node::TYPE_ARRAY_CONSTRUCT: {
|
||||
SL::ArrayConstructNode *arr_con_node = (SL::ArrayConstructNode *)p_node;
|
||||
int sz = arr_con_node->initializer.size();
|
||||
if (arr_con_node->datatype == SL::TYPE_STRUCT) {
|
||||
code += _mkid(arr_con_node->struct_name);
|
||||
} else {
|
||||
code += _typestr(arr_con_node->datatype);
|
||||
}
|
||||
code += "[";
|
||||
code += itos(arr_con_node->initializer.size());
|
||||
code += "]";
|
||||
code += "(";
|
||||
for (int i = 0; i < sz; i++) {
|
||||
code += _dump_node_code(arr_con_node->initializer[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
if (i != sz - 1) {
|
||||
code += ", ";
|
||||
}
|
||||
}
|
||||
code += ")";
|
||||
} break;
|
||||
case SL::Node::TYPE_ARRAY_DECLARATION: {
|
||||
SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
|
||||
|
||||
StringBuffer<> declaration;
|
||||
declaration += _prestr(arr_dec_node->precision);
|
||||
declaration += _typestr(arr_dec_node->datatype);
|
||||
|
||||
if (arr_dec_node->datatype == SL::TYPE_STRUCT) {
|
||||
declaration += _mkid(arr_dec_node->struct_name);
|
||||
} else {
|
||||
declaration += _prestr(arr_dec_node->precision);
|
||||
declaration += _typestr(arr_dec_node->datatype);
|
||||
}
|
||||
for (int i = 0; i < arr_dec_node->declarations.size(); i++) {
|
||||
if (i > 0) {
|
||||
declaration += ",";
|
||||
|
@ -539,6 +648,23 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
} break;
|
||||
case SL::Node::TYPE_ARRAY: {
|
||||
SL::ArrayNode *arr_node = (SL::ArrayNode *)p_node;
|
||||
bool use_fragment_varying = false;
|
||||
|
||||
if (current_func_name != vertex_name) {
|
||||
if (arr_node->assign_expression != nullptr) {
|
||||
use_fragment_varying = true;
|
||||
} else {
|
||||
if (p_assigning) {
|
||||
if (shader->varyings.has(arr_node->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
} else {
|
||||
if (fragment_varyings.has(arr_node->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) {
|
||||
*p_actions.write_flag_pointers[arr_node->name] = true;
|
||||
|
@ -565,6 +691,8 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
if (p_default_actions.renames.has(arr_node->name)) {
|
||||
code += p_default_actions.renames[arr_node->name];
|
||||
} else if (use_fragment_varying) {
|
||||
code += "frag_to_light." + _mkid(arr_node->name);
|
||||
} else {
|
||||
code += _mkid(arr_node->name);
|
||||
}
|
||||
|
@ -640,12 +768,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
} break;
|
||||
|
||||
case SL::OP_CALL:
|
||||
case SL::OP_STRUCT:
|
||||
case SL::OP_CONSTRUCT: {
|
||||
ERR_FAIL_COND_V(op_node->arguments[0]->type != SL::Node::TYPE_VARIABLE, String());
|
||||
|
||||
SL::VariableNode *var_node = (SL::VariableNode *)op_node->arguments[0];
|
||||
|
||||
if (op_node->op == SL::OP_CONSTRUCT) {
|
||||
if (op_node->op == SL::OP_STRUCT) {
|
||||
code += _mkid(var_node->name);
|
||||
} else if (op_node->op == SL::OP_CONSTRUCT) {
|
||||
code += var_node->name;
|
||||
} else {
|
||||
if (var_node->name == "texture") {
|
||||
|
@ -840,6 +970,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
code += _dump_node_code(member_node->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
code += ".";
|
||||
code += member_node->name;
|
||||
if (member_node->index_expression != nullptr) {
|
||||
code += "[";
|
||||
code += _dump_node_code(member_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
code += "]";
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
|
@ -874,8 +1009,11 @@ Error ShaderCompilerGLES2::compile(VS::ShaderMode p_mode, const String &p_code,
|
|||
used_name_defines.clear();
|
||||
used_rmode_defines.clear();
|
||||
used_flag_pointers.clear();
|
||||
fragment_varyings.clear();
|
||||
|
||||
_dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false);
|
||||
shader = parser.get_shader();
|
||||
function = nullptr;
|
||||
_dump_node_code(shader, 1, r_gen_code, *p_actions, actions[p_mode], false);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -73,9 +73,11 @@ private:
|
|||
Map<StringName, String> usage_defines;
|
||||
};
|
||||
|
||||
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
|
||||
String _dump_node_code(ShaderLanguage::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 = true);
|
||||
void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_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_use_scope = true);
|
||||
|
||||
const ShaderLanguage::ShaderNode *shader;
|
||||
const ShaderLanguage::FunctionNode *function;
|
||||
StringName current_func_name;
|
||||
StringName vertex_name;
|
||||
StringName fragment_name;
|
||||
|
@ -86,6 +88,7 @@ private:
|
|||
Set<StringName> used_flag_pointers;
|
||||
Set<StringName> used_rmode_defines;
|
||||
Set<StringName> internal_functions;
|
||||
Set<StringName> fragment_varyings;
|
||||
|
||||
DefaultIdentifierActions actions[VS::SHADER_MAX];
|
||||
|
||||
|
|
|
@ -2355,6 +2355,9 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
|
|||
ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
|
||||
pi.name = E->get();
|
||||
switch (u.type) {
|
||||
case ShaderLanguage::TYPE_STRUCT:
|
||||
pi.type = Variant::ARRAY;
|
||||
break;
|
||||
case ShaderLanguage::TYPE_VOID:
|
||||
pi.type = Variant::NIL;
|
||||
break;
|
||||
|
|
|
@ -112,6 +112,8 @@ static int _get_datatype_size(SL::DataType p_type) {
|
|||
return 16;
|
||||
case SL::TYPE_SAMPLEREXT:
|
||||
return 16;
|
||||
case SL::TYPE_STRUCT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERR_FAIL_V(0);
|
||||
|
@ -181,6 +183,8 @@ static int _get_datatype_alignment(SL::DataType p_type) {
|
|||
return 16;
|
||||
case SL::TYPE_SAMPLEREXT:
|
||||
return 16;
|
||||
case SL::TYPE_STRUCT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERR_FAIL_V(0);
|
||||
|
@ -327,7 +331,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
|
|||
}
|
||||
}
|
||||
|
||||
void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
|
||||
void ShaderCompilerGLES3::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
|
||||
int fidx = -1;
|
||||
|
||||
for (int i = 0; i < p_node->functions.size(); i++) {
|
||||
|
@ -360,12 +364,20 @@ void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const Stri
|
|||
r_to_add += "\n";
|
||||
|
||||
String header;
|
||||
header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";
|
||||
if (fnode->return_type == SL::TYPE_STRUCT) {
|
||||
header = _mkid(fnode->return_struct_name) + " " + _mkid(fnode->name) + "(";
|
||||
} else {
|
||||
header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";
|
||||
}
|
||||
for (int i = 0; i < fnode->arguments.size(); i++) {
|
||||
if (i > 0) {
|
||||
header += ", ";
|
||||
}
|
||||
header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
|
||||
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
||||
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
||||
} else {
|
||||
header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
header += ")\n";
|
||||
|
@ -376,7 +388,7 @@ void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const Stri
|
|||
}
|
||||
}
|
||||
|
||||
String ShaderCompilerGLES3::_dump_node_code(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 ShaderCompilerGLES3::_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 code;
|
||||
|
||||
switch (p_node->type) {
|
||||
|
@ -399,6 +411,40 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
}
|
||||
}
|
||||
|
||||
// structs
|
||||
|
||||
for (int i = 0; i < pnode->vstructs.size(); i++) {
|
||||
SL::StructNode *st = pnode->vstructs[i].shader_struct;
|
||||
String struct_code;
|
||||
|
||||
struct_code += "struct ";
|
||||
struct_code += _mkid(pnode->vstructs[i].name);
|
||||
struct_code += " ";
|
||||
struct_code += "{\n";
|
||||
for (int j = 0; j < st->members.size(); j++) {
|
||||
SL::MemberNode *m = st->members[j];
|
||||
if (m->datatype == SL::TYPE_STRUCT) {
|
||||
struct_code += _mkid(m->struct_name);
|
||||
} else {
|
||||
struct_code += _prestr(m->precision);
|
||||
struct_code += _typestr(m->datatype);
|
||||
}
|
||||
struct_code += " ";
|
||||
struct_code += m->name;
|
||||
if (m->array_size > 0) {
|
||||
struct_code += "[";
|
||||
struct_code += itos(m->array_size);
|
||||
struct_code += "]";
|
||||
}
|
||||
struct_code += ";\n";
|
||||
}
|
||||
struct_code += "}";
|
||||
struct_code += ";\n";
|
||||
|
||||
r_gen_code.vertex_global += struct_code;
|
||||
r_gen_code.fragment_global += struct_code;
|
||||
}
|
||||
|
||||
int max_texture_uniforms = 0;
|
||||
int max_uniforms = 0;
|
||||
|
||||
|
@ -475,7 +521,14 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
r_gen_code.uniform_total_size += r_gen_code.uniform_total_size % 16;
|
||||
}
|
||||
|
||||
List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light;
|
||||
|
||||
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());
|
||||
continue;
|
||||
}
|
||||
String vcode;
|
||||
String interp_mode = _interpstr(E->get().interpolation);
|
||||
vcode += _prestr(E->get().precision);
|
||||
|
@ -491,11 +544,30 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
r_gen_code.fragment_global += interp_mode + "in " + vcode;
|
||||
}
|
||||
|
||||
if (var_frag_to_light.size() > 0) {
|
||||
String gcode = "\n\nstruct {\n";
|
||||
for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) {
|
||||
gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first);
|
||||
if (E->get().second.array_size > 0) {
|
||||
gcode += "[";
|
||||
gcode += itos(E->get().second.array_size);
|
||||
gcode += "]";
|
||||
}
|
||||
gcode += ";\n";
|
||||
}
|
||||
gcode += "} frag_to_light;\n";
|
||||
r_gen_code.fragment_global += gcode;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pnode->vconstants.size(); i++) {
|
||||
String gcode;
|
||||
gcode += "const ";
|
||||
gcode += _prestr(pnode->vconstants[i].precision);
|
||||
gcode += _typestr(pnode->vconstants[i].type);
|
||||
if (pnode->vconstants[i].type == SL::TYPE_STRUCT) {
|
||||
gcode += _mkid(pnode->vconstants[i].type_str);
|
||||
} else {
|
||||
gcode += _prestr(pnode->vconstants[i].precision);
|
||||
gcode += _typestr(pnode->vconstants[i].type);
|
||||
}
|
||||
gcode += " " + _mkid(String(pnode->vconstants[i].name));
|
||||
gcode += "=";
|
||||
gcode += _dump_node_code(pnode->vconstants[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
|
@ -509,8 +581,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
//code for functions
|
||||
for (int i = 0; i < pnode->functions.size(); i++) {
|
||||
SL::FunctionNode *fnode = pnode->functions[i].function;
|
||||
function = fnode;
|
||||
current_func_name = fnode->name;
|
||||
function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
function = nullptr;
|
||||
}
|
||||
|
||||
//place functions in actual code
|
||||
|
@ -521,6 +595,8 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
for (int i = 0; i < pnode->functions.size(); i++) {
|
||||
SL::FunctionNode *fnode = pnode->functions[i].function;
|
||||
|
||||
function = fnode;
|
||||
|
||||
current_func_name = fnode->name;
|
||||
|
||||
if (fnode->name == vertex_name) {
|
||||
|
@ -537,10 +613,14 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment);
|
||||
r_gen_code.light = function_code[light_name];
|
||||
}
|
||||
|
||||
function = nullptr;
|
||||
}
|
||||
|
||||
//code+=dump_node_code(pnode->body,p_level);
|
||||
} break;
|
||||
case SL::Node::TYPE_STRUCT: {
|
||||
} break;
|
||||
case SL::Node::TYPE_FUNCTION: {
|
||||
} break;
|
||||
case SL::Node::TYPE_BLOCK: {
|
||||
|
@ -572,8 +652,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
if (vdnode->is_const) {
|
||||
declaration += "const ";
|
||||
}
|
||||
declaration += _prestr(vdnode->precision);
|
||||
declaration += _typestr(vdnode->datatype);
|
||||
if (vdnode->datatype == SL::TYPE_STRUCT) {
|
||||
declaration += _mkid(vdnode->struct_name);
|
||||
} else {
|
||||
declaration += _prestr(vdnode->precision);
|
||||
declaration += _typestr(vdnode->datatype);
|
||||
}
|
||||
for (int i = 0; i < vdnode->declarations.size(); i++) {
|
||||
if (i > 0) {
|
||||
declaration += ",";
|
||||
|
@ -591,6 +675,19 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
} break;
|
||||
case SL::Node::TYPE_VARIABLE: {
|
||||
SL::VariableNode *vnode = (SL::VariableNode *)p_node;
|
||||
bool use_fragment_varying = false;
|
||||
|
||||
if (current_func_name != vertex_name) {
|
||||
if (p_assigning) {
|
||||
if (shader->varyings.has(vnode->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
} else {
|
||||
if (fragment_varyings.has(vnode->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) {
|
||||
*p_actions.write_flag_pointers[vnode->name] = true;
|
||||
|
@ -612,6 +709,8 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
if (p_default_actions.renames.has(vnode->name)) {
|
||||
code = p_default_actions.renames[vnode->name];
|
||||
} else if (use_fragment_varying) {
|
||||
code = "frag_to_light." + _mkid(vnode->name);
|
||||
} else {
|
||||
code = _mkid(vnode->name);
|
||||
}
|
||||
|
@ -626,6 +725,26 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
}
|
||||
|
||||
} break;
|
||||
case SL::Node::TYPE_ARRAY_CONSTRUCT: {
|
||||
SL::ArrayConstructNode *acnode = (SL::ArrayConstructNode *)p_node;
|
||||
int sz = acnode->initializer.size();
|
||||
if (acnode->datatype == SL::TYPE_STRUCT) {
|
||||
code += _mkid(acnode->struct_name);
|
||||
} else {
|
||||
code += _typestr(acnode->datatype);
|
||||
}
|
||||
code += "[";
|
||||
code += itos(acnode->initializer.size());
|
||||
code += "]";
|
||||
code += "(";
|
||||
for (int i = 0; i < sz; i++) {
|
||||
code += _dump_node_code(acnode->initializer[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
if (i != sz - 1) {
|
||||
code += ", ";
|
||||
}
|
||||
}
|
||||
code += ")";
|
||||
} break;
|
||||
case SL::Node::TYPE_ARRAY_DECLARATION: {
|
||||
SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
|
||||
|
||||
|
@ -633,8 +752,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
if (adnode->is_const) {
|
||||
declaration += "const ";
|
||||
}
|
||||
declaration += _prestr(adnode->precision);
|
||||
declaration += _typestr(adnode->datatype);
|
||||
if (adnode->datatype == SL::TYPE_STRUCT) {
|
||||
declaration += _mkid(adnode->struct_name);
|
||||
} else {
|
||||
declaration += _prestr(adnode->precision);
|
||||
declaration += _typestr(adnode->datatype);
|
||||
}
|
||||
for (int i = 0; i < adnode->declarations.size(); i++) {
|
||||
if (i > 0) {
|
||||
declaration += ",";
|
||||
|
@ -648,7 +771,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
int sz = adnode->declarations[i].initializer.size();
|
||||
if (sz > 0) {
|
||||
declaration += "=";
|
||||
declaration += _typestr(adnode->datatype);
|
||||
if (adnode->datatype == SL::TYPE_STRUCT) {
|
||||
declaration += _mkid(adnode->struct_name);
|
||||
} else {
|
||||
declaration += _typestr(adnode->datatype);
|
||||
}
|
||||
declaration += "[";
|
||||
declaration += itos(sz);
|
||||
declaration += "]";
|
||||
|
@ -667,6 +794,23 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
} break;
|
||||
case SL::Node::TYPE_ARRAY: {
|
||||
SL::ArrayNode *anode = (SL::ArrayNode *)p_node;
|
||||
bool use_fragment_varying = false;
|
||||
|
||||
if (current_func_name != vertex_name) {
|
||||
if (anode->assign_expression != nullptr) {
|
||||
use_fragment_varying = true;
|
||||
} else {
|
||||
if (p_assigning) {
|
||||
if (shader->varyings.has(anode->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
} else {
|
||||
if (fragment_varyings.has(anode->name)) {
|
||||
use_fragment_varying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) {
|
||||
*p_actions.write_flag_pointers[anode->name] = true;
|
||||
|
@ -688,6 +832,8 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
|
||||
if (p_default_actions.renames.has(anode->name)) {
|
||||
code = p_default_actions.renames[anode->name];
|
||||
} else if (use_fragment_varying) {
|
||||
code = "frag_to_light." + _mkid(anode->name);
|
||||
} else {
|
||||
code = _mkid(anode->name);
|
||||
}
|
||||
|
@ -695,12 +841,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
if (anode->call_expression != nullptr) {
|
||||
code += ".";
|
||||
code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
|
||||
}
|
||||
|
||||
if (anode->index_expression != nullptr) {
|
||||
} else if (anode->index_expression != nullptr) {
|
||||
code += "[";
|
||||
code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
code += "]";
|
||||
} else if (anode->assign_expression != nullptr) {
|
||||
code += "=";
|
||||
code += _dump_node_code(anode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
|
||||
}
|
||||
|
||||
if (anode->name == time_name) {
|
||||
|
@ -747,12 +894,15 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op);
|
||||
break;
|
||||
case SL::OP_CALL:
|
||||
case SL::OP_STRUCT:
|
||||
case SL::OP_CONSTRUCT: {
|
||||
ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String());
|
||||
|
||||
SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
|
||||
|
||||
if (onode->op == SL::OP_CONSTRUCT) {
|
||||
if (onode->op == SL::OP_STRUCT) {
|
||||
code += _mkid(vnode->name);
|
||||
} else if (onode->op == SL::OP_CONSTRUCT) {
|
||||
code += String(vnode->name);
|
||||
} else {
|
||||
if (internal_functions.has(vnode->name)) {
|
||||
|
@ -861,7 +1011,14 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||
case SL::Node::TYPE_MEMBER: {
|
||||
SL::MemberNode *mnode = (SL::MemberNode *)p_node;
|
||||
code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + mnode->name;
|
||||
|
||||
if (mnode->index_expression != nullptr) {
|
||||
code += "[";
|
||||
code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||
code += "]";
|
||||
} else if (mnode->assign_expression != nullptr) {
|
||||
code += "=";
|
||||
code += _dump_node_code(mnode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
|
@ -893,8 +1050,11 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
|
|||
used_name_defines.clear();
|
||||
used_rmode_defines.clear();
|
||||
used_flag_pointers.clear();
|
||||
fragment_varyings.clear();
|
||||
|
||||
_dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false);
|
||||
shader = parser.get_shader();
|
||||
function = nullptr;
|
||||
_dump_node_code(shader, 1, r_gen_code, *p_actions, actions[p_mode], false);
|
||||
|
||||
if (r_gen_code.uniform_total_size) { //uniforms used?
|
||||
int md = sizeof(float) * 4;
|
||||
|
|
|
@ -75,9 +75,11 @@ private:
|
|||
Map<StringName, String> usage_defines;
|
||||
};
|
||||
|
||||
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added);
|
||||
String _dump_node_code(ShaderLanguage::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 = true);
|
||||
void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &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_use_scope = true);
|
||||
|
||||
const ShaderLanguage::ShaderNode *shader;
|
||||
const ShaderLanguage::FunctionNode *function;
|
||||
StringName current_func_name;
|
||||
StringName vertex_name;
|
||||
StringName fragment_name;
|
||||
|
@ -88,6 +90,7 @@ private:
|
|||
Set<StringName> used_flag_pointers;
|
||||
Set<StringName> used_rmode_defines;
|
||||
Set<StringName> internal_functions;
|
||||
Set<StringName> fragment_varyings;
|
||||
|
||||
DefaultIdentifierActions actions[VS::SHADER_MAX];
|
||||
|
||||
|
|
|
@ -174,6 +174,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
|
|||
|
||||
//code+=dump_node_code(pnode->body,p_level);
|
||||
} break;
|
||||
case SL::Node::TYPE_STRUCT: {
|
||||
} break;
|
||||
case SL::Node::TYPE_FUNCTION: {
|
||||
} break;
|
||||
case SL::Node::TYPE_BLOCK: {
|
||||
|
@ -212,6 +214,9 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
|
|||
case SL::Node::TYPE_ARRAY_DECLARATION: {
|
||||
// FIXME: Implement
|
||||
} break;
|
||||
case SL::Node::TYPE_ARRAY_CONSTRUCT: {
|
||||
// FIXME: Implement
|
||||
} break;
|
||||
case SL::Node::TYPE_CONSTANT: {
|
||||
SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
|
||||
return get_constant_text(cnode->datatype, cnode->values);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,6 +41,11 @@
|
|||
|
||||
class ShaderLanguage {
|
||||
public:
|
||||
struct TkPos {
|
||||
int char_idx;
|
||||
int tk_line;
|
||||
};
|
||||
|
||||
enum TokenType {
|
||||
TK_EMPTY,
|
||||
TK_IDENTIFIER,
|
||||
|
@ -82,6 +87,7 @@ public:
|
|||
TK_INTERPOLATION_FLAT,
|
||||
TK_INTERPOLATION_SMOOTH,
|
||||
TK_CONST,
|
||||
TK_STRUCT,
|
||||
TK_PRECISION_LOW,
|
||||
TK_PRECISION_MID,
|
||||
TK_PRECISION_HIGH,
|
||||
|
@ -201,6 +207,7 @@ public:
|
|||
TYPE_USAMPLER3D,
|
||||
TYPE_SAMPLERCUBE,
|
||||
TYPE_SAMPLEREXT,
|
||||
TYPE_STRUCT,
|
||||
};
|
||||
|
||||
enum DataPrecision {
|
||||
|
@ -256,6 +263,7 @@ public:
|
|||
OP_POST_DECREMENT,
|
||||
OP_CALL,
|
||||
OP_CONSTRUCT,
|
||||
OP_STRUCT,
|
||||
OP_INDEX,
|
||||
OP_MAX
|
||||
};
|
||||
|
@ -300,11 +308,15 @@ public:
|
|||
TYPE_MEMBER,
|
||||
TYPE_ARRAY,
|
||||
TYPE_ARRAY_DECLARATION,
|
||||
TYPE_ARRAY_CONSTRUCT,
|
||||
TYPE_STRUCT,
|
||||
};
|
||||
|
||||
Type type;
|
||||
|
||||
virtual DataType get_datatype() const { return TYPE_VOID; }
|
||||
virtual String get_datatype_name() const { return ""; }
|
||||
|
||||
Node(Type t) :
|
||||
next(nullptr),
|
||||
type(t) {}
|
||||
|
@ -325,20 +337,25 @@ public:
|
|||
DataType return_cache;
|
||||
DataPrecision return_precision_cache;
|
||||
Operator op;
|
||||
StringName struct_name;
|
||||
Vector<Node *> arguments;
|
||||
virtual DataType get_datatype() const { return return_cache; }
|
||||
virtual String get_datatype_name() const { return String(struct_name); }
|
||||
|
||||
OperatorNode() :
|
||||
Node(TYPE_OPERATOR),
|
||||
return_cache(TYPE_VOID),
|
||||
return_precision_cache(PRECISION_DEFAULT),
|
||||
op(OP_EQUAL) {}
|
||||
op(OP_EQUAL),
|
||||
struct_name("") {}
|
||||
};
|
||||
|
||||
struct VariableNode : public Node {
|
||||
DataType datatype_cache;
|
||||
StringName name;
|
||||
StringName struct_name;
|
||||
virtual DataType get_datatype() const { return datatype_cache; }
|
||||
virtual String get_datatype_name() const { return String(struct_name); }
|
||||
bool is_const;
|
||||
|
||||
VariableNode() :
|
||||
|
@ -350,6 +367,7 @@ public:
|
|||
struct VariableDeclarationNode : public Node {
|
||||
DataPrecision precision;
|
||||
DataType datatype;
|
||||
String struct_name;
|
||||
bool is_const;
|
||||
|
||||
struct Declaration {
|
||||
|
@ -369,24 +387,40 @@ public:
|
|||
|
||||
struct ArrayNode : public Node {
|
||||
DataType datatype_cache;
|
||||
StringName struct_name;
|
||||
StringName name;
|
||||
Node *index_expression;
|
||||
Node *call_expression;
|
||||
Node *assign_expression;
|
||||
bool is_const;
|
||||
|
||||
virtual DataType get_datatype() const { return datatype_cache; }
|
||||
virtual String get_datatype_name() const { return String(struct_name); }
|
||||
|
||||
ArrayNode() :
|
||||
Node(TYPE_ARRAY),
|
||||
datatype_cache(TYPE_VOID),
|
||||
index_expression(nullptr),
|
||||
call_expression(nullptr),
|
||||
assign_expression(nullptr),
|
||||
is_const(false) {}
|
||||
};
|
||||
|
||||
struct ArrayConstructNode : public Node {
|
||||
DataType datatype;
|
||||
String struct_name;
|
||||
Vector<Node *> initializer;
|
||||
|
||||
ArrayConstructNode() :
|
||||
Node(TYPE_ARRAY_CONSTRUCT),
|
||||
datatype(TYPE_VOID) {
|
||||
}
|
||||
};
|
||||
|
||||
struct ArrayDeclarationNode : public Node {
|
||||
DataPrecision precision;
|
||||
DataType datatype;
|
||||
String struct_name;
|
||||
bool is_const;
|
||||
|
||||
struct Declaration {
|
||||
|
@ -441,6 +475,7 @@ public:
|
|||
|
||||
struct Variable {
|
||||
DataType type;
|
||||
StringName struct_name;
|
||||
DataPrecision precision;
|
||||
int line; //for completion
|
||||
int array_size;
|
||||
|
@ -472,17 +507,35 @@ public:
|
|||
|
||||
struct MemberNode : public Node {
|
||||
DataType basetype;
|
||||
StringName base_struct_name;
|
||||
DataPrecision precision;
|
||||
DataType datatype;
|
||||
int array_size;
|
||||
StringName struct_name;
|
||||
StringName name;
|
||||
Node *owner;
|
||||
Node *index_expression;
|
||||
Node *assign_expression;
|
||||
bool has_swizzling_duplicates;
|
||||
|
||||
virtual DataType get_datatype() const { return datatype; }
|
||||
virtual String get_datatype_name() const { return String(struct_name); }
|
||||
|
||||
MemberNode() :
|
||||
Node(TYPE_MEMBER),
|
||||
basetype(TYPE_VOID),
|
||||
datatype(TYPE_VOID),
|
||||
owner(nullptr) {}
|
||||
array_size(0),
|
||||
owner(nullptr),
|
||||
index_expression(nullptr),
|
||||
assign_expression(nullptr),
|
||||
has_swizzling_duplicates(false) {}
|
||||
};
|
||||
|
||||
struct StructNode : public Node {
|
||||
List<MemberNode *> members;
|
||||
StructNode() :
|
||||
Node(TYPE_STRUCT) {}
|
||||
};
|
||||
|
||||
struct FunctionNode : public Node {
|
||||
|
@ -490,11 +543,13 @@ public:
|
|||
ArgumentQualifier qualifier;
|
||||
StringName name;
|
||||
DataType type;
|
||||
StringName type_str;
|
||||
DataPrecision precision;
|
||||
};
|
||||
|
||||
StringName name;
|
||||
DataType return_type;
|
||||
StringName return_struct_name;
|
||||
DataPrecision return_precision;
|
||||
Vector<Argument> arguments;
|
||||
BlockNode *body;
|
||||
|
@ -512,6 +567,7 @@ public:
|
|||
struct Constant {
|
||||
StringName name;
|
||||
DataType type;
|
||||
StringName type_str;
|
||||
DataPrecision precision;
|
||||
ConstantNode *initializer;
|
||||
};
|
||||
|
@ -523,13 +579,30 @@ public:
|
|||
bool callable;
|
||||
};
|
||||
|
||||
struct Struct {
|
||||
StringName name;
|
||||
StructNode *shader_struct;
|
||||
};
|
||||
|
||||
struct Varying {
|
||||
enum Stage {
|
||||
STAGE_UNKNOWN,
|
||||
STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT or STAGE_VERTEX_TO_LIGHT, emits error if they are not used
|
||||
STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits error if it's not used
|
||||
STAGE_VERTEX_TO_FRAGMENT,
|
||||
STAGE_VERTEX_TO_LIGHT,
|
||||
STAGE_FRAGMENT_TO_LIGHT,
|
||||
};
|
||||
|
||||
Stage stage;
|
||||
DataType type;
|
||||
DataInterpolation interpolation;
|
||||
DataPrecision precision;
|
||||
int array_size;
|
||||
TkPos tkpos;
|
||||
|
||||
Varying() :
|
||||
stage(STAGE_UNKNOWN),
|
||||
type(TYPE_VOID),
|
||||
interpolation(INTERPOLATION_FLAT),
|
||||
precision(PRECISION_DEFAULT),
|
||||
|
@ -573,10 +646,12 @@ public:
|
|||
Map<StringName, Constant> constants;
|
||||
Map<StringName, Varying> varyings;
|
||||
Map<StringName, Uniform> uniforms;
|
||||
Map<StringName, Struct> structs;
|
||||
Vector<StringName> render_modes;
|
||||
|
||||
Vector<Function> functions;
|
||||
Vector<Constant> vconstants;
|
||||
Vector<Struct> vstructs;
|
||||
|
||||
ShaderNode() :
|
||||
Node(TYPE_SHADER) {}
|
||||
|
@ -603,6 +678,7 @@ public:
|
|||
COMPLETION_FUNCTION_CALL,
|
||||
COMPLETION_CALL_ARGUMENTS,
|
||||
COMPLETION_INDEX,
|
||||
COMPLETION_STRUCT,
|
||||
};
|
||||
|
||||
struct Token {
|
||||
|
@ -673,11 +749,7 @@ private:
|
|||
int tk_line;
|
||||
|
||||
StringName current_function;
|
||||
|
||||
struct TkPos {
|
||||
int char_idx;
|
||||
int tk_line;
|
||||
};
|
||||
bool last_const = false;
|
||||
|
||||
TkPos _get_tkpos() {
|
||||
TkPos tkp;
|
||||
|
@ -718,7 +790,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 = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr);
|
||||
bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr);
|
||||
bool _is_operator_assign(Operator p_op) const;
|
||||
bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = nullptr);
|
||||
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
|
||||
|
@ -743,6 +815,7 @@ private:
|
|||
DataType completion_base;
|
||||
SubClassTag completion_class;
|
||||
StringName completion_function;
|
||||
StringName completion_struct;
|
||||
int completion_argument;
|
||||
|
||||
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
|
||||
|
@ -750,11 +823,15 @@ private:
|
|||
static const BuiltinFuncOutArgs builtin_func_out_args[];
|
||||
|
||||
Error _validate_datatype(DataType p_type);
|
||||
bool _compare_datatypes_in_nodes(Node *a, Node *b) const;
|
||||
|
||||
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
|
||||
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
|
||||
bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = nullptr);
|
||||
bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message);
|
||||
bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message);
|
||||
|
||||
Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
|
||||
Node *_parse_array_constructor(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, DataType p_type, const StringName &p_struct_name, int p_array_size);
|
||||
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
|
||||
|
||||
Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
|
||||
|
|
Loading…
Reference in a new issue