diff --git a/.ccls b/.ccls index d79e21d79..460b00b9d 100644 --- a/.ccls +++ b/.ccls @@ -17,8 +17,7 @@ -I./python/pybind11/include/ -I./external/Vulkan-Headers/include/ -I./external/googletest/googletest/include/ --I./external/shaderc/libshaderc/include/ --I./external/shaderc/libshaderc_util/include/ +-I./external/glslang/ -I./external/spdlog/include/ -I./src/include/ -I./single_include/ diff --git a/.gitmodules b/.gitmodules index 086a6f8fd..108a5773e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,7 +14,7 @@ path = python/pybind11 url = https://github.com/pybind/pybind11 branch = v2.6.1 -[submodule "external/shaderc"] - path = external/shaderc - url = https://github.com/google/shaderc - branch = v2020.4 +[submodule "external/glslang"] + path = external/glslang + url = https://github.com/KhronosGroup/glslang/ + branch = 11.1.0 diff --git a/external/glslang b/external/glslang new file mode 160000 index 000000000..c594de23c --- /dev/null +++ b/external/glslang @@ -0,0 +1 @@ +Subproject commit c594de23cdd790d64ad5f9c8b059baae0ee2941d diff --git a/external/shaderc b/external/shaderc deleted file mode 160000 index 0dbd89994..000000000 --- a/external/shaderc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0dbd899941a43ffd55df527d65128b3b66e75c9c diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c6b89e880..d326f5317 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -45,31 +45,36 @@ add_test(NAME test_kompute COMMAND test_kompute) set(SHADERC_SKIP_TESTS 1) if(KOMPUTE_OPT_REPO_SUBMODULE_BUILD) - # Ensure shaderc is initialised by cloning all dependencies - message(STATUS "Cloning all repositories for shaderc dependency") - execute_process(COMMAND - python3 ${PROJECT_SOURCE_DIR}/external/shaderc/utils/git-sync-deps) - - add_subdirectory(${PROJECT_SOURCE_DIR}/external/shaderc - ${CMAKE_CURRENT_BINARY_DIR}/kompute_shaderc) + add_subdirectory(${PROJECT_SOURCE_DIR}/external/glslang + ${CMAKE_CURRENT_BINARY_DIR}/kompute_glslang) target_include_directories( test_kompute PRIVATE - ${PROJECT_SOURCE_DIR}/external/shaderc/libshaderc/include) + ${PROJECT_SOURCE_DIR}/external/glslang) target_link_libraries(test_kompute PRIVATE - shaderc_combined) + # Not including hlsl support + # HLSL + # glslang includes OGLCompiler, OSDependent, MachineIndependent + glslang + SPIRV + glslang-default-resource-limits + MachineIndependent) else() - find_library(SHADERC_LIB shaderc_combined) - - find_path(SHADERC_INCLUDE_DIRS shaderc) + find_package(glslang CONFIG REQUIRED) target_include_directories( test_kompute PRIVATE - ${SHADERC_INCLUDE_DIRS}) + ${GLSLANG_GENERATED_INCLUDEDIR}) target_link_libraries(test_kompute PRIVATE - ${SHADERC_LIB}) + # Not including hlsl support + # glslang::HLSL + # Adding explicit dependencies to match above + glslang + SPIRV + glslang-default-resource-limits + MachineIndependent) endif() ##################################################### diff --git a/test/TestUtils.cpp b/test/TestUtils.cpp index a6c854a44..a620e2041 100644 --- a/test/TestUtils.cpp +++ b/test/TestUtils.cpp @@ -4,28 +4,72 @@ #include +#include +#include +#include + static std::vector spirv_from_string(const std::string& source, + const std::string& entryPoint = "main", shaderc_optimization_level optimization = shaderc_optimization_level_zero, std::vector> definitions = {}) { - shaderc::Compiler compiler; - shaderc::CompileOptions options; - for (const std::pair& def : definitions) { - options.AddMacroDefinition(def.first, def.second); - } - if (optimization) options.SetOptimizationLevel(optimization); + // Initialize glslang library. + glslang::InitializeProcess(); - std::string errorTag = "kompute"; - shaderc::SpvCompilationResult module = - compiler.CompileGlslToSpv(source, shaderc_glsl_compute_shader, errorTag.c_str(), options); + const EShLanguage language = EShLangCompute; + glslang::TShader shader(language); - if (module.GetCompilationStatus() != shaderc_compilation_status_success) { - throw std::runtime_error("Shader string invalid: " + module.GetErrorMessage()); + const char *file_name_list[1] = {""}; + const char *shader_source = reinterpret_cast(source.data()); + shader.setStringsWithLengthsAndNames(&shader_source, nullptr, file_name_list, 1); + shader.setEntryPoint(entryPoint.c_str()); + shader.setSourceEntryPoint(entryPoint.c_str()); + + std::string info_log = ""; + const EShMessages messages = static_cast(EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules); + if (!shader.parse(&glslang::DefaultTBuiltInResource, 100, false, messages)) + { + info_log = std::string(shader.getInfoLog()) + "\n" + std::string(shader.getInfoDebugLog()); + throw std::runtime_error(info_log); } - std::vector vi = {module.cbegin(), module.cend()}; - auto p = reinterpret_cast(vi.data()); - std::vector vc{p, p + vi.size() * sizeof(int)}; - return vc; + // Add shader to new program object. + glslang::TProgram program; + program.addShader(&shader); + // Link program. + if (!program.link(messages)) + { + info_log = std::string(program.getInfoLog()) + "\n" + std::string(program.getInfoDebugLog()); + throw std::runtime_error(info_log); + } + + // Save any info log that was generated. + if (shader.getInfoLog()) + { + info_log += std::string(shader.getInfoLog()) + "\n" + std::string(shader.getInfoDebugLog()) + "\n"; + } + + if (program.getInfoLog()) + { + info_log += std::string(program.getInfoLog()) + "\n" + std::string(program.getInfoDebugLog()); + } + + glslang::TIntermediate *intermediate = program.getIntermediate(language); + // Translate to SPIRV. + if (!intermediate) + { + info_log += "Failed to get shared intermediate code.\n"; + throw std::runtime_error(info_log); + } + + spv::SpvBuildLogger logger; + std::vector spirv; + glslang::GlslangToSpv(*intermediate, spirv, &logger); + info_log += logger.getAllMessages() + "\n"; + + // Shutdown glslang library. + glslang::FinalizeProcess(); + + return std::vector((char*)spirv.data(), (char*)(spirv.data()+spirv.size()) ); }