aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/runner.py6
-rw-r--r--tests/skinning_test_no_simd.cpp202
2 files changed, 208 insertions, 0 deletions
diff --git a/tests/runner.py b/tests/runner.py
index ac6755e0..6b85eb0e 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -4452,6 +4452,12 @@ else:
src = open(path_from_root('tests', 'raytrace.cpp'), 'r').read().replace('double', 'float') # benchmark with floats
self.do_benchmark(src, ['7', '256'], open(path_from_root('tests', 'raytrace_7_256.ppm')).read(), llvm_opts=True, handpicked=True)
+ def test_skinning(self):
+ global POST_OPTIMIZATIONS; POST_OPTIMIZATIONS = ['eliminator', 'closure']
+
+ src = open(path_from_root('tests', 'skinning_test_no_simd.cpp'), 'r').read()
+ self.do_benchmark(src, ['10000', '3000'], 'blah=0.000000', llvm_opts=True, handpicked=True)
+
def test_dlmalloc(self):
global POST_OPTIMIZATIONS; POST_OPTIMIZATIONS = ['eliminator']
diff --git a/tests/skinning_test_no_simd.cpp b/tests/skinning_test_no_simd.cpp
new file mode 100644
index 00000000..1df6e44c
--- /dev/null
+++ b/tests/skinning_test_no_simd.cpp
@@ -0,0 +1,202 @@
+// From https://github.com/chadaustin/Web-Benchmarks/blob/master/skinning_test_no_simd.cpp
+// Modifications:
+// 1. Run for a fixed # of iterations, so the total runtime is the benchmark
+// 2. Not have so much stuff on the stack in main()
+//
+// compiled in cygwin with:
+// g++ -Wall -O2 -o skinning_test_no_simd skinning_test_no_simd.cpp
+
+#include <vector>
+#include <set>
+#include <map>
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct CalBase4 {
+ float x, y, z, w;
+
+ void set(float _x, float _y, float _z, float _w) {
+ x = _x;
+ y = _y;
+ z = _z;
+ w = _w;
+ }
+};
+
+struct CalVector4 : CalBase4 {
+ CalVector4() {
+ x = 0.0f;
+ y = 0.0f;
+ z = 0.0f;
+ w = 0.0f;
+ }
+
+ CalVector4(float x, float y, float z, float w = 0.0f) {
+ this->x = x;
+ this->y = y;
+ this->z = z;
+ this->w = w;
+ }
+
+ void setAsVector(float x, float y, float z) {
+ this->x = x;
+ this->y = y;
+ this->z = z;
+ w = 0.0f;
+ }
+};
+
+struct CalPoint4 : CalBase4 {
+ CalPoint4() {
+ x = 0.0f;
+ y = 0.0f;
+ z = 0.0f;
+ w = 1.0f;
+ }
+
+ CalPoint4(float x, float y, float z, float w = 1.0f) {
+ this->x = x;
+ this->y = y;
+ this->z = z;
+ this->w = w;
+ }
+
+ void setAsPoint(float x, float y, float z) {
+ x = this->x;
+ y = this->y;
+ z = this->z;
+ w = 1.0f;
+ }
+};
+
+// 3x3 transform matrix plus a translation 3-vector (stored in the w components
+// of the rows.
+struct BoneTransform {
+ CalVector4 rowx;
+ CalVector4 rowy;
+ CalVector4 rowz;
+};
+
+struct Influence
+{
+ Influence() {
+ boneId = -1;
+ weight = 0.0f;
+ lastInfluenceForThisVertex = 0;
+ }
+
+ Influence(unsigned b, float w, bool last) {
+ boneId = b;
+ weight = w;
+ lastInfluenceForThisVertex = last ? 1 : 0;
+ }
+
+ unsigned boneId;
+ float weight;
+ unsigned lastInfluenceForThisVertex;
+};
+
+struct Vertex
+{
+ CalPoint4 position;
+ CalVector4 normal;
+};
+
+inline void ScaleMatrix(BoneTransform& result, const BoneTransform& mat, const float s) {
+ result.rowx.x = s * mat.rowx.x;
+ result.rowx.y = s * mat.rowx.y;
+ result.rowx.z = s * mat.rowx.z;
+ result.rowx.w = s * mat.rowx.w;
+ result.rowy.x = s * mat.rowy.x;
+ result.rowy.y = s * mat.rowy.y;
+ result.rowy.z = s * mat.rowy.z;
+ result.rowy.w = s * mat.rowy.w;
+ result.rowz.x = s * mat.rowz.x;
+ result.rowz.y = s * mat.rowz.y;
+ result.rowz.z = s * mat.rowz.z;
+ result.rowz.w = s * mat.rowz.w;
+}
+inline void AddScaledMatrix(BoneTransform& result, const BoneTransform& mat, const float s) {
+ result.rowx.x += s * mat.rowx.x;
+ result.rowx.y += s * mat.rowx.y;
+ result.rowx.z += s * mat.rowx.z;
+ result.rowx.w += s * mat.rowx.w;
+ result.rowy.x += s * mat.rowy.x;
+ result.rowy.y += s * mat.rowy.y;
+ result.rowy.z += s * mat.rowy.z;
+ result.rowy.w += s * mat.rowy.w;
+ result.rowz.x += s * mat.rowz.x;
+ result.rowz.y += s * mat.rowz.y;
+ result.rowz.z += s * mat.rowz.z;
+ result.rowz.w += s * mat.rowz.w;
+}
+inline void TransformPoint(CalVector4& result, const BoneTransform& m, const CalBase4& v) {
+ result.x = m.rowx.x * v.x + m.rowx.y * v.y + m.rowx.z * v.z + m.rowx.w;
+ result.y = m.rowy.x * v.x + m.rowy.y * v.y + m.rowy.z * v.z + m.rowy.w;
+ result.z = m.rowz.x * v.x + m.rowz.y * v.y + m.rowz.z * v.z + m.rowz.w;
+}
+inline void TransformVector(CalVector4& result, const BoneTransform& m, const CalBase4& v) {
+ result.x = m.rowx.x * v.x + m.rowx.y * v.y + m.rowx.z * v.z;
+ result.y = m.rowy.x * v.x + m.rowy.y * v.y + m.rowy.z * v.z;
+ result.z = m.rowz.x * v.x + m.rowz.y * v.y + m.rowz.z * v.z;
+}
+
+void calculateVerticesAndNormals_x87(
+ const BoneTransform* boneTransforms,
+ int vertexCount,
+ const Vertex* vertices,
+ const Influence* influences,
+ CalVector4* output_vertex
+) {
+
+ BoneTransform total_transform;
+
+ // calculate all submesh vertices
+ while (vertexCount--) {
+ ScaleMatrix(total_transform, boneTransforms[influences->boneId], influences->weight);
+
+ while (!influences++->lastInfluenceForThisVertex) {
+ AddScaledMatrix(total_transform, boneTransforms[influences->boneId], influences->weight);
+ }
+
+ TransformPoint(output_vertex[0], total_transform, vertices->position);
+ TransformVector(output_vertex[1], total_transform, vertices->normal);
+ ++vertices;
+ output_vertex += 2;
+ }
+}
+
+int main (int argc, char*argv[])
+{
+ const int N=atoi(argv[1]);
+ const int M=atoi(argv[2]);
+
+ Vertex *v = new Vertex[N];
+ Influence *i = new Influence[N];
+ for (int k = 0; k < N; ++k) {
+ v[k].position.setAsPoint(1.0f, 2.0f, 3.0f);
+ v[k].normal.setAsVector(0.0f, 0.0f, 1.0f);
+ i[k].boneId = 0;
+ i[k].weight = 1.0f;
+ i[k].lastInfluenceForThisVertex = true;
+ }
+
+ BoneTransform bt;
+ memset(&bt, 0, sizeof(bt));
+
+ CalVector4 *output = new CalVector4[N * 2];
+
+ for (unsigned j = 0; j < M; j++)
+ calculateVerticesAndNormals_x87(&bt, N, v, i, output);
+
+ float sum = 0;
+ for (unsigned j = 0; j < N * 2; ++j) {
+ sum += (output[j].x + output[j].y + output[j].z + output[j].w);
+ }
+
+ printf("blah=%f\n", sum);
+}
+