diff --git a/PCSX2_qt.sln b/PCSX2_qt.sln
index e3064125c4..4e283b61a7 100644
--- a/PCSX2_qt.sln
+++ b/PCSX2_qt.sln
@@ -27,8 +27,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeb", "3rdparty\cubeb\cub
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ryml", "3rdparty\rapidyaml\ryml.vcxproj", "{DE9653B6-17DD-356A-9EE0-28A731772587}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang", "3rdparty\glslang\glslang.vcxproj", "{EF6834A9-11F3-4331-BC34-21B325ABB180}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzip", "3rdparty\libzip\libzip.vcxproj", "{20B2E9FE-F020-42A0-B324-956F5B06EA68}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d12memalloc", "3rdparty\d3d12memalloc\d3d12memalloc.vcxproj", "{D45CEC7A-3171-40DD-975D-E1544CF16139}"
@@ -331,30 +329,6 @@ Global
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release Clang|x64.Build.0 = Release Clang|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.ActiveCfg = Release|x64
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.Build.0 = Release|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.ActiveCfg = Debug|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.Build.0 = Debug|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug Clang AVX2|x64.ActiveCfg = Debug Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug Clang AVX2|x64.Build.0 = Debug Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug Clang|x64.ActiveCfg = Debug Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug Clang|x64.Build.0 = Debug Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.ActiveCfg = Debug|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.Build.0 = Debug|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.ActiveCfg = Devel|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.Build.0 = Devel|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel Clang AVX2|x64.ActiveCfg = Devel Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel Clang AVX2|x64.Build.0 = Devel Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel Clang|x64.ActiveCfg = Devel Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel Clang|x64.Build.0 = Devel Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.ActiveCfg = Devel|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.Build.0 = Devel|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.ActiveCfg = Release|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.Build.0 = Release|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release Clang AVX2|x64.ActiveCfg = Release Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release Clang AVX2|x64.Build.0 = Release Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release Clang|x64.ActiveCfg = Release Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release Clang|x64.Build.0 = Release Clang|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.ActiveCfg = Release|x64
- {EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.Build.0 = Release|x64
{20B2E9FE-F020-42A0-B324-956F5B06EA68}.Debug AVX2|x64.ActiveCfg = Debug|x64
{20B2E9FE-F020-42A0-B324-956F5B06EA68}.Debug AVX2|x64.Build.0 = Debug|x64
{20B2E9FE-F020-42A0-B324-956F5B06EA68}.Debug Clang AVX2|x64.ActiveCfg = Debug Clang|x64
@@ -620,7 +594,6 @@ Global
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{BF74C473-DC04-44B3-92E8-4145F4E77342} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{DE9653B6-17DD-356A-9EE0-28A731772587} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
- {EF6834A9-11F3-4331-BC34-21B325ABB180} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{20B2E9FE-F020-42A0-B324-956F5B06EA68} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{D45CEC7A-3171-40DD-975D-E1544CF16139} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{A4323327-3F2B-4271-83D9-7F9A3C66B6B2} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
diff --git a/cmake/FindShaderc.cmake b/cmake/FindShaderc.cmake
new file mode 100644
index 0000000000..17d229646f
--- /dev/null
+++ b/cmake/FindShaderc.cmake
@@ -0,0 +1,32 @@
+# - Try to find SHADERC
+# Once done this will define
+# SHADERC_FOUND - System has SHADERC
+# SHADERC_INCLUDE_DIRS - The SHADERC include directories
+# SHADERC_LIBRARIES - The libraries needed to use SHADERC
+
+FIND_PATH(
+ SHADERC_INCLUDE_DIR shaderc/shaderc.h
+ HINTS /usr/include /usr/local/include
+ ${SHADERC_PATH_INCLUDES}
+)
+
+FIND_LIBRARY(
+ SHADERC_LIBRARY
+ NAMES shaderc_shared
+ PATHS ${ADDITIONAL_LIBRARY_PATHS} ${SHADERC_PATH_LIB}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Shaderc DEFAULT_MSG
+ SHADERC_LIBRARY SHADERC_INCLUDE_DIR)
+
+if(SHADERC_FOUND)
+ add_library(Shaderc::shaderc_shared UNKNOWN IMPORTED)
+ set_target_properties(Shaderc::shaderc_shared PROPERTIES
+ IMPORTED_LOCATION ${SHADERC_LIBRARY}
+ INTERFACE_INCLUDE_DIRECTORIES ${SHADERC_INCLUDE_DIR}
+ INTERFACE_COMPILE_DEFINITIONS "SHADERC_SHAREDLIB"
+ )
+endif()
+
+mark_as_advanced(SHADERC_INCLUDE_DIR SHADERC_LIBRARY)
diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake
index f51bc65c4a..37ae51823a 100644
--- a/cmake/SearchForStuff.cmake
+++ b/cmake/SearchForStuff.cmake
@@ -19,6 +19,10 @@ find_package(LZ4 REQUIRED)
find_package(WebP REQUIRED) # v1.3.2, spews an error on Linux because no pkg-config.
find_package(SDL2 2.30.2 REQUIRED)
+if(USE_VULKAN)
+ find_package(Shaderc REQUIRED)
+endif()
+
# Platform-specific dependencies.
if (WIN32)
add_subdirectory(3rdparty/D3D12MemAlloc EXCLUDE_FROM_ALL)
@@ -110,7 +114,6 @@ if(USE_OPENGL)
endif()
if(USE_VULKAN)
- add_subdirectory(3rdparty/glslang EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/vulkan-headers EXCLUDE_FROM_ALL)
endif()
diff --git a/common/vsprops/LinkPCSX2Deps.props b/common/vsprops/LinkPCSX2Deps.props
index 3b1d8d780b..05c9c44680 100644
--- a/common/vsprops/LinkPCSX2Deps.props
+++ b/common/vsprops/LinkPCSX2Deps.props
@@ -4,7 +4,7 @@
$(DepsLibDir);%(AdditionalLibraryDirectories)
- %(AdditionalDependencies);libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib
+ %(AdditionalDependencies);libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;shaderc_shared.lib;zlib.lib;zstd.lib
@@ -16,6 +16,7 @@
+
diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt
index 543fb9d5d9..8094db3344 100644
--- a/pcsx2/CMakeLists.txt
+++ b/pcsx2/CMakeLists.txt
@@ -626,7 +626,7 @@ if(USE_VULKAN)
GS/Renderers/Vulkan/VKStreamBuffer.h
GS/Renderers/Vulkan/VKSwapChain.h
)
- target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers glslang)
+ target_link_libraries(PCSX2_FLAGS INTERFACE Vulkan-Headers Shaderc::shaderc_shared)
endif()
set(pcsx2GSMetalShaders
@@ -1243,7 +1243,7 @@ function(setup_main_executable target)
# Copy dependency libraries.
set(DEPS_BINDIR "${CMAKE_SOURCE_DIR}/deps/bin")
- set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL2.dll zlib1.dll zstd.dll)
+ set(DEPS_TO_COPY freetype.dll harfbuzz.dll libjpeg.dll libpng16.dll libsharpyuv.dll libwebp.dll lz4.dll SDL2.dll shaderc_shared.dll zlib1.dll zstd.dll)
foreach(DEP_TO_COPY ${DEPS_TO_COPY})
install(FILES "${DEPS_BINDIR}/${DEP_TO_COPY}" DESTINATION "${CMAKE_SOURCE_DIR}/bin")
endforeach()
diff --git a/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp b/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp
index 62e96cd787..ce88744ac1 100644
--- a/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp
+++ b/pcsx2/GS/Renderers/Vulkan/VKShaderCache.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
+// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
#include "GS/GS.h"
@@ -15,12 +15,8 @@
#include "common/MD5Digest.h"
#include "common/Path.h"
-// glslang includes
-#include "SPIRV/GlslangToSpv.h"
-#include "StandAlone/ResourceLimits.h"
-#include "glslang/Public/ShaderLang.h"
-
#include "fmt/format.h"
+#include "shaderc/shaderc.hpp"
#include
#include
@@ -30,6 +26,9 @@
std::unique_ptr g_vulkan_shader_cache;
+static std::unique_ptr s_shaderc_compiler;
+static u32 s_next_bad_shader_id = 0;
+
namespace
{
#pragma pack(push, 4)
@@ -100,49 +99,34 @@ static void FillPipelineCacheHeader(VK_PIPELINE_CACHE_HEADER* header)
std::memcpy(header->uuid, GSDeviceVK::GetInstance()->GetDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE);
}
-static unsigned s_next_bad_shader_id = 1;
-static bool s_glslang_initialized = false;
-
-// Registers itself for cleanup via atexit
-static bool InitializeGlslang()
+std::optional VKShaderCache::CompileShaderToSPV(u32 stage, std::string_view source, bool debug)
{
- if (s_glslang_initialized)
- return true;
+ // TODO: NOT thread safe, yet.
+ if (!s_shaderc_compiler)
+ s_shaderc_compiler = std::make_unique();
- if (!glslang::InitializeProcess())
+ shaderc::CompileOptions options;
+ options.SetSourceLanguage(shaderc_source_language_glsl);
+ options.SetTargetEnvironment(shaderc_target_env_vulkan, 0);
+
+ if (debug)
{
- pxFailRel("Failed to initialize glslang shader compiler");
- return false;
+ options.SetOptimizationLevel(shaderc_optimization_level_zero);
+ options.SetGenerateDebugInfo();
+ }
+ else
+ {
+ options.SetOptimizationLevel(shaderc_optimization_level_performance);
}
- std::atexit(&glslang::FinalizeProcess);
- s_glslang_initialized = true;
- return true;
-}
-
-std::optional VKShaderCache::CompileShaderToSPV(
- u32 stage, std::string_view source, bool debug)
-{
- if (!InitializeGlslang())
- return std::nullopt;
-
- std::unique_ptr shader = std::make_unique(static_cast(stage));
- std::unique_ptr program;
- glslang::TShader::ForbidIncluder includer;
- const EProfile profile = ECoreProfile;
- const EShMessages messages =
- static_cast(EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules | (debug ? EShMsgDebugInfo : 0));
- const int default_version = 450;
-
- std::string full_source_code;
- const char* pass_source_code = source.data();
- int pass_source_code_length = static_cast(source.size());
- shader->setStringsWithLengths(&pass_source_code, &pass_source_code_length, 1);
-
- auto DumpBadShader = [&shader, &source, &program](const char* msg) {
+ 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.Error("CompileShaderToSPV: %s, writing to %s", msg, filename.c_str());
+ 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())
@@ -151,62 +135,17 @@ std::optional VKShaderCache::CompileShaderToSPV(
ofs << "\n";
ofs << msg << std::endl;
- ofs << "Shader Info Log:" << std::endl;
- ofs << shader->getInfoLog() << std::endl;
- ofs << shader->getInfoDebugLog() << std::endl;
- if (program)
- {
- ofs << "Program Info Log:" << std::endl;
- ofs << program->getInfoLog() << std::endl;
- ofs << program->getInfoDebugLog() << std::endl;
- }
-
ofs.close();
}
- };
- if (!shader->parse(&glslang::DefaultTBuiltInResource, default_version, profile, false, true, messages, includer))
- {
- DumpBadShader("Failed to parse shader");
return std::nullopt;
}
-
- // Even though there's only a single shader, we still need to link it to generate SPV
- program = std::make_unique();
- program->addShader(shader.get());
- if (!program->link(messages))
+ else if (result.GetNumWarnings() > 0)
{
- DumpBadShader("Failed to link program");
- return std::nullopt;
+ Console.WarningFmt("CompileShaderToSPV(): Shader compiled with warnings:\n{}", result.GetErrorMessage());
}
- glslang::TIntermediate* intermediate = program->getIntermediate(static_cast(stage));
- if (!intermediate)
- {
- DumpBadShader("Failed to generate SPIR-V");
- return std::nullopt;
- }
-
- SPIRVCodeVector out_code;
- spv::SpvBuildLogger logger;
- glslang::SpvOptions options;
- options.generateDebugInfo = debug;
- glslang::GlslangToSpv(*intermediate, out_code, &logger, &options);
-
- // Write out messages
- if (std::strlen(shader->getInfoLog()) > 0)
- Console.Warning("Shader info log: %s", shader->getInfoLog());
- if (std::strlen(shader->getInfoDebugLog()) > 0)
- Console.Warning("Shader debug info log: %s", shader->getInfoDebugLog());
- if (std::strlen(program->getInfoLog()) > 0)
- Console.Warning("Program info log: %s", program->getInfoLog());
- if (std::strlen(program->getInfoDebugLog()) > 0)
- Console.Warning("Program debug info log: %s", program->getInfoDebugLog());
- std::string spv_messages = logger.getAllMessages();
- if (!spv_messages.empty())
- Console.Warning("SPIR-V conversion messages: %s", spv_messages.c_str());
-
- return out_code;
+ return SPIRVCodeVector(result.cbegin(), result.cend());
}
VKShaderCache::VKShaderCache() = default;
@@ -595,17 +534,17 @@ VkShaderModule VKShaderCache::GetShaderModule(u32 type, std::string_view shader_
VkShaderModule VKShaderCache::GetVertexShader(std::string_view shader_code)
{
- return GetShaderModule(EShLangVertex, std::move(shader_code));
+ return GetShaderModule(shaderc_glsl_vertex_shader, std::move(shader_code));
}
VkShaderModule VKShaderCache::GetFragmentShader(std::string_view shader_code)
{
- return GetShaderModule(EShLangFragment, std::move(shader_code));
+ return GetShaderModule(shaderc_glsl_fragment_shader, std::move(shader_code));
}
VkShaderModule VKShaderCache::GetComputeShader(std::string_view shader_code)
{
- return GetShaderModule(EShLangCompute, std::move(shader_code));
+ return GetShaderModule(shaderc_glsl_compute_shader, std::move(shader_code));
}
std::optional VKShaderCache::CompileAndAddShaderSPV(
diff --git a/pcsx2/ShaderCacheVersion.h b/pcsx2/ShaderCacheVersion.h
index f73a803376..b5c115fdf4 100644
--- a/pcsx2/ShaderCacheVersion.h
+++ b/pcsx2/ShaderCacheVersion.h
@@ -1,6 +1,6 @@
-// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
+// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
/// Version number for GS and other shaders. Increment whenever any of the contents of the
/// shaders change, to invalidate the cache.
-static constexpr u32 SHADER_CACHE_VERSION = 44;
+static constexpr u32 SHADER_CACHE_VERSION = 45;
diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj
index 35b6408fae..568819ee2a 100644
--- a/pcsx2/pcsx2.vcxproj
+++ b/pcsx2/pcsx2.vcxproj
@@ -51,7 +51,6 @@
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\jpgd
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\ffmpeg\include
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\glad\include
- %(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\glslang\glslang
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\vulkan-headers\include
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\d3d12memalloc\include
%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\lzma\include
@@ -822,9 +821,6 @@
{e960dfdf-1bd3-4c29-b251-d1a0919c9b09}
-
- {ef6834a9-11f3-4331-bc34-21b325abb180}
-
{20b2e9fe-f020-42a0-b324-956f5b06ea68}