mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-11 08:39:48 +12:00
[PICA] Why is attribute fetching so hard
This commit is contained in:
parent
39bfeda586
commit
8770e6dc41
6 changed files with 44 additions and 8 deletions
|
@ -146,4 +146,4 @@ namespace Floats {
|
|||
using f20 = Float<12, 7>;
|
||||
using f16 = Float<10, 5>;
|
||||
|
||||
} // namespace Pica
|
||||
} // namespace Floats
|
||||
|
|
|
@ -51,6 +51,12 @@ class GPU {
|
|||
struct AttribInfo {
|
||||
u32 offset = 0; // Offset from base vertex array
|
||||
int size = 0; // Bytes per vertex
|
||||
u32 config1 = 0;
|
||||
u32 config2 = 0;
|
||||
|
||||
u64 getConfigFull() {
|
||||
return u64(config1) | (u64(config2) << 32);
|
||||
}
|
||||
};
|
||||
|
||||
std::array<AttribInfo, maxAttribCount> attributeInfo; // Info for each of the 12 attributes
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
namespace PICAInternalRegs {
|
||||
enum : u32 {
|
||||
// Geometry pipelin regs
|
||||
// Geometry pipeline regs
|
||||
VertexAttribLoc = 0x200,
|
||||
AttribFormatLow = 0x201,
|
||||
AttribFormatHigh = 0x202,
|
||||
IndexBufferConfig = 0x227,
|
||||
VertexCountReg = 0x228,
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
#include <array>
|
||||
#include <cstring>
|
||||
#include "helpers.hpp"
|
||||
#include "opengl.hpp"
|
||||
#include "PICA/float_types.hpp"
|
||||
|
||||
class PICAShader {
|
||||
int bufferIndex; // Index of the next instruction to overwrite
|
||||
using f24 = Floats::f24;
|
||||
using vec4f = OpenGL::Vector<f24, 4>;
|
||||
|
||||
public:
|
||||
std::array<u32, 512> loadedShader; // Currently loaded & active shader
|
||||
|
@ -13,16 +17,23 @@ public:
|
|||
|
||||
u32 boolUniform;
|
||||
std::array<u32, 4> intUniforms;
|
||||
std::array<u32, 8> floatUniforms;
|
||||
std::array<vec4f, 8> floatUniforms;
|
||||
|
||||
std::array<vec4f, 16> attributes;
|
||||
std::array<vec4f, 16> outputs;
|
||||
|
||||
void reset() {
|
||||
loadedShader.fill(0);
|
||||
bufferedShader.fill(0);
|
||||
|
||||
intUniforms.fill(0);
|
||||
floatUniforms.fill(0);
|
||||
boolUniform = 0;
|
||||
bufferIndex = 0;
|
||||
|
||||
const vec4f zero = vec4f({ f24::fromFloat32(0.0), f24::fromFloat32(0.0), f24::fromFloat32(0.0), f24::fromFloat32(0.0) });
|
||||
attributes.fill(zero);
|
||||
floatUniforms.fill(zero);
|
||||
outputs.fill(zero);
|
||||
}
|
||||
|
||||
void finalize() {
|
||||
|
|
|
@ -13,6 +13,8 @@ GPU::GPU(Memory& mem) : mem(mem) {
|
|||
for (auto& e : attributeInfo) {
|
||||
e.offset = 0;
|
||||
e.size = 0;
|
||||
e.config1 = 0;
|
||||
e.config2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +43,10 @@ void GPU::drawArrays() {
|
|||
const u32 vertexBase = ((regs[PICAInternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
|
||||
const u32 vertexCount = regs[PICAInternalRegs::VertexCountReg]; // Total # of vertices to transfer
|
||||
|
||||
// Stuff the global attribute config registers in one u64 to make attr parsing easier
|
||||
// TODO: Cache this when the vertex attribute format registers are written to
|
||||
u64 vertexCfg = u64(regs[PICAInternalRegs::AttribFormatLow]) | (u64(regs[PICAInternalRegs::AttribFormatHigh]) << 32);
|
||||
|
||||
if constexpr (!indexed) {
|
||||
u32 offset = regs[PICAInternalRegs::VertexOffsetReg];
|
||||
printf("PICA::DrawArrays(vertex count = %d, vertexOffset = %d)\n", vertexCount, offset);
|
||||
|
@ -58,14 +64,23 @@ void GPU::drawArrays() {
|
|||
|
||||
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
|
||||
auto& attr = attributeInfo[attrCount]; // Get information for this attribute
|
||||
u64 attrCfg = attr.getConfigFull(); // Get config1 | (config2 << 32)
|
||||
uint index = (attrCfg >> (attrCount * 4)) & 0xf; // Get index of attribute in vertexCfg
|
||||
|
||||
if (index >= 12) Helpers::panic("[PICA] Vertex attribute used as padding");
|
||||
|
||||
u32 attribInfo = (vertexCfg >> (index * 4)) & 0xf;
|
||||
u32 attribType = attribInfo & 0x3;
|
||||
u32 attribSize = (attribInfo >> 2) + 1;
|
||||
|
||||
// Address to fetch the attribute from
|
||||
u32 attrAddress = vertexBase + attr.offset + (vertexIndex * attr.size);
|
||||
printf("Attribute %d, type: %d, size: %d\n", attrCount, attribType, attribSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,8 +74,11 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
|
||||
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
|
||||
case 1:
|
||||
attr.config1 = value;
|
||||
break;
|
||||
case 2:
|
||||
attr.config2 = value;
|
||||
attr.size = (value >> 16) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue