Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/scene.cpp
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "scene.h"
5
6
#include "../../common/tasking/taskscheduler.h"
7
8
#include "../bvh/bvh4_factory.h"
9
#include "../bvh/bvh8_factory.h"
10
11
#include "../../common/algorithms/parallel_reduce.h"
12
13
#if defined(EMBREE_SYCL_SUPPORT)
14
# include "../sycl/rthwif_embree_builder.h"
15
#endif
16
17
18
namespace embree
19
{
20
21
struct TaskGroup {
22
/*! global lock step task scheduler */
23
#if defined(TASKING_INTERNAL)
24
MutexSys schedulerMutex;
25
Ref<TaskScheduler> scheduler;
26
#elif defined(TASKING_TBB) && TASKING_TBB_USE_TASK_ISOLATION
27
tbb::isolated_task_group group;
28
#elif defined(TASKING_TBB)
29
tbb::task_group group;
30
#elif defined(TASKING_PPL)
31
concurrency::task_group group;
32
#endif
33
};
34
35
/* error raising rtcIntersect and rtcOccluded functions */
36
void missing_rtcCommit() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed"); }
37
void invalid_rtcIntersect1() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect and rtcOccluded not enabled"); }
38
void invalid_rtcIntersect4() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect4 and rtcOccluded4 not enabled"); }
39
void invalid_rtcIntersect8() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect8 and rtcOccluded8 not enabled"); }
40
void invalid_rtcIntersect16() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect16 and rtcOccluded16 not enabled"); }
41
void invalid_rtcIntersectN() { throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersectN and rtcOccludedN not enabled"); }
42
43
Scene::Scene (Device* device)
44
: device(device),
45
scene_device(nullptr),
46
flags_modified(true), enabled_geometry_types(0),
47
scene_flags(RTC_SCENE_FLAG_NONE),
48
quality_flags(RTC_BUILD_QUALITY_MEDIUM),
49
modified(true),
50
maxTimeSegments(0),
51
#if defined(EMBREE_SYCL_SUPPORT)
52
geometries_device(nullptr),
53
geometry_data_device(nullptr),
54
num_geometries(0),
55
geometry_data_byte_size(0),
56
offsets(nullptr),
57
geometries_host(nullptr),
58
geometry_data_host(nullptr),
59
#endif
60
taskGroup(new TaskGroup()),
61
progressInterface(this), progress_monitor_function(nullptr), progress_monitor_ptr(nullptr), progress_monitor_counter(0)
62
{
63
device->refInc();
64
65
intersectors = Accel::Intersectors(missing_rtcCommit);
66
67
/* use proper device and context for SYCL allocations */
68
#if defined(EMBREE_SYCL_SUPPORT)
69
if (dynamic_cast<DeviceGPU*>(device))
70
accelBuffer = AccelBuffer(device);
71
#endif
72
73
/* one can overwrite flags through device for debugging */
74
if (device->quality_flags != -1)
75
quality_flags = (RTCBuildQuality) device->quality_flags;
76
if (device->scene_flags != -1)
77
scene_flags = (RTCSceneFlags) device->scene_flags;
78
}
79
80
Scene::~Scene() noexcept
81
{
82
#if defined(EMBREE_SYCL_SUPPORT)
83
if (geometry_data_device) {
84
device->free(geometry_data_device);
85
}
86
if (geometries_device) {
87
device->free(geometries_device);
88
}
89
if (scene_device) {
90
device->free(scene_device);
91
}
92
if (offsets) {
93
device->free(offsets);
94
}
95
if (geometries_host) {
96
device->free(geometries_host);
97
}
98
if (geometry_data_host) {
99
device->free(geometry_data_host);
100
}
101
#endif
102
103
device->refDec();
104
}
105
106
void Scene::printStatistics()
107
{
108
/* calculate maximum number of time segments */
109
unsigned max_time_steps = 0;
110
for (size_t i=0; i<size(); i++) {
111
if (!get(i)) continue;
112
max_time_steps = max(max_time_steps,get(i)->numTimeSteps);
113
}
114
115
/* initialize vectors*/
116
std::vector<size_t> statistics[Geometry::GTY_END];
117
for (size_t i=0; i<Geometry::GTY_END; i++)
118
statistics[i].resize(max_time_steps);
119
120
/* gather statistics */
121
for (size_t i=0; i<size(); i++)
122
{
123
if (!get(i)) continue;
124
int ty = get(i)->getType();
125
assert(ty<Geometry::GTY_END);
126
int timesegments = get(i)->numTimeSegments();
127
assert((unsigned int)timesegments < max_time_steps);
128
statistics[ty][timesegments] += get(i)->size();
129
}
130
131
/* print statistics */
132
std::cout << std::setw(23) << "segments" << ": ";
133
for (size_t t=0; t<max_time_steps; t++)
134
std::cout << std::setw(10) << t;
135
std::cout << std::endl;
136
137
std::cout << "-------------------------";
138
for (size_t t=0; t<max_time_steps; t++)
139
std::cout << "----------";
140
std::cout << std::endl;
141
142
for (size_t p=0; p<Geometry::GTY_END; p++)
143
{
144
if (std::string(Geometry::gtype_names[p]) == "") continue;
145
std::cout << std::setw(23) << Geometry::gtype_names[p] << ": ";
146
for (size_t t=0; t<max_time_steps; t++)
147
std::cout << std::setw(10) << statistics[p][t];
148
std::cout << std::endl;
149
}
150
}
151
152
void Scene::createTriangleAccel()
153
{
154
#if defined(EMBREE_GEOMETRY_TRIANGLE)
155
156
if (device->tri_accel == "default")
157
{
158
if (quality_flags != RTC_BUILD_QUALITY_LOW)
159
{
160
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
161
switch (mode) {
162
case /*0b00*/ 0:
163
#if defined (EMBREE_TARGET_SIMD8)
164
if (device->canUseAVX())
165
{
166
if (quality_flags == RTC_BUILD_QUALITY_HIGH)
167
accels_add(device->bvh8_factory->BVH8Triangle4(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST));
168
else
169
accels_add(device->bvh8_factory->BVH8Triangle4(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
170
}
171
else
172
#endif
173
{
174
if (quality_flags == RTC_BUILD_QUALITY_HIGH)
175
accels_add(device->bvh4_factory->BVH4Triangle4(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST));
176
else
177
accels_add(device->bvh4_factory->BVH4Triangle4(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
178
}
179
break;
180
181
case /*0b01*/ 1:
182
#if defined (EMBREE_TARGET_SIMD8)
183
if (device->canUseAVX())
184
accels_add(device->bvh8_factory->BVH8Triangle4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
185
else
186
#endif
187
accels_add(device->bvh4_factory->BVH4Triangle4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
188
189
break;
190
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
191
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
192
}
193
}
194
else /* dynamic */
195
{
196
#if defined (EMBREE_TARGET_SIMD8)
197
if (device->canUseAVX())
198
{
199
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
200
switch (mode) {
201
case /*0b00*/ 0: accels_add(device->bvh8_factory->BVH8Triangle4 (this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST )); break;
202
case /*0b01*/ 1: accels_add(device->bvh8_factory->BVH8Triangle4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
203
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST )); break;
204
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
205
}
206
}
207
else
208
#endif
209
{
210
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
211
switch (mode) {
212
case /*0b00*/ 0: accels_add(device->bvh4_factory->BVH4Triangle4 (this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST )); break;
213
case /*0b01*/ 1: accels_add(device->bvh4_factory->BVH4Triangle4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
214
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST )); break;
215
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Triangle4i(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
216
}
217
}
218
}
219
}
220
else if (device->tri_accel == "bvh4.triangle4") accels_add(device->bvh4_factory->BVH4Triangle4 (this));
221
else if (device->tri_accel == "bvh4.triangle4v") accels_add(device->bvh4_factory->BVH4Triangle4v(this));
222
else if (device->tri_accel == "bvh4.triangle4i") accels_add(device->bvh4_factory->BVH4Triangle4i(this));
223
else if (device->tri_accel == "qbvh4.triangle4i") accels_add(device->bvh4_factory->BVH4QuantizedTriangle4i(this));
224
225
#if defined (EMBREE_TARGET_SIMD8)
226
else if (device->tri_accel == "bvh8.triangle4") accels_add(device->bvh8_factory->BVH8Triangle4 (this));
227
else if (device->tri_accel == "bvh8.triangle4v") accels_add(device->bvh8_factory->BVH8Triangle4v(this));
228
else if (device->tri_accel == "bvh8.triangle4i") accels_add(device->bvh8_factory->BVH8Triangle4i(this));
229
else if (device->tri_accel == "qbvh8.triangle4i") accels_add(device->bvh8_factory->BVH8QuantizedTriangle4i(this));
230
else if (device->tri_accel == "qbvh8.triangle4") accels_add(device->bvh8_factory->BVH8QuantizedTriangle4(this));
231
#endif
232
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown triangle acceleration structure "+device->tri_accel);
233
#endif
234
235
}
236
237
void Scene::createTriangleMBAccel()
238
{
239
#if defined(EMBREE_GEOMETRY_TRIANGLE)
240
241
if (device->tri_accel_mb == "default")
242
{
243
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
244
245
#if defined (EMBREE_TARGET_SIMD8)
246
if (device->canUseAVX2()) // BVH8 reduces performance on AVX only-machines
247
{
248
switch (mode) {
249
case /*0b00*/ 0: accels_add(device->bvh8_factory->BVH8Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
250
case /*0b01*/ 1: accels_add(device->bvh8_factory->BVH8Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
251
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
252
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
253
}
254
}
255
else
256
#endif
257
{
258
switch (mode) {
259
case /*0b00*/ 0: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
260
case /*0b01*/ 1: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
261
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
262
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Triangle4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
263
}
264
}
265
}
266
else if (device->tri_accel_mb == "bvh4.triangle4imb") accels_add(device->bvh4_factory->BVH4Triangle4iMB(this));
267
else if (device->tri_accel_mb == "bvh4.triangle4vmb") accels_add(device->bvh4_factory->BVH4Triangle4vMB(this));
268
#if defined (EMBREE_TARGET_SIMD8)
269
else if (device->tri_accel_mb == "bvh8.triangle4imb") accels_add(device->bvh8_factory->BVH8Triangle4iMB(this));
270
else if (device->tri_accel_mb == "bvh8.triangle4vmb") accels_add(device->bvh8_factory->BVH8Triangle4vMB(this));
271
#endif
272
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown motion blur triangle acceleration structure "+device->tri_accel_mb);
273
#endif
274
}
275
276
void Scene::createQuadAccel()
277
{
278
#if defined(EMBREE_GEOMETRY_QUAD)
279
280
if (device->quad_accel == "default")
281
{
282
if (quality_flags != RTC_BUILD_QUALITY_LOW)
283
{
284
/* static */
285
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
286
switch (mode) {
287
case /*0b00*/ 0:
288
#if defined (EMBREE_TARGET_SIMD8)
289
if (device->canUseAVX())
290
{
291
if (quality_flags == RTC_BUILD_QUALITY_HIGH)
292
accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST));
293
else
294
accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
295
}
296
else
297
#endif
298
{
299
if (quality_flags == RTC_BUILD_QUALITY_HIGH)
300
accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST));
301
else
302
accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
303
}
304
break;
305
306
case /*0b01*/ 1:
307
#if defined (EMBREE_TARGET_SIMD8)
308
if (device->canUseAVX())
309
accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
310
else
311
#endif
312
accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
313
break;
314
315
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Quad4i(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST)); break;
316
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Quad4i(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
317
}
318
}
319
else /* dynamic */
320
{
321
#if defined (EMBREE_TARGET_SIMD8)
322
if (device->canUseAVX())
323
{
324
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
325
switch (mode) {
326
case /*0b00*/ 0: accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST)); break;
327
case /*0b01*/ 1: accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
328
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST)); break;
329
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
330
}
331
}
332
else
333
#endif
334
{
335
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
336
switch (mode) {
337
case /*0b00*/ 0: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST)); break;
338
case /*0b01*/ 1: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
339
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::FAST)); break;
340
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::DYNAMIC,BVHFactory::IntersectVariant::ROBUST)); break;
341
}
342
}
343
}
344
}
345
else if (device->quad_accel == "bvh4.quad4v") accels_add(device->bvh4_factory->BVH4Quad4v(this));
346
else if (device->quad_accel == "bvh4.quad4i") accels_add(device->bvh4_factory->BVH4Quad4i(this));
347
else if (device->quad_accel == "qbvh4.quad4i") accels_add(device->bvh4_factory->BVH4QuantizedQuad4i(this));
348
349
#if defined (EMBREE_TARGET_SIMD8)
350
else if (device->quad_accel == "bvh8.quad4v") accels_add(device->bvh8_factory->BVH8Quad4v(this));
351
else if (device->quad_accel == "bvh8.quad4i") accels_add(device->bvh8_factory->BVH8Quad4i(this));
352
else if (device->quad_accel == "qbvh8.quad4i") accels_add(device->bvh8_factory->BVH8QuantizedQuad4i(this));
353
#endif
354
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown quad acceleration structure "+device->quad_accel);
355
#endif
356
}
357
358
void Scene::createQuadMBAccel()
359
{
360
#if defined(EMBREE_GEOMETRY_QUAD)
361
362
if (device->quad_accel_mb == "default")
363
{
364
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
365
switch (mode) {
366
case /*0b00*/ 0:
367
#if defined (EMBREE_TARGET_SIMD8)
368
if (device->canUseAVX())
369
accels_add(device->bvh8_factory->BVH8Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
370
else
371
#endif
372
accels_add(device->bvh4_factory->BVH4Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
373
break;
374
375
case /*0b01*/ 1:
376
#if defined (EMBREE_TARGET_SIMD8)
377
if (device->canUseAVX())
378
accels_add(device->bvh8_factory->BVH8Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
379
else
380
#endif
381
accels_add(device->bvh4_factory->BVH4Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
382
break;
383
384
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST )); break;
385
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); break;
386
}
387
}
388
else if (device->quad_accel_mb == "bvh4.quad4imb") accels_add(device->bvh4_factory->BVH4Quad4iMB(this));
389
#if defined (EMBREE_TARGET_SIMD8)
390
else if (device->quad_accel_mb == "bvh8.quad4imb") accels_add(device->bvh8_factory->BVH8Quad4iMB(this));
391
#endif
392
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown quad motion blur acceleration structure "+device->quad_accel_mb);
393
#endif
394
}
395
396
void Scene::createHairAccel()
397
{
398
#if defined(EMBREE_GEOMETRY_CURVE) || defined(EMBREE_GEOMETRY_POINT)
399
400
if (device->hair_accel == "default")
401
{
402
int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel();
403
#if defined (EMBREE_TARGET_SIMD8)
404
if (device->canUseAVX2()) // only enable on HSW machines, for SNB this codepath is slower
405
{
406
switch (mode) {
407
case /*0b00*/ 0: accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8v(this,BVHFactory::IntersectVariant::FAST)); break;
408
case /*0b01*/ 1: accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8v(this,BVHFactory::IntersectVariant::ROBUST)); break;
409
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve8i(this,BVHFactory::IntersectVariant::FAST)); break;
410
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve8i(this,BVHFactory::IntersectVariant::ROBUST)); break;
411
}
412
}
413
else
414
#endif
415
{
416
switch (mode) {
417
case /*0b00*/ 0: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4v(this,BVHFactory::IntersectVariant::FAST)); break;
418
case /*0b01*/ 1: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4v(this,BVHFactory::IntersectVariant::ROBUST)); break;
419
case /*0b10*/ 2: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4i(this,BVHFactory::IntersectVariant::FAST)); break;
420
case /*0b11*/ 3: accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4i(this,BVHFactory::IntersectVariant::ROBUST)); break;
421
}
422
}
423
}
424
else if (device->hair_accel == "bvh4obb.virtualcurve4v" ) accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4v(this,BVHFactory::IntersectVariant::FAST));
425
else if (device->hair_accel == "bvh4obb.virtualcurve4i" ) accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4i(this,BVHFactory::IntersectVariant::FAST));
426
#if defined (EMBREE_TARGET_SIMD8)
427
else if (device->hair_accel == "bvh8obb.virtualcurve8v" ) accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8v(this,BVHFactory::IntersectVariant::FAST));
428
else if (device->hair_accel == "bvh4obb.virtualcurve8i" ) accels_add(device->bvh4_factory->BVH4OBBVirtualCurve8i(this,BVHFactory::IntersectVariant::FAST));
429
#endif
430
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown hair acceleration structure "+device->hair_accel);
431
#endif
432
}
433
434
void Scene::createHairMBAccel()
435
{
436
#if defined(EMBREE_GEOMETRY_CURVE) || defined(EMBREE_GEOMETRY_POINT)
437
438
if (device->hair_accel_mb == "default")
439
{
440
#if defined (EMBREE_TARGET_SIMD8)
441
if (device->canUseAVX2()) // only enable on HSW machines, on SNB this codepath is slower
442
{
443
if (isRobustAccel()) accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8iMB(this,BVHFactory::IntersectVariant::ROBUST));
444
else accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8iMB(this,BVHFactory::IntersectVariant::FAST));
445
}
446
else
447
#endif
448
{
449
if (isRobustAccel()) accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4iMB(this,BVHFactory::IntersectVariant::ROBUST));
450
else accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4iMB(this,BVHFactory::IntersectVariant::FAST));
451
}
452
}
453
else if (device->hair_accel_mb == "bvh4.virtualcurve4imb") accels_add(device->bvh4_factory->BVH4OBBVirtualCurve4iMB(this,BVHFactory::IntersectVariant::FAST));
454
455
#if defined (EMBREE_TARGET_SIMD8)
456
else if (device->hair_accel_mb == "bvh4.virtualcurve8imb") accels_add(device->bvh4_factory->BVH4OBBVirtualCurve8iMB(this,BVHFactory::IntersectVariant::FAST));
457
else if (device->hair_accel_mb == "bvh8.virtualcurve8imb") accels_add(device->bvh8_factory->BVH8OBBVirtualCurve8iMB(this,BVHFactory::IntersectVariant::FAST));
458
#endif
459
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown motion blur hair acceleration structure "+device->hair_accel_mb);
460
#endif
461
}
462
463
void Scene::createSubdivAccel()
464
{
465
#if defined(EMBREE_GEOMETRY_SUBDIVISION)
466
if (device->subdiv_accel == "default") {
467
accels_add(device->bvh4_factory->BVH4SubdivPatch1(this));
468
}
469
else if (device->subdiv_accel == "bvh4.grid.eager" ) accels_add(device->bvh4_factory->BVH4SubdivPatch1(this));
470
else if (device->subdiv_accel == "bvh4.subdivpatch1eager" ) accels_add(device->bvh4_factory->BVH4SubdivPatch1(this));
471
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown subdiv accel "+device->subdiv_accel);
472
#endif
473
}
474
475
void Scene::createSubdivMBAccel()
476
{
477
#if defined(EMBREE_GEOMETRY_SUBDIVISION)
478
if (device->subdiv_accel_mb == "default") {
479
accels_add(device->bvh4_factory->BVH4SubdivPatch1MB(this));
480
}
481
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown subdiv mblur accel "+device->subdiv_accel_mb);
482
#endif
483
}
484
485
void Scene::createUserGeometryAccel()
486
{
487
#if defined(EMBREE_GEOMETRY_USER)
488
489
if (device->object_accel == "default")
490
{
491
#if defined (EMBREE_TARGET_SIMD8)
492
if (device->canUseAVX() && !isCompactAccel())
493
{
494
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
495
accels_add(device->bvh8_factory->BVH8UserGeometry(this,BVHFactory::BuildVariant::STATIC));
496
} else {
497
accels_add(device->bvh8_factory->BVH8UserGeometry(this,BVHFactory::BuildVariant::DYNAMIC));
498
}
499
}
500
else
501
#endif
502
{
503
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
504
accels_add(device->bvh4_factory->BVH4UserGeometry(this,BVHFactory::BuildVariant::STATIC));
505
} else {
506
accels_add(device->bvh4_factory->BVH4UserGeometry(this,BVHFactory::BuildVariant::DYNAMIC));
507
}
508
}
509
}
510
else if (device->object_accel == "bvh4.object") accels_add(device->bvh4_factory->BVH4UserGeometry(this));
511
#if defined (EMBREE_TARGET_SIMD8)
512
else if (device->object_accel == "bvh8.object") accels_add(device->bvh8_factory->BVH8UserGeometry(this));
513
#endif
514
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown user geometry accel "+device->object_accel);
515
#endif
516
}
517
518
void Scene::createUserGeometryMBAccel()
519
{
520
#if defined(EMBREE_GEOMETRY_USER)
521
522
if (device->object_accel_mb == "default" ) {
523
#if defined (EMBREE_TARGET_SIMD8)
524
if (device->canUseAVX() && !isCompactAccel())
525
accels_add(device->bvh8_factory->BVH8UserGeometryMB(this));
526
else
527
#endif
528
accels_add(device->bvh4_factory->BVH4UserGeometryMB(this));
529
}
530
else if (device->object_accel_mb == "bvh4.object") accels_add(device->bvh4_factory->BVH4UserGeometryMB(this));
531
#if defined (EMBREE_TARGET_SIMD8)
532
else if (device->object_accel_mb == "bvh8.object") accels_add(device->bvh8_factory->BVH8UserGeometryMB(this));
533
#endif
534
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown user geometry mblur accel "+device->object_accel_mb);
535
#endif
536
}
537
538
void Scene::createInstanceAccel()
539
{
540
#if defined(EMBREE_GEOMETRY_INSTANCE)
541
542
// if (device->object_accel == "default")
543
{
544
#if defined (EMBREE_TARGET_SIMD8)
545
if (device->canUseAVX() && !isCompactAccel()) {
546
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
547
accels_add(device->bvh8_factory->BVH8Instance(this, false, BVHFactory::BuildVariant::STATIC));
548
} else {
549
accels_add(device->bvh8_factory->BVH8Instance(this, false, BVHFactory::BuildVariant::DYNAMIC));
550
}
551
}
552
else
553
#endif
554
{
555
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
556
accels_add(device->bvh4_factory->BVH4Instance(this, false, BVHFactory::BuildVariant::STATIC));
557
} else {
558
accels_add(device->bvh4_factory->BVH4Instance(this, false, BVHFactory::BuildVariant::DYNAMIC));
559
}
560
}
561
}
562
// else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance accel "+device->instance_accel);
563
#endif
564
}
565
566
void Scene::createInstanceMBAccel()
567
{
568
#if defined(EMBREE_GEOMETRY_INSTANCE)
569
570
//if (device->instance_accel_mb == "default")
571
{
572
#if defined (EMBREE_TARGET_SIMD8)
573
if (device->canUseAVX() && !isCompactAccel())
574
accels_add(device->bvh8_factory->BVH8InstanceMB(this, false));
575
else
576
#endif
577
accels_add(device->bvh4_factory->BVH4InstanceMB(this, false));
578
}
579
//else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance mblur accel "+device->instance_accel_mb);
580
#endif
581
}
582
583
void Scene::createInstanceExpensiveAccel()
584
{
585
#if defined(EMBREE_GEOMETRY_INSTANCE)
586
// if (device->object_accel == "default")
587
{
588
#if defined (EMBREE_TARGET_SIMD8)
589
if (device->canUseAVX() && !isCompactAccel()) {
590
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
591
accels_add(device->bvh8_factory->BVH8Instance(this, true, BVHFactory::BuildVariant::STATIC));
592
} else {
593
accels_add(device->bvh8_factory->BVH8Instance(this, true, BVHFactory::BuildVariant::DYNAMIC));
594
}
595
}
596
else
597
#endif
598
{
599
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
600
accels_add(device->bvh4_factory->BVH4Instance(this, true, BVHFactory::BuildVariant::STATIC));
601
} else {
602
accels_add(device->bvh4_factory->BVH4Instance(this, true, BVHFactory::BuildVariant::DYNAMIC));
603
}
604
}
605
}
606
// else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance accel "+device->instance_accel);
607
#endif
608
}
609
610
void Scene::createInstanceExpensiveMBAccel()
611
{
612
#if defined(EMBREE_GEOMETRY_INSTANCE)
613
//if (device->instance_accel_mb == "default")
614
{
615
#if defined (EMBREE_TARGET_SIMD8)
616
if (device->canUseAVX() && !isCompactAccel())
617
accels_add(device->bvh8_factory->BVH8InstanceMB(this, true));
618
else
619
#endif
620
accels_add(device->bvh4_factory->BVH4InstanceMB(this, true));
621
}
622
//else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance mblur accel "+device->instance_accel_mb);
623
#endif
624
}
625
626
void Scene::createInstanceArrayAccel()
627
{
628
#if defined(EMBREE_GEOMETRY_INSTANCE_ARRAY)
629
630
// if (device->object_accel == "default")
631
{
632
#if defined (EMBREE_TARGET_SIMD8)
633
if (device->canUseAVX() && !isCompactAccel()) {
634
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
635
accels_add(device->bvh8_factory->BVH8InstanceArray(this, BVHFactory::BuildVariant::STATIC));
636
} else {
637
accels_add(device->bvh8_factory->BVH8InstanceArray(this, BVHFactory::BuildVariant::DYNAMIC));
638
}
639
}
640
else
641
#endif
642
{
643
if (quality_flags != RTC_BUILD_QUALITY_LOW) {
644
accels_add(device->bvh4_factory->BVH4InstanceArray(this, BVHFactory::BuildVariant::STATIC));
645
} else {
646
accels_add(device->bvh4_factory->BVH4InstanceArray(this, BVHFactory::BuildVariant::DYNAMIC));
647
}
648
}
649
}
650
// else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance accel "+device->instance_accel);
651
#endif
652
}
653
654
void Scene::createInstanceArrayMBAccel()
655
{
656
#if defined(EMBREE_GEOMETRY_INSTANCE_ARRAY)
657
658
//if (device->instance_accel_mb == "default")
659
{
660
#if defined (EMBREE_TARGET_SIMD8)
661
if (device->canUseAVX() && !isCompactAccel())
662
accels_add(device->bvh8_factory->BVH8InstanceArrayMB(this));
663
else
664
#endif
665
accels_add(device->bvh4_factory->BVH4InstanceArrayMB(this));
666
}
667
//else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown instance mblur accel "+device->instance_accel_mb);
668
#endif
669
}
670
671
672
void Scene::createGridAccel()
673
{
674
#if defined(EMBREE_GEOMETRY_GRID)
675
676
BVHFactory::IntersectVariant ivariant = isRobustAccel() ? BVHFactory::IntersectVariant::ROBUST : BVHFactory::IntersectVariant::FAST;
677
678
if (device->grid_accel == "default")
679
{
680
#if defined (EMBREE_TARGET_SIMD8)
681
if (device->canUseAVX() && !isCompactAccel())
682
{
683
accels_add(device->bvh8_factory->BVH8Grid(this,BVHFactory::BuildVariant::STATIC,ivariant));
684
}
685
else
686
#endif
687
{
688
accels_add(device->bvh4_factory->BVH4Grid(this,BVHFactory::BuildVariant::STATIC,ivariant));
689
}
690
}
691
else if (device->grid_accel == "bvh4.grid") accels_add(device->bvh4_factory->BVH4Grid(this,BVHFactory::BuildVariant::STATIC,ivariant));
692
#if defined (EMBREE_TARGET_SIMD8)
693
else if (device->grid_accel == "bvh8.grid") accels_add(device->bvh8_factory->BVH8Grid(this,BVHFactory::BuildVariant::STATIC,ivariant));
694
#endif
695
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown grid accel "+device->grid_accel);
696
#endif
697
698
}
699
700
void Scene::createGridMBAccel()
701
{
702
#if defined(EMBREE_GEOMETRY_GRID)
703
704
if (device->grid_accel_mb == "default")
705
{
706
accels_add(device->bvh4_factory->BVH4GridMB(this,BVHFactory::BuildVariant::STATIC));
707
}
708
else if (device->grid_accel_mb == "bvh4mb.grid") accels_add(device->bvh4_factory->BVH4GridMB(this));
709
else throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"unknown grid mb accel "+device->grid_accel);
710
#endif
711
712
}
713
714
void Scene::clear() {
715
}
716
717
unsigned Scene::bind(unsigned geomID, Ref<Geometry> geometry)
718
{
719
Lock<MutexSys> lock(geometriesMutex);
720
if (geomID == RTC_INVALID_GEOMETRY_ID) {
721
geomID = id_pool.allocate();
722
if (geomID == RTC_INVALID_GEOMETRY_ID)
723
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"too many geometries inside scene");
724
}
725
else
726
{
727
if (!id_pool.add(geomID))
728
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry ID provided");
729
}
730
if (geomID >= geometries.size()) {
731
geometries.resize(geomID+1);
732
vertices.resize(geomID+1);
733
geometryModCounters_.resize(geomID+1);
734
}
735
geometries[geomID] = geometry;
736
geometryModCounters_[geomID] = 0;
737
if (geometry->isEnabled()) {
738
setModified ();
739
}
740
return geomID;
741
}
742
743
void Scene::detachGeometry(size_t geomID)
744
{
745
Lock<MutexSys> lock(geometriesMutex);
746
747
if (geomID >= geometries.size())
748
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry ID");
749
750
Ref<Geometry>& geometry = geometries[geomID];
751
if (geometry == null)
752
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry");
753
754
setModified ();
755
accels_deleteGeometry(unsigned(geomID));
756
id_pool.deallocate((unsigned)geomID);
757
geometries[geomID] = null;
758
vertices[geomID] = nullptr;
759
geometryModCounters_[geomID] = 0;
760
}
761
762
void Scene::build_cpu_accels()
763
{
764
/* select acceleration structures to build */
765
unsigned int new_enabled_geometry_types = world.enabledGeometryTypesMask();
766
767
if (flags_modified || new_enabled_geometry_types != enabled_geometry_types)
768
{
769
accels_init();
770
771
/* we need to make all geometries modified, otherwise two level builder will
772
not rebuild currently not modified geometries */
773
parallel_for(geometryModCounters_.size(), [&] ( const size_t i ) {
774
geometryModCounters_[i] = 0;
775
});
776
777
if (getNumPrimitives(TriangleMesh::geom_type,false)) createTriangleAccel();
778
if (getNumPrimitives(TriangleMesh::geom_type,true)) createTriangleMBAccel();
779
if (getNumPrimitives(QuadMesh::geom_type,false)) createQuadAccel();
780
if (getNumPrimitives(QuadMesh::geom_type,true)) createQuadMBAccel();
781
if (getNumPrimitives(GridMesh::geom_type,false)) createGridAccel();
782
if (getNumPrimitives(GridMesh::geom_type,true)) createGridMBAccel();
783
if (getNumPrimitives(SubdivMesh::geom_type,false)) createSubdivAccel();
784
if (getNumPrimitives(SubdivMesh::geom_type,true)) createSubdivMBAccel();
785
if (getNumPrimitives(Geometry::MTY_CURVES,false)) createHairAccel();
786
if (getNumPrimitives(Geometry::MTY_CURVES,true)) createHairMBAccel();
787
if (getNumPrimitives(UserGeometry::geom_type,false)) createUserGeometryAccel();
788
if (getNumPrimitives(UserGeometry::geom_type,true)) createUserGeometryMBAccel();
789
if (getNumPrimitives(Geometry::MTY_INSTANCE_CHEAP,false)) createInstanceAccel();
790
if (getNumPrimitives(Geometry::MTY_INSTANCE_CHEAP,true)) createInstanceMBAccel();
791
if (getNumPrimitives(Geometry::MTY_INSTANCE_EXPENSIVE,false)) createInstanceExpensiveAccel();
792
if (getNumPrimitives(Geometry::MTY_INSTANCE_EXPENSIVE,true)) createInstanceExpensiveMBAccel();
793
if (getNumPrimitives(Geometry::MTY_INSTANCE_ARRAY,false)) createInstanceArrayAccel();
794
if (getNumPrimitives(Geometry::MTY_INSTANCE_ARRAY,true)) createInstanceArrayMBAccel();
795
796
flags_modified = false;
797
enabled_geometry_types = new_enabled_geometry_types;
798
}
799
800
/* select fast code path if no filter function is present */
801
accels_select(hasFilterFunction());
802
803
/* build all hierarchies of this scene */
804
accels_build();
805
806
/* make static geometry immutable */
807
if (!isDynamicAccel()) {
808
accels_immutable();
809
flags_modified = true; // in non-dynamic mode we have to re-create accels
810
}
811
812
if (device->verbosity(2)) {
813
std::cout << "created scene intersector" << std::endl;
814
accels_print(2);
815
std::cout << "selected scene intersector" << std::endl;
816
intersectors.print(2);
817
}
818
}
819
820
void Scene::build_gpu_accels()
821
{
822
#if defined(EMBREE_SYCL_SUPPORT)
823
accelBuffer.build(this);
824
bounds = LBBox<embree::Vec3fa>(accelBuffer.getBounds());
825
#endif
826
}
827
828
void Scene::commit_task ()
829
{
830
checkIfModifiedAndSet();
831
if (!isModified()) return;
832
833
834
/* print scene statistics */
835
if (device->verbosity(2))
836
printStatistics();
837
838
progress_monitor_counter = 0;
839
840
/* gather scene stats and call preCommit function of each geometry */
841
this->world = parallel_reduce (size_t(0), geometries.size(), GeometryCounts (),
842
[this](const range<size_t>& r)->GeometryCounts
843
{
844
GeometryCounts c;
845
for (auto i=r.begin(); i<r.end(); ++i)
846
{
847
if (geometries[i] && geometries[i]->isEnabled())
848
{
849
geometries[i]->preCommit();
850
geometries[i]->addElementsToCount (c);
851
c.numFilterFunctions += (int) geometries[i]->hasArgumentFilterFunctions();
852
c.numFilterFunctions += (int) geometries[i]->hasGeometryFilterFunctions();
853
}
854
}
855
return c;
856
},
857
std::plus<GeometryCounts>()
858
);
859
860
/* calculate maximal number of motion blur time segments in scene */
861
maxTimeSegments = 1;
862
for (size_t geomID=0; geomID<size(); geomID++)
863
{
864
Geometry* geom = get(geomID);
865
if (geom == nullptr) continue;
866
maxTimeSegments = std::max(maxTimeSegments, geom->numTimeSegments());
867
}
868
869
#if defined(EMBREE_SYCL_SUPPORT)
870
DeviceGPU* gpu_device = dynamic_cast<DeviceGPU*>(device);
871
if (gpu_device)
872
build_gpu_accels();
873
else
874
#endif
875
build_cpu_accels();
876
877
/* call postCommit function of each geometry */
878
parallel_for(geometries.size(), [&] ( const size_t i ) {
879
if (geometries[i] && geometries[i]->isEnabled()) {
880
geometries[i]->postCommit();
881
vertices[i] = geometries[i]->getCompactVertexArray();
882
geometryModCounters_[i] = geometries[i]->getModCounter();
883
}
884
});
885
886
setModified(false);
887
}
888
889
void Scene::setBuildQuality(RTCBuildQuality quality_flags_i)
890
{
891
if (quality_flags == quality_flags_i) return;
892
quality_flags = quality_flags_i;
893
flags_modified = true;
894
}
895
896
RTCBuildQuality Scene::getBuildQuality() const {
897
return quality_flags;
898
}
899
900
void Scene::setSceneFlags(RTCSceneFlags scene_flags_i)
901
{
902
if (scene_flags == scene_flags_i) return;
903
scene_flags = scene_flags_i;
904
flags_modified = true;
905
}
906
907
RTCSceneFlags Scene::getSceneFlags() const {
908
return scene_flags;
909
}
910
911
#if defined(EMBREE_SYCL_SUPPORT)
912
sycl::event Scene::commit (bool join, sycl::queue queue)
913
{
914
commit_internal(join);
915
return syncWithDevice(queue);
916
}
917
#endif
918
919
void Scene::commit (bool join)
920
{
921
commit_internal(join);
922
923
#if defined(EMBREE_SYCL_SUPPORT)
924
syncWithDevice();
925
#endif
926
}
927
928
Scene* Scene::getTraversable() {
929
#if defined(EMBREE_SYCL_SUPPORT)
930
if(device->is_gpu()) {
931
return scene_device;
932
}
933
#endif
934
return this;
935
}
936
937
#if defined(TASKING_INTERNAL)
938
939
void Scene::commit_internal (bool join)
940
{
941
Lock<MutexSys> buildLock(buildMutex,false);
942
943
/* allocates own taskscheduler for each build */
944
Ref<TaskScheduler> scheduler = nullptr;
945
{
946
Lock<MutexSys> lock(taskGroup->schedulerMutex);
947
scheduler = taskGroup->scheduler;
948
if (scheduler == null) {
949
buildLock.lock();
950
taskGroup->scheduler = scheduler = new TaskScheduler;
951
}
952
}
953
954
/* worker threads join build */
955
if (!buildLock.isLocked())
956
{
957
if (!join)
958
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"use rtcJoinCommitScene to join a build operation");
959
960
scheduler->join();
961
return;
962
}
963
964
/* initiate build */
965
//try {
966
TaskScheduler::TaskGroupContext context;
967
scheduler->spawn_root([&]() { commit_task(); Lock<MutexSys> lock(taskGroup->schedulerMutex); taskGroup->scheduler = nullptr; }, &context, 1, !join);
968
//}
969
//catch (...) {
970
// accels_clear();
971
// Lock<MutexSys> lock(taskGroup->schedulerMutex);
972
// taskGroup->scheduler = nullptr;
973
// throw;
974
//}
975
}
976
977
#endif
978
979
#if defined(TASKING_TBB)
980
981
void Scene::commit_internal (bool join)
982
{
983
#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION_MAJOR < 8)
984
if (join)
985
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcJoinCommitScene not supported with this TBB version");
986
#endif
987
988
/* try to obtain build lock */
989
Lock<MutexSys> lock(buildMutex,buildMutex.try_lock());
990
991
/* join hierarchy build */
992
if (!lock.isLocked())
993
{
994
#if !TASKING_TBB_USE_TASK_ISOLATION
995
if (!join)
996
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invoking rtcCommitScene from multiple threads is not supported with this TBB version");
997
#endif
998
999
do {
1000
device->execute(join, [&](){ taskGroup->group.wait(); });
1001
1002
pause_cpu();
1003
yield();
1004
} while (!buildMutex.try_lock());
1005
1006
buildMutex.unlock();
1007
return;
1008
}
1009
1010
/* for best performance set FTZ and DAZ flags in the MXCSR control and status register */
1011
const unsigned int mxcsr = _mm_getcsr();
1012
_mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6));
1013
1014
try {
1015
#if TBB_INTERFACE_VERSION_MAJOR < 8
1016
tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits);
1017
#else
1018
tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits | tbb::task_group_context::fp_settings );
1019
#endif
1020
//ctx.set_priority(tbb::priority_high);
1021
device->execute(join, [&]()
1022
{
1023
taskGroup->group.run([&]{
1024
tbb::parallel_for (size_t(0), size_t(1), size_t(1), [&] (size_t) { commit_task(); }, ctx);
1025
});
1026
taskGroup->group.wait();
1027
});
1028
1029
/* reset MXCSR register again */
1030
_mm_setcsr(mxcsr);
1031
}
1032
catch (...)
1033
{
1034
/* reset MXCSR register again */
1035
_mm_setcsr(mxcsr);
1036
1037
accels_clear();
1038
throw;
1039
}
1040
}
1041
#endif
1042
1043
#if defined(TASKING_PPL)
1044
1045
void Scene::commit_internal (bool join)
1046
{
1047
#if defined(TASKING_PPL)
1048
if (join)
1049
throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcJoinCommitScene not supported with PPL");
1050
#endif
1051
1052
/* try to obtain build lock */
1053
Lock<MutexSys> lock(buildMutex);
1054
1055
checkIfModifiedAndSet ();
1056
if (!isModified()) {
1057
return;
1058
}
1059
1060
/* for best performance set FTZ and DAZ flags in the MXCSR control and status register */
1061
const unsigned int mxcsr = _mm_getcsr();
1062
_mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6));
1063
1064
try {
1065
1066
taskGroup->group.run([&]{
1067
concurrency::parallel_for(size_t(0), size_t(1), size_t(1), [&](size_t) { commit_task(); });
1068
});
1069
taskGroup->group.wait();
1070
1071
/* reset MXCSR register again */
1072
_mm_setcsr(mxcsr);
1073
}
1074
catch (...)
1075
{
1076
/* reset MXCSR register again */
1077
_mm_setcsr(mxcsr);
1078
1079
accels_clear();
1080
throw;
1081
}
1082
1083
}
1084
#endif
1085
1086
void Scene::setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr)
1087
{
1088
progress_monitor_function = func;
1089
progress_monitor_ptr = ptr;
1090
}
1091
1092
void Scene::progressMonitor(double dn)
1093
{
1094
if (progress_monitor_function) {
1095
size_t n = size_t(dn) + progress_monitor_counter.fetch_add(size_t(dn));
1096
if (!progress_monitor_function(progress_monitor_ptr, n / (double(numPrimitives())))) {
1097
throw_RTCError(RTC_ERROR_CANCELLED,"progress monitor forced termination");
1098
}
1099
}
1100
}
1101
1102
}
1103
1104