From 68698ae7a722d3e528c4de16ba2ff8cbda2a6758 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sun, 18 Sep 2022 17:30:26 +0300 Subject: [PATCH] Add GSP::GPU::AcquireRight --- include/kernel/kernel.hpp | 3 ++- include/opengl.hpp | 13 +++++++++++++ include/services/gsp_gpu.hpp | 8 +++++++- include/services/service_manager.hpp | 2 +- src/core/services/gsp_gpu.cpp | 26 ++++++++++++++++++++++++-- src/core/services/service_manager.cpp | 5 ++--- 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index f9ec44ef..d8c70be6 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -74,7 +74,8 @@ class Kernel { void outputDebugString(); public: - Kernel(std::array& regs, Memory& mem) : regs(regs), mem(mem), handleCounter(0), serviceManager(regs, mem) { + Kernel(std::array& regs, Memory& mem) + : regs(regs), mem(mem), handleCounter(0), serviceManager(regs, mem, currentProcess) { objects.reserve(512); // Make room for a few objects to avoid further memory allocs later portHandles.reserve(32); } diff --git a/include/opengl.hpp b/include/opengl.hpp index 50911f01..e3424bb1 100644 --- a/include/opengl.hpp +++ b/include/opengl.hpp @@ -331,6 +331,17 @@ namespace OpenGL { } }; + enum DepthFunc { + Never = GL_NEVER, // Depth test never passes + Always = GL_ALWAYS, // Depth test always passes + Equal = GL_EQUAL, // Depth test passes if frag z == depth buffer z + NotEqual = GL_NOTEQUAL, // Depth test passes if frag z != depth buffer z + Less = GL_LESS, // Depth test passes if frag z < depth buffer z + Lequal = GL_LEQUAL, // Depth test passes if frag z <= depth buffer z + Greater = GL_GREATER, // Depth test passes if frag z > depth buffer z + Gequal = GL_GEQUAL, // Depth test passes if frag z >= depth buffer z + }; + static void setClearColor(float val) { glClearColor(val, val, val, val); } static void setClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); } static void setClearDepth(float depth) { glClearDepthf(depth); } @@ -359,6 +370,8 @@ namespace OpenGL { static void enableStencil() { glEnable(GL_STENCIL_TEST); } static void disableStencil() { glDisable(GL_STENCIL_TEST); } + static void setDepthFunc(DepthFunc func) { glDepthFunc(static_cast(func)); } + enum Primitives { Triangle = GL_TRIANGLES, Triangles = Triangle, diff --git a/include/services/gsp_gpu.hpp b/include/services/gsp_gpu.hpp index 86109a76..55ba66f6 100644 --- a/include/services/gsp_gpu.hpp +++ b/include/services/gsp_gpu.hpp @@ -6,11 +6,17 @@ class GPUService { Handle handle = KernelHandles::GPU; Memory& mem; + u32& currentPID; // Process ID of the current process + + // At any point in time only 1 process has privileges to use rendering functions + // This is the PID of that process + u32 privilegedProcess; // Service commands + void acquireRight(u32 messagePointer); public: - GPUService(Memory& mem) : mem(mem) {} + GPUService(Memory& mem, u32& currentPID) : mem(mem), currentPID(currentPID) {} void reset(); void handleSyncRequest(u32 messagePointer); }; \ No newline at end of file diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 9d5ce610..d19260a1 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -23,7 +23,7 @@ class ServiceManager { void registerClient(u32 messagePointer); public: - ServiceManager(std::array& regs, Memory& mem); + ServiceManager(std::array& regs, Memory& mem, u32& currentPID); void reset(); void handleSyncRequest(u32 messagePointer); diff --git a/src/core/services/gsp_gpu.cpp b/src/core/services/gsp_gpu.cpp index 8daf0280..6d83e951 100644 --- a/src/core/services/gsp_gpu.cpp +++ b/src/core/services/gsp_gpu.cpp @@ -2,6 +2,7 @@ namespace GPUCommands { enum : u32 { + AcquireRight = 0x00160042 }; } @@ -11,11 +12,32 @@ namespace Result { }; } -void GPUService::reset() {} +void GPUService::reset() { + privilegedProcess = 0xFFFFFFFF; // Set the privileged process to an invalid handle +} void GPUService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { - default: Helpers::panic("GPU service requested. Command: %08X\n", command); + case GPUCommands::AcquireRight: acquireRight(messagePointer); break; +; default: Helpers::panic("GPU service requested. Command: %08X\n", command); } +} + +void GPUService::acquireRight(u32 messagePointer) { + const u32 flag = mem.read32(messagePointer + 4); + const u32 pid = mem.read32(messagePointer + 12); + printf("GSP::GPU::acquireRight (flag = %d, pid = %X)\n", flag, pid); + + if (flag != 0) { + Helpers::panic("GSP::GPU::acquireRight with flag != 0 needs to perform additional initialization"); + } + + if (pid == KernelHandles::CurrentProcess) { + privilegedProcess = currentPID; + } else { + privilegedProcess = pid; + } + + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 7bf6f895..3524c8ca 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -1,8 +1,7 @@ #include "services/service_manager.hpp" -ServiceManager::ServiceManager(std::array& regs, Memory& mem) : regs(regs), mem(mem), - apt(mem), hid(mem), fs(mem), - gsp_gpu(mem), gsp_lcd(mem) {} +ServiceManager::ServiceManager(std::array& regs, Memory& mem, u32& currentPID) + : regs(regs), mem(mem), apt(mem), hid(mem), fs(mem), gsp_gpu(mem, currentPID), gsp_lcd(mem) {} void ServiceManager::reset() { apt.reset();