summaryrefslogtreecommitdiff
path: root/drivers/gles3/shader_compiler_gles3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/shader_compiler_gles3.cpp')
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp184
1 files changed, 165 insertions, 19 deletions
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 350107de69..7499962da3 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -79,6 +79,12 @@ static int _get_datatype_size(SL::DataType p_type) {
case SL::TYPE_SAMPLER2D: return 16;
case SL::TYPE_ISAMPLER2D: return 16;
case SL::TYPE_USAMPLER2D: return 16;
+ case SL::TYPE_SAMPLER2DARRAY: return 16;
+ case SL::TYPE_ISAMPLER2DARRAY: return 16;
+ case SL::TYPE_USAMPLER2DARRAY: return 16;
+ case SL::TYPE_SAMPLER3D: return 16;
+ case SL::TYPE_ISAMPLER3D: return 16;
+ case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
}
@@ -112,6 +118,12 @@ static int _get_datatype_alignment(SL::DataType p_type) {
case SL::TYPE_SAMPLER2D: return 16;
case SL::TYPE_ISAMPLER2D: return 16;
case SL::TYPE_USAMPLER2D: return 16;
+ case SL::TYPE_SAMPLER2DARRAY: return 16;
+ case SL::TYPE_ISAMPLER2DARRAY: return 16;
+ case SL::TYPE_USAMPLER2DARRAY: return 16;
+ case SL::TYPE_SAMPLER3D: return 16;
+ case SL::TYPE_ISAMPLER3D: return 16;
+ case SL::TYPE_USAMPLER3D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
}
@@ -121,8 +133,7 @@ static String _interpstr(SL::DataInterpolation p_interp) {
switch (p_interp) {
case SL::INTERPOLATION_FLAT: return "flat ";
- case SL::INTERPOLATION_NO_PERSPECTIVE: return "noperspective ";
- case SL::INTERPOLATION_SMOOTH: return "smooth ";
+ case SL::INTERPOLATION_SMOOTH: return "";
}
return "";
}
@@ -155,15 +166,17 @@ static String _opstr(SL::Operator p_op) {
static String _mkid(const String &p_id) {
- return "m_" + p_id;
+ String id = "m_" + p_id;
+ return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
static String f2sp0(float p_float) {
- if (int(p_float) == p_float)
- return itos(p_float) + ".0";
- else
- return rtoss(p_float);
+ String num = rtoss(p_float);
+ if (num.find(".") == -1 && num.find("e") == -1) {
+ num += ".0";
+ }
+ return num;
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) {
@@ -216,7 +229,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
text += ")";
return text;
} break;
- case SL::TYPE_FLOAT: return f2sp0(p_values[0].real) + "f";
+ case SL::TYPE_FLOAT: return f2sp0(p_values[0].real);
case SL::TYPE_VEC2:
case SL::TYPE_VEC3:
case SL::TYPE_VEC4: {
@@ -360,7 +373,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
ucode = "uniform ";
}
- ucode += _prestr(E->get().precission);
+ ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type);
ucode += " " + _mkid(E->key());
ucode += ";\n";
@@ -451,19 +464,38 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
String vcode;
String interp_mode = _interpstr(E->get().interpolation);
- vcode += _prestr(E->get().precission);
+ vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key());
+ if (E->get().array_size > 0) {
+ vcode += "[";
+ vcode += itos(E->get().array_size);
+ vcode += "]";
+ }
vcode += ";\n";
r_gen_code.vertex_global += interp_mode + "out " + vcode;
r_gen_code.fragment_global += interp_mode + "in " + vcode;
}
+ for (Map<StringName, SL::ShaderNode::Constant>::Element *E = pnode->constants.front(); E; E = E->next()) {
+ String gcode;
+ gcode += "const ";
+ gcode += _prestr(E->get().precision);
+ 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);
+ gcode += ";\n";
+ r_gen_code.vertex_global += gcode;
+ r_gen_code.fragment_global += gcode;
+ }
+
Map<StringName, String> function_code;
//code for functions
for (int i = 0; i < pnode->functions.size(); i++) {
SL::FunctionNode *fnode = pnode->functions[i].function;
+ 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);
}
@@ -528,7 +560,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
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 ";
+ }
+ declaration += _prestr(vdnode->precision);
+ declaration += _typestr(vdnode->datatype);
for (int i = 0; i < vdnode->declarations.size(); i++) {
if (i > 0) {
declaration += ",";
@@ -580,6 +617,93 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
} break;
+ case SL::Node::TYPE_ARRAY_DECLARATION: {
+
+ SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
+
+ String declaration;
+ 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) {
+ declaration += ",";
+ } else {
+ declaration += " ";
+ }
+ declaration += _mkid(adnode->declarations[i].name);
+ declaration += "[";
+ declaration += itos(adnode->declarations[i].size);
+ declaration += "]";
+ int sz = adnode->declarations[i].initializer.size();
+ if (sz > 0) {
+ declaration += "=";
+ declaration += _typestr(adnode->datatype);
+ declaration += "[";
+ declaration += itos(sz);
+ declaration += "]";
+ declaration += "(";
+ for (int j = 0; j < sz; j++) {
+ 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) {
+ declaration += ", ";
+ }
+ }
+ declaration += ")";
+ }
+ }
+
+ code += declaration;
+ } break;
+ case SL::Node::TYPE_ARRAY: {
+ SL::ArrayNode *anode = (SL::ArrayNode *)p_node;
+
+ if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) {
+ *p_actions.write_flag_pointers[anode->name] = true;
+ }
+
+ if (p_default_actions.usage_defines.has(anode->name) && !used_name_defines.has(anode->name)) {
+ String define = p_default_actions.usage_defines[anode->name];
+ if (define.begins_with("@")) {
+ define = p_default_actions.usage_defines[define.substr(1, define.length())];
+ }
+ r_gen_code.defines.push_back(define.utf8());
+ used_name_defines.insert(anode->name);
+ }
+
+ if (p_actions.usage_flag_pointers.has(anode->name) && !used_flag_pointers.has(anode->name)) {
+ *p_actions.usage_flag_pointers[anode->name] = true;
+ used_flag_pointers.insert(anode->name);
+ }
+
+ if (p_default_actions.renames.has(anode->name))
+ code = p_default_actions.renames[anode->name];
+ else
+ code = _mkid(anode->name);
+
+ if (anode->call_expression != NULL) {
+ code += ".";
+ code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ }
+
+ if (anode->index_expression != NULL) {
+ code += "[";
+ code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += "]";
+ }
+
+ if (anode->name == time_name) {
+ if (current_func_name == vertex_name) {
+ r_gen_code.uses_vertex_time = true;
+ }
+ if (current_func_name == fragment_name || current_func_name == light_name) {
+ r_gen_code.uses_fragment_time = true;
+ }
+ }
+
+ } break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
return get_constant_text(cnode->datatype, cnode->values);
@@ -653,11 +777,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_SELECT_IF: {
+ code += "(";
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "?";
code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += ":";
code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ")";
} break;
@@ -680,6 +806,20 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _mktab(p_level) + "else\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
+ } else if (cfnode->flow_op == SL::FLOW_OP_SWITCH) {
+ code += _mktab(p_level) + "switch (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_CASE) {
+ code += _mktab(p_level) + "case " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_DEFAULT) {
+ code += _mktab(p_level) + "default:\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_DO) {
+ code += _mktab(p_level) + "do";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");";
+
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
@@ -734,7 +874,7 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
Vector<String> shader = p_code.split("\n");
for (int i = 0; i < shader.size(); i++) {
- print_line(itos(i) + " " + shader[i]);
+ print_line(itos(i + 1) + " " + shader[i]);
}
_err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER);
@@ -772,7 +912,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
/** CANVAS ITEM SHADER **/
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
- actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp";
+ actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize";
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
@@ -801,6 +941,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
@@ -809,6 +950,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
@@ -824,6 +966,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["NORMAL"] = "normal";
actions[VS::SHADER_SPATIAL].renames["TANGENT"] = "tangent";
actions[VS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal";
+ actions[VS::SHADER_SPATIAL].renames["POSITION"] = "position";
actions[VS::SHADER_SPATIAL].renames["UV"] = "uv_interp";
actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp";
actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp";
@@ -860,6 +1003,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth";
actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
@@ -888,6 +1032,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
@@ -927,13 +1072,14 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
/* PARTICLES SHADER */
actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color";
actions[VS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz";
actions[VS::SHADER_PARTICLES].renames["MASS"] = "mass";
- actions[VS::SHADER_PARTICLES].renames["ACTIVE"] = "active";
+ actions[VS::SHADER_PARTICLES].renames["ACTIVE"] = "shader_active";
actions[VS::SHADER_PARTICLES].renames["RESTART"] = "restart";
actions[VS::SHADER_PARTICLES].renames["CUSTOM"] = "out_custom";
actions[VS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform";
@@ -946,9 +1092,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform";
actions[VS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed";
- actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n";
- actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n";
- actions[VS::SHADER_SPATIAL].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n";
+ actions[VS::SHADER_PARTICLES].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n";
+ actions[VS::SHADER_PARTICLES].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n";
+ actions[VS::SHADER_PARTICLES].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n";
vertex_name = "vertex";
fragment_name = "fragment";