diff --git a/include/PICA/gpu.hpp b/include/PICA/gpu.hpp index 338aba9b..955fb0ae 100644 --- a/include/PICA/gpu.hpp +++ b/include/PICA/gpu.hpp @@ -14,8 +14,11 @@ class GPU { static constexpr u32 regNum = 0x300; + static constexpr u32 extRegNum = 0x1000; + using vec4f = std::array; - using Registers = std::array; + using Registers = std::array; // Internal registers (named registers in short since they're the main ones) + using ExternalRegisters = std::array; Memory& mem; EmulatorConfig& config; @@ -29,7 +32,6 @@ class GPU { static constexpr u32 vramSize = u32(6_MB); Registers regs; // GPU internal registers std::array currentAttributes; // Vertex attributes before being passed to the shader - std::array external_regs; // GPU external registers std::array immediateModeAttributes; // Vertex attributes uploaded via immediate mode submission std::array immediateModeVertices; @@ -144,4 +146,10 @@ class GPU { Helpers::panic("[GPU] Tried to access unknown physical address: %08X", paddr); } } + + private: + // GPU external registers + // We have them in the end of the struct for cache locality reasons. Tl;dr we want the more commonly used things to be packed in the start + // Of the struct, instead of externalRegs being in the middle + ExternalRegisters externalRegs; }; diff --git a/include/renderer.hpp b/include/renderer.hpp index 230c7d89..fff25ab5 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -21,8 +21,11 @@ struct SDL_Window; class Renderer { protected: GPU& gpu; - static constexpr u32 regNum = 0x300; // Number of internal PICA registers + static constexpr u32 regNum = 0x300; // Number of internal PICA registers + static constexpr u32 extRegNum = 0x1000; // Number of external PICA registers + const std::array& regs; + const std::array& externalRegs; std::array fbSize; // The size of the framebuffer (ie both the colour and depth buffer)' @@ -34,7 +37,7 @@ class Renderer { PICA::DepthFmt depthBufferFormat; public: - Renderer(GPU& gpu, const std::array& internalRegs); + Renderer(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs); virtual ~Renderer(); static constexpr u32 vertexBufferSize = 0x10000; diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index a69d7623..52d97524 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -68,7 +68,8 @@ class RendererGL final : public Renderer { void updateLightingLUT(); public: - RendererGL(GPU& gpu, const std::array& internalRegs) : Renderer(gpu, internalRegs) {} + RendererGL(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) + : Renderer(gpu, internalRegs, externalRegs) {} ~RendererGL() override; void reset() override; diff --git a/include/renderer_null/renderer_null.hpp b/include/renderer_null/renderer_null.hpp index 05de067c..22293ba6 100644 --- a/include/renderer_null/renderer_null.hpp +++ b/include/renderer_null/renderer_null.hpp @@ -4,7 +4,7 @@ class GPU; class RendererNull final : public Renderer { public: - RendererNull(GPU& gpu, const std::array& internalRegs); + RendererNull(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs); ~RendererNull() override; void reset() override; diff --git a/include/renderer_sw/renderer_sw.hpp b/include/renderer_sw/renderer_sw.hpp index 5c42e188..171fc084 100644 --- a/include/renderer_sw/renderer_sw.hpp +++ b/include/renderer_sw/renderer_sw.hpp @@ -4,7 +4,7 @@ class GPU; class RendererSw final : public Renderer { public: - RendererSw(GPU& gpu, const std::array& internalRegs); + RendererSw(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs); ~RendererSw() override; void reset() override; diff --git a/include/renderer_vk/renderer_vk.hpp b/include/renderer_vk/renderer_vk.hpp index 5e621bdc..4b6e65b0 100644 --- a/include/renderer_vk/renderer_vk.hpp +++ b/include/renderer_vk/renderer_vk.hpp @@ -44,7 +44,7 @@ class RendererVK final : public Renderer { u64 currentFrame = 0; public: - RendererVK(GPU& gpu, const std::array& internalRegs); + RendererVK(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs); ~RendererVK() override; void reset() override; diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 755bc2f4..3668b32f 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -16,11 +16,11 @@ #include "renderer_vk/renderer_vk.hpp" #endif -constexpr u32 top_screen_width = 240; -constexpr u32 top_screen_height = 400; +constexpr u32 topScreenWidth = 240; +constexpr u32 topScreenHeight = 400; -constexpr u32 bottom_screen_width = 240; -constexpr u32 bottom_screen_height = 300; +constexpr u32 bottomScreenWidth = 240; +constexpr u32 bottomScreenHeight = 300; using namespace Floats; @@ -32,24 +32,24 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) { switch (config.rendererType) { case RendererType::Null: { - renderer.reset(new RendererNull(*this, regs)); + renderer.reset(new RendererNull(*this, regs, externalRegs)); break; } case RendererType::Software: { - renderer.reset(new RendererSw(*this, regs)); + renderer.reset(new RendererSw(*this, regs, externalRegs)); break; } #ifdef PANDA3DS_ENABLE_OPENGL case RendererType::OpenGL: { - renderer.reset(new RendererGL(*this, regs)); + renderer.reset(new RendererGL(*this, regs, externalRegs)); break; } #endif #ifdef PANDA3DS_ENABLE_VULKAN case RendererType::Vulkan: { - renderer.reset(new RendererVK(*this, regs)); + renderer.reset(new RendererVK(*this, regs, externalRegs)); break; } #endif @@ -88,22 +88,22 @@ void GPU::reset() { using namespace PICA::ExternalRegs; // Top screen addresses and dimentions. - external_regs[Framebuffer0AFirstAddr] = 0x181E6000; - external_regs[Framebuffer0ASecondAddr] = 0x1822C800; - external_regs[Framebuffer0BFirstAddr] = 0x18273000; - external_regs[Framebuffer0BSecondAddr] = 0x182B9800; - external_regs[Framebuffer0Size] = (top_screen_height << 16) | top_screen_width; - external_regs[Framebuffer0Stride] = 720; - external_regs[Framebuffer0Config] = static_cast(PICA::ColorFmt::RGB8); - external_regs[Framebuffer0Select] = 0; + externalRegs[Framebuffer0AFirstAddr] = 0x181E6000; + externalRegs[Framebuffer0ASecondAddr] = 0x1822C800; + externalRegs[Framebuffer0BFirstAddr] = 0x18273000; + externalRegs[Framebuffer0BSecondAddr] = 0x182B9800; + externalRegs[Framebuffer0Size] = (topScreenHeight << 16) | topScreenWidth; + externalRegs[Framebuffer0Stride] = 720; + externalRegs[Framebuffer0Config] = static_cast(PICA::ColorFmt::RGB8); + externalRegs[Framebuffer0Select] = 0; // Bottom screen addresses and dimentions. - external_regs[Framebuffer1AFirstAddr] = 0x1848F000; - external_regs[Framebuffer1ASecondAddr] = 0x184C7800; - external_regs[Framebuffer1Size] = (bottom_screen_height << 16) | bottom_screen_width; - external_regs[Framebuffer1Stride] = 720; - external_regs[Framebuffer1Config] = static_cast(PICA::ColorFmt::RGB8); - external_regs[Framebuffer1Select] = 0; + externalRegs[Framebuffer1AFirstAddr] = 0x1848F000; + externalRegs[Framebuffer1ASecondAddr] = 0x184C7800; + externalRegs[Framebuffer1Size] = (bottomScreenHeight << 16) | bottomScreenWidth; + externalRegs[Framebuffer1Stride] = 720; + externalRegs[Framebuffer1Config] = static_cast(PICA::ColorFmt::RGB8); + externalRegs[Framebuffer1Select] = 0; renderer->reset(); } diff --git a/src/core/PICA/regs.cpp b/src/core/PICA/regs.cpp index 04261526..baaa2256 100644 --- a/src/core/PICA/regs.cpp +++ b/src/core/PICA/regs.cpp @@ -35,7 +35,7 @@ u32 GPU::readExternalReg(u32 index) { return -1; } - return external_regs[index]; + return externalRegs[index]; } void GPU::writeExternalReg(u32 index, u32 value) { @@ -46,7 +46,7 @@ void GPU::writeExternalReg(u32 index, u32 value) { return; } - external_regs[index] = value; + externalRegs[index] = value; } u32 GPU::readInternalReg(u32 index) { diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index d59cfa17..4aa4fcc7 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -461,8 +461,8 @@ void RendererGL::display() { OpenGL::disableClipPlane(1); using namespace PICA::ExternalRegs; - const u32 topScreenAddr = gpu.readExternalReg(Framebuffer0AFirstAddr); - const u32 bottomScreenAddr = gpu.readExternalReg(Framebuffer1AFirstAddr); + const u32 topScreenAddr = externalRegs[Framebuffer0AFirstAddr]; + const u32 bottomScreenAddr = externalRegs[Framebuffer1AFirstAddr]; auto topScreen = colourBufferCache.findFromAddress(topScreenAddr); auto bottomScreen = colourBufferCache.findFromAddress(bottomScreenAddr); diff --git a/src/core/renderer_null/renderer_null.cpp b/src/core/renderer_null/renderer_null.cpp index 44a44aa5..546d8a81 100644 --- a/src/core/renderer_null/renderer_null.cpp +++ b/src/core/renderer_null/renderer_null.cpp @@ -1,6 +1,7 @@ #include "renderer_null/renderer_null.hpp" -RendererNull::RendererNull(GPU& gpu, const std::array& internalRegs) : Renderer(gpu, internalRegs) {} +RendererNull::RendererNull(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) + : Renderer(gpu, internalRegs, externalRegs) {} RendererNull::~RendererNull() {} void RendererNull::reset() {} diff --git a/src/core/renderer_sw/renderer_sw.cpp b/src/core/renderer_sw/renderer_sw.cpp index 9c15d6f8..1ea452ae 100644 --- a/src/core/renderer_sw/renderer_sw.cpp +++ b/src/core/renderer_sw/renderer_sw.cpp @@ -1,6 +1,7 @@ #include "renderer_sw/renderer_sw.hpp" -RendererSw::RendererSw(GPU& gpu, const std::array& internalRegs) : Renderer(gpu, internalRegs) {} +RendererSw::RendererSw(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) + : Renderer(gpu, internalRegs, externalRegs) {} RendererSw::~RendererSw() {} void RendererSw::reset() { printf("RendererSW: Unimplemented reset call\n"); } diff --git a/src/core/renderer_vk/renderer_vk.cpp b/src/core/renderer_vk/renderer_vk.cpp index e13a1597..23048f51 100644 --- a/src/core/renderer_vk/renderer_vk.cpp +++ b/src/core/renderer_vk/renderer_vk.cpp @@ -200,7 +200,8 @@ vk::Result RendererVK::recreateSwapchain(vk::SurfaceKHR surface, vk::Extent2D sw return vk::Result::eSuccess; } -RendererVK::RendererVK(GPU& gpu, const std::array& internalRegs) : Renderer(gpu, internalRegs) {} +RendererVK::RendererVK(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) + : Renderer(gpu, internalRegs, externalRegs) {} RendererVK::~RendererVK() {} diff --git a/src/renderer.cpp b/src/renderer.cpp index 22d0accb..76c3e7a0 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -3,7 +3,8 @@ #include #include -Renderer::Renderer(GPU& gpu, const std::array& internalRegs) : gpu(gpu), regs(internalRegs) {} +Renderer::Renderer(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) + : gpu(gpu), regs(internalRegs), externalRegs(externalRegs) {} Renderer::~Renderer() {} std::optional Renderer::typeFromString(std::string inString) {