X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=tests%2Fglsl%2Fglslcompiler.cpp;h=7deeb1f35190b403f8594e159562498e522e5b9e;hb=08d3b5a55fad7439b47fc93d8ba604cbeb7e19ca;hp=01c1fba28e2e4fe90d0f2268a485538fd671f258;hpb=7563b92050d7c249c9ce848c1310dbfb993eadb7;p=libs%2Fgl.git diff --git a/tests/glsl/glslcompiler.cpp b/tests/glsl/glslcompiler.cpp index 01c1fba2..7deeb1f3 100644 --- a/tests/glsl/glslcompiler.cpp +++ b/tests/glsl/glslcompiler.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -14,6 +15,7 @@ protected: { std::string name; std::string source; + Msp::GL::GraphicsApi target_api; Msp::GL::SL::Compiler::Mode compile_mode; std::map spec_values; std::map expected_output; @@ -58,13 +60,29 @@ private: virtual void fail(const std::string &m) { Test::fail(m); } }; +class GlslCompilerSpirV: public Msp::Test::RegisteredTest, private GlslCompilerHelper +{ +private: + spvtools::SpirvTools spirv_tools; + +public: + GlslCompilerSpirV(); + + static const char *get_name() { return "GLSL to SPIR-V compilation"; } + +private: + void run_test_case(const TestCase *); + void diagnostic(spv_message_level_t, const char *, const spv_position_t &, const char *); + virtual void fail(const std::string &m) { Test::fail(m); } +}; + using namespace std; using namespace Msp; void GlslCompilerHelper::load_all_test_cases(const FS::Path &tests_dir) { - list test_files = FS::list_filtered(tests_dir, "\\.glsl$"); - test_files.sort(); + vector test_files = FS::list_filtered(tests_dir, "\\.glsl$"); + sort(test_files); for(const auto &fn: test_files) load_test_case((tests_dir/fn).str()); } @@ -74,6 +92,7 @@ const GlslCompilerHelper::TestCase &GlslCompilerHelper::load_test_case(const str IO::BufferedFile file(fn); TestCase test_case; test_case.name = FS::basename(fn); + test_case.target_api = GL::OPENGL; test_case.compile_mode = GL::SL::Compiler::PROGRAM; string *target = &test_case.source; while(!file.eof()) @@ -110,6 +129,21 @@ const GlslCompilerHelper::TestCase &GlslCompilerHelper::load_test_case(const str continue; } + pos = line.find("Target API:"); + if(pos!=string::npos) + { + string api = strip(line.substr(pos+11)); + if(api=="OpenGL") + test_case.target_api = GL::OPENGL; + else if(api=="OpenGL ES") + test_case.target_api = GL::OPENGL_ES; + else if(api=="Vulkan") + test_case.target_api = GL::VULKAN; + else + throw runtime_error("Unknown API "+api); + continue; + } + pos = line.find("Compile mode:"); if(pos!=string::npos) { @@ -234,7 +268,7 @@ GlslCompilerTest::GlslCompilerTest() void GlslCompilerTest::run_test_case(const TestCase *test_case) { - GL::SL::Compiler compiler(GL::SL::Features::latest()); + GL::SL::Compiler compiler(GL::SL::Features::latest(test_case->target_api)); try { compiler.set_source(test_case->source, ""); @@ -291,13 +325,13 @@ GlslCompilerIdempotence::GlslCompilerIdempotence() void GlslCompilerIdempotence::run_test_case(const TestCase *test_case) { - GL::SL::Compiler compiler(GL::SL::Features::latest()); + GL::SL::Compiler compiler(GL::SL::Features::latest(test_case->target_api)); compiler.set_source(test_case->source, ""); if(test_case->compile_mode==GL::SL::Compiler::PROGRAM) compiler.specialize(test_case->spec_values); compiler.compile(test_case->compile_mode); - GL::SL::Compiler compiler2(GL::SL::Features::latest()); + GL::SL::Compiler compiler2(GL::SL::Features::latest(test_case->target_api)); compiler2.set_source(compiler.get_combined_glsl(), ""); compiler2.compile(test_case->compile_mode); @@ -318,3 +352,41 @@ void GlslCompilerIdempotence::run_test_case(const TestCase *test_case) if(j!=stages2.end()) fail(format("Second pass produced extra stage %s", GL::SL::Stage::get_stage_name(*j))); } + + +GlslCompilerSpirV::GlslCompilerSpirV(): + spirv_tools(SPV_ENV_UNIVERSAL_1_5) +{ + load_all_test_cases("glsl"); + for(const auto &tc: test_cases) + if(tc.expect_success) + add(&GlslCompilerSpirV::run_test_case, &tc, tc.name); + + using namespace std::placeholders; + spirv_tools.SetMessageConsumer(std::bind(std::mem_fn(&GlslCompilerSpirV::diagnostic), this, _1, _2, _3, _4)); +} + +void GlslCompilerSpirV::run_test_case(const TestCase *test_case) +{ + GL::SL::Compiler compiler(GL::SL::Features::latest(test_case->target_api)); + compiler.set_source(test_case->source, ""); + compiler.compile(GL::SL::Compiler::SPIRV); + + vector code = compiler.get_combined_spirv(); + if(!spirv_tools.Validate(code)) + fail("Invalid SPIR-V generated"); +} + +void GlslCompilerSpirV::diagnostic(spv_message_level_t level, const char *, const spv_position_t &, const char *message) +{ + const char *prefix; + switch(level) + { + case SPV_MSG_DEBUG: prefix = "debug: "; break; + case SPV_MSG_INFO: prefix = "info: "; break; + case SPV_MSG_WARNING: prefix = "warning: "; break; + case SPV_MSG_ERROR: prefix = "error: "; break; + default: prefix = ""; + } + info(format("%s%s", prefix, message)); +}