GS/Vulkan: Swap out glslang for shaderc

This commit is contained in:
Stenzek 2024-04-06 17:06:10 +10:00 committed by Connor McLaughlin
parent 291ce2cbb0
commit ec3f1b2aa4
8 changed files with 75 additions and 131 deletions

View File

@ -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}

32
cmake/FindShaderc.cmake Normal file
View File

@ -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)

View File

@ -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()

View File

@ -4,7 +4,7 @@
<ItemDefinitionGroup>
<Link>
<AdditionalLibraryDirectories>$(DepsLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies);libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib</AdditionalDependencies>
<AdditionalDependencies>%(AdditionalDependencies);libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;shaderc_shared.lib;zlib.lib;zstd.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -16,6 +16,7 @@
<DepsDLLs Include="$(DepsBinDir)libwebp.dll" />
<DepsDLLs Include="$(DepsBinDir)lz4.dll" />
<DepsDLLs Include="$(DepsBinDir)SDL2.dll" />
<DepsDLLs Include="$(DepsBinDir)shaderc_shared.dll" />
<DepsDLLs Include="$(DepsBinDir)zlib1.dll" />
<DepsDLLs Include="$(DepsBinDir)zstd.dll" />
</ItemGroup>

View File

@ -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()

View File

@ -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 <cstring>
#include <fstream>
@ -30,6 +26,9 @@
std::unique_ptr<VKShaderCache> g_vulkan_shader_cache;
static std::unique_ptr<shaderc::Compiler> 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::SPIRVCodeVector> 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<shaderc::Compiler>();
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::SPIRVCodeVector> VKShaderCache::CompileShaderToSPV(
u32 stage, std::string_view source, bool debug)
{
if (!InitializeGlslang())
return std::nullopt;
std::unique_ptr<glslang::TShader> shader = std::make_unique<glslang::TShader>(static_cast<EShLanguage>(stage));
std::unique_ptr<glslang::TProgram> program;
glslang::TShader::ForbidIncluder includer;
const EProfile profile = ECoreProfile;
const EShMessages messages =
static_cast<EShMessages>(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<int>(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<shaderc_shader_kind>(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::SPIRVCodeVector> 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<glslang::TProgram>();
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<EShLanguage>(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::SPIRVCodeVector> VKShaderCache::CompileAndAddShaderSPV(

View File

@ -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;

View File

@ -51,7 +51,6 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\jpgd</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\ffmpeg\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\glad\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\glslang\glslang</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\vulkan-headers\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\d3d12memalloc\include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\lzma\include</AdditionalIncludeDirectories>
@ -822,9 +821,6 @@
<ProjectReference Include="..\3rdparty\discord-rpc\discord-rpc.vcxproj">
<Project>{e960dfdf-1bd3-4c29-b251-d1a0919c9b09}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\glslang\glslang.vcxproj">
<Project>{ef6834a9-11f3-4331-bc34-21b325abb180}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\libzip\libzip.vcxproj">
<Project>{20b2e9fe-f020-42a0-b324-956f5b06ea68}</Project>
</ProjectReference>