From 58e1a536996348d1ec4c8ab5a65b396fe28ccb3b Mon Sep 17 00:00:00 2001 From: Samuliak Date: Fri, 16 Aug 2024 11:06:23 +0200 Subject: [PATCH] metal: create renderer --- include/panda_qt/main_window.hpp | 1 + include/renderer.hpp | 3 ++- include/renderer_gl/surface_cache.hpp | 4 ++-- src/core/PICA/gpu.cpp | 11 ++++++++++- src/panda_qt/main_window.cpp | 5 ++++- src/panda_sdl/frontend_sdl.cpp | 14 ++++++++++++-- src/renderer.cpp | 4 +++- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/panda_qt/main_window.hpp b/include/panda_qt/main_window.hpp index 3ff16a1d..fc756b9f 100644 --- a/include/panda_qt/main_window.hpp +++ b/include/panda_qt/main_window.hpp @@ -129,6 +129,7 @@ class MainWindow : public QMainWindow { // Tracks whether we are using an OpenGL-backed renderer or a Vulkan-backed renderer bool usingGL = false; bool usingVk = false; + bool usingMtl = false; // Variables to keep track of whether the user is controlling the 3DS analog stick with their keyboard // This is done so when a gamepad is connected, we won't automatically override the 3DS analog stick settings with the gamepad's state diff --git a/include/renderer.hpp b/include/renderer.hpp index 569a730b..4eacf0b1 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -17,7 +17,8 @@ enum class RendererType : s8 { Null = 0, OpenGL = 1, Vulkan = 2, - Software = 3, + Metal = 3, + Software = 4, }; struct EmulatorConfig; diff --git a/include/renderer_gl/surface_cache.hpp b/include/renderer_gl/surface_cache.hpp index 5323741f..7346fd11 100644 --- a/include/renderer_gl/surface_cache.hpp +++ b/include/renderer_gl/surface_cache.hpp @@ -19,8 +19,8 @@ template class SurfaceCache { // Vanilla std::optional can't hold actual references using OptionalRef = std::optional>; - static_assert(std::is_same() || std::is_same() || - std::is_same(), "Invalid surface type"); + //static_assert(std::is_same() || std::is_same() || + // std::is_same(), "Invalid surface type"); size_t size; size_t evictionIndex; diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index fe336edc..95001b33 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -15,6 +15,9 @@ #ifdef PANDA3DS_ENABLE_VULKAN #include "renderer_vk/renderer_vk.hpp" #endif +#ifdef PANDA3DS_ENABLE_METAL +#include "renderer_mtl/renderer_mtl.hpp" +#endif constexpr u32 topScreenWidth = 240; constexpr u32 topScreenHeight = 400; @@ -52,6 +55,12 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) { renderer.reset(new RendererVK(*this, regs, externalRegs)); break; } +#endif +#ifdef PANDA3DS_ENABLE_METAL + case RendererType::Metal: { + renderer.reset(new RendererMTL(*this, regs, externalRegs)); + break; + } #endif default: { Helpers::panic("Rendering backend not supported: %s", Renderer::typeToString(config.rendererType)); @@ -365,7 +374,7 @@ PICA::Vertex GPU::getImmediateModeVertex() { // Run VS and return vertex data. TODO: Don't hardcode offsets for each attribute shaderUnit.vs.run(); - + // Map shader outputs to fixed function properties const u32 totalShaderOutputs = regs[PICA::InternalRegs::ShaderOutputCount] & 7; for (int i = 0; i < totalShaderOutputs; i++) { diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index f1949da7..4c187bc2 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -103,6 +103,7 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) const RendererType rendererType = emu->getConfig().rendererType; usingGL = (rendererType == RendererType::OpenGL || rendererType == RendererType::Software || rendererType == RendererType::Null); usingVk = (rendererType == RendererType::Vulkan); + usingMtl = (rendererType == RendererType::Metal); if (usingGL) { // Make GL context current for this thread, enable VSync @@ -113,6 +114,8 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) emu->initGraphicsContext(glContext); } else if (usingVk) { Helpers::panic("Vulkan on Qt is currently WIP, try the SDL frontend instead!"); + } else if (usingMtl) { + Helpers::panic("Metal on Qt currently doesn't work, try the SDL frontend instead!"); } else { Helpers::panic("Unsupported graphics backend for Qt frontend!"); } @@ -628,4 +631,4 @@ void MainWindow::setupControllerSensors(SDL_GameController* controller) { if (haveGyro) { SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); } -} \ No newline at end of file +} diff --git a/src/panda_sdl/frontend_sdl.cpp b/src/panda_sdl/frontend_sdl.cpp index 8f9f4240..057a4858 100644 --- a/src/panda_sdl/frontend_sdl.cpp +++ b/src/panda_sdl/frontend_sdl.cpp @@ -67,6 +67,16 @@ FrontendSDL::FrontendSDL() : keyboardMappings(InputMappings::defaultKeyboardMapp } #endif +#ifdef PANDA3DS_ENABLE_METAL + if (config.rendererType == RendererType::Metal) { + window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 480, SDL_WINDOW_METAL | SDL_WINDOW_RESIZABLE); + + if (window == nullptr) { + Helpers::warn("Window creation failed: %s", SDL_GetError()); + } + } +#endif + emu.initGraphicsContext(window); } @@ -286,7 +296,7 @@ void FrontendSDL::run() { } break; } - + case SDL_CONTROLLERSENSORUPDATE: { if (event.csensor.sensor == SDL_SENSOR_GYRO) { auto rotation = Gyro::SDL::convertRotation({ @@ -370,4 +380,4 @@ void FrontendSDL::setupControllerSensors(SDL_GameController* controller) { if (haveGyro) { SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); } -} \ No newline at end of file +} diff --git a/src/renderer.cpp b/src/renderer.cpp index 76c3e7a0..6a18df85 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -17,6 +17,7 @@ std::optional Renderer::typeFromString(std::string inString) { {"null", RendererType::Null}, {"nil", RendererType::Null}, {"none", RendererType::Null}, {"gl", RendererType::OpenGL}, {"ogl", RendererType::OpenGL}, {"opengl", RendererType::OpenGL}, {"vk", RendererType::Vulkan}, {"vulkan", RendererType::Vulkan}, {"vulcan", RendererType::Vulkan}, + {"mtl", RendererType::Metal}, {"metal", RendererType::Metal}, {"sw", RendererType::Software}, {"soft", RendererType::Software}, {"software", RendererType::Software}, {"softrast", RendererType::Software}, }; @@ -33,7 +34,8 @@ const char* Renderer::typeToString(RendererType rendererType) { case RendererType::Null: return "null"; case RendererType::OpenGL: return "opengl"; case RendererType::Vulkan: return "vulkan"; + case RendererType::Metal: return "metal"; case RendererType::Software: return "software"; default: return "Invalid"; } -} \ No newline at end of file +}