diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d5cb7..d3aed20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,12 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.c DEPENDS ${CMAKE_SOURCE_DIR}/patches/patches.bin ) +# Generate mm_shader_cache.c from the MM shader cache +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mm_shader_cache.c ${CMAKE_CURRENT_BINARY_DIR}/mm_shader_cache.h + COMMAND file_to_c ${CMAKE_SOURCE_DIR}/shadercache/mm_shader_cache.bin mm_shader_cache_bytes ${CMAKE_CURRENT_BINARY_DIR}/mm_shader_cache.c ${CMAKE_CURRENT_BINARY_DIR}/mm_shader_cache.h + DEPENDS ${CMAKE_SOURCE_DIR}/shadercache/mm_shader_cache.bin +) + # Recompile patches elf into patches.c add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches.c @@ -152,6 +158,8 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/rsp/njpgdspMain.cpp ${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp + + ${CMAKE_CURRENT_BINARY_DIR}/mm_shader_cache.c ) target_include_directories(Zelda64Recompiled PRIVATE @@ -169,6 +177,7 @@ target_include_directories(Zelda64Recompiled PRIVATE ${CMAKE_SOURCE_DIR}/lib/freetype-windows-binaries/include ${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/nativefiledialog-extended/src/include ${CMAKE_BINARY_DIR}/shaders + ${CMAKE_CURRENT_BINARY_DIR} ) target_compile_options(Zelda64Recompiled PRIVATE @@ -221,7 +230,6 @@ if (LINUX) COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png ) - target_include_directories(Zelda64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_sources(Zelda64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c) message(STATUS "X11_FOUND = ${X11_FOUND}") diff --git a/include/rt64_layer.h b/include/rt64_layer.h index a0bf2e3..1b38ed6 100644 --- a/include/rt64_layer.h +++ b/include/rt64_layer.h @@ -23,6 +23,7 @@ namespace ultramodern { void shutdown(); void set_dummy_vi(); uint32_t get_display_framerate(); + void load_shader_cache(std::span cache_binary); private: std::unique_ptr app; }; diff --git a/shadercache/mm_shader_cache.bin b/shadercache/mm_shader_cache.bin new file mode 100644 index 0000000..a89d81f Binary files /dev/null and b/shadercache/mm_shader_cache.bin differ diff --git a/src/recomp/recomp.cpp b/src/recomp/recomp.cpp index 0f049df..73230b3 100644 --- a/src/recomp/recomp.cpp +++ b/src/recomp/recomp.cpp @@ -16,6 +16,7 @@ #include "xxHash/xxh3.h" #include "../ultramodern/ultramodern.hpp" #include "../../RecompiledPatches/patches_bin.h" +#include "mm_shader_cache.h" #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { @@ -412,6 +413,7 @@ void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::a if (!recomp::load_stored_rom(recomp::Game::MM)) { recomp::message_box("Error opening stored ROM! Please restart this program."); } + ultramodern::load_shader_cache({mm_shader_cache_bytes, sizeof(mm_shader_cache_bytes)}); init(rdram, &context); try { recomp_entrypoint(rdram, &context); diff --git a/ultramodern/events.cpp b/ultramodern/events.cpp index 6ba64dd..7627462 100644 --- a/ultramodern/events.cpp +++ b/ultramodern/events.cpp @@ -31,7 +31,11 @@ struct SwapBuffersAction { struct UpdateConfigAction { }; -using Action = std::variant; +struct LoadShaderCacheAction { + std::span data; +}; + +using Action = std::variant; static struct { struct { @@ -293,6 +297,10 @@ uint32_t ultramodern::get_display_refresh_rate() { return display_refresh_rate.load(); } +void ultramodern::load_shader_cache(std::span cache_data) { + events_context.action_queue.enqueue(LoadShaderCacheAction{cache_data}); +} + void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready, ultramodern::WindowHandle window_handle) { bool enabled_instant_present = false; using namespace std::chrono_literals; @@ -352,6 +360,9 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re old_config = new_config; } } + else if (const auto* load_shader_cache_action = std::get_if(&action)) { + rt64.load_shader_cache(load_shader_cache_action->data); + } } } // TODO move recomp code out of ultramodern. diff --git a/ultramodern/rt64_layer.cpp b/ultramodern/rt64_layer.cpp index d70a3af..2e9e3d2 100644 --- a/ultramodern/rt64_layer.cpp +++ b/ultramodern/rt64_layer.cpp @@ -245,6 +245,16 @@ uint32_t ultramodern::RT64Context::get_display_framerate() { return app->presentQueue->ext.sharedResources->swapChainRate; } +void ultramodern::RT64Context::load_shader_cache(std::span cache_binary) { + // TODO figure out how to avoid a copy here. + std::istringstream cache_stream{std::string{cache_binary.data(), cache_binary.size()}}; + + if (!app->rasterShaderCache->loadOfflineList(cache_stream)) { + printf("Failed to preload shader cache!\n"); + assert(false); + } +} + RT64::UserConfiguration::Antialiasing ultramodern::RT64MaxMSAA() { return device_max_msaa; } diff --git a/ultramodern/ultramodern.hpp b/ultramodern/ultramodern.hpp index f125e6a..7fd0496 100644 --- a/ultramodern/ultramodern.hpp +++ b/ultramodern/ultramodern.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #undef MOODYCAMEL_DELETE_FUNCTION #define MOODYCAMEL_DELETE_FUNCTION = delete @@ -114,6 +115,7 @@ void sleep_until(const std::chrono::high_resolution_clock::time_point& time_poin void get_window_size(uint32_t& width, uint32_t& height); uint32_t get_target_framerate(uint32_t original); uint32_t get_display_refresh_rate(); +void load_shader_cache(std::span cache_data); // Audio void init_audio();