+#include <msp/core/algorithm.h>
+#include <msp/gl/resources.h>
+#include <msp/io/seekable.h>
#include "builtin.h"
-#include "generate.h"
#include "parser.h"
using namespace std;
-namespace {
-
-const char builtins_src[] =
- "#pragma MSP stage(vertex)\n"
- "out gl_PerVertex {\n"
- " vec4 gl_Position;\n"
- " float gl_ClipDistance[];\n"
- "};\n"
- "#pragma MSP stage(geometry)\n"
- "in gl_PerVertex {\n"
- " vec4 gl_Position;\n"
- " float gl_ClipDistance[];\n"
- "} gl_in[];\n"
- "out gl_PerVertex {\n"
- " vec4 gl_Position;\n"
- " float gl_ClipDistance[];\n"
- "};\n";
-
-}
-
namespace Msp {
namespace GL {
namespace SL {
-Module *create_builtins_module()
+void add_builtin_type(Stage &stage, const string &name, BasicTypeDeclaration::Kind kind, unsigned size, unsigned sign)
{
- Parser parser;
- Module *module = new Module(parser.parse(builtins_src, "<builtin>"));
- for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
- {
- VariableResolver().visit(i->content);
- for(map<string, VariableDeclaration *>::iterator j=i->content.variables.begin(); j!=i->content.variables.end(); ++j)
- j->second->linked_declaration = j->second;
- }
- return module;
+ RefPtr<BasicTypeDeclaration> type = new BasicTypeDeclaration;
+ type->source = BUILTIN_SOURCE;
+ type->name = name;
+ type->kind = kind;
+ type->size = size;
+ type->sign = sign;
+ stage.content.body.push_back(type);
+ stage.types[name] = type.get();
}
-Module &get_builtins_module()
+Module *get_builtins_module()
{
- static RefPtr<Module> builtins_module = create_builtins_module();
- return *builtins_module;
+ static RefPtr<Module> builtins_module;
+ static bool initialized = false;
+ if(!initialized)
+ {
+ initialized = true;
+
+ RefPtr<IO::Seekable> io = Resources::get_builtins().open("_builtin.glsl");
+ if(!io)
+ return 0;
+
+ builtins_module = new Module;
+ add_builtin_type(builtins_module->shared, "void", BasicTypeDeclaration::VOID, 0, true);
+ add_builtin_type(builtins_module->shared, "bool", BasicTypeDeclaration::BOOL, 1, true);
+ add_builtin_type(builtins_module->shared, "int", BasicTypeDeclaration::INT, 32, true);
+ add_builtin_type(builtins_module->shared, "uint", BasicTypeDeclaration::INT, 32, false);
+ add_builtin_type(builtins_module->shared, "float", BasicTypeDeclaration::FLOAT, 32, true);
+
+ try
+ {
+ Parser parser(0);
+ parser.parse(*builtins_module, *io, "<builtin>", BUILTIN_SOURCE);
+ }
+ catch(...)
+ {
+ builtins_module = 0;
+ throw;
+ }
+ }
+ return builtins_module.get();
}
-Stage *get_builtins(Stage::Type type)
+const Stage *get_builtins(Stage::Type type)
{
- Module &module = get_builtins_module();
- for(list<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)
- if(i->type==type)
- return &*i;
- return 0;
+ Module *module = get_builtins_module();
+ if(!module)
+ return 0;
+
+ if(type==Stage::SHARED)
+ return &module->shared;
+ auto i = find_member(module->stages, type, &Stage::type);
+ return (i!=module->stages.end() ? &*i : 0);
}
} // namespace SL