commit 59b190fe3b8c1dae705cf860ed39087c49df10bd
parent 98d026e481b5286f800b45d9548072f1e3132acd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 19 Jan 2021 16:54:36 +0100
Add the suvm_volume_compute_hash function
Diffstat:
3 files changed, 126 insertions(+), 2 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -25,7 +25,7 @@ option(NO_TEST "Do not build tests" OFF)
################################################################################
find_package(Embree 3.6 REQUIRED)
find_package(RCMake 0.4 REQUIRED)
-find_package(RSys 0.10 REQUIRED)
+find_package(RSys 0.12 REQUIRED)
find_package(StarTetraHedra)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
diff --git a/src/suvm.h b/src/suvm.h
@@ -16,6 +16,7 @@
#ifndef SUVM_H
#define SUVM_H
+#include <rsys/hash.h>
#include <rsys/rsys.h>
#include <float.h>
@@ -40,6 +41,13 @@
/* Maximum number of vertices per volumetric primitive */
#define SUVM_PRIMITIVE_MAX_VERTICES_COUNT 4
+enum suvm_volume_cpnt_flag {
+ SUVM_POSITIONS = BIT(0),
+ SUVM_INDICES = BIT(1),
+ SUVM_PRIMITIVE_DATA = BIT(2),
+ SUVM_VERTEX_DATA = BIT(3)
+};
+
struct suvm_data {
void (*get)(const size_t id, void* data, void* ctx); /* Data getter */
size_t size; /* Size of the data in bytes */
@@ -215,6 +223,12 @@ suvm_volume_get_primitive
const size_t iprim, /* In [0, suvm_volume_get_primitives_count[ */
struct suvm_primitive* prim);
+SUVM_API res_T
+suvm_volume_compute_hash
+ (const struct suvm_volume* volume,
+ const int cpnt_mask, /* Combination of suvm_volume_cpnt_flag */
+ hash256_T hash);
+
/*******************************************************************************
* Primitive API
******************************************************************************/
diff --git a/src/suvm_volume.c b/src/suvm_volume.c
@@ -23,6 +23,18 @@
#include <rsys/dynamic_array_size_t.h>
#include <rsys/ref_count.h>
+struct hash_context {
+ struct cpnt {
+ const void* mem;
+ size_t size; /* Size in bytes */
+ size_t chunk_min; /* Inclusive */
+ size_t chunk_max; /* Exclusive */
+ } cpnts[4];
+ int ncpnts;
+ int icpnt;
+};
+static const struct hash_context HASH_CONTEXT_NULL;
+
/* Generate the dynamic array of RTCBuildPrimitive */
#define DARRAY_NAME rtc_prim
#define DARRAY_DATA struct RTCBuildPrimitive
@@ -86,8 +98,14 @@ buffer_init_from_data
/* Fill the buffer with the submitted data */
FOR_EACH(idata, 0, ndata) {
- void* elmt = (char*)buf->mem + idata*buf->elmt_stride;
+ char* elmt = (char*)buf->mem + idata*buf->elmt_stride;
data->get(idata, elmt, context);
+
+ /* Clean up padding bytes to initialise them regarding their possible
+ * hashing by the suvm_volume_compute_hash function */
+ if(buf->elmt_stride != buf->elmt_size) {
+ memset(elmt + buf->elmt_size, 0, buf->elmt_stride - buf->elmt_size);
+ }
}
exit:
@@ -515,6 +533,31 @@ fixup_tetrahedra_normals(struct suvm_volume* vol)
}
static void
+get_chunk(char dst[64], const size_t ichunk, void* context)
+{
+ struct hash_context* ctx = context;
+ const struct cpnt* cpnt = NULL;
+ const char* chunk = NULL;
+ size_t cpnt_offset = 0;
+ size_t chunk_sz = 0;
+ ASSERT(dst && ctx);
+
+ cpnt = ctx->cpnts + ctx->icpnt;
+ ASSERT(cpnt->chunk_min <= ichunk);
+ ASSERT(cpnt->chunk_max > ichunk);
+
+ cpnt_offset = (ichunk - cpnt->chunk_min) * 64;
+ chunk = (const char*)cpnt->mem + cpnt_offset;
+ chunk_sz = MMIN(cpnt->size - cpnt_offset, 64);
+ memcpy(dst, chunk, chunk_sz);
+ if(chunk_sz < 64) memset(dst + chunk_sz, 0, 64 - chunk_sz);
+
+ if(ichunk == cpnt->chunk_max - 1) {
+ ++ctx->icpnt;
+ }
+}
+
+static void
volume_release(ref_T* ref)
{
struct suvm_volume* vol = NULL;
@@ -654,3 +697,70 @@ suvm_volume_get_primitive
volume_primitive_setup(vol, iprim, prim);
return RES_OK;
}
+
+res_T
+suvm_volume_compute_hash
+ (const struct suvm_volume* vol,
+ const int cpnt_mask,
+ hash256_T hash)
+{
+ struct chunked_data_desc chunked_data = CHUNKED_DATA_DESC_NULL;
+ struct hash_context ctx = HASH_CONTEXT_NULL;
+ size_t sz = 0;
+ int i = 0;
+ res_T res = RES_OK;
+
+ if(!vol || !hash) {
+ res = RES_OK;
+ goto error;
+ }
+
+ if(cpnt_mask & SUVM_POSITIONS) {
+ ctx.cpnts[i].mem = darray_float_cdata_get(&vol->positions);
+ ctx.cpnts[i].size = darray_float_size_get(&vol->positions) * sizeof(float);
+ ++i;
+ }
+ if(cpnt_mask & SUVM_INDICES) {
+ ctx.cpnts[i].mem = darray_u32_cdata_get(&vol->indices);
+ ctx.cpnts[i].size = darray_u32_size_get(&vol->indices) * sizeof(uint32_t);
+ ++i;
+ }
+ if(cpnt_mask & SUVM_PRIMITIVE_DATA) {
+ ctx.cpnts[i].mem = vol->prim_data.mem;
+ ctx.cpnts[i].size = vol->prim_data.size * vol->prim_data.elmt_stride;
+ ++i;
+ }
+ if(cpnt_mask & SUVM_VERTEX_DATA) {
+ ctx.cpnts[i].mem = vol->vert_data.mem;
+ ctx.cpnts[i].size = vol->vert_data.size * vol->vert_data.elmt_stride;
+ ++i;
+ }
+ ctx.ncpnts = i;
+
+ FOR_EACH(i, 0, ctx.ncpnts) {
+ const size_t nchunks = (ctx.cpnts[i].size + 63/*ceil*/) / 64;
+ if(i == ctx.ncpnts-1) {
+ sz += ctx.cpnts[i].size;
+ } else {
+ sz += nchunks * 64;
+ }
+ if(i == 0) {
+ ctx.cpnts[i].chunk_min = 0;
+ ctx.cpnts[i].chunk_max = nchunks;
+ } else {
+ ctx.cpnts[i].chunk_max = ctx.cpnts[i-1].chunk_max;
+ ctx.cpnts[i].chunk_max = ctx.cpnts[i-1].chunk_max + nchunks;
+ }
+ }
+ ctx.icpnt = 0;
+
+ chunked_data.get_chunk512 = get_chunk;
+ chunked_data.size = sz;
+ chunked_data.context = &ctx;
+ hash_sha256_chunked_data(&chunked_data, hash);
+
+exit:
+ return res;
+error:
+ goto exit;
+}