]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/finalize.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / glsl / finalize.cpp
index fcf48c61cd0ae1fbce706cff7744384525be7d7c..469cb92daba088493168f82f55e47a4b5938dccd 100644 (file)
@@ -75,7 +75,12 @@ void LocationAllocator::apply(Module &module, const Features &f, bool a)
        for(VariableDeclaration *b: unbound_blocks)
                bind_uniform(b->layout, b->block_declaration->block_name, features.uniform_binding_range);
        for(VariableDeclaration *t: unbound_textures)
-               bind_uniform(t->layout, t->name, features.texture_binding_range);
+       {
+               const TypeDeclaration *base_type = get_ultimate_base_type(t->type_declaration);
+               unsigned range = (static_cast<const ImageTypeDeclaration *>(base_type)->sampled ?
+                       features.texture_binding_range : features.storage_texture_binding_range);
+               bind_uniform(t->layout, t->name, range);
+       }
 }
 
 void LocationAllocator::apply(Stage &stage)
@@ -86,6 +91,8 @@ void LocationAllocator::apply(Stage &stage)
        stage.content.visit(*this);
 
        allocate_locations("in");
+       if(stage.type==Stage::VERTEX)
+               swap(used_locations["in"], used_vertex_attribs);
        allocate_locations("out");
 }
 
@@ -116,6 +123,8 @@ void LocationAllocator::allocate_locations(const string &iface)
                if(!alloc_new)
                        continue;
 
+               bool flat = ((*i)->interpolation=="flat" || ((*i)->linked_declaration && (*i)->linked_declaration->interpolation=="flat"));
+
                set<unsigned> &used = used_locations[(*i)->interface];
 
                unsigned size = LocationCounter().apply(**i);
@@ -123,7 +132,7 @@ void LocationAllocator::allocate_locations(const string &iface)
                {
                        int blocking = -1;
                        for(unsigned j=0; j<size; ++j)
-                               if(used.count(next+j))
+                               if(used.count(next+j) || (flat && used_vertex_attribs.count(next+j)))
                                        blocking = next+j;
                        if(blocking<0)
                                break;
@@ -251,9 +260,42 @@ void DepthRangeConverter::apply(Stage &stage, const Features &features)
        stage.content.visit(*this);
 }
 
+void DepthRangeConverter::visit(VariableReference &var)
+{
+       const StructDeclaration *strct = dynamic_cast<const StructDeclaration *>(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";
@@ -433,13 +475,27 @@ void StructuralFeatureConverter::visit(RefPtr<Expression> &expr)
 
 bool StructuralFeatureConverter::supports_stage(Stage::Type st) const
 {
-       if(st==Stage::GEOMETRY)
+       if(st==Stage::TESS_CONTROL || st==Stage::TESS_EVAL)
+       {
+               if(features.target_api==OPENGL_ES)
+                       return check_version(Version(3, 20));
+               else
+                       return check_version(Version(4, 0));
+       }
+       else if(st==Stage::GEOMETRY)
        {
                if(features.target_api==OPENGL_ES)
                        return check_version(Version(3, 20));
                else
                        return check_version(Version(1, 50));
        }
+       else if(st==Stage::COMPUTE)
+       {
+               if(features.target_api==OPENGL_ES)
+                       return check_version(Version(3, 10));
+               else
+                       return check_version(Version(4, 30));
+       }
        else
                return true;
 }