Separate renderer and PICA completely

This commit is contained in:
wheremyfoodat 2023-01-01 22:06:54 +02:00
parent 9f792c2cf5
commit 57ef4e25e7
6 changed files with 65 additions and 37 deletions

View file

@ -78,7 +78,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp inc
include/loader/lz77.hpp include/fs/archive_base.hpp include/fs/archive_ncch.hpp
include/services/dsp.hpp include/services/cfg.hpp include/services/region_codes.hpp
include/fs/archive_save_data.hpp include/fs/archive_sdmc.hpp include/services/ptm.hpp
include/services/mic.hpp include/services/cecd.hpp
include/services/mic.hpp include/services/cecd.hpp include/renderer_gl/renderer_gl.hpp
)
set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp

View file

@ -3,9 +3,9 @@
#include "helpers.hpp"
#include "logger.hpp"
#include "memory.hpp"
#include "opengl.hpp"
#include "PICA/float_types.hpp"
#include "PICA/shader_unit.hpp"
#include "renderer_gl/renderer_gl.hpp"
class GPU {
using vec4f = OpenGL::Vector<Floats::f24, 4>;
@ -20,11 +20,6 @@ class GPU {
static constexpr u32 vramSize = 6_MB;
std::array<u32, regNum> regs; // GPU internal registers
struct Vertex {
OpenGL::vec4 position;
OpenGL::vec4 colour;
};
// Read a value of type T from physical address paddr
// This is necessary because vertex attribute fetching uses physical addresses
template<typename T>
@ -80,32 +75,15 @@ class GPU {
u32 fixedAttribCount = 0; // How many attribute components have we written? When we get to 4 the attr will actually get submitted
std::array<u32, 3> fixedAttrBuff; // Buffer to hold fixed attributes in until they get submitted
// OpenGL renderer state
OpenGL::Framebuffer fbo;
OpenGL::Texture fboTexture;
OpenGL::Program triangleProgram;
OpenGL::Program displayProgram;
OpenGL::VertexArray vao;
OpenGL::VertexBuffer vbo;
GLint alphaControlLoc = -1;
u32 oldAlphaControl = 0;
// Dummy VAO/VBO for blitting the final output
OpenGL::VertexArray dummyVAO;
OpenGL::VertexBuffer dummyVBO;
static constexpr u32 vertexBufferSize = 0x1000;
void drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count);
Renderer renderer;
public:
GPU(Memory& mem);
void initGraphicsContext(); // Initialize graphics context
void getGraphicsContext(); // Set up the graphics context for rendering
void display(); // Display the screen contents onto our window
void initGraphicsContext() { renderer.initGraphicsContext(); }
void getGraphicsContext() { renderer.getGraphicsContext(); }
void display() { renderer.display(); }
void fireDMA(u32 dest, u32 source, u32 size);
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control);
void reset();
// Used by the GSP GPU service for readHwRegs/writeHwRegs/writeHwRegsMasked
@ -115,4 +93,8 @@ public:
// Used when processing GPU command lists
u32 readInternalReg(u32 index);
void writeInternalReg(u32 index, u32 value, u32 mask);
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
renderer.clearBuffer(startAddress, endAddress, value, control);
}
};

View file

@ -25,6 +25,7 @@ namespace Log {
static Logger<false> svcLogger;
static Logger<false> threadLogger;
static Logger<false> gpuLogger;
static Logger<false> rendererLogger;
// Service loggers
static Logger<false> aptLogger;

View file

@ -0,0 +1,44 @@
#pragma once
#include <array>
#include "helpers.hpp"
#include "logger.hpp"
#include "opengl.hpp"
struct Vertex {
OpenGL::vec4 position;
OpenGL::vec4 colour;
};
class Renderer {
// OpenGL renderer state
OpenGL::Framebuffer fbo;
OpenGL::Texture fboTexture;
OpenGL::Program triangleProgram;
OpenGL::Program displayProgram;
OpenGL::VertexArray vao;
OpenGL::VertexBuffer vbo;
GLint alphaControlLoc = -1;
u32 oldAlphaControl = 0;
// Dummy VAO/VBO for blitting the final output
OpenGL::VertexArray dummyVAO;
OpenGL::VertexBuffer dummyVBO;
static constexpr u32 regNum = 0x300; // Number of internal PICA registers
const std::array<u32, regNum>& regs;
MAKE_LOG_FUNCTION(log, rendererLogger)
public:
Renderer(const std::array<u32, regNum>& internalRegs) : regs(internalRegs) {}
void reset();
void display(); // Display the 3DS screen contents to the window
void initGraphicsContext(); // Initialize graphics context
void getGraphicsContext(); // Set up graphics context for rendering
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control); // Clear a GPU buffer in VRAM
void drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count); // Draw the given vertices
static constexpr u32 vertexBufferSize = 0x1500;
};

View file

@ -6,6 +6,7 @@
using namespace Floats;
GPU::GPU(Memory& mem) : mem(mem) {
GPU::GPU(Memory& mem) : mem(mem), renderer(regs) {
vram = new u8[vramSize];
}
@ -49,12 +50,13 @@ void GPU::drawArrays() {
const u32 primType = (primConfig >> 8) & 3;
if (primType != 0 && primType != 1) Helpers::panic("[PICA] Tried to draw unimplemented shape %d\n", primType);
if (vertexCount > vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize");
if (vertexCount > Renderer::vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize");
if ((primType == 0 && vertexCount % 3) || (primType == 1 && vertexCount < 3)) {
Helpers::panic("Invalid vertex count for primitive. Type: %d, vert count: %d\n", primType, vertexCount);
}
Vertex vertices[vertexBufferSize];
Vertex vertices[Renderer::vertexBufferSize];
// Get the configuration for the index buffer, used only for indexed drawing
u32 indexBufferConfig = regs[PICAInternalRegs::IndexBufferConfig];
@ -157,7 +159,7 @@ void GPU::drawArrays() {
OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::LineStrip
};
const auto shape = primTypes[primType];
drawVertices(shape, vertices, vertexCount);
renderer.drawVertices(shape, vertices, vertexCount);
}
void GPU::fireDMA(u32 dest, u32 source, u32 size) {

View file

@ -1,7 +1,6 @@
#include "renderer_gl/renderer_gl.hpp"
#include "PICA/float_types.hpp"
#include "PICA/gpu.hpp"
#include "PICA/regs.hpp"
#include "opengl.hpp"
using namespace Floats;
@ -106,7 +105,7 @@ const char* displayFragmentShader = R"(
}
)";
void GPU::initGraphicsContext() {
void Renderer::initGraphicsContext() {
// Set up texture for top screen
fboTexture.create(400, 240, GL_RGBA8);
fboTexture.bind();
@ -159,7 +158,7 @@ void GPU::initGraphicsContext() {
dummyVAO.create();
}
void GPU::getGraphicsContext() {
void Renderer::getGraphicsContext() {
OpenGL::disableScissor();
OpenGL::setViewport(400, 240);
fbo.bind(OpenGL::DrawAndReadFramebuffer);
@ -169,7 +168,7 @@ void GPU::getGraphicsContext() {
triangleProgram.use();
}
void GPU::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count) {
void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count) {
// Adjust alpha test if necessary
const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig];
if (alphaControl != oldAlphaControl) {
@ -220,7 +219,7 @@ constexpr u32 topScreenBuffer = 0x1f000000;
constexpr u32 bottomScreenBuffer = 0x1f05dc00;
// Quick hack to display top screen for now
void GPU::display() {
void Renderer::display() {
OpenGL::disableDepth();
OpenGL::disableScissor();
OpenGL::bindScreenFramebuffer();
@ -234,7 +233,7 @@ void GPU::display() {
OpenGL::draw(OpenGL::TriangleStrip, 4);
}
void GPU::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
void Renderer::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
log("GPU: Clear buffer\nStart: %08X End: %08X\nValue: %08X Control: %08X\n", startAddress, endAddress, value, control);
const float r = float((value >> 24) & 0xff) / 255.0;