Skip to content

Commit

Permalink
Merge pull request #48075 from lyuma/varying_fragment_to_light_3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored May 18, 2021
2 parents 530a999 + 2d1f8f2 commit 330ddc3
Show file tree
Hide file tree
Showing 9 changed files with 1,391 additions and 207 deletions.
3 changes: 3 additions & 0 deletions drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
184 changes: 161 additions & 23 deletions drivers/gles2/shader_compiler_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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";
Expand All @@ -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) {
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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 ";
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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;

Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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 += ",";
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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") {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
7 changes: 5 additions & 2 deletions drivers/gles2/shader_compiler_gles2.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ class ShaderCompilerGLES2 {
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;
Expand All @@ -86,6 +88,7 @@ class ShaderCompilerGLES2 {
Set<StringName> used_flag_pointers;
Set<StringName> used_rmode_defines;
Set<StringName> internal_functions;
Set<StringName> fragment_varyings;

DefaultIdentifierActions actions[VS::SHADER_MAX];

Expand Down
3 changes: 3 additions & 0 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 330ddc3

Please sign in to comment.