Revision: 56768
http://sourceforge.net/p/brlcad/code/56768
Author: brlcad
Date: 2013-08-13 03:16:40 +0000 (Tue, 13 Aug 2013)
Log Message:
-----------
Fix 32-bit TIE. The problem was someone trying to be far too clever packing
bits into a pointer address. You read that right. Bits were being set/unset
and read from WITHIN the pointer VALUE. Even remember telling Justin many many
years ago this would be a problem, but obviously nothing came of that. My
vague recollection was that he was hijacking particular bits that were always
zero given particular struct allocation sizes. Of course, this is incredibly
presumptuous and volatile to struct member type sizes, 32-bit vs 64-bit
compilation, implicit padding/alignment issues, and more.
This gets TIE working on 32-bit compilation (and generally more portably all
around) by extracting those bit values that were being packed into their own
struct element (for both the kdtree and the tri structs) where this was
happening. This took quite a bit of very cautious surgery to extract and
propagate the bits correctly. There may be more needed (e.g., didn't test
single-precision), but seems to work swell in all the tests I threw at it.
Made (probably unnecessarily) most of the memory allocation zero-initialize
just for good measure too.
Modified Paths:
--------------
brlcad/trunk/src/librt/primitives/bot/tie.c
brlcad/trunk/src/librt/primitives/bot/tie_kdtree.c
brlcad/trunk/src/librt/primitives/bot/tieprivate.h
Modified: brlcad/trunk/src/librt/primitives/bot/tie.c
===================================================================
--- brlcad/trunk/src/librt/primitives/bot/tie.c 2013-08-13 02:53:41 UTC (rev
56767)
+++ brlcad/trunk/src/librt/primitives/bot/tie.c 2013-08-13 03:16:40 UTC (rev
56768)
@@ -100,10 +100,11 @@
tri->v[0] = v1.v[i2] - tri->data[0].v[i2];
tri->v[1] = v2.v[i2] - tri->data[0].v[i2];
+ /* !!! what? no entiendo. */
if (i1 == 0 && i2 == 1)
- tri->v = (tfloat *)((intptr_t)(tri->v) + 2);
+ tri->b = tri->b + 2;
else if (i1 == 0)
- tri->v = (tfloat *)((intptr_t)(tri->v) + 1);
+ tri->b = tri->b + 1;
/* Compute DotVN */
VSCALE(v1.v, tri->data[0].v, -1.0);
@@ -134,7 +135,7 @@
tie->tri_num = 0;
tie->tri_num_alloc = tri_num;
/* set to NULL if tri_num == 0. bu_malloc(0) causes issues. */
- tie->tri_list = tri_num?(struct tie_tri_s *)bu_malloc(sizeof(struct
tie_tri_s) * tri_num, "tie_init"):NULL;
+ tie->tri_list = tri_num?(struct tie_tri_s *)bu_calloc(tri_num,
sizeof(struct tie_tri_s), "tie_init"):NULL;
tie->stat = 0;
tie->rays_fired = 0;
}
@@ -154,7 +155,7 @@
/* Free Triangle Data */
for (i = 0; i < tie->tri_num; i++) {
- tfloat *ptr = (tfloat *)((intptr_t)(tie->tri_list[i].v) & ~0x7L);
+ tfloat *ptr = tie->tri_list[i].v;
bu_free(ptr, "free tfloat list");
}
bu_free(tie->tri_list, "tie_free");
@@ -209,9 +210,10 @@
struct tie_id_s t = {{0,0,0},{0,0,0},0,0,0}, id_list[256];
struct tie_tri_s *hit_list[256], *tri;
struct tie_geom_s *data;
- struct tie_kdtree_s *node_aligned, *temp[2];
+ struct tie_kdtree_s *node, *temp[2];
tfloat near, far, dirinv[3], dist;
- unsigned int i, n, hit_count;
+ unsigned int i, n;
+ uint8_t hit_count;
int ab[3], split, stack_ind;
void *result;
@@ -233,8 +235,8 @@
ab[i] = dirinv[i] < 0.0 ? 1.0 : 0.0;
}
- /* Extracting value of splitting plane from tie->kdtree pointer */
- split = ((intptr_t)(((struct tie_kdtree_s *)((intptr_t)tie->kdtree &
~0x7L))->data)) & 0x3;
+ /* Extracting value of splitting plane from the kdtree */
+ split = tie->kdtree->b & (uint32_t)0x3L;
/* Initialize ray segment */
if (ray->dir[split] < 0.0)
@@ -256,7 +258,7 @@
* Take the pointer from stack[stack_ind] and remove lower pts bits
used to store data to
* give a valid ptr address.
*/
- node_aligned = (struct tie_kdtree_s *)((intptr_t)stack[stack_ind].node
& ~0x7L);
+ node = stack[stack_ind].node;
stack_ind--;
/*
@@ -269,20 +271,20 @@
*
* Gordon Stoll's Mantra - Rays are Measured in Millions :-)
*/
- while (node_aligned && node_aligned->data &&
TIE_HAS_CHILDREN(node_aligned->data)) {
+ while (node && node->data && TIE_HAS_CHILDREN(node->b)) {
ray->kdtree_depth++;
/* Retrieve the splitting plane */
- split = ((intptr_t)(node_aligned->data)) & 0x3;
+ split = node->b & (uint32_t)0x3L;
/* Calculate the projected 1d distance to splitting axis */
- dist = (node_aligned->axis - ray->pos[split]) * dirinv[split];
+ dist = (node->axis - ray->pos[split]) * dirinv[split];
- temp[0] = &((struct tie_kdtree_s *)(node_aligned->data))[ab[split]];
- temp[1] = &((struct tie_kdtree_s
*)(node_aligned->data))[1-ab[split]];
+ temp[0] = &((struct tie_kdtree_s *)(node->data))[ab[split]];
+ temp[1] = &((struct tie_kdtree_s *)(node->data))[1-ab[split]];
i = near >= dist; /* Node B Only? */
- node_aligned = (struct tie_kdtree_s *)((intptr_t)(temp[i]) & ~0x7L);
+ node = temp[i];
if (far < dist || i)
continue;
@@ -295,7 +297,7 @@
far = dist;
}
- if (!node_aligned || !node_aligned->data) {
+ if (!node || !node->data) {
/* bu_log("INTERNAL ERROR: Unexpected TIE tree traversal
encountered\n"); */
continue;
}
@@ -306,7 +308,7 @@
*/
hit_count = 0;
- data = (struct tie_geom_s *)(node_aligned->data);
+ data = (struct tie_geom_s *)(node->data);
for (i = 0; i < data->tri_num; i++) {
/*
@@ -333,11 +335,11 @@
VSCALE(t.pos, ray->dir, t.dist);
VADD2(t.pos, ray->pos, t.pos);
- /* Extract i1 and i2 indices from lower bits of the v pointer */
- v = (tfloat *)((intptr_t)(tri->v) & ~0x7L);
+ /* Extract i1 and i2 indices from the 'b' field */
+ v = tri->v;
- i1 = TIE_TAB1[((intptr_t)(tri->v) & 0x7L)];
- i2 = TIE_TAB1[3 + ((intptr_t)(tri->v) & 0x7L)];
+ i1 = TIE_TAB1[tri->b & (uint32_t)0x7L];
+ i2 = TIE_TAB1[3 + (tri->b & (uint32_t)0x7L)];
/* Compute U and V */
u0 = t.pos[i1] - tri->data[0].v[i1];
@@ -363,7 +365,7 @@
continue;
/* Triangle Intersected, append it in the list */
- if (hit_count < 0xff) {
+ if (hit_count < 0xFF) {
hit_list[hit_count] = tri;
id_list[hit_count] = t;
hit_count++;
@@ -455,9 +457,8 @@
plist = (void *)((intptr_t)plist + pstride);
/* ??? this looks like it might cause fragmentation? use a memory pool?
*/
- tie->tri_list[tie->tri_num].v = (tfloat *)bu_malloc(2*sizeof(tfloat),
"alloc tfloat list");
- if (tie->tri_list[tie->tri_num].v == NULL)
- bu_log("Bad malloc! %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);
+ tie->tri_list[tie->tri_num].v = (tfloat *)bu_calloc(2, sizeof(tfloat),
"alloc tfloat list");
+ tie->tri_list[tie->tri_num].b = 0;
tie->tri_num++;
}
return;
Modified: brlcad/trunk/src/librt/primitives/bot/tie_kdtree.c
===================================================================
--- brlcad/trunk/src/librt/primitives/bot/tie_kdtree.c 2013-08-13 02:53:41 UTC
(rev 56767)
+++ brlcad/trunk/src/librt/primitives/bot/tie_kdtree.c 2013-08-13 03:16:40 UTC
(rev 56768)
@@ -116,16 +116,14 @@
static void
tie_kdtree_free_node(struct tie_kdtree_s *node)
{
- struct tie_kdtree_s *node_aligned = (struct tie_kdtree_s *)((intptr_t)node
& ~0x7L);
-
- if (node_aligned && node_aligned->data &&
TIE_HAS_CHILDREN(node_aligned->data)) {
+ if (node && TIE_HAS_CHILDREN(node->b)) {
/* Node Data is KDTREE Children, Recurse */
- tie_kdtree_free_node(&((struct tie_kdtree_s
*)(((intptr_t)(node_aligned->data)) & ~0x7L))[0]);
- tie_kdtree_free_node(&((struct tie_kdtree_s
*)(((intptr_t)(node_aligned->data)) & ~0x7L))[1]);
+ tie_kdtree_free_node(&((struct tie_kdtree_s *)(node->data))[0]);
+ tie_kdtree_free_node(&((struct tie_kdtree_s *)(node->data))[1]);
} else {
/* This node points to a geometry node, free it */
struct tie_geom_s *tmp;
- tmp = (struct tie_geom_s *)((intptr_t)(node_aligned->data) & ~0x7L);
+ tmp = (struct tie_geom_s *)node->data;
if (tmp) {
if (tmp->tri_num > 0) {
bu_free(tmp->tri_list, "tri_list");
@@ -597,17 +595,11 @@
bu_bomb("Illegal tie kdtree method\n");
/* Allocate 2 children nodes for the parent node */
- node->data = (void *)bu_calloc(2, sizeof(struct tie_kdtree_s),
__FUNCTION__);
- if(((intptr_t)node->data & 0x7L))
- bu_log("node->data 0x%X is not aligned! %zu\n", node->data,
(intptr_t)node->data & 0x7L);
+ node->data = bu_calloc(2, sizeof(struct tie_kdtree_s), __FUNCTION__);
+ node->b = 0;
BU_ALLOC(((struct tie_kdtree_s *)(node->data))[0].data, struct tie_geom_s);
- if(((intptr_t)((struct tie_kdtree_s *)(node->data))[0].data & 0x7L))
- bu_log("node->data[0].data 0x%X is not aligned!\n", ((struct
tie_kdtree_s *)(node->data))[0].data);
-
BU_ALLOC(((struct tie_kdtree_s *)(node->data))[1].data, struct tie_geom_s);
- if(((intptr_t)((struct tie_kdtree_s *)(node->data))[1].data & 0x7L))
- bu_log("node->data[1].data 0x%X is not aligned!\n", ((struct
tie_kdtree_s *)(node->data))[1].data);
/* Initialize Triangle List */
child[0] = ((struct tie_geom_s *)(((struct tie_kdtree_s
*)(node->data))[0].data));
@@ -665,8 +657,9 @@
bu_free( child[n]->tri_list, "tri_list");
child[n]->tri_list = NULL;
}
- } else
+ } else {
child[n]->tri_list = (struct tie_tri_s
**)bu_realloc(child[n]->tri_list, sizeof(struct tie_tri_s *)*child[n]->tri_num,
__FUNCTION__);
+ }
}
/*
@@ -690,7 +683,7 @@
/* Assign the splitting dimension to the node */
/* If we've come this far then YES, this node DOES have child nodes, MARK
it as so. */
- node->data = (void *)(TIE_SET_HAS_CHILDREN(node->data) + split);
+ node->b = TIE_SET_HAS_CHILDREN(node->b) + split;
}
/*************************************************************
Modified: brlcad/trunk/src/librt/primitives/bot/tieprivate.h
===================================================================
--- brlcad/trunk/src/librt/primitives/bot/tieprivate.h 2013-08-13 02:53:41 UTC
(rev 56767)
+++ brlcad/trunk/src/librt/primitives/bot/tieprivate.h 2013-08-13 03:16:40 UTC
(rev 56768)
@@ -30,16 +30,17 @@
extern "C" {
#endif
-/* The last three bits of the void* in the kdtree are used to store data about
- * the object. 0x4 marks if the node has children (is set to 0 for a leaf), the
- * last two are the encoding for the splitting plane. Allocation must be a
- * multiple of 8. */
-#define TIE_HAS_CHILDREN(ptr) (((intptr_t)(ptr))&0x4L)
-#define TIE_SET_HAS_CHILDREN(ptr) (((intptr_t)(ptr))|0x4L)
+/* The last three bits of the 'b' field in the kdtree are used to
+ * store data about the object. 0x4L marks if the node has children
+ * (is set to 0 for a leaf), the last two are the encoding for the
+ * splitting plane.
+ */
+#define TIE_HAS_CHILDREN(bits) (bits & (uint32_t)0x4L)
+#define TIE_SET_HAS_CHILDREN(bits) (bits | (uint32_t)0x4L)
struct tie_geom_s {
- struct tie_tri_s **tri_list;
- unsigned int tri_num;
+ struct tie_tri_s **tri_list; /* 4-bytes or 8-bytes */
+ uint32_t tri_num; /* 4-bytes */
};
#ifdef _WIN32
@@ -48,9 +49,9 @@
#endif
struct tie_stack_s {
- struct tie_kdtree_s *node;
- tfloat near;
- tfloat far;
+ struct tie_kdtree_s *node; /* 4-bytes or 8-bytes */
+ tfloat near; /* 4-bytes or 8-bytes */
+ tfloat far; /* 4-bytes or 8-bytes */
};
#ifdef __cplusplus
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits