]> 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 4c135892056c1e82b3c33ca0536232202a05ac69..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");
@@ -60,6 +70,11 @@ void DeclarationValidator::apply(Stage &s, const Features &f)
                if(!have_output_vertex_count)
                        error(*global_err_node, "No vertex count qualifier found on output");
        }
+       else if(s.type==Stage::COMPUTE)
+       {
+               if(!have_workgroup_size)
+                       error(*global_err_node, "No workgroup size qualifier found");
+       }
 }
 
 const char *DeclarationValidator::describe_variable(ScopeType scope)
@@ -147,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");
@@ -169,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");
@@ -193,7 +234,11 @@ void DeclarationValidator::visit(Layout &layout)
                        value = false;
                }
                else if(q.name=="local_size_x" || q.name=="local_size_y" || q.name=="local_size_z")
+               {
                        allowed = (stage->type==Stage::COMPUTE && iface_layout && iface_layout->interface=="in");
+                       if(allowed)
+                               have_workgroup_size = true;
+               }
                else if(q.name=="rgba32f" || q.name=="rgba16f" || q.name=="rg32f" || q.name=="rg16f" || q.name=="r32f" || q.name=="r16f" ||
                        q.name=="rgba16" || q.name=="rgba8" || q.name=="rg16" || q.name=="rg8" || q.name=="r16" || q.name=="r8" ||
                        q.name=="rgba16_snorm" || q.name=="rgba8_snorm" || q.name=="rg16_snorm" || q.name=="rg8_snorm" || q.name=="r16_snorm" || q.name=="r8_snorm")
@@ -293,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())
@@ -810,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)
@@ -823,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())