mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 23:25:40 +12:00
Cleanup for #98
This commit is contained in:
parent
2f45714240
commit
7b6cd90d36
10 changed files with 95 additions and 33 deletions
|
@ -49,6 +49,7 @@ class ShaderEmitter : public Xbyak::CodeGenerator {
|
||||||
const u32 opcode = instruction >> 26;
|
const u32 opcode = instruction >> 26;
|
||||||
return (opcode == ShaderOpcodes::CALL) || (opcode == ShaderOpcodes::CALLC) || (opcode == ShaderOpcodes::CALLU);
|
return (opcode == ShaderOpcodes::CALL) || (opcode == ShaderOpcodes::CALLC) || (opcode == ShaderOpcodes::CALLU);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the shader code for call instructions to fill up the returnPCs vector before starting compilation
|
// Scan the shader code for call instructions to fill up the returnPCs vector before starting compilation
|
||||||
void scanForCalls(const PICAShader& shaderUnit);
|
void scanForCalls(const PICAShader& shaderUnit);
|
||||||
|
|
||||||
|
@ -106,9 +107,11 @@ class ShaderEmitter : public Xbyak::CodeGenerator {
|
||||||
MAKE_LOG_FUNCTION(log, shaderJITLogger)
|
MAKE_LOG_FUNCTION(log, shaderJITLogger)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using InstructionCallback = const void (*)(PICAShader& shaderUnit); // Callback type used for instructions
|
// Callback type used for instructions
|
||||||
|
using InstructionCallback = const void (*)(PICAShader& shaderUnit);
|
||||||
// Callback type used for the JIT prologue. This is what the caller will call
|
// Callback type used for the JIT prologue. This is what the caller will call
|
||||||
using PrologueCallback = const void (*)(PICAShader& shaderUnit, InstructionCallback cb);
|
using PrologueCallback = const void (*)(PICAShader& shaderUnit, InstructionCallback cb);
|
||||||
|
|
||||||
PrologueCallback prologueCb = nullptr;
|
PrologueCallback prologueCb = nullptr;
|
||||||
|
|
||||||
// Initialize our emitter with "allocSize" bytes of RWX memory
|
// Initialize our emitter with "allocSize" bytes of RWX memory
|
||||||
|
|
|
@ -103,7 +103,9 @@ class GPU {
|
||||||
|
|
||||||
// TODO: Emulate the transfer engine & its registers
|
// TODO: Emulate the transfer engine & its registers
|
||||||
// Then this can be emulated by just writing the appropriate values there
|
// Then this can be emulated by just writing the appropriate values there
|
||||||
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) { renderer->clearBuffer(startAddress, endAddress, value, control); }
|
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) {
|
||||||
|
renderer->clearBuffer(startAddress, endAddress, value, control);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Emulate the transfer engine & its registers
|
// TODO: Emulate the transfer engine & its registers
|
||||||
// Then this can be emulated by just writing the appropriate values there
|
// Then this can be emulated by just writing the appropriate values there
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
#include "PICA/pica_hash.hpp"
|
#include "PICA/pica_hash.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
enum class ShaderType { Vertex, Geometry };
|
enum class ShaderType {
|
||||||
|
Vertex,
|
||||||
|
Geometry,
|
||||||
|
};
|
||||||
|
|
||||||
namespace ShaderOpcodes {
|
namespace ShaderOpcodes {
|
||||||
enum : u32 {
|
enum : u32 {
|
||||||
|
@ -221,11 +224,13 @@ class PICAShader {
|
||||||
void finalize() { std::memcpy(&loadedShader[0], &bufferedShader[0], 4096 * sizeof(u32)); }
|
void finalize() { std::memcpy(&loadedShader[0], &bufferedShader[0], 4096 * sizeof(u32)); }
|
||||||
|
|
||||||
void setBufferIndex(u32 index) { bufferIndex = index & 0xfff; }
|
void setBufferIndex(u32 index) { bufferIndex = index & 0xfff; }
|
||||||
|
|
||||||
void setOpDescriptorIndex(u32 index) { opDescriptorIndex = index & 0x7f; }
|
void setOpDescriptorIndex(u32 index) { opDescriptorIndex = index & 0x7f; }
|
||||||
|
|
||||||
void uploadWord(u32 word) {
|
void uploadWord(u32 word) {
|
||||||
if (bufferIndex >= 4095) Helpers::panic("o no, shader upload overflew");
|
if (bufferIndex >= 4095) {
|
||||||
|
Helpers::panic("o no, shader upload overflew");
|
||||||
|
}
|
||||||
|
|
||||||
bufferedShader[bufferIndex++] = word;
|
bufferedShader[bufferIndex++] = word;
|
||||||
bufferIndex &= 0xfff;
|
bufferIndex &= 0xfff;
|
||||||
|
|
||||||
|
@ -247,7 +252,9 @@ class PICAShader {
|
||||||
|
|
||||||
void uploadFloatUniform(u32 word) {
|
void uploadFloatUniform(u32 word) {
|
||||||
floatUniformBuffer[floatUniformWordCount++] = word;
|
floatUniformBuffer[floatUniformWordCount++] = word;
|
||||||
if (floatUniformIndex >= 96) Helpers::panic("[PICA] Tried to write float uniform %d", floatUniformIndex);
|
if (floatUniformIndex >= 96) {
|
||||||
|
Helpers::panic("[PICA] Tried to write float uniform %d", floatUniformIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if ((f32UniformTransfer && floatUniformWordCount >= 4) || (!f32UniformTransfer && floatUniformWordCount >= 3)) {
|
if ((f32UniformTransfer && floatUniformWordCount >= 4) || (!f32UniformTransfer && floatUniformWordCount >= 3)) {
|
||||||
vec4f& uniform = floatUniforms[floatUniformIndex++];
|
vec4f& uniform = floatUniforms[floatUniformIndex++];
|
||||||
|
|
|
@ -17,7 +17,12 @@
|
||||||
#include "httpserver.hpp"
|
#include "httpserver.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum class ROMType { None, ELF, NCSD, CXI };
|
enum class ROMType {
|
||||||
|
None,
|
||||||
|
ELF,
|
||||||
|
NCSD,
|
||||||
|
CXI,
|
||||||
|
};
|
||||||
|
|
||||||
class Emulator {
|
class Emulator {
|
||||||
CPU cpu;
|
CPU cpu;
|
||||||
|
@ -29,7 +34,7 @@ class Emulator {
|
||||||
EmulatorConfig config;
|
EmulatorConfig config;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
|
|
||||||
#if PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stb_image_write.h>
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "PICA/regs.hpp"
|
#include "PICA/regs.hpp"
|
||||||
|
|
||||||
#if PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
#include "renderer_gl/renderer_gl.hpp"
|
#include "renderer_gl/renderer_gl.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) {
|
||||||
vram = new u8[vramSize];
|
vram = new u8[vramSize];
|
||||||
mem.setVRAM(vram); // Give the bus a pointer to our VRAM
|
mem.setVRAM(vram); // Give the bus a pointer to our VRAM
|
||||||
|
|
||||||
// TODO: configurable backend
|
// TODO: Configurable backend
|
||||||
#if PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
renderer.reset(new RendererGL(*this, regs));
|
renderer.reset(new RendererGL(*this, regs));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,10 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VertexFloatUniformIndex: shaderUnit.vs.setFloatUniformIndex(value); break;
|
case VertexFloatUniformIndex: {
|
||||||
|
shaderUnit.vs.setFloatUniformIndex(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexFloatUniformData0:
|
case VertexFloatUniformData0:
|
||||||
case VertexFloatUniformData1:
|
case VertexFloatUniformData1:
|
||||||
|
@ -143,7 +146,10 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
case VertexFloatUniformData4:
|
case VertexFloatUniformData4:
|
||||||
case VertexFloatUniformData5:
|
case VertexFloatUniformData5:
|
||||||
case VertexFloatUniformData6:
|
case VertexFloatUniformData6:
|
||||||
case VertexFloatUniformData7: shaderUnit.vs.uploadFloatUniform(value); break;
|
case VertexFloatUniformData7: {
|
||||||
|
shaderUnit.vs.uploadFloatUniform(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case FixedAttribIndex:
|
case FixedAttribIndex:
|
||||||
fixedAttribCount = 0;
|
fixedAttribCount = 0;
|
||||||
|
@ -208,7 +214,10 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
switch (primType) {
|
switch (primType) {
|
||||||
// Triangle or geometry primitive. Draw a triangle and discard all vertices
|
// Triangle or geometry primitive. Draw a triangle and discard all vertices
|
||||||
case 0:
|
case 0:
|
||||||
case 3: immediateModeVertIndex = 0; break;
|
case 3: {
|
||||||
|
immediateModeVertIndex = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Triangle strip. Draw triangle, discard first vertex and keep the last 2
|
// Triangle strip. Draw triangle, discard first vertex and keep the last 2
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -233,7 +242,10 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VertexShaderOpDescriptorIndex: shaderUnit.vs.setOpDescriptorIndex(value); break;
|
case VertexShaderOpDescriptorIndex: {
|
||||||
|
shaderUnit.vs.setOpDescriptorIndex(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexShaderOpDescriptorData0:
|
case VertexShaderOpDescriptorData0:
|
||||||
case VertexShaderOpDescriptorData1:
|
case VertexShaderOpDescriptorData1:
|
||||||
|
@ -242,14 +254,23 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
case VertexShaderOpDescriptorData4:
|
case VertexShaderOpDescriptorData4:
|
||||||
case VertexShaderOpDescriptorData5:
|
case VertexShaderOpDescriptorData5:
|
||||||
case VertexShaderOpDescriptorData6:
|
case VertexShaderOpDescriptorData6:
|
||||||
case VertexShaderOpDescriptorData7: shaderUnit.vs.uploadDescriptor(value); break;
|
case VertexShaderOpDescriptorData7: {
|
||||||
|
shaderUnit.vs.uploadDescriptor(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexBoolUniform: shaderUnit.vs.boolUniform = value & 0xffff; break;
|
case VertexBoolUniform: {
|
||||||
|
shaderUnit.vs.boolUniform = value & 0xffff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexIntUniform0:
|
case VertexIntUniform0:
|
||||||
case VertexIntUniform1:
|
case VertexIntUniform1:
|
||||||
case VertexIntUniform2:
|
case VertexIntUniform2:
|
||||||
case VertexIntUniform3: shaderUnit.vs.uploadIntUniform(index - VertexIntUniform0, value); break;
|
case VertexIntUniform3: {
|
||||||
|
shaderUnit.vs.uploadIntUniform(index - VertexIntUniform0, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexShaderData0:
|
case VertexShaderData0:
|
||||||
case VertexShaderData1:
|
case VertexShaderData1:
|
||||||
|
@ -258,9 +279,15 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
case VertexShaderData4:
|
case VertexShaderData4:
|
||||||
case VertexShaderData5:
|
case VertexShaderData5:
|
||||||
case VertexShaderData6:
|
case VertexShaderData6:
|
||||||
case VertexShaderData7: shaderUnit.vs.uploadWord(value); break;
|
case VertexShaderData7: {
|
||||||
|
shaderUnit.vs.uploadWord(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexShaderEntrypoint: shaderUnit.vs.entrypoint = value & 0xffff; break;
|
case VertexShaderEntrypoint: {
|
||||||
|
shaderUnit.vs.entrypoint = value & 0xffff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VertexShaderTransferEnd:
|
case VertexShaderTransferEnd:
|
||||||
if (value != 0) shaderUnit.vs.finalize();
|
if (value != 0) shaderUnit.vs.finalize();
|
||||||
|
|
|
@ -20,7 +20,11 @@ void PICAShader::run() {
|
||||||
case ShaderOpcodes::CALLC: callc(instruction); break;
|
case ShaderOpcodes::CALLC: callc(instruction); break;
|
||||||
case ShaderOpcodes::CALLU: callu(instruction); break;
|
case ShaderOpcodes::CALLU: callu(instruction); break;
|
||||||
case ShaderOpcodes::CMP1:
|
case ShaderOpcodes::CMP1:
|
||||||
case ShaderOpcodes::CMP2: cmp(instruction); break;
|
case ShaderOpcodes::CMP2: {
|
||||||
|
cmp(instruction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ShaderOpcodes::DP3: dp3(instruction); break;
|
case ShaderOpcodes::DP3: dp3(instruction); break;
|
||||||
case ShaderOpcodes::DP4: dp4(instruction); break;
|
case ShaderOpcodes::DP4: dp4(instruction); break;
|
||||||
case ShaderOpcodes::DPHI: dphi(instruction); break;
|
case ShaderOpcodes::DPHI: dphi(instruction); break;
|
||||||
|
@ -52,7 +56,10 @@ void PICAShader::run() {
|
||||||
case 0x34:
|
case 0x34:
|
||||||
case 0x35:
|
case 0x35:
|
||||||
case 0x36:
|
case 0x36:
|
||||||
case 0x37: madi(instruction); break;
|
case 0x37: {
|
||||||
|
madi(instruction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x38:
|
case 0x38:
|
||||||
case 0x39:
|
case 0x39:
|
||||||
|
@ -61,7 +68,10 @@ void PICAShader::run() {
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
case 0x3D:
|
case 0x3D:
|
||||||
case 0x3E:
|
case 0x3E:
|
||||||
case 0x3F: mad(instruction); break;
|
case 0x3F: {
|
||||||
|
mad(instruction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: Helpers::panic("Unimplemented PICA instruction %08X (Opcode = %02X)", instruction, opcode);
|
default: Helpers::panic("Unimplemented PICA instruction %08X (Opcode = %02X)", instruction, opcode);
|
||||||
}
|
}
|
||||||
|
@ -588,7 +598,10 @@ void PICAShader::cmp(u32 instruction) {
|
||||||
cmpRegister[i] = srcVec1[i] >= srcVec2[i];
|
cmpRegister[i] = srcVec1[i] >= srcVec2[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: cmpRegister[i] = true; break;
|
default: {
|
||||||
|
cmpRegister[i] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,7 +695,9 @@ void PICAShader::loop(u32 instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PICAShader::jmpc(u32 instruction) {
|
void PICAShader::jmpc(u32 instruction) {
|
||||||
if (isCondTrue(instruction)) pc = getBits<10, 12>(instruction);
|
if (isCondTrue(instruction)) {
|
||||||
|
pc = getBits<10, 12>(instruction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PICAShader::jmpu(u32 instruction) {
|
void PICAShader::jmpu(u32 instruction) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "renderer_gl/renderer_gl.hpp"
|
#include "renderer_gl/renderer_gl.hpp"
|
||||||
|
|
||||||
|
#include <stb_image_write.h>
|
||||||
|
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "PICA/gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
#include "PICA/regs.hpp"
|
#include "PICA/regs.hpp"
|
||||||
|
@ -841,9 +843,14 @@ void RendererGL::updateLightingLUT() {
|
||||||
|
|
||||||
void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> vertices) {
|
void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> vertices) {
|
||||||
// The fourth type is meant to be "Geometry primitive". TODO: Find out what that is
|
// The fourth type is meant to be "Geometry primitive". TODO: Find out what that is
|
||||||
static constexpr std::array<OpenGL::Primitives, 4> primTypes = {OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::Triangle};
|
static constexpr std::array<OpenGL::Primitives, 4> primTypes = {
|
||||||
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
OpenGL::Triangle,
|
||||||
|
OpenGL::TriangleStrip,
|
||||||
|
OpenGL::TriangleFan,
|
||||||
|
OpenGL::Triangle,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
||||||
gl.disableScissor();
|
gl.disableScissor();
|
||||||
gl.bindVBO(vbo);
|
gl.bindVBO(vbo);
|
||||||
gl.bindVAO(vao);
|
gl.bindVAO(vao);
|
||||||
|
@ -1048,7 +1055,6 @@ void RendererGL::screenshot(const std::string& name) {
|
||||||
std::vector<uint8_t> pixels, flippedPixels;
|
std::vector<uint8_t> pixels, flippedPixels;
|
||||||
pixels.resize(width * height * 4);
|
pixels.resize(width * height * 4);
|
||||||
flippedPixels.resize(pixels.size());
|
flippedPixels.resize(pixels.size());
|
||||||
;
|
|
||||||
|
|
||||||
OpenGL::bindScreenFramebuffer();
|
OpenGL::bindScreenFramebuffer();
|
||||||
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels.data());
|
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels.data());
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include "emulator.hpp"
|
#include "emulator.hpp"
|
||||||
|
|
||||||
#include <stb_image_write.h>
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
|
|
||||||
#if PANDA3DS_ENABLE_OPENGL
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory
|
||||||
Helpers::warn("Failed to initialize SDL2 GameController: %s", SDL_GetError());
|
Helpers::warn("Failed to initialize SDL2 GameController: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
// Request OpenGL 4.1 Core (Max available on MacOS)
|
// Request OpenGL 4.1 Core (Max available on MacOS)
|
||||||
// MacOS gets mad if we don't explicitly demand a core profile
|
// MacOS gets mad if we don't explicitly demand a core profile
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
|
Loading…
Add table
Reference in a new issue