diff --git a/include/PICA/gpu.hpp b/include/PICA/gpu.hpp index 501fe37f..5c9580b7 100644 --- a/include/PICA/gpu.hpp +++ b/include/PICA/gpu.hpp @@ -65,7 +65,11 @@ class GPU { std::array attributeInfo; // Info for each of the 12 attributes u32 totalAttribCount = 0; // Number of vertex attributes to send to VS - u32 fixedAttribMask = 0; + u32 fixedAttribMask = 0; // Which attributes are fixed? + + u32 fixedAttribIndex = 0; // Which fixed attribute are we writing to ([0, 12] range) + u32 fixedAttribCount = 0; // How many attribute components have we written? When we get to 4 the attr will actually get submitted + std::array fixedAttrBuff; // Buffer to hold fixed attributes in until they get submitted public: GPU(Memory& mem); diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 6e1067f6..eacafcc9 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -41,6 +41,12 @@ namespace PICAInternalRegs { AttribInfoStart = Attrib0Offset, AttribInfoEnd = Attrib11Config2, + // Fixed attribute registers + FixedAttribIndex = 0x232, + FixedAttribData0 = 0x233, + FixedAttribData1 = 0x234, + FixedAttribData2 = 0x235, + // Vertex shader registers VertexShaderTransferEnd = 0x2BF, VertexShaderTransferIndex = 0x2CB, diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index a51e4bed..8a876a95 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -6,6 +6,11 @@ #include "opengl.hpp" #include "PICA/float_types.hpp" +enum class ShaderType { + Vertex, Geometry +}; + +template class PICAShader { int bufferIndex; // Index of the next instruction to overwrite using f24 = Floats::f24; @@ -19,7 +24,8 @@ public: std::array intUniforms; std::array floatUniforms; - std::array attributes; + std::array fixedAttributes; // Fixed vertex attributes + std::array attributes; // Attributes past to the shader std::array outputs; void reset() { diff --git a/include/PICA/shader_unit.hpp b/include/PICA/shader_unit.hpp index 3fa59bfa..b1e7e3f2 100644 --- a/include/PICA/shader_unit.hpp +++ b/include/PICA/shader_unit.hpp @@ -4,8 +4,8 @@ class ShaderUnit { public: - PICAShader vs; // Vertex shader - PICAShader gs; // Geometry shader + PICAShader vs; // Vertex shader + PICAShader gs; // Geometry shader void reset(); }; \ No newline at end of file diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 840b6317..f8cd60ef 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -7,8 +7,18 @@ using namespace Floats; GPU::GPU(Memory& mem) : mem(mem) { vram = new u8[vramSize]; +} + +void GPU::reset() { + regs.fill(0); + shaderUnit.reset(); + std::memset(vram, 0, vramSize); + totalAttribCount = 0; fixedAttribMask = 0; + fixedAttribIndex = 0; + fixedAttribCount = 0; + fixedAttrBuff.fill(0); for (auto& e : attributeInfo) { e.offset = 0; @@ -16,12 +26,7 @@ GPU::GPU(Memory& mem) : mem(mem) { e.config1 = 0; e.config2 = 0; } -} -void GPU::reset() { - regs.fill(0); - shaderUnit.reset(); - std::memset(vram, 0, vramSize); // TODO: Reset blending, texturing, etc here } diff --git a/src/core/PICA/regs.cpp b/src/core/PICA/regs.cpp index 0c72935c..b8ab7417 100644 --- a/src/core/PICA/regs.cpp +++ b/src/core/PICA/regs.cpp @@ -1,6 +1,8 @@ #include "PICA/gpu.hpp" #include "PICA/regs.hpp" +using namespace Floats; + u32 GPU::readReg(u32 address) { printf("Ignoring read from GPU register %08X\n", address); return 0; @@ -52,6 +54,34 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) { fixedAttribMask = (value >> 16) & 0xfff; // Determines which vertex attributes are fixed for all vertices break; + case FixedAttribIndex: + fixedAttribCount = 0; + fixedAttribIndex = value & 0xf; + + if (fixedAttribIndex == 0xf) Helpers::panic("[PICA] Immediate mode vertex submission"); + break; + + case FixedAttribData0: case FixedAttribData1: case FixedAttribData2: + if (fixedAttribIndex >= 12) Helpers::panic("[PICA] Tried to write to fixed attribute %d", fixedAttribIndex); + + fixedAttrBuff[fixedAttribCount++] = value; + if (fixedAttribCount == 3) { + fixedAttribCount = 0; + + vec4f& attr = shaderUnit.vs.fixedAttributes[fixedAttribIndex]; + // These are stored in the reverse order anyone would expect them to be in + attr.x() = f24::fromRaw(fixedAttrBuff[2] & 0xffffff); + attr.y() = f24::fromRaw(((fixedAttrBuff[1] & 0xffff) << 8) | (fixedAttrBuff[2] >> 24)); + attr.z() = f24::fromRaw(((fixedAttrBuff[0] & 0xff) << 16) | (fixedAttrBuff[1] >> 16)); + attr.w() = f24::fromRaw(fixedAttrBuff[0] >> 8); + + printf("r: %f g: %f b: %f a: %f\n", (double)attr.r().toFloat32(), (double)attr.g().toFloat32(), (double)attr.b().toFloat32(), (double)attr.a().toFloat32()); + + fixedAttribIndex++; + } + + break; + case VertexShaderTransferEnd: if (value != 0) shaderUnit.vs.finalize(); break;