X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=55f7b82e5ed107aae78042d4bacc2204accc5945;hb=7a41f6dcc1339a4a2dda2207b6b051f20c09a239;hp=fb76ab6d57dc49c22997ad7a64b07e030ed45b34;hpb=c8de66203565f07f10898a74dbd55072432790fc;p=libs%2Fgl.git diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index fb76ab6d..55f7b82e 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -10,17 +10,18 @@ namespace Msp { namespace GL { namespace SL { -DefaultPrecisionGenerator::DefaultPrecisionGenerator(): +PrecisionConverter::PrecisionConverter(): stage(0) { } -void DefaultPrecisionGenerator::apply(Stage &s) +void PrecisionConverter::apply(Stage &s) { stage = &s; s.content.visit(*this); + NodeRemover().apply(s, nodes_to_remove); } -void DefaultPrecisionGenerator::visit(Block &block) +void PrecisionConverter::visit(Block &block) { for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) { @@ -30,56 +31,55 @@ void DefaultPrecisionGenerator::visit(Block &block) } } -void DefaultPrecisionGenerator::visit(Precision &prec) +void PrecisionConverter::visit(Precision &prec) { - have_default.insert(prec.type); + if(stage->required_features.gl_api==OPENGL_ES2) + have_default.insert(prec.type); + else + nodes_to_remove.insert(&prec); } -void DefaultPrecisionGenerator::visit(VariableDeclaration &var) +void PrecisionConverter::visit(VariableDeclaration &var) { - if(var.type_declaration) + if(stage->required_features.gl_api!=OPENGL_ES2) + { + var.precision.clear(); return; + } - string type = var.type; - if(!type.compare(0, 3, "vec") || !type.compare(0, 3, "mat")) - type = "float"; - else if(!type.compare(0, 3, "ivec") || type=="uint") - type = "int"; + const char *default_prec = (stage->type==Stage::FRAGMENT ? "mediump" : "highp"); + const TypeDeclaration *type = var.type_declaration; + while(type) + { + if(dynamic_cast(type)) + { + default_prec = "lowp"; + break; + } + else if(const BasicTypeDeclaration *basic = dynamic_cast(type)) + { + if(basic->kind==BasicTypeDeclaration::INT || basic->kind==BasicTypeDeclaration::FLOAT) + break; + type = basic->base_type; + } + else + return; + } + if(!type) + return; - if(!have_default.count(type)) + if(!have_default.count(type->name)) { Precision *prec = new Precision; - if(!type.compare(0, 7, "sampler")) - prec->precision = "lowp"; - else if(stage->type==Stage::FRAGMENT) - prec->precision = "mediump"; - else - prec->precision = "highp"; - prec->type = type; + prec->precision = default_prec; + prec->type = type->name; stage->content.body.insert(insert_point, prec); - have_default.insert(type); + have_default.insert(type->name); } } -void PrecisionRemover::apply(Stage &stage) -{ - stage.content.visit(*this); - NodeRemover().apply(stage, nodes_to_remove); -} - -void PrecisionRemover::visit(Precision &prec) -{ - nodes_to_remove.insert(&prec); -} - -void PrecisionRemover::visit(VariableDeclaration &var) -{ - var.precision.clear(); -} - - LegacyConverter::LegacyConverter(): frag_out(0) { } @@ -89,7 +89,12 @@ void LegacyConverter::apply(Stage &s, const Features &feat) stage = &s; features = feat; if(supports_stage(s.type)) + { s.content.visit(*this); + + if(!stage->required_features.glsl_version) + stage->required_features.glsl_version = Version(1, (stage->required_features.gl_api==OPENGL_ES2 ? 0 : 10)); + } else unsupported(format("Stage %s is not supported", Stage::get_stage_name(s.type))); } @@ -161,12 +166,7 @@ void LegacyConverter::visit(VariableReference &var) { var.name = "gl_FragColor"; var.declaration = 0; - r_type = "vec4"; } - else if(var.declaration) - r_type = var.declaration->type; - else - r_type.clear(); } void LegacyConverter::visit(Assignment &assign) @@ -186,58 +186,39 @@ bool LegacyConverter::supports_unified_sampling_functions() const void LegacyConverter::visit(FunctionCall &call) { - if(call.name=="texture") + if(call.declaration && call.declaration->source==BUILTIN_SOURCE) { - string sampler_type; - r_type.clear(); - NodeArray::iterator i = call.arguments.begin(); - if(i!=call.arguments.end()) + if(!call.name.compare(0, 7, "texture") && call.arguments.size()>=1) { - (*i)->visit(*this); - sampler_type = r_type; - - for(; i!=call.arguments.end(); ++i) - (*i)->visit(*this); - } - - if(!supports_unified_sampling_functions()) - { - if(sampler_type=="sampler1D") - call.name = "texture1D"; - else if(sampler_type=="sampler2D") - call.name = "texture2D"; - else if(sampler_type=="sampler3D") - call.name = "texture3D"; - else if(sampler_type=="samplerCube") - call.name = "textureCube"; - else if(sampler_type=="sampler1DShadow") - call.name = "shadow1D"; - else if(sampler_type=="sampler2DShadow") - call.name = "shadow2D"; - else if(sampler_type=="sampler1DArray") - { - check_extension(&Features::ext_texture_array); - call.name = "texture1DArray"; - } - else if(sampler_type=="sampler2DArray") + const ImageTypeDeclaration *arg_image = dynamic_cast(call.arguments.front()->type); + if(arg_image && !supports_unified_sampling_functions()) { - check_extension(&Features::ext_texture_array); - call.name = "texture2DArray"; - } - else if(sampler_type=="sampler1DArrayShadow") - { - check_extension(&Features::ext_texture_array); - call.name = "shadow1DArray"; - } - else if(sampler_type=="sampler2DArrayShadow") - { - check_extension(&Features::ext_texture_array); - call.name = "shadow2DArray"; + string suffix = call.name.substr(7); + call.name = (arg_image->shadow ? "shadow" : "texture"); + + switch(arg_image->dimensions) + { + case ImageTypeDeclaration::ONE: call.name += "1D"; break; + case ImageTypeDeclaration::TWO: call.name += "2D"; break; + case ImageTypeDeclaration::THREE: call.name += "3D"; break; + case ImageTypeDeclaration::CUBE: call.name += "Cube"; break; + } + + if(arg_image->array) + { + /* Array textures and the unified sampling function name were + both introduced in GLSL 1.30. */ + if(arg_image->dimensions==ImageTypeDeclaration::ONE || arg_image->dimensions==ImageTypeDeclaration::TWO) + check_extension(&Features::ext_texture_array); + call.name += "Array"; + } + + call.name += suffix; } } } - else - TraversingVisitor::visit(call); + + TraversingVisitor::visit(call); } bool LegacyConverter::supports_interface_layouts() const @@ -272,29 +253,30 @@ bool LegacyConverter::supports_sample_sampling() const void LegacyConverter::visit(VariableDeclaration &var) { - if(var.layout && !supports_interface_layouts()) + if(var.layout) { - vector::iterator i; - for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->name!="location"); ++i) ; - if(i!=var.layout->qualifiers.end()) + for(vector::const_iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) { - if(stage->type==Stage::VERTEX && var.interface=="in") - { - stage->locations[var.name] = i->value; - var.layout->qualifiers.erase(i); - } - else if(stage->type==Stage::FRAGMENT && var.interface=="out") + if(i->name=="location" && !supports_interface_layouts()) { - if(check_extension(&Features::ext_gpu_shader4)) + if(stage->type==Stage::VERTEX && var.interface=="in") stage->locations[var.name] = i->value; - else if(i->value!=0) - unsupported("EXT_gpu_shader4 required for multiple fragment shader outputs"); - var.layout->qualifiers.erase(i); + else if(stage->type==Stage::FRAGMENT && var.interface=="out") + { + if(check_extension(&Features::ext_gpu_shader4)) + stage->locations[var.name] = i->value; + else if(i->value!=0) + unsupported("EXT_gpu_shader4 required for multiple fragment shader outputs"); + } + + i = var.layout->qualifiers.erase(i); } - - if(var.layout->qualifiers.empty()) - var.layout = 0; + else + ++i; } + + if(var.layout->qualifiers.empty()) + var.layout = 0; } if(var.sampling=="centroid")