X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fvalidate.cpp;h=883b950ff07f2e46d9aa0037ddfce2fa2719c425;hp=4c135892056c1e82b3c33ca0536232202a05ac69;hb=HEAD;hpb=abcd1fa06f9fab27c5934b4069523dd009862b18 diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index 4c135892..f6b11ef2 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -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(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())