optimized draw data calculations using VU0

This commit is contained in:
Sandro Sobczyński
2020-11-04 16:03:30 +01:00
parent 4d53c6c5fe
commit aa6b2d314b
2 changed files with 147 additions and 52 deletions
+4 -16
View File
@@ -108,22 +108,10 @@ Vector3 Vector3::operator*(Vector3 &v)
asm volatile( // VU0 Macro program asm volatile( // VU0 Macro program
"lqc2 vf4, 0x0(%1) \n\t" // vf4 = this "lqc2 vf4, 0x0(%1) \n\t" // vf4 = this
"lqc2 vf5, 0x0(%2) \n\t" // vf5 = v "lqc2 vf5, 0x0(%2) \n\t" // vf5 = v
"vopmula.xyz ACC, vf4, vf5 \n\t"
"vmulz.y vf6, vf4, vf5 \n\t" // vf6.y = vf4.y * vf5.z "vopmsub.xyz vf8, vf5, vf4 \n\t"
"vmuly.z vf6, vf4, vf5 \n\t" "vsub.w vf8, vf00, vf00 \n\t"
"vsubz.y vf6, vf6, vf6 \n\t" // vf6.y = vf4.y - vf4.z "sqc2 vf8, 0x0(%0) \n\t" // vf8 = res
"vaddy.x vf8, vf0, vf6 \n\t" // res.x = vf4.y * vf5.z - vf4.z * vf5.y
"vmulx.z vf6, vf4, vf5 \n\t"
"vmulz.x vf6, vf4, vf5 \n\t"
"vsubx.z vf6, vf6, vf6 \n\t"
"vaddz.y vf8, vf0, vf6 \n\t" // res.y = vf4.z * vf5.x - vf4.x * vf5.z
"vmuly.x vf6, vf4, vf5 \n\t"
"vmulx.y vf6, vf4, vf5 \n\t"
"vsuby.x vf6, vf6, vf6 \n\t"
"vaddx.z vf8, vf0, vf6 \n\t" // res.z = vf4.x * vf5.y - vf4.y * vf5.x
"sqc2 vf8, 0x0(%0) \n\t"
: :
: "r"(res.xyz), "r"(this->xyz), "r"(v.xyz)); : "r"(res.xyz), "r"(this->xyz), "r"(v.xyz));
// result.x = y * v.z - z * v.y; // result.x = y * v.z - z * v.y;
+136 -29
View File
@@ -183,56 +183,163 @@ void Mesh::animate()
} }
} }
// TODO think about that, because in Ari sample it eats 88 FPS :O
u32 Mesh::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, Vector3 &t_cameraPos) u32 Mesh::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, Vector3 &t_cameraPos)
{ {
VECTOR ONE_VEC = {1.0F, 1.0F, 1.0F, 1.0F};
asm volatile(
// VU0 macro program:
// Load vector with 1.0F values to VF21
"lqc2 vf21, 0x0(%0) \n\t" // load "one vec"
:
: "r"(ONE_VEC));
u32 addedFaces = 0; u32 addedFaces = 0;
#define CURR_FRAME frames[animState.currentFrame] #define CURR_FRAME frames[animState.currentFrame]
#define NEXT_FRAME frames[animState.nextFrame] #define NEXT_FRAME frames[animState.nextFrame]
MeshMaterial *material = &CURR_FRAME.getMaterial(t_materialIndex); // cache MeshMaterial *material = &CURR_FRAME.getMaterial(t_materialIndex); // cache
u32 *vertFaces = material->getVertexFaces(); // cache
u32 *normalFaces = material->getNormalFaces(); // cache
u32 *stFaces = material->getSTFaces(); // cache
Vector3 *verts = CURR_FRAME.getVertices(); // cache Vector3 *verts = CURR_FRAME.getVertices(); // cache
Vector3 *nextVerts = NEXT_FRAME.getVertices(); // cache Vector3 *nextVerts = NEXT_FRAME.getVertices(); // cache
Point *sts = CURR_FRAME.getSTs(); // cache Point *sts = CURR_FRAME.getSTs(); // cache
Vector3 *normals = CURR_FRAME.getNormals(); // cache Vector3 *normals = CURR_FRAME.getNormals(); // cache
#define CURR_VERT verts[material->getVertexFace(matI + vertI)]
#define CURR_ST sts[material->getSTFace(matI + vertI)]
#define CURR_NORMAL normals[material->getNormalFace(matI + vertI)]
#define NEXT_VERT nextVerts[material->getVertexFace(matI + vertI)]
for (u32 matI = 0; matI < material->getFacesCount(); matI += 3) for (u32 faceI = 0; faceI < material->getFacesCount(); faceI += 3)
{ {
for (u32 vertI = 0; vertI < 3; vertI++)
if (animState.currentFrame != animState.nextFrame) if (animState.currentFrame != animState.nextFrame)
calc3Vectors[vertI].setByLerp(CURR_VERT, NEXT_VERT, animState.interpolation, scale);
if (!shouldBeBackfaceCulled ||
Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[0], &calc3Vectors[1], &calc3Vectors[2]))
for (u32 vertI = 0; vertI < 3; vertI++)
{ {
asm volatile(
// VU0 macro program:
// Calculate lerp() and store data into calc3Vectors
if (animState.currentFrame == animState.nextFrame) // Vertex 0
{ "lqc2 vf4, 0x0(%3) \n\t" // vf4 = v1
o_vertices[addedFaces][0] = CURR_VERT.x; "lqc2 vf5, 0x0(%6) \n\t" // vf5 = v2
o_vertices[addedFaces][1] = CURR_VERT.y; "mfc1 $10, %9 \n\t" // vf6 = t
o_vertices[addedFaces][2] = CURR_VERT.z; "qmtc2 $10, vf6 \n\t" // lerp:
"vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = v2 - v1
"vmulx.xyz vf8, vf7, vf6 \n\t" // vf8 = vf7 * t
"vadd.xyz vf9, vf8, vf4 \n\t" // vf9 = vf8 + vf4
"sqc2 vf9, 0x0(%0) \n\t" // v0 = vf9
// Vertex 1
"lqc2 vf4, 0x0(%4) \n\t" // vf4 = v1
"lqc2 vf5, 0x0(%7) \n\t" // vf5 = v2
"mfc1 $10, %9 \n\t" // vf6 = t
"qmtc2 $10, vf6 \n\t" // lerp:
"vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = v2 - v1
"vmulx.xyz vf8, vf7, vf6 \n\t" // vf8 = vf7 * t
"vadd.xyz vf9, vf8, vf4 \n\t" // vf9 = vf8 + vf4
"sqc2 vf9, 0x0(%1) \n\t" // v0 = vf9
// Vertex 2
"lqc2 vf4, 0x0(%5) \n\t" // vf4 = v1
"lqc2 vf5, 0x0(%8) \n\t" // vf5 = v2
"mfc1 $10, %9 \n\t" // vf6 = t
"qmtc2 $10, vf6 \n\t" // lerp:
"vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = v2 - v1
"vmulx.xyz vf8, vf7, vf6 \n\t" // vf8 = vf7 * t
"vadd.xyz vf9, vf8, vf4 \n\t" // vf9 = vf8 + vf4
"sqc2 vf9, 0x0(%2) \n\t" // v0 = vf9
:
: "r"(calc3Vectors[0].xyz),
"r"(calc3Vectors[1].xyz),
"r"(calc3Vectors[2].xyz),
"r"(verts[vertFaces[faceI]].xyz),
"r"(verts[vertFaces[faceI + 1]].xyz),
"r"(verts[vertFaces[faceI + 2]].xyz),
"r"(nextVerts[vertFaces[faceI]].xyz),
"r"(nextVerts[vertFaces[faceI + 1]].xyz),
"r"(nextVerts[vertFaces[faceI + 2]].xyz),
"f"(animState.interpolation)
: "$10");
} }
else else
{ {
o_vertices[addedFaces][0] = calc3Vectors[vertI].x; asm volatile(
o_vertices[addedFaces][1] = calc3Vectors[vertI].y; // VU0 macro program
o_vertices[addedFaces][2] = calc3Vectors[vertI].z; // Copy 0,1,2 vertices
"lqc2 vf1, 0x0(%3) \n\t" // load vert
"lqc2 vf2, 0x0(%4) \n\t" // load normal
"lqc2 vf3, 0x0(%5) \n\t" // load st
"sqc2 vf1, 0x0(%0) \n\t" // store vert
"sqc2 vf2, 0x0(%1) \n\t" // store normal
"sqc2 vf3, 0x0(%2) \n\t" // store st
:
: "r"(calc3Vectors[0].xyz),
"r"(calc3Vectors[1].xyz),
"r"(calc3Vectors[2].xyz),
"r"(verts[vertFaces[faceI]].xyz),
"r"(verts[vertFaces[faceI + 1]].xyz),
"r"(verts[vertFaces[faceI + 2]].xyz));
} }
o_vertices[addedFaces][3] = 1.0F;
o_normals[addedFaces][0] = CURR_NORMAL.x; if (!shouldBeBackfaceCulled ||
o_normals[addedFaces][1] = CURR_NORMAL.y; !Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[2], &calc3Vectors[1], &calc3Vectors[0]))
o_normals[addedFaces][2] = CURR_NORMAL.z; {
o_normals[addedFaces][3] = 1.0F;
o_coordinates[addedFaces][0] = CURR_ST.x; asm volatile(
o_coordinates[addedFaces][1] = CURR_ST.y; // VU0 macro program:
o_coordinates[addedFaces][2] = 1.0F; // Copy data and set vert/normal "w" and st "z"+"w" to 1.0F
o_coordinates[addedFaces++][3] = 1.0F;
// Vertex 0
"lqc2 vf1, 0x0(%3) \n\t" // load vert
"lqc2 vf2, 0x0(%4) \n\t" // load normal
"lqc2 vf3, 0x0(%5) \n\t" // load st
"vadd.w vf1, vf20, vf21 \n\t" // set vert.w to 1.0F
"vadd.w vf2, vf20, vf21 \n\t" // set normal.W to 1.0F
"vadd.zw vf3, vf20, vf21 \n\t" // set st.zw to 1.0F
"sqc2 vf1, 0x0(%0) \n\t" // store vert
"sqc2 vf2, 0x0(%1) \n\t" // store normal
"sqc2 vf3, 0x0(%2) \n\t" // store st
// Vertex 1
"lqc2 vf1, 0x0(%9) \n\t" // load vert
"lqc2 vf2, 0x0(%10) \n\t" // load normal
"lqc2 vf3, 0x0(%11) \n\t" // load st
"vadd.w vf1, vf20, vf21 \n\t" // set vert.w to 1.0F
"vadd.w vf2, vf20, vf21 \n\t" // set normal.W to 1.0F
"vadd.zw vf3, vf20, vf21 \n\t" // set st.zw to 1.0F
"sqc2 vf1, 0x0(%6) \n\t" // store vert
"sqc2 vf2, 0x0(%7) \n\t" // store normal
"sqc2 vf3, 0x0(%8) \n\t" // store st
// Vertex 2
"lqc2 vf1, 0x0(%15) \n\t" // load vert
"lqc2 vf2, 0x0(%16) \n\t" // load normal
"lqc2 vf3, 0x0(%17) \n\t" // load st
"vadd.w vf1, vf20, vf21 \n\t" // set vert.w to 1.0F
"vadd.w vf2, vf20, vf21 \n\t" // set normal.W to 1.0F
"vadd.zw vf3, vf20, vf21 \n\t" // set st.zw to 1.0F
"sqc2 vf1, 0x0(%12) \n\t" // store vert
"sqc2 vf2, 0x0(%13) \n\t" // store normal
"sqc2 vf3, 0x0(%14) \n\t" // store st
:
: "r"(o_vertices[addedFaces]),
"r"(o_normals[addedFaces]),
"r"(o_coordinates[addedFaces]),
"r"(calc3Vectors[0].xyz),
"r"(normals[normalFaces[faceI]].xyz),
"r"(sts[stFaces[faceI]].xy),
"r"(o_vertices[addedFaces + 1]),
"r"(o_normals[addedFaces + 1]),
"r"(o_coordinates[addedFaces + 1]),
"r"(calc3Vectors[1].xyz),
"r"(normals[normalFaces[faceI + 1]].xyz),
"r"(sts[stFaces[faceI + 1]].xy),
"r"(o_vertices[addedFaces + 2]),
"r"(o_normals[addedFaces + 2]),
"r"(o_coordinates[addedFaces + 2]),
"r"(calc3Vectors[2].xyz),
"r"(normals[normalFaces[faceI + 2]].xyz),
"r"(sts[stFaces[faceI + 2]].xy));
addedFaces += 3;
} }
} }
return addedFaces; return addedFaces;