From ff7995f0d6caaacaf919908e1e9f8b5d6c5983ae Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 21 May 2024 12:42:45 +1000 Subject: [PATCH] Deps: Bump to shaderc 2024.1 And use dynamic loading. --- .../scripts/common/shaderc-changes.patch | 401 ++++++++++++++++-- .../workflows/scripts/linux/appimage-qt.sh | 24 +- .../scripts/linux/build-dependencies-qt.sh | 16 +- .../linux/flatpak/modules/22-shaderc.json | 14 +- .../scripts/macos/build-dependencies.sh | 16 +- .../scripts/windows/build-dependencies.bat | 16 +- cmake/FindShaderc.cmake | 7 +- common/vsprops/LinkPCSX2Deps.props | 2 +- pcsx2/CMakeLists.txt | 7 +- pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp | 186 ++++++-- 10 files changed, 576 insertions(+), 113 deletions(-) diff --git a/.github/workflows/scripts/common/shaderc-changes.patch b/.github/workflows/scripts/common/shaderc-changes.patch index 4cbca1e3ef..4524d53e64 100644 --- a/.github/workflows/scripts/common/shaderc-changes.patch +++ b/.github/workflows/scripts/common/shaderc-changes.patch @@ -1,13 +1,18 @@ +diff --git a/CHANGES b/CHANGES +index 5d3dd16..587b612 100644 --- a/CHANGES +++ b/CHANGES -@@ -1,6 +1,6 @@ - Revision history for Shaderc +@@ -4,7 +4,7 @@ v2024.1 + - Update dependencies + - Propagate test/install options to Glslang -v2024.0 +v2024.0 2024-03-09 - Update dependencies - Utilities: - Use Python3 explicitly in utility scripts +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ffcb54b..7c1a6d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,9 @@ if(MSVC) @@ -34,6 +39,8 @@ define_pkg_config_file(shaderc -lshaderc_shared) -define_pkg_config_file(shaderc_static "-lshaderc ${EXTRA_STATIC_PKGCONFIG_LIBS} -lshaderc_util") -define_pkg_config_file(shaderc_combined -lshaderc_combined) +diff --git a/libshaderc/CMakeLists.txt b/libshaderc/CMakeLists.txt +index df9a88d..b15e5d7 100644 --- a/libshaderc/CMakeLists.txt +++ b/libshaderc/CMakeLists.txt @@ -24,13 +24,6 @@ set(SHADERC_SOURCES @@ -103,48 +110,372 @@ if(${SHADERC_ENABLE_TESTS}) add_executable(shaderc_c_smoke_test ./src/shaderc_c_smoke_test.c) shaderc_default_c_compile_options(shaderc_c_smoke_test) +diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/shaderc.h +index 3a3e97d..65d5b77 100644 --- a/libshaderc/include/shaderc/shaderc.h +++ b/libshaderc/include/shaderc/shaderc.h -@@ -319,6 +319,10 @@ SHADERC_EXPORT void shaderc_compile_options_set_source_language( - SHADERC_EXPORT void shaderc_compile_options_set_generate_debug_info( - shaderc_compile_options_t options); +@@ -317,7 +317,7 @@ SHADERC_EXPORT void shaderc_compile_options_set_source_language( + + // Sets the compiler mode to generate debug information in the output. + SHADERC_EXPORT void shaderc_compile_options_set_generate_debug_info( +- shaderc_compile_options_t options); ++ shaderc_compile_options_t options, bool enabled, bool enable_non_semantic); -+// Sets the compiler mode to emit non-semantic debug information in the output. -+SHADERC_EXPORT void shaderc_compile_options_set_emit_non_semantic_debug_info( -+ shaderc_compile_options_t options); -+ // Sets the compiler optimization level to the given level. Only the last one // takes effect if multiple calls of this function exist. - SHADERC_EXPORT void shaderc_compile_options_set_optimization_level( +@@ -506,6 +506,10 @@ SHADERC_EXPORT void shaderc_compile_options_set_invert_y( + SHADERC_EXPORT void shaderc_compile_options_set_nan_clamp( + shaderc_compile_options_t options, bool enable); + ++// Returns a string representation of the specified compilation status. ++SHADERC_EXPORT const char* shaderc_compilation_status_to_string( ++ shaderc_compilation_status status); ++ + // An opaque handle to the results of a call to any shaderc_compile_into_*() + // function. + typedef struct shaderc_compilation_result* shaderc_compilation_result_t; +@@ -529,28 +533,31 @@ typedef struct shaderc_compilation_result* shaderc_compilation_result_t; + // present. May be safely called from multiple threads without explicit + // synchronization. If there was failure in allocating the compiler object, + // null will be returned. +-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv( ++SHADERC_EXPORT 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); ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result); + + // Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text + // instead of a SPIR-V binary module. The SPIR-V assembly syntax is as defined + // by the SPIRV-Tools open source project. +-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly( ++SHADERC_EXPORT 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); ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result); + + // Like shaderc_compile_into_spv, but the result contains preprocessed source + // code instead of a SPIR-V binary module +-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text( ++SHADERC_EXPORT 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); ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result); + + // Takes an assembly string of the format defined in the SPIRV-Tools project + // (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md), +@@ -561,10 +568,11 @@ SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_te + // May be safely called from multiple threads without explicit synchronization. + // If there was failure in allocating the compiler object, null will be + // returned. +-SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv( ++SHADERC_EXPORT 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); ++ const shaderc_compile_options_t additional_options, ++ shaderc_compilation_result_t* result); + + // The following functions, operating on shaderc_compilation_result_t objects, + // offer only the basic thread-safety guarantee. +diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp +index 3817af8..5592b49 100644 --- a/libshaderc/include/shaderc/shaderc.hpp +++ b/libshaderc/include/shaderc/shaderc.hpp -@@ -172,6 +172,12 @@ class CompileOptions { - shaderc_compile_options_set_generate_debug_info(options_); +@@ -168,8 +168,9 @@ class CompileOptions { + } + + // Sets the compiler mode to generate debug information in the output. +- void SetGenerateDebugInfo() { +- shaderc_compile_options_set_generate_debug_info(options_); ++ void SetGenerateDebugInfo(bool enabled, bool non_semantic_debug_info) { ++ shaderc_compile_options_set_generate_debug_info(options_, enabled, ++ non_sematic_debug_info); } -+ // Sets the compiler mode to emit non-semantic debug information in the -+ // output. -+ void SetEmitNonSemanticDebugInfo() { -+ shaderc_compile_options_set_emit_non_semantic_debug_info(options_); -+ } -+ // Sets the compiler optimization level to the given level. Only the last one - // takes effect if multiple calls of this function exist. - void SetOptimizationLevel(shaderc_optimization_level level) { +@@ -425,9 +426,10 @@ class Compiler { + const char* input_file_name, + const char* entry_point_name, + const CompileOptions& options) const { +- shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv( ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_compile_into_spv( + compiler_, source_text, source_text_size, shader_kind, input_file_name, +- entry_point_name, options.options_); ++ entry_point_name, options.options_, &compilation_result); + return SpvCompilationResult(compilation_result); + } + +@@ -451,9 +453,10 @@ class Compiler { + size_t source_text_size, + shaderc_shader_kind shader_kind, + const char* input_file_name) const { +- shaderc_compilation_result_t compilation_result = +- shaderc_compile_into_spv(compiler_, source_text, source_text_size, +- shader_kind, input_file_name, "main", nullptr); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_compile_into_spv(compiler_, source_text, source_text_size, ++ shader_kind, input_file_name, "main", nullptr, ++ &compilation_result); + return SpvCompilationResult(compilation_result); + } + +@@ -504,8 +507,11 @@ class Compiler { + SpvCompilationResult AssembleToSpv(const char* source_assembly, + size_t source_assembly_size, + const CompileOptions& options) const { +- return SpvCompilationResult(shaderc_assemble_into_spv( +- compiler_, source_assembly, source_assembly_size, options.options_)); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_assemble_into_spv( ++ compiler_, source_assembly, source_assembly_size, options.options_, ++ &compilation_result); ++ return SpvCompilationResult(compilation_result); + } + + // Assembles the given SPIR-V assembly and returns a SPIR-V binary module +@@ -513,8 +519,11 @@ class Compiler { + // Like the first AssembleToSpv method but uses the default compiler options. + SpvCompilationResult AssembleToSpv(const char* source_assembly, + size_t source_assembly_size) const { +- return SpvCompilationResult(shaderc_assemble_into_spv( +- compiler_, source_assembly, source_assembly_size, nullptr)); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_assemble_into_spv( ++ compiler_, source_assembly, source_assembly_size, nullptr, ++ &compilation_result); ++ return SpvCompilationResult(compilation_result); + } + + // Assembles the given SPIR-V assembly and returns a SPIR-V binary module +@@ -523,9 +532,11 @@ class Compiler { + // std::string. + SpvCompilationResult AssembleToSpv(const std::string& source_assembly, + const CompileOptions& options) const { +- return SpvCompilationResult( +- shaderc_assemble_into_spv(compiler_, source_assembly.data(), +- source_assembly.size(), options.options_)); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_assemble_into_spv( ++ compiler_, source_assembly.data(), source_assembly.size(), ++ options.options_, &compilation_result); ++ return SpvCompilationResult(compilation_result); + } + + // Assembles the given SPIR-V assembly and returns a SPIR-V binary module +@@ -533,8 +544,10 @@ class Compiler { + // Like the first AssembleToSpv method but the source is provided as a + // std::string and also uses default compiler options. + SpvCompilationResult AssembleToSpv(const std::string& source_assembly) const { +- return SpvCompilationResult(shaderc_assemble_into_spv( +- compiler_, source_assembly.data(), source_assembly.size(), nullptr)); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_assemble_into_spv(compiler_, source_assembly.data(), ++ source_assembly.size(), nullptr, &compilation_result); ++ return SpvCompilationResult(compilation_result); + } + + // Compiles the given source GLSL and returns the SPIR-V assembly text +@@ -544,10 +557,11 @@ class 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 CompileOptions& options) const { +- shaderc_compilation_result_t compilation_result = +- shaderc_compile_into_spv_assembly( +- compiler_, source_text, source_text_size, shader_kind, +- input_file_name, entry_point_name, options.options_); ++ shaderc_compilation_result_t compilation_result = nullptr; ++ shaderc_compile_into_spv_assembly( ++ compiler_, source_text, source_text_size, shader_kind, ++ input_file_name, entry_point_name, options.options_, ++ &compilation_result); + return AssemblyCompilationResult(compilation_result); + } + +@@ -592,10 +606,10 @@ class Compiler { + const char* source_text, size_t source_text_size, + shaderc_shader_kind shader_kind, const char* input_file_name, + const CompileOptions& options) const { +- shaderc_compilation_result_t compilation_result = +- shaderc_compile_into_preprocessed_text( ++ shaderc_compilation_result_t compilation_result; ++ shaderc_compile_into_preprocessed_text( + compiler_, source_text, source_text_size, shader_kind, +- input_file_name, "main", options.options_); ++ input_file_name, "main", options.options_, &compilation_result); + return PreprocessedSourceCompilationResult(compilation_result); + } + +diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc +index 63f1bbc..c1a9b12 100644 --- a/libshaderc/src/shaderc.cc +++ b/libshaderc/src/shaderc.cc -@@ -422,6 +422,11 @@ void shaderc_compile_options_set_generate_debug_info( - options->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/.github/workflows/scripts/linux/appimage-qt.sh b/.github/workflows/scripts/linux/appimage-qt.sh index 8fc4c14340..775dca08df 100755 --- a/.github/workflows/scripts/linux/appimage-qt.sh +++ b/.github/workflows/scripts/linux/appimage-qt.sh @@ -41,6 +41,10 @@ BINARY=pcsx2-qt APPDIRNAME=PCSX2.AppDir STRIP=strip +declare -a MANUAL_LIBS=( + "libshaderc_shared.so.1" +) + declare -a MANUAL_QT_LIBS=( "libQt6WaylandEglClientHwIntegration.so.6" ) @@ -76,6 +80,24 @@ fi OUTDIR=$(realpath "./$APPDIRNAME") rm -fr "$OUTDIR" +echo "Locating extra libraries..." +EXTRA_LIBS_ARGS="" +for lib in "${MANUAL_LIBS[@]}"; do + srcpath=$(find "$DEPSDIR" -name "$lib") + if [ ! -f "$srcpath" ]; then + echo "Missinge extra library $lib. Exiting." + exit 1 + fi + + echo "Found $lib at $srcpath." + + if [ "$EXTRA_LIBS_ARGS" == "" ]; then + EXTRA_LIBS_ARGS="--library=$srcpath" + else + EXTRA_LIBS_ARGS="$EXTRA_LIBS_ARGS,$srcpath" + fi +done + # Why the nastyness? linuxdeploy strips our main binary, and there's no option to turn it off. # It also doesn't strip the Qt libs. We can't strip them after running linuxdeploy, because # patchelf corrupts the libraries (but they still work), but patchelf+strip makes them crash @@ -102,7 +124,7 @@ EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" \ DEPLOY_PLATFORM_THEMES="1" \ QMAKE="$DEPSDIR/bin/qmake" \ NO_STRIP="1" \ -$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt" \ +$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt" $EXTRA_LIBS_ARGS \ --desktop-file="net.pcsx2.PCSX2.desktop" --icon-file="PCSX2.png" echo "Copying resources into AppDir..." diff --git a/.github/workflows/scripts/linux/build-dependencies-qt.sh b/.github/workflows/scripts/linux/build-dependencies-qt.sh index c48159ae86..bfbfac8953 100755 --- a/.github/workflows/scripts/linux/build-dependencies-qt.sh +++ b/.github/workflows/scripts/linux/build-dependencies-qt.sh @@ -23,10 +23,10 @@ SDL=SDL2-2.30.3 QT=6.7.1 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 mkdir -p deps-build cd deps-build @@ -45,10 +45,10 @@ a733b98f771064d000476b8861f822143982749448ba8abf9f1813edb8dfe79f qtimageformats 0953cddf6248f3959279a10904892e8a98eb3e463d729a174b6fc47febd99824 qttools-everywhere-src-$QT.tar.xz 03d71565872b0e0e7303349071df031ab0f922f6dbdd3a5ec1ade9e188e4fbf4 qttranslations-everywhere-src-$QT.tar.xz 7ef176a8e701c90edd8e591dad36f83c30d623ef94439ff62cafcffd46a83d20 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 EOF curl -C - -L \ diff --git a/.github/workflows/scripts/linux/flatpak/modules/22-shaderc.json b/.github/workflows/scripts/linux/flatpak/modules/22-shaderc.json index bb61782746..138e8331c3 100644 --- a/.github/workflows/scripts/linux/flatpak/modules/22-shaderc.json +++ b/.github/workflows/scripts/linux/flatpak/modules/22-shaderc.json @@ -15,24 +15,24 @@ { "type": "git", "url": "https://github.com/google/shaderc.git", - "commit": "d792558a8902cb39b1c237243cc4edab226513a5" + "commit": "47a9387ef5b3600d30d84c71ec77a59dc7db46fa" }, { "type": "archive", - "url": "https://github.com/KhronosGroup/glslang/archive/d73712b8f6c9047b09e99614e20d456d5ada2390.tar.gz", - "sha256": "d27f7359156a92749f8fd4681d1d518c736864213c431cf8144ecc2fb6689a2d", + "url": "https://github.com/KhronosGroup/glslang/archive/142052fa30f9eca191aa9dcf65359fcaed09eeec.tar.gz", + "sha256": "aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f", "dest": "third_party/glslang" }, { "type": "archive", - "url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/8b246ff75c6615ba4532fe4fde20f1be090c3764.tar.gz", - "sha256": "cfeed5f9a97d12a9761a26e7f5bd10fedb1a8ce92033075151ae3bc7206fc229", + "url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/5e3ad389ee56fca27c9705d093ae5387ce404df4.tar.gz", + "sha256": "5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697", "dest": "third_party/spirv-headers" }, { "type": "archive", - "url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/04896c462d9f3f504c99a4698605b6524af813c1.tar.gz", - "sha256": "c0d01e758a543b3a358cb97af02c6817ebd3f5ff13a2edf9fb220646a3d67999", + "url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/dd4b663e13c07fea4fbb3f70c1c91c86731099f7.tar.gz", + "sha256": "03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47", "dest": "third_party/spirv-tools" }, { diff --git a/.github/workflows/scripts/macos/build-dependencies.sh b/.github/workflows/scripts/macos/build-dependencies.sh index ffab9b30ce..cba8cd4f14 100755 --- a/.github/workflows/scripts/macos/build-dependencies.sh +++ b/.github/workflows/scripts/macos/build-dependencies.sh @@ -32,10 +32,10 @@ FFMPEG=6.0 MOLTENVK=1.2.8 QT=6.7.1 -SHADERC=2024.0 -SHADERC_GLSLANG=d73712b8f6c9047b09e99614e20d456d5ada2390 -SHADERC_SPIRVHEADERS=8b246ff75c6615ba4532fe4fde20f1be090c3764 -SHADERC_SPIRVTOOLS=04896c462d9f3f504c99a4698605b6524af813c1 +SHADERC=2024.1 +SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec +SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4 +SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 mkdir -p deps-build cd deps-build @@ -69,10 +69,10 @@ a733b98f771064d000476b8861f822143982749448ba8abf9f1813edb8dfe79f qtimageformats 3ed5b80f7228c41dd463b7a57284ed273d224d1c323c0dd78c5209635807cbce qtsvg-everywhere-src-$QT.tar.xz 0953cddf6248f3959279a10904892e8a98eb3e463d729a174b6fc47febd99824 qttools-everywhere-src-$QT.tar.xz 03d71565872b0e0e7303349071df031ab0f922f6dbdd3a5ec1ade9e188e4fbf4 qttranslations-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 EOF curl -L \ diff --git a/.github/workflows/scripts/windows/build-dependencies.bat b/.github/workflows/scripts/windows/build-dependencies.bat index 328965c5a1..5753492717 100644 --- a/.github/workflows/scripts/windows/build-dependencies.bat +++ b/.github/workflows/scripts/windows/build-dependencies.bat @@ -53,10 +53,10 @@ set ZLIB=1.3.1 set ZLIBSHORT=131 set ZSTD=1.5.5 -set SHADERC=2024.0 -set SHADERC_GLSLANG=d73712b8f6c9047b09e99614e20d456d5ada2390 -set SHADERC_SPIRVHEADERS=8b246ff75c6615ba4532fe4fde20f1be090c3764 -set SHADERC_SPIRVTOOLS=04896c462d9f3f504c99a4698605b6524af813c1 +set SHADERC=2024.1 +set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec +set SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4 +set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7 call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 || goto error call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip b2bc56184ae37324bc4829fde7d3f9e6916866ad711ee85792e457547c9fd127 || goto error @@ -73,10 +73,10 @@ call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" c5c8daa1d40dabc51790c62a5b86af2b36dfc4e1a738ff10dc4a46ea4e68ee51 || goto error -call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 5397160432fb5b780e9372327060b1be47acafcd0689fea44fd939e7305668ba || goto error -call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 58a0d4b670986f8618c371b088f2ee11006596e8c71fe499ec044d5ea469d39b || goto error -call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 1385538d16f8875e76209388187b3814cb0b0e9cecc3bc440faa7665b570ff47 || goto error -call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" 4eb9a3fc940ed1b05f968c181763dfdb8e637cbfbf57c625112b3ad0f76e2c28 || goto error +call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error +call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error +call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" fa59a54334feaba5702b9c25724c3f4746123865769b36dd5a28d9ef5e9d39ab || goto error +call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" bf385994c20293485b378c27dfdbd77a31b949deabccd9218a977f173eda9f6f || goto error if %DEBUG%==1 ( echo Building debug and release libraries... diff --git a/cmake/FindShaderc.cmake b/cmake/FindShaderc.cmake index 17d229646f..760184aa0e 100644 --- a/cmake/FindShaderc.cmake +++ b/cmake/FindShaderc.cmake @@ -4,15 +4,14 @@ # SHADERC_INCLUDE_DIRS - The SHADERC include directories # SHADERC_LIBRARIES - The libraries needed to use SHADERC -FIND_PATH( +find_path( SHADERC_INCLUDE_DIR shaderc/shaderc.h - HINTS /usr/include /usr/local/include ${SHADERC_PATH_INCLUDES} ) -FIND_LIBRARY( +find_library( SHADERC_LIBRARY - NAMES shaderc_shared + NAMES shaderc_shared.1 shaderc_shared PATHS ${ADDITIONAL_LIBRARY_PATHS} ${SHADERC_PATH_LIB} ) diff --git a/common/vsprops/LinkPCSX2Deps.props b/common/vsprops/LinkPCSX2Deps.props index 5eba91fab1..581422b35c 100644 --- a/common/vsprops/LinkPCSX2Deps.props +++ b/common/vsprops/LinkPCSX2Deps.props @@ -4,7 +4,7 @@ $(DepsLibDir);%(AdditionalLibraryDirectories) - %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;shaderc_shared.lib;zlib.lib;zstd.lib + %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 0910857328..a1829865a6 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -609,7 +609,8 @@ if(USE_VULKAN) GS/Renderers/Vulkan/VKStreamBuffer.h GS/Renderers/Vulkan/VKSwapChain.h ) - target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers Shaderc::shaderc_shared) + target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers) + target_include_directories(PCSX2_FLAGS INTERFACE ${SHADERC_INCLUDE_DIR}) endif() set(pcsx2GSMetalShaders @@ -1286,6 +1287,10 @@ function(setup_main_executable target) pcsx2_resource(${target} ${PCSX2_SOURCE_DIR}/Resources/PCSX2.icns ${PCSX2_SOURCE_DIR}/Resources) + # Copy shaderc into the bundle + target_sources(${target} PRIVATE "${SHADERC_LIBRARY}") + set_source_files_properties("${SHADERC_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks) + # Copy MoltenVK into the bundle unset(MOLTENVK_PATH CACHE) find_file(MOLTENVK_PATH NAMES diff --git a/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp b/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp index b71e93040a..d4df386617 100644 --- a/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp +++ b/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp @@ -11,22 +11,22 @@ #include "common/Assertions.h" #include "common/Console.h" +#include "common/DynamicLibrary.h" +#include "common/Error.h" #include "common/FileSystem.h" #include "common/MD5Digest.h" #include "common/Path.h" #include "fmt/format.h" -#include "shaderc/shaderc.hpp" +#include "shaderc/shaderc.h" #include -#include #include // TODO: store the driver version and stuff in the shader header std::unique_ptr g_vulkan_shader_cache; -static std::unique_ptr s_shaderc_compiler; static u32 s_next_bad_shader_id = 0; namespace @@ -99,56 +99,156 @@ static void FillPipelineCacheHeader(VK_PIPELINE_CACHE_HEADER* header) std::memcpy(header->uuid, GSDeviceVK::GetInstance()->GetDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE); } +#define SHADERC_FUNCTIONS(X) \ + X(shaderc_compiler_initialize) \ + X(shaderc_compiler_release) \ + X(shaderc_compile_options_initialize) \ + 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_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_bytes) \ + X(shaderc_result_get_error_message) + +// TODO: NOT thread safe, yet. +namespace dyn_shaderc +{ + static bool Open(); + static void Close(); + + static DynamicLibrary s_library; + static shaderc_compiler_t s_compiler = nullptr; + +#define ADD_FUNC(F) static decltype(&::F) F; + SHADERC_FUNCTIONS(ADD_FUNC) +#undef ADD_FUNC + +} // namespace dyn_shaderc + +bool dyn_shaderc::Open() +{ + if (s_library.IsOpen()) + return true; + + Error error; + +#ifdef _WIN32 + const std::string libname = DynamicLibrary::GetVersionedFilename("shaderc_shared"); +#else + // Use versioned, bundle post-processing adds it.. + const std::string libname = DynamicLibrary::GetVersionedFilename("shaderc_shared", 1); +#endif + if (!s_library.Open(libname.c_str(), &error)) + { + ERROR_LOG("Failed to load shaderc: {}", error.GetDescription()); + return false; + } + +#define LOAD_FUNC(F) \ + if (!s_library.GetSymbol(#F, &F)) \ + { \ + ERROR_LOG("Failed to find function {}", #F); \ + Close(); \ + return false; \ + } + + SHADERC_FUNCTIONS(LOAD_FUNC) +#undef LOAD_FUNC + + s_compiler = shaderc_compiler_initialize(); + if (!s_compiler) + { + ERROR_LOG("shaderc_compiler_initialize() failed"); + Close(); + return false; + } + + std::atexit(&dyn_shaderc::Close); + return true; +} + +void dyn_shaderc::Close() +{ + if (s_compiler) + { + shaderc_compiler_release(s_compiler); + s_compiler = nullptr; + } + +#define UNLOAD_FUNC(F) F = nullptr; + SHADERC_FUNCTIONS(UNLOAD_FUNC) +#undef UNLOAD_FUNC + + s_library.Close(); +} + +#undef SHADERC_FUNCTIONS +#undef SHADERC_INIT_FUNCTIONS + +static void DumpBadShader(std::string_view code, std::string_view errors) +{ + const std::string filename = Path::Combine(EmuFolders::Logs, fmt::format("pcsx2_bad_shader_{}.txt", ++s_next_bad_shader_id)); + auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "wb"); + if (fp) + { + if (!code.empty()) + std::fwrite(code.data(), code.size(), 1, fp.get()); + std::fputs("\n\n**** ERRORS ****\n", fp.get()); + if (!errors.empty()) + std::fwrite(errors.data(), errors.size(), 1, fp.get()); + } +} + std::optional VKShaderCache::CompileShaderToSPV(u32 stage, std::string_view source, bool debug) { - // TODO: NOT thread safe, yet. - if (!s_shaderc_compiler) - s_shaderc_compiler = std::make_unique(); + std::optional ret; + if (!dyn_shaderc::Open()) + return ret; - shaderc::CompileOptions options; - options.SetSourceLanguage(shaderc_source_language_glsl); - options.SetTargetEnvironment(shaderc_target_env_vulkan, 0); + shaderc_compile_options_t options = dyn_shaderc::shaderc_compile_options_initialize(); + pxAssertRel(options, "shaderc_compile_options_initialize() failed"); - if (debug) + 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, debug, + debug && GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_khr_shader_non_semantic_info); + dyn_shaderc::shaderc_compile_options_set_optimization_level( + options, debug ? 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, source.data(), source.length(), static_cast(stage), "source", + "main", options, &result); + if (status != shaderc_compilation_status_success) { - options.SetGenerateDebugInfo(); - if (GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_khr_shader_non_semantic_info) - options.SetEmitNonSemanticDebugInfo(); - - options.SetOptimizationLevel(shaderc_optimization_level_zero); + const std::string_view errors(result ? dyn_shaderc::shaderc_result_get_error_message(result) : + "null result object"); + ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", + dyn_shaderc::shaderc_compilation_status_to_string(status), errors); + DumpBadShader(source, errors); } else { - options.SetOptimizationLevel(shaderc_optimization_level_performance); + const size_t num_warnings = dyn_shaderc::shaderc_result_get_num_warnings(result); + if (num_warnings > 0) + WARNING_LOG("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); + const char* bytes = dyn_shaderc::shaderc_result_get_bytes(result); + pxAssert(spirv_size > 0 && ((spirv_size % sizeof(u32)) == 0)); + ret = VKShaderCache::SPIRVCodeVector(reinterpret_cast(bytes), + reinterpret_cast(bytes + spirv_size)); } - const shaderc::SpvCompilationResult result = s_shaderc_compiler->CompileGlslToSpv( - source.data(), source.length(), static_cast(stage), "source", "main", options); - if (result.GetCompilationStatus() != shaderc_compilation_status_success) - { - const std::string msg = result.GetErrorMessage(); - const std::string filename = - Path::Combine(EmuFolders::Logs, fmt::format("pcsx2_bad_shader_{}.txt", ++s_next_bad_shader_id)); - Console.ErrorFmt("CompileShaderToSPV(): {}, writing to {}", msg, filename.c_str()); - - std::ofstream ofs(filename, std::ofstream::out | std::ofstream::binary); - if (ofs.is_open()) - { - ofs << source; - ofs << "\n"; - - ofs << msg << std::endl; - ofs.close(); - } - - return std::nullopt; - } - else if (result.GetNumWarnings() > 0) - { - Console.WarningFmt("CompileShaderToSPV(): Shader compiled with warnings:\n{}", result.GetErrorMessage()); - } - - return SPIRVCodeVector(result.cbegin(), result.cend()); + dyn_shaderc::shaderc_result_release(result); + dyn_shaderc::shaderc_compile_options_release(options); + return ret; } VKShaderCache::VKShaderCache() = default;