]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/validate.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / glsl / validate.cpp
index 5a28fcb6abca0ec042dda6f41aff0f5d6067053d..f6b11ef22e34f8e019a43c5ff040eb8f05283c08 100644 (file)
@@ -51,7 +51,17 @@ void DeclarationValidator::apply(Stage &s, const Features &f)
                                global_err_node = j->get();
        }
 
-       if(s.type==Stage::GEOMETRY)
+       if(s.type==Stage::TESS_CONTROL)
+       {
+               if(!have_output_vertex_count)
+                       error(*global_err_node, "No vertex count qualifier found on output");
+       }
+       else if(s.type==Stage::TESS_EVAL)
+       {
+               if(!have_input_primitive)
+                       error(*global_err_node, "No primitive type qualifier found on input");
+       }
+       else if(s.type==Stage::GEOMETRY)
        {
                if(!have_input_primitive)
                        error(*global_err_node, "No primitive type qualifier found on input");
@@ -152,13 +162,27 @@ void DeclarationValidator::visit(Layout &layout)
                                        have_output_primitive = true;
                        }
                }
-               else if(q.name=="lines" || q.name=="lines_adjacency" || q.name=="triangles" || q.name=="triangles_adjacency")
+               else if(q.name=="triangles")
+               {
+                       allowed = ((stage->type==Stage::GEOMETRY || stage->type==Stage::TESS_EVAL) && iface_layout && iface_layout->interface=="in");
+                       value = false;
+                       if(allowed)
+                               have_input_primitive = true;
+               }
+               else if(q.name=="lines" || q.name=="lines_adjacency" || q.name=="triangles_adjacency")
                {
                        allowed = (stage->type==Stage::GEOMETRY && iface_layout && iface_layout->interface=="in");
                        value = false;
                        if(allowed)
                                have_input_primitive = true;
                }
+               else if(q.name=="quads" || q.name=="isolines")
+               {
+                       allowed = (stage->type==Stage::TESS_EVAL && iface_layout && iface_layout->interface=="in");
+                       value = false;
+                       if(allowed)
+                               have_input_primitive = true;
+               }
                else if(q.name=="line_strip" || q.name=="triangle_strip")
                {
                        allowed = (stage->type==Stage::GEOMETRY && iface_layout && iface_layout->interface=="out");
@@ -174,6 +198,18 @@ void DeclarationValidator::visit(Layout &layout)
                        if(allowed)
                                have_output_vertex_count = true;
                }
+               else if(q.name=="vertices")
+               {
+                       allowed = (stage->type==Stage::TESS_CONTROL && iface_layout && iface_layout->interface=="out");
+                       if(allowed)
+                               have_output_vertex_count = true;
+               }
+               else if(q.name=="cw" || q.name=="ccw" ||
+                       q.name=="equal_spacing" || q.name=="fractional_even_spacing" || q.name=="fractional_odd_spacing")
+               {
+                       allowed = (stage->type==Stage::TESS_EVAL && iface_layout && iface_layout->interface=="in");
+                       value = false;
+               }
                else if(q.name=="std140" || q.name=="std430")
                {
                        allowed = (iface_block && !variable && iface_block->interface=="uniform");
@@ -302,12 +338,16 @@ void DeclarationValidator::visit(VariableDeclaration &var)
 
        if(!var.interpolation.empty() || !var.sampling.empty())
        {
-               if(var.interface!="in" && stage->type==Stage::VERTEX)
+               if(var.interface=="in" && stage->type==Stage::VERTEX)
                        error(var, "Interpolation qualifier not allowed on vertex input");
-               else if(var.interface!="out" && stage->type==Stage::FRAGMENT)
+               else if(var.interface=="out" && stage->type==Stage::FRAGMENT)
                        error(var, "Interpolation qualifier not allowed on fragment output");
                else if((var.interface!="in" && var.interface!="out") || (scope==FUNCTION_PARAM || scope==FUNCTION))
                        error(var, "Interpolation qualifier not allowed on non-interpolated variable");
+               else if(var.sampling=="patch" && (stage->type!=Stage::TESS_CONTROL || var.interface!="out") && (stage->type!=Stage::TESS_EVAL || var.interface!="in"))
+                       error(var, "Per-patch variables only allowed on tessellation control output or tessellation evaluation input");
+               if(var.sampling=="patch" && !var.interpolation.empty())
+                       error(var, "Interpolation qualifier not allowed on per-patch variable");
        }
 
        if(!var.interface.empty())
@@ -819,7 +859,7 @@ void StageInterfaceValidator::visit(VariableDeclaration &var)
                if(var.type_declaration && var.linked_declaration->type_declaration)
                {
                        TypeDeclaration *type = var.type_declaration;
-                       if(stage->type==Stage::GEOMETRY)
+                       if(stage->type==Stage::TESS_CONTROL || stage->type==Stage::GEOMETRY)
                        {
                                if(const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(type))
                                        if(basic->kind==BasicTypeDeclaration::ARRAY && basic->base_type)
@@ -832,6 +872,12 @@ void StageInterfaceValidator::visit(VariableDeclaration &var)
                                        var.linked_declaration->name, var.linked_declaration->type_declaration->name));
                        }
                }
+               if((var.sampling=="patch") != (var.linked_declaration->sampling=="patch"))
+               {
+                       error(var, format("Mismatched sampling qualifier '%s' for 'in %s'", var.sampling, var.name));
+                       add_info(*var.linked_declaration, format("Linked to 'out %s' qualified as '%s'",
+                               var.linked_declaration->name, var.linked_declaration->sampling));
+               }
        }
 
        if(location>=0 && !var.interface.empty())