diff --git a/CMakeModules/FindShaderc.cmake b/CMakeModules/FindShaderc.cmake index 17d229646..78979c540 100644 --- a/CMakeModules/FindShaderc.cmake +++ b/CMakeModules/FindShaderc.cmake @@ -6,7 +6,6 @@ FIND_PATH( SHADERC_INCLUDE_DIR shaderc/shaderc.h - HINTS /usr/include /usr/local/include ${SHADERC_PATH_INCLUDES} ) diff --git a/scripts/build-dependencies-linux.sh b/scripts/build-dependencies-linux.sh index d58e3934b..33b91df7b 100755 --- a/scripts/build-dependencies-linux.sh +++ b/scripts/build-dependencies-linux.sh @@ -19,10 +19,10 @@ SDL=SDL2-2.30.3 QT=6.7.0 ZSTD=1.5.5 -SHADERC=2024.0 -SHADERC_GLSLANG=d73712b8f6c9047b09e99614e20d456d5ada2390 -SHADERC_SPIRVHEADERS=8b246ff75c6615ba4532fe4fde20f1be090c3764 -SHADERC_SPIRVTOOLS=04896c462d9f3f504c99a4698605b6524af813c1 +SHADERC=2024.1 +SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec +SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4 +SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 SPIRV_CROSS=vulkan-sdk-1.3.280.0 mkdir -p deps-build @@ -41,10 +41,10 @@ fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE. c8da6b239e82fe1e23465cbf0936c0da5a334438d3fb433e19c503cbb1abee7b qttools-everywhere-src-$QT.tar.xz 26fc8047062ca4bacd1bd953be86fd39c6e0a5f5e9920c72ba9d40876cea4b56 qttranslations-everywhere-src-$QT.tar.xz d73470e4217da388d8cd2a517ee8bb373853f33c569306e80f04397845157aea qtwayland-everywhere-src-$QT.tar.xz -c761044e4e204be8e0b9a2d7494f08671ca35b92c4c791c7049594ca7514197f shaderc-$SHADERC.tar.gz -d27f7359156a92749f8fd4681d1d518c736864213c431cf8144ecc2fb6689a2d shaderc-glslang-$SHADERC_GLSLANG.tar.gz -cfeed5f9a97d12a9761a26e7f5bd10fedb1a8ce92033075151ae3bc7206fc229 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz -c0d01e758a543b3a358cb97af02c6817ebd3f5ff13a2edf9fb220646a3d67999 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz +eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz +aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz +5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz +03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz eb11e1b3715b2211442b7e5933a1135885b664cc10530a1a022355fe9e1bb4ac SPIRV-Cross-$SPIRV_CROSS.tar.gz EOF diff --git a/scripts/build-dependencies-mac.sh b/scripts/build-dependencies-mac.sh index 83994c346..b83f5d2bf 100755 --- a/scripts/build-dependencies-mac.sh +++ b/scripts/build-dependencies-mac.sh @@ -45,10 +45,10 @@ LIBWEBP=1.3.2 MOLTENVK=1.2.8 QT=6.7.0 -SHADERC=2024.0 -SHADERC_GLSLANG=d73712b8f6c9047b09e99614e20d456d5ada2390 -SHADERC_SPIRVHEADERS=8b246ff75c6615ba4532fe4fde20f1be090c3764 -SHADERC_SPIRVTOOLS=04896c462d9f3f504c99a4698605b6524af813c1 +SHADERC=2024.1 +SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec +SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4 +SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 SPIRV_CROSS=vulkan-sdk-1.3.280.0 mkdir -p deps-build @@ -83,10 +83,10 @@ cat > SHASUMS <compiler.SetGenerateDebugInfo(); +@@ -418,8 +418,12 @@ void shaderc_compile_options_set_source_language( } -+void shaderc_compile_options_set_emit_non_semantic_debug_info( -+ shaderc_compile_options_t options) { -+ options->compiler.SetEmitNonSemanticDebugInfo(); + void shaderc_compile_options_set_generate_debug_info( +- shaderc_compile_options_t options) { +- options->compiler.SetGenerateDebugInfo(); ++ shaderc_compile_options_t options, bool enabled, bool enable_non_semantic) { ++ if (enabled) { ++ options->compiler.SetGenerateDebugInfo(); ++ if (enable_non_semantic) ++ options->compiler.SetEmitNonSemanticDebugInfo(); ++ } + } + + void shaderc_compile_options_set_optimization_level( +@@ -591,8 +595,31 @@ void shaderc_compiler_release(shaderc_compiler_t compiler) { + delete compiler; + } + ++const char* shaderc_compilation_status_to_string(shaderc_compilation_status status) ++{ ++ static constexpr const std::pair status_names[] = { ++ {shaderc_compilation_status_success, "shaderc_compilation_status_success"}, ++ {shaderc_compilation_status_invalid_stage, "shaderc_compilation_status_invalid_stage"}, ++ {shaderc_compilation_status_compilation_error, "shaderc_compilation_status_compilation_error"}, ++ {shaderc_compilation_status_internal_error, "shaderc_compilation_status_internal_error"}, ++ {shaderc_compilation_status_null_result_object, "shaderc_compilation_status_null_result_object"}, ++ {shaderc_compilation_status_invalid_assembly, "shaderc_compilation_status_invalid_assembly"}, ++ {shaderc_compilation_status_validation_error, "shaderc_compilation_status_validation_error"}, ++ {shaderc_compilation_status_transformation_error, "shaderc_compilation_status_transformation_error"}, ++ {shaderc_compilation_status_configuration_error, "shaderc_compilation_status_configuration_error"}, ++ }; ++ ++ for (const auto& it : status_names) ++ { ++ if (status == it.first) ++ return it.second; ++ } ++ ++ return "shaderc_compilation_status_unknown"; +} + - void shaderc_compile_options_set_optimization_level( - shaderc_compile_options_t options, shaderc_optimization_level level) { - auto opt_level = shaderc_util::Compiler::OptimizationLevel::Zero; + namespace { +-shaderc_compilation_result_t CompileToSpecifiedOutputType( ++shaderc_compilation_result_vector* CompileToSpecifiedOutputType( + const shaderc_compiler_t compiler, const char* source_text, + size_t source_text_size, shaderc_shader_kind shader_kind, + const char* input_file_name, const char* entry_point_name, +@@ -669,48 +696,59 @@ shaderc_compilation_result_t CompileToSpecifiedOutputType( + } + } // anonymous namespace + +-shaderc_compilation_result_t shaderc_compile_into_spv( ++shaderc_compilation_status shaderc_compile_into_spv( + const shaderc_compiler_t compiler, const char* source_text, + size_t source_text_size, shaderc_shader_kind shader_kind, + const char* input_file_name, const char* entry_point_name, +- const shaderc_compile_options_t additional_options) { +- return CompileToSpecifiedOutputType( ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result) { ++ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType( + compiler, source_text, source_text_size, shader_kind, input_file_name, + entry_point_name, additional_options, + shaderc_util::Compiler::OutputType::SpirvBinary); ++ *result = resultv; ++ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error; + } + +-shaderc_compilation_result_t shaderc_compile_into_spv_assembly( ++shaderc_compilation_status shaderc_compile_into_spv_assembly( + const shaderc_compiler_t compiler, const char* source_text, + size_t source_text_size, shaderc_shader_kind shader_kind, + const char* input_file_name, const char* entry_point_name, +- const shaderc_compile_options_t additional_options) { +- return CompileToSpecifiedOutputType( ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result) { ++ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType( + compiler, source_text, source_text_size, shader_kind, input_file_name, + entry_point_name, additional_options, + shaderc_util::Compiler::OutputType::SpirvAssemblyText); ++ *result = resultv; ++ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error; + } + +-shaderc_compilation_result_t shaderc_compile_into_preprocessed_text( ++shaderc_compilation_status shaderc_compile_into_preprocessed_text( + const shaderc_compiler_t compiler, const char* source_text, + size_t source_text_size, shaderc_shader_kind shader_kind, + const char* input_file_name, const char* entry_point_name, +- const shaderc_compile_options_t additional_options) { +- return CompileToSpecifiedOutputType( ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result) { ++ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType( + compiler, source_text, source_text_size, shader_kind, input_file_name, + entry_point_name, additional_options, + shaderc_util::Compiler::OutputType::PreprocessedText); ++ *result = resultv; ++ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error; + } + +-shaderc_compilation_result_t shaderc_assemble_into_spv( ++shaderc_compilation_status shaderc_assemble_into_spv( + const shaderc_compiler_t compiler, const char* source_assembly, + size_t source_assembly_size, +- const shaderc_compile_options_t additional_options) { +- auto* result = new (std::nothrow) shaderc_compilation_result_spv_binary; +- if (!result) return nullptr; +- result->compilation_status = shaderc_compilation_status_invalid_assembly; +- if (!compiler->initializer) return result; +- if (source_assembly == nullptr) return result; ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result) { ++ auto* bresult = new (std::nothrow) shaderc_compilation_result_spv_binary; ++ if (!bresult) return shaderc_compilation_status_internal_error; ++ bresult->compilation_status = shaderc_compilation_status_invalid_assembly; ++ *result = bresult; ++ if (!compiler->initializer) return bresult->compilation_status; ++ if (source_assembly == nullptr) return bresult->compilation_status; + + TRY_IF_EXCEPTIONS_ENABLED { + spv_binary assembling_output_data = nullptr; +@@ -724,22 +762,22 @@ shaderc_compilation_result_t shaderc_assemble_into_spv( + GetCompilerTargetEnvVersion(target_env_version), + {source_assembly, source_assembly + source_assembly_size}, + &assembling_output_data, &errors); +- result->num_errors = !assembling_succeeded; ++ bresult->num_errors = !assembling_succeeded; + if (assembling_succeeded) { +- result->SetOutputData(assembling_output_data); +- result->output_data_size = ++ bresult->SetOutputData(assembling_output_data); ++ bresult->output_data_size = + assembling_output_data->wordCount * sizeof(uint32_t); +- result->compilation_status = shaderc_compilation_status_success; ++ bresult->compilation_status = shaderc_compilation_status_success; + } else { +- result->messages = std::move(errors); +- result->compilation_status = shaderc_compilation_status_invalid_assembly; ++ bresult->messages = std::move(errors); ++ bresult->compilation_status = shaderc_compilation_status_invalid_assembly; + } + } + CATCH_IF_EXCEPTIONS_ENABLED(...) { +- result->compilation_status = shaderc_compilation_status_internal_error; ++ bresult->compilation_status = shaderc_compilation_status_internal_error; + } + +- return result; ++ return bresult->compilation_status; + } + + size_t shaderc_result_get_length(const shaderc_compilation_result_t result) { +diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h +index d9d02b9..b076ec8 100644 --- a/libshaderc_util/include/libshaderc_util/compiler.h +++ b/libshaderc_util/include/libshaderc_util/compiler.h @@ -195,6 +195,7 @@ class Compiler { @@ -177,6 +508,8 @@ // Optimization passes to be applied. std::vector enabled_opt_passes_; +diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc +index e5f5d10..1f9e6a5 100644 --- a/libshaderc_util/src/compiler.cc +++ b/libshaderc_util/src/compiler.cc @@ -341,6 +341,11 @@ std::tuple, size_t> Compiler::Compile( @@ -202,6 +535,8 @@ void Compiler::SetOptimizationLevel(Compiler::OptimizationLevel level) { // Clear previous settings first. enabled_opt_passes_.clear(); +diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt +index d44f62a..83966b6 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -20,9 +20,9 @@ set(SHADERC_TINT_DIR "${SHADERC_THIRD_PARTY_ROOT_DIR}/tint" CACHE STRING @@ -229,11 +564,13 @@ if (NOT "${SPIRV_SKIP_TESTS}") if (MSVC) if (${MSVC_VERSION} LESS 1920) -@@ -83,7 +86,7 @@ endif() - - if (NOT TARGET glslang) - if (IS_DIRECTORY ${SHADERC_GLSLANG_DIR}) +@@ -87,8 +90,8 @@ if (NOT TARGET glslang) + # Glslang tests are off by default. Turn them on if testing Shaderc. + set(GLSLANG_TESTS ON) + endif() +- set(GLSLANG_ENABLE_INSTALL $) - add_subdirectory(${SHADERC_GLSLANG_DIR} glslang) ++ set(GLSLANG_ENABLE_INSTALL OFF) + add_subdirectory(${SHADERC_GLSLANG_DIR} glslang EXCLUDE_FROM_ALL) endif() if (NOT TARGET glslang) diff --git a/src/util/gpu_device.cpp b/src/util/gpu_device.cpp index b68933216..3603a5a33 100644 --- a/src/util/gpu_device.cpp +++ b/src/util/gpu_device.cpp @@ -1121,14 +1121,13 @@ std::unique_ptr GPUDevice::CreateDeviceForAPI(RenderAPI api) X(shaderc_compile_options_release) \ X(shaderc_compile_options_set_source_language) \ X(shaderc_compile_options_set_generate_debug_info) \ - X(shaderc_compile_options_set_emit_non_semantic_debug_info) \ X(shaderc_compile_options_set_optimization_level) \ X(shaderc_compile_options_set_target_env) \ + X(shaderc_compilation_status_to_string) \ X(shaderc_compile_into_spv) \ X(shaderc_result_release) \ X(shaderc_result_get_length) \ X(shaderc_result_get_num_warnings) \ - X(shaderc_result_get_compilation_status) \ X(shaderc_result_get_bytes) \ X(shaderc_result_get_error_message) @@ -1195,81 +1194,46 @@ bool GPUDevice::CompileGLSLShaderToVulkanSpv(GPUShaderStage stage, std::string_v shaderc_glsl_compute_shader, }}; - // TODO: Move to library. - static constexpr const std::pair status_names[] = { - {shaderc_compilation_status_success, "shaderc_compilation_status_success"}, - {shaderc_compilation_status_invalid_stage, "shaderc_compilation_status_invalid_stage"}, - {shaderc_compilation_status_compilation_error, "shaderc_compilation_status_compilation_error"}, - {shaderc_compilation_status_internal_error, "shaderc_compilation_status_internal_error"}, - {shaderc_compilation_status_null_result_object, "shaderc_compilation_status_null_result_object"}, - {shaderc_compilation_status_invalid_assembly, "shaderc_compilation_status_invalid_assembly"}, - {shaderc_compilation_status_validation_error, "shaderc_compilation_status_validation_error"}, - {shaderc_compilation_status_transformation_error, "shaderc_compilation_status_transformation_error"}, - {shaderc_compilation_status_configuration_error, "shaderc_compilation_status_configuration_error"}, - }; - if (!dyn_shaderc::Open()) return false; - const std::unique_ptr options( - dyn_shaderc::shaderc_compile_options_initialize(), dyn_shaderc::shaderc_compile_options_release); - if (!options) + shaderc_compile_options_t options = dyn_shaderc::shaderc_compile_options_initialize(); + AssertMsg(options, "shaderc_compile_options_initialize() failed"); + + dyn_shaderc::shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl); + dyn_shaderc::shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0); + dyn_shaderc::shaderc_compile_options_set_generate_debug_info(options, m_debug_device, + m_debug_device && nonsemantic_debug_info); + dyn_shaderc::shaderc_compile_options_set_optimization_level( + options, m_debug_device ? shaderc_optimization_level_zero : shaderc_optimization_level_performance); + + shaderc_compilation_result_t result; + const shaderc_compilation_status status = dyn_shaderc::shaderc_compile_into_spv( + dyn_shaderc::s_compiler.get(), source.data(), source.length(), stage_kinds[static_cast(stage)], "source", + entry_point, options, &result); + if (status != shaderc_compilation_status_success) { - Log_ErrorPrint("Failed to create shaderc options."); - return false; - } - - dyn_shaderc::shaderc_compile_options_set_source_language(options.get(), shaderc_source_language_glsl); - dyn_shaderc::shaderc_compile_options_set_target_env(options.get(), shaderc_target_env_vulkan, 0); - - if (m_debug_device) - { - dyn_shaderc::shaderc_compile_options_set_generate_debug_info(options.get()); - if (nonsemantic_debug_info) - dyn_shaderc::shaderc_compile_options_set_emit_non_semantic_debug_info(options.get()); - - dyn_shaderc::shaderc_compile_options_set_optimization_level(options.get(), shaderc_optimization_level_zero); + const std::string_view errors(result ? dyn_shaderc::shaderc_result_get_error_message(result) : + "null result object"); + Log_ErrorFmt("Failed to compile shader to SPIR-V: {}\n{}", + dyn_shaderc::shaderc_compilation_status_to_string(status), errors); + DumpBadShader(source, errors); } else { - dyn_shaderc::shaderc_compile_options_set_optimization_level(options.get(), shaderc_optimization_level_performance); + const size_t num_warnings = dyn_shaderc::shaderc_result_get_num_warnings(result); + if (num_warnings > 0) + Log_WarningFmt("Shader compiled with warnings:\n{}", dyn_shaderc::shaderc_result_get_error_message(result)); + + const size_t spirv_size = dyn_shaderc::shaderc_result_get_length(result); + DebugAssert(spirv_size > 0); + out_binary->resize(spirv_size); + std::memcpy(out_binary->data(), dyn_shaderc::shaderc_result_get_bytes(result), spirv_size); } - const std::unique_ptr result( - dyn_shaderc::shaderc_compile_into_spv(dyn_shaderc::s_compiler.get(), source.data(), source.length(), - stage_kinds[static_cast(stage)], "source", entry_point, - options.get()), - dyn_shaderc::shaderc_result_release); - const shaderc_compilation_status status = result ? dyn_shaderc::shaderc_result_get_compilation_status(result.get()) : - shaderc_compilation_status_null_result_object; - if (status != shaderc_compilation_status_success) - { - const char* status_name = "UNKNOWN"; - for (const auto& it : status_names) - { - if (status == it.first) - { - status_name = it.second; - break; - } - } - - const std::string_view errors(result ? dyn_shaderc::shaderc_result_get_error_message(result.get()) : - "null result object"); - Log_ErrorFmt("Failed to compile shader to SPIR-V: {}\n{}", status_name, errors); - DumpBadShader(source, errors); - return false; - } - - const size_t num_warnings = dyn_shaderc::shaderc_result_get_num_warnings(result.get()); - if (num_warnings > 0) - Log_WarningFmt("Shader compiled with warnings:\n{}", dyn_shaderc::shaderc_result_get_error_message(result.get())); - - const size_t spirv_size = dyn_shaderc::shaderc_result_get_length(result.get()); - DebugAssert(spirv_size > 0); - out_binary->resize(spirv_size); - std::memcpy(out_binary->data(), dyn_shaderc::shaderc_result_get_bytes(result.get()), spirv_size); - return true; + dyn_shaderc::shaderc_result_release(result); + dyn_shaderc::shaderc_compile_options_release(options); + return (status == shaderc_compilation_status_success); } #endif