From 2df88d0ff22aaf1182712ae67761a773a1ce32c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 2 Oct 2026 10:11:27 +0200 Subject: [PATCH 1/5] Fix VDB recommit and observer registry issues - recommiting VDB reallocated VDBGrid, which is referenced by samplers; VDBGrid is now embedded - fix crash when recommitting VDB increased the number of leaf nodes when an old VDB leaf node access observer was reused and not recreated; observers still become stale and need to be recreated when the VDB volumes changes, to get correct access counts - fix of-by-one error when an older observer was removed while a recent observer still stays registered --- CHANGELOG.md | 1 + doc/api.md | 4 + .../devices/cpu/observer/ObserverRegistry.cpp | 4 +- .../devices/cpu/observer/ObserverRegistry.h | 2 +- .../devices/cpu/observer/ObserverRegistry.ih | 1 + .../cpu/observer/ObserverRegistry.ispc | 34 ++++--- .../cpu/volume/vdb/VdbLeafAccessObserver.cpp | 2 +- .../cpu/volume/vdb/VdbLeafAccessObserver.ih | 3 +- .../devices/cpu/volume/vdb/VdbSampler.ispc | 2 +- openvkl/devices/cpu/volume/vdb/VdbVolume.cpp | 9 +- openvkl/devices/cpu/volume/vdb/VdbVolume.h | 2 +- openvkl/devices/cpu/volume/vdb/VdbVolume.ispc | 12 --- .../devices/cpu/volume/vdb/VdbVolumeShared.h | 3 +- testing/apps/CMakeLists.txt | 2 + testing/apps/tests/vdb_volume_recommit.cpp | 89 +++++++++++++++++++ 15 files changed, 134 insertions(+), 36 deletions(-) create mode 100644 testing/apps/tests/vdb_volume_recommit.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index ef314cf3..68292d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Version History - Ship all release packages with OpenVDB - Set DEPENDENTLOADFLAG also on the Windows binaries built with Clang/SYCL - Fix linking applications against the GPU device module on Windows +- Fix VDB recommit and observer registry issues - Update to latest versions of dependencies (compiling the tests now needs CMake v3.16 and C++14) diff --git a/doc/api.md b/doc/api.md index 3579d931..ea824555 100644 --- a/doc/api.md +++ b/doc/api.md @@ -1845,6 +1845,10 @@ so that the observer may be mapped again. When an observer is no longer needed, it should be released using `vklRelease`. +Observers are tied to the state of the observed volume at the time the observer +was created. Before committing a volume again, release all observers of that +volume and of its samplers; create new observers after the commit as needed. + The observer API is not thread safe, and these functions should not be called concurrently on the same object. diff --git a/openvkl/devices/cpu/observer/ObserverRegistry.cpp b/openvkl/devices/cpu/observer/ObserverRegistry.cpp index 383b3ee4..3c5e5adb 100644 --- a/openvkl/devices/cpu/observer/ObserverRegistry.cpp +++ b/openvkl/devices/cpu/observer/ObserverRegistry.cpp @@ -28,10 +28,10 @@ namespace openvkl { } template - void ObserverRegistry::add(void *ptr) + void ObserverRegistry::add(void *ptr, size_t numElements) { std::lock_guard g(mtx); - CALL_ISPC(ObserverRegistry_add, ispcEquivalent, ptr); + CALL_ISPC(ObserverRegistry_add, ispcEquivalent, ptr, numElements); } template diff --git a/openvkl/devices/cpu/observer/ObserverRegistry.h b/openvkl/devices/cpu/observer/ObserverRegistry.h index 2beb00da..841c237a 100644 --- a/openvkl/devices/cpu/observer/ObserverRegistry.h +++ b/openvkl/devices/cpu/observer/ObserverRegistry.h @@ -29,7 +29,7 @@ namespace openvkl { ObserverRegistry(ObserverRegistry &&other) = delete; ObserverRegistry &operator=(ObserverRegistry &&other) = delete; - void add(void *ptr); + void add(void *ptr, size_t numElements); void remove(void *ptr); diff --git a/openvkl/devices/cpu/observer/ObserverRegistry.ih b/openvkl/devices/cpu/observer/ObserverRegistry.ih index f8b6e30d..f9ce4a41 100644 --- a/openvkl/devices/cpu/observer/ObserverRegistry.ih +++ b/openvkl/devices/cpu/observer/ObserverRegistry.ih @@ -8,4 +8,5 @@ struct ObserverRegistry size_t size; size_t capacity; void *uniform *uniform data; + size_t *uniform numElements; // per data entry }; diff --git a/openvkl/devices/cpu/observer/ObserverRegistry.ispc b/openvkl/devices/cpu/observer/ObserverRegistry.ispc index f387be1e..c4818dab 100644 --- a/openvkl/devices/cpu/observer/ObserverRegistry.ispc +++ b/openvkl/devices/cpu/observer/ObserverRegistry.ispc @@ -13,6 +13,7 @@ export void *uniform EXPORT_UNIQUE(ObserverRegistry_create) self->size = 0; self->capacity = 0; self->data = NULL; + self->numElements = NULL; return self; } @@ -21,13 +22,16 @@ export void EXPORT_UNIQUE(ObserverRegistry_destroy, void *uniform _self) assert(_self); ObserverRegistry *uniform self = ((ObserverRegistry * uniform) _self); if (self->data) - delete self->data; + delete[] self->data; + if (self->numElements) + delete[] self->numElements; delete self; } export void EXPORT_UNIQUE(ObserverRegistry_add, void *uniform _self, - void *uniform ptr) + void *uniform ptr, + uniform size_t numElements) { assert(_self); ObserverRegistry *uniform self = ((ObserverRegistry * uniform) _self); @@ -40,23 +44,31 @@ export void EXPORT_UNIQUE(ObserverRegistry_add, assert(self->size <= self->capacity); if (self->size >= self->capacity) { void *uniform *uniform oldData = self->data; + size_t *uniform oldNumElements = self->numElements; const uniform size_t newCapacity = self->capacity + 1; // ISPC seems to not be able to parse // uniform new void *uniform [...] // directly. typedef void *uniform VoidPtr; - self->data = uniform new uniform VoidPtr[newCapacity]; - self->capacity = newCapacity; + self->data = uniform new uniform VoidPtr[newCapacity]; + self->numElements = uniform new uniform size_t[newCapacity]; + self->capacity = newCapacity; if (oldData) { - if (self->size > 0) + if (self->size > 0) { memcpy(self->data, oldData, sizeof(void *uniform) * self->size); - delete oldData; + memcpy(self->numElements, + oldNumElements, + sizeof(uniform size_t) * self->size); + } + delete[] oldData; + delete[] oldNumElements; } else assert(self->capacity == 1); } - self->data[self->size] = ptr; - self->size = self->size + 1; + self->data[self->size] = ptr; + self->numElements[self->size] = numElements; + self->size = self->size + 1; } export void EXPORT_UNIQUE(ObserverRegistry_remove, @@ -67,9 +79,11 @@ export void EXPORT_UNIQUE(ObserverRegistry_remove, ObserverRegistry *uniform self = ((ObserverRegistry * uniform) _self); for (uniform size_t i = 0; i < self->size; ++i) { if (self->data[i] == ptr) { - self->data[i] = self->data[self->size]; - self->size = self->size - 1; // Like std::vector, we never decrease capacity. + self->size = self->size - 1; + self->data[i] = self->data[self->size]; + self->numElements[i] = self->numElements[self->size]; + return; } } } diff --git a/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.cpp b/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.cpp index 468ebada..e8a26939 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.cpp +++ b/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.cpp @@ -21,7 +21,7 @@ namespace openvkl { { accessBuffer = allocator.allocate(grid.numLeaves); size = grid.numLeaves; - getRegistry().add(accessBuffer); + getRegistry().add(accessBuffer, size); } template diff --git a/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.ih b/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.ih index 78e45e38..43817b8e 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.ih +++ b/openvkl/devices/cpu/volume/vdb/VdbLeafAccessObserver.ih @@ -25,7 +25,8 @@ inline uniform bool VdbLeafAccessObserver_isObservable( for (uniform size_t i = 0; i < registry->size; ++i) { \ uint32 *uniform accessBuffer = ((uint32 * uniform) registry->data[i]); \ /* NOTE: this is not synchronized between threads! */ \ - accessBuffer[leafIndex] = 1; \ + if (leafIndex < registry->numElements[i]) \ + accessBuffer[leafIndex] = 1; \ } \ } diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc index 684c1b71..f8d27b45 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc @@ -575,7 +575,7 @@ export void EXPORT_UNIQUE(VdbSampler_create, // Our internal sampling interface. The sampler object is passed into the // inner loop. const VdbVolume *uniform vdbVolume = (const VdbVolume *uniform)volume; - sampler->grid = volume->grid; + sampler->grid = &volume->grid; sampler->leafAccessObservers = leafAccessObservers; } diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp b/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp index 49329f35..a7745c46 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp @@ -52,7 +52,8 @@ namespace openvkl { allocator.deallocate(grid->leafData); allocator.deallocate(grid->nodesPackedDense); allocator.deallocate(grid->nodesPackedTile); - allocator.deallocate(grid); + std::memset(grid, 0, sizeof(VdbGrid)); + grid = nullptr; } // other Data members are cleared in commit() as they are replaced, or on @@ -596,7 +597,7 @@ namespace openvkl { // We use exceptions for error reporting, so make sure to release // memory in catch()! try { - grid = allocator.allocate(1); + grid = &this->getSh()->grid; if (dense && !denseData.size()) { runtimeError("VdbVolume has dense flag set, but no dense data"); @@ -1037,10 +1038,6 @@ namespace openvkl { } } - CALL_ISPC(VdbVolume_setGrid, - this->getSh(), - reinterpret_cast(grid)); - computeValueRanges( leafOffsets, *leafLevel, *leafFormat, this->getSh(), grid); diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.h b/openvkl/devices/cpu/volume/vdb/VdbVolume.h index 69545afe..0211bdd6 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.h +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.h @@ -201,7 +201,7 @@ namespace openvkl { VKLFeatureFlagsInternal temporalFeatureFlags{VKL_FEATURE_FLAG_NONE}; - VdbGrid *grid{nullptr}; + VdbGrid *grid{nullptr}; // &getSh()->grid if committed Allocator allocator{this->getDevice()}; // Data can either be interpreted as constant cell data, or diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc b/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc index 6af51f11..550b407b 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc @@ -31,15 +31,3 @@ export void EXPORT_UNIQUE(VdbVolume_Constructor, void *uniform _self) * Destructor for ISPC versions of the volume. */ export void EXPORT_UNIQUE(VdbVolume_destroy, void *uniform _self) {} - -/* - * Initialize the volume data structure. - */ -export void EXPORT_UNIQUE(VdbVolume_setGrid, - void *uniform _self, - const VdbGrid *uniform grid) -{ - assert(_self); - VdbVolume *uniform volume = (VdbVolume * uniform) _self; - volume->grid = grid; -} diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h b/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h index 8305c1be..494e942c 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h +++ b/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h @@ -4,6 +4,7 @@ #pragma once #include "../VolumeShared.h" +#include "VdbGridShared.h" #ifdef __cplusplus namespace ispc { @@ -16,7 +17,7 @@ namespace ispc { struct VdbVolume { VolumeShared super; - const VdbGrid *VKL_INTEROP_UNIFORM grid; + VdbGrid grid; // embedded: samplers rely on a stable address }; #ifdef __cplusplus diff --git a/testing/apps/CMakeLists.txt b/testing/apps/CMakeLists.txt index 5e69341d..3f189a46 100644 --- a/testing/apps/CMakeLists.txt +++ b/testing/apps/CMakeLists.txt @@ -144,6 +144,7 @@ if (BUILD_TESTING) tests/vdb_volume_motion_blur.cpp tests/vdb_volume_inner_node_observer.cpp tests/vdb_volume_dense.cpp + tests/vdb_volume_recommit.cpp tests/particle_volume_sampling.cpp tests/particle_volume_gradients.cpp tests/particle_volume_value_range.cpp @@ -194,6 +195,7 @@ if (BUILD_TESTING) tests/vdb_volume.cpp tests/vdb_volume_multi.cpp tests/vdb_volume_motion_blur.cpp + tests/vdb_volume_recommit.cpp tests/hit_iterator.cpp tests/interval_iterator.cpp tests/multi_device.cpp diff --git a/testing/apps/tests/vdb_volume_recommit.cpp b/testing/apps/tests/vdb_volume_recommit.cpp new file mode 100644 index 00000000..e34d8ec4 --- /dev/null +++ b/testing/apps/tests/vdb_volume_recommit.cpp @@ -0,0 +1,89 @@ +// Copyright 2026 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include "../../external/catch.hpp" +#include "openvkl_testing.h" +#include "wrappers.h" + +using namespace openvkl::testing; + +// only the grid changes on recommit; sampler parameters (e.g. filter) are not +// updated by a volume recommit, thus are kept unchanged + +static const VKLFilter filters[] = { + VKL_FILTER_NEAREST, VKL_FILTER_LINEAR, VKL_FILTER_CUBIC}; + +static VKLSampler newSampler(VKLVolume volume, VKLFilter filter) +{ + VKLSampler sampler = vklNewSampler(volume); + vklSetInt(sampler, "filter", filter); + vklCommit(sampler); + return sampler; +} + +// sampler created before the recommit must match a fresh sampler +static void requireSamplesOfFreshSampler(VKLVolume volume, + VKLSampler sampler, + VKLFilter filter, + unsigned int attributeIndex = 0) +{ + VKLSampler freshSampler = newSampler(volume, filter); + + const vkl_box3f bbox = vklGetBoundingBox(volume); + std::mt19937 eng(0); + std::uniform_real_distribution distX(bbox.lower.x, bbox.upper.x); + std::uniform_real_distribution distY(bbox.lower.y, bbox.upper.y); + std::uniform_real_distribution distZ(bbox.lower.z, bbox.upper.z); + + size_t numValid = 0; + for (size_t i = 0; i < 64; i++) { + const vkl_vec3f oc{distX(eng), distY(eng), distZ(eng)}; + const float expected = + vklComputeSampleWrapper(&freshSampler, &oc, attributeIndex, 0.f); + const float sample = + vklComputeSampleWrapper(&sampler, &oc, attributeIndex, 0.f); + + INFO("filter = " << filter << ", attributeIndex = " << attributeIndex); + INFO("objectCoordinates = " << oc.x << " " << oc.y << " " << oc.z); + if (std::isnan(expected)) { + REQUIRE(std::isnan(sample)); + } else { + REQUIRE(sample == expected); + numValid++; + } + } + REQUIRE(numValid > 0); + + vklRelease(freshSampler); +} + +#if OPENVKL_DEVICE_CPU_VDB || defined(OPENVKL_TESTING_GPU) +TEST_CASE("VDB volume recommit with existing sampler", "[volume_sampling]") +{ + initializeOpenVKL(); + + SECTION("sparse") + { + for (VKLFilter filter : filters) { + WaveletVdbVolumeFloat v( + getOpenVKLDevice(), vec3i(64), vec3f(0.f), vec3f(1.f)); + VKLVolume volume = v.getVKLVolume(getOpenVKLDevice()); + VKLSampler sampler = newSampler(volume, filter); + + // transform is part of the grid + const AffineSpace3f indexToObject = + AffineSpace3f::translate(vec3f(1.f, 2.f, 3.f)) * + AffineSpace3f::scale(vec3f(0.5f, 1.f, 2.f)); + vklSetParam(volume, "indexToObject", VKL_AFFINE3F, &indexToObject); + vklCommit(volume); + + requireSamplesOfFreshSampler(volume, sampler, filter); + + vklRelease(sampler); + } + } + + shutdownOpenVKL(); +} +#endif From 9e68d286df25b284ed231601b5a4c5e60de0cb31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 2 Oct 2026 13:23:42 +0200 Subject: [PATCH 2/5] Fix dense VDB sampling after volume recommit Move denseLeafSample_* from sampler to VDBVolume, thus samplers do not use stale handlers when the volume got recommited. This also prevents samplers to leak the handler arrays on their recommit. --- .../devices/cpu/volume/vdb/VdbSampler.ispc | 83 +++++++++++-------- .../devices/cpu/volume/vdb/VdbSamplerShared.h | 21 ----- .../vdb/VdbSampler_traverseAndSample.ih | 9 +- openvkl/devices/cpu/volume/vdb/VdbVolume.cpp | 3 + .../devices/cpu/volume/vdb/VdbVolumeShared.h | 22 +++++ testing/apps/tests/vdb_volume_recommit.cpp | 48 +++++++++++ 6 files changed, 127 insertions(+), 59 deletions(-) diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc index f8d27b45..5e0ac469 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc @@ -593,52 +593,63 @@ export void EXPORT_UNIQUE(VdbSampler_set, VdbSampler_iterator_computeSample_varying; sampler->maxSamplingDepth = maxSamplingDepth; +} + +export void EXPORT_UNIQUE(VdbSampler_destroy, void *uniform _sampler) {} + +// Dense sampling dispatch, owned by the volume (depends on grid only). +export void EXPORT_UNIQUE(VdbSampler_initDenseLeafSampling, + void *uniform _volume) +{ + VdbVolume *uniform volume = (VdbVolume * uniform) _volume; + const VdbGrid *uniform grid = &volume->grid; + if (!grid->dense) + return; - if (sampler->grid && sampler->grid->dense) { - // Redefine handler macros to allow us to use them for setting function - // pointers, rather than making function calls. + // Redefine handler macros to allow us to use them for setting function + // pointers, rather than making function calls. #undef __vkl_vdb_dense_handler_impl #define __vkl_vdb_dense_handler_impl(handler, postfix, ...) handler##_##postfix; - const uniform uint32 numAttributes = sampler->grid->numAttributes; - - sampler->denseLeafSample_varying = - uniform new DenseLeafSamplingVaryingFunc[numAttributes]; - sampler->denseLeafSample_uniform = - uniform new DenseLeafSamplingUniformFunc[numAttributes]; - - for (uniform uint32 i = 0; i < numAttributes; i++) { - const uniform vkl_uint32 voxelType = sampler->grid->attributeTypes[i]; - const uniform VKLTemporalFormat temporalFormat = - sampler->grid->denseTemporalFormat; - const uniform bool addressing32bit = - safe_32bit_indexing(sampler->grid->denseData[i]); - - __vkl_vdb_dense_handler( - sampler->denseLeafSample_uniform[i] = VdbSampler_sample_dense_uniform, - voxelType, - temporalFormat, - addressing32bit); - - __vkl_vdb_dense_handler( - sampler->denseLeafSample_varying[i] = VdbSampler_sample_dense_varying, - voxelType, - temporalFormat, - addressing32bit); - } -#undef __vkl_vdb_dense_handler_impl + const uniform uint32 numAttributes = grid->numAttributes; + + volume->denseLeafSample_varying = + uniform new DenseLeafSamplingVaryingFunc[numAttributes]; + volume->denseLeafSample_uniform = + uniform new DenseLeafSamplingUniformFunc[numAttributes]; + + for (uniform uint32 i = 0; i < numAttributes; i++) { + const uniform vkl_uint32 voxelType = grid->attributeTypes[i]; + const uniform VKLTemporalFormat temporalFormat = grid->denseTemporalFormat; + const uniform bool addressing32bit = safe_32bit_indexing(grid->denseData[i]); + + __vkl_vdb_dense_handler( + volume->denseLeafSample_uniform[i] = VdbSampler_sample_dense_uniform, + voxelType, + temporalFormat, + addressing32bit); + + __vkl_vdb_dense_handler( + volume->denseLeafSample_varying[i] = VdbSampler_sample_dense_varying, + voxelType, + temporalFormat, + addressing32bit); } +#undef __vkl_vdb_dense_handler_impl } -export void EXPORT_UNIQUE(VdbSampler_destroy, void *uniform _sampler) +export void EXPORT_UNIQUE(VdbSampler_cleanupDenseLeafSampling, + void *uniform _volume) { - VdbSamplerShared *uniform sampler = (VdbSamplerShared * uniform) _sampler; + VdbVolume *uniform volume = (VdbVolume * uniform) _volume; - if (sampler->denseLeafSample_varying) { - delete[] sampler->denseLeafSample_varying; + if (volume->denseLeafSample_varying) { + delete[] volume->denseLeafSample_varying; + volume->denseLeafSample_varying = NULL; } - if (sampler->denseLeafSample_uniform) { - delete[] sampler->denseLeafSample_uniform; + if (volume->denseLeafSample_uniform) { + delete[] volume->denseLeafSample_uniform; + volume->denseLeafSample_uniform = NULL; } } diff --git a/openvkl/devices/cpu/volume/vdb/VdbSamplerShared.h b/openvkl/devices/cpu/volume/vdb/VdbSamplerShared.h index 4b6ebbdf..b548bcf2 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSamplerShared.h +++ b/openvkl/devices/cpu/volume/vdb/VdbSamplerShared.h @@ -11,24 +11,6 @@ namespace ispc { #endif // __cplusplus -#ifdef __cplusplus - typedef void *DenseLeafSamplingVaryingFunc; - - typedef void *DenseLeafSamplingUniformFunc; -#else -typedef varying float (*uniform DenseLeafSamplingVaryingFunc)( - const VdbGrid *uniform grid, - uniform uint32 attributeIndex, - const varying vec3ui &offset, - const varying float &time); - -typedef uniform float (*uniform DenseLeafSamplingUniformFunc)( - const VdbGrid *uniform grid, - uniform uint32 attributeIndex, - const uniform vec3ui &offset, - uniform float time); -#endif - #ifndef __ISPC_STRUCT_VdbSamplerShared__ #define __ISPC_STRUCT_VdbSamplerShared__ @@ -39,9 +21,6 @@ typedef uniform float (*uniform DenseLeafSamplingUniformFunc)( const VdbGrid *VKL_INTEROP_UNIFORM grid; const void *VKL_INTEROP_UNIFORM leafAccessObservers; vkl_uint32 maxSamplingDepth; - - DenseLeafSamplingVaryingFunc *VKL_INTEROP_UNIFORM denseLeafSample_varying; - DenseLeafSamplingUniformFunc *VKL_INTEROP_UNIFORM denseLeafSample_uniform; }; #endif diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler_traverseAndSample.ih b/openvkl/devices/cpu/volume/vdb/VdbSampler_traverseAndSample.ih index 40e17988..b61c8440 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler_traverseAndSample.ih +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler_traverseAndSample.ih @@ -6,6 +6,7 @@ #include "VdbGrid.h" #include "VdbLeafAccessObserver.ih" #include "VdbSamplerShared.h" +#include "VdbVolumeShared.h" #include "VdbSampler_denseHandler.ih" #include "VdbSampler_leafHandler.ih" #include "VdbSampler_packedHandler.ih" @@ -323,7 +324,9 @@ inline uniform float VdbSampler_traverseAndSample_dense( const uniform vec3ui domainOffset = VdbSampler_toDomainOffset(ic, sampler->grid->rootOrigin); if (VdbSampler_isInDomain(sampler->grid->activeSize, domainOffset)) { - return sampler->denseLeafSample_uniform[attributeIndex]( + const VdbVolume *uniform volume = + (const VdbVolume *uniform)sampler->super.super.volume; + return volume->denseLeafSample_uniform[attributeIndex]( sampler->grid, attributeIndex, domainOffset, time); } return sampler->super.super.volume->background[attributeIndex]; @@ -342,7 +345,9 @@ inline float VdbSampler_traverseAndSample_dense( const vec3ui domainOffset = VdbSampler_toDomainOffset(ic, sampler->grid->rootOrigin); if (VdbSampler_isInDomain(sampler->grid->activeSize, domainOffset)) { - return sampler->denseLeafSample_varying[attributeIndex]( + const VdbVolume *uniform volume = + (const VdbVolume *uniform)sampler->super.super.volume; + return volume->denseLeafSample_varying[attributeIndex]( sampler->grid, attributeIndex, domainOffset, time); } return sampler->super.super.volume->background[attributeIndex]; diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp b/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp index a7745c46..0d4809d3 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.cpp @@ -52,6 +52,7 @@ namespace openvkl { allocator.deallocate(grid->leafData); allocator.deallocate(grid->nodesPackedDense); allocator.deallocate(grid->nodesPackedTile); + CALL_ISPC(VdbSampler_cleanupDenseLeafSampling, this->getSh()); std::memset(grid, 0, sizeof(VdbGrid)); grid = nullptr; } @@ -1038,6 +1039,8 @@ namespace openvkl { } } + CALL_ISPC(VdbSampler_initDenseLeafSampling, this->getSh()); + computeValueRanges( leafOffsets, *leafLevel, *leafFormat, this->getSh(), grid); diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h b/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h index 494e942c..e6e55393 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h +++ b/openvkl/devices/cpu/volume/vdb/VdbVolumeShared.h @@ -14,10 +14,32 @@ namespace ispc { const VdbGrid *VKL_INTEROP_UNIFORM grid, const VKL_INTEROP_VARYING vec3i &ic); +#ifdef __cplusplus + typedef void *DenseLeafSamplingVaryingFunc; + + typedef void *DenseLeafSamplingUniformFunc; +#else +typedef varying float (*uniform DenseLeafSamplingVaryingFunc)( + const VdbGrid *uniform grid, + uniform uint32 attributeIndex, + const varying vec3ui &offset, + const varying float &time); + +typedef uniform float (*uniform DenseLeafSamplingUniformFunc)( + const VdbGrid *uniform grid, + uniform uint32 attributeIndex, + const uniform vec3ui &offset, + uniform float time); +#endif + struct VdbVolume { VolumeShared super; VdbGrid grid; // embedded: samplers rely on a stable address + + // dense only, per attribute + DenseLeafSamplingVaryingFunc *VKL_INTEROP_UNIFORM denseLeafSample_varying; + DenseLeafSamplingUniformFunc *VKL_INTEROP_UNIFORM denseLeafSample_uniform; }; #ifdef __cplusplus diff --git a/testing/apps/tests/vdb_volume_recommit.cpp b/testing/apps/tests/vdb_volume_recommit.cpp index e34d8ec4..67c01a82 100644 --- a/testing/apps/tests/vdb_volume_recommit.cpp +++ b/testing/apps/tests/vdb_volume_recommit.cpp @@ -58,6 +58,20 @@ static void requireSamplesOfFreshSampler(VKLVolume volume, vklRelease(freshSampler); } +#if OPENVKL_DEVICE_CPU_STRUCTURED_REGULAR && !defined(OPENVKL_TESTING_GPU) +static VKLData newVoxelData(const TestingStructuredVolume &v) +{ + std::vector voxels; + std::vector time; + std::vector tuvIndex; + v.generateVoxels(voxels, time, tuvIndex); + return vklNewData(getOpenVKLDevice(), + v.getDimensions().long_product(), + v.getVoxelType(), + voxels.data()); +} +#endif + #if OPENVKL_DEVICE_CPU_VDB || defined(OPENVKL_TESTING_GPU) TEST_CASE("VDB volume recommit with existing sampler", "[volume_sampling]") { @@ -84,6 +98,40 @@ TEST_CASE("VDB volume recommit with existing sampler", "[volume_sampling]") } } +#if OPENVKL_DEVICE_CPU_STRUCTURED_REGULAR && !defined(OPENVKL_TESTING_GPU) + // structuredRegular is implemented as dense VDB on CPU + SECTION("dense") + { + for (VKLFilter filter : filters) { + WaveletStructuredRegularVolumeFloat v( + vec3i(8, 9, 10), vec3f(0.f), vec3f(1.f)); + VKLVolume volume = v.getVKLVolume(getOpenVKLDevice()); + VKLSampler sampler = newSampler(volume, filter); + + // other dimensions, voxel type and number of attributes + const vec3i dimensions(12, 10, 9); + const VKLData attributes[] = { + newVoxelData(WaveletStructuredRegularVolumeUChar( + dimensions, vec3f(0.f), vec3f(1.f))), + newVoxelData(XYZStructuredRegularVolumeFloat( + dimensions, vec3f(0.f), vec3f(1.f)))}; + VKLData data = vklNewData(getOpenVKLDevice(), 2, VKL_DATA, attributes); + vklSetVec3i( + volume, "dimensions", dimensions.x, dimensions.y, dimensions.z); + vklSetData(volume, "data", data); + vklRelease(data); + for (VKLData d : attributes) + vklRelease(d); + vklCommit(volume); + + requireSamplesOfFreshSampler(volume, sampler, filter, 0); + requireSamplesOfFreshSampler(volume, sampler, filter, 1); + + vklRelease(sampler); + } + } +#endif + shutdownOpenVKL(); } #endif From dd48e50f37a0ad5f8afc277cc26131761791528a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Fri, 2 Oct 2026 14:28:41 +0200 Subject: [PATCH 3/5] Fix cornercase in BVH node discrimination --- .../cpu/iterator/UnstructuredIterator.ispc | 2 +- openvkl/devices/cpu/volume/UnstructuredBVH.h | 9 ++-- openvkl/devices/cpu/volume/UnstructuredBVH.ih | 22 ++++++++++ .../devices/cpu/volume/UnstructuredVolume.cpp | 4 +- .../devices/cpu/volume/UnstructuredVolume.ih | 1 + .../cpu/volume/UnstructuredVolume.ispc | 6 +-- .../cpu/volume/particle/ParticleVolume.cpp | 2 +- .../devices/gpu/compute/vklComputeParticle.h | 3 +- .../gpu/compute/vklComputeUnstructured.h | 3 +- .../gpu/compute/vklIterateUnstructured.h | 3 +- .../tests/unstructured_volume_sampling.cpp | 43 +++++++++++++++++++ 11 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 openvkl/devices/cpu/volume/UnstructuredBVH.ih diff --git a/openvkl/devices/cpu/iterator/UnstructuredIterator.ispc b/openvkl/devices/cpu/iterator/UnstructuredIterator.ispc index 90c43f8a..b04f4a73 100644 --- a/openvkl/devices/cpu/iterator/UnstructuredIterator.ispc +++ b/openvkl/devices/cpu/iterator/UnstructuredIterator.ispc @@ -140,7 +140,7 @@ static box1f evalNodeStacklessV(const varying UnstructuredIterator *uniform iterator->super.super.context->super.sampler; while (1) { - uniform bool isInner = (node->nominalLength.x >= 0); + uniform bool isInner = !isLeafNode(node); if (isInner && (elementaryCellIteration || diff --git a/openvkl/devices/cpu/volume/UnstructuredBVH.h b/openvkl/devices/cpu/volume/UnstructuredBVH.h index 06fcdcc3..f2977853 100644 --- a/openvkl/devices/cpu/volume/UnstructuredBVH.h +++ b/openvkl/devices/cpu/volume/UnstructuredBVH.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include "../../common/BufferShared.h" @@ -150,7 +151,7 @@ namespace openvkl { struct Node { - vec3f nominalLength; // x set to negative for LeafNode; + vec3f nominalLength; // sign bit of x set => leaf (incl. -0) range1f valueRange; int level; Node *parent; @@ -276,14 +277,14 @@ namespace openvkl { inline bool isLeafNode(const Node *node) { - return (node->nominalLength.x < 0); + return (std::signbit)(node->nominalLength.x); } inline void addLevelToNodes(Node *root, int level) { root->level = level; - if (root->nominalLength.x > 0) { + if (!isLeafNode(root)) { auto inner = (InnerNode *)root; addLevelToNodes(inner->children[0], level + 1); @@ -293,7 +294,7 @@ namespace openvkl { inline int getMaxNodeLevel(Node *root) { - if (root->nominalLength.x > 0) { + if (!isLeafNode(root)) { auto inner = (InnerNode *)root; return std::max(getMaxNodeLevel(inner->children[0]), getMaxNodeLevel(inner->children[1])); diff --git a/openvkl/devices/cpu/volume/UnstructuredBVH.ih b/openvkl/devices/cpu/volume/UnstructuredBVH.ih new file mode 100644 index 00000000..cbfa5238 --- /dev/null +++ b/openvkl/devices/cpu/volume/UnstructuredBVH.ih @@ -0,0 +1,22 @@ +// Copyright 2026 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "rkcommon/math/math.ih" +#include "UnstructuredVolumeBaseShared.h" + +#ifndef ISPC +namespace ispc { +#endif + + // leaf iff sign bit of nominalLength.x set (incl. -0, missed by < 0) + inline VKL_INTEROP_UNIFORM bool isLeafNode( + const VKL_INTEROP_UNIFORM Node *VKL_INTEROP_UNIFORM node) + { + return (intbits(node->nominalLength.x) >> 31) != 0; + } + +#ifndef ISPC +} // namespace ispc +#endif diff --git a/openvkl/devices/cpu/volume/UnstructuredVolume.cpp b/openvkl/devices/cpu/volume/UnstructuredVolume.cpp index 47fd8446..7ad50c12 100644 --- a/openvkl/devices/cpu/volume/UnstructuredVolume.cpp +++ b/openvkl/devices/cpu/volume/UnstructuredVolume.cpp @@ -46,7 +46,7 @@ namespace openvkl { static void dumpBVH(Node *root, int indent = 0) { - if (root->nominalLength.x < 0) { + if (isLeafNode(root)) { auto leaf = (LeafNodeSingle *)root; tabIndent(indent); std::cerr << "id: " << leaf->cellID << " bounds: " << leaf->bounds @@ -381,7 +381,7 @@ namespace openvkl { throw std::runtime_error("bvh build failure"); } - if (rtcRoot->nominalLength.x < 0) { + if (isLeafNode(rtcRoot)) { auto &val = ((LeafNode *)rtcRoot)->bounds; bounds = box3f(val.lower, val.upper); } else { diff --git a/openvkl/devices/cpu/volume/UnstructuredVolume.ih b/openvkl/devices/cpu/volume/UnstructuredVolume.ih index 1bc1d749..f2cbc09e 100644 --- a/openvkl/devices/cpu/volume/UnstructuredVolume.ih +++ b/openvkl/devices/cpu/volume/UnstructuredVolume.ih @@ -4,6 +4,7 @@ #pragma once #include "../common/Data.ih" +#include "UnstructuredBVH.ih" #include "UnstructuredVolumeShared.h" inline uniform Node *uniform sibling(uniform Node *uniform node) diff --git a/openvkl/devices/cpu/volume/UnstructuredVolume.ispc b/openvkl/devices/cpu/volume/UnstructuredVolume.ispc index e06bc822..d9d3495b 100644 --- a/openvkl/devices/cpu/volume/UnstructuredVolume.ispc +++ b/openvkl/devices/cpu/volume/UnstructuredVolume.ispc @@ -31,7 +31,7 @@ inline bool pointInAABBTest(const uniform box3fa &box, const vec3f &point) uniform int stackPtr = 0; \ \ while (1) { \ - uniform bool isLeaf = (node->nominalLength.x < 0); \ + uniform bool isLeaf = isLeafNode(node); \ if (isLeaf) { \ uniform LeafNodeSingle *uniform leaf = \ (uniform LeafNodeSingle * uniform) node; \ @@ -80,7 +80,7 @@ inline bool pointInAABBTest(const uniform box3fa &box, const vec3f &point) uniform int stackPtr = 0; \ \ while (1) { \ - uniform bool isLeaf = (node->nominalLength.x < 0); \ + uniform bool isLeaf = isLeafNode(node); \ if (isLeaf) { \ uniform LeafNodeMulti *uniform leaf = \ (uniform LeafNodeMulti * uniform) node; \ @@ -145,7 +145,7 @@ inline void traverseBVH(uniform Node *uniform root, uniform uint32 bitstack = 0; while (1) { - uniform bool isInner = (node->nominalLength.x >= 0); + uniform bool isInner = !isLeafNode(node); if (isInner) { uniform InnerNode *uniform inner = (uniform InnerNode * uniform) node; diff --git a/openvkl/devices/cpu/volume/particle/ParticleVolume.cpp b/openvkl/devices/cpu/volume/particle/ParticleVolume.cpp index bb605014..76807a32 100644 --- a/openvkl/devices/cpu/volume/particle/ParticleVolume.cpp +++ b/openvkl/devices/cpu/volume/particle/ParticleVolume.cpp @@ -284,7 +284,7 @@ namespace openvkl { throw std::runtime_error("bvh build failure"); } - if (rtcRoot->nominalLength.x < 0) { + if (isLeafNode(rtcRoot)) { auto &val = ((ParticleLeafNode *)rtcRoot)->bounds; bounds = box3f(val.lower, val.upper); } else { diff --git a/openvkl/devices/gpu/compute/vklComputeParticle.h b/openvkl/devices/gpu/compute/vklComputeParticle.h index d94d33b6..81f181cc 100644 --- a/openvkl/devices/gpu/compute/vklComputeParticle.h +++ b/openvkl/devices/gpu/compute/vklComputeParticle.h @@ -3,6 +3,7 @@ #pragma once +#include "../../cpu/volume/UnstructuredBVH.ih" #include "../../cpu/volume/particle/ParticleVolumeShared.h" namespace ispc { @@ -89,7 +90,7 @@ namespace ispc { int stackPtr = 0; while (1) { - bool isLeaf = (node->nominalLength.x < 0); + bool isLeaf = isLeafNode(node); if (isLeaf) { LeafNodeMulti *leaf = (LeafNodeMulti *)node; if (pointInAABBTest(leaf->super.bounds, samplePos)) { diff --git a/openvkl/devices/gpu/compute/vklComputeUnstructured.h b/openvkl/devices/gpu/compute/vklComputeUnstructured.h index e6ef0467..4ddd39a9 100644 --- a/openvkl/devices/gpu/compute/vklComputeUnstructured.h +++ b/openvkl/devices/gpu/compute/vklComputeUnstructured.h @@ -3,6 +3,7 @@ #pragma once +#include "../../cpu/volume/UnstructuredBVH.ih" #include "../../cpu/volume/UnstructuredVolumeShared.h" namespace ispc { @@ -719,7 +720,7 @@ namespace ispc { Node *nodeStack[32]; int stackPtr = 0; while (1) { - bool isLeaf = (node->nominalLength.x < 0.0f); + bool isLeaf = isLeafNode(node); if (isLeaf) { LeafNodeSingle *leaf = (LeafNodeSingle *)node; if (pointInAABBTest(leaf->super.bounds, samplePos)) { diff --git a/openvkl/devices/gpu/compute/vklIterateUnstructured.h b/openvkl/devices/gpu/compute/vklIterateUnstructured.h index c129d5cc..de2f3e36 100644 --- a/openvkl/devices/gpu/compute/vklIterateUnstructured.h +++ b/openvkl/devices/gpu/compute/vklIterateUnstructured.h @@ -8,6 +8,7 @@ #include "../../cpu/iterator/IteratorContextShared.h" #include "../../cpu/iterator/IteratorShared.h" +#include "../../cpu/volume/UnstructuredBVH.ih" namespace ispc { @@ -401,7 +402,7 @@ namespace ispc { const SamplerShared *sampler = (const SamplerShared *)iterator->sampler; while (1) { - bool isInner = (node->nominalLength.x >= 0); + bool isInner = !isLeafNode(node); if (isInner && (elementaryCellIteration || diff --git a/testing/apps/tests/unstructured_volume_sampling.cpp b/testing/apps/tests/unstructured_volume_sampling.cpp index 079132c1..481415c5 100644 --- a/testing/apps/tests/unstructured_volume_sampling.cpp +++ b/testing/apps/tests/unstructured_volume_sampling.cpp @@ -194,4 +194,47 @@ TEST_CASE("Unstructured volume sampling", "[volume_sampling]") shutdownOpenVKL(); } + +// zero x-spacing: all cells flat, BVH leaves have nominalLength.x == -0 +static void zero_extent_cells(const vec3i &dimensions) +{ + XYZUnstructuredProceduralVolume v( + dimensions, vec3f(0.f), vec3f(0.f, 1.f, 1.f), VKL_TETRAHEDRON); + + VKLVolume vklVolume = v.getVKLVolume(getOpenVKLDevice()); + const vkl_box3f bbox = vklGetBoundingBox(vklVolume); + REQUIRE(bbox.lower.x == 0.f); + REQUIRE(bbox.upper.x == 0.f); + + VKLSampler vklSampler = vklNewSampler(vklVolume); + vklCommit(vklSampler); + + // flat cells are never inside + multidim_index_sequence<2> mis(vec2i(dimensions.y, dimensions.z) * 2); + for (const auto &yz : mis) { + const vec3f oc(0.f, 0.25f + 0.5f * yz.x, 0.25f + 0.5f * yz.y); + INFO("objectCoordinates = " << oc.x << " " << oc.y << " " << oc.z); + REQUIRE(std::isnan( + vklComputeSampleWrapper(&vklSampler, (const vkl_vec3f *)&oc, 0, 0.f))); + } + + vklRelease(vklSampler); +} + +TEST_CASE("Unstructured volume zero-extent cells", "[volume_sampling]") +{ + initializeOpenVKL(); + + SECTION("BVH root is leaf") + { + zero_extent_cells(vec3i(1)); + } + + SECTION("BVH with inner nodes") + { + zero_extent_cells(vec3i(1, 4, 4)); + } + + shutdownOpenVKL(); +} #endif From db29d668b6ee97d261160bb0c481785fac4d830b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Tue, 29 Sep 2026 14:08:01 +0200 Subject: [PATCH 4/5] Improvements and cleanups to non-clobber install of packages --- superbuild/CMakeLists.txt | 5 +++++ superbuild/dependencies/dep_embree.cmake | 14 +++++++------- superbuild/dependencies/dep_rkcommon.cmake | 7 ++++--- superbuild/dependencies/package_install.cmake | 12 +++--------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/superbuild/CMakeLists.txt b/superbuild/CMakeLists.txt index 0bc217fc..3d3d03cd 100644 --- a/superbuild/CMakeLists.txt +++ b/superbuild/CMakeLists.txt @@ -36,7 +36,12 @@ if (POLICY CMP0135) cmake_policy(SET CMP0135 NEW) # 3.24 endif () +if (POLICY CMP0114) + cmake_policy(SET CMP0114 NEW) # 3.19 +endif () + include(ExternalProject) +set_property(DIRECTORY PROPERTY EP_STEP_TARGETS download) # parallel downloads include(GNUInstallDirs) include(ProcessorCount) diff --git a/superbuild/dependencies/dep_embree.cmake b/superbuild/dependencies/dep_embree.cmake index 23f21315..62200053 100644 --- a/superbuild/dependencies/dep_embree.cmake +++ b/superbuild/dependencies/dep_embree.cmake @@ -68,17 +68,17 @@ else() INSTALL_COMMAND "${CMAKE_COMMAND}" -DSRC= -DDST=${COMPONENT_PATH} - -DMANIFEST=/install_manifest.txt + -DMANIFEST=/package_manifest.txt -P ${CMAKE_CURRENT_LIST_DIR}/package_install.cmake BUILD_ALWAYS OFF ) - # the package bundles TBB, install after ours to keep it - ExternalProject_Add_StepDependencies(${COMPONENT_NAME} - install - $<$:tbb> - ) - + if (NOT INSTALL_IN_SEPARATE_DIRECTORIES) # bundled deps must not win + ExternalProject_Add_StepDependencies(${COMPONENT_NAME} + install + $<$:tbb> + ) + endif() endif() add_to_prefix_path(${COMPONENT_PATH}) diff --git a/superbuild/dependencies/dep_rkcommon.cmake b/superbuild/dependencies/dep_rkcommon.cmake index 347a8d94..0a02d585 100644 --- a/superbuild/dependencies/dep_rkcommon.cmake +++ b/superbuild/dependencies/dep_rkcommon.cmake @@ -42,9 +42,10 @@ ExternalProject_Add(${COMPONENT_NAME} BUILD_ALWAYS ${ALWAYS_REBUILD} ) -if (BUILD_TBB) - ExternalProject_Add_StepDependencies(${COMPONENT_NAME} configure tbb) -endif() +ExternalProject_Add_StepDependencies(${COMPONENT_NAME} +configure + $<$:tbb> +) add_to_prefix_path(${COMPONENT_PATH}) diff --git a/superbuild/dependencies/package_install.cmake b/superbuild/dependencies/package_install.cmake index ae23ce46..0228d9c5 100644 --- a/superbuild/dependencies/package_install.cmake +++ b/superbuild/dependencies/package_install.cmake @@ -3,19 +3,13 @@ # Installs an unpacked pre-built package into DST, keeping files another # component installed there already: the packages bundle their dependencies, -# which the superbuild builds first, thus first writer wins. Files of the -# previous install are removed, thus version bumps still replace them. +# which the superbuild installs first, thus first writer wins. Files of the +# previous install (MANIFEST) are removed first, so version bumps replace them. # # cmake -DSRC= -DDST= -DMANIFEST= -P cmake_minimum_required(VERSION 3.10) -foreach (ARG SRC DST MANIFEST) - if (NOT ${ARG}) - message(FATAL_ERROR "package_install.cmake: ${ARG} not set") - endif() -endforeach() - if (EXISTS "${MANIFEST}") file(STRINGS "${MANIFEST}" PREVIOUS) foreach (FILE IN LISTS PREVIOUS) @@ -26,7 +20,7 @@ endif() file(GLOB_RECURSE FILES RELATIVE "${SRC}" "${SRC}/*") set(INSTALLED "") foreach (FILE IN LISTS FILES) - if (NOT EXISTS "${DST}/${FILE}") + if (NOT EXISTS "${DST}/${FILE}" AND NOT IS_SYMLINK "${DST}/${FILE}") get_filename_component(DIR "${FILE}" DIRECTORY) file(COPY "${SRC}/${FILE}" DESTINATION "${DST}/${DIR}") list(APPEND INSTALLED "${FILE}") From 8f82dbe9d19908095adb81bebaef6648018a180e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20G=C3=BCnther?= Date: Mon, 5 Oct 2026 10:59:53 +0200 Subject: [PATCH 5/5] Cleanup dead/empty ISPC *_destroy functions Leftovers from SharedStruct refactor 5eeefe84 --- openvkl/devices/cpu/sampler/Sampler.ih | 2 -- openvkl/devices/cpu/sampler/Sampler.ispc | 7 ------- openvkl/devices/cpu/volume/amr/AMRSampler.h | 7 ------- openvkl/devices/cpu/volume/amr/AMRVolume.ispc | 2 -- openvkl/devices/cpu/volume/vdb/VdbSampler.cpp | 6 ------ openvkl/devices/cpu/volume/vdb/VdbSampler.h | 1 - openvkl/devices/cpu/volume/vdb/VdbSampler.ispc | 2 -- openvkl/devices/cpu/volume/vdb/VdbVolume.h | 1 - openvkl/devices/cpu/volume/vdb/VdbVolume.ispc | 5 ----- 9 files changed, 33 deletions(-) diff --git a/openvkl/devices/cpu/sampler/Sampler.ih b/openvkl/devices/cpu/sampler/Sampler.ih index 4a502f4e..2a689d97 100644 --- a/openvkl/devices/cpu/sampler/Sampler.ih +++ b/openvkl/devices/cpu/sampler/Sampler.ih @@ -18,8 +18,6 @@ export void EXPORT_UNIQUE(Sampler_create, const void *uniform _volume, void *uniform _sampler); -export void EXPORT_UNIQUE(Sampler_destroy, void *uniform _sampler); - export void EXPORT_UNIQUE(Sampler_setFilters, void *uniform _sampler, uniform VKLFilter filter, diff --git a/openvkl/devices/cpu/sampler/Sampler.ispc b/openvkl/devices/cpu/sampler/Sampler.ispc index 16d5a496..35036c21 100644 --- a/openvkl/devices/cpu/sampler/Sampler.ispc +++ b/openvkl/devices/cpu/sampler/Sampler.ispc @@ -24,13 +24,6 @@ export void EXPORT_UNIQUE(Sampler_setFilters, Sampler_setFiltersInternal(sampler, filter, gradientFilter); } -export void EXPORT_UNIQUE(Sampler_destroy, - void *uniform _sampler) -{ - SamplerShared *uniform sampler = (SamplerShared *uniform)_sampler; - delete sampler; -} - // these functions do not yet support multi-attribute or time-varying volumes. export void EXPORT_UNIQUE(Sampler_sample_N_export, diff --git a/openvkl/devices/cpu/volume/amr/AMRSampler.h b/openvkl/devices/cpu/volume/amr/AMRSampler.h index 38f73d07..8d8f873a 100644 --- a/openvkl/devices/cpu/volume/amr/AMRSampler.h +++ b/openvkl/devices/cpu/volume/amr/AMRSampler.h @@ -29,7 +29,6 @@ namespace openvkl { ispc::UnstructuredSamplerShared> { AMRSampler(Device *, AMRVolume &volume); - ~AMRSampler() override; void commit() override; @@ -73,12 +72,6 @@ namespace openvkl { CALL_ISPC(AMRSampler_create, volume.getSh(), this->getSh()); } - template - inline AMRSampler::~AMRSampler() - { - CALL_ISPC(AMRSampler_destroy, this->getSh()); - } - template inline void AMRSampler::commit() { diff --git a/openvkl/devices/cpu/volume/amr/AMRVolume.ispc b/openvkl/devices/cpu/volume/amr/AMRVolume.ispc index 2066cab5..83ad2218 100644 --- a/openvkl/devices/cpu/volume/amr/AMRVolume.ispc +++ b/openvkl/devices/cpu/volume/amr/AMRVolume.ispc @@ -201,5 +201,3 @@ export void EXPORT_UNIQUE(AMRSampler_create, sampler->computeGradient_varying = AMRVolume_computeGradient; } - -export void EXPORT_UNIQUE(AMRSampler_destroy, void *uniform _sampler) {} diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler.cpp b/openvkl/devices/cpu/volume/vdb/VdbSampler.cpp index bcbd2b0b..b991d601 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler.cpp +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler.cpp @@ -28,12 +28,6 @@ namespace openvkl { this->getSh()); } - template - VdbSampler::~VdbSampler() - { - CALL_ISPC(VdbSampler_destroy, this->getSh()); - } - template void VdbSampler::commit() { diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler.h b/openvkl/devices/cpu/volume/vdb/VdbSampler.h index 4f91e131..2b9b20ac 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler.h +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler.h @@ -27,7 +27,6 @@ namespace openvkl { : public AddStructShared, ispc::VdbSamplerShared> { explicit VdbSampler(Device *, VdbVolume &volume); - ~VdbSampler() override; void commit() override; diff --git a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc index 5e0ac469..1c1ce318 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc +++ b/openvkl/devices/cpu/volume/vdb/VdbSampler.ispc @@ -595,8 +595,6 @@ export void EXPORT_UNIQUE(VdbSampler_set, sampler->maxSamplingDepth = maxSamplingDepth; } -export void EXPORT_UNIQUE(VdbSampler_destroy, void *uniform _sampler) {} - // Dense sampling dispatch, owned by the volume (depends on grid only). export void EXPORT_UNIQUE(VdbSampler_initDenseLeafSampling, void *uniform _volume) diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.h b/openvkl/devices/cpu/volume/vdb/VdbVolume.h index 0211bdd6..194b7c80 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.h +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.h @@ -237,7 +237,6 @@ namespace openvkl { VdbVolume::~VdbVolume() { cleanup(); - CALL_ISPC(VdbVolume_destroy, this->getSh()); this->SharedStructInitialized = false; } diff --git a/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc b/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc index 550b407b..763bd92c 100644 --- a/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc +++ b/openvkl/devices/cpu/volume/vdb/VdbVolume.ispc @@ -26,8 +26,3 @@ export void EXPORT_UNIQUE(VdbVolume_Constructor, void *uniform _self) uniform VdbVolume *uniform self = (uniform VdbVolume * uniform) _self; memset(self, 0, sizeof(uniform VdbVolume)); } - -/* - * Destructor for ISPC versions of the volume. - */ -export void EXPORT_UNIQUE(VdbVolume_destroy, void *uniform _self) {}