aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRémi Verschelde2017-06-15 15:12:43 +0200
committerGitHub2017-06-15 15:12:43 +0200
commit734045667dcd502373e5661c9c486111bcbc9a1b (patch)
treef807573a8948b5390ed48eef7c08fd0e6bbac293 /drivers
parent8536d21931f69941bce9316da4307c41e0558919 (diff)
parent184ef184209d42c06f04a5a3162bd76a1a184be0 (diff)
downloadgodot-734045667dcd502373e5661c9c486111bcbc9a1b.tar.gz
godot-734045667dcd502373e5661c9c486111bcbc9a1b.tar.zst
godot-734045667dcd502373e5661c9c486111bcbc9a1b.zip
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp58
-rw-r--r--drivers/gles2/shader_compiler_gles2.h2
-rw-r--r--drivers/gles2/shaders/canvas.glsl6
3 files changed, 59 insertions, 7 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 56e1777ef..eeb373af0 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -502,15 +502,30 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node, int p_level, bool p
SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node;
if (cfnode->flow_op == SL::FLOW_OP_IF) {
- code += "if (" + dump_node_code(cfnode->statements[0], p_level) + ") {" ENDL;
- code += dump_node_code(cfnode->statements[1], p_level + 1);
- if (cfnode->statements.size() == 3) {
+ // Help lazy drivers
+ if (!_is_condition_preprocessable(cfnode->statements[0])) {
- code += "} else {" ENDL;
- code += dump_node_code(cfnode->statements[2], p_level + 1);
- }
+ code += "if (" + dump_node_code(cfnode->statements[0], p_level) + ") {" ENDL;
+ code += dump_node_code(cfnode->statements[1], p_level + 1);
+ if (cfnode->statements.size() == 3) {
+
+ code += "} else {" ENDL;
+ code += dump_node_code(cfnode->statements[2], p_level + 1);
+ }
+
+ code += "}" ENDL;
+ } else {
- code += "}" ENDL;
+ code += "#if (" + dump_node_code(cfnode->statements[0], p_level) + ")" ENDL;
+ code += dump_node_code(cfnode->statements[1], p_level);
+ if (cfnode->statements.size() == 3) {
+
+ code += "#else" ENDL;
+ code += dump_node_code(cfnode->statements[2], p_level);
+ }
+
+ code += "#endif" ENDL;
+ }
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
@@ -649,6 +664,33 @@ String ShaderCompilerGLES2::replace_string(const StringName &p_string) {
return "_" + p_string.operator String();
}
+bool ShaderCompilerGLES2::_is_condition_preprocessable(ShaderLanguage::Node *p_condition) const {
+
+ // Check if this is a "(!)variable" expression
+
+ SL::Node *maybe_variable;
+ if (p_condition->type == SL::Node::TYPE_OPERATOR) {
+ SL::OperatorNode *op = (SL::OperatorNode *)p_condition;
+ if (op->op != SL::OP_NOT)
+ return false;
+ maybe_variable = op->arguments[0];
+ } else {
+ maybe_variable = p_condition;
+ }
+
+ if (maybe_variable->type != SL::Node::TYPE_VARIABLE)
+ return false;
+
+ SL::VariableNode *variable = (SL::VariableNode *)maybe_variable;
+ // Hardcoding since it's currently the only;
+ // if more were added, they would be better characterized
+ // in the various ShaderLanguage::BuiltinsDef
+ if (variable->name != String("AT_LIGHT_PASS"))
+ return false;
+
+ return true;
+}
+
Error ShaderCompilerGLES2::compile(const String &p_code, ShaderLanguage::ShaderType p_type, String &r_code_line, String &r_globals_line, Flags &r_flags, Map<StringName, ShaderLanguage::Uniform> *r_uniforms) {
uses_texscreen = false;
@@ -873,6 +915,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["PROJECTION_MATRIX"] = "projection_matrix";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["EXTRA_MATRIX"] = "extra_matrix";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["TIME"] = "time";
+ mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["AT_LIGHT_PASS"] = "at_light_pass";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["POSITION"] = "(gl_FragCoord.xy)";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["NORMAL"] = "normal";
@@ -888,6 +931,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["SCREEN_UV"] = "screen_uv";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["POINT_COORD"] = "gl_PointCoord";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["TIME"] = "time";
+ mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["AT_LIGHT_PASS"] = "at_light_pass";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["POSITION"] = "(gl_FragCoord.xy)";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["NORMAL"] = "normal";
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index 02f9e5897..b71eb1fb5 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -44,6 +44,8 @@ private:
Error compile_node(ShaderLanguage::ProgramNode *p_program);
static Error create_glsl_120_code(void *p_str, ShaderLanguage::ProgramNode *p_program);
+ bool _is_condition_preprocessable(ShaderLanguage::Node *p_condition) const;
+
bool uses_light;
bool uses_texscreen;
bool uses_texpos;
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 5f4767940..3ffa25379 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -39,6 +39,9 @@ uniform vec2 normal_flip;
varying highp vec2 pos;
#endif
+#define at_light_pass 1
+#else
+#define at_light_pass 0
#endif
#if defined(ENABLE_VAR1_INTERP)
@@ -176,6 +179,9 @@ uniform float shadow_esm_multiplier;
#endif
+#define at_light_pass 1
+#else
+#define at_light_pass 0
#endif
#if defined(USE_TEXPIXEL_SIZE)