mirror of
https://github.com/stenzek/duckstation.git
synced 2026-07-08 17:46:19 +00:00
GPUDevice: Pack shaderc/spirv-cross function pointers together
This commit is contained in:
@@ -138,7 +138,7 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package(FFMPEG 8.1.0 COMPONENTS avcodec avformat avutil swresample swscale)
|
||||
find_package(FFMPEG 8.1.1 COMPONENTS avcodec avformat avutil swresample swscale)
|
||||
if(NOT FFMPEG_FOUND)
|
||||
message(WARNING "FFmpeg not found, using bundled headers.")
|
||||
endif()
|
||||
|
||||
@@ -378,3 +378,38 @@ function(add_resources TARGET DEST_SUBDIR SOURCE_DIR)
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(bundle_libraries TARGET)
|
||||
unset(LIBRARY_SOURCES)
|
||||
foreach(NAME IN LISTS ARGN)
|
||||
get_target_property(dyn_lib_path ${NAME} IMPORTED_LOCATION_RELEASE)
|
||||
get_target_property(dyn_lib_soname ${NAME} IMPORTED_SONAME_RELEASE)
|
||||
if(dyn_lib_soname)
|
||||
string(REPLACE "@rpath/" "" dyn_lib_soname_filename "${dyn_lib_soname}")
|
||||
get_filename_component(dyn_lib_dir "${dyn_lib_path}" DIRECTORY)
|
||||
set(dyn_lib_major_path "${dyn_lib_dir}/${dyn_lib_soname_filename}")
|
||||
if(EXISTS "${dyn_lib_major_path}")
|
||||
set(dyn_lib_path "${dyn_lib_major_path}")
|
||||
else()
|
||||
message(WARNING "Could not find major-versioned symlink for ${NAME}.")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find ${NAME}.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Bundling imported library ${dyn_lib_soname}")
|
||||
|
||||
if(APPLE)
|
||||
target_sources(${target} PRIVATE "${dyn_lib_path}")
|
||||
set_source_files_properties("${dyn_lib_path}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
else()
|
||||
list(APPEND LIBRARY_SOURCES "${dyn_lib_path}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT APPLE)
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBRARY_SOURCES} "$<TARGET_FILE_DIR:${TARGET}>"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -39,11 +39,8 @@ declare -a MANUAL_LIBS=(
|
||||
"libavutil.so.60"
|
||||
"libswscale.so.9"
|
||||
"libswresample.so.6"
|
||||
"libdiscord-rpc.so"
|
||||
"libharfbuzz.so"
|
||||
"libfreetype.so.6"
|
||||
"libshaderc_shared.so"
|
||||
"libspirv-cross-c-shared.so.0"
|
||||
)
|
||||
|
||||
set -e
|
||||
@@ -119,6 +116,7 @@ $LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/duckstat
|
||||
|
||||
echo "Copying resources into AppDir..."
|
||||
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
|
||||
cp "$BUILDDIR/bin/"*.so* "$OUTDIR/usr/bin"
|
||||
|
||||
# Restore unstripped deps (for cache).
|
||||
rm -fr "$DEPSDIR"
|
||||
|
||||
@@ -88,6 +88,26 @@ std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major,
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string DynamicLibrary::GetBundledLibraryPath(const char* libname, int major /*= -1*/, int minor /*= -1*/,
|
||||
int patch /*= -1*/)
|
||||
{
|
||||
Error error;
|
||||
std::string program_path = FileSystem::GetProgramPath(&error);
|
||||
if (program_path.empty()) [[unlikely]]
|
||||
{
|
||||
ERROR_LOG("Failed to get program path: {}", error.GetDescription());
|
||||
return {};
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
program_path = Path::Combine(Path::GetDirectory(program_path), ".." FS_OSPATH_SEPARATOR_STR "Frameworks");
|
||||
Path::Canonicalize(&program_path);
|
||||
return Path::Combine(program_path, GetVersionedFilename(libname, major, minor, patch));
|
||||
#else
|
||||
return Path::Combine(Path::GetDirectory(program_path), GetVersionedFilename(libname, major, minor, patch));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DynamicLibrary::Open(const char* filename, Error* error)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -179,7 +199,8 @@ bool DynamicLibrary::ResolveSymbols(const SymbolTable* symbols, size_t count, Er
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicLibrary::ResolveSymbols(const OptionalSymbolTable* symbols, size_t count, Error* error /* = nullptr */) const
|
||||
bool DynamicLibrary::ResolveSymbols(const OptionalSymbolTable* symbols, size_t count,
|
||||
Error* error /* = nullptr */) const
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
@@ -206,7 +227,8 @@ bool DynamicLibrary::ResolveSymbols(const std::span<const SymbolTable> symbols,
|
||||
return ResolveSymbols(symbols.data(), symbols.size(), error);
|
||||
}
|
||||
|
||||
bool DynamicLibrary::ResolveSymbols(const std::span<const OptionalSymbolTable> symbols, Error* error /*= nullptr*/) const
|
||||
bool DynamicLibrary::ResolveSymbols(const std::span<const OptionalSymbolTable> symbols,
|
||||
Error* error /*= nullptr*/) const
|
||||
{
|
||||
return ResolveSymbols(symbols.data(), symbols.size(), error);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ public:
|
||||
/// Mac: libLIBNAME.MAJOR.MINOR.PATCH.dylib
|
||||
static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1, int patch = -1);
|
||||
|
||||
/// Returns the path to the specified library name, depending on the platform.
|
||||
static std::string GetBundledLibraryPath(const char* libname, int major = -1, int minor = -1, int patch = -1);
|
||||
|
||||
/// Returns true if a module is loaded, otherwise false.
|
||||
bool IsOpen() const { return m_handle != nullptr; }
|
||||
|
||||
|
||||
@@ -215,10 +215,6 @@ function(add_core_resources target)
|
||||
|
||||
add_resources(${target} "resources" ${CMAKE_SOURCE_DIR}/data/resources)
|
||||
|
||||
if(APPLE)
|
||||
# Copy discord-rpc into the bundle
|
||||
get_target_property(DISCORD_RPC_LIBRARY DiscordRPC::discord-rpc IMPORTED_LOCATION_RELEASE)
|
||||
target_sources(${target} PRIVATE "${DISCORD_RPC_LIBRARY}")
|
||||
set_source_files_properties("${DISCORD_RPC_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
endif()
|
||||
# Copy dynamically-loaded libraries into the bundle.
|
||||
bundle_libraries(${target} DiscordRPC::discord-rpc)
|
||||
endfunction()
|
||||
|
||||
@@ -58,8 +58,7 @@ bool DiscordPresence::OpenDiscordRPC(Error* error)
|
||||
if (s_locals.rpc_library.IsOpen())
|
||||
return true;
|
||||
|
||||
const std::string libname = DynamicLibrary::GetVersionedFilename("discord-rpc");
|
||||
if (!s_locals.rpc_library.Open(libname.c_str(), error))
|
||||
if (!s_locals.rpc_library.Open(DynamicLibrary::GetBundledLibraryPath("discord-rpc").c_str(), error))
|
||||
{
|
||||
Error::AddPrefix(error, "Failed to load discord-rpc: ");
|
||||
return false;
|
||||
|
||||
@@ -90,7 +90,9 @@ add_library(util
|
||||
target_precompile_headers(util PRIVATE "pch.h")
|
||||
target_include_directories(util PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(util PUBLIC common imgui)
|
||||
target_link_libraries(util PRIVATE libchdr lzma libjpeg-turbo::jpeg PNG::PNG WebP::webp plutosvg::plutosvg ZLIB::ZLIB SoundTouch::SoundTouchDLL xxhash zstd::libzstd_shared reshadefx)
|
||||
target_link_libraries(util PRIVATE libchdr lzma libjpeg-turbo::jpeg PNG::png_shared WebP::webp
|
||||
plutosvg::plutosvg ZLIB::ZLIB SoundTouch::SoundTouchDLL xxhash
|
||||
zstd::libzstd_shared reshadefx)
|
||||
|
||||
if(ENABLE_X11)
|
||||
target_sources(util PRIVATE
|
||||
@@ -303,39 +305,18 @@ function(add_util_resources target)
|
||||
message(WARNING "MoltenVK not found in path, it will depend on the target system having it.")
|
||||
endif()
|
||||
|
||||
# Copy dynamically-loaded libraries (harfbuzz/shaderc/spirv-cross) into the bundle.
|
||||
# Use IMPORTED_SONAME_RELEASE to get the major-versioned filename (stripping the @rpath/ prefix).
|
||||
foreach(dyn_lib harfbuzz::harfbuzz spirv-cross-c-shared Shaderc::shaderc_shared)
|
||||
get_target_property(dyn_lib_path ${dyn_lib} IMPORTED_LOCATION_RELEASE)
|
||||
get_target_property(dyn_lib_soname ${dyn_lib} IMPORTED_SONAME_RELEASE)
|
||||
if(dyn_lib_soname)
|
||||
string(REPLACE "@rpath/" "" dyn_lib_soname_filename "${dyn_lib_soname}")
|
||||
get_filename_component(dyn_lib_dir "${dyn_lib_path}" DIRECTORY)
|
||||
set(dyn_lib_major_path "${dyn_lib_dir}/${dyn_lib_soname_filename}")
|
||||
if(EXISTS "${dyn_lib_major_path}")
|
||||
set(dyn_lib_path "${dyn_lib_major_path}")
|
||||
else()
|
||||
message(WARNING "Could not find major-versioned symlink for ${dyn_lib}.")
|
||||
endif()
|
||||
endif()
|
||||
target_sources(${target} PRIVATE "${dyn_lib_path}")
|
||||
set_source_files_properties("${dyn_lib_path}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
endforeach()
|
||||
|
||||
# Copy FFmpeg libraries into the bundle
|
||||
# Copy ffmpeg into the bundle.
|
||||
foreach(component avcodec avformat avutil swresample swscale)
|
||||
string(REGEX REPLACE "\([0-9]+\)\.[0-9]+\.[0-9]+" "\\1" major "${FFMPEG_${component}_VERSION}")
|
||||
string(REPLACE "lib${component}.dylib" "lib${component}.${major}.dylib" version_lib "${FFMPEG_${component}_LIBRARIES}")
|
||||
target_sources(${target} PRIVATE ${version_lib})
|
||||
set_source_files_properties(${target} PRIVATE ${version_lib} PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
endforeach()
|
||||
elseif(NOT WIN32)
|
||||
# We need to add the rpath for shaderc to the executable.
|
||||
get_target_property(SHADERC_LIBRARY Shaderc::shaderc_shared IMPORTED_LOCATION)
|
||||
get_filename_component(SHADERC_LIBRARY_DIRECTORY ${SHADERC_LIBRARY} DIRECTORY)
|
||||
set_target_properties(${target} PROPERTIES BUILD_RPATH "${SHADERC_LIBRARY_DIRECTORY}")
|
||||
get_target_property(SPIRV_CROSS_LIBRARY spirv-cross-c-shared IMPORTED_LOCATION)
|
||||
get_filename_component(SPIRV_CROSS_LIBRARY_DIRECTORY ${SPIRV_CROSS_LIBRARY} DIRECTORY)
|
||||
set_target_properties(${target} PROPERTIES BUILD_RPATH "${SPIRV_CROSS_LIBRARY_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
# Copy dynamically-loaded libraries (harfbuzz/shaderc/spirv-cross) into the bundle.
|
||||
bundle_libraries(${target} spirv-cross-c-shared Shaderc::shaderc_shared)
|
||||
if(APPLE)
|
||||
bundle_libraries(${target} harfbuzz::harfbuzz)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
X(shaderc_result_get_error_message) \
|
||||
X(shaderc_optimize_spv)
|
||||
|
||||
namespace dyn_libs {
|
||||
|
||||
extern bool OpenShaderc(Error* error);
|
||||
extern shaderc_compiler_t GetShadercCompiler();
|
||||
|
||||
#define ADD_FUNC(F) extern decltype(&::F) F;
|
||||
DYN_SHADERC_FUNCTIONS(ADD_FUNC)
|
||||
struct DynShaderc
|
||||
{
|
||||
#define ADD_FUNC(F) decltype(&::F) F;
|
||||
DYN_SHADERC_FUNCTIONS(ADD_FUNC)
|
||||
#undef ADD_FUNC
|
||||
|
||||
} // namespace dyn_libs
|
||||
shaderc_compiler_t compiler;
|
||||
|
||||
bool Open(Error* error);
|
||||
};
|
||||
|
||||
extern DynShaderc g_dyn_shaderc;
|
||||
|
||||
@@ -46,13 +46,15 @@ class Error;
|
||||
#define SPIRV_CROSS_MSL_FUNCTIONS(X)
|
||||
#endif
|
||||
|
||||
namespace dyn_libs {
|
||||
extern bool OpenSpirvCross(Error* error);
|
||||
|
||||
#define ADD_FUNC(F) extern decltype(&::F) F;
|
||||
SPIRV_CROSS_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(ADD_FUNC)
|
||||
struct DynSpirvCross
|
||||
{
|
||||
#define ADD_FUNC(F) decltype(&::F) F;
|
||||
SPIRV_CROSS_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(ADD_FUNC)
|
||||
#undef ADD_FUNC
|
||||
|
||||
} // namespace dyn_libs
|
||||
bool Open(Error* error);
|
||||
};
|
||||
|
||||
extern DynSpirvCross g_dyn_spirv_cross;
|
||||
|
||||
@@ -59,7 +59,6 @@ struct Locals
|
||||
// Dynamic libraries
|
||||
DynamicLibrary shaderc_library;
|
||||
DynamicLibrary spirv_cross_library;
|
||||
shaderc_compiler_t shaderc_compiler;
|
||||
std::once_flag shaderc_init_flag;
|
||||
std::once_flag spirv_cross_init_flag;
|
||||
};
|
||||
@@ -67,6 +66,11 @@ struct Locals
|
||||
|
||||
ALIGN_TO_CACHE_LINE static Locals s_locals;
|
||||
|
||||
static_assert(std::is_trivially_copyable_v<DynShaderc> && std::is_standard_layout_v<DynShaderc>);
|
||||
static_assert(std::is_trivially_copyable_v<DynSpirvCross> && std::is_standard_layout_v<DynSpirvCross>);
|
||||
DynShaderc g_dyn_shaderc;
|
||||
DynSpirvCross g_dyn_spirv_cross;
|
||||
|
||||
size_t GPUDevice::s_total_vram_usage = 0;
|
||||
GPUDevice::Statistics GPUDevice::s_stats = {};
|
||||
|
||||
@@ -1384,148 +1388,85 @@ std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
||||
}
|
||||
}
|
||||
|
||||
namespace dyn_libs {
|
||||
static void InitializeShaderc(Error* error);
|
||||
static void CloseShaderc();
|
||||
static void InitializeSpirvCross(Error* error);
|
||||
static void CloseSpirvCross();
|
||||
|
||||
// TODO: Merge all of these into a struct?
|
||||
#define ADD_FUNC(F) decltype(&::F) F;
|
||||
DYN_SHADERC_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(ADD_FUNC)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(ADD_FUNC)
|
||||
#undef ADD_FUNC
|
||||
|
||||
} // namespace dyn_libs
|
||||
|
||||
bool dyn_libs::OpenShaderc(Error* error)
|
||||
bool DynShaderc::Open(Error* error)
|
||||
{
|
||||
if (s_locals.shaderc_library.IsOpen())
|
||||
if (compiler)
|
||||
return true;
|
||||
|
||||
std::call_once(s_locals.shaderc_init_flag, [&error]() { InitializeShaderc(error); });
|
||||
return s_locals.shaderc_library.IsOpen();
|
||||
}
|
||||
std::call_once(s_locals.shaderc_init_flag, [&error]() {
|
||||
Error lerror;
|
||||
DynamicLibrary lib;
|
||||
if (!lib.Open(DynamicLibrary::GetBundledLibraryPath("shaderc_shared").c_str(), error))
|
||||
{
|
||||
ERROR_LOG("Failed to load shaderc: {}", (error ? error : &lerror)->GetDescription());
|
||||
Error::AddPrefix(error, "Failed to load shaderc: ");
|
||||
return;
|
||||
}
|
||||
|
||||
void dyn_libs::InitializeShaderc(Error* error)
|
||||
{
|
||||
Error lerror;
|
||||
DynamicLibrary lib;
|
||||
const std::string libname = DynamicLibrary::GetVersionedFilename("shaderc_shared");
|
||||
if (!lib.Open(libname.c_str(), error))
|
||||
{
|
||||
ERROR_LOG("Failed to load shaderc: {}", (error ? error : &lerror)->GetDescription());
|
||||
Error::AddPrefix(error, "Failed to load shaderc: ");
|
||||
return;
|
||||
}
|
||||
|
||||
static const DynamicLibrary::SymbolTable shaderc_symbols[] = {
|
||||
#define SHADERC_SYMBOL(F) {#F, (void**)&F},
|
||||
DYN_SHADERC_FUNCTIONS(SHADERC_SYMBOL)
|
||||
static const DynamicLibrary::SymbolTable shaderc_symbols[] = {
|
||||
#define SHADERC_SYMBOL(F) {#F, (void**)&g_dyn_shaderc.F},
|
||||
DYN_SHADERC_FUNCTIONS(SHADERC_SYMBOL)
|
||||
#undef SHADERC_SYMBOL
|
||||
};
|
||||
};
|
||||
|
||||
if (!lib.ResolveSymbols(shaderc_symbols, std::size(shaderc_symbols), error))
|
||||
{
|
||||
CloseShaderc();
|
||||
return;
|
||||
}
|
||||
if (!lib.ResolveSymbols(shaderc_symbols, error))
|
||||
return;
|
||||
|
||||
s_locals.shaderc_compiler = shaderc_compiler_initialize();
|
||||
if (!s_locals.shaderc_compiler)
|
||||
{
|
||||
ERROR_LOG("shaderc_compiler_initialize() failed");
|
||||
Error::SetStringView(error, "shaderc_compiler_initialize() failed");
|
||||
CloseShaderc();
|
||||
return;
|
||||
}
|
||||
g_dyn_shaderc.compiler = g_dyn_shaderc.shaderc_compiler_initialize();
|
||||
if (!g_dyn_shaderc.compiler)
|
||||
{
|
||||
ERROR_LOG("shaderc_compiler_initialize() failed");
|
||||
Error::SetStringView(error, "shaderc_compiler_initialize() failed");
|
||||
DynamicLibrary::ClearSymbols(shaderc_symbols);
|
||||
return;
|
||||
}
|
||||
|
||||
s_locals.shaderc_library = std::move(lib);
|
||||
s_locals.shaderc_library = std::move(lib);
|
||||
});
|
||||
|
||||
return (compiler != nullptr);
|
||||
}
|
||||
|
||||
shaderc_compiler_t dyn_libs::GetShadercCompiler()
|
||||
{
|
||||
return s_locals.shaderc_compiler;
|
||||
}
|
||||
|
||||
void dyn_libs::CloseShaderc()
|
||||
{
|
||||
if (s_locals.shaderc_compiler)
|
||||
{
|
||||
shaderc_compiler_release(s_locals.shaderc_compiler);
|
||||
s_locals.shaderc_compiler = nullptr;
|
||||
}
|
||||
|
||||
#define UNLOAD_FUNC(F) F = nullptr;
|
||||
DYN_SHADERC_FUNCTIONS(UNLOAD_FUNC)
|
||||
#undef UNLOAD_FUNC
|
||||
|
||||
s_locals.shaderc_library.Close();
|
||||
}
|
||||
|
||||
bool dyn_libs::OpenSpirvCross(Error* error)
|
||||
bool DynSpirvCross::Open(Error* error)
|
||||
{
|
||||
if (s_locals.spirv_cross_library.IsOpen())
|
||||
return true;
|
||||
|
||||
std::call_once(s_locals.spirv_cross_init_flag, [&error]() { InitializeSpirvCross(error); });
|
||||
return s_locals.spirv_cross_library.IsOpen();
|
||||
}
|
||||
|
||||
void dyn_libs::InitializeSpirvCross(Error* error)
|
||||
{
|
||||
Error lerror;
|
||||
DynamicLibrary lib;
|
||||
std::call_once(s_locals.spirv_cross_init_flag, [&error]() {
|
||||
Error lerror;
|
||||
DynamicLibrary lib;
|
||||
#if defined(_WIN32) || defined(__ANDROID__)
|
||||
// SPVC's build on Windows doesn't spit out a versioned DLL.
|
||||
const std::string libname = DynamicLibrary::GetVersionedFilename("spirv-cross-c-shared");
|
||||
// SPVC's build on Windows doesn't spit out a versioned DLL.
|
||||
const std::string libpath = DynamicLibrary::GetBundledLibraryPath("spirv-cross-c-shared");
|
||||
#else
|
||||
const std::string libname = DynamicLibrary::GetVersionedFilename("spirv-cross-c-shared", SPVC_C_API_VERSION_MAJOR);
|
||||
const std::string libpath = DynamicLibrary::GetBundledLibraryPath("spirv-cross-c-shared", SPVC_C_API_VERSION_MAJOR);
|
||||
#endif
|
||||
if (!lib.Open(libname.c_str(), error ? error : &lerror))
|
||||
{
|
||||
ERROR_LOG("Failed to load spirv-cross: {}", (error ? error : &lerror)->GetDescription());
|
||||
Error::AddPrefix(error, "Failed to load spirv-cross: ");
|
||||
return;
|
||||
}
|
||||
if (!lib.Open(libpath.c_str(), error ? error : &lerror))
|
||||
{
|
||||
ERROR_LOG("Failed to load spirv-cross: {}", (error ? error : &lerror)->GetDescription());
|
||||
Error::AddPrefix(error, "Failed to load spirv-cross: ");
|
||||
return;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
static const DynamicLibrary::SymbolTable spirv_cross_symbols[] = {
|
||||
#define SPIRV_CROSS_SYMBOL(F) {#F, (void**)&F},
|
||||
#define SPIRV_CROSS_SYMBOL(F) {#F, (void**)&g_dyn_spirv_cross.F},
|
||||
SPIRV_CROSS_FUNCTIONS(SPIRV_CROSS_SYMBOL)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(SPIRV_CROSS_SYMBOL)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(SPIRV_CROSS_SYMBOL)
|
||||
#undef SPIRV_CROSS_SYMBOL
|
||||
};
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
if (!lib.ResolveSymbols(spirv_cross_symbols, std::size(spirv_cross_symbols), error))
|
||||
{
|
||||
CloseShaderc();
|
||||
return;
|
||||
}
|
||||
if (!lib.ResolveSymbols(spirv_cross_symbols, std::size(spirv_cross_symbols), error))
|
||||
return;
|
||||
|
||||
s_locals.spirv_cross_library = std::move(lib);
|
||||
s_locals.spirv_cross_library = std::move(lib);
|
||||
});
|
||||
|
||||
return s_locals.spirv_cross_library.IsOpen();
|
||||
}
|
||||
|
||||
void dyn_libs::CloseSpirvCross()
|
||||
{
|
||||
#define UNLOAD_FUNC(F) F = nullptr;
|
||||
SPIRV_CROSS_FUNCTIONS(UNLOAD_FUNC)
|
||||
SPIRV_CROSS_HLSL_FUNCTIONS(UNLOAD_FUNC)
|
||||
SPIRV_CROSS_MSL_FUNCTIONS(UNLOAD_FUNC)
|
||||
#undef UNLOAD_FUNC
|
||||
|
||||
s_locals.spirv_cross_library.Close();
|
||||
}
|
||||
|
||||
#undef SPIRV_CROSS_HLSL_FUNCTIONS
|
||||
#undef SPIRV_CROSS_MSL_FUNCTIONS
|
||||
#undef SPIRV_CROSS_FUNCTIONS
|
||||
#undef DYN_SHADERC_FUNCTIONS
|
||||
|
||||
std::optional<DynamicHeapArray<u8>> GPUDevice::OptimizeVulkanSpv(const std::span<const u8> spirv, Error* error)
|
||||
{
|
||||
std::optional<DynamicHeapArray<u8>> ret;
|
||||
@@ -1552,34 +1493,35 @@ std::optional<DynamicHeapArray<u8>> GPUDevice::OptimizeVulkanSpv(const std::span
|
||||
else
|
||||
target_version = shaderc_env_version_vulkan_1_1;
|
||||
|
||||
if (!dyn_libs::OpenShaderc(error))
|
||||
if (!g_dyn_shaderc.Open(error))
|
||||
return ret;
|
||||
|
||||
const shaderc_compile_options_t options = dyn_libs::shaderc_compile_options_initialize();
|
||||
const shaderc_compile_options_t options = g_dyn_shaderc.shaderc_compile_options_initialize();
|
||||
AssertMsg(options, "shaderc_compile_options_initialize() failed");
|
||||
dyn_libs::shaderc_compile_options_set_target_env(options, target_env, target_version);
|
||||
dyn_libs::shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_target_env(options, target_env, target_version);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_performance);
|
||||
|
||||
const shaderc_compilation_result_t result =
|
||||
dyn_libs::shaderc_optimize_spv(s_locals.shaderc_compiler, spirv.data(), spirv.size(), options);
|
||||
g_dyn_shaderc.shaderc_optimize_spv(g_dyn_shaderc.compiler, spirv.data(), spirv.size(), options);
|
||||
const shaderc_compilation_status status =
|
||||
result ? dyn_libs::shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
result ? g_dyn_shaderc.shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
if (status != shaderc_compilation_status_success)
|
||||
{
|
||||
const std::string_view errors(result ? dyn_libs::shaderc_result_get_error_message(result) : "null result object");
|
||||
const std::string_view errors(result ? g_dyn_shaderc.shaderc_result_get_error_message(result) :
|
||||
"null result object");
|
||||
Error::SetStringFmt(error, "Failed to optimize SPIR-V: {}\n{}",
|
||||
dyn_libs::shaderc_compilation_status_to_string(status), errors);
|
||||
g_dyn_shaderc.shaderc_compilation_status_to_string(status), errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t spirv_size = dyn_libs::shaderc_result_get_length(result);
|
||||
const size_t spirv_size = g_dyn_shaderc.shaderc_result_get_length(result);
|
||||
DebugAssert(spirv_size > 0);
|
||||
ret = DynamicHeapArray<u8>(spirv_size);
|
||||
std::memcpy(ret->data(), dyn_libs::shaderc_result_get_bytes(result), spirv_size);
|
||||
std::memcpy(ret->data(), g_dyn_shaderc.shaderc_result_get_bytes(result), spirv_size);
|
||||
}
|
||||
|
||||
dyn_libs::shaderc_result_release(result);
|
||||
dyn_libs::shaderc_compile_options_release(options);
|
||||
g_dyn_shaderc.shaderc_result_release(result);
|
||||
g_dyn_shaderc.shaderc_compile_options_release(options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1602,47 +1544,48 @@ bool GPUDevice::CompileGLSLShaderToVulkanSpv(GPUShaderStage stage, GPUShaderLang
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dyn_libs::OpenShaderc(error))
|
||||
if (!g_dyn_shaderc.Open(error))
|
||||
return false;
|
||||
|
||||
const shaderc_compile_options_t options = dyn_libs::shaderc_compile_options_initialize();
|
||||
const shaderc_compile_options_t options = g_dyn_shaderc.shaderc_compile_options_initialize();
|
||||
AssertMsg(options, "shaderc_compile_options_initialize() failed");
|
||||
|
||||
dyn_libs::shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl);
|
||||
dyn_libs::shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0);
|
||||
dyn_libs::shaderc_compile_options_set_generate_debug_info(options, m_debug_device,
|
||||
m_debug_device && nonsemantic_debug_info);
|
||||
dyn_libs::shaderc_compile_options_set_optimization_level(
|
||||
g_dyn_shaderc.shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_generate_debug_info(options, m_debug_device,
|
||||
m_debug_device && nonsemantic_debug_info);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_optimization_level(
|
||||
options, optimization ? shaderc_optimization_level_performance : shaderc_optimization_level_zero);
|
||||
|
||||
const shaderc_compilation_result_t result =
|
||||
dyn_libs::shaderc_compile_into_spv(s_locals.shaderc_compiler, source.data(), source.length(),
|
||||
stage_kinds[static_cast<size_t>(stage)], "source", entry_point, options);
|
||||
g_dyn_shaderc.shaderc_compile_into_spv(g_dyn_shaderc.compiler, source.data(), source.length(),
|
||||
stage_kinds[static_cast<size_t>(stage)], "source", entry_point, options);
|
||||
const shaderc_compilation_status status =
|
||||
result ? dyn_libs::shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
result ? g_dyn_shaderc.shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
if (status != shaderc_compilation_status_success)
|
||||
{
|
||||
const std::string_view errors(result ? dyn_libs::shaderc_result_get_error_message(result) : "null result object");
|
||||
const std::string_view errors(result ? g_dyn_shaderc.shaderc_result_get_error_message(result) :
|
||||
"null result object");
|
||||
Error::SetStringFmt(error, "Failed to compile shader to SPIR-V: {}\n{}",
|
||||
dyn_libs::shaderc_compilation_status_to_string(status), errors);
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", dyn_libs::shaderc_compilation_status_to_string(status),
|
||||
g_dyn_shaderc.shaderc_compilation_status_to_string(status), errors);
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", g_dyn_shaderc.shaderc_compilation_status_to_string(status),
|
||||
errors);
|
||||
DumpBadShader(source, errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t num_warnings = dyn_libs::shaderc_result_get_num_warnings(result);
|
||||
const size_t num_warnings = g_dyn_shaderc.shaderc_result_get_num_warnings(result);
|
||||
if (num_warnings > 0)
|
||||
WARNING_LOG("Shader compiled with warnings:\n{}", dyn_libs::shaderc_result_get_error_message(result));
|
||||
WARNING_LOG("Shader compiled with warnings:\n{}", g_dyn_shaderc.shaderc_result_get_error_message(result));
|
||||
|
||||
const size_t spirv_size = dyn_libs::shaderc_result_get_length(result);
|
||||
const size_t spirv_size = g_dyn_shaderc.shaderc_result_get_length(result);
|
||||
DebugAssert(spirv_size > 0);
|
||||
out_binary->resize(spirv_size);
|
||||
std::memcpy(out_binary->data(), dyn_libs::shaderc_result_get_bytes(result), spirv_size);
|
||||
std::memcpy(out_binary->data(), g_dyn_shaderc.shaderc_result_get_bytes(result), spirv_size);
|
||||
}
|
||||
|
||||
dyn_libs::shaderc_result_release(result);
|
||||
dyn_libs::shaderc_compile_options_release(options);
|
||||
g_dyn_shaderc.shaderc_result_release(result);
|
||||
g_dyn_shaderc.shaderc_compile_options_release(options);
|
||||
return (status == shaderc_compilation_status_success);
|
||||
}
|
||||
|
||||
@@ -1650,20 +1593,20 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
GPUShaderLanguage target_language, u32 target_version, std::string* output,
|
||||
Error* error)
|
||||
{
|
||||
if (!dyn_libs::OpenSpirvCross(error))
|
||||
if (!g_dyn_spirv_cross.Open(error))
|
||||
return false;
|
||||
|
||||
spvc_context sctx;
|
||||
spvc_result sres;
|
||||
if ((sres = dyn_libs::spvc_context_create(&sctx)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_create(&sctx)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_create() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
const ScopedGuard sctx_guard = [&sctx]() { dyn_libs::spvc_context_destroy(sctx); };
|
||||
const ScopedGuard sctx_guard = [&sctx]() { g_dyn_spirv_cross.spvc_context_destroy(sctx); };
|
||||
|
||||
dyn_libs::spvc_context_set_error_callback(
|
||||
g_dyn_spirv_cross.spvc_context_set_error_callback(
|
||||
sctx,
|
||||
[](void* error, const char* errormsg) {
|
||||
ERROR_LOG("SPIRV-Cross reported an error: {}", errormsg);
|
||||
@@ -1672,8 +1615,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
error);
|
||||
|
||||
spvc_parsed_ir sir;
|
||||
if ((sres = dyn_libs::spvc_context_parse_spirv(sctx, reinterpret_cast<const u32*>(spirv.data()), spirv.size() / 4,
|
||||
&sir)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_parse_spirv(sctx, reinterpret_cast<const u32*>(spirv.data()),
|
||||
spirv.size() / 4, &sir)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_parse_spirv() failed: {}", static_cast<int>(sres));
|
||||
return {};
|
||||
@@ -1684,22 +1627,23 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
SPVC_BACKEND_NONE}};
|
||||
|
||||
spvc_compiler scompiler;
|
||||
if ((sres = dyn_libs::spvc_context_create_compiler(sctx, backends[static_cast<size_t>(target_language)], sir,
|
||||
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &scompiler)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_create_compiler(sctx, backends[static_cast<size_t>(target_language)], sir,
|
||||
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &scompiler)) !=
|
||||
SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_create_compiler() failed: {}", static_cast<int>(sres));
|
||||
return {};
|
||||
}
|
||||
|
||||
spvc_compiler_options soptions;
|
||||
if ((sres = dyn_libs::spvc_compiler_create_compiler_options(scompiler, &soptions)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_create_compiler_options(scompiler, &soptions)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_create_compiler_options() failed: {}", static_cast<int>(sres));
|
||||
return {};
|
||||
}
|
||||
|
||||
spvc_resources resources;
|
||||
if ((sres = dyn_libs::spvc_compiler_create_shader_resources(scompiler, &resources)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_create_shader_resources(scompiler, &resources)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_create_shader_resources() failed: {}", static_cast<int>(sres));
|
||||
return {};
|
||||
@@ -1708,20 +1652,20 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
// Need to know if there's UBOs for mapping.
|
||||
const spvc_reflected_resource *ubos, *push_constants, *textures, *images;
|
||||
size_t ubos_count, push_constants_count, textures_count, images_count;
|
||||
if ((sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &ubos,
|
||||
&ubos_count)) != SPVC_SUCCESS ||
|
||||
(sres = dyn_libs::spvc_resources_get_resource_list_for_type(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER,
|
||||
&ubos, &ubos_count)) != SPVC_SUCCESS ||
|
||||
(sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(
|
||||
resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &push_constants, &push_constants_count)) != SPVC_SUCCESS ||
|
||||
(sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE,
|
||||
&textures, &textures_count)) != SPVC_SUCCESS ||
|
||||
(sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_IMAGE, &images,
|
||||
&images_count)) != SPVC_SUCCESS)
|
||||
(sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(
|
||||
resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, &textures, &textures_count)) != SPVC_SUCCESS ||
|
||||
(sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_IMAGE,
|
||||
&images, &images_count)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_resources_get_resource_list_for_type() failed: {}", static_cast<int>(sres));
|
||||
return {};
|
||||
}
|
||||
|
||||
[[maybe_unused]] const SpvExecutionModel execmodel = dyn_libs::spvc_compiler_get_execution_model(scompiler);
|
||||
[[maybe_unused]] const SpvExecutionModel execmodel = g_dyn_spirv_cross.spvc_compiler_get_execution_model(scompiler);
|
||||
[[maybe_unused]] static constexpr u32 UBO_DESCRIPTOR_SET = 0;
|
||||
[[maybe_unused]] static constexpr u32 TEXTURE_DESCRIPTOR_SET = 1;
|
||||
[[maybe_unused]] static constexpr u32 IMAGE_DESCRIPTOR_SET = 2;
|
||||
@@ -1735,8 +1679,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
{
|
||||
const spvc_reflected_resource* inputs;
|
||||
size_t inputs_count;
|
||||
if ((sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STAGE_INPUT,
|
||||
&inputs, &inputs_count)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(
|
||||
resources, SPVC_RESOURCE_TYPE_STAGE_INPUT, &inputs, &inputs_count)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_resources_get_resource_list_for_type() for vertex attributes failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1745,10 +1689,12 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
|
||||
for (const spvc_reflected_resource& res : std::span<const spvc_reflected_resource>(inputs, inputs_count))
|
||||
{
|
||||
const unsigned location = dyn_libs::spvc_compiler_get_decoration(scompiler, res.id, SpvDecorationLocation);
|
||||
const unsigned location =
|
||||
g_dyn_spirv_cross.spvc_compiler_get_decoration(scompiler, res.id, SpvDecorationLocation);
|
||||
const TinyString name = TinyString::from_format("ATTR{}", location);
|
||||
const spvc_hlsl_vertex_attribute_remap va = {.location = location, .semantic = name.c_str()};
|
||||
if ((sres = dyn_libs::spvc_compiler_hlsl_add_vertex_attribute_remap(scompiler, &va, 1)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_hlsl_add_vertex_attribute_remap(scompiler, &va, 1)) !=
|
||||
SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_hlsl_add_vertex_attribute_remap() failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1757,15 +1703,15 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
}
|
||||
}
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL,
|
||||
target_version)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL,
|
||||
target_version)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_options_set_uint(SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL) failed: {}",
|
||||
static_cast<int>(sres));
|
||||
return {};
|
||||
}
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(
|
||||
soptions, SPVC_COMPILER_OPTION_HLSL_SUPPORT_NONZERO_BASE_VERTEX_BASE_INSTANCE, false)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error,
|
||||
@@ -1775,8 +1721,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
return {};
|
||||
}
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(soptions, SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT,
|
||||
true)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(
|
||||
soptions, SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT, true)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error,
|
||||
"spvc_compiler_options_set_bool(SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT) failed: {}",
|
||||
@@ -1793,7 +1739,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
.uav = {},
|
||||
.srv = {},
|
||||
.sampler = {}};
|
||||
if ((sres = dyn_libs::spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_hlsl_add_resource_binding() for UBO failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1810,7 +1756,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
.uav = {},
|
||||
.srv = {},
|
||||
.sampler = {}};
|
||||
if ((sres = dyn_libs::spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_hlsl_add_resource_binding() for push constant failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1822,7 +1768,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
{
|
||||
for (u32 i = 0; i < textures_count; i++)
|
||||
{
|
||||
const u32 binding = dyn_libs::spvc_compiler_get_decoration(scompiler, textures[i].id, SpvDecorationBinding);
|
||||
const u32 binding =
|
||||
g_dyn_spirv_cross.spvc_compiler_get_decoration(scompiler, textures[i].id, SpvDecorationBinding);
|
||||
|
||||
const spvc_hlsl_resource_binding rb = {.stage = execmodel,
|
||||
.desc_set = TEXTURE_DESCRIPTOR_SET,
|
||||
@@ -1831,7 +1778,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
.uav = {},
|
||||
.srv = {.register_space = 0, .register_binding = binding},
|
||||
.sampler = {.register_space = 0, .register_binding = binding}};
|
||||
if ((sres = dyn_libs::spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_hlsl_add_resource_binding() for texture failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1851,7 +1798,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
.uav = {.register_space = 0, .register_binding = i},
|
||||
.srv = {},
|
||||
.sampler = {}};
|
||||
if ((sres = dyn_libs::spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_hlsl_add_resource_binding(scompiler, &rb)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_hlsl_add_resource_binding() for image failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1867,8 +1814,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
case GPUShaderLanguage::GLSL:
|
||||
case GPUShaderLanguage::GLSLES:
|
||||
{
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_GLSL_VERSION,
|
||||
target_version)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_GLSL_VERSION,
|
||||
target_version)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_options_set_uint(SPVC_COMPILER_OPTION_GLSL_VERSION) failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1876,7 +1823,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
}
|
||||
|
||||
const bool is_gles = (target_language == GPUShaderLanguage::GLSLES);
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(soptions, SPVC_COMPILER_OPTION_GLSL_ES, is_gles)) !=
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(soptions, SPVC_COMPILER_OPTION_GLSL_ES, is_gles)) !=
|
||||
SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_options_set_bool(SPVC_COMPILER_OPTION_GLSL_ES) failed: {}",
|
||||
@@ -1885,8 +1832,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
}
|
||||
|
||||
const bool enable_420pack = (is_gles ? (target_version >= 310) : (target_version >= 420));
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(soptions, SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION,
|
||||
enable_420pack)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(
|
||||
soptions, SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION, enable_420pack)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(
|
||||
error, "spvc_compiler_options_set_bool(SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION) failed: {}",
|
||||
@@ -1897,16 +1844,16 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
if (ubos_count > 0)
|
||||
{
|
||||
// Set name of UBO block to match our shaders, so that drivers without binding info can still find it.
|
||||
dyn_libs::spvc_compiler_set_name(scompiler, ubos[0].id, "UBOBlock");
|
||||
g_dyn_spirv_cross.spvc_compiler_set_name(scompiler, ubos[0].id, "UBOBlock");
|
||||
}
|
||||
|
||||
if (push_constants_count > 0)
|
||||
{
|
||||
// Set name of push constant block to match our shaders, so that drivers without binding info can still find it.
|
||||
dyn_libs::spvc_compiler_set_name(scompiler, push_constants[0].id, "PushConstants");
|
||||
dyn_libs::spvc_compiler_set_decoration(scompiler, push_constants[0].id, SpvDecorationBinding, 1);
|
||||
g_dyn_spirv_cross.spvc_compiler_set_name(scompiler, push_constants[0].id, "PushConstants");
|
||||
g_dyn_spirv_cross.spvc_compiler_set_decoration(scompiler, push_constants[0].id, SpvDecorationBinding, 1);
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(
|
||||
soptions, SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER, SPVC_TRUE)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(
|
||||
@@ -1923,7 +1870,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
#ifdef __APPLE__
|
||||
case GPUShaderLanguage::MSL:
|
||||
{
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(
|
||||
soptions, SPVC_COMPILER_OPTION_MSL_PAD_FRAGMENT_OUTPUT_COMPONENTS, true)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(
|
||||
@@ -1932,8 +1879,9 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
return {};
|
||||
}
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_options_set_bool(soptions, SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS,
|
||||
m_features.framebuffer_fetch)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_options_set_bool(soptions,
|
||||
SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS,
|
||||
m_features.framebuffer_fetch)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(
|
||||
error, "spvc_compiler_options_set_bool(SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS) failed: {}",
|
||||
@@ -1942,8 +1890,8 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
}
|
||||
|
||||
if (m_features.framebuffer_fetch &&
|
||||
((sres = dyn_libs::spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_MSL_VERSION,
|
||||
target_version)) != SPVC_SUCCESS))
|
||||
((sres = g_dyn_spirv_cross.spvc_compiler_options_set_uint(soptions, SPVC_COMPILER_OPTION_MSL_VERSION,
|
||||
target_version)) != SPVC_SUCCESS))
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_options_set_uint(SPVC_COMPILER_OPTION_MSL_VERSION) failed: {}",
|
||||
static_cast<int>(sres));
|
||||
@@ -1960,7 +1908,7 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
.msl_texture = msl_texture,
|
||||
.msl_sampler = msl_sampler};
|
||||
|
||||
const spvc_result sres = dyn_libs::spvc_compiler_msl_add_resource_binding(scompiler, &rb);
|
||||
const spvc_result sres = g_dyn_spirv_cross.spvc_compiler_msl_add_resource_binding(scompiler, &rb);
|
||||
if (sres != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_msl_add_resource_binding() failed: {}", static_cast<int>(sres));
|
||||
@@ -2007,14 +1955,14 @@ bool GPUDevice::TranslateVulkanSpvToLanguage(const std::span<const u8> spirv, GP
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sres = dyn_libs::spvc_compiler_install_compiler_options(scompiler, soptions)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_install_compiler_options(scompiler, soptions)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_install_compiler_options() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* out_src;
|
||||
if ((sres = dyn_libs::spvc_compiler_compile(scompiler, &out_src)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_compile(scompiler, &out_src)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_compile() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
@@ -2105,8 +2053,13 @@ void GPUDevice::UnloadDynamicLibraries()
|
||||
{
|
||||
Assert(!g_gpu_device);
|
||||
|
||||
dyn_libs::CloseSpirvCross();
|
||||
dyn_libs::CloseShaderc();
|
||||
g_dyn_spirv_cross = {};
|
||||
s_locals.spirv_cross_library.Close();
|
||||
|
||||
if (g_dyn_shaderc.compiler)
|
||||
g_dyn_shaderc.shaderc_compiler_release(g_dyn_shaderc.compiler);
|
||||
g_dyn_shaderc = {};
|
||||
s_locals.shaderc_library.Close();
|
||||
|
||||
#ifdef ENABLE_VULKAN
|
||||
VulkanLoader::DestroyVulkanInstance();
|
||||
|
||||
@@ -1219,46 +1219,47 @@ bool PostProcessing::SlangShader::ParsePresetPass(std::string_view preset_path,
|
||||
static std::optional<DynamicHeapArray<u32>> CompileToSPV(shaderc_shader_kind stage, std::string_view code, Error* error)
|
||||
{
|
||||
std::optional<DynamicHeapArray<u32>> ret;
|
||||
if (!dyn_libs::OpenShaderc(error))
|
||||
if (!g_dyn_shaderc.Open(error))
|
||||
return ret;
|
||||
|
||||
const bool generate_debug_info = (g_gpu_device && g_gpu_device->IsDebugDevice());
|
||||
const shaderc_compile_options_t options = dyn_libs::shaderc_compile_options_initialize();
|
||||
const shaderc_compile_options_t options = g_dyn_shaderc.shaderc_compile_options_initialize();
|
||||
AssertMsg(options, "shaderc_compile_options_initialize() failed");
|
||||
|
||||
dyn_libs::shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl);
|
||||
dyn_libs::shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0);
|
||||
dyn_libs::shaderc_compile_options_set_generate_debug_info(options, generate_debug_info, false);
|
||||
dyn_libs::shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_zero);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_source_language(options, shaderc_source_language_glsl);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_target_env(options, shaderc_target_env_vulkan, 0);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_generate_debug_info(options, generate_debug_info, false);
|
||||
g_dyn_shaderc.shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_zero);
|
||||
|
||||
const shaderc_compilation_result_t result = dyn_libs::shaderc_compile_into_spv(
|
||||
dyn_libs::GetShadercCompiler(), code.data(), code.length(), stage, "source", "main", options);
|
||||
const shaderc_compilation_result_t result = g_dyn_shaderc.shaderc_compile_into_spv(
|
||||
g_dyn_shaderc.compiler, code.data(), code.length(), stage, "source", "main", options);
|
||||
const shaderc_compilation_status status =
|
||||
result ? dyn_libs::shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
result ? g_dyn_shaderc.shaderc_result_get_compilation_status(result) : shaderc_compilation_status_internal_error;
|
||||
if (status != shaderc_compilation_status_success)
|
||||
{
|
||||
const std::string_view errors(result ? dyn_libs::shaderc_result_get_error_message(result) : "null result object");
|
||||
const std::string_view errors(result ? g_dyn_shaderc.shaderc_result_get_error_message(result) :
|
||||
"null result object");
|
||||
Error::SetStringFmt(error, "Failed to compile shader to SPIR-V: {}\n{}",
|
||||
dyn_libs::shaderc_compilation_status_to_string(status), errors);
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", dyn_libs::shaderc_compilation_status_to_string(status),
|
||||
g_dyn_shaderc.shaderc_compilation_status_to_string(status), errors);
|
||||
ERROR_LOG("Failed to compile shader to SPIR-V: {}\n{}", g_dyn_shaderc.shaderc_compilation_status_to_string(status),
|
||||
errors);
|
||||
GPUDevice::DumpBadShader(code, errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t num_warnings = dyn_libs::shaderc_result_get_num_warnings(result);
|
||||
const size_t num_warnings = g_dyn_shaderc.shaderc_result_get_num_warnings(result);
|
||||
if (num_warnings > 0)
|
||||
WARNING_LOG("Shader compiled with warnings:\n{}", dyn_libs::shaderc_result_get_error_message(result));
|
||||
WARNING_LOG("Shader compiled with warnings:\n{}", g_dyn_shaderc.shaderc_result_get_error_message(result));
|
||||
|
||||
const size_t spirv_size = dyn_libs::shaderc_result_get_length(result);
|
||||
const size_t spirv_size = g_dyn_shaderc.shaderc_result_get_length(result);
|
||||
Assert(spirv_size > 0 && (spirv_size % sizeof(u32)) == 0);
|
||||
ret.emplace();
|
||||
ret->resize(spirv_size / sizeof(u32));
|
||||
std::memcpy(ret->data(), dyn_libs::shaderc_result_get_bytes(result), spirv_size);
|
||||
std::memcpy(ret->data(), g_dyn_shaderc.shaderc_result_get_bytes(result), spirv_size);
|
||||
}
|
||||
|
||||
dyn_libs::shaderc_result_release(result);
|
||||
dyn_libs::shaderc_compile_options_release(options);
|
||||
g_dyn_shaderc.shaderc_result_release(result);
|
||||
g_dyn_shaderc.shaderc_compile_options_release(options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1284,20 +1285,20 @@ bool PostProcessing::SlangShader::ReflectPass(Pass& pass, Error* error)
|
||||
|
||||
bool PostProcessing::SlangShader::ReflectShader(Pass& pass, std::span<u32> spv, GPUShaderStage stage, Error* error)
|
||||
{
|
||||
if (!dyn_libs::OpenSpirvCross(error))
|
||||
if (!g_dyn_spirv_cross.Open(error))
|
||||
return false;
|
||||
|
||||
spvc_context sctx;
|
||||
spvc_result sres;
|
||||
if ((sres = dyn_libs::spvc_context_create(&sctx)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_create(&sctx)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_create() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
const ScopedGuard sctx_guard = [&sctx]() { dyn_libs::spvc_context_destroy(sctx); };
|
||||
const ScopedGuard sctx_guard = [&sctx]() { g_dyn_spirv_cross.spvc_context_destroy(sctx); };
|
||||
|
||||
dyn_libs::spvc_context_set_error_callback(
|
||||
g_dyn_spirv_cross.spvc_context_set_error_callback(
|
||||
sctx,
|
||||
[](void* error, const char* errormsg) {
|
||||
ERROR_LOG("SPIRV-Cross reported an error: {}", errormsg);
|
||||
@@ -1306,30 +1307,31 @@ bool PostProcessing::SlangShader::ReflectShader(Pass& pass, std::span<u32> spv,
|
||||
error);
|
||||
|
||||
spvc_parsed_ir sir;
|
||||
if ((sres = dyn_libs::spvc_context_parse_spirv(sctx, reinterpret_cast<const u32*>(spv.data()), spv.size(), &sir)) !=
|
||||
SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_parse_spirv(sctx, reinterpret_cast<const u32*>(spv.data()), spv.size(),
|
||||
&sir)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_parse_spirv() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
spvc_compiler scompiler;
|
||||
if ((sres = dyn_libs::spvc_context_create_compiler(sctx, SPVC_BACKEND_NONE /*SPVC_BACKEND_GLSL*/, sir,
|
||||
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &scompiler)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_context_create_compiler(sctx, SPVC_BACKEND_NONE /*SPVC_BACKEND_GLSL*/, sir,
|
||||
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &scompiler)) !=
|
||||
SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_context_create_compiler() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
spvc_compiler_options soptions;
|
||||
if ((sres = dyn_libs::spvc_compiler_create_compiler_options(scompiler, &soptions)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_create_compiler_options(scompiler, &soptions)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_create_compiler_options() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
}
|
||||
|
||||
spvc_resources resources;
|
||||
if ((sres = dyn_libs::spvc_compiler_create_shader_resources(scompiler, &resources)) != SPVC_SUCCESS)
|
||||
if ((sres = g_dyn_spirv_cross.spvc_compiler_create_shader_resources(scompiler, &resources)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_create_shader_resources() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
@@ -1338,12 +1340,12 @@ bool PostProcessing::SlangShader::ReflectShader(Pass& pass, std::span<u32> spv,
|
||||
// Need to know if there's UBOs for mapping.
|
||||
const spvc_reflected_resource *ubos, *push_constants, *textures;
|
||||
size_t ubos_count, push_constants_count, textures_count;
|
||||
if ((sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &ubos,
|
||||
&ubos_count)) != SPVC_SUCCESS ||
|
||||
(sres = dyn_libs::spvc_resources_get_resource_list_for_type(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER,
|
||||
&ubos, &ubos_count)) != SPVC_SUCCESS ||
|
||||
(sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(
|
||||
resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &push_constants, &push_constants_count)) != SPVC_SUCCESS ||
|
||||
(sres = dyn_libs::spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE,
|
||||
&textures, &textures_count)) != SPVC_SUCCESS)
|
||||
(sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE,
|
||||
&textures, &textures_count)) != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_resources_get_resource_list_for_type() failed: {}", static_cast<int>(sres));
|
||||
return false;
|
||||
@@ -1351,15 +1353,16 @@ bool PostProcessing::SlangShader::ReflectShader(Pass& pass, std::span<u32> spv,
|
||||
|
||||
// Try to only allocate active textures.
|
||||
std::optional<std::span<const spvc_reflected_resource>> active_textures;
|
||||
if (spvc_set active_interface_variables; (sres = dyn_libs::spvc_compiler_get_active_interface_variables(
|
||||
if (spvc_set active_interface_variables; (sres = g_dyn_spirv_cross.spvc_compiler_get_active_interface_variables(
|
||||
scompiler, &active_interface_variables)) == SPVC_SUCCESS)
|
||||
{
|
||||
if (spvc_resources active_resources; (sres = dyn_libs::spvc_compiler_create_shader_resources_for_active_variables(
|
||||
scompiler, &active_resources, active_interface_variables)) == SPVC_SUCCESS)
|
||||
if (spvc_resources active_resources;
|
||||
(sres = g_dyn_spirv_cross.spvc_compiler_create_shader_resources_for_active_variables(
|
||||
scompiler, &active_resources, active_interface_variables)) == SPVC_SUCCESS)
|
||||
{
|
||||
const spvc_reflected_resource* active_textures_begin;
|
||||
size_t active_textures_count;
|
||||
if ((sres = dyn_libs::spvc_resources_get_resource_list_for_type(
|
||||
if ((sres = g_dyn_spirv_cross.spvc_resources_get_resource_list_for_type(
|
||||
active_resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, &active_textures_begin, &active_textures_count)) ==
|
||||
SPVC_SUCCESS)
|
||||
{
|
||||
@@ -1419,8 +1422,9 @@ bool PostProcessing::SlangShader::ReflectShader(Pass& pass, std::span<u32> spv,
|
||||
}
|
||||
|
||||
const unsigned orig_descriptor_set =
|
||||
dyn_libs::spvc_compiler_get_decoration(scompiler, tex.id, SpvDecorationDescriptorSet);
|
||||
const unsigned orig_binding = dyn_libs::spvc_compiler_get_decoration(scompiler, tex.id, SpvDecorationBinding);
|
||||
g_dyn_spirv_cross.spvc_compiler_get_decoration(scompiler, tex.id, SpvDecorationDescriptorSet);
|
||||
const unsigned orig_binding =
|
||||
g_dyn_spirv_cross.spvc_compiler_get_decoration(scompiler, tex.id, SpvDecorationBinding);
|
||||
if (orig_descriptor_set != 0)
|
||||
{
|
||||
Error::SetStringFmt(error, "Texture '{}' is in descriptor set {}, only set 0 is supported", tex.name,
|
||||
@@ -1507,7 +1511,7 @@ bool PostProcessing::SlangShader::ReflectPassUniforms(const spvc_compiler& scomp
|
||||
const spvc_reflected_resource& resource, Pass& pass,
|
||||
bool push_constant, Error* error)
|
||||
{
|
||||
const spvc_type type_handle = dyn_libs::spvc_compiler_get_type_handle(scompiler, resource.base_type_id);
|
||||
const spvc_type type_handle = g_dyn_spirv_cross.spvc_compiler_get_type_handle(scompiler, resource.base_type_id);
|
||||
if (!type_handle)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_get_type_handle() failed for resource '{}'", resource.name);
|
||||
@@ -1515,7 +1519,8 @@ bool PostProcessing::SlangShader::ReflectPassUniforms(const spvc_compiler& scomp
|
||||
}
|
||||
|
||||
size_t struct_size = 0;
|
||||
if (const spvc_result sres = dyn_libs::spvc_compiler_get_declared_struct_size(scompiler, type_handle, &struct_size);
|
||||
if (const spvc_result sres =
|
||||
g_dyn_spirv_cross.spvc_compiler_get_declared_struct_size(scompiler, type_handle, &struct_size);
|
||||
sres != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_get_declared_struct_size() failed for resource '{}': {}", resource.name,
|
||||
@@ -1545,16 +1550,17 @@ bool PostProcessing::SlangShader::ReflectPassUniforms(const spvc_compiler& scomp
|
||||
|
||||
for (unsigned member_idx = 0;; member_idx++)
|
||||
{
|
||||
const char* member_name = dyn_libs::spvc_compiler_get_member_name(scompiler, resource.base_type_id, member_idx);
|
||||
const char* member_name =
|
||||
g_dyn_spirv_cross.spvc_compiler_get_member_name(scompiler, resource.base_type_id, member_idx);
|
||||
if (!member_name || member_name[0] == '\0')
|
||||
break;
|
||||
|
||||
const u32 offset =
|
||||
dyn_libs::spvc_compiler_get_member_decoration(scompiler, resource.base_type_id, member_idx, SpvDecorationOffset);
|
||||
const u32 offset = g_dyn_spirv_cross.spvc_compiler_get_member_decoration(scompiler, resource.base_type_id,
|
||||
member_idx, SpvDecorationOffset);
|
||||
|
||||
size_t member_size = 0;
|
||||
if (const spvc_result sres =
|
||||
dyn_libs::spvc_compiler_get_declared_struct_member_size(scompiler, type_handle, member_idx, &member_size);
|
||||
if (const spvc_result sres = g_dyn_spirv_cross.spvc_compiler_get_declared_struct_member_size(
|
||||
scompiler, type_handle, member_idx, &member_size);
|
||||
sres != SPVC_SUCCESS)
|
||||
{
|
||||
Error::SetStringFmt(error, "spvc_compiler_get_declared_struct_member_size() failed for member '{}' of '{}': {}",
|
||||
|
||||
Reference in New Issue
Block a user