optimized draw data calculations using VU0
This commit is contained in:
@@ -105,25 +105,13 @@ Vector3 Vector3::operator-(void)
|
||||
Vector3 Vector3::operator*(Vector3 &v)
|
||||
{
|
||||
Vector3 res;
|
||||
asm volatile( // VU0 Macro program
|
||||
"lqc2 vf4, 0x0(%1) \n\t" // vf4 = this
|
||||
"lqc2 vf5, 0x0(%2) \n\t" // vf5 = v
|
||||
|
||||
"vmulz.y vf6, vf4, vf5 \n\t" // vf6.y = vf4.y * vf5.z
|
||||
"vmuly.z vf6, vf4, vf5 \n\t"
|
||||
"vsubz.y vf6, vf6, vf6 \n\t" // vf6.y = vf4.y - vf4.z
|
||||
"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"
|
||||
asm volatile( // VU0 Macro program
|
||||
"lqc2 vf4, 0x0(%1) \n\t" // vf4 = this
|
||||
"lqc2 vf5, 0x0(%2) \n\t" // vf5 = v
|
||||
"vopmula.xyz ACC, vf4, vf5 \n\t"
|
||||
"vopmsub.xyz vf8, vf5, vf4 \n\t"
|
||||
"vsub.w vf8, vf00, vf00 \n\t"
|
||||
"sqc2 vf8, 0x0(%0) \n\t" // vf8 = res
|
||||
:
|
||||
: "r"(res.xyz), "r"(this->xyz), "r"(v.xyz));
|
||||
// result.x = y * v.z - z * v.y;
|
||||
|
||||
+140
-33
@@ -183,57 +183,164 @@ 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)
|
||||
{
|
||||
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;
|
||||
#define CURR_FRAME frames[animState.currentFrame]
|
||||
#define NEXT_FRAME frames[animState.nextFrame]
|
||||
|
||||
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 *nextVerts = NEXT_FRAME.getVertices(); // cache
|
||||
Point *sts = CURR_FRAME.getSTs(); // 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)
|
||||
calc3Vectors[vertI].setByLerp(CURR_VERT, NEXT_VERT, animState.interpolation, scale);
|
||||
if (animState.currentFrame != animState.nextFrame)
|
||||
{
|
||||
asm volatile(
|
||||
// VU0 macro program:
|
||||
// Calculate lerp() and store data into calc3Vectors
|
||||
|
||||
// Vertex 0
|
||||
"lqc2 vf4, 0x0(%3) \n\t" // vf4 = v1
|
||||
"lqc2 vf5, 0x0(%6) \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(%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
|
||||
{
|
||||
asm volatile(
|
||||
// VU0 macro program
|
||||
// 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));
|
||||
}
|
||||
|
||||
if (!shouldBeBackfaceCulled ||
|
||||
Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[0], &calc3Vectors[1], &calc3Vectors[2]))
|
||||
!Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[2], &calc3Vectors[1], &calc3Vectors[0]))
|
||||
{
|
||||
|
||||
for (u32 vertI = 0; vertI < 3; vertI++)
|
||||
{
|
||||
asm volatile(
|
||||
// VU0 macro program:
|
||||
// Copy data and set vert/normal "w" and st "z"+"w" to 1.0F
|
||||
|
||||
if (animState.currentFrame == animState.nextFrame)
|
||||
{
|
||||
o_vertices[addedFaces][0] = CURR_VERT.x;
|
||||
o_vertices[addedFaces][1] = CURR_VERT.y;
|
||||
o_vertices[addedFaces][2] = CURR_VERT.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_vertices[addedFaces][0] = calc3Vectors[vertI].x;
|
||||
o_vertices[addedFaces][1] = calc3Vectors[vertI].y;
|
||||
o_vertices[addedFaces][2] = calc3Vectors[vertI].z;
|
||||
}
|
||||
o_vertices[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
|
||||
|
||||
o_normals[addedFaces][0] = CURR_NORMAL.x;
|
||||
o_normals[addedFaces][1] = CURR_NORMAL.y;
|
||||
o_normals[addedFaces][2] = CURR_NORMAL.z;
|
||||
o_normals[addedFaces][3] = 1.0F;
|
||||
// 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
|
||||
|
||||
o_coordinates[addedFaces][0] = CURR_ST.x;
|
||||
o_coordinates[addedFaces][1] = CURR_ST.y;
|
||||
o_coordinates[addedFaces][2] = 1.0F;
|
||||
o_coordinates[addedFaces++][3] = 1.0F;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user