Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/bvh/bvh_statistics.h
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "bvh.h"
7
#include <sstream>
8
9
namespace embree
10
{
11
template<int N>
12
class BVHNStatistics
13
{
14
typedef BVHN<N> BVH;
15
typedef typename BVH::AABBNode AABBNode;
16
typedef typename BVH::OBBNode OBBNode;
17
typedef typename BVH::AABBNodeMB AABBNodeMB;
18
typedef typename BVH::AABBNodeMB4D AABBNodeMB4D;
19
typedef typename BVH::OBBNodeMB OBBNodeMB;
20
typedef typename BVH::QuantizedNode QuantizedNode;
21
22
typedef typename BVH::NodeRef NodeRef;
23
24
struct Statistics
25
{
26
template<typename Node>
27
struct NodeStat
28
{
29
NodeStat ( double nodeSAH = 0,
30
size_t numNodes = 0,
31
size_t numChildren = 0)
32
: nodeSAH(nodeSAH),
33
numNodes(numNodes),
34
numChildren(numChildren) {}
35
36
double sah(BVH* bvh) const {
37
return nodeSAH/bvh->getLinearBounds().expectedHalfArea();
38
}
39
40
size_t bytes() const {
41
return numNodes*sizeof(Node);
42
}
43
44
size_t size() const {
45
return numNodes;
46
}
47
48
double fillRateNom () const { return double(numChildren); }
49
double fillRateDen () const { return double(numNodes*N); }
50
double fillRate () const { return fillRateNom()/fillRateDen(); }
51
52
__forceinline friend NodeStat operator+ ( const NodeStat& a, const NodeStat& b)
53
{
54
return NodeStat(a.nodeSAH + b.nodeSAH,
55
a.numNodes+b.numNodes,
56
a.numChildren+b.numChildren);
57
}
58
59
std::string toString(BVH* bvh, double sahTotal, size_t bytesTotal) const
60
{
61
std::ostringstream stream;
62
stream.setf(std::ios::fixed, std::ios::floatfield);
63
stream << "sah = " << std::setw(7) << std::setprecision(3) << sah(bvh);
64
stream << " (" << std::setw(6) << std::setprecision(2) << 100.0*sah(bvh)/sahTotal << "%), ";
65
stream << "#bytes = " << std::setw(7) << std::setprecision(2) << bytes()/1E6 << " MB ";
66
stream << "(" << std::setw(6) << std::setprecision(2) << 100.0*double(bytes())/double(bytesTotal) << "%), ";
67
stream << "#nodes = " << std::setw(7) << numNodes << " (" << std::setw(6) << std::setprecision(2) << 100.0*fillRate() << "% filled), ";
68
stream << "#bytes/prim = " << std::setw(6) << std::setprecision(2) << double(bytes())/double(bvh->numPrimitives);
69
return stream.str();
70
}
71
72
public:
73
double nodeSAH;
74
size_t numNodes;
75
size_t numChildren;
76
};
77
78
struct LeafStat
79
{
80
static const int NHIST = 8;
81
82
LeafStat ( double leafSAH = 0.0f,
83
size_t numLeaves = 0,
84
size_t numPrimsActive = 0,
85
size_t numPrimsTotal = 0,
86
size_t numPrimBlocks = 0,
87
size_t numBytes = 0)
88
: leafSAH(leafSAH),
89
numLeaves(numLeaves),
90
numPrimsActive(numPrimsActive),
91
numPrimsTotal(numPrimsTotal),
92
numPrimBlocks(numPrimBlocks),
93
numBytes(numBytes)
94
{
95
for (size_t i=0; i<NHIST; i++)
96
numPrimBlocksHistogram[i] = 0;
97
}
98
99
double sah(BVH* bvh) const {
100
return leafSAH/bvh->getLinearBounds().expectedHalfArea();
101
}
102
103
size_t bytes(BVH* bvh) const {
104
return numBytes;
105
}
106
107
size_t size() const {
108
return numLeaves;
109
}
110
111
double fillRateNom (BVH* bvh) const { return double(numPrimsActive); }
112
double fillRateDen (BVH* bvh) const { return double(numPrimsTotal); }
113
double fillRate (BVH* bvh) const { return fillRateNom(bvh)/fillRateDen(bvh); }
114
115
__forceinline friend LeafStat operator+ ( const LeafStat& a, const LeafStat& b)
116
{
117
LeafStat stat(a.leafSAH + b.leafSAH,
118
a.numLeaves+b.numLeaves,
119
a.numPrimsActive+b.numPrimsActive,
120
a.numPrimsTotal+b.numPrimsTotal,
121
a.numPrimBlocks+b.numPrimBlocks,
122
a.numBytes+b.numBytes);
123
for (size_t i=0; i<NHIST; i++) {
124
stat.numPrimBlocksHistogram[i] += a.numPrimBlocksHistogram[i];
125
stat.numPrimBlocksHistogram[i] += b.numPrimBlocksHistogram[i];
126
}
127
return stat;
128
}
129
130
std::string toString(BVH* bvh, double sahTotal, size_t bytesTotal) const
131
{
132
std::ostringstream stream;
133
stream.setf(std::ios::fixed, std::ios::floatfield);
134
stream << "sah = " << std::setw(7) << std::setprecision(3) << sah(bvh);
135
stream << " (" << std::setw(6) << std::setprecision(2) << 100.0*sah(bvh)/sahTotal << "%), ";
136
stream << "#bytes = " << std::setw(7) << std::setprecision(2) << double(bytes(bvh))/1E6 << " MB ";
137
stream << "(" << std::setw(6) << std::setprecision(2) << 100.0*double(bytes(bvh))/double(bytesTotal) << "%), ";
138
stream << "#nodes = " << std::setw(7) << numLeaves << " (" << std::setw(6) << std::setprecision(2) << 100.0*fillRate(bvh) << "% filled), ";
139
stream << "#bytes/prim = " << std::setw(6) << std::setprecision(2) << double(bytes(bvh))/double(bvh->numPrimitives);
140
return stream.str();
141
}
142
143
std::string histToString() const
144
{
145
std::ostringstream stream;
146
stream.setf(std::ios::fixed, std::ios::floatfield);
147
for (size_t i=0; i<NHIST; i++)
148
stream << std::setw(6) << std::setprecision(2) << 100.0f*float(numPrimBlocksHistogram[i])/float(numLeaves) << "% ";
149
return stream.str();
150
}
151
152
public:
153
double leafSAH; //!< SAH of the leaves only
154
size_t numLeaves; //!< Number of leaf nodes.
155
size_t numPrimsActive; //!< Number of active primitives (
156
size_t numPrimsTotal; //!< Number of active and inactive primitives
157
size_t numPrimBlocks; //!< Number of primitive blocks.
158
size_t numBytes; //!< Number of bytes of leaves.
159
size_t numPrimBlocksHistogram[8];
160
};
161
162
public:
163
Statistics (size_t depth = 0,
164
LeafStat statLeaf = LeafStat(),
165
NodeStat<AABBNode> statAABBNodes = NodeStat<AABBNode>(),
166
NodeStat<OBBNode> statOBBNodes = NodeStat<OBBNode>(),
167
NodeStat<AABBNodeMB> statAABBNodesMB = NodeStat<AABBNodeMB>(),
168
NodeStat<AABBNodeMB4D> statAABBNodesMB4D = NodeStat<AABBNodeMB4D>(),
169
NodeStat<OBBNodeMB> statOBBNodesMB = NodeStat<OBBNodeMB>(),
170
NodeStat<QuantizedNode> statQuantizedNodes = NodeStat<QuantizedNode>())
171
172
: depth(depth),
173
statLeaf(statLeaf),
174
statAABBNodes(statAABBNodes),
175
statOBBNodes(statOBBNodes),
176
statAABBNodesMB(statAABBNodesMB),
177
statAABBNodesMB4D(statAABBNodesMB4D),
178
statOBBNodesMB(statOBBNodesMB),
179
statQuantizedNodes(statQuantizedNodes) {}
180
181
double sah(BVH* bvh) const
182
{
183
return statLeaf.sah(bvh) +
184
statAABBNodes.sah(bvh) +
185
statOBBNodes.sah(bvh) +
186
statAABBNodesMB.sah(bvh) +
187
statAABBNodesMB4D.sah(bvh) +
188
statOBBNodesMB.sah(bvh) +
189
statQuantizedNodes.sah(bvh);
190
}
191
192
size_t bytes(BVH* bvh) const {
193
return statLeaf.bytes(bvh) +
194
statAABBNodes.bytes() +
195
statOBBNodes.bytes() +
196
statAABBNodesMB.bytes() +
197
statAABBNodesMB4D.bytes() +
198
statOBBNodesMB.bytes() +
199
statQuantizedNodes.bytes();
200
}
201
202
size_t size() const
203
{
204
return statLeaf.size() +
205
statAABBNodes.size() +
206
statOBBNodes.size() +
207
statAABBNodesMB.size() +
208
statAABBNodesMB4D.size() +
209
statOBBNodesMB.size() +
210
statQuantizedNodes.size();
211
}
212
213
double fillRate (BVH* bvh) const
214
{
215
double nom = statLeaf.fillRateNom(bvh) +
216
statAABBNodes.fillRateNom() +
217
statOBBNodes.fillRateNom() +
218
statAABBNodesMB.fillRateNom() +
219
statAABBNodesMB4D.fillRateNom() +
220
statOBBNodesMB.fillRateNom() +
221
statQuantizedNodes.fillRateNom();
222
double den = statLeaf.fillRateDen(bvh) +
223
statAABBNodes.fillRateDen() +
224
statOBBNodes.fillRateDen() +
225
statAABBNodesMB.fillRateDen() +
226
statAABBNodesMB4D.fillRateDen() +
227
statOBBNodesMB.fillRateDen() +
228
statQuantizedNodes.fillRateDen();
229
return nom/den;
230
}
231
232
friend Statistics operator+ ( const Statistics& a, const Statistics& b )
233
{
234
return Statistics(max(a.depth,b.depth),
235
a.statLeaf + b.statLeaf,
236
a.statAABBNodes + b.statAABBNodes,
237
a.statOBBNodes + b.statOBBNodes,
238
a.statAABBNodesMB + b.statAABBNodesMB,
239
a.statAABBNodesMB4D + b.statAABBNodesMB4D,
240
a.statOBBNodesMB + b.statOBBNodesMB,
241
a.statQuantizedNodes + b.statQuantizedNodes);
242
}
243
244
static Statistics add ( const Statistics& a, const Statistics& b ) {
245
return a+b;
246
}
247
248
public:
249
size_t depth;
250
LeafStat statLeaf;
251
NodeStat<AABBNode> statAABBNodes;
252
NodeStat<OBBNode> statOBBNodes;
253
NodeStat<AABBNodeMB> statAABBNodesMB;
254
NodeStat<AABBNodeMB4D> statAABBNodesMB4D;
255
NodeStat<OBBNodeMB> statOBBNodesMB;
256
NodeStat<QuantizedNode> statQuantizedNodes;
257
};
258
259
public:
260
261
/* Constructor gathers statistics. */
262
BVHNStatistics (BVH* bvh);
263
264
/*! Convert statistics into a string */
265
std::string str();
266
267
double sah() const {
268
return stat.sah(bvh);
269
}
270
271
size_t bytesUsed() const {
272
return stat.bytes(bvh);
273
}
274
275
private:
276
Statistics statistics(NodeRef node, const double A, const BBox1f dt);
277
278
private:
279
BVH* bvh;
280
Statistics stat;
281
};
282
283
typedef BVHNStatistics<4> BVH4Statistics;
284
typedef BVHNStatistics<8> BVH8Statistics;
285
}
286
287