From 6f8393f691b508ae363c474ee22bfa07461e14b3 Mon Sep 17 00:00:00 2001 From: Wiseguy <68165316+Mr-Wiseguy@users.noreply.github.com> Date: Sun, 23 Mar 2025 21:39:30 -0400 Subject: [PATCH] Allow renderers to pick the graphics API (#96) --- ultramodern/include/ultramodern/config.hpp | 3 +- .../include/ultramodern/renderer_context.hpp | 6 ++- ultramodern/src/events.cpp | 6 ++- ultramodern/src/renderer_context.cpp | 44 ++++++------------- 4 files changed, 23 insertions(+), 36 deletions(-) diff --git a/ultramodern/include/ultramodern/config.hpp b/ultramodern/include/ultramodern/config.hpp index a6af8e6..a8cd8e0 100644 --- a/ultramodern/include/ultramodern/config.hpp +++ b/ultramodern/include/ultramodern/config.hpp @@ -74,8 +74,6 @@ namespace ultramodern { virtual ~GraphicsConfig() = default; - std::string get_graphics_api_name() const; - auto operator<=>(const GraphicsConfig& rhs) const = default; }; @@ -103,6 +101,7 @@ namespace ultramodern { {ultramodern::renderer::GraphicsApi::Auto, "Auto"}, {ultramodern::renderer::GraphicsApi::D3D12, "D3D12"}, {ultramodern::renderer::GraphicsApi::Vulkan, "Vulkan"}, + {ultramodern::renderer::GraphicsApi::Metal, "Metal"}, }); NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::renderer::AspectRatio, { diff --git a/ultramodern/include/ultramodern/renderer_context.hpp b/ultramodern/include/ultramodern/renderer_context.hpp index a299a15..67ae544 100644 --- a/ultramodern/include/ultramodern/renderer_context.hpp +++ b/ultramodern/include/ultramodern/renderer_context.hpp @@ -62,6 +62,7 @@ namespace ultramodern { virtual bool valid() = 0; virtual SetupResult get_setup_result() const { return setup_result; } + virtual GraphicsApi get_chosen_api() const { return chosen_api; } virtual bool update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config) = 0; @@ -74,11 +75,12 @@ namespace ultramodern { protected: SetupResult setup_result; + GraphicsApi chosen_api; }; struct callbacks_t { using create_render_context_t = std::unique_ptr(uint8_t* rdram, WindowHandle window_handle, bool developer_mode); - using get_graphics_api_name_t = std::string(const GraphicsConfig& config); + using get_graphics_api_name_t = std::string(GraphicsApi api); /** * Instances a subclass of RendererContext that is used to render the game. @@ -97,7 +99,7 @@ namespace ultramodern { std::unique_ptr create_render_context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode); - std::string get_graphics_api_name(const GraphicsConfig& config); + std::string get_graphics_api_name(GraphicsApi api); } } diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index fa5b4c6..879d536 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -249,6 +249,7 @@ void ultramodern::trigger_config_action() { } std::atomic renderer_setup_result = ultramodern::renderer::SetupResult::Success; +std::atomic renderer_chosen_api = ultramodern::renderer::GraphicsApi::Auto; void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready, ultramodern::renderer::WindowHandle window_handle) { bool enabled_instant_present = false; @@ -261,6 +262,7 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re auto renderer_context = ultramodern::renderer::create_render_context(rdram, window_handle, ultramodern::renderer::get_graphics_config().developer_mode); + renderer_chosen_api.store(renderer_context->get_chosen_api()); if (!renderer_context->valid()) { renderer_setup_result.store(renderer_context->get_setup_result()); // Notify the caller thread that this thread is ready. @@ -534,10 +536,10 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::renderer::WindowHandle wind 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_renderer_error(ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + " is not supported on this platform. Please select a different graphics API."); + show_renderer_error(ultramodern::renderer::get_graphics_api_name(renderer_chosen_api.load()) + " is not supported on this platform. Please select a different graphics API."); break; case ultramodern::renderer::SetupResult::GraphicsAPINotFound: - show_renderer_error("Unable to initialize " + ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + "." + driver_os_suffix); + show_renderer_error("Unable to initialize " + ultramodern::renderer::get_graphics_api_name(renderer_chosen_api.load()) + "." + driver_os_suffix); break; case ultramodern::renderer::SetupResult::GraphicsDeviceNotFound: show_renderer_error("Unable to find compatible graphics device." + driver_os_suffix); diff --git a/ultramodern/src/renderer_context.cpp b/ultramodern/src/renderer_context.cpp index 8394a3c..a6af900 100644 --- a/ultramodern/src/renderer_context.cpp +++ b/ultramodern/src/renderer_context.cpp @@ -20,11 +20,22 @@ std::unique_ptr ultramodern::renderer::c return render_callbacks.create_render_context(rdram, window_handle, developer_mode); } -std::string ultramodern::renderer::get_graphics_api_name(const GraphicsConfig& config) { +std::string ultramodern::renderer::get_graphics_api_name(GraphicsApi api) { if (render_callbacks.get_graphics_api_name != nullptr) { - return render_callbacks.get_graphics_api_name(config); + return render_callbacks.get_graphics_api_name(api); + } + switch (api) { + case ultramodern::renderer::GraphicsApi::Auto: + return "Auto"; + case ultramodern::renderer::GraphicsApi::D3D12: + return "D3D12"; + case ultramodern::renderer::GraphicsApi::Vulkan: + return "Vulkan"; + case ultramodern::renderer::GraphicsApi::Metal: + return "Metal"; + default: + return "[Unknown graphics API]"; } - return config.get_graphics_api_name(); } @@ -41,30 +52,3 @@ const ultramodern::renderer::GraphicsConfig& ultramodern::renderer::get_graphics std::lock_guard lock(graphic_config_mutex); return graphic_config; } - -std::string ultramodern::renderer::GraphicsConfig::get_graphics_api_name() const { - ultramodern::renderer::GraphicsApi api = api_option; - - if (api == ultramodern::renderer::GraphicsApi::Auto) { -#if defined(_WIN32) - api = ultramodern::renderer::GraphicsApi::D3D12; -#elif defined(__gnu_linux__) - api = ultramodern::renderer::GraphicsApi::Vulkan; -#elif defined(__APPLE__) - api = ultramodern::renderer::GraphicsApi::Metal; -#else - static_assert(false && "Unimplemented") -#endif - } - - switch (api) { - case ultramodern::renderer::GraphicsApi::D3D12: - return "D3D12"; - case ultramodern::renderer::GraphicsApi::Vulkan: - return "Vulkan"; - case ultramodern::renderer::GraphicsApi::Metal: - return "Metal"; - default: - return "[Unknown graphics API]"; - } -}