1 // Copyright 2019-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3
4 // ========================================================================== //
5 // This is a shared ISPC and C++ header, which contains the internal data
6 // types used to represent VDB trees.
7 // ========================================================================== //
8
9 #pragma once
10
11 #include "VKLDataType.h"
12 #include "VKLFilter.h"
13 #include "ispc_cpp_interop.h"
14
15 // ========================================================================== //
16 // Tree topology information. The file vdb_topology.h is generated
17 // from vdb_topology.h.in, and defines both VKL_VDB_NUM_LEVELS and, for
18 // each <level> in {0, VKL_VDB_NUM_LEVELS-1}:
19 // VKL_VDB_LOG_RES_<level>: The base two logarithm of the storage
20 // resolution of nodes on this level.
21 // VKL_VDB_STORAGE_RES_<level>: The storage resolution of nodes on this
22 // level.
23 // VKL_VDB_NUM_VOXELS_<level>: The number of voxels stored in a node on
24 // this level.
25 // VKL_VDB_TOTAL_LOG_RES_<level>: The base two logarithm of the domain
26 // resolution on this level.
27 // VKL_VDB_RES_<level>: The domain resolution on this level.
28 //
29 // This file also defines macros
30 //
31 // __vkl_vdb_iterate_levels_<level>(macro) (see __vkl_vdb_iterate_levels below)
32 // __vkl_vdb_map_offset_to_voxel_<level>(univary, offset)
33 // __vkl_vdb_3d_to_linear_<level>(offx, offy, offz)
34 // __vkl_vdb_map_offset_to_lindex_<level>(offset_3d)
35 // ========================================================================== //
36 //
37 #include "openvkl/vdb/topology.h" // This file is generated by cmake.
38
39 // ========================================================================== //
40 // The following are runtime versions of the constants described above,
41 // to be used when the level is not known at runtime.
42 // ========================================================================== //
43
vklVdbNumLevels()44 inline VKL_INTEROP_CONSTEXPR VKL_INTEROP_UNIFORM vkl_uint32 vklVdbNumLevels()
45 {
46 return VKL_VDB_NUM_LEVELS;
47 }
48
49 #define __vkl_vdb_switch_case(Level, Prefix) \
50 case Level: \
51 return Prefix##Level;
52
53 #define __vkl_vdb_define_topology_functions(univary) \
54 inline univary vkl_uint32 vklVdbLevelLogRes(univary vkl_uint32 level) \
55 { \
56 switch (level) { \
57 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case, \
58 VKL_VDB_LOG_RES_) default : return 0; \
59 } \
60 } \
61 inline univary vkl_uint32 vklVdbLevelResShift(univary vkl_uint32 level) \
62 { \
63 return vklVdbLevelLogRes(level); \
64 } \
65 inline univary vkl_uint32 vklVdbLevelTotalLogRes(univary vkl_uint32 level) \
66 { \
67 switch (level) { \
68 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case, \
69 VKL_VDB_TOTAL_LOG_RES_) default : return 0; \
70 } \
71 } \
72 inline univary vkl_uint32 vklVdbLevelStorageRes(univary vkl_uint32 level) \
73 { \
74 switch (level) { \
75 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case, \
76 VKL_VDB_STORAGE_RES_) default : return 0; \
77 } \
78 } \
79 inline univary vkl_uint32 vklVdbLevelRes(univary vkl_uint32 level) \
80 { \
81 switch (level) { \
82 __vkl_vdb_iterate_levels_0( \
83 __vkl_vdb_switch_case, \
84 VKL_VDB_RES_) /* Special case: we use this to determine cell \
85 resolution. */ \
86 case VKL_VDB_NUM_LEVELS : return 1; \
87 default: \
88 return 0; \
89 } \
90 } \
91 inline univary vkl_uint32 vklVdbLevelNumVoxels(univary vkl_uint32 level) \
92 { \
93 switch (level) { \
94 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case, \
95 VKL_VDB_NUM_VOXELS_) default : return 0; \
96 } \
97 }
98
__vkl_interop_univary(__vkl_vdb_define_topology_functions)99 __vkl_interop_univary(__vkl_vdb_define_topology_functions)
100 #undef __vkl_vdb_define_topology_functions
101 #undef __vkl_vdb_switch_case
102
103 // ========================================================================== //
104 // Functions that help with index computations.
105 // ========================================================================== //
106
107 #define __vkl_vdb_switch_case(Level, Macro, ...) \
108 __vkl_vdb_expand(case Level : return Macro##_##Level(__VA_ARGS__));
109
110 /*
111 * Map a 1D domain offset w.r.t. the root node to an offset inside the
112 * surrounding voxel on the given level.
113 */
114 inline VKL_INTEROP_UNIFORM vkl_uint64
115 vklVdbDomainOffsetToVoxel(VKL_INTEROP_UNIFORM vkl_uint32 level,
116 VKL_INTEROP_UNIFORM vkl_uint32 offset)
117 {
118 switch (level) {
119 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
120 __vkl_vdb_domain_offset_to_voxel_uniform,
121 offset) default : return 0;
122 }
123 }
124
125 /*
126 * Map a 3D offset to a linear index. Note that vdb volume store
127 * data in z-major order!
128 */
129 inline VKL_INTEROP_UNIFORM vkl_uint64
vklVdb3DToLinear(VKL_INTEROP_UNIFORM vkl_uint32 level,VKL_INTEROP_UNIFORM vkl_uint64 offsetX,VKL_INTEROP_UNIFORM vkl_uint64 offsetY,VKL_INTEROP_UNIFORM vkl_uint64 offsetZ)130 vklVdb3DToLinear(VKL_INTEROP_UNIFORM vkl_uint32 level,
131 VKL_INTEROP_UNIFORM vkl_uint64 offsetX,
132 VKL_INTEROP_UNIFORM vkl_uint64 offsetY,
133 VKL_INTEROP_UNIFORM vkl_uint64 offsetZ)
134 {
135 switch (level) {
136 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
137 __vkl_vdb_3d_to_linear_uniform,
138 offsetX,
139 offsetY,
140 offsetZ) default : return 0;
141 }
142 }
143
144 /*
145 * Map a 3D domain offset w.r.t. to the root node to a linear voxel index
146 * inside the surrounding voxel on the given level.
147 */
148 inline VKL_INTEROP_UNIFORM vkl_uint64
vklVdbDomainOffsetToLinear(VKL_INTEROP_UNIFORM vkl_uint32 level,VKL_INTEROP_UNIFORM vkl_uint64 offsetX,VKL_INTEROP_UNIFORM vkl_uint64 offsetY,VKL_INTEROP_UNIFORM vkl_uint64 offsetZ)149 vklVdbDomainOffsetToLinear(VKL_INTEROP_UNIFORM vkl_uint32 level,
150 VKL_INTEROP_UNIFORM vkl_uint64 offsetX,
151 VKL_INTEROP_UNIFORM vkl_uint64 offsetY,
152 VKL_INTEROP_UNIFORM vkl_uint64 offsetZ)
153 {
154 switch (level) {
155 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
156 __vkl_vdb_domain_offset_to_linear_uniform,
157 offsetX,
158 offsetY,
159 offsetZ) default : return 0;
160 }
161 }
162
163 #if defined(ISPC)
164
165 // Varying versions of the above. We do not use __vkl_interop_univary here
166 // because there is no standard way to handle empty __VA_ARGS__, which happen
167 // in C++ when univary expands to nothing.
168 // This also conveniently leads to better error messages.
169
170 /*
171 * Map a 1D domain offset w.r.t. the root node to an offset inside the
172 * surrounding voxel on the given level.
173 */
vklVdbDomainOffsetToVoxel(varying vkl_uint32 level,varying vkl_uint32 offset)174 inline varying vkl_uint64 vklVdbDomainOffsetToVoxel(varying vkl_uint32 level,
175 varying vkl_uint32 offset)
176 {
177 switch (level) {
178 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
179 __vkl_vdb_domain_offset_to_voxel_varying,
180 offset) default : return 0;
181 }
182 }
183
184 /*
185 * Map a 3D offset to a linear index. Note that vdb volume store
186 * data in z-major order!
187 */
vklVdb3DToLinear(varying vkl_uint32 level,varying vkl_uint64 offsetX,varying vkl_uint64 offsetY,varying vkl_uint64 offsetZ)188 inline varying vkl_uint64 vklVdb3DToLinear(varying vkl_uint32 level,
189 varying vkl_uint64 offsetX,
190 varying vkl_uint64 offsetY,
191 varying vkl_uint64 offsetZ)
192 {
193 switch (level) {
194 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
195 __vkl_vdb_3d_to_linear_varying,
196 offsetX,
197 offsetY,
198 offsetZ) default : return 0;
199 }
200 }
201
202 /*
203 * Map a 3D domain offset w.r.t. to the root node to a linear voxel index
204 * inside the surrounding voxel on the given level.
205 */
vklVdbDomainOffsetToLinear(varying vkl_uint32 level,varying vkl_uint64 offsetX,varying vkl_uint64 offsetY,varying vkl_uint64 offsetZ)206 inline varying vkl_uint64 vklVdbDomainOffsetToLinear(varying vkl_uint32 level,
207 varying vkl_uint64 offsetX,
208 varying vkl_uint64 offsetY,
209 varying vkl_uint64 offsetZ)
210 {
211 switch (level) {
212 __vkl_vdb_iterate_levels_0(__vkl_vdb_switch_case,
213 __vkl_vdb_domain_offset_to_linear_varying,
214 offsetX,
215 offsetY,
216 offsetZ) default : return 0;
217 }
218 }
219
220 #endif
221
222 #undef __vkl_vdb_switch_case
223