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.cpp128
1 files changed, 91 insertions, 37 deletions
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index ac43b3ce1b..f1d7085d54 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -56,6 +56,41 @@ static int _get_datatype_size(SL::DataType p_type) {
case SL::TYPE_VOID: return 0;
case SL::TYPE_BOOL: return 4;
case SL::TYPE_BVEC2: return 8;
+ case SL::TYPE_BVEC3: return 12;
+ case SL::TYPE_BVEC4: return 16;
+ case SL::TYPE_INT: return 4;
+ case SL::TYPE_IVEC2: return 8;
+ case SL::TYPE_IVEC3: return 12;
+ case SL::TYPE_IVEC4: return 16;
+ case SL::TYPE_UINT: return 4;
+ case SL::TYPE_UVEC2: return 8;
+ case SL::TYPE_UVEC3: return 12;
+ case SL::TYPE_UVEC4: return 16;
+ case SL::TYPE_FLOAT: return 4;
+ case SL::TYPE_VEC2: return 8;
+ case SL::TYPE_VEC3: return 12;
+ case SL::TYPE_VEC4: return 16;
+ case SL::TYPE_MAT2:
+ return 32; //4 * 4 + 4 * 4
+ case SL::TYPE_MAT3:
+ return 48; // 4 * 4 + 4 * 4 + 4 * 4
+ case SL::TYPE_MAT4: return 64;
+ case SL::TYPE_SAMPLER2D: return 16;
+ case SL::TYPE_ISAMPLER2D: return 16;
+ case SL::TYPE_USAMPLER2D: return 16;
+ case SL::TYPE_SAMPLERCUBE: return 16;
+ }
+
+ ERR_FAIL_V(0);
+}
+
+static int _get_datatype_alignment(SL::DataType p_type) {
+
+ switch (p_type) {
+
+ case SL::TYPE_VOID: return 0;
+ case SL::TYPE_BOOL: return 4;
+ case SL::TYPE_BVEC2: return 8;
case SL::TYPE_BVEC3: return 16;
case SL::TYPE_BVEC4: return 16;
case SL::TYPE_INT: return 4;
@@ -71,8 +106,8 @@ static int _get_datatype_size(SL::DataType p_type) {
case SL::TYPE_VEC3: return 16;
case SL::TYPE_VEC4: return 16;
case SL::TYPE_MAT2: return 16;
- case SL::TYPE_MAT3: return 48;
- case SL::TYPE_MAT4: return 64;
+ case SL::TYPE_MAT3: return 16;
+ case SL::TYPE_MAT4: return 16;
case SL::TYPE_SAMPLER2D: return 16;
case SL::TYPE_ISAMPLER2D: return 16;
case SL::TYPE_USAMPLER2D: return 16;
@@ -81,7 +116,6 @@ static int _get_datatype_size(SL::DataType p_type) {
ERR_FAIL_V(0);
}
-
static String _interpstr(SL::DataInterpolation p_interp) {
switch (p_interp) {
@@ -267,7 +301,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) {
+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) {
String code;
@@ -341,7 +375,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
uniform_defines[E->get().order] = ucode;
uniform_sizes[E->get().order] = _get_datatype_size(E->get().type);
- uniform_alignments[E->get().order] = MIN(16, _get_datatype_size(E->get().type));
+ uniform_alignments[E->get().order] = _get_datatype_alignment(E->get().type);
}
p_actions.uniforms->insert(E->key(), E->get());
@@ -350,6 +384,27 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
for (int i = 0; i < max_uniforms; i++) {
r_gen_code.uniforms += uniform_defines[i];
}
+#if 1
+ // add up
+ int offset = 0;
+ for (int i = 0; i < uniform_sizes.size(); i++) {
+
+ int align = offset % uniform_alignments[i];
+
+ if (align != 0) {
+ offset += uniform_alignments[i] - align;
+ }
+
+ r_gen_code.uniform_offsets.push_back(offset);
+
+ offset += uniform_sizes[i];
+ }
+
+ r_gen_code.uniform_total_size = offset;
+ if (r_gen_code.uniform_total_size % 16 != 0) { //UBO sizes must be multiples of 16
+ r_gen_code.uniform_total_size += r_gen_code.uniform_total_size % 16;
+ }
+#else
// add up
for (int i = 0; i < uniform_sizes.size(); i++) {
@@ -389,6 +444,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} else {
r_gen_code.uniform_total_size = 0;
}
+#endif
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
@@ -407,7 +463,7 @@ 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_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions);
+ function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
//place functions in actual code
@@ -455,7 +511,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
for (int i = 0; i < bnode->statements.size(); i++) {
- String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions);
+ String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) {
code += scode; //use directly
@@ -481,7 +537,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
declaration += _mkid(vdnode->declarations[i].name);
if (vdnode->declarations[i].initializer) {
declaration += "=";
- declaration += _dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions);
+ declaration += _dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
}
}
@@ -490,6 +546,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode = (SL::VariableNode *)p_node;
+ if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) {
+ *p_actions.write_flag_pointers[vnode->name] = true;
+ }
+
if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
String define = p_default_actions.usage_defines[vnode->name];
if (define.begins_with("@")) {
@@ -540,24 +600,18 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::OP_ASSIGN_BIT_AND:
case SL::OP_ASSIGN_BIT_OR:
case SL::OP_ASSIGN_BIT_XOR:
- if (onode->arguments[0]->type == SL::Node::TYPE_VARIABLE) {
- SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
- if (p_actions.write_flag_pointers.has(vnode->name)) {
- *p_actions.write_flag_pointers[vnode->name] = true;
- }
- }
- code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions);
+ code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
break;
case SL::OP_BIT_INVERT:
case SL::OP_NEGATE:
case SL::OP_NOT:
case SL::OP_DECREMENT:
case SL::OP_INCREMENT:
- code = _opstr(onode->op) + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions);
+ code = _opstr(onode->op) + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
break;
case SL::OP_POST_DECREMENT:
case SL::OP_POST_INCREMENT:
- code = _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op);
+ 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_CONSTRUCT: {
@@ -584,31 +638,31 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
for (int i = 1; i < onode->arguments.size(); i++) {
if (i > 1)
code += ", ";
- code += _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions);
+ code += _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
}
code += ")";
} break;
case SL::OP_INDEX: {
- code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions);
+ 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);
+ code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "]";
} break;
case SL::OP_SELECT_IF: {
- code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions);
+ 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);
+ 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);
+ code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
} break;
default: {
- code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions) + ")";
+ code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")";
break;
}
}
@@ -618,29 +672,29 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node;
if (cfnode->flow_op == SL::FLOW_OP_IF) {
- code += _mktab(p_level) + "if (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n";
- code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions);
+ code += _mktab(p_level) + "if (" + _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);
if (cfnode->blocks.size() == 2) {
code += _mktab(p_level) + "else\n";
- code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions);
+ 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_WHILE) {
- code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n";
- code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions);
+ code += _mktab(p_level) + "while (" + _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_FOR) {
- String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions);
- String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions);
- String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions);
+ String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += _mktab(p_level) + "for (" + left + ";" + middle + ";" + right + ")\n";
- code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions);
+ 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_RETURN) {
if (cfnode->expressions.size()) {
- code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ";";
+ code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ";";
} else {
code = "return;";
}
@@ -658,7 +712,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
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) + "." + mnode->name;
+ code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + mnode->name;
} break;
}
@@ -694,7 +748,7 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code,
used_rmode_defines.clear();
used_flag_pointers.clear();
- _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode]);
+ _dump_node_code(parser.get_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;
@@ -717,7 +771,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix";
+ actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time";
actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";