From: Mikko Rasa Date: Sun, 7 Nov 2021 10:46:29 +0000 (+0200) Subject: Apply implicit conversion to return expressions in GLSL functions X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=f661973abaa7d189a61d76708d0c90cfcdb4b440 Apply implicit conversion to return expressions in GLSL functions --- diff --git a/source/glsl/resolve.cpp b/source/glsl/resolve.cpp index b80ae217..eb99bec2 100644 --- a/source/glsl/resolve.cpp +++ b/source/glsl/resolve.cpp @@ -1141,6 +1141,28 @@ void ExpressionResolver::visit(VariableDeclaration &var) convert_to(var.init_expression, *var_basic); } +void ExpressionResolver::visit(FunctionDeclaration &func) +{ + SetForScope set_func(current_function, &func); + TraversingVisitor::visit(func); +} + +void ExpressionResolver::visit(Return &ret) +{ + TraversingVisitor::visit(ret); + if(!current_function || !ret.expression) + return; + + BasicTypeDeclaration *ret_basic = dynamic_cast(current_function->return_type_declaration); + BasicTypeDeclaration *expr_basic = dynamic_cast(ret.expression->type); + if(!ret_basic || !expr_basic) + return; + + Compatibility compat = get_compatibility(*ret_basic, *expr_basic); + if(compat==RIGHT_CONVERTIBLE) + convert_to(ret.expression, *ret_basic); +} + bool FunctionResolver::apply(Stage &s) { diff --git a/source/glsl/resolve.h b/source/glsl/resolve.h index 10322d49..fdbebfe8 100644 --- a/source/glsl/resolve.h +++ b/source/glsl/resolve.h @@ -102,6 +102,7 @@ private: }; Stage *stage = 0; + const FunctionDeclaration *current_function = 0; std::vector basic_types; NodeList::iterator insert_point; bool r_any_resolved = false; @@ -133,6 +134,8 @@ private: virtual void visit(FunctionCall &); virtual void visit(BasicTypeDeclaration &); virtual void visit(VariableDeclaration &); + virtual void visit(FunctionDeclaration &); + virtual void visit(Return &); }; /** Resolves function declarations and calls. */ diff --git a/tests/glsl/return_type_conversion.glsl b/tests/glsl/return_type_conversion.glsl new file mode 100644 index 00000000..3467311c --- /dev/null +++ b/tests/glsl/return_type_conversion.glsl @@ -0,0 +1,78 @@ +uniform Shadow +{ + mat4 shadow_matrix; +}; +uniform Camera +{ + mat4 viewproj_matrix; +}; +uniform Surface +{ + vec4 color; +}; +uniform mat4 model_matrix; +uniform sampler2DShadow shadow_map; + +#pragma MSP stage(vertex) +layout(location=0) in vec4 position; +void main() +{ + out vec4 world_position = model_matrix*position; + gl_Position = viewproj_matrix*world_position; +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_out; +float get_shadow() +{ + vec3 shadow_coord = (shadow_matrix*world_position).xyz; + if(shadow_coord.x>=0 && shadow_coord.x<=1 && shadow_coord.y>=0 && shadow_coord.y<=1) + return texture(shadow_map, shadow_coord); + else + return 1; +} +void main() +{ + frag_out = vec4(color.rgb*get_shadow(), color.a); +} + +/* Expected output: vertex +layout(binding=72) uniform Camera +{ + mat4 viewproj_matrix; +}; +layout(location=0) uniform mat4 model_matrix; +layout(location=0) in vec4 position; +layout(location=0) out vec4 world_position; +void main() +{ + world_position = model_matrix*position; + gl_Position = viewproj_matrix*world_position; +} +*/ + +/* Expected output: fragment +layout(binding=71) uniform Shadow +{ + mat4 shadow_matrix; +}; +layout(binding=77) uniform Surface +{ + vec4 color; +}; +layout(location=4, binding=73) uniform sampler2DShadow shadow_map; +layout(location=0) out vec4 frag_out; +layout(location=0) in vec4 world_position; +float get_shadow() +{ + vec3 shadow_coord = (shadow_matrix*world_position).xyz; + if(shadow_coord.x>=0.0&&shadow_coord.x<=1.0&&shadow_coord.y>=0.0&&shadow_coord.y<=1.0) + return texture(shadow_map, shadow_coord); + else + return 1.0; +} +void main() +{ + frag_out = vec4(color.rgb*get_shadow(), color.a); +} +*/