Feature states are now recorded in a struct.
#include <msp/core/algorithm.h>
#include <msp/core/raii.h>
-#include <msp/gl/extensions/arb_explicit_attrib_location.h>
-#include <msp/gl/extensions/arb_gpu_shader5.h>
-#include <msp/gl/extensions/arb_uniform_buffer_object.h>
-#include <msp/gl/extensions/ext_gpu_shader4.h>
-#include <msp/gl/extensions/ext_texture_array.h>
#include <msp/strings/lexicalcast.h>
#include "compatibility.h"
LegacyConverter::LegacyConverter():
- target_api(get_gl_api()),
- target_version(get_glsl_version()),
frag_out(0)
{ }
-void LegacyConverter::apply(Stage &s)
+void LegacyConverter::apply(Stage &s, const Features &feat)
{
stage = &s;
+ features = feat;
visit(s.content);
}
bool LegacyConverter::check_version(const Version &feature_version) const
{
- if(target_version<feature_version)
+ if(features.glsl_version<feature_version)
return false;
- else if(stage->required_version<feature_version)
- stage->required_version = feature_version;
+ else if(stage->required_features.glsl_version<feature_version)
+ stage->required_features.glsl_version = feature_version;
return true;
}
-bool LegacyConverter::check_extension(const Extension &extension) const
+bool LegacyConverter::check_extension(bool Features::*extension) const
{
- if(!extension)
+ if(!(features.*extension))
return false;
- vector<const Extension *>::iterator i = find(stage->required_extensions, &extension);
- if(i==stage->required_extensions.end())
- stage->required_extensions.push_back(&extension);
+ stage->required_features.*extension = true;
return true;
}
bool LegacyConverter::supports_unified_interface_syntax() const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
return check_version(Version(3, 0));
else
return check_version(Version(1, 30));
bool LegacyConverter::supports_unified_sampling_functions() const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
return check_version(Version(3, 0));
else
return check_version(Version(1, 30));
call.name = "shadow2D";
else if(sampler_type=="sampler1DArray")
{
- check_extension(EXT_texture_array);
+ check_extension(&Features::ext_texture_array);
call.name = "texture1DArray";
}
else if(sampler_type=="sampler2DArray")
{
- check_extension(EXT_texture_array);
+ check_extension(&Features::ext_texture_array);
call.name = "texture2DArray";
}
else if(sampler_type=="sampler1DArrayShadow")
{
- check_extension(EXT_texture_array);
+ check_extension(&Features::ext_texture_array);
call.name = "shadow1DArray";
}
else if(sampler_type=="sampler2DArrayShadow")
{
- check_extension(EXT_texture_array);
+ check_extension(&Features::ext_texture_array);
call.name = "shadow2DArray";
}
}
bool LegacyConverter::supports_interface_layouts() const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
return check_version(Version(3, 0));
else if(check_version(Version(3, 30)))
return true;
else
- return check_extension(ARB_explicit_attrib_location);
+ return check_extension(&Features::arb_explicit_attrib_location);
}
bool LegacyConverter::supports_centroid_sampling() const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
return check_version(Version(3, 0));
else if(check_version(Version(1, 20)))
return true;
else
- return check_extension(EXT_gpu_shader4);
+ return check_extension(&Features::ext_gpu_shader4);
}
bool LegacyConverter::supports_sample_sampling() const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
return check_version(Version(3, 20));
else if(check_version(Version(4, 0)))
return true;
else
- return check_extension(ARB_gpu_shader5);
+ return check_extension(&Features::arb_gpu_shader5);
}
void LegacyConverter::visit(VariableDeclaration &var)
else if(stage->type==Stage::FRAGMENT && var.interface=="out")
{
if(location!=0)
- static Require _req(EXT_gpu_shader4);
+ check_extension(&Features::ext_gpu_shader4);
stage->locations[var.name] = location;
var.layout->qualifiers.erase(i);
}
bool LegacyConverter::supports_interface_blocks(const string &iface) const
{
- if(target_api==OPENGL_ES2)
+ if(features.gl_api==OPENGL_ES2)
{
if(iface=="uniform")
return check_version(Version(3, 0));
else if(check_version(Version(1, 50)))
return true;
else if(iface=="uniform")
- return check_extension(ARB_uniform_buffer_object);
+ return check_extension(&Features::arb_uniform_buffer_object);
else
return false;
}
{
private:
Stage *stage;
- GLApi target_api;
- Version target_version;
+ Features features;
std::string type;
VariableDeclaration *frag_out;
NodeList<Statement>::iterator uniform_insert_point;
public:
LegacyConverter();
- virtual void apply(Stage &);
+ virtual void apply(Stage &, const Features &);
private:
virtual void visit(Block &);
bool check_version(const Version &) const;
- bool check_extension(const Extension &) const;
+ bool check_extension(bool Features::*) const;
bool supports_unified_interface_syntax() const;
virtual void visit(VariableReference &);
virtual void visit(Assignment &);
namespace SL {
Compiler::Compiler():
+ features(Features::from_context()),
+ module(0)
+{ }
+
+Compiler::Compiler(const Features &f):
+ features(f),
module(0)
{ }
target = &*i;
}
- if(stage.required_version>target->required_version)
- target->required_version = stage.required_version;
+ if(stage.required_features.glsl_version>target->required_features.glsl_version)
+ target->required_features.glsl_version = stage.required_features.glsl_version;
for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
target->content.body.push_back(*i);
DeclarationCombiner().apply(*target);
void Compiler::generate(Stage &stage, Mode mode)
{
- if(module->shared.required_version>stage.required_version)
- stage.required_version = module->shared.required_version;
+ stage.required_features.gl_api = features.gl_api;
+ if(module->shared.required_features.glsl_version>stage.required_features.glsl_version)
+ stage.required_features.glsl_version = module->shared.required_features.glsl_version;
inject_block(stage.content, module->shared.content);
DeclarationReorderer().apply(stage);
DeclarationReorderer().apply(stage);
FunctionResolver().apply(stage);
if(mode==PROGRAM)
- LegacyConverter().apply(stage);
+ LegacyConverter().apply(stage, features);
}
bool Compiler::optimize(Stage &stage)
};
private:
+ Features features;
Module *module;
std::vector<std::string> imported_names;
public:
Compiler();
+ Compiler(const Features &);
~Compiler();
private:
--- /dev/null
+#include <msp/gl/extensions/arb_explicit_attrib_location.h>
+#include <msp/gl/extensions/arb_gpu_shader5.h>
+#include <msp/gl/extensions/arb_uniform_buffer_object.h>
+#include <msp/gl/extensions/ext_gpu_shader4.h>
+#include <msp/gl/extensions/ext_texture_array.h>
+#include "features.h"
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+Features::Features():
+ gl_api(OPENGL),
+ arb_explicit_attrib_location(false),
+ arb_gpu_shader5(false),
+ arb_uniform_buffer_object(false),
+ ext_gpu_shader4(false),
+ ext_texture_array(false)
+{ }
+
+Features Features::from_context()
+{
+ Features features;
+ features.gl_api = get_gl_api();
+ features.glsl_version = get_glsl_version();
+ features.arb_explicit_attrib_location = ARB_explicit_attrib_location;
+ features.arb_gpu_shader5 = ARB_gpu_shader5;
+ //features.arb_texture_cube_map_array = ARB_texture_cube_map_array;
+ features.arb_uniform_buffer_object = ARB_uniform_buffer_object;
+ features.ext_gpu_shader4 = EXT_gpu_shader4;
+ features.ext_texture_array = EXT_texture_array;
+ return features;
+}
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
--- /dev/null
+#ifndef MSP_GL_SL_FEATURES_H_
+#define MSP_GL_SL_FEATURES_H_
+
+#include <msp/gl/extension.h>
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+struct Features
+{
+ GLApi gl_api;
+ Version glsl_version;
+ bool arb_explicit_attrib_location;
+ bool arb_gpu_shader5;
+ bool arb_uniform_buffer_object;
+ bool ext_gpu_shader4;
+ bool ext_texture_array;
+
+ Features();
+
+ static Features from_context();
+};
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
+
+#endif
mode = m;
stage = &s;
- GLApi api = get_gl_api();
- const Version &ver = s.required_version;
+ const Version &ver = s.required_features.glsl_version;
if(ver)
{
append(format("#version %d%02d", ver.major, ver.minor));
- if(api==OPENGL_ES2 && ver>=Version(3, 0))
+ if(s.required_features.gl_api==OPENGL_ES2 && ver>=Version(3, 0))
append(" es");
formatted += '\n';
}
- for(vector<const Extension *>::const_iterator i=s.required_extensions.begin(); i!=s.required_extensions.end(); ++i)
- append(format("#extension %s: require\n", (*i)->get_name()));
- if(!s.required_extensions.empty())
- formatted += '\n';
+ if(s.required_features.arb_explicit_attrib_location)
+ append("#extension arb_explicit_attrib_location: require\n");
+ if(s.required_features.arb_gpu_shader5)
+ append("#extension arb_gpu_shader5: require\n");
+ if(s.required_features.arb_uniform_buffer_object)
+ append("#extension arb_uniform_buffer_object: require\n");
+ if(s.required_features.ext_gpu_shader4)
+ append("#extension ext_gpu_shader4: require\n");
+ if(s.required_features.ext_texture_array)
+ append("#extension ext_texture_array: require\n");
+ formatted += '\n';
visit(s.content);
else
{
unsigned l = line;
- if(mode==Compiler::PROGRAM && stage && stage->required_version<Version(3, 30))
+ if(mode==Compiler::PROGRAM && stage && stage->required_features.glsl_version<Version(3, 30))
--l;
formatted += format("#line %d %d\n", l, index);
}
if(!var.interface.empty() && var.interface!=block_interface)
{
string interface = var.interface;
- if(mode==Compiler::PROGRAM && stage && stage->required_version<Version(1, 30))
+ if(mode==Compiler::PROGRAM && stage && stage->required_features.glsl_version<Version(1, 30))
{
if(stage->type==Stage::VERTEX && var.interface=="in")
interface = "attribute";
void Parser::set_required_version(const Version &ver)
{
- cur_stage->required_version = ver;
+ cur_stage->required_features.glsl_version = ver;
}
void Parser::source_reference(unsigned index, const string &name)
#include <string>
#include <vector>
#include <msp/core/refptr.h>
-#include "extension.h"
+#include "features.h"
#include "sourcemap.h"
#pragma push_macro("interface")
std::map<std::string, VariableDeclaration *> in_variables;
std::map<std::string, VariableDeclaration *> out_variables;
std::map<std::string, unsigned> locations;
- Version required_version;
- std::vector<const Extension *> required_extensions;
+ Features required_features;
Stage(Type);