[PICA] Get vertex attributes being semi-properly read

This commit is contained in:
wheremyfoodat 2022-09-22 16:48:43 +03:00
parent 1bbd377ee7
commit 434c840aeb
6 changed files with 135 additions and 14 deletions

View file

@ -5,9 +5,14 @@
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);
// TODO: Reset blending, texturing, etc here
}
@ -15,10 +20,23 @@ void GPU::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control)
printf("GPU: Clear buffer\nStart: %08X End: %08X\nValue: %08X Control: %08X\n", startAddress, endAddress, value, control);
}
void GPU::drawArrays() {
const u32 vertexCount = regs[PICAInternalRegs::VertexCountReg];
const u32 vertexOffset = regs[PICAInternalRegs::VertexOffsetReg];
void GPU::drawArrays(bool indexed) {
if (indexed)
drawArrays<true>();
else
drawArrays<false>();
}
template <bool indexed>
void GPU::drawArrays() {
// Base address for vertex attributes
// 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<u32*>(mem.getReadPointer(vertexBase));
//if (!vertexBuffer) Helpers::panic("PICA::DrawArrays: Failed to get attribute buffer");
u32* attrBuffer = &regs[0x233];
auto a = f24::fromRaw(attrBuffer[0] >> 8);
@ -26,6 +44,29 @@ void GPU::drawArrays() {
auto g = f24::fromRaw(((attrBuffer[1] & 0xFFFF) << 8) | ((attrBuffer[2] >> 24) & 0xFF));
auto r = f24::fromRaw(attrBuffer[2] & 0xFFFFFF);
printf("PICA::DrawArrays(vertex count = %d, vertexOffset = %d)\n", vertexCount, vertexOffset);
if constexpr (!indexed) {
u32 offset = regs[PICAInternalRegs::VertexOffsetReg];
printf("PICA::DrawArrays(vertex count = %d, vertexOffset = %d)\n", vertexCount, offset);
} else {
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) {
vertexIndex = i + regs[PICAInternalRegs::VertexOffsetReg];
} else {
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<u32>(attr0Addr);
u32 attr0Float = *(float*)&attr0;
printf("Attr0: %f\n", (double)attr0Float);
}
}

View file

@ -40,7 +40,11 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
// We currently use the unmasked value like Citra does
switch (index) {
case SignalDrawArrays:
if (value != 0) drawArrays();
if (value != 0) drawArrays(false);
break;
case SignalDrawElements:
if (value != 0) drawArrays(true);
break;
case VertexShaderTransferEnd:
@ -57,7 +61,22 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
break;
default:
printf("GPU: Wrote to unimplemented internal reg: %X, value: %08X\n", index, newValue);
// Vertex attribute registers
if (index >= AttribInfoStart && index <= AttribInfoEnd) {
uint attributeIndex = (index - AttribInfoStart) / 3; // Which attribute are we writing to
uint reg = (index - AttribInfoStart) % 3; // Which of this attribute's registers are we writing to?
auto& attr = attributeInfo[attributeIndex];
switch (reg) {
case 0: attr.offset = value & 0xfffffff; break; // Attribute offset
case 1: break; // We don't handle this yet
case 2: // We don't handle most of this yet
attr.size = (value >> 16) & 0xff;
break;
}
} else {
printf("GPU: Wrote to unimplemented internal reg: %X, value: %08X\n", index, newValue);
}
break;
}
}