diff options
Diffstat (limited to 'drivers/gles2/shader_compiler_gles2.cpp')
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 123 |
1 files changed, 104 insertions, 19 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 5dec6f2fee..620fcdbdca 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -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"; @@ -305,12 +304,48 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.texture_uniforms.resize(max_texture_uniforms); r_gen_code.texture_hints.resize(max_texture_uniforms); + r_gen_code.texture_types.resize(max_texture_uniforms); r_gen_code.uniforms.resize(max_uniforms + max_texture_uniforms); 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()) { @@ -332,6 +367,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener if (SL::is_sampler_type(E->get().type)) { r_gen_code.texture_uniforms.write[E->get().texture_order] = E->key(); r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint; + r_gen_code.texture_types.write[E->get().texture_order] = E->get().type; } else { r_gen_code.uniforms.write[E->get().order] = E->key(); } @@ -372,7 +408,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); @@ -418,7 +458,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; @@ -457,8 +499,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++) { @@ -517,14 +563,37 @@ 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 (acnode->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) { @@ -644,12 +713,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 { @@ -660,6 +731,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener code += "texture2D"; } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) { code += "textureCube"; + } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER3D) { + code += "texture3D"; + } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2DARRAY) { + code += "texture2DArray"; } } else if (var_node->name == "textureLod") { @@ -669,6 +744,10 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener code += "texture2DLod"; } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) { code += "textureCubeLod"; + } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER3D) { + code += "texture3DLod"; + } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2DARRAY) { + code += "texture2DArrayLod"; } } else if (var_node->name == "mix") { @@ -844,6 +923,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 != NULL) { + code += "["; + code += _dump_node_code(member_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "]"; + } } break; } @@ -869,6 +953,7 @@ Error ShaderCompilerGLES2::compile(VS::ShaderMode p_mode, const String &p_code, r_gen_code.uniforms.clear(); r_gen_code.texture_uniforms.clear(); r_gen_code.texture_hints.clear(); + r_gen_code.texture_types.clear(); r_gen_code.vertex = String(); r_gen_code.vertex_global = String(); r_gen_code.fragment = String(); |