From ceff20f57fe09644b3074d1cf2b4bf68d2b6eddd Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Mon, 17 Jul 2023 10:12:38 -0700 Subject: [PATCH] Add configurable Renderer backend There are still some initialization errors to work through, such as config not being initialized properly by the time GPU tries to utilize it too. Also some life-time issues. But manually forcing it to use the Null backnd successfully works and allows games to be "played" headlessly. --- include/config.hpp | 3 +++ include/emulator.hpp | 4 ++-- include/renderer.hpp | 6 ++++++ src/config.cpp | 2 ++ src/core/PICA/gpu.cpp | 18 +++++++++++++++--- src/emulator.cpp | 33 +++++++++++++++++---------------- src/main.cpp | 6 +++--- 7 files changed, 48 insertions(+), 24 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index bdb697bf..adbddd32 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -1,9 +1,12 @@ #pragma once #include +#include "renderer.hpp" + // Remember to initialize every field here to its default value otherwise bad things will happen struct EmulatorConfig { bool shaderJitEnabled = false; + RendererType rendererType = RendererType::OpenGL; void load(const std::filesystem::path& path); void save(const std::filesystem::path& path); diff --git a/include/emulator.hpp b/include/emulator.hpp index f27cd990..5df986dc 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -70,8 +70,8 @@ class Emulator { public: // Decides whether to reload or not reload the ROM when resetting. We use enum class over a plain bool for clarity. // If NoReload is selected, the emulator will not reload its selected ROM. This is useful for things like booting up the emulator, or resetting to - // change ROMs. If Reload is selected, the emulator will reload its selected ROM. This is useful for eg a "reset" button that keeps the current ROM - // and just resets the emu + // change ROMs. If Reload is selected, the emulator will reload its selected ROM. This is useful for eg a "reset" button that keeps the current + // ROM and just resets the emu enum class ReloadOption { NoReload, Reload }; Emulator(); diff --git a/include/renderer.hpp b/include/renderer.hpp index 5a2b40b4..50ed1a32 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -6,6 +6,12 @@ #include "PICA/regs.hpp" #include "helpers.hpp" +enum class RendererType : s8 { + // Todo: Auto = -1, + Null = 0, + OpenGL = 1, +}; + class GPU; class Renderer { diff --git a/src/config.cpp b/src/config.cpp index 6c9a8450..7df73dbd 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -31,6 +31,7 @@ void EmulatorConfig::load(const std::filesystem::path& path) { if (gpuResult.is_ok()) { auto gpu = gpuResult.unwrap(); + rendererType = RendererType(toml::find_or(gpu, "Renderer", int64_t(rendererType))); shaderJitEnabled = toml::find_or(gpu, "EnableShaderJIT", false); } } @@ -54,6 +55,7 @@ void EmulatorConfig::save(const std::filesystem::path& path) { printf("Saving new configuration file %s\n", path.string().c_str()); } + data["GPU"]["Renderer"] = static_cast(rendererType); data["GPU"]["EnableShaderJIT"] = shaderJitEnabled; std::ofstream file(path, std::ios::out); diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 15c99c42..487a8743 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -7,7 +7,7 @@ #include "PICA/float_types.hpp" #include "PICA/regs.hpp" - +#include "renderer_null/renderer_null.hpp" #ifdef PANDA3DS_ENABLE_OPENGL #include "renderer_gl/renderer_gl.hpp" #endif @@ -20,10 +20,22 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) { vram = new u8[vramSize]; mem.setVRAM(vram); // Give the bus a pointer to our VRAM - // TODO: Configurable backend + switch (config.rendererType) { + case RendererType::Null: { + renderer.reset(new RendererNull(*this, regs)); + break; + } #ifdef PANDA3DS_ENABLE_OPENGL - renderer.reset(new RendererGL(*this, regs)); + case RendererType::OpenGL: { + renderer.reset(new RendererGL(*this, regs)); + break; + } #endif + default: { + Helpers::panic("Invalid rendering backend index: %d", static_cast(config.rendererType)); + break; + } + } } void GPU::reset() { diff --git a/src/emulator.cpp b/src/emulator.cpp index 23baa258..07ce61b5 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -26,24 +26,26 @@ Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory } #ifdef PANDA3DS_ENABLE_OPENGL - // Request OpenGL 4.1 Core (Max available on MacOS) - // MacOS gets mad if we don't explicitly demand a core profile - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); + if (config.rendererType == RendererType::OpenGL) { + // Request OpenGL 4.1 Core (Max available on MacOS) + // MacOS gets mad if we don't explicitly demand a core profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); - if (window == nullptr) { - Helpers::panic("Window creation failed: %s", SDL_GetError()); - } + if (window == nullptr) { + Helpers::panic("Window creation failed: %s", SDL_GetError()); + } - glContext = SDL_GL_CreateContext(window); - if (glContext == nullptr) { - Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); - } + glContext = SDL_GL_CreateContext(window); + if (glContext == nullptr) { + Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); + } - if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { - Helpers::panic("OpenGL init failed: %s", SDL_GetError()); + if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { + Helpers::panic("OpenGL init failed: %s", SDL_GetError()); + } } #endif @@ -56,7 +58,6 @@ Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory } } - config.load(std::filesystem::current_path() / "config.toml"); reset(ReloadOption::NoReload); } diff --git a/src/main.cpp b/src/main.cpp index 1559565a..66a04b9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,9 @@ #include "emulator.hpp" -int main (int argc, char *argv[]) { - Emulator emu; +int main(int argc, char *argv[]) { + Emulator emu; - emu.initGraphicsContext(); + emu.initGraphicsContext(); if (argc > 1) { auto romPath = std::filesystem::current_path() / argv[1];