mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-20 20:49:12 +12:00
Geometry pipeline v2
Co-Authored-By: Sky <skylersaleh@gmail.com>
This commit is contained in:
parent
1019f65824
commit
e80679fe77
9 changed files with 114 additions and 48 deletions
|
@ -72,6 +72,10 @@ void GPU::drawArrays() {
|
|||
log("PICA::DrawElements(vertex count = %d, index buffer config = %08X)\n", vertexCount, indexBufferConfig);
|
||||
}
|
||||
|
||||
// Total number of input attributes to shader. Differs between GS and VS. Currently stubbed to the VS one, as we don't have geometry shaders.
|
||||
const u32 inputAttrCount = (regs[PICAInternalRegs::VertexShaderInputBufferCfg] & 0xf) + 1;
|
||||
const u64 inputAttrCfg = getVertexShaderInputConfig();
|
||||
|
||||
for (u32 i = 0; i < vertexCount; i++) {
|
||||
u32 vertexIndex; // Index of the vertex in the VBO
|
||||
|
||||
|
@ -89,72 +93,112 @@ void GPU::drawArrays() {
|
|||
}
|
||||
}
|
||||
|
||||
int attrCount = 0; // Number of attributes we've passed to the shader
|
||||
for (int attrCount = 0; attrCount < totalAttribCount; attrCount++) {
|
||||
int attrCount = 0;
|
||||
int buffer = 0; // Vertex buffer index for non-fixed attributes
|
||||
|
||||
while (attrCount < totalAttribCount) {
|
||||
// Check if attribute is fixed or not
|
||||
if (fixedAttribMask & (1 << attrCount)) { // Fixed attribute
|
||||
vec4f& fixedAttr = shaderUnit.vs.fixedAttributes[attrCount]; // TODO: Is this how it works?
|
||||
vec4f& inputAttr = shaderUnit.vs.attributes[attrCount];
|
||||
vec4f& inputAttr = currentAttributes[attrCount];
|
||||
std::memcpy(&inputAttr, &fixedAttr, sizeof(vec4f)); // Copy fixed attr to input attr
|
||||
attrCount++;
|
||||
} else { // Non-fixed attribute
|
||||
auto& attr = attributeInfo[attrCount]; // Get information for this attribute
|
||||
auto& attr = attributeInfo[buffer]; // 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; // Type of attribute(sbyte/ubyte/short/float)
|
||||
u32 componentCount = (attribInfo >> 2) + 1; // Total number of components
|
||||
|
||||
// Address to fetch the attribute from
|
||||
u32 attrAddress = vertexBase + attr.offset + (vertexIndex * attr.size);
|
||||
vec4f& attribute = shaderUnit.vs.attributes[attrCount];
|
||||
uint component; // Current component
|
||||
|
||||
switch (attribType) {
|
||||
case 2: { // Short
|
||||
s16* ptr = getPointerPhys<s16>(attrAddress);
|
||||
for (component = 0; component < componentCount; component++) {
|
||||
float val = static_cast<float>(*ptr++);
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
for (int j = 0; j < attr.componentCount; j++) {
|
||||
uint index = (attrCfg >> (j * 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; // Type of attribute(sbyte/ubyte/short/float)
|
||||
u32 size = (attribInfo >> 2) + 1; // Total number of components
|
||||
|
||||
//printf("vertex_attribute_strides[%d] = %d\n", attrCount, attr.size);
|
||||
vec4f& attribute = currentAttributes[attrCount];
|
||||
uint component; // Current component
|
||||
|
||||
switch (attribType) {
|
||||
case 0: { // Signed byte
|
||||
s8* ptr = getPointerPhys<s8>(attrAddress);
|
||||
for (component = 0; component < size; component++) {
|
||||
float val = static_cast<float>(*ptr++);
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
}
|
||||
attrAddress += size * sizeof(s8);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: { // Unsigned byte
|
||||
u8* ptr = getPointerPhys<u8>(attrAddress);
|
||||
for (component = 0; component < size; component++) {
|
||||
float val = static_cast<float>(*ptr++);
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
}
|
||||
attrAddress += size * sizeof(u8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: { // Short
|
||||
s16* ptr = getPointerPhys<s16>(attrAddress);
|
||||
for (component = 0; component < size; component++) {
|
||||
float val = static_cast<float>(*ptr++);
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
}
|
||||
attrAddress += size * sizeof(s16);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: { // Float
|
||||
float* ptr = getPointerPhys<float>(attrAddress);
|
||||
for (component = 0; component < size; component++) {
|
||||
float val = *ptr++;
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
}
|
||||
attrAddress += size * sizeof(float);
|
||||
break;
|
||||
}
|
||||
|
||||
default: Helpers::panic("[PICA] Unimplemented attribute type %d", attribType);
|
||||
}
|
||||
|
||||
case 3: { // Float
|
||||
float* ptr = getPointerPhys<float>(attrAddress);
|
||||
for (component = 0; component < componentCount; component++) {
|
||||
float val = *ptr++;
|
||||
attribute[component] = f24::fromFloat32(val);
|
||||
}
|
||||
break;
|
||||
// Fill the remaining attribute lanes with default parameters (1.0 for alpha/w, 0.0) for everything else
|
||||
// Corgi does this although I'm not sure if it's actually needed for anything.
|
||||
// TODO: Find out
|
||||
while (component < 4) {
|
||||
attribute[component] = (component == 3) ? f24::fromFloat32(1.0) : f24::fromFloat32(0.0);
|
||||
component++;
|
||||
}
|
||||
|
||||
default: Helpers::panic("[PICA] Unimplemented attribute type %d", attribType);
|
||||
}
|
||||
|
||||
// Fill the remaining attribute lanes with default parameters (1.0 for alpha/w, 0.0) for everything else
|
||||
// Corgi does this although I'm not sure if it's actually needed for anything.
|
||||
// TODO: Find out
|
||||
while (component < 4) {
|
||||
attribute[component] = (component == 3) ? f24::fromFloat32(1.0) : f24::fromFloat32(0.0);
|
||||
component++;
|
||||
attrCount++;
|
||||
}
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
// Before running the shader, the PICA maps the fetched attributes from the attribute registers to the shader input registers
|
||||
// Based on the SH_ATTRIBUTES_PERMUTATION registers.
|
||||
// Ie it might attribute #0 to v2, #1 to v7, etc
|
||||
for (int j = 0; j < totalAttribCount; j++) {
|
||||
const u32 mapping = (inputAttrCfg >> (j * 4)) & 0xf;
|
||||
std::memcpy(&shaderUnit.vs.inputs[mapping], ¤tAttributes[j], sizeof(vec4f));
|
||||
}
|
||||
|
||||
shaderUnit.vs.run();
|
||||
std::memcpy(&vertices[i].position, &shaderUnit.vs.outputs[0], sizeof(vec4f));
|
||||
std::memcpy(&vertices[i].colour, &shaderUnit.vs.outputs[1], sizeof(vec4f));
|
||||
std::memcpy(&vertices[i].UVs, &shaderUnit.vs.outputs[2], 2 * sizeof(f24));
|
||||
|
||||
//printf("(x, y, z, w) = (%f, %f, %f, %f)\n", (double)vertices[i].position.x(), (double)vertices[i].position.y(), (double)vertices[i].position.z(), (double)vertices[i].position.w());
|
||||
//printf("(r, g, b, a) = (%f, %f, %f, %f)\n", (double)vertices[i].colour.r(), (double)vertices[i].colour.g(), (double)vertices[i].colour.b(), (double)vertices[i].colour.a());
|
||||
//printf("U: %f, V: %f\n", vertices[i].UVs.u(), vertices[i].UVs.v());
|
||||
}
|
||||
|
||||
// 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::LineStrip
|
||||
OpenGL::Triangle, OpenGL::TriangleStrip, OpenGL::TriangleFan, OpenGL::Triangle
|
||||
};
|
||||
const auto shape = primTypes[primType];
|
||||
renderer.drawVertices(shape, vertices, vertexCount);
|
||||
|
|
|
@ -94,7 +94,7 @@ u8 PICAShader::getIndexedSource(u32 source, u32 index) {
|
|||
|
||||
PICAShader::vec4f PICAShader::getSource(u32 source) {
|
||||
if (source < 0x10)
|
||||
return attributes[source];
|
||||
return inputs[source];
|
||||
else if (source < 0x20)
|
||||
return tempRegisters[source - 0x10];
|
||||
else if (source <= 0x7f)
|
||||
|
@ -237,7 +237,6 @@ void PICAShader::mova(u32 instruction) {
|
|||
const u32 operandDescriptor = operandDescriptors[instruction & 0x7f];
|
||||
const u32 src = (instruction >> 12) & 0x7f;
|
||||
const u32 idx = (instruction >> 19) & 3;
|
||||
const u32 dest = (instruction >> 21) & 0x1f;
|
||||
|
||||
if (idx) Helpers::panic("[PICA] MOVA: idx != 0");
|
||||
vec4f srcVector = getSourceSwizzled<1>(src, operandDescriptor);
|
||||
|
|
|
@ -18,7 +18,7 @@ void PICAShader::reset() {
|
|||
f32UniformTransfer = false;
|
||||
|
||||
const vec4f zero = vec4f({ f24::zero(), f24::zero(), f24::zero(), f24::zero() });
|
||||
attributes.fill(zero);
|
||||
inputs.fill(zero);
|
||||
floatUniforms.fill(zero);
|
||||
outputs.fill(zero);
|
||||
tempRegisters.fill(zero);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue