commit 7280acd0a10bf0ddc879b737f1c7aa6ff359912e
parent 54f4031ad8b5dba6e8b54f399694aa9105b29d09
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 20 Jan 2021 10:26:52 +0100
Test the suvm_volume_compute_hash function
Diffstat:
1 file changed, 171 insertions(+), 0 deletions(-)
diff --git a/src/test_suvm_volume.c b/src/test_suvm_volume.c
@@ -479,6 +479,147 @@ check_prims_intersect_aabb
}
static void
+check_hash
+ (const struct suvm_volume* vol,
+ const struct mesh* msh,
+ const int has_prim_data,
+ const int has_vert_data)
+{
+ void* mem = NULL;
+ float* pos = NULL;
+ uint32_t* ids = NULL;
+ void* prims = NULL;
+ void* verts = NULL;
+ size_t sz_pos = 0;
+ size_t sz_ids = 0;
+ size_t sz_prims = 0;
+ size_t sz_verts = 0;
+ size_t i;
+ hash256_T hash0, hash1;
+
+ CHK(suvm_volume_compute_hash(NULL, 0, hash0) == RES_BAD_ARG);
+ CHK(suvm_volume_compute_hash(vol, 0, NULL) == RES_BAD_ARG);
+ CHK(suvm_volume_compute_hash(vol, 0, hash0) == RES_OK);
+
+ hash_sha256(NULL, 0, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ /* Compute data size to hash. Note that SUVM align the data to hash on 64
+ * bytes by padding data with null bytes if necessary */
+ sz_pos = ALIGN_SIZE(msh->nvertices*sizeof(float[3]), 64u);
+ sz_ids = ALIGN_SIZE(msh->ntetrahedra*sizeof(uint32_t[4]), 64u);
+ if(has_prim_data) {
+ sz_prims = ALIGN_SIZE(msh->ntetrahedra*sizeof(size_t[4]), 64u);
+ }
+ if(has_vert_data) {
+ sz_verts = ALIGN_SIZE(msh->nvertices*sizeof(double[3]), 64u);
+ }
+ mem = mem_calloc(1, sz_pos + sz_ids + sz_prims + sz_verts);
+ CHK(mem != NULL);
+
+ /* Copy data to hash into the allocated memory block. Be carefull the memory
+ * layout used by SUVM to hash the volume. First the vertices, then the
+ * indices followed by the per prim data and finally the per vertex data */
+
+ /* SUVM stores the vertices in single precision. Convert vertex coordinates
+ * in float to ensure bit correspondance */
+ pos = mem;
+ FOR_EACH(i, 0, msh->nvertices) {
+ pos[i*3 + 0] = (float)msh->vertices[i*3+0];
+ pos[i*3 + 1] = (float)msh->vertices[i*3+1];
+ pos[i*3 + 2] = (float)msh->vertices[i*3+2];
+ }
+
+ /* SUVM stores the tetrahedron indices as 32 bits unsigned integers. Convert
+ * indices to ensure bit correspondance */
+ ids = (uint32_t*)((char*)mem + sz_pos);
+ FOR_EACH(i, 0, msh->ntetrahedra) {
+ ids[i*4 + 0] = (uint32_t)msh->tetrahedra[i*4+0];
+ ids[i*4 + 1] = (uint32_t)msh->tetrahedra[i*4+1];
+ ids[i*4 + 2] = (uint32_t)msh->tetrahedra[i*4+2];
+ ids[i*4 + 3] = (uint32_t)msh->tetrahedra[i*4+3];
+ }
+
+ /* Copy per primitive data */
+ if(has_prim_data) {
+ prims = ((char*)mem + sz_pos + sz_ids);
+ memcpy(prims, msh->tetrahedra, msh->ntetrahedra*sizeof(size_t[4]));
+ }
+
+ /* Copy per vertex data */
+ if(has_vert_data) {
+ verts = ((char*)mem + sz_pos + sz_ids + sz_prims);
+ memcpy(verts, msh->vertices, msh->nvertices*sizeof(double[3]));
+ }
+
+ CHK(suvm_volume_compute_hash(vol, SUVM_POSITIONS, hash0) == RES_OK);
+ hash_sha256(pos, sz_pos, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash(vol, SUVM_INDICES, hash0) == RES_OK);
+ hash_sha256(ids, sz_ids, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash(vol, SUVM_PRIMITIVE_DATA, hash0) == RES_OK);
+ hash_sha256(prims, sz_prims, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash(vol, SUVM_VERTEX_DATA, hash0) == RES_OK);
+ hash_sha256(verts, sz_verts, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash(vol, SUVM_POSITIONS|SUVM_INDICES, hash0) == RES_OK);
+ hash_sha256(mem, sz_pos + sz_ids, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash
+ (vol, SUVM_POSITIONS|SUVM_INDICES|SUVM_PRIMITIVE_DATA, hash0) == RES_OK);
+ hash_sha256(mem, sz_pos + sz_ids + sz_prims, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ CHK(suvm_volume_compute_hash(vol,
+ SUVM_POSITIONS|SUVM_INDICES|SUVM_PRIMITIVE_DATA|SUVM_VERTEX_DATA,
+ hash0) == RES_OK);
+ hash_sha256(mem, sz_pos + sz_ids + sz_prims + sz_verts, hash1);
+ CHK(hash256_eq(hash0, hash1));
+
+ mem_rm(mem);
+}
+
+static void
+test_volume_hash(struct suvm_device* dev, struct mesh* msh)
+{
+ struct suvm_tetrahedral_mesh_args args = SUVM_TETRAHEDRAL_MESH_ARGS_NULL;
+ struct suvm_volume* vol = NULL;
+
+ args.ntetrahedra = msh->ntetrahedra;
+ args.nvertices = msh->nvertices;
+ args.get_indices = get_indices;
+ args.get_position = get_position;
+ args.context = msh;
+ CHK(suvm_tetrahedral_mesh_create(dev, &args, &vol) == RES_OK);
+
+ check_hash(vol, msh, 0, 0);
+ CHK(suvm_volume_ref_put(vol) == RES_OK);
+
+ args.vertex_data.get = get_vert_data;
+ args.vertex_data.size = sizeof(double[3]);
+ args.vertex_data.alignment = ALIGNOF(double[3]);
+ CHK(suvm_tetrahedral_mesh_create(dev, &args, &vol) == RES_OK);
+
+ check_hash(vol, msh, 0, 1);
+ CHK(suvm_volume_ref_put(vol) == RES_OK);
+
+ args.tetrahedron_data.get = get_tetra_data;
+ args.tetrahedron_data.size = sizeof(size_t[4]);
+ args.tetrahedron_data.alignment = ALIGNOF(size_t[4]);
+ CHK(suvm_tetrahedral_mesh_create(dev, &args, &vol) == RES_OK);
+ check_hash(vol, msh, 1, 1);
+
+ CHK(suvm_volume_ref_put(vol) == RES_OK);
+}
+
+static void
prim_intersect_aabb
(const struct suvm_primitive* prim,
const double low[3],
@@ -612,6 +753,20 @@ test_volume_at_cube(struct suvm_device* dev)
}
static void
+test_volume_hash_cube(struct suvm_device* dev)
+{
+ struct mesh msh = MESH_NULL;
+
+ msh.vertices = box_vertices;
+ msh.nvertices = box_nverts;
+ msh.tetrahedra = box_indices;
+ msh.ntetrahedra = box_ntetras;
+ msh.tetrahedron_data_alignment = ALIGNOF(size_t[4]);
+ msh.vertex_data_alignment = ALIGNOF(double[3]);
+ test_volume_hash(dev, &msh);
+}
+
+static void
test_volume_at_ball(struct suvm_device* dev)
{
struct darray_prim prims;
@@ -724,6 +879,20 @@ test_volume_at_ball(struct suvm_device* dev)
darray_prim_release(&prims);
}
+static void
+test_volume_hash_ball(struct suvm_device* dev)
+{
+ struct mesh msh = MESH_NULL;
+
+ msh.vertices = ball_vertices;
+ msh.nvertices = ball_nvertices;
+ msh.tetrahedra = ball_tetrahedra;
+ msh.ntetrahedra = ball_ntetrahedra;
+ msh.tetrahedron_data_alignment = ALIGNOF(size_t[4]);
+ msh.vertex_data_alignment = ALIGNOF(double[3]);
+ test_volume_hash(dev, &msh);
+}
+
/*******************************************************************************
* Main function
******************************************************************************/
@@ -738,6 +907,8 @@ main(int argc, char** argv)
test_tetrahedral_mesh_creation(dev);
test_volume_at_cube(dev);
test_volume_at_ball(dev);
+ test_volume_hash_cube(dev);
+ test_volume_hash_ball(dev);
CHK(suvm_device_ref_put(dev) == RES_OK);