Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/scene.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "default.h"
7
#include "device.h"
8
#include "builder.h"
9
#include "scene_triangle_mesh.h"
10
#include "scene_quad_mesh.h"
11
#include "scene_user_geometry.h"
12
#include "scene_instance.h"
13
#include "scene_instance_array.h"
14
#include "scene_curves.h"
15
#include "scene_line_segments.h"
16
#include "scene_subdiv_mesh.h"
17
#include "scene_grid_mesh.h"
18
#include "scene_points.h"
19
#include "../subdiv/tessellation_cache.h"
20
21
#include "acceln.h"
22
#include "geometry.h"
23
24
#if defined(EMBREE_SYCL_SUPPORT)
25
#include "../sycl/rthwif_embree_builder.h"
26
#endif
27
28
#if !defined(EMBREE_SYCL_SUPPORT)
29
namespace sycl {
30
struct queue;
31
}
32
#endif
33
namespace embree
34
{
35
struct TaskGroup;
36
37
/*! Base class all scenes are derived from */
38
class __aligned(16) Scene : public AccelN
39
{
40
public:
41
template<typename Ty, bool mblur = false>
42
class Iterator
43
{
44
public:
45
Iterator () {}
46
47
Iterator (Scene* scene, bool all = false)
48
: scene(scene), all(all) {}
49
50
__forceinline Ty* at(const size_t i)
51
{
52
Geometry* geom = scene->geometries[i].ptr;
53
if (geom == nullptr) return nullptr;
54
if (!all && !geom->isEnabled()) return nullptr;
55
const size_t mask = geom->getTypeMask() & Ty::geom_type;
56
if (!(mask)) return nullptr;
57
if ((geom->numTimeSteps != 1) != mblur) return nullptr;
58
return (Ty*) geom;
59
}
60
61
__forceinline Ty* operator[] (const size_t i) {
62
return at(i);
63
}
64
65
__forceinline size_t numPrimitives() const {
66
return scene->getNumPrimitives(Ty::geom_type,mblur);
67
}
68
69
__forceinline size_t maxPrimitivesPerGeometry()
70
{
71
size_t ret = 0;
72
for (size_t i=0; i<scene->size(); i++) {
73
Ty* mesh = at(i);
74
if (mesh == nullptr) continue;
75
ret = max(ret,mesh->size());
76
}
77
return ret;
78
}
79
80
__forceinline unsigned int maxGeomID()
81
{
82
unsigned int ret = 0;
83
for (size_t i=0; i<scene->size(); i++) {
84
Ty* mesh = at(i);
85
if (mesh == nullptr) continue;
86
ret = max(ret,(unsigned int)i);
87
}
88
return ret;
89
}
90
91
__forceinline unsigned maxTimeStepsPerGeometry()
92
{
93
unsigned ret = 0;
94
for (size_t i=0; i<scene->size(); i++) {
95
Ty* mesh = at(i);
96
if (mesh == nullptr) continue;
97
ret = max(ret,mesh->numTimeSteps);
98
}
99
return ret;
100
}
101
102
__forceinline size_t size() const {
103
return scene->size();
104
}
105
106
107
private:
108
Scene* scene;
109
bool all;
110
};
111
112
class Iterator2
113
{
114
public:
115
Iterator2 () {}
116
117
Iterator2 (Scene* scene, Geometry::GTypeMask typemask, bool mblur)
118
: scene(scene), typemask(typemask), mblur(mblur) {}
119
120
__forceinline Geometry* at(const size_t i)
121
{
122
Geometry* geom = scene->geometries[i].ptr;
123
if (geom == nullptr) return nullptr;
124
if (!geom->isEnabled()) return nullptr;
125
if (!(geom->getTypeMask() & typemask)) return nullptr;
126
if ((geom->numTimeSteps != 1) != mblur) return nullptr;
127
return geom;
128
}
129
130
__forceinline Geometry* operator[] (const size_t i) {
131
return at(i);
132
}
133
134
__forceinline size_t size() const {
135
return scene->size();
136
}
137
138
private:
139
Scene* scene;
140
Geometry::GTypeMask typemask;
141
bool mblur;
142
};
143
144
public:
145
146
/*! Scene construction */
147
Scene (Device* device);
148
149
/*! Scene destruction */
150
~Scene () noexcept;
151
152
private:
153
154
/*! class is non-copyable */
155
Scene (const Scene& other) DELETED; // do not implement
156
Scene& operator= (const Scene& other) DELETED; // do not implement
157
158
public:
159
void createTriangleAccel();
160
void createTriangleMBAccel();
161
void createQuadAccel();
162
void createQuadMBAccel();
163
void createHairAccel();
164
void createHairMBAccel();
165
void createSubdivAccel();
166
void createSubdivMBAccel();
167
void createUserGeometryAccel();
168
void createUserGeometryMBAccel();
169
void createInstanceAccel();
170
void createInstanceMBAccel();
171
void createInstanceExpensiveAccel();
172
void createInstanceExpensiveMBAccel();
173
void createInstanceArrayAccel();
174
void createInstanceArrayMBAccel();
175
void createGridAccel();
176
void createGridMBAccel();
177
178
/*! prints statistics about the scene */
179
void printStatistics();
180
181
/*! clears the scene */
182
void clear();
183
184
/*! detaches some geometry */
185
void detachGeometry(size_t geomID);
186
187
void setBuildQuality(RTCBuildQuality quality_flags);
188
RTCBuildQuality getBuildQuality() const;
189
190
void setSceneFlags(RTCSceneFlags scene_flags);
191
RTCSceneFlags getSceneFlags() const;
192
193
void build_cpu_accels();
194
void build_gpu_accels();
195
void commit_internal (bool join);
196
#if defined(EMBREE_SYCL_SUPPORT)
197
sycl::event commit (bool join, sycl::queue queue);
198
#endif
199
void commit (bool join);
200
void commit_task ();
201
void build () {}
202
203
Scene* getTraversable();
204
205
/* return number of geometries */
206
#if defined(__SYCL_DEVICE_ONLY__)
207
__forceinline size_t size() const { return num_geometries; }
208
#else
209
__forceinline size_t size() const { return geometries.size(); }
210
#endif
211
212
/* bind geometry to the scene */
213
unsigned int bind (unsigned geomID, Ref<Geometry> geometry);
214
215
/* determines if scene is modified */
216
__forceinline bool isModified() const { return modified; }
217
218
/* sets modified flag */
219
__forceinline void setModified(bool f = true) {
220
modified = f;
221
}
222
223
__forceinline bool hasMotionBlur() const { return maxTimeSegments > 1; };
224
225
__forceinline uint32_t getMaxTimeSegments() const { return maxTimeSegments; };
226
227
#if !defined(__SYCL_DEVICE_ONLY__)
228
__forceinline bool isGeometryModified(size_t geomID)
229
{
230
Ref<Geometry>& g = geometries[geomID];
231
if (!g) return false;
232
return g->getModCounter() > geometryModCounters_[geomID];
233
}
234
#endif
235
236
protected:
237
238
void checkIfModifiedAndSet ();
239
240
public:
241
242
#if defined(__SYCL_DEVICE_ONLY__)
243
/* get mesh by ID */
244
__forceinline Geometry* get(size_t i) { return geometries_device[i]; }
245
__forceinline const Geometry* get(size_t i) const { return geometries_device[i]; }
246
247
template<typename Mesh>
248
__forceinline Mesh* get(size_t i) {
249
return (Mesh*)geometries_device[i];
250
}
251
template<typename Mesh>
252
__forceinline const Mesh* get(size_t i) const {
253
return (Mesh*)geometries_device[i];
254
}
255
256
template<typename Mesh>
257
__forceinline Mesh* getSafe(size_t i) {
258
if (geometries_device[i] == nullptr) return nullptr;
259
if (!(geometries_device[i]->getTypeMask() & Mesh::geom_type)) return nullptr;
260
else return (Mesh*) geometries_device[i];
261
}
262
#else
263
/* get mesh by ID */
264
__forceinline Geometry* get(size_t i) { assert(i < geometries.size()); return geometries[i].ptr; }
265
__forceinline const Geometry* get(size_t i) const { assert(i < geometries.size()); return geometries[i].ptr; }
266
267
template<typename Mesh>
268
__forceinline Mesh* get(size_t i) {
269
assert(i < geometries.size());
270
assert(geometries[i]->getTypeMask() & Mesh::geom_type);
271
return (Mesh*)geometries[i].ptr;
272
}
273
template<typename Mesh>
274
__forceinline const Mesh* get(size_t i) const {
275
assert(i < geometries.size());
276
assert(geometries[i]->getTypeMask() & Mesh::geom_type);
277
return (Mesh*)geometries[i].ptr;
278
}
279
280
template<typename Mesh>
281
__forceinline Mesh* getSafe(size_t i) {
282
assert(i < geometries.size());
283
if (geometries[i] == null) return nullptr;
284
if (!(geometries[i]->getTypeMask() & Mesh::geom_type)) return nullptr;
285
else return (Mesh*) geometries[i].ptr;
286
}
287
#endif
288
289
290
#if !defined(__SYCL_DEVICE_ONLY__)
291
__forceinline Ref<Geometry> get_locked(size_t i) {
292
Lock<MutexSys> lock(geometriesMutex);
293
assert(i < geometries.size());
294
return geometries[i];
295
}
296
#endif
297
298
/* flag decoding */
299
__forceinline bool isFastAccel() const { return !isCompactAccel() && !isRobustAccel(); }
300
__forceinline bool isCompactAccel() const { return scene_flags & RTC_SCENE_FLAG_COMPACT; }
301
__forceinline bool isRobustAccel() const { return scene_flags & RTC_SCENE_FLAG_ROBUST; }
302
__forceinline bool isStaticAccel() const { return !(scene_flags & RTC_SCENE_FLAG_DYNAMIC); }
303
__forceinline bool isDynamicAccel() const { return scene_flags & RTC_SCENE_FLAG_DYNAMIC; }
304
305
__forceinline bool hasArgumentFilterFunction() const {
306
return scene_flags & RTC_SCENE_FLAG_FILTER_FUNCTION_IN_ARGUMENTS;
307
}
308
309
__forceinline bool hasGeometryFilterFunction() {
310
return world.numFilterFunctions != 0;
311
}
312
313
__forceinline bool hasFilterFunction() {
314
return hasArgumentFilterFunction() || hasGeometryFilterFunction();
315
}
316
317
void* createQBVH6Accel();
318
319
#if defined(EMBREE_SYCL_SUPPORT)
320
private:
321
void syncWithDevice();
322
sycl::event syncWithDevice(sycl::queue queue);
323
#endif
324
325
public:
326
Device* device;
327
Scene* scene_device;
328
329
public:
330
IDPool<unsigned,0xFFFFFFFE> id_pool;
331
Device::vector<Ref<Geometry>> geometries = device; //!< list of all user geometries
332
avector<unsigned int> geometryModCounters_;
333
Device::vector<float*> vertices = device;
334
335
public:
336
/* these are to detect if we need to recreate the acceleration structures */
337
bool flags_modified;
338
unsigned int enabled_geometry_types;
339
340
RTCSceneFlags scene_flags;
341
RTCBuildQuality quality_flags;
342
MutexSys buildMutex;
343
MutexSys geometriesMutex;
344
345
#if defined(EMBREE_SYCL_SUPPORT)
346
public:
347
AccelBuffer accelBuffer;
348
#endif
349
350
private:
351
bool modified; //!< true if scene got modified
352
uint32_t maxTimeSegments; //!< maximal number of motion blur time segments in scene
353
354
#if defined(EMBREE_SYCL_SUPPORT)
355
Geometry** geometries_device; //!< list of all geometries on device
356
char* geometry_data_device; //!< data buffer of all geometries on device
357
size_t num_geometries;
358
size_t geometry_data_byte_size;
359
360
// host buffers used for creating representation of scene/geometry for device
361
// will be freed after scene commit if the scene is static, otherwise the
362
// buffers will stay for quicker rebuild.
363
size_t *offsets;
364
Geometry **geometries_host;
365
char *geometry_data_host;
366
#endif
367
368
public:
369
370
std::unique_ptr<TaskGroup> taskGroup;
371
372
public:
373
struct BuildProgressMonitorInterface : public BuildProgressMonitor {
374
BuildProgressMonitorInterface(Scene* scene)
375
: scene(scene) {}
376
void operator() (size_t dn) const { scene->progressMonitor(double(dn)); }
377
private:
378
Scene* scene;
379
};
380
BuildProgressMonitorInterface progressInterface;
381
RTCProgressMonitorFunction progress_monitor_function;
382
void* progress_monitor_ptr;
383
std::atomic<size_t> progress_monitor_counter;
384
void progressMonitor(double nprims);
385
void setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr);
386
387
private:
388
GeometryCounts world; //!< counts for geometry
389
390
public:
391
392
__forceinline size_t numPrimitives() const {
393
return world.size();
394
}
395
396
__forceinline size_t getNumPrimitives(Geometry::GTypeMask mask, bool mblur) const
397
{
398
size_t count = 0;
399
400
if (mask & Geometry::MTY_TRIANGLE_MESH)
401
count += mblur ? world.numMBTriangles : world.numTriangles;
402
403
if (mask & Geometry::MTY_QUAD_MESH)
404
count += mblur ? world.numMBQuads : world.numQuads;
405
406
if (mask & Geometry::MTY_CURVE2)
407
count += mblur ? world.numMBLineSegments : world.numLineSegments;
408
409
if (mask & Geometry::MTY_CURVE4)
410
count += mblur ? world.numMBBezierCurves : world.numBezierCurves;
411
412
if (mask & Geometry::MTY_POINTS)
413
count += mblur ? world.numMBPoints : world.numPoints;
414
415
if (mask & Geometry::MTY_SUBDIV_MESH)
416
count += mblur ? world.numMBSubdivPatches : world.numSubdivPatches;
417
418
if (mask & Geometry::MTY_USER_GEOMETRY)
419
count += mblur ? world.numMBUserGeometries : world.numUserGeometries;
420
421
if (mask & Geometry::MTY_INSTANCE_CHEAP)
422
count += mblur ? world.numMBInstancesCheap : world.numInstancesCheap;
423
424
if (mask & Geometry::MTY_INSTANCE_EXPENSIVE)
425
count += mblur ? world.numMBInstancesExpensive : world.numInstancesExpensive;
426
427
if (mask & Geometry::MTY_INSTANCE_ARRAY)
428
count += mblur ? world.numMBInstanceArrays : world.numInstanceArrays;
429
430
if (mask & Geometry::MTY_GRID_MESH)
431
count += mblur ? world.numMBGrids : world.numGrids;
432
433
return count;
434
}
435
436
__forceinline size_t getNumSubPrimitives(Geometry::GTypeMask mask, bool mblur) const
437
{
438
size_t count = 0;
439
440
if (mask & Geometry::MTY_GRID_MESH)
441
count += mblur ? world.numMBSubGrids : world.numSubGrids;
442
443
Geometry::GTypeMask new_mask = (Geometry::GTypeMask)(mask & ~Geometry::MTY_GRID_MESH);
444
count += getNumPrimitives(new_mask, mblur);
445
446
return count;
447
}
448
449
template<typename Mesh, bool mblur>
450
__forceinline unsigned getNumTimeSteps()
451
{
452
if (!mblur)
453
return 1;
454
455
Scene::Iterator<Mesh,mblur> iter(this);
456
return iter.maxTimeStepsPerGeometry();
457
}
458
459
template<typename Mesh, bool mblur>
460
__forceinline unsigned int getMaxGeomID()
461
{
462
Scene::Iterator<Mesh,mblur> iter(this);
463
return iter.maxGeomID();
464
}
465
};
466
}
467
468