ConstantSpecializer().apply(s, spec_values);
}
if(mode==PROGRAM)
- {
- for(Stage &s: module->stages)
- DepthRangeConverter().apply(s, features);
- }
+ DepthRangeConverter().apply(*module, features);
for(auto i=module->stages.begin(); i!=module->stages.end(); )
{
OptimizeResult result = optimize(*i);
}
-void DepthRangeConverter::apply(Stage &stage, const Features &features)
+void DepthRangeConverter::apply(Module &module, const Features &features)
{
- if(stage.type!=Stage::VERTEX || features.target_api==VULKAN)
+ if(features.target_api==VULKAN)
return;
- stage.content.visit(*this);
+ for(Stage *s=&module.stages.back(); (!r_position_z_assigned && s); s=s->previous)
+ s->content.visit(*this);
}
NodePtr<Statement> DepthRangeConverter::create_conversion_statement()
return statement;
}
+void DepthRangeConverter::visit(Block &block)
+{
+ for(auto i=block.body.begin(); i!=block.body.end(); ++i)
+ {
+ r_emitvertex = false;
+ (*i)->visit(*this);
+ if(r_emitvertex && !r_position_z_assigned)
+ {
+ block.body.insert_nocopy(i, create_conversion_statement());
+ r_position_z_assigned = true;
+ }
+ }
+}
+
void DepthRangeConverter::visit(VariableReference &var)
{
const StructDeclaration *strct = dynamic_cast<const StructDeclaration *>(var.type);
r_gl_pervertex = false;
memacc.left->visit(*this);
r_gl_position = (r_gl_pervertex && memacc.member=="gl_Position");
+ if(assignment_target && r_gl_position)
+ {
+ r_position_assigned = true;
+ r_position_z_assigned = false;
+ }
}
void DepthRangeConverter::visit(Swizzle &swiz)
assign.right->visit(*this);
}
+void DepthRangeConverter::visit(FunctionCall &call)
+{
+ if(call.name=="EmitVertex")
+ r_emitvertex = true;
+}
+
void DepthRangeConverter::visit(FunctionDeclaration &func)
{
r_position_z_assigned = false;
TraversingVisitor::visit(func);
- if(func.definition==&func && func.name=="main" && !r_position_z_assigned)
+ if(func.definition==&func && func.name=="main" && r_position_assigned && !r_position_z_assigned)
+ {
func.body.body.push_back_nocopy(create_conversion_statement());
+ r_position_z_assigned = true;
+ }
}
bool assignment_target = false;
bool r_gl_pervertex = false;
bool r_gl_position = false;
+ bool r_emitvertex = false;
+ bool r_position_assigned = false;
bool r_position_z_assigned = false;
public:
- void apply(Stage &, const Features &);
+ void apply(Module &, const Features &);
private:
NodePtr<Statement> create_conversion_statement();
+ virtual void visit(Block &);
virtual void visit(VariableReference &);
virtual void visit(MemberAccess &);
virtual void visit(Swizzle &);
virtual void visit(Assignment &);
+ virtual void visit(FunctionCall &);
virtual void visit(FunctionDeclaration &);
};