From 39bfeda586deeab949e74e41b36c214c986c71b0 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Thu, 22 Sep 2022 19:17:19 +0300 Subject: [PATCH] [PICA] More progress on attribute parsing --- include/PICA/gpu.hpp | 22 ++++++++++++++++++++-- include/PICA/regs.hpp | 1 + src/core/PICA/gpu.cpp | 38 +++++++++++++++++++------------------- src/core/PICA/regs.cpp | 5 +++++ 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/include/PICA/gpu.hpp b/include/PICA/gpu.hpp index 56898455..ef7a61af 100644 --- a/include/PICA/gpu.hpp +++ b/include/PICA/gpu.hpp @@ -9,11 +9,13 @@ class GPU { ShaderUnit shaderUnit; u8* vram = nullptr; - static constexpr u32 totalAttribCount = 12; // Up to 12 vertex attributes + static constexpr u32 maxAttribCount = 12; // Up to 12 vertex attributes static constexpr u32 regNum = 0x300; static constexpr u32 vramSize = 6_MB; std::array regs; // GPU internal registers + // Read a value of type T from physical address paddr + // This is necessary because vertex attribute fetching uses physical addresses template T readPhysical(u32 paddr) { if (paddr >= PhysicalAddrs::FCRAM && paddr <= PhysicalAddrs::FCRAMEnd) { @@ -26,6 +28,20 @@ class GPU { } } + // Get a pointer of type T* to the data starting from physical address paddr + template + T* getPointerPhys(u32 paddr) { + if (paddr >= PhysicalAddrs::FCRAM && paddr <= PhysicalAddrs::FCRAMEnd) { + u8* fcram = mem.getFCRAM(); + u32 index = paddr - PhysicalAddrs::FCRAM; + + return (T*)&fcram[index]; + } + else { + Helpers::panic("[PICA] Pointer to unimplemented paddr %08X", paddr); + } + } + template void drawArrays(); @@ -37,7 +53,9 @@ class GPU { int size = 0; // Bytes per vertex }; - std::array attributeInfo; + std::array attributeInfo; // Info for each of the 12 attributes + u32 totalAttribCount = 0; // Number of vertex attributes to send to VS + u32 fixedAttribMask = 0; public: GPU(Memory& mem); diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 4d4e5447..b1d2c039 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -4,6 +4,7 @@ namespace PICAInternalRegs { enum : u32 { // Geometry pipelin regs VertexAttribLoc = 0x200, + AttribFormatHigh = 0x202, IndexBufferConfig = 0x227, VertexCountReg = 0x228, VertexOffsetReg = 0x22A, diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 762e6a4c..8f37c631 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -7,6 +7,13 @@ using namespace Floats; GPU::GPU(Memory& mem) : mem(mem) { vram = new u8[vramSize]; + totalAttribCount = 0; + fixedAttribMask = 0; + + for (auto& e : attributeInfo) { + e.offset = 0; + e.size = 0; + } } void GPU::reset() { @@ -33,16 +40,6 @@ void GPU::drawArrays() { // The vertex base is always on a quadword boundary because the PICA does weird alignment shit any time possible const u32 vertexBase = ((regs[PICAInternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16; const u32 vertexCount = regs[PICAInternalRegs::VertexCountReg]; // Total # of vertices to transfer - printf("Vertex location: %08X\n", vertexBase); - - //u32* vertexBuffer = static_cast(mem.getReadPointer(vertexBase)); - //if (!vertexBuffer) Helpers::panic("PICA::DrawArrays: Failed to get attribute buffer"); - - u32* attrBuffer = ®s[0x233]; - auto a = f24::fromRaw(attrBuffer[0] >> 8); - auto b = f24::fromRaw(((attrBuffer[0] & 0xFF) << 16) | ((attrBuffer[1] >> 16) & 0xFFFF)); - auto g = f24::fromRaw(((attrBuffer[1] & 0xFFFF) << 8) | ((attrBuffer[2] >> 24) & 0xFF)); - auto r = f24::fromRaw(attrBuffer[2] & 0xFFFFFF); if constexpr (!indexed) { u32 offset = regs[PICAInternalRegs::VertexOffsetReg]; @@ -51,8 +48,6 @@ void GPU::drawArrays() { Helpers::panic("[PICA] Indexed drawing"); } - printf("(r: %f, g: %f, b: %f, a: %f)\n", r.toFloat32(), g.toFloat32(), b.toFloat32(), a.toFloat32()); - for (u32 i = 0; i < vertexCount; i++) { u32 vertexIndex; // Index of the vertex in the VBO if constexpr (!indexed) { @@ -61,12 +56,17 @@ void GPU::drawArrays() { Helpers::panic("[PICA]: Unimplemented indexed rendering"); } - // Get address of attribute 0 - auto& attr = attributeInfo[0]; - u32 attr0Addr = vertexBase + attr.offset + (vertexIndex * attr.size); - - u32 attr0 = readPhysical(attr0Addr); - u32 attr0Float = *(float*)&attr0; - printf("Attr0: %f\n", (double)attr0Float); + int attrCount = 0; // Number of attributes we've passed to the shader + for (int attrCount = 0; attrCount < totalAttribCount; attrCount++) { + auto& attr = attributeInfo[attrCount]; // Get information for this attribute + + // Check if attribute is fixed or not + if (fixedAttribMask & (1 << attrCount)) { // Fixed attribute + + } else { // Non-fixed attribute + // Address to fetch the attribute from + u32 attrAddress = vertexBase + attr.offset + (vertexIndex * attr.size); + } + } } } \ No newline at end of file diff --git a/src/core/PICA/regs.cpp b/src/core/PICA/regs.cpp index 3b3c312c..c65c43d7 100644 --- a/src/core/PICA/regs.cpp +++ b/src/core/PICA/regs.cpp @@ -47,6 +47,11 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) { if (value != 0) drawArrays(true); break; + case AttribFormatHigh: + totalAttribCount = (value >> 28) + 1; // Total number of vertex attributes + fixedAttribMask = (value >> 16) & 0xfff; // Determines which vertex attributes are fixed for all vertices + break; + case VertexShaderTransferEnd: if (value != 0) shaderUnit.vs.finalize(); break;