Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/state.cpp
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "state.h"
5
#include "../../common/lexers/streamfilters.h"
6
7
namespace embree
8
{
9
MutexSys g_printMutex;
10
11
State::ErrorHandler State::g_errorHandler;
12
13
State::ErrorHandler::ErrorHandler()
14
: thread_error(createTls()) {}
15
16
State::ErrorHandler::~ErrorHandler()
17
{
18
Lock<MutexSys> lock(errors_mutex);
19
for (size_t i=0; i<thread_errors.size(); i++) {
20
delete thread_errors[i];
21
}
22
destroyTls(thread_error);
23
thread_errors.clear();
24
}
25
26
RTCErrorMessage* State::ErrorHandler::error()
27
{
28
RTCErrorMessage* stored_error = (RTCErrorMessage*) getTls(thread_error);
29
if (stored_error) {
30
return stored_error;
31
}
32
33
Lock<MutexSys> lock(errors_mutex);
34
stored_error = new RTCErrorMessage(RTC_ERROR_NONE, "");
35
thread_errors.push_back(stored_error);
36
setTls(thread_error,stored_error);
37
return stored_error;
38
}
39
40
State::State ()
41
: enabled_cpu_features(getCPUFeatures()),
42
enabled_builder_cpu_features(enabled_cpu_features),
43
frequency_level(FREQUENCY_SIMD256)
44
{
45
tri_accel = "default";
46
tri_builder = "default";
47
tri_traverser = "default";
48
49
tri_accel_mb = "default";
50
tri_builder_mb = "default";
51
tri_traverser_mb = "default";
52
53
quad_accel = "default";
54
quad_builder = "default";
55
quad_traverser = "default";
56
57
quad_accel_mb = "default";
58
quad_builder_mb = "default";
59
quad_traverser_mb = "default";
60
61
line_accel = "default";
62
line_builder = "default";
63
line_traverser = "default";
64
65
line_accel_mb = "default";
66
line_builder_mb = "default";
67
line_traverser_mb = "default";
68
69
hair_accel = "default";
70
hair_builder = "default";
71
hair_traverser = "default";
72
73
hair_accel_mb = "default";
74
hair_builder_mb = "default";
75
hair_traverser_mb = "default";
76
77
object_accel = "default";
78
object_builder = "default";
79
object_accel_min_leaf_size = 1;
80
object_accel_max_leaf_size = 1;
81
82
object_accel_mb = "default";
83
object_builder_mb = "default";
84
object_accel_mb_min_leaf_size = 1;
85
object_accel_mb_max_leaf_size = 1;
86
87
max_spatial_split_replications = 1.2f;
88
useSpatialPreSplits = false;
89
90
max_triangles_per_leaf = inf;
91
92
tessellation_cache_size = 128*1024*1024;
93
94
subdiv_accel = "default";
95
subdiv_accel_mb = "default";
96
97
grid_accel = "default";
98
grid_builder = "default";
99
grid_accel_mb = "default";
100
grid_builder_mb = "default";
101
102
instancing_open_min = 0;
103
instancing_block_size = 0;
104
instancing_open_factor = 8.0f;
105
instancing_open_max_depth = 32;
106
instancing_open_max = 50000000;
107
108
float_exceptions = false;
109
quality_flags = -1;
110
scene_flags = -1;
111
verbose = 0;
112
benchmark = 0;
113
114
numThreads = 0;
115
numUserThreads = 0;
116
117
#if TASKING_INTERNAL
118
set_affinity = true;
119
#else
120
set_affinity = false;
121
#endif
122
123
start_threads = false;
124
enable_selockmemoryprivilege = false;
125
#if defined(__LINUX__)
126
hugepages = true;
127
#else
128
hugepages = false;
129
#endif
130
hugepages_success = true;
131
132
alloc_main_block_size = 0;
133
alloc_num_main_slots = 0;
134
alloc_thread_block_size = 0;
135
alloc_single_thread_alloc = -1;
136
137
error_function = nullptr;
138
error_function_userptr = nullptr;
139
140
memory_monitor_function = nullptr;
141
memory_monitor_userptr = nullptr;
142
}
143
144
State::~State() {
145
}
146
147
bool State::hasISA(const int isa) {
148
return (enabled_cpu_features & isa) == isa;
149
}
150
151
bool State::checkISASupport() {
152
#if defined(__ARM_NEON)
153
/*
154
* NEON CPU type is a mixture of NEON and SSE2
155
*/
156
157
bool hasSSE2 = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_SSE2;
158
159
/* this will be true when explicitly initialize Device with `isa=neon` config */
160
bool hasNEON = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_NEON;
161
162
return hasSSE2 || hasNEON;
163
#else
164
return (getCPUFeatures() & enabled_cpu_features) == enabled_cpu_features;
165
#endif
166
}
167
168
void State::verify()
169
{
170
/* verify that calculations stay in range */
171
assert(rcp(min_rcp_input)*FLT_LARGE+FLT_LARGE < 0.01f*FLT_MAX);
172
173
/* here we verify that CPP files compiled for a specific ISA only
174
* call that same or lower ISA version of non-inlined class member
175
* functions */
176
#if defined(DEBUG)
177
#if defined(EMBREE_TARGET_SSE2)
178
#if !defined(__ARM_NEON)
179
assert(sse2::getISA() <= SSE2);
180
#endif
181
#endif
182
#if defined(EMBREE_TARGET_SSE42)
183
assert(sse42::getISA() <= SSE42);
184
#endif
185
#if defined(EMBREE_TARGET_AVX)
186
assert(avx::getISA() <= AVX);
187
#endif
188
#if defined(EMBREE_TARGET_AVX2)
189
assert(avx2::getISA() <= AVX2);
190
#endif
191
#if defined (EMBREE_TARGET_AVX512)
192
assert(avx512::getISA() <= AVX512);
193
#endif
194
#endif
195
}
196
197
const char* symbols[3] = { "=", ",", "|" };
198
199
bool State::parseFile(const FileName& fileName)
200
{
201
Ref<Stream<int> > file;
202
//try {
203
file = new FileStream(fileName);
204
//}
205
//catch (std::runtime_error& e) {
206
// (void) e;
207
// return false;
208
//}
209
210
std::vector<std::string> syms;
211
for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)
212
syms.push_back(symbols[i]);
213
214
Ref<TokenStream> cin = new TokenStream(new LineCommentFilter(file,"#"),
215
TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",
216
TokenStream::separators,syms);
217
parse(cin);
218
return true;
219
}
220
221
void State::parseString(const char* cfg)
222
{
223
if (cfg == nullptr) return;
224
225
std::vector<std::string> syms;
226
for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)
227
syms.push_back(symbols[i]);
228
229
Ref<TokenStream> cin = new TokenStream(new StrStream(cfg),
230
TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",
231
TokenStream::separators,syms);
232
parse(cin);
233
}
234
235
int string_to_cpufeatures(const std::string& isa)
236
{
237
if (isa == "sse" ) return SSE;
238
else if (isa == "sse2") return SSE2;
239
else if (isa == "sse3") return SSE3;
240
else if (isa == "ssse3") return SSSE3;
241
else if (isa == "sse41") return SSE41;
242
else if (isa == "sse4.1") return SSE41;
243
else if (isa == "sse42") return SSE42;
244
else if (isa == "sse4.2") return SSE42;
245
else if (isa == "avx") return AVX;
246
else if (isa == "avxi") return AVXI;
247
else if (isa == "avx2") return AVX2;
248
else if (isa == "avx512") return AVX512;
249
else return SSE2;
250
}
251
252
void State::parse(Ref<TokenStream> cin)
253
{
254
/* parse until end of stream */
255
while (cin->peek() != Token::Eof())
256
{
257
const Token tok = cin->get();
258
259
if (tok == Token::Id("threads") && cin->trySymbol("="))
260
numThreads = cin->get().Int();
261
262
else if (tok == Token::Id("user_threads")&& cin->trySymbol("="))
263
numUserThreads = cin->get().Int();
264
265
else if (tok == Token::Id("set_affinity")&& cin->trySymbol("="))
266
set_affinity = cin->get().Int();
267
268
else if (tok == Token::Id("affinity")&& cin->trySymbol("="))
269
set_affinity = cin->get().Int();
270
271
else if (tok == Token::Id("start_threads")&& cin->trySymbol("="))
272
start_threads = cin->get().Int();
273
274
else if (tok == Token::Id("isa") && cin->trySymbol("=")) {
275
std::string isa_str = toLowerCase(cin->get().Identifier());
276
enabled_cpu_features = string_to_cpufeatures(isa_str);
277
enabled_builder_cpu_features = enabled_cpu_features;
278
}
279
280
else if (tok == Token::Id("max_isa") && cin->trySymbol("=")) {
281
std::string isa_str = toLowerCase(cin->get().Identifier());
282
enabled_cpu_features &= string_to_cpufeatures(isa_str);
283
enabled_builder_cpu_features &= enabled_cpu_features;
284
}
285
286
else if (tok == Token::Id("max_builder_isa") && cin->trySymbol("=")) {
287
std::string isa_str = toLowerCase(cin->get().Identifier());
288
enabled_builder_cpu_features &= string_to_cpufeatures(isa_str);
289
}
290
291
else if (tok == Token::Id("frequency_level") && cin->trySymbol("=")) {
292
std::string freq = cin->get().Identifier();
293
if (freq == "simd128") frequency_level = FREQUENCY_SIMD128;
294
else if (freq == "simd256") frequency_level = FREQUENCY_SIMD256;
295
else if (freq == "simd512") frequency_level = FREQUENCY_SIMD512;
296
}
297
298
else if (tok == Token::Id("enable_selockmemoryprivilege") && cin->trySymbol("=")) {
299
enable_selockmemoryprivilege = cin->get().Int();
300
}
301
else if (tok == Token::Id("hugepages") && cin->trySymbol("=")) {
302
hugepages = cin->get().Int();
303
}
304
305
else if (tok == Token::Id("float_exceptions") && cin->trySymbol("="))
306
float_exceptions = cin->get().Int();
307
308
else if ((tok == Token::Id("tri_accel") || tok == Token::Id("accel")) && cin->trySymbol("="))
309
tri_accel = cin->get().Identifier();
310
else if ((tok == Token::Id("tri_builder") || tok == Token::Id("builder")) && cin->trySymbol("="))
311
tri_builder = cin->get().Identifier();
312
else if ((tok == Token::Id("tri_traverser") || tok == Token::Id("traverser")) && cin->trySymbol("="))
313
tri_traverser = cin->get().Identifier();
314
315
else if ((tok == Token::Id("tri_accel_mb") || tok == Token::Id("accel_mb")) && cin->trySymbol("="))
316
tri_accel_mb = cin->get().Identifier();
317
else if ((tok == Token::Id("tri_builder_mb") || tok == Token::Id("builder_mb")) && cin->trySymbol("="))
318
tri_builder_mb = cin->get().Identifier();
319
else if ((tok == Token::Id("tri_traverser_mb") || tok == Token::Id("traverser_mb")) && cin->trySymbol("="))
320
tri_traverser_mb = cin->get().Identifier();
321
322
else if ((tok == Token::Id("quad_accel")) && cin->trySymbol("="))
323
quad_accel = cin->get().Identifier();
324
else if ((tok == Token::Id("quad_builder")) && cin->trySymbol("="))
325
quad_builder = cin->get().Identifier();
326
else if ((tok == Token::Id("quad_traverser")) && cin->trySymbol("="))
327
quad_traverser = cin->get().Identifier();
328
329
else if ((tok == Token::Id("quad_accel_mb")) && cin->trySymbol("="))
330
quad_accel_mb = cin->get().Identifier();
331
else if ((tok == Token::Id("quad_builder_mb")) && cin->trySymbol("="))
332
quad_builder_mb = cin->get().Identifier();
333
else if ((tok == Token::Id("quad_traverser_mb")) && cin->trySymbol("="))
334
quad_traverser_mb = cin->get().Identifier();
335
336
else if ((tok == Token::Id("line_accel")) && cin->trySymbol("="))
337
line_accel = cin->get().Identifier();
338
else if ((tok == Token::Id("line_builder")) && cin->trySymbol("="))
339
line_builder = cin->get().Identifier();
340
else if ((tok == Token::Id("line_traverser")) && cin->trySymbol("="))
341
line_traverser = cin->get().Identifier();
342
343
else if ((tok == Token::Id("line_accel_mb")) && cin->trySymbol("="))
344
line_accel_mb = cin->get().Identifier();
345
else if ((tok == Token::Id("line_builder_mb")) && cin->trySymbol("="))
346
line_builder_mb = cin->get().Identifier();
347
else if ((tok == Token::Id("line_traverser_mb")) && cin->trySymbol("="))
348
line_traverser_mb = cin->get().Identifier();
349
350
else if (tok == Token::Id("hair_accel") && cin->trySymbol("="))
351
hair_accel = cin->get().Identifier();
352
else if (tok == Token::Id("hair_builder") && cin->trySymbol("="))
353
hair_builder = cin->get().Identifier();
354
else if (tok == Token::Id("hair_traverser") && cin->trySymbol("="))
355
hair_traverser = cin->get().Identifier();
356
357
else if (tok == Token::Id("hair_accel_mb") && cin->trySymbol("="))
358
hair_accel_mb = cin->get().Identifier();
359
else if (tok == Token::Id("hair_builder_mb") && cin->trySymbol("="))
360
hair_builder_mb = cin->get().Identifier();
361
else if (tok == Token::Id("hair_traverser_mb") && cin->trySymbol("="))
362
hair_traverser_mb = cin->get().Identifier();
363
364
else if (tok == Token::Id("object_accel") && cin->trySymbol("="))
365
object_accel = cin->get().Identifier();
366
else if (tok == Token::Id("object_builder") && cin->trySymbol("="))
367
object_builder = cin->get().Identifier();
368
else if (tok == Token::Id("object_accel_min_leaf_size") && cin->trySymbol("="))
369
object_accel_min_leaf_size = cin->get().Int();
370
else if (tok == Token::Id("object_accel_max_leaf_size") && cin->trySymbol("="))
371
object_accel_max_leaf_size = cin->get().Int();
372
373
else if (tok == Token::Id("object_accel_mb") && cin->trySymbol("="))
374
object_accel_mb = cin->get().Identifier();
375
else if (tok == Token::Id("object_builder_mb") && cin->trySymbol("="))
376
object_builder_mb = cin->get().Identifier();
377
else if (tok == Token::Id("object_accel_mb_min_leaf_size") && cin->trySymbol("="))
378
object_accel_mb_min_leaf_size = cin->get().Int();
379
else if (tok == Token::Id("object_accel_mb_max_leaf_size") && cin->trySymbol("="))
380
object_accel_mb_max_leaf_size = cin->get().Int();
381
382
else if (tok == Token::Id("instancing_open_min") && cin->trySymbol("="))
383
instancing_open_min = cin->get().Int();
384
else if (tok == Token::Id("instancing_block_size") && cin->trySymbol("=")) {
385
instancing_block_size = cin->get().Int();
386
instancing_open_factor = 0.0f;
387
}
388
else if (tok == Token::Id("instancing_open_max_depth") && cin->trySymbol("="))
389
instancing_open_max_depth = cin->get().Int();
390
else if (tok == Token::Id("instancing_open_factor") && cin->trySymbol("=")) {
391
instancing_block_size = 0;
392
instancing_open_factor = cin->get().Float();
393
}
394
else if (tok == Token::Id("instancing_open_max") && cin->trySymbol("="))
395
instancing_open_max = cin->get().Int();
396
397
else if (tok == Token::Id("subdiv_accel") && cin->trySymbol("="))
398
subdiv_accel = cin->get().Identifier();
399
else if (tok == Token::Id("subdiv_accel_mb") && cin->trySymbol("="))
400
subdiv_accel_mb = cin->get().Identifier();
401
402
else if (tok == Token::Id("grid_accel") && cin->trySymbol("="))
403
grid_accel = cin->get().Identifier();
404
else if (tok == Token::Id("grid_accel_mb") && cin->trySymbol("="))
405
grid_accel_mb = cin->get().Identifier();
406
407
else if (tok == Token::Id("verbose") && cin->trySymbol("="))
408
verbose = cin->get().Int();
409
else if (tok == Token::Id("benchmark") && cin->trySymbol("="))
410
benchmark = cin->get().Int();
411
412
else if (tok == Token::Id("quality")) {
413
if (cin->trySymbol("=")) {
414
Token flag = cin->get();
415
if (flag == Token::Id("low")) quality_flags = RTC_BUILD_QUALITY_LOW;
416
else if (flag == Token::Id("medium")) quality_flags = RTC_BUILD_QUALITY_MEDIUM;
417
else if (flag == Token::Id("high")) quality_flags = RTC_BUILD_QUALITY_HIGH;
418
}
419
}
420
421
else if (tok == Token::Id("scene_flags")) {
422
scene_flags = 0;
423
if (cin->trySymbol("=")) {
424
do {
425
Token flag = cin->get();
426
if (flag == Token::Id("dynamic") ) scene_flags |= RTC_SCENE_FLAG_DYNAMIC;
427
else if (flag == Token::Id("compact")) scene_flags |= RTC_SCENE_FLAG_COMPACT;
428
else if (flag == Token::Id("robust")) scene_flags |= RTC_SCENE_FLAG_ROBUST;
429
} while (cin->trySymbol("|"));
430
}
431
}
432
433
else if (tok == Token::Id("max_spatial_split_replications") && cin->trySymbol("="))
434
max_spatial_split_replications = cin->get().Float();
435
436
else if (tok == Token::Id("max_triangles_per_leaf") && cin->trySymbol("="))
437
max_triangles_per_leaf = cin->get().Float();
438
439
else if (tok == Token::Id("presplits") && cin->trySymbol("="))
440
useSpatialPreSplits = cin->get().Int() != 0 ? true : false;
441
442
else if (tok == Token::Id("tessellation_cache_size") && cin->trySymbol("="))
443
tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);
444
else if (tok == Token::Id("cache_size") && cin->trySymbol("="))
445
tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);
446
447
else if (tok == Token::Id("alloc_main_block_size") && cin->trySymbol("="))
448
alloc_main_block_size = cin->get().Int();
449
else if (tok == Token::Id("alloc_num_main_slots") && cin->trySymbol("="))
450
alloc_num_main_slots = cin->get().Int();
451
else if (tok == Token::Id("alloc_thread_block_size") && cin->trySymbol("="))
452
alloc_thread_block_size = cin->get().Int();
453
else if (tok == Token::Id("alloc_single_thread_alloc") && cin->trySymbol("="))
454
alloc_single_thread_alloc = cin->get().Int();
455
456
cin->trySymbol(","); // optional , separator
457
}
458
}
459
460
bool State::verbosity(size_t N) {
461
return N <= verbose;
462
}
463
464
void State::print()
465
{
466
std::cout << "general:" << std::endl;
467
std::cout << " build threads = " << numThreads << std::endl;
468
std::cout << " build user threads = " << numUserThreads << std::endl;
469
std::cout << " start_threads = " << start_threads << std::endl;
470
std::cout << " affinity = " << set_affinity << std::endl;
471
std::cout << " frequency_level = ";
472
switch (frequency_level) {
473
case FREQUENCY_SIMD128: std::cout << "simd128" << std::endl; break;
474
case FREQUENCY_SIMD256: std::cout << "simd256" << std::endl; break;
475
case FREQUENCY_SIMD512: std::cout << "simd512" << std::endl; break;
476
default: std::cout << "error" << std::endl; break;
477
}
478
479
std::cout << " hugepages = ";
480
if (!hugepages) std::cout << "disabled" << std::endl;
481
else if (hugepages_success) std::cout << "enabled" << std::endl;
482
else std::cout << "failed" << std::endl;
483
484
std::cout << " verbosity = " << verbose << std::endl;
485
std::cout << " cache_size = " << float(tessellation_cache_size)*1E-6 << " MB" << std::endl;
486
std::cout << " max_spatial_split_replications = " << max_spatial_split_replications << std::endl;
487
488
std::cout << "triangles:" << std::endl;
489
std::cout << " accel = " << tri_accel << std::endl;
490
std::cout << " builder = " << tri_builder << std::endl;
491
std::cout << " traverser = " << tri_traverser << std::endl;
492
493
std::cout << "motion blur triangles:" << std::endl;
494
std::cout << " accel = " << tri_accel_mb << std::endl;
495
std::cout << " builder = " << tri_builder_mb << std::endl;
496
std::cout << " traverser = " << tri_traverser_mb << std::endl;
497
498
std::cout << "quads:" << std::endl;
499
std::cout << " accel = " << quad_accel << std::endl;
500
std::cout << " builder = " << quad_builder << std::endl;
501
std::cout << " traverser = " << quad_traverser << std::endl;
502
503
std::cout << "motion blur quads:" << std::endl;
504
std::cout << " accel = " << quad_accel_mb << std::endl;
505
std::cout << " builder = " << quad_builder_mb << std::endl;
506
std::cout << " traverser = " << quad_traverser_mb << std::endl;
507
508
std::cout << "line segments:" << std::endl;
509
std::cout << " accel = " << line_accel << std::endl;
510
std::cout << " builder = " << line_builder << std::endl;
511
std::cout << " traverser = " << line_traverser << std::endl;
512
513
std::cout << "motion blur line segments:" << std::endl;
514
std::cout << " accel = " << line_accel_mb << std::endl;
515
std::cout << " builder = " << line_builder_mb << std::endl;
516
std::cout << " traverser = " << line_traverser_mb << std::endl;
517
518
std::cout << "hair:" << std::endl;
519
std::cout << " accel = " << hair_accel << std::endl;
520
std::cout << " builder = " << hair_builder << std::endl;
521
std::cout << " traverser = " << hair_traverser << std::endl;
522
523
std::cout << "motion blur hair:" << std::endl;
524
std::cout << " accel = " << hair_accel_mb << std::endl;
525
std::cout << " builder = " << hair_builder_mb << std::endl;
526
std::cout << " traverser = " << hair_traverser_mb << std::endl;
527
528
std::cout << "subdivision surfaces:" << std::endl;
529
std::cout << " accel = " << subdiv_accel << std::endl;
530
531
std::cout << "grids:" << std::endl;
532
std::cout << " accel = " << grid_accel << std::endl;
533
std::cout << " builder = " << grid_builder << std::endl;
534
535
std::cout << "motion blur grids:" << std::endl;
536
std::cout << " accel = " << grid_accel_mb << std::endl;
537
std::cout << " builder = " << grid_builder_mb << std::endl;
538
539
std::cout << "object_accel:" << std::endl;
540
std::cout << " min_leaf_size = " << object_accel_min_leaf_size << std::endl;
541
std::cout << " max_leaf_size = " << object_accel_max_leaf_size << std::endl;
542
543
std::cout << "object_accel_mb:" << std::endl;
544
std::cout << " min_leaf_size = " << object_accel_mb_min_leaf_size << std::endl;
545
std::cout << " max_leaf_size = " << object_accel_mb_max_leaf_size << std::endl;
546
}
547
}
548
549