From 6425fd2ec9c7e1e13c3afa7a79a9a2442d9e5c50 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 9 Apr 2022 19:01:25 +0300 Subject: [PATCH] Don't add depth range conversion if an assignment to gl_Position.z exists This is kinda crude since it triggers from any such assignment, but it allows the idempotence test cases to work. --- source/glsl/finalize.cpp | 35 ++++++++++++++++++++++++++++++++++- source/glsl/finalize.h | 10 ++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index fcf48c61..85a6b07a 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -251,9 +251,42 @@ void DepthRangeConverter::apply(Stage &stage, const Features &features) stage.content.visit(*this); } +void DepthRangeConverter::visit(VariableReference &var) +{ + const StructDeclaration *strct = dynamic_cast(var.type); + r_gl_pervertex = (strct && strct->block_name=="gl_PerVertex"); +} + +void DepthRangeConverter::visit(MemberAccess &memacc) +{ + r_gl_pervertex = false; + memacc.left->visit(*this); + r_gl_position = (r_gl_pervertex && memacc.member=="gl_Position"); +} + +void DepthRangeConverter::visit(Swizzle &swiz) +{ + r_gl_position = false; + swiz.left->visit(*this); + if(assignment_target && r_gl_position && swiz.count==1 && swiz.components[0]==2) + r_position_z_assigned = true; +} + +void DepthRangeConverter::visit(Assignment &assign) +{ + { + SetFlag set_target(assignment_target); + assign.left->visit(*this); + } + assign.right->visit(*this); +} + void DepthRangeConverter::visit(FunctionDeclaration &func) { - if(func.definition==&func && func.name=="main") + r_position_z_assigned = false; + TraversingVisitor::visit(func); + + if(func.definition==&func && func.name=="main" && !r_position_z_assigned) { VariableReference *position = new VariableReference; position->name = "gl_Position"; diff --git a/source/glsl/finalize.h b/source/glsl/finalize.h index 6e96c65e..ec5f459a 100644 --- a/source/glsl/finalize.h +++ b/source/glsl/finalize.h @@ -61,10 +61,20 @@ Converts the output depth range to match expectations of the target API. */ class DepthRangeConverter: private TraversingVisitor { +private: + bool assignment_target = false; + bool r_gl_pervertex = false; + bool r_gl_position = false; + bool r_position_z_assigned = false; + public: void apply(Stage &, const Features &); private: + virtual void visit(VariableReference &); + virtual void visit(MemberAccess &); + virtual void visit(Swizzle &); + virtual void visit(Assignment &); virtual void visit(FunctionDeclaration &); }; -- 2.45.2