From: Mikko Rasa Date: Fri, 26 Feb 2021 23:21:11 +0000 (+0200) Subject: Add interfaces for using specialization constants with Programs X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=0912a8d73043961ab7a4d66cd2fbb13187483ffd Add interfaces for using specialization constants with Programs This replaces the old way of redefining variables withing the GLSL source, and as such the Program constructor from string is now deprecated. --- diff --git a/source/core/program.cpp b/source/core/program.cpp index 2a34feb3..9ef5d6d7 100644 --- a/source/core/program.cpp +++ b/source/core/program.cpp @@ -55,6 +55,13 @@ Program::Program(const string &vert, const string &frag) link(); } +Program::Program(const Module &mod, const map &spec_values) +{ + init(); + add_stages(mod, spec_values); + link(); +} + void Program::init() { static Require _req(ARB_shader_objects); @@ -71,12 +78,13 @@ Program::~Program() glDeleteProgram(id); } -void Program::add_stages(const Module &mod) +void Program::add_stages(const Module &mod, const map &spec_values) { module = &mod; SL::Compiler compiler; compiler.set_source(module->get_prepared_source(), ""); + compiler.specialize(spec_values); compiler.compile(SL::Compiler::PROGRAM); vector stages = compiler.get_stages(); @@ -479,7 +487,10 @@ void Program::Loader::finish() void Program::Loader::module(const string &n) { - obj.add_stages(get_collection().get(n)); + map spec_values; + SpecializationLoader ldr(spec_values); + load_sub_with(ldr); + obj.add_stages(get_collection().get(n), spec_values); } #pragma GCC diagnostic push @@ -505,5 +516,30 @@ void Program::Loader::vertex_shader(const string &src) } #pragma GCC diagnostic pop + +DataFile::Loader::ActionMap Program::SpecializationLoader::shared_actions; + +Program::SpecializationLoader::SpecializationLoader(map &sv): + spec_values(sv) +{ + set_actions(shared_actions); +} + +void Program::SpecializationLoader::init_actions() +{ + add("specialize", &SpecializationLoader::specialize_bool); + add("specialize", &SpecializationLoader::specialize_int); +} + +void Program::SpecializationLoader::specialize_bool(const string &name, bool value) +{ + spec_values[name] = value; +} + +void Program::SpecializationLoader::specialize_int(const string &name, int value) +{ + spec_values[name] = value; +} + } // namespace GL } // namespace Msp diff --git a/source/core/program.h b/source/core/program.h index e86ee059..05223627 100644 --- a/source/core/program.h +++ b/source/core/program.h @@ -36,6 +36,25 @@ public: void vertex_shader(const std::string &); }; +private: + class SpecializationLoader: public DataFile::Loader + { + private: + std::map &spec_values; + + static ActionMap shared_actions; + + public: + SpecializationLoader(std::map &); + + private: + virtual void init_actions(); + + void specialize_bool(const std::string &, bool); + void specialize_int(const std::string &, int); + }; + +public: typedef unsigned LayoutHash; struct UniformBlockInfo; @@ -82,21 +101,24 @@ private: AttributeMap attributes; public: - /// Constructs an empty Program with no Shaders attached. + /// Constructs an empty Program with no shader stages attached. Program(); /// Constructs a Program from unified source code using ProgramCompiler. - Program(const std::string &); + DEPRECATED Program(const std::string &); /// Constructs a Program from vertex and fragment shader source code. DEPRECATED Program(const std::string &, const std::string &); + /// Constructs a Program from a Module, with specialization constants. + Program(const Module &, const std::map & = std::map()); + private: void init(); public: virtual ~Program(); - void add_stages(const Module &); + void add_stages(const Module &, const std::map & = std::map()); DEPRECATED void attach_shader(Shader &shader); DEPRECATED void attach_shader_owned(Shader *shader);