Skip to content

Commit

Permalink
Implementation of 'struct' for shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
Chaosus committed Feb 11, 2020
1 parent 1eb424e commit 6f16239
Show file tree
Hide file tree
Showing 6 changed files with 673 additions and 178 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 @@ -1636,6 +1636,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
82 changes: 63 additions & 19 deletions drivers/gles2/shader_compiler_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,21 +240,20 @@ 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 Down Expand Up @@ -312,6 +311,36 @@ 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;
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 @@ -374,7 +403,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
String gcode;
gcode += "const ";
gcode += _prestr(E->get().precision);
gcode += _typestr(E->get().type);
if (E->get().type == SL::TYPE_STRUCT) {
gcode += _mkid(E->get().type_str);
} else {
gcode += _typestr(E->get().type);
}
gcode += " " + _mkid(E->key());
gcode += "=";
gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
Expand Down Expand Up @@ -420,7 +453,9 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
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 @@ -459,8 +494,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++) {

Expand Down Expand Up @@ -524,9 +563,12 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
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) {
Expand Down Expand Up @@ -646,12 +688,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 {

Expand Down
3 changes: 3 additions & 0 deletions main/tests/test_shader_lang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ 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: {

Expand Down
85 changes: 77 additions & 8 deletions servers/visual/rasterizer_rd/shader_compiler_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static int _get_datatype_size(SL::DataType p_type) {
case SL::TYPE_ISAMPLER3D: return 16;
case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
case SL::TYPE_STRUCT: return 0;
}

ERR_FAIL_V(0);
Expand Down Expand Up @@ -129,6 +130,7 @@ static int _get_datatype_alignment(SL::DataType p_type) {
case SL::TYPE_ISAMPLER3D: return 16;
case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
case SL::TYPE_STRUCT: return 0;
}

ERR_FAIL_V(0);
Expand Down Expand Up @@ -315,12 +317,20 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
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";
Expand Down Expand Up @@ -359,6 +369,36 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
}

// 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;
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;

Expand Down Expand Up @@ -506,7 +546,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
String gcode;
gcode += "const ";
gcode += _prestr(E->get().precision);
gcode += _typestr(E->get().type);
if (E->get().type == SL::TYPE_STRUCT) {
gcode += _mkid(E->get().type_str);
} else {
gcode += _typestr(E->get().type);
}
gcode += " " + _mkid(E->key());
gcode += "=";
gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
Expand Down Expand Up @@ -560,6 +604,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}

//code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_STRUCT: {

} break;
case SL::Node::TYPE_FUNCTION: {

Expand Down Expand Up @@ -590,7 +637,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
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 ";
}
if (vdnode->datatype == SL::TYPE_STRUCT) {
declaration += _mkid(vdnode->struct_name);
} else {
declaration += _prestr(vdnode->precision) + _typestr(vdnode->datatype);
}
for (int i = 0; i < vdnode->declarations.size(); i++) {
if (i > 0) {
declaration += ",";
Expand Down Expand Up @@ -649,8 +704,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
case SL::Node::TYPE_ARRAY_DECLARATION: {

SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;

String declaration = _prestr(adnode->precision) + _typestr(adnode->datatype);
String declaration;
if (adnode->is_const) {
declaration += "const ";
}
if (adnode->datatype == SL::TYPE_STRUCT) {
declaration += _mkid(adnode->struct_name);
} else {
declaration = _prestr(adnode->precision) + _typestr(adnode->datatype);
}
for (int i = 0; i < adnode->declarations.size(); i++) {
if (i > 0) {
declaration += ",";
Expand All @@ -664,7 +726,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
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 += "]";
Expand Down Expand Up @@ -763,14 +829,17 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
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];

bool is_texture_func = false;
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 {

Expand Down
Loading

0 comments on commit 6f16239

Please sign in to comment.