Make GraphicsConfig an abstract class

This commit is contained in:
Angie 2024-05-31 15:29:26 -04:00 committed by angie
parent 0af92b76f1
commit 55801577be
5 changed files with 44 additions and 137 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "rt64"]
path = rt64
url = https://github.com/rt64/rt64.git

View file

@ -1,88 +0,0 @@
#ifndef __CONFIG_HPP__
#define __CONFIG_HPP__
// TODO remove this direct dependency on RT64.
#include "common/rt64_user_configuration.h"
namespace ultramodern {
enum class Resolution {
Original,
Original2x,
Auto,
OptionCount
};
enum class WindowMode {
Windowed,
Fullscreen,
OptionCount
};
enum class HUDRatioMode {
Original,
Clamp16x9,
Full,
OptionCount
};
enum class GraphicsApi {
Auto,
D3D12,
Vulkan,
OptionCount
};
enum class HighPrecisionFramebuffer {
Auto,
On,
Off,
OptionCount
};
struct GraphicsConfig {
Resolution res_option;
WindowMode wm_option;
HUDRatioMode hr_option;
GraphicsApi api_option;
// TODO make custom enums that map to the RT64 ones to remove the direct dependency on RT64 in this file.
RT64::UserConfiguration::AspectRatio ar_option;
RT64::UserConfiguration::Antialiasing msaa_option;
RT64::UserConfiguration::RefreshRate rr_option;
HighPrecisionFramebuffer hpfb_option;
int rr_manual_value;
int ds_option;
bool developer_mode;
auto operator<=>(const GraphicsConfig& rhs) const = default;
};
void set_graphics_config(const GraphicsConfig& config);
GraphicsConfig get_graphics_config();
NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::Resolution, {
{ultramodern::Resolution::Original, "Original"},
{ultramodern::Resolution::Original2x, "Original2x"},
{ultramodern::Resolution::Auto, "Auto"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::WindowMode, {
{ultramodern::WindowMode::Windowed, "Windowed"},
{ultramodern::WindowMode::Fullscreen, "Fullscreen"}
});
NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::HUDRatioMode, {
{ultramodern::HUDRatioMode::Original, "Original"},
{ultramodern::HUDRatioMode::Clamp16x9, "Clamp16x9"},
{ultramodern::HUDRatioMode::Full, "Full"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::GraphicsApi, {
{ultramodern::GraphicsApi::Auto, "Auto"},
{ultramodern::GraphicsApi::D3D12, "D3D12"},
{ultramodern::GraphicsApi::Vulkan, "Vulkan"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::HighPrecisionFramebuffer, {
{ultramodern::HighPrecisionFramebuffer::Auto, "Auto"},
{ultramodern::HighPrecisionFramebuffer::On, "On"},
{ultramodern::HighPrecisionFramebuffer::Off, "Off"},
});
};
#endif

View file

@ -6,7 +6,6 @@
#include <span> #include <span>
#include "ultra64.h" #include "ultra64.h"
#include "config.hpp"
namespace ultramodern { namespace ultramodern {
@ -14,6 +13,17 @@ namespace ultramodern {
struct WindowHandle; struct WindowHandle;
namespace renderer { namespace renderer {
class GraphicsConfig {
public:
bool developer_mode;
virtual ~GraphicsConfig() = 0;
virtual std::string get_graphics_api_name() const = 0;
auto operator<=>(const GraphicsConfig& rhs) const = default;
};
enum class SetupResult { enum class SetupResult {
Success, Success,
DynamicLibrariesNotFound, DynamicLibrariesNotFound,
@ -27,16 +37,16 @@ namespace ultramodern {
virtual ~RendererContext() = 0; virtual ~RendererContext() = 0;
virtual bool valid() = 0; virtual bool valid() = 0;
virtual SetupResult get_setup_result() { return setup_result; } virtual SetupResult get_setup_result() const { return setup_result; }
virtual void update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config) = 0; virtual void update_config(const GraphicsConfig* old_config, const GraphicsConfig* new_config) = 0;
virtual void enable_instant_present() = 0; virtual void enable_instant_present() = 0;
virtual void send_dl(const OSTask* task) = 0; virtual void send_dl(const OSTask* task) = 0;
virtual void update_screen(uint32_t vi_origin) = 0; virtual void update_screen(uint32_t vi_origin) = 0;
virtual void shutdown() = 0; virtual void shutdown() = 0;
virtual uint32_t get_display_framerate() = 0; virtual uint32_t get_display_framerate() const = 0;
virtual float get_resolution_scale() = 0; virtual float get_resolution_scale() const = 0;
virtual void load_shader_cache(std::span<const char> cache_binary) = 0; virtual void load_shader_cache(std::span<const char> cache_binary) = 0;
private: private:
@ -52,6 +62,10 @@ namespace ultramodern {
void set_callbacks(const callbacks_t& callbacks); void set_callbacks(const callbacks_t& callbacks);
std::unique_ptr<RendererContext> create_render_context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode); std::unique_ptr<RendererContext> create_render_context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode);
void set_graphics_config(const GraphicsConfig* config);
const GraphicsConfig* get_graphics_config();
} }
} }

View file

@ -13,7 +13,6 @@
#include "ultramodern/ultra64.h" #include "ultramodern/ultra64.h"
#include "ultramodern/ultramodern.hpp" #include "ultramodern/ultramodern.hpp"
#include "ultramodern/config.hpp"
#include "ultramodern/rsp.hpp" #include "ultramodern/rsp.hpp"
#include "ultramodern/renderer_wrapper.hpp" #include "ultramodern/renderer_wrapper.hpp"
@ -224,21 +223,11 @@ void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_r
} }
} }
static std::atomic<ultramodern::GraphicsConfig> cur_config{};
void ultramodern::set_graphics_config(const ultramodern::GraphicsConfig& config) {
cur_config = config;
events_context.action_queue.enqueue(UpdateConfigAction{});
}
ultramodern::GraphicsConfig ultramodern::get_graphics_config() {
return cur_config;
}
std::atomic_uint32_t display_refresh_rate = 60; std::atomic_uint32_t display_refresh_rate = 60;
std::atomic<float> resolution_scale = 1.0f; std::atomic<float> resolution_scale = 1.0f;
uint32_t ultramodern::get_target_framerate(uint32_t original) { uint32_t ultramodern::get_target_framerate(uint32_t original) {
#if 0
ultramodern::GraphicsConfig graphics_config = ultramodern::get_graphics_config(); ultramodern::GraphicsConfig graphics_config = ultramodern::get_graphics_config();
switch (graphics_config.rr_option) { switch (graphics_config.rr_option) {
@ -248,8 +237,11 @@ uint32_t ultramodern::get_target_framerate(uint32_t original) {
case RT64::UserConfiguration::RefreshRate::Manual: case RT64::UserConfiguration::RefreshRate::Manual:
return graphics_config.rr_manual_value; return graphics_config.rr_manual_value;
case RT64::UserConfiguration::RefreshRate::Display: case RT64::UserConfiguration::RefreshRate::Display:
#endif
return display_refresh_rate.load(); return display_refresh_rate.load();
#if 0
} }
#endif
} }
uint32_t ultramodern::get_display_refresh_rate() { uint32_t ultramodern::get_display_refresh_rate() {
@ -273,10 +265,10 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re
ultramodern::set_native_thread_name("Gfx Thread"); ultramodern::set_native_thread_name("Gfx Thread");
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Normal); ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Normal);
ultramodern::GraphicsConfig old_config = ultramodern::get_graphics_config(); auto old_config = ultramodern::renderer::get_graphics_config();
//ultramodern::RT64Context rt64{rdram, window_handle, cur_config.load().developer_mode}; //ultramodern::RT64Context rt64{rdram, window_handle, cur_config.load().developer_mode};
auto renderer_context = ultramodern::renderer::create_render_context(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()) { if (!renderer_context->valid()) {
rt64_setup_result.store(renderer_context->get_setup_result()); rt64_setup_result.store(renderer_context->get_setup_result());
@ -325,8 +317,8 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re
resolution_scale = renderer_context->get_resolution_scale(); resolution_scale = renderer_context->get_resolution_scale();
} }
else if (const auto* config_action = std::get_if<UpdateConfigAction>(&action)) { else if (const auto* config_action = std::get_if<UpdateConfigAction>(&action)) {
ultramodern::GraphicsConfig new_config = cur_config; auto new_config = ultramodern::renderer::get_graphics_config();
if (old_config != new_config) { if (*old_config != *new_config) {
renderer_context->update_config(old_config, new_config); renderer_context->update_config(old_config, new_config);
old_config = new_config; old_config = new_config;
} }
@ -507,29 +499,6 @@ void ultramodern::send_si_message(RDRAM_ARG1) {
osSendMesg(PASS_RDRAM events_context.si.mq, events_context.si.msg, OS_MESG_NOBLOCK); osSendMesg(PASS_RDRAM events_context.si.mq, events_context.si.msg, OS_MESG_NOBLOCK);
} }
std::string get_graphics_api_name(ultramodern::GraphicsApi api) {
if (api == ultramodern::GraphicsApi::Auto) {
#if defined(_WIN32)
api = ultramodern::GraphicsApi::D3D12;
#elif defined(__gnu_linux__)
api = ultramodern::GraphicsApi::Vulkan;
#elif defined(__APPLE__)
api = ultramodern::GraphicsApi::Vulkan;
#else
static_assert(false && "Unimplemented")
#endif
}
switch (api) {
case ultramodern::GraphicsApi::D3D12:
return "D3D12";
case ultramodern::GraphicsApi::Vulkan:
return "Vulkan";
default:
return "[Unknown graphics API]";
}
}
void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle) { void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle) {
moodycamel::LightweightSemaphore gfx_thread_ready; moodycamel::LightweightSemaphore gfx_thread_ready;
moodycamel::LightweightSemaphore task_thread_ready; moodycamel::LightweightSemaphore task_thread_ready;
@ -552,14 +521,16 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle)
const std::string driver_os_suffix = "\nPlease make sure your GPU drivers and your OS are up to date."; const std::string driver_os_suffix = "\nPlease make sure your GPU drivers and your OS are up to date.";
switch (rt64_setup_result) { switch (rt64_setup_result) {
case ultramodern::renderer::SetupResult::Success:
break;
case ultramodern::renderer::SetupResult::DynamicLibrariesNotFound: case ultramodern::renderer::SetupResult::DynamicLibrariesNotFound:
show_rt64_error("Failed to load dynamic libraries. Make sure the DLLs are next to the recomp executable."); show_rt64_error("Failed to load dynamic libraries. Make sure the DLLs are next to the recomp executable.");
break; break;
case ultramodern::renderer::SetupResult::InvalidGraphicsAPI: case ultramodern::renderer::SetupResult::InvalidGraphicsAPI:
show_rt64_error(get_graphics_api_name(cur_config.load().api_option) + " is not supported on this platform. Please select a different graphics API."); show_rt64_error(ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + " is not supported on this platform. Please select a different graphics API.");
break; break;
case ultramodern::renderer::SetupResult::GraphicsAPINotFound: case ultramodern::renderer::SetupResult::GraphicsAPINotFound:
show_rt64_error("Unable to initialize " + get_graphics_api_name(cur_config.load().api_option) + "." + driver_os_suffix); show_rt64_error("Unable to initialize " + ultramodern::renderer::get_graphics_config()->get_graphics_api_name() + "." + driver_os_suffix);
break; break;
case ultramodern::renderer::SetupResult::GraphicsDeviceNotFound: case ultramodern::renderer::SetupResult::GraphicsDeviceNotFound:
show_rt64_error("Unable to find compatible graphics device." + driver_os_suffix); show_rt64_error("Unable to find compatible graphics device." + driver_os_suffix);

View file

@ -17,3 +17,16 @@ std::unique_ptr<ultramodern::renderer::RendererContext> ultramodern::renderer::c
return render_callbacks.create_render_context(rdram, window_handle, developer_mode); return render_callbacks.create_render_context(rdram, window_handle, developer_mode);
} }
static std::unique_ptr<const ultramodern::renderer::GraphicsConfig> graphic_config{};
static std::mutex graphic_config_mutex;
void ultramodern::renderer::set_graphics_config(const GraphicsConfig* config) {
std::lock_guard<std::mutex> lock(graphic_config_mutex);
graphic_config.reset(config);
}
const ultramodern::renderer::GraphicsConfig* ultramodern::renderer::get_graphics_config() {
return graphic_config.get();
}