mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 23:25:40 +12:00
[PICA] Rework how external registers work, format
This commit is contained in:
parent
a8a76ab64d
commit
9695b57bf5
13 changed files with 54 additions and 38 deletions
|
@ -14,8 +14,11 @@
|
||||||
|
|
||||||
class GPU {
|
class GPU {
|
||||||
static constexpr u32 regNum = 0x300;
|
static constexpr u32 regNum = 0x300;
|
||||||
|
static constexpr u32 extRegNum = 0x1000;
|
||||||
|
|
||||||
using vec4f = std::array<Floats::f24, 4>;
|
using vec4f = std::array<Floats::f24, 4>;
|
||||||
using Registers = std::array<u32, regNum>;
|
using Registers = std::array<u32, regNum>; // Internal registers (named registers in short since they're the main ones)
|
||||||
|
using ExternalRegisters = std::array<u32, extRegNum>;
|
||||||
|
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
EmulatorConfig& config;
|
EmulatorConfig& config;
|
||||||
|
@ -29,7 +32,6 @@ class GPU {
|
||||||
static constexpr u32 vramSize = u32(6_MB);
|
static constexpr u32 vramSize = u32(6_MB);
|
||||||
Registers regs; // GPU internal registers
|
Registers regs; // GPU internal registers
|
||||||
std::array<vec4f, 16> currentAttributes; // Vertex attributes before being passed to the shader
|
std::array<vec4f, 16> currentAttributes; // Vertex attributes before being passed to the shader
|
||||||
std::array<u32, 0x1000> external_regs; // GPU external registers
|
|
||||||
|
|
||||||
std::array<vec4f, 16> immediateModeAttributes; // Vertex attributes uploaded via immediate mode submission
|
std::array<vec4f, 16> immediateModeAttributes; // Vertex attributes uploaded via immediate mode submission
|
||||||
std::array<PICA::Vertex, 3> immediateModeVertices;
|
std::array<PICA::Vertex, 3> immediateModeVertices;
|
||||||
|
@ -144,4 +146,10 @@ class GPU {
|
||||||
Helpers::panic("[GPU] Tried to access unknown physical address: %08X", paddr);
|
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,8 +21,11 @@ struct SDL_Window;
|
||||||
class Renderer {
|
class Renderer {
|
||||||
protected:
|
protected:
|
||||||
GPU& gpu;
|
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<u32, regNum>& regs;
|
const std::array<u32, regNum>& regs;
|
||||||
|
const std::array<u32, extRegNum>& externalRegs;
|
||||||
|
|
||||||
std::array<u32, 2> fbSize; // The size of the framebuffer (ie both the colour and depth buffer)'
|
std::array<u32, 2> fbSize; // The size of the framebuffer (ie both the colour and depth buffer)'
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@ class Renderer {
|
||||||
PICA::DepthFmt depthBufferFormat;
|
PICA::DepthFmt depthBufferFormat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs);
|
Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||||
virtual ~Renderer();
|
virtual ~Renderer();
|
||||||
|
|
||||||
static constexpr u32 vertexBufferSize = 0x10000;
|
static constexpr u32 vertexBufferSize = 0x10000;
|
||||||
|
|
|
@ -68,7 +68,8 @@ class RendererGL final : public Renderer {
|
||||||
void updateLightingLUT();
|
void updateLightingLUT();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RendererGL(GPU& gpu, const std::array<u32, regNum>& internalRegs) : Renderer(gpu, internalRegs) {}
|
RendererGL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
: Renderer(gpu, internalRegs, externalRegs) {}
|
||||||
~RendererGL() override;
|
~RendererGL() override;
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
|
@ -4,7 +4,7 @@ class GPU;
|
||||||
|
|
||||||
class RendererNull final : public Renderer {
|
class RendererNull final : public Renderer {
|
||||||
public:
|
public:
|
||||||
RendererNull(GPU& gpu, const std::array<u32, regNum>& internalRegs);
|
RendererNull(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||||
~RendererNull() override;
|
~RendererNull() override;
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
|
@ -4,7 +4,7 @@ class GPU;
|
||||||
|
|
||||||
class RendererSw final : public Renderer {
|
class RendererSw final : public Renderer {
|
||||||
public:
|
public:
|
||||||
RendererSw(GPU& gpu, const std::array<u32, regNum>& internalRegs);
|
RendererSw(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||||
~RendererSw() override;
|
~RendererSw() override;
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
|
@ -44,7 +44,7 @@ class RendererVK final : public Renderer {
|
||||||
|
|
||||||
u64 currentFrame = 0;
|
u64 currentFrame = 0;
|
||||||
public:
|
public:
|
||||||
RendererVK(GPU& gpu, const std::array<u32, regNum>& internalRegs);
|
RendererVK(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||||
~RendererVK() override;
|
~RendererVK() override;
|
||||||
|
|
||||||
void reset() override;
|
void reset() override;
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
#include "renderer_vk/renderer_vk.hpp"
|
#include "renderer_vk/renderer_vk.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr u32 top_screen_width = 240;
|
constexpr u32 topScreenWidth = 240;
|
||||||
constexpr u32 top_screen_height = 400;
|
constexpr u32 topScreenHeight = 400;
|
||||||
|
|
||||||
constexpr u32 bottom_screen_width = 240;
|
constexpr u32 bottomScreenWidth = 240;
|
||||||
constexpr u32 bottom_screen_height = 300;
|
constexpr u32 bottomScreenHeight = 300;
|
||||||
|
|
||||||
using namespace Floats;
|
using namespace Floats;
|
||||||
|
|
||||||
|
@ -32,24 +32,24 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) {
|
||||||
|
|
||||||
switch (config.rendererType) {
|
switch (config.rendererType) {
|
||||||
case RendererType::Null: {
|
case RendererType::Null: {
|
||||||
renderer.reset(new RendererNull(*this, regs));
|
renderer.reset(new RendererNull(*this, regs, externalRegs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RendererType::Software: {
|
case RendererType::Software: {
|
||||||
renderer.reset(new RendererSw(*this, regs));
|
renderer.reset(new RendererSw(*this, regs, externalRegs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
case RendererType::OpenGL: {
|
case RendererType::OpenGL: {
|
||||||
renderer.reset(new RendererGL(*this, regs));
|
renderer.reset(new RendererGL(*this, regs, externalRegs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef PANDA3DS_ENABLE_VULKAN
|
#ifdef PANDA3DS_ENABLE_VULKAN
|
||||||
case RendererType::Vulkan: {
|
case RendererType::Vulkan: {
|
||||||
renderer.reset(new RendererVK(*this, regs));
|
renderer.reset(new RendererVK(*this, regs, externalRegs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -88,22 +88,22 @@ void GPU::reset() {
|
||||||
|
|
||||||
using namespace PICA::ExternalRegs;
|
using namespace PICA::ExternalRegs;
|
||||||
// Top screen addresses and dimentions.
|
// Top screen addresses and dimentions.
|
||||||
external_regs[Framebuffer0AFirstAddr] = 0x181E6000;
|
externalRegs[Framebuffer0AFirstAddr] = 0x181E6000;
|
||||||
external_regs[Framebuffer0ASecondAddr] = 0x1822C800;
|
externalRegs[Framebuffer0ASecondAddr] = 0x1822C800;
|
||||||
external_regs[Framebuffer0BFirstAddr] = 0x18273000;
|
externalRegs[Framebuffer0BFirstAddr] = 0x18273000;
|
||||||
external_regs[Framebuffer0BSecondAddr] = 0x182B9800;
|
externalRegs[Framebuffer0BSecondAddr] = 0x182B9800;
|
||||||
external_regs[Framebuffer0Size] = (top_screen_height << 16) | top_screen_width;
|
externalRegs[Framebuffer0Size] = (topScreenHeight << 16) | topScreenWidth;
|
||||||
external_regs[Framebuffer0Stride] = 720;
|
externalRegs[Framebuffer0Stride] = 720;
|
||||||
external_regs[Framebuffer0Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
externalRegs[Framebuffer0Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
||||||
external_regs[Framebuffer0Select] = 0;
|
externalRegs[Framebuffer0Select] = 0;
|
||||||
|
|
||||||
// Bottom screen addresses and dimentions.
|
// Bottom screen addresses and dimentions.
|
||||||
external_regs[Framebuffer1AFirstAddr] = 0x1848F000;
|
externalRegs[Framebuffer1AFirstAddr] = 0x1848F000;
|
||||||
external_regs[Framebuffer1ASecondAddr] = 0x184C7800;
|
externalRegs[Framebuffer1ASecondAddr] = 0x184C7800;
|
||||||
external_regs[Framebuffer1Size] = (bottom_screen_height << 16) | bottom_screen_width;
|
externalRegs[Framebuffer1Size] = (bottomScreenHeight << 16) | bottomScreenWidth;
|
||||||
external_regs[Framebuffer1Stride] = 720;
|
externalRegs[Framebuffer1Stride] = 720;
|
||||||
external_regs[Framebuffer1Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
externalRegs[Framebuffer1Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
||||||
external_regs[Framebuffer1Select] = 0;
|
externalRegs[Framebuffer1Select] = 0;
|
||||||
|
|
||||||
renderer->reset();
|
renderer->reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ u32 GPU::readExternalReg(u32 index) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return external_regs[index];
|
return externalRegs[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::writeExternalReg(u32 index, u32 value) {
|
void GPU::writeExternalReg(u32 index, u32 value) {
|
||||||
|
@ -46,7 +46,7 @@ void GPU::writeExternalReg(u32 index, u32 value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
external_regs[index] = value;
|
externalRegs[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GPU::readInternalReg(u32 index) {
|
u32 GPU::readInternalReg(u32 index) {
|
||||||
|
|
|
@ -461,8 +461,8 @@ void RendererGL::display() {
|
||||||
OpenGL::disableClipPlane(1);
|
OpenGL::disableClipPlane(1);
|
||||||
|
|
||||||
using namespace PICA::ExternalRegs;
|
using namespace PICA::ExternalRegs;
|
||||||
const u32 topScreenAddr = gpu.readExternalReg(Framebuffer0AFirstAddr);
|
const u32 topScreenAddr = externalRegs[Framebuffer0AFirstAddr];
|
||||||
const u32 bottomScreenAddr = gpu.readExternalReg(Framebuffer1AFirstAddr);
|
const u32 bottomScreenAddr = externalRegs[Framebuffer1AFirstAddr];
|
||||||
|
|
||||||
auto topScreen = colourBufferCache.findFromAddress(topScreenAddr);
|
auto topScreen = colourBufferCache.findFromAddress(topScreenAddr);
|
||||||
auto bottomScreen = colourBufferCache.findFromAddress(bottomScreenAddr);
|
auto bottomScreen = colourBufferCache.findFromAddress(bottomScreenAddr);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "renderer_null/renderer_null.hpp"
|
#include "renderer_null/renderer_null.hpp"
|
||||||
|
|
||||||
RendererNull::RendererNull(GPU& gpu, const std::array<u32, regNum>& internalRegs) : Renderer(gpu, internalRegs) {}
|
RendererNull::RendererNull(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
: Renderer(gpu, internalRegs, externalRegs) {}
|
||||||
RendererNull::~RendererNull() {}
|
RendererNull::~RendererNull() {}
|
||||||
|
|
||||||
void RendererNull::reset() {}
|
void RendererNull::reset() {}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "renderer_sw/renderer_sw.hpp"
|
#include "renderer_sw/renderer_sw.hpp"
|
||||||
|
|
||||||
RendererSw::RendererSw(GPU& gpu, const std::array<u32, regNum>& internalRegs) : Renderer(gpu, internalRegs) {}
|
RendererSw::RendererSw(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
: Renderer(gpu, internalRegs, externalRegs) {}
|
||||||
RendererSw::~RendererSw() {}
|
RendererSw::~RendererSw() {}
|
||||||
|
|
||||||
void RendererSw::reset() { printf("RendererSW: Unimplemented reset call\n"); }
|
void RendererSw::reset() { printf("RendererSW: Unimplemented reset call\n"); }
|
||||||
|
|
|
@ -200,7 +200,8 @@ vk::Result RendererVK::recreateSwapchain(vk::SurfaceKHR surface, vk::Extent2D sw
|
||||||
return vk::Result::eSuccess;
|
return vk::Result::eSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererVK::RendererVK(GPU& gpu, const std::array<u32, regNum>& internalRegs) : Renderer(gpu, internalRegs) {}
|
RendererVK::RendererVK(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
: Renderer(gpu, internalRegs, externalRegs) {}
|
||||||
|
|
||||||
RendererVK::~RendererVK() {}
|
RendererVK::~RendererVK() {}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
Renderer::Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs) : gpu(gpu), regs(internalRegs) {}
|
Renderer::Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
: gpu(gpu), regs(internalRegs), externalRegs(externalRegs) {}
|
||||||
Renderer::~Renderer() {}
|
Renderer::~Renderer() {}
|
||||||
|
|
||||||
std::optional<RendererType> Renderer::typeFromString(std::string inString) {
|
std::optional<RendererType> Renderer::typeFromString(std::string inString) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue