OpenVDB 13.1.0
Loading...
Searching...
No Matches
common.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#ifndef _USE_MATH_DEFINES
7#define _USE_MATH_DEFINES
8#endif
9#include <cmath>
10#include <chrono>
11#include <fstream>
12#include <nanovdb/NanoVDB.h>
13#include "ComputePrimitives.h"
14
15inline __hostdev__ uint32_t CompactBy1(uint32_t x)
16{
17 x &= 0x55555555;
18 x = (x ^ (x >> 1)) & 0x33333333;
19 x = (x ^ (x >> 2)) & 0x0f0f0f0f;
20 x = (x ^ (x >> 4)) & 0x00ff00ff;
21 x = (x ^ (x >> 8)) & 0x0000ffff;
22 return x;
23}
24
25inline __hostdev__ uint32_t SeparateBy1(uint32_t x)
26{
27 x &= 0x0000ffff;
28 x = (x ^ (x << 8)) & 0x00ff00ff;
29 x = (x ^ (x << 4)) & 0x0f0f0f0f;
30 x = (x ^ (x << 2)) & 0x33333333;
31 x = (x ^ (x << 1)) & 0x55555555;
32 return x;
33}
34
35inline __hostdev__ void mortonDecode(uint32_t code, uint32_t& x, uint32_t& y)
36{
37 x = CompactBy1(code);
38 y = CompactBy1(code >> 1);
39}
40
41inline __hostdev__ void mortonEncode(uint32_t& code, uint32_t x, uint32_t y)
42{
43 code = SeparateBy1(x) | (SeparateBy1(y) << 1);
44}
45
46template<typename RenderFn, typename GridT>
47inline float renderImage(bool useCuda, const RenderFn renderOp, int width, int height, float* image, const GridT* grid)
48{
49#if defined(__CUDACC__)
50 // Kernel-only timing on the GPU path. cudaEventElapsedTime measures only
51 // the work between the two record points on the default stream, so it
52 // excludes host-side launch latency and the cudaDeviceSynchronize wakeup
53 // that std::chrono would otherwise pick up. Events are created/destroyed
54 // per call; the ~10us creation cost is dwarfed by the kernel itself.
55 if (useCuda) {
56 cudaEvent_t startEv, stopEv;
57 NANOVDB_CUDA_CHECK_ERROR(cudaEventCreate(&startEv), __FILE__, __LINE__);
58 NANOVDB_CUDA_CHECK_ERROR(cudaEventCreate(&stopEv), __FILE__, __LINE__);
59
60 NANOVDB_CUDA_CHECK_ERROR(cudaEventRecord(startEv, 0), __FILE__, __LINE__);
61
63 true, width * height, 256, __FILE__, __LINE__, [renderOp, image, grid] __hostdev__(int start, int end) {
64 renderOp(start, end, image, grid);
65 });
66
67 NANOVDB_CUDA_CHECK_ERROR(cudaEventRecord(stopEv, 0), __FILE__, __LINE__);
68 NANOVDB_CUDA_CHECK_ERROR(cudaEventSynchronize(stopEv), __FILE__, __LINE__);
69
70 float ms = 0.f;
71 NANOVDB_CUDA_CHECK_ERROR(cudaEventElapsedTime(&ms, startEv, stopEv), __FILE__, __LINE__);
72
73 NANOVDB_CUDA_CHECK_ERROR(cudaEventDestroy(startEv), __FILE__, __LINE__);
74 NANOVDB_CUDA_CHECK_ERROR(cudaEventDestroy(stopEv), __FILE__, __LINE__);
75 return ms;
76 }
77#endif
78
79 using ClockT = std::chrono::high_resolution_clock;
80 auto t0 = ClockT::now();
81
83 useCuda, width * height, 256, __FILE__, __LINE__, [renderOp, image, grid] __hostdev__(int start, int end) {
84 renderOp(start, end, image, grid);
85 });
86 computeSync(useCuda, __FILE__, __LINE__);
87
88 auto t1 = ClockT::now();
89 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count() / 1000.f;
90 return duration;
91}
92
93inline void saveImage(const std::string& filename, int width, int height, const float* image)
94{
95 const auto isLittleEndian = []() -> bool {
96 static int x = 1;
97 static bool result = reinterpret_cast<uint8_t*>(&x)[0] == 1;
98 return result;
99 };
100
101 float scale = 1.0f;
102 if (isLittleEndian())
103 scale = -scale;
104
105 std::fstream fs(filename, std::ios::out | std::ios::binary);
106 if (!fs.is_open()) {
107 throw std::runtime_error("Unable to open file: " + filename);
108 }
109
110 fs << "Pf\n"
111 << width << "\n"
112 << height << "\n"
113 << scale << "\n";
114
115 for (int i = 0; i < width * height; ++i) {
116 float r = image[i];
117 fs.write((char*)&r, sizeof(float));
118 }
119}
120
121template<typename Vec3T>
122struct RayGenOp
123{
124 float mWBBoxDimZ;
125 Vec3T mWBBoxCenter;
126
127 inline RayGenOp(float wBBoxDimZ, Vec3T wBBoxCenter)
128 : mWBBoxDimZ(wBBoxDimZ)
129 , mWBBoxCenter(wBBoxCenter)
130 {
131 }
132
133 inline __hostdev__ void operator()(int i, int w, int h, Vec3T& outOrigin, Vec3T& outDir) const
134 {
135 // perspective camera along Z-axis...
136 uint32_t x, y;
137#if 0
138 mortonDecode(i, x, y);
139#else
140 x = i % w;
141 y = i / w;
142#endif
143 const float fov = 45.f;
144 const float u = (float(x) + 0.5f) / w;
145 const float v = (float(y) + 0.5f) / h;
146 const float aspect = w / float(h);
147 const float Px = (2.f * u - 1.f) * tanf(fov / 2 * 3.14159265358979323846f / 180.f) * aspect;
148 const float Py = (2.f * v - 1.f) * tanf(fov / 2 * 3.14159265358979323846f / 180.f);
149 const Vec3T origin = mWBBoxCenter + Vec3T(0, 0, mWBBoxDimZ);
150 Vec3T dir(Px, Py, -1.f);
151 dir.normalize();
152 outOrigin = origin;
153 outDir = dir;
154 }
155};
156
157struct CompositeOp
158{
159 inline __hostdev__ void operator()(float* outImage, int i, int w, int h, float value, float alpha) const
160 {
161 uint32_t x, y;
162 int offset;
163#if 0
164 mortonDecode(i, x, y);
165 offset = x + y * w;
166#else
167 x = i % w;
168 y = i / w;
169 offset = i;
170#endif
171
172 // checkerboard background...
173 const int mask = 1 << 7;
174 const float bg = ((x & mask) ^ (y & mask)) ? 1.0f : 0.5f;
175 outImage[offset] = alpha * value + (1.0f - alpha) * bg;
176 }
177};
A collection of parallel compute primitives.
void computeForEach(bool useCuda, int numItems, int blockSize, const char *file, int line, const FunctorT &op, Args... args)
Definition ComputePrimitives.h:128
void computeSync(bool useCuda, const char *file, int line)
Definition ComputePrimitives.h:107
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
__hostdev__ void mortonDecode(uint32_t code, uint32_t &x, uint32_t &y)
Definition common.h:35
__hostdev__ void mortonEncode(uint32_t &code, uint32_t x, uint32_t y)
Definition common.h:41
__hostdev__ uint32_t SeparateBy1(uint32_t x)
Definition common.h:25
float renderImage(bool useCuda, const RenderFn renderOp, int width, int height, float *image, const GridT *grid)
Definition common.h:47
__hostdev__ uint32_t CompactBy1(uint32_t x)
Definition common.h:15
void saveImage(const std::string &filename, int width, int height, const float *image)
Definition common.h:63
__hostdev__ void mortonDecode(uint32_t code, uint32_t &x, uint32_t &y)
Definition common.h:35
#define __hostdev__
Definition SampleFromVoxels.h:29
Definition common.h:128
__hostdev__ void operator()(float *outImage, int i, int w, int h, float value, float alpha) const
Definition common.h:159
Definition common.h:93
RayGenOp(float wBBoxDimZ, Vec3T wBBoxCenter)
Definition common.h:127
__hostdev__ void operator()(int i, int w, int h, Vec3T &outOrigin, Vec3T &outDir) const
Definition common.h:133
Vec3T mWBBoxCenter
Definition common.h:95
float mWBBoxDimZ
Definition common.h:94