1 // Copyright 2020-2021 Intel Corporation 2 // SPDX-License-Identifier: Apache-2.0 3 4 #pragma once 5 6 #include "../common/export_util.h" 7 #include "../iterator/DefaultIterator.h" 8 #include "../iterator/GridAcceleratorIterator.h" 9 #include "../sampler/Sampler.h" 10 #include "Sampler_ispc.h" 11 #include "SharedStructuredVolume_ispc.h" 12 #include "StructuredRegularVolume.h" 13 #include "StructuredSphericalVolume.h" 14 #include "StructuredVolume.h" 15 #include "Volume_ispc.h" 16 #include "openvkl/VKLFilter.h" 17 18 namespace openvkl { 19 namespace cpu_device { 20 21 template <int W, 22 template <int> 23 class IntervalIteratorFactory, 24 template <int> 25 class HitIteratorFactory> 26 struct StructuredSampler : public SamplerBase<W, 27 StructuredVolume, 28 IntervalIteratorFactory, 29 HitIteratorFactory> 30 { 31 StructuredSampler(StructuredVolume<W> *volume); 32 ~StructuredSampler() override; 33 34 void commit() override; 35 36 // single attribute ///////////////////////////////////////////////////// 37 38 void computeSample(const vvec3fn<1> &objectCoordinates, 39 vfloatn<1> &samples, 40 unsigned int attributeIndex, 41 const vfloatn<1> &time) const override final; 42 43 void computeSampleV(const vintn<W> &valid, 44 const vvec3fn<W> &objectCoordinates, 45 vfloatn<W> &samples, 46 unsigned int attributeIndex, 47 const vfloatn<W> &time) const override final; 48 49 void computeSampleN(unsigned int N, 50 const vvec3fn<1> *objectCoordinates, 51 float *samples, 52 unsigned int attributeIndex, 53 const float *times) const override final; 54 55 void computeGradientV(const vintn<W> &valid, 56 const vvec3fn<W> &objectCoordinates, 57 vvec3fn<W> &gradients, 58 unsigned int attributeIndex, 59 const vfloatn<W> &time) const override final; 60 61 void computeGradientN(unsigned int N, 62 const vvec3fn<1> *objectCoordinates, 63 vvec3fn<1> *gradients, 64 unsigned int attributeIndex, 65 const float *times) const override final; 66 67 // multi-attribute ////////////////////////////////////////////////////// 68 69 void computeSampleM(const vvec3fn<1> &objectCoordinates, 70 float *samples, 71 unsigned int M, 72 const unsigned int *attributeIndices, 73 const vfloatn<1> &time) const override final; 74 75 void computeSampleMV(const vintn<W> &valid, 76 const vvec3fn<W> &objectCoordinates, 77 float *samples, 78 unsigned int M, 79 const unsigned int *attributeIndices, 80 const vfloatn<W> &time) const override final; 81 82 void computeSampleMN(unsigned int N, 83 const vvec3fn<1> *objectCoordinates, 84 float *samples, 85 unsigned int M, 86 const unsigned int *attributeIndices, 87 const float *times) const override final; 88 89 ///////////////////////////////////////////////////////////////////////// 90 91 protected: 92 using Sampler<W>::ispcEquivalent; 93 using SamplerBase<W, 94 StructuredVolume, 95 IntervalIteratorFactory, 96 HitIteratorFactory>::volume; 97 98 VKLFilter filter; 99 VKLFilter gradientFilter; 100 }; 101 102 // Inlined definitions //////////////////////////////////////////////////// 103 104 template <int W, 105 template <int> 106 class IntervalIteratorFactory, 107 template <int> 108 class HitIteratorFactory> 109 inline StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: StructuredSampler(StructuredVolume<W> * volume)110 StructuredSampler(StructuredVolume<W> *volume) 111 : SamplerBase<W, 112 StructuredVolume, 113 IntervalIteratorFactory, 114 HitIteratorFactory>(*volume), 115 filter(volume->getFilter()), 116 gradientFilter(volume->getGradientFilter()) 117 { 118 assert(volume); 119 ispcEquivalent = 120 CALL_ISPC(StructuredSampler_create, volume->getISPCEquivalent()); 121 } 122 123 template <int W, 124 template <int> 125 class IntervalIteratorFactory, 126 template <int> 127 class HitIteratorFactory> 128 inline StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: ~StructuredSampler()129 ~StructuredSampler() 130 { 131 CALL_ISPC(StructuredSampler_destroy, ispcEquivalent); 132 ispcEquivalent = nullptr; 133 } 134 135 template <int W, 136 template <int> 137 class IntervalIteratorFactory, 138 template <int> 139 class HitIteratorFactory> 140 inline void commit()141 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::commit() 142 { 143 filter = (VKLFilter)this->template getParam<int>("filter", filter); 144 145 // Note: We fall back to the sampler object filter parameter if it is set. 146 // This enables users to specify *only* the field filter override. 147 // This does mean that users must set the gradientFilter explicitly 148 // if they set filter and want gradientFilter to be different. 149 gradientFilter = (VKLFilter)this->template getParam<int>( 150 "gradientFilter", this->hasParam("filter") ? filter : gradientFilter); 151 152 CALL_ISPC(Sampler_setFilters, 153 ispcEquivalent, 154 (ispc::VKLFilter)filter, 155 (ispc::VKLFilter)gradientFilter); 156 } 157 158 template <int W, 159 template <int> 160 class IntervalIteratorFactory, 161 template <int> 162 class HitIteratorFactory> 163 inline void 164 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSample(const vvec3fn<1> & objectCoordinates,vfloatn<1> & samples,unsigned int attributeIndex,const vfloatn<1> & time)165 computeSample(const vvec3fn<1> &objectCoordinates, 166 vfloatn<1> &samples, 167 unsigned int attributeIndex, 168 const vfloatn<1> &time) const 169 { 170 assert(attributeIndex < volume->getNumAttributes()); 171 assertValidTime(time[0]); 172 CALL_ISPC(SharedStructuredVolume_sample_uniform_export, 173 ispcEquivalent, 174 &objectCoordinates, 175 attributeIndex, 176 &time, 177 &samples); 178 } 179 180 template <int W, 181 template <int> 182 class IntervalIteratorFactory, 183 template <int> 184 class HitIteratorFactory> 185 inline void 186 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSampleV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,vfloatn<W> & samples,unsigned int attributeIndex,const vfloatn<W> & time)187 computeSampleV(const vintn<W> &valid, 188 const vvec3fn<W> &objectCoordinates, 189 vfloatn<W> &samples, 190 unsigned int attributeIndex, 191 const vfloatn<W> &time) const 192 { 193 assert(attributeIndex < volume->getNumAttributes()); 194 assertValidTimes(valid, time); 195 CALL_ISPC(SharedStructuredVolume_sample_export, 196 static_cast<const int *>(valid), 197 ispcEquivalent, 198 &objectCoordinates, 199 attributeIndex, 200 &time, 201 &samples); 202 } 203 204 template <int W, 205 template <int> 206 class IntervalIteratorFactory, 207 template <int> 208 class HitIteratorFactory> 209 inline void 210 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSampleN(unsigned int N,const vvec3fn<1> * objectCoordinates,float * samples,unsigned int attributeIndex,const float * times)211 computeSampleN(unsigned int N, 212 const vvec3fn<1> *objectCoordinates, 213 float *samples, 214 unsigned int attributeIndex, 215 const float *times) const 216 { 217 assert(attributeIndex < volume->getNumAttributes()); 218 assertAllValidTimes(N, times); 219 CALL_ISPC(SharedStructuredVolume_sample_N_export, 220 ispcEquivalent, 221 N, 222 (ispc::vec3f *)objectCoordinates, 223 attributeIndex, 224 times, 225 samples); 226 } 227 228 template <int W, 229 template <int> 230 class IntervalIteratorFactory, 231 template <int> 232 class HitIteratorFactory> 233 inline void 234 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeGradientV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,vvec3fn<W> & gradients,unsigned int attributeIndex,const vfloatn<W> & time)235 computeGradientV(const vintn<W> &valid, 236 const vvec3fn<W> &objectCoordinates, 237 vvec3fn<W> &gradients, 238 unsigned int attributeIndex, 239 const vfloatn<W> &time) const 240 { 241 assert(attributeIndex < volume->getNumAttributes()); 242 assertValidTimes(valid, time); 243 CALL_ISPC(SharedStructuredVolume_gradient_export, 244 static_cast<const int *>(valid), 245 ispcEquivalent, 246 &objectCoordinates, 247 attributeIndex, 248 time, 249 &gradients); 250 } 251 252 template <int W, 253 template <int> 254 class IntervalIteratorFactory, 255 template <int> 256 class HitIteratorFactory> 257 inline void 258 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeGradientN(unsigned int N,const vvec3fn<1> * objectCoordinates,vvec3fn<1> * gradients,unsigned int attributeIndex,const float * times)259 computeGradientN(unsigned int N, 260 const vvec3fn<1> *objectCoordinates, 261 vvec3fn<1> *gradients, 262 unsigned int attributeIndex, 263 const float *times) const 264 { 265 assert(attributeIndex < volume->getNumAttributes()); 266 assertAllValidTimes(N, times); 267 CALL_ISPC(SharedStructuredVolume_gradient_N_export, 268 ispcEquivalent, 269 N, 270 (ispc::vec3f *)objectCoordinates, 271 attributeIndex, 272 times, 273 (ispc::vec3f *)gradients); 274 } 275 276 template <int W, 277 template <int> 278 class IntervalIteratorFactory, 279 template <int> 280 class HitIteratorFactory> 281 inline void 282 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSampleM(const vvec3fn<1> & objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const vfloatn<1> & time)283 computeSampleM(const vvec3fn<1> &objectCoordinates, 284 float *samples, 285 unsigned int M, 286 const unsigned int *attributeIndices, 287 const vfloatn<1> &time) const 288 { 289 assertValidAttributeIndices(volume, M, attributeIndices); 290 assertValidTime(time[0]); 291 CALL_ISPC(SharedStructuredVolume_sampleM_uniform_export, 292 ispcEquivalent, 293 &objectCoordinates, 294 M, 295 attributeIndices, 296 &time, 297 samples); 298 } 299 300 template <int W, 301 template <int> 302 class IntervalIteratorFactory, 303 template <int> 304 class HitIteratorFactory> 305 inline void 306 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSampleMV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const vfloatn<W> & time)307 computeSampleMV(const vintn<W> &valid, 308 const vvec3fn<W> &objectCoordinates, 309 float *samples, 310 unsigned int M, 311 const unsigned int *attributeIndices, 312 const vfloatn<W> &time) const 313 { 314 assertValidAttributeIndices(volume, M, attributeIndices); 315 assertValidTimes(valid, time); 316 CALL_ISPC(SharedStructuredVolume_sampleM_export, 317 static_cast<const int *>(valid), 318 ispcEquivalent, 319 &objectCoordinates, 320 M, 321 attributeIndices, 322 &time, 323 samples); 324 } 325 326 template <int W, 327 template <int> 328 class IntervalIteratorFactory, 329 template <int> 330 class HitIteratorFactory> 331 inline void 332 StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>:: computeSampleMN(unsigned int N,const vvec3fn<1> * objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const float * times)333 computeSampleMN(unsigned int N, 334 const vvec3fn<1> *objectCoordinates, 335 float *samples, 336 unsigned int M, 337 const unsigned int *attributeIndices, 338 const float *times) const 339 { 340 assertValidAttributeIndices(volume, M, attributeIndices); 341 assertAllValidTimes(N, times); 342 CALL_ISPC(SharedStructuredVolume_sampleM_N_export, 343 ispcEquivalent, 344 N, 345 (ispc::vec3f *)objectCoordinates, 346 M, 347 attributeIndices, 348 times, 349 samples); 350 } 351 352 template <int W> 353 using StructuredRegularSampler = 354 StructuredSampler<W, 355 GridAcceleratorIntervalIteratorFactory, 356 GridAcceleratorHitIteratorFactory>; 357 358 template <int W> 359 using StructuredSphericalIntervalIteratorFactory = 360 ConcreteIteratorFactory<W, 361 IntervalIterator, 362 DefaultIntervalIterator, 363 IntervalIteratorContext, 364 IntervalIteratorContext>; 365 366 template <int W> 367 using StructuredSphericalHitIterator = 368 DefaultHitIterator<W, DefaultIntervalIterator<W>>; 369 370 template <int W> 371 using StructuredSphericalHitIteratorFactory = 372 ConcreteIteratorFactory<W, 373 HitIterator, 374 StructuredSphericalHitIterator, 375 HitIteratorContext, 376 HitIteratorContext>; 377 378 template <int W> 379 using StructuredSphericalSampler = 380 StructuredSampler<W, 381 StructuredSphericalIntervalIteratorFactory, 382 StructuredSphericalHitIteratorFactory>; 383 384 } // namespace cpu_device 385 } // namespace openvkl 386