From 5bd4fc2958e8337694b414625c41e378e918467f Mon Sep 17 00:00:00 2001 From: Angie Date: Fri, 31 May 2024 16:06:28 -0400 Subject: [PATCH] Remove rt64 --- .gitmodules | 3 ++ README.md | 8 ++-- librecomp/CMakeLists.txt | 5 +- rt64 | 1 - thirdparty/xxHash | 1 + ultramodern/CMakeLists.txt | 12 +---- .../include/ultramodern/renderer_wrapper.hpp | 2 + ultramodern/src/events.cpp | 46 ++++++++----------- ultramodern/src/renderer_wrapper.cpp | 12 ++++- 9 files changed, 42 insertions(+), 48 deletions(-) delete mode 160000 rt64 create mode 160000 thirdparty/xxHash diff --git a/.gitmodules b/.gitmodules index e69de29..3bed9da 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "thirdparty/xxHash"] + path = thirdparty/xxHash + url = git@github.com:Cyan4973/xxHash.git diff --git a/README.md b/README.md index cab8b4b..7f2200d 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,10 @@ This repo is a WIP as files are moved out of Zelda64Recomp and genericized. It c This repo contains two libraries: Ultramodern and Librecomp. -### Ultramodern +## Ultramodern Ultramodern is a reimplementation of much of the core functionality of libultra. It can be used with either statically recompiled projects that use N64Recomp or direct source ports. It implements the following libultra functionality: + * Threads * Controllers * Audio @@ -18,11 +19,12 @@ Ultramodern is a reimplementation of much of the core functionality of libultra. Platform-specific I/O is handled via callbacks that are provided by the project using ultramodern. This includes reading from controllers and playing back audio samples. -Currently, ultramodern depends directly on [RT64](https://github.com/rt64/rt64) for rendering. It may be decoupled in the future to allow using other renderers for targeting different platforms. +ultramodern expects the user to provide and regiter a graphics renderer. The recommended one is [RT64](https://github.com/rt64/rt64). -### Librecomp +## Librecomp Librecomp is a library meant to be used to bridge the gap between code generated by N64Recomp and ultramodern. It provides wrappers to allow recompiled code to call ultramodern. Librecomp also provides some of the remaining libultra functionality that ultramodern doesn't provide, which includes: + * Overlay handling * PI DMA (ROM reads) * EEPROM, SRAM and Flashram saving (these may be partially moved to ultramodern in the future) \ No newline at end of file diff --git a/librecomp/CMakeLists.txt b/librecomp/CMakeLists.txt index 55c1bc8..bce0988 100644 --- a/librecomp/CMakeLists.txt +++ b/librecomp/CMakeLists.txt @@ -26,12 +26,9 @@ add_library(librecomp STATIC target_include_directories(librecomp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}/../ultramodern/include" + "${PROJECT_SOURCE_DIR}/../thirdparty" "${PROJECT_SOURCE_DIR}/../thirdparty/concurrentqueue" ) -target_include_directories(librecomp PRIVATE - "${PROJECT_SOURCE_DIR}/../rt64/src/contrib" - "${CMAKE_CURRENT_SOURCE_DIR}/include/librecomp" -) target_compile_options(librecomp PRIVATE -Wno-deprecated-declarations) diff --git a/rt64 b/rt64 deleted file mode 160000 index 1adcbea..0000000 --- a/rt64 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1adcbea31a04f2403da729eb5dfed3950dd7ec52 diff --git a/thirdparty/xxHash b/thirdparty/xxHash new file mode 160000 index 0000000..ac3a25d --- /dev/null +++ b/thirdparty/xxHash @@ -0,0 +1 @@ +Subproject commit ac3a25da3d957d9ef3e4114d9f8332d34ce83a46 diff --git a/ultramodern/CMakeLists.txt b/ultramodern/CMakeLists.txt index 333ed13..66c798d 100644 --- a/ultramodern/CMakeLists.txt +++ b/ultramodern/CMakeLists.txt @@ -28,21 +28,11 @@ add_library(ultramodern STATIC target_include_directories(ultramodern PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/" + "${PROJECT_SOURCE_DIR}/../thirdparty" "${PROJECT_SOURCE_DIR}/../thirdparty/concurrentqueue" "${PROJECT_SOURCE_DIR}/../thirdparty/sse2neon" ) -# TODO: remove when rt64 is no longer a hard dependency -target_include_directories(ultramodern PRIVATE - "${PROJECT_SOURCE_DIR}/../rt64/src" - "${PROJECT_SOURCE_DIR}/../rt64/src/contrib" - "${PROJECT_SOURCE_DIR}/../rt64/src/contrib/hlslpp/include" - "${PROJECT_SOURCE_DIR}/../rt64/src/contrib/dxc/inc" - "${PROJECT_SOURCE_DIR}/../rt64/src/rhi" - "${PROJECT_SOURCE_DIR}/../rt64/src/render" - "${PROJECT_SOURCE_DIR}/../rt64/src/contrib/nativefiledialog-extended/src/include" -) - if (WIN32) include(FetchContent) # Fetch SDL2 on windows diff --git a/ultramodern/include/ultramodern/renderer_wrapper.hpp b/ultramodern/include/ultramodern/renderer_wrapper.hpp index eb2b889..02931e0 100644 --- a/ultramodern/include/ultramodern/renderer_wrapper.hpp +++ b/ultramodern/include/ultramodern/renderer_wrapper.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include "ultra64.h" @@ -20,6 +21,7 @@ namespace ultramodern { virtual ~GraphicsConfig() = 0; virtual std::string get_graphics_api_name() const = 0; + virtual std::optional get_target_framerate() const = 0; auto operator<=>(const GraphicsConfig& rhs) const = default; }; diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index cd2c73f..a4a13cd 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -227,21 +227,12 @@ std::atomic_uint32_t display_refresh_rate = 60; std::atomic resolution_scale = 1.0f; uint32_t ultramodern::get_target_framerate(uint32_t original) { -#if 0 - ultramodern::GraphicsConfig graphics_config = ultramodern::get_graphics_config(); + auto maybe_framerate = ultramodern::renderer::get_graphics_config()->get_target_framerate(); - switch (graphics_config.rr_option) { - case RT64::UserConfiguration::RefreshRate::Original: - default: - return original; - case RT64::UserConfiguration::RefreshRate::Manual: - return graphics_config.rr_manual_value; - case RT64::UserConfiguration::RefreshRate::Display: -#endif - return display_refresh_rate.load(); -#if 0 + if (maybe_framerate.has_value()) { + return maybe_framerate.value(); } -#endif + return display_refresh_rate.load(); } uint32_t ultramodern::get_display_refresh_rate() { @@ -256,7 +247,7 @@ void ultramodern::load_shader_cache(std::span cache_data) { events_context.action_queue.enqueue(LoadShaderCacheAction{cache_data}); } -std::atomic rt64_setup_result = ultramodern::renderer::SetupResult::Success; +std::atomic renderer_setup_result = ultramodern::renderer::SetupResult::Success; void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready, ultramodern::WindowHandle window_handle) { bool enabled_instant_present = false; @@ -267,11 +258,10 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re auto old_config = ultramodern::renderer::get_graphics_config(); - //ultramodern::RT64Context rt64{rdram, window_handle, cur_config.load().developer_mode}; auto renderer_context = ultramodern::renderer::create_render_context(rdram, window_handle, ultramodern::renderer::get_graphics_config()->developer_mode); if (!renderer_context->valid()) { - rt64_setup_result.store(renderer_context->get_setup_result()); + renderer_setup_result.store(renderer_context->get_setup_result()); // Notify the caller thread that this thread is ready. thread_ready->signal(); return; @@ -304,11 +294,11 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re sp_complete(); ultramodern::measure_input_latency(); - auto rt64_start = std::chrono::high_resolution_clock::now(); + auto renderer_start = std::chrono::high_resolution_clock::now(); renderer_context->send_dl(&task_action->task); - auto rt64_end = std::chrono::high_resolution_clock::now(); + auto renderer_end = std::chrono::high_resolution_clock::now(); dp_complete(); - // printf("RT64 ProcessDList time: %d us\n", static_cast(std::chrono::duration_cast(rt64_end - rt64_start).count())); + // printf("Renderer ProcessDList time: %d us\n", static_cast(std::chrono::duration_cast(renderer_end - renderer_start).count())); } else if (const auto* swap_action = std::get_if(&action)) { events_context.vi.current_buffer = events_context.vi.next_buffer; @@ -511,32 +501,32 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle) gfx_thread_ready.wait(); task_thread_ready.wait(); - ultramodern::renderer::SetupResult setup_result = rt64_setup_result.load(); - if (rt64_setup_result != ultramodern::renderer::SetupResult::Success) { - auto show_rt64_error = [](const std::string& msg) { + ultramodern::renderer::SetupResult setup_result = renderer_setup_result.load(); + if (renderer_setup_result != ultramodern::renderer::SetupResult::Success) { + auto show_renderer_error = [](const std::string& msg) { std::string error_msg = "An error has been encountered on startup: " + msg; ultramodern::error_handling::message_box(error_msg.c_str()); }; const std::string driver_os_suffix = "\nPlease make sure your GPU drivers and your OS are up to date."; - switch (rt64_setup_result) { + switch (renderer_setup_result) { case ultramodern::renderer::SetupResult::Success: break; case ultramodern::renderer::SetupResult::DynamicLibrariesNotFound: - show_rt64_error("Failed to load dynamic libraries. Make sure the DLLs are next to the recomp executable."); + show_renderer_error("Failed to load dynamic libraries. Make sure the DLLs are next to the recomp executable."); break; case ultramodern::renderer::SetupResult::InvalidGraphicsAPI: - show_rt64_error(ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + " is not supported on this platform. Please select a different graphics API."); + show_renderer_error(ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + " is not supported on this platform. Please select a different graphics API."); break; case ultramodern::renderer::SetupResult::GraphicsAPINotFound: - show_rt64_error("Unable to initialize " + ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + "." + driver_os_suffix); + show_renderer_error("Unable to initialize " + ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + "." + driver_os_suffix); break; case ultramodern::renderer::SetupResult::GraphicsDeviceNotFound: - show_rt64_error("Unable to find compatible graphics device." + driver_os_suffix); + show_renderer_error("Unable to find compatible graphics device." + driver_os_suffix); break; } - throw std::runtime_error("Failed to initialize RT64"); + throw std::runtime_error("Failed to initialize the renderer"); } events_context.vi.thread = std::thread{ vi_thread_func }; diff --git a/ultramodern/src/renderer_wrapper.cpp b/ultramodern/src/renderer_wrapper.cpp index e249405..36e1a78 100644 --- a/ultramodern/src/renderer_wrapper.cpp +++ b/ultramodern/src/renderer_wrapper.cpp @@ -1,3 +1,5 @@ +#include + #include "ultramodern/renderer_wrapper.hpp" #include "ultramodern/ultramodern.hpp" @@ -24,9 +26,17 @@ static std::mutex graphic_config_mutex; void ultramodern::renderer::set_graphics_config(const GraphicsConfig* config) { std::lock_guard lock(graphic_config_mutex); + assert(config != nullptr); graphic_config.reset(config); } const ultramodern::renderer::GraphicsConfig* ultramodern::renderer::get_graphics_config() { - return graphic_config.get(); + std::lock_guard lock(graphic_config_mutex); + auto ptr = graphic_config.get(); + if (ptr == nullptr) { + error_handling::message_box("[Error] The graphic configuration was not registered"); + // TODO: should we make a macro for this? + error_handling::quick_exit(__FILE__, __LINE__, __func__); + } + return ptr; }