Prepare frontend for multiple graphics APIs (#6347)

* externals: Update dynarmic

* settings: Introduce GraphicsAPI enum

* For now it's OpenGL only but will be expanded upon later

* citra_qt: Introduce backend agnostic context management

* Mostly a direct port from yuzu

* core: Simplify context acquire

* settings: Add option to create debug contexts

* renderer_opengl: Abstract initialization to Driver

* This commit also updates glad and adds some useful extensions which we will use in part 2

* Rasterizer construction is moved to the specific renderer instead of RendererBase.
  Software rendering has been disable to achieve this but will be brought back in the next commit.

* video_core: Remove Init/Shutdown methods from renderer

* The constructor and destructor can do the same job

* In addition move opengl function loading to Qt since SDL already does this. Also remove ErrorVideoCore which is never reached

* citra_qt: Decouple software renderer from opengl part 1

* citra: Decouple software renderer from opengl part 2

* android: Decouple software renderer from opengl part 3

* swrasterizer: Decouple software renderer from opengl part 4

* This commit simply enforces the renderer naming conventions in the software renderer

* video_core: Move RendererBase to VideoCore

* video_core: De-globalize screenshot state

* video_core: Pass system to the renderers

* video_core: Commonize shader uniform data

* video_core: Abstract backend agnostic rasterizer operations

* bootmanager: Remove references to OpenGL for macOS

OpenGL macOS headers definitions clash heavily with each other

* citra_qt: Proper title for api settings

* video_core: Reduce boost usage

* bootmanager: Fix hide mouse option

Remove event handlers from RenderWidget for events that are
already handled by the parent GRenderWindow.
Also enable mouse tracking on the RenderWidget.

* android: Remove software from graphics api list

* code: Address review comments

* citra: Port per-game settings read

* Having to update the default value for all backends is a pain so lets centralize it

* android: Rename to OpenGLES

---------

Co-authored-by: MerryMage <MerryMage@users.noreply.github.com>
Co-authored-by: Vitor Kiguchi <vitor-kiguchi@hotmail.com>
This commit is contained in:
GPUCode 2023-03-27 14:29:17 +03:00 committed by GitHub
parent 9ef42040af
commit b5d6f645bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 3165 additions and 4501 deletions

View file

@ -5,6 +5,7 @@
#include <iomanip>
#include <memory>
#include <sstream>
#include <type_traits>
#include <unordered_map>
#include <SDL.h>
#include <inih/cpp/INIReader.h>
@ -71,6 +72,30 @@ static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs>
},
}};
template <>
void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
if (setting_value.empty()) {
setting_value = setting.GetDefault();
}
setting = std::move(setting_value);
}
template <>
void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) {
setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
}
template <typename Type, bool ranged>
void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
if constexpr (std::is_floating_point_v<Type>) {
setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault());
} else {
setting = static_cast<Type>(sdl2_config->GetInteger(
group, setting.GetLabel(), static_cast<long>(setting.GetDefault())));
}
}
void Config::ReadValues() {
// Controls
// TODO: add multiple input profile support
@ -104,104 +129,71 @@ void Config::ReadValues() {
InputCommon::CemuhookUDP::DEFAULT_PORT));
// Core
Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
Settings::values.cpu_clock_percentage =
sdl2_config->GetInteger("Core", "cpu_clock_percentage", 100);
ReadSetting("Core", Settings::values.use_cpu_jit);
ReadSetting("Core", Settings::values.cpu_clock_percentage);
// Renderer
Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", false);
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true);
ReadSetting("Renderer", Settings::values.graphics_api);
ReadSetting("Renderer", Settings::values.use_gles);
ReadSetting("Renderer", Settings::values.use_hw_shader);
#ifdef __APPLE__
// Separable shader is broken on macos with Intel GPU thanks to poor drivers.
// We still want to provide this option for test/development purposes, but disable it by
// default.
Settings::values.separable_shader =
sdl2_config->GetBoolean("Renderer", "separable_shader", false);
ReadSetting("Renderer", Settings::values.separable_shader);
#endif
Settings::values.shaders_accurate_mul =
sdl2_config->GetBoolean("Renderer", "shaders_accurate_mul", true);
Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true);
Settings::values.resolution_factor =
static_cast<u16>(sdl2_config->GetInteger("Renderer", "resolution_factor", 1));
Settings::values.use_disk_shader_cache =
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true);
Settings::values.frame_limit =
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
Settings::values.use_vsync_new =
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1));
Settings::values.texture_filter_name =
sdl2_config->GetString("Renderer", "texture_filter_name", "none");
ReadSetting("Renderer", Settings::values.shaders_accurate_mul);
ReadSetting("Renderer", Settings::values.use_shader_jit);
ReadSetting("Renderer", Settings::values.resolution_factor);
ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
ReadSetting("Renderer", Settings::values.frame_limit);
ReadSetting("Renderer", Settings::values.use_vsync_new);
ReadSetting("Renderer", Settings::values.texture_filter_name);
Settings::values.mono_render_option = static_cast<Settings::MonoRenderOption>(
sdl2_config->GetInteger("Renderer", "mono_render_option", 0));
Settings::values.render_3d = static_cast<Settings::StereoRenderOption>(
sdl2_config->GetInteger("Renderer", "render_3d", 0));
Settings::values.factor_3d =
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
Settings::values.pp_shader_name =
sdl2_config->GetString("Renderer", "pp_shader_name", "none (builtin)");
Settings::values.anaglyph_shader_name =
sdl2_config->GetString("Renderer", "anaglyph_shader_name", "dubois (builtin)");
Settings::values.filter_mode = sdl2_config->GetBoolean("Renderer", "filter_mode", true);
ReadSetting("Renderer", Settings::values.mono_render_option);
ReadSetting("Renderer", Settings::values.render_3d);
ReadSetting("Renderer", Settings::values.factor_3d);
ReadSetting("Renderer", Settings::values.pp_shader_name);
ReadSetting("Renderer", Settings::values.anaglyph_shader_name);
ReadSetting("Renderer", Settings::values.filter_mode);
Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0));
Settings::values.bg_green =
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0));
Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0));
ReadSetting("Renderer", Settings::values.bg_red);
ReadSetting("Renderer", Settings::values.bg_green);
ReadSetting("Renderer", Settings::values.bg_blue);
// Layout
Settings::values.layout_option =
static_cast<Settings::LayoutOption>(sdl2_config->GetInteger("Layout", "layout_option", 0));
Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false);
Settings::values.upright_screen = sdl2_config->GetBoolean("Layout", "upright_screen", false);
Settings::values.large_screen_proportion =
sdl2_config->GetReal("Layout", "large_screen_proportion", 4.0);
Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false);
Settings::values.custom_top_left =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_left", 0));
Settings::values.custom_top_top =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_top", 0));
Settings::values.custom_top_right =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_right", 400));
Settings::values.custom_top_bottom =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_bottom", 240));
Settings::values.custom_bottom_left =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_left", 40));
Settings::values.custom_bottom_top =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_top", 240));
Settings::values.custom_bottom_right =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_right", 360));
Settings::values.custom_bottom_bottom =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_bottom", 480));
Settings::values.custom_second_layer_opacity =
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_second_layer_opacity", 100));
ReadSetting("Layout", Settings::values.layout_option);
ReadSetting("Layout", Settings::values.swap_screen);
ReadSetting("Layout", Settings::values.upright_screen);
ReadSetting("Layout", Settings::values.large_screen_proportion);
ReadSetting("Layout", Settings::values.custom_layout);
ReadSetting("Layout", Settings::values.custom_top_left);
ReadSetting("Layout", Settings::values.custom_top_top);
ReadSetting("Layout", Settings::values.custom_top_right);
ReadSetting("Layout", Settings::values.custom_top_bottom);
ReadSetting("Layout", Settings::values.custom_bottom_left);
ReadSetting("Layout", Settings::values.custom_bottom_top);
ReadSetting("Layout", Settings::values.custom_bottom_right);
ReadSetting("Layout", Settings::values.custom_bottom_bottom);
ReadSetting("Layout", Settings::values.custom_second_layer_opacity);
// Utility
Settings::values.dump_textures = sdl2_config->GetBoolean("Utility", "dump_textures", false);
Settings::values.custom_textures = sdl2_config->GetBoolean("Utility", "custom_textures", false);
Settings::values.preload_textures =
sdl2_config->GetBoolean("Utility", "preload_textures", false);
ReadSetting("Utility", Settings::values.dump_textures);
ReadSetting("Utility", Settings::values.custom_textures);
ReadSetting("Utility", Settings::values.preload_textures);
// Audio
Settings::values.audio_emulation = static_cast<Settings::AudioEmulation>(
sdl2_config->GetInteger("Audio", "audio_emulation", 0));
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
Settings::values.enable_audio_stretching =
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
Settings::values.audio_device_id = sdl2_config->GetString("Audio", "output_device", "auto");
Settings::values.volume = static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1));
Settings::values.mic_input_device =
sdl2_config->GetString("Audio", "mic_input_device", Frontend::Mic::default_device_name);
Settings::values.mic_input_type =
static_cast<Settings::MicInputType>(sdl2_config->GetInteger("Audio", "mic_input_type", 0));
ReadSetting("Audio", Settings::values.audio_emulation);
ReadSetting("Audio", Settings::values.sink_id);
ReadSetting("Audio", Settings::values.enable_audio_stretching);
ReadSetting("Audio", Settings::values.audio_device_id);
ReadSetting("Audio", Settings::values.volume);
ReadSetting("Audio", Settings::values.mic_input_device);
ReadSetting("Audio", Settings::values.mic_input_type);
// Data Storage
Settings::values.use_virtual_sd =
sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
Settings::values.use_custom_storage =
sdl2_config->GetBoolean("Data Storage", "use_custom_storage", false);
ReadSetting("Data Storage", Settings::values.use_virtual_sd);
ReadSetting("Data Storage", Settings::values.use_custom_storage);
if (Settings::values.use_custom_storage) {
FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir,
@ -211,11 +203,9 @@ void Config::ReadValues() {
}
// System
Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", true);
Settings::values.region_value =
sdl2_config->GetInteger("System", "region_value", Settings::REGION_VALUE_AUTO_SELECT);
Settings::values.init_clock =
static_cast<Settings::InitClock>(sdl2_config->GetInteger("System", "init_clock", 1));
ReadSetting("System", Settings::values.is_new_3ds);
ReadSetting("System", Settings::values.region_value);
ReadSetting("System", Settings::values.init_clock);
{
std::tm t;
t.tm_sec = 1;
@ -236,6 +226,8 @@ void Config::ReadValues() {
std::chrono::system_clock::from_time_t(std::mktime(&t)).time_since_epoch())
.count();
}
ReadSetting("System", Settings::values.plugin_loader_enabled);
ReadSetting("System", Settings::values.allow_plugin_loader);
{
constexpr const char* default_init_time_offset = "0 00:00:00";
@ -311,14 +303,14 @@ void Config::ReadValues() {
sdl2_config->GetInteger("Camera", "camera_outer_left_flip", 0);
// Miscellaneous
Settings::values.log_filter = sdl2_config->GetString("Miscellaneous", "log_filter", "*:Info");
ReadSetting("Miscellaneous", Settings::values.log_filter);
// Debugging
Settings::values.record_frame_times =
sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false);
Settings::values.gdbstub_port =
static_cast<u16>(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689));
ReadSetting("Debugging", Settings::values.renderer_debug);
ReadSetting("Debugging", Settings::values.use_gdbstub);
ReadSetting("Debugging", Settings::values.gdbstub_port);
for (const auto& service_module : Service::service_module_map) {
bool use_lle = sdl2_config->GetBoolean("Debugging", "LLE\\" + service_module.name, false);