Embed shader cache to the executable.

This commit is contained in:
Skyth 2024-10-20 00:53:16 +03:00
parent 99906bfddc
commit 018b32062e
9 changed files with 56 additions and 45 deletions

View file

@ -104,6 +104,7 @@ find_package(xxHash CONFIG REQUIRED)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(tomlplusplus REQUIRED IMPORTED_TARGET tomlplusplus) pkg_check_modules(tomlplusplus REQUIRED IMPORTED_TARGET tomlplusplus)
find_package(directx-dxc REQUIRED) find_package(directx-dxc REQUIRED)
find_package(zstd CONFIG REQUIRED)
target_link_libraries(UnleashedRecomp PRIVATE target_link_libraries(UnleashedRecomp PRIVATE
comctl32 comctl32
@ -123,6 +124,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
winmm winmm
xxHash::xxhash xxHash::xxhash
PkgConfig::tomlplusplus PkgConfig::tomlplusplus
zstd::libzstd_static
) )
target_include_directories(UnleashedRecomp PRIVATE target_include_directories(UnleashedRecomp PRIVATE

View file

@ -6,6 +6,7 @@
#include <cpu/guest_code.h> #include <cpu/guest_code.h>
#include <kernel/memory.h> #include <kernel/memory.h>
#include <xxHashMap.h> #include <xxHashMap.h>
#include <shader/shader_cache.h>
#include "video.h" #include "video.h"
#include "ui/window.h" #include "ui/window.h"
@ -290,42 +291,17 @@ static void FlushBarriers()
} }
} }
struct ShaderCacheHeader
{
uint32_t version;
uint32_t shaderCount;
uint32_t reserved0;
uint32_t reserved1;
};
struct ShaderCacheEntry
{
XXH64_hash_t hash;
uint32_t dxilOffset;
uint32_t dxilSize;
uint32_t spirvOffset;
uint32_t spirvSize;
GuestShader* shader = nullptr;
};
static std::unique_ptr<uint8_t[]> g_shaderCache; static std::unique_ptr<uint8_t[]> g_shaderCache;
static void LoadShaderCache() static void LoadShaderCache()
{ {
FILE* file = fopen("ShaderCache.bin", "rb"); const size_t decompressedSize = g_vulkan ? g_spirvCacheDecompressedSize : g_dxilCacheDecompressedSize;
if (file) g_shaderCache = std::make_unique<uint8_t[]>(decompressedSize);
{
fseek(file, 0, SEEK_END); ZSTD_decompress(g_shaderCache.get(),
long fileSize = ftell(file); decompressedSize,
fseek(file, 0, SEEK_SET); g_vulkan ? g_compressedSpirvCache : g_compressedDxilCache,
g_shaderCache = std::make_unique<uint8_t[]>(fileSize); g_vulkan ? g_spirvCacheCompressedSize : g_dxilCacheCompressedSize);
fread(g_shaderCache.get(), 1, fileSize, file);
fclose(file);
}
else
{
MessageBox(nullptr, TEXT("Unable to locate ShaderCache.bin in root directory."), TEXT("SWA"), MB_ICONERROR);
}
} }
static void SetRenderState(GuestDevice* device, uint32_t value) static void SetRenderState(GuestDevice* device, uint32_t value)
@ -2082,10 +2058,8 @@ static GuestShader* CreateShader(const be<uint32_t>* function, ResourceType reso
{ {
XXH64_hash_t hash = XXH3_64bits(function, function[1] + function[2]); XXH64_hash_t hash = XXH3_64bits(function, function[1] + function[2]);
auto shaderCache = reinterpret_cast<ShaderCacheHeader*>(g_shaderCache.get()); auto end = g_shaderCacheEntries + g_shaderCacheEntryCount;
auto begin = reinterpret_cast<ShaderCacheEntry*>(shaderCache + 1); auto findResult = std::lower_bound(g_shaderCacheEntries, end, hash, [](ShaderCacheEntry& lhs, XXH64_hash_t rhs)
auto end = begin + shaderCache->shaderCount;
auto findResult = std::lower_bound(begin, end, hash, [](ShaderCacheEntry& lhs, XXH64_hash_t rhs)
{ {
return lhs.hash < rhs; return lhs.hash < rhs;
}); });
@ -2094,7 +2068,7 @@ static GuestShader* CreateShader(const be<uint32_t>* function, ResourceType reso
if (findResult != end && findResult->hash == hash) if (findResult != end && findResult->hash == hash)
{ {
if (findResult->shader == nullptr) if (findResult->userData == nullptr)
{ {
shader = g_userHeap.AllocPhysical<GuestShader>(resourceType); shader = g_userHeap.AllocPhysical<GuestShader>(resourceType);
@ -2103,11 +2077,11 @@ static GuestShader* CreateShader(const be<uint32_t>* function, ResourceType reso
else else
shader->shader = g_device->createShader(g_shaderCache.get() + findResult->dxilOffset, findResult->dxilSize, "main", RenderShaderFormat::DXIL); shader->shader = g_device->createShader(g_shaderCache.get() + findResult->dxilOffset, findResult->dxilSize, "main", RenderShaderFormat::DXIL);
findResult->shader = shader; findResult->userData = shader;
} }
else else
{ {
shader = findResult->shader; shader = reinterpret_cast<GuestShader*>(findResult->userData);
} }
} }

View file

@ -13,6 +13,7 @@
#include <ddspp.h> #include <ddspp.h>
#include <ppc/ppc_recomp_shared.h> #include <ppc/ppc_recomp_shared.h>
#include <toml++/toml.hpp> #include <toml++/toml.hpp>
#include <zstd.h>
#include "framework.h" #include "framework.h"
#include "mutex.h" #include "mutex.h"

View file

@ -5,10 +5,17 @@ add_compile_options(
"-march=sandybridge" "-march=sandybridge"
"-fno-strict-aliasing") "-fno-strict-aliasing")
file(GLOB SWA_RECOMPILED_SOURCES "ppc/*.cpp") file(GLOB SWA_PPC_RECOMPILED_SOURCES "ppc/*.cpp")
add_library(UnleashedRecompLib "main.cpp" ${SWA_RECOMPILED_SOURCES}) file(GLOB SWA_SHADER_RECOMPILED_SOURCES "shader/*.cpp")
add_library(UnleashedRecompLib "main.cpp" ${SWA_PPC_RECOMPILED_SOURCES} "shader/shader_cache.h" ${SWA_SHADER_RECOMPILED_SOURCES})
target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_precompile_headers(UnleashedRecompLib PUBLIC ppc/ppc_recomp_shared.h) target_precompile_headers(UnleashedRecompLib PUBLIC ppc/ppc_recomp_shared.h)
target_compile_definitions(PowerRecomp PRIVATE CONFIG_FILE_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml\")
target_compile_definitions(PowerRecomp PRIVATE
CONFIG_FILE_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml\")
target_compile_definitions(ShaderRecomp PRIVATE
SHADER_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"
SHADER_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\")

3
UnleashedRecompLib/shader/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*
!shader_cache.h
!.gitignore

View file

@ -0,0 +1,22 @@
#pragma once
struct ShaderCacheEntry
{
uint64_t hash;
uint32_t dxilOffset;
uint32_t dxilSize;
uint32_t spirvOffset;
uint32_t spirvSize;
void* userData;
};
extern ShaderCacheEntry g_shaderCacheEntries[];
extern size_t g_shaderCacheEntryCount;
extern uint8_t g_compressedDxilCache[];
extern size_t g_dxilCacheCompressedSize;
extern size_t g_dxilCacheDecompressedSize;
extern uint8_t g_compressedSpirvCache[];
extern size_t g_spirvCacheCompressedSize;
extern size_t g_spirvCacheDecompressedSize;

View file

@ -1,2 +1,3 @@
add_subdirectory(${SWA_THIRDPARTY_ROOT}/PowerRecomp) add_subdirectory(${SWA_THIRDPARTY_ROOT}/PowerRecomp)
add_subdirectory(${SWA_THIRDPARTY_ROOT}/ShaderRecomp)
add_subdirectory(${SWA_THIRDPARTY_ROOT}/o1heap) add_subdirectory(${SWA_THIRDPARTY_ROOT}/o1heap)

@ -1 +1 @@
Subproject commit 9da6b59ce51c5becc919c2f1aed7c5e5f3b86f31 Subproject commit b15214270923fa9d73dd59d5a27170acdcb8d689

View file

@ -10,6 +10,7 @@
"vulkan-memory-allocator", "vulkan-memory-allocator",
"xxhash", "xxhash",
"pkgconf", "pkgconf",
"tomlplusplus" "tomlplusplus",
"zstd"
] ]
} }