X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fcompatibility.cpp;h=a5ba8247a53d705c82223d9b8241e5d28dbea14e;hb=02c43c5aebb2214af8144eaf19f25b9a04aa2414;hp=2e13a5f678eaa7592809fa292071b89cecf28beb;hpb=c0be4e4ae1a8b6ac31ff6b7080e2242c13d947ff;p=libs%2Fgl.git diff --git a/source/glsl/compatibility.cpp b/source/glsl/compatibility.cpp index 2e13a5f6..a5ba8247 100644 --- a/source/glsl/compatibility.cpp +++ b/source/glsl/compatibility.cpp @@ -2,6 +2,7 @@ #include #include #include "compatibility.h" +#include "glsl_error.h" using namespace std; @@ -16,7 +17,7 @@ DefaultPrecisionGenerator::DefaultPrecisionGenerator(): void DefaultPrecisionGenerator::apply(Stage &s) { stage = &s; - visit(s.content); + s.content.visit(*this); } void DefaultPrecisionGenerator::visit(Block &block) @@ -64,7 +65,7 @@ void DefaultPrecisionGenerator::visit(VariableDeclaration &var) void PrecisionRemover::apply(Stage &stage) { - visit(stage.content); + stage.content.visit(*this); NodeRemover().apply(stage, nodes_to_remove); } @@ -87,7 +88,20 @@ void LegacyConverter::apply(Stage &s, const Features &feat) { stage = &s; features = feat; - visit(s.content); + if(supports_stage(s.type)) + s.content.visit(*this); + else + unsupported(format("Stage %s is not supported", Stage::get_stage_name(s.type))); +} + +void LegacyConverter::unsupported(const string &reason) +{ + Diagnostic diagnostic; + diagnostic.severity = Diagnostic::ERR; + diagnostic.source = GENERATED_SOURCE; + diagnostic.line = 0; + diagnostic.message = reason; + stage->diagnostics.push_back(diagnostic); } void LegacyConverter::visit(Block &block) @@ -120,6 +134,19 @@ bool LegacyConverter::check_extension(bool Features::*extension) const return true; } +bool LegacyConverter::supports_stage(Stage::Type st) const +{ + if(st==Stage::GEOMETRY) + { + if(features.gl_api==OPENGL_ES2) + return check_version(Version(3, 20)); + else + return check_version(Version(1, 50)); + } + else + return true; +} + bool LegacyConverter::supports_unified_interface_syntax() const { if(features.gl_api==OPENGL_ES2) @@ -134,12 +161,12 @@ void LegacyConverter::visit(VariableReference &var) { var.name = "gl_FragColor"; var.declaration = 0; - type = "vec4"; + r_type = "vec4"; } else if(var.declaration) - type = var.declaration->type; + r_type = var.declaration->type; else - type = string(); + r_type.clear(); } void LegacyConverter::visit(Assignment &assign) @@ -162,12 +189,12 @@ void LegacyConverter::visit(FunctionCall &call) if(call.name=="texture") { string sampler_type; - type = string(); + r_type.clear(); NodeArray::iterator i = call.arguments.begin(); if(i!=call.arguments.end()) { (*i)->visit(*this); - sampler_type = type; + sampler_type = r_type; for(; i!=call.arguments.end(); ++i) (*i)->visit(*this); @@ -248,21 +275,23 @@ void LegacyConverter::visit(VariableDeclaration &var) if(var.layout && !supports_interface_layouts()) { vector::iterator i; - for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->identifier!="location"); ++i) ; + for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->name!="location"); ++i) ; if(i!=var.layout->qualifiers.end()) { - unsigned location = lexical_cast(i->value); if(stage->type==Stage::VERTEX && var.interface=="in") { - stage->locations[var.name] = location; + stage->locations[var.name] = i->value; var.layout->qualifiers.erase(i); } else if(stage->type==Stage::FRAGMENT && var.interface=="out") { - if(location!=0) - check_extension(&Features::ext_gpu_shader4); - stage->locations[var.name] = location; - var.layout->qualifiers.erase(i); + if(check_extension(&Features::ext_gpu_shader4)) + { + stage->locations[var.name] = i->value; + var.layout->qualifiers.erase(i); + } + else if(i->value!=0) + unsupported("EXT_gpu_shader4 required for multiple fragment shader outputs"); } if(var.layout->qualifiers.empty()) @@ -314,8 +343,13 @@ void LegacyConverter::visit(InterfaceBlock &iface) { if(!supports_interface_blocks(iface.interface)) { - stage->content.body.splice(uniform_insert_point, iface.members.body); - nodes_to_remove.insert(&iface); + if(!iface.instance_name.empty()) + unsupported("ARB_uniform_buffer_object required for interface block instances"); + else + { + stage->content.body.splice(uniform_insert_point, iface.members.body); + nodes_to_remove.insert(&iface); + } } }