| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- // ======================================================================== //
- // Copyright 2009-2017 Intel Corporation //
- // //
- // Licensed under the Apache License, Version 2.0 (the "License"); //
- // you may not use this file except in compliance with the License. //
- // You may obtain a copy of the License at //
- // //
- // http://www.apache.org/licenses/LICENSE-2.0 //
- // //
- // Unless required by applicable law or agreed to in writing, software //
- // distributed under the License is distributed on an "AS IS" BASIS, //
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
- // See the License for the specific language governing permissions and //
- // limitations under the License. //
- // ======================================================================== //
- #include "scene.h"
- #include "../bvh/bvh4_factory.h"
- #include "../bvh/bvh8_factory.h"
-
- namespace embree
- {
- /* error raising rtcIntersect and rtcOccluded functions */
- void missing_rtcCommit() { throw_RTCError(RTC_INVALID_OPERATION,"scene got not committed"); }
- void invalid_rtcIntersect1() { throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect and rtcOccluded not enabled"); }
- void invalid_rtcIntersect4() { throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect4 and rtcOccluded4 not enabled"); }
- void invalid_rtcIntersect8() { throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect8 and rtcOccluded8 not enabled"); }
- void invalid_rtcIntersect16() { throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect16 and rtcOccluded16 not enabled"); }
- void invalid_rtcIntersectN() { throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersectN and rtcOccludedN not enabled"); }
- Scene::Scene (Device* device, RTCSceneFlags sflags, RTCAlgorithmFlags aflags)
- : Accel(AccelData::TY_UNKNOWN),
- device(device),
- commitCounterSubdiv(0),
- numMappedBuffers(0),
- flags(sflags), aflags(aflags),
- needTriangleIndices(false), needTriangleVertices(false),
- needQuadIndices(false), needQuadVertices(false),
- needBezierIndices(false), needBezierVertices(false),
- needLineIndices(false), needLineVertices(false),
- needSubdivIndices(false), needSubdivVertices(false),
- is_build(false), modified(true),
- progressInterface(this), progress_monitor_function(nullptr), progress_monitor_ptr(nullptr), progress_monitor_counter(0),
- numIntersectionFilters1(0), numIntersectionFilters4(0), numIntersectionFilters8(0), numIntersectionFilters16(0), numIntersectionFiltersN(0)
- {
- #if defined(TASKING_INTERNAL)
- scheduler = nullptr;
- #elif defined(TASKING_TBB)
- group = new tbb::task_group;
- #elif defined(TASKING_PPL)
- group = new concurrency::task_group;
- #endif
- intersectors = Accel::Intersectors(missing_rtcCommit);
- if (device->scene_flags != -1)
- flags = (RTCSceneFlags) device->scene_flags;
- if (aflags & RTC_INTERPOLATE) {
- needTriangleIndices = true;
- needQuadIndices = true;
- needBezierIndices = true;
- needLineIndices = true;
- //needSubdivIndices = true; // not required for interpolation
- needTriangleVertices = true;
- needQuadVertices = true;
- needBezierVertices = true;
- needLineVertices = true;
- needSubdivVertices = true;
- }
- createTriangleAccel();
- createTriangleMBAccel();
- createQuadAccel();
- createQuadMBAccel();
- createSubdivAccel();
- createSubdivMBAccel();
- createHairAccel();
- createHairMBAccel();
- createLineAccel();
- createLineMBAccel();
- #if defined(EMBREE_GEOMETRY_TRIANGLES)
- accels.add(device->bvh4_factory->BVH4InstancedBVH4Triangle4ObjectSplit(this));
- #endif
- // has to be the last as the instID field of a hit instance is not invalidated by other hit geometry
- createUserGeometryAccel();
- createUserGeometryMBAccel();
- }
- void Scene::createTriangleAccel()
- {
- #if defined(EMBREE_GEOMETRY_TRIANGLES)
- if (device->tri_accel == "default")
- {
- if (isStatic()) {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- {
- if (isHighQuality())
- accels.add(device->bvh8_factory->BVH8Triangle4(this,BVH8Factory::BuildVariant::HIGH_QUALITY,BVH8Factory::IntersectVariant::FAST));
- else
- accels.add(device->bvh8_factory->BVH8Triangle4(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::FAST));
- }
- else
- #endif
- {
- if (isHighQuality())
- accels.add(device->bvh4_factory->BVH4Triangle4(this,BVH4Factory::BuildVariant::HIGH_QUALITY,BVH4Factory::IntersectVariant::FAST));
- else
- accels.add(device->bvh4_factory->BVH4Triangle4(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST));
- }
- break;
- case /*0b01*/ 1:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Triangle4v(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::ROBUST));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Triangle4v(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST));
- break;
- case /*0b10*/ 2:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Triangle4i(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::FAST ));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Triangle4i(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST ));
- break;
- case /*0b11*/ 3:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Triangle4i(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::ROBUST));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Triangle4i(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST));
- break;
- }
- }
- else /* dynamic */
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh8_factory->BVH8Triangle4 (this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::FAST )); break;
- case /*0b01*/ 1: accels.add(device->bvh8_factory->BVH8Triangle4v(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh8_factory->BVH8Triangle4i(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::FAST )); break;
- case /*0b11*/ 3: accels.add(device->bvh8_factory->BVH8Triangle4i(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::ROBUST)); break;
- }
- }
- else
- #endif
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh4_factory->BVH4Triangle4 (this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b01*/ 1: accels.add(device->bvh4_factory->BVH4Triangle4v(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Triangle4i(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Triangle4i(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- }
- }
- else if (device->tri_accel == "bvh4.triangle4") accels.add(device->bvh4_factory->BVH4Triangle4 (this));
- else if (device->tri_accel == "bvh4.triangle4v") accels.add(device->bvh4_factory->BVH4Triangle4v(this));
- else if (device->tri_accel == "bvh4.triangle4i") accels.add(device->bvh4_factory->BVH4Triangle4i(this));
- else if (device->tri_accel == "qbvh4.triangle4i") accels.add(device->bvh4_factory->BVH4QuantizedTriangle4i(this));
- #if defined (__TARGET_AVX__)
- else if (device->tri_accel == "bvh8.triangle4") accels.add(device->bvh8_factory->BVH8Triangle4 (this));
- else if (device->tri_accel == "bvh8.triangle4i") accels.add(device->bvh8_factory->BVH8Triangle4i(this));
- else if (device->tri_accel == "qbvh8.triangle4i") accels.add(device->bvh8_factory->BVH8QuantizedTriangle4i(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown triangle acceleration structure "+device->tri_accel);
- #endif
- }
- void Scene::createTriangleMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_TRIANGLES)
- if (device->tri_accel_mb == "default")
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
-
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX2)) // BVH8 reduces performance on AVX only-machines
- {
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh8_factory->BVH8Triangle4iMB(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::FAST )); break;
- case /*0b01*/ 1: accels.add(device->bvh8_factory->BVH8Triangle4iMB(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- else
- #endif
- {
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b01*/ 1: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Triangle4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- }
- else if (device->tri_accel_mb == "bvh4.triangle4vmb") accels.add(device->bvh4_factory->BVH4Triangle4vMB(this));
- else if (device->tri_accel_mb == "bvh4.triangle4imb") accels.add(device->bvh4_factory->BVH4Triangle4iMB(this));
- #if defined (__TARGET_AVX__)
- else if (device->tri_accel_mb == "bvh8.triangle4vmb") accels.add(device->bvh8_factory->BVH8Triangle4vMB(this));
- else if (device->tri_accel_mb == "bvh8.triangle4imb") accels.add(device->bvh8_factory->BVH8Triangle4iMB(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown motion blur triangle acceleration structure "+device->tri_accel_mb);
- #endif
- }
- void Scene::createQuadAccel()
- {
- #if defined(EMBREE_GEOMETRY_QUADS)
- if (device->quad_accel == "default")
- {
- if (isStatic())
- {
- /* static */
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- {
- if (isHighQuality())
- accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::HIGH_QUALITY,BVH8Factory::IntersectVariant::FAST));
- else
- accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::FAST));
- }
- else
- #endif
- {
- if (isHighQuality())
- accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::HIGH_QUALITY,BVH4Factory::IntersectVariant::FAST));
- else
- accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST));
- }
- break;
- case /*0b01*/ 1:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::ROBUST));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST));
- break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Quad4i(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST)); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Quad4i(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- else /* dynamic */
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::FAST)); break;
- case /*0b01*/ 1: accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::FAST)); break;
- case /*0b11*/ 3: accels.add(device->bvh8_factory->BVH8Quad4v(this,BVH8Factory::BuildVariant::DYNAMIC,BVH8Factory::IntersectVariant::ROBUST)); break;
- }
- }
- else
- #endif
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::FAST)); break;
- case /*0b01*/ 1: accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::FAST)); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Quad4v(this,BVH4Factory::BuildVariant::DYNAMIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- }
- }
- else if (device->quad_accel == "bvh4.quad4v") accels.add(device->bvh4_factory->BVH4Quad4v(this));
- else if (device->quad_accel == "bvh4.quad4i") accels.add(device->bvh4_factory->BVH4Quad4i(this));
- else if (device->quad_accel == "qbvh4.quad4i") accels.add(device->bvh4_factory->BVH4QuantizedQuad4i(this));
- #if defined (__TARGET_AVX__)
- else if (device->quad_accel == "bvh8.quad4v") accels.add(device->bvh8_factory->BVH8Quad4v(this));
- else if (device->quad_accel == "bvh8.quad4i") accels.add(device->bvh8_factory->BVH8Quad4i(this));
- else if (device->quad_accel == "qbvh8.quad4i") accels.add(device->bvh8_factory->BVH8QuantizedQuad4i(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown quad acceleration structure "+device->quad_accel);
- #endif
- }
- void Scene::createQuadMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_QUADS)
- if (device->quad_accel_mb == "default")
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- switch (mode) {
- case /*0b00*/ 0:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Quad4iMB(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::FAST));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Quad4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST));
- break;
- case /*0b01*/ 1:
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX))
- accels.add(device->bvh8_factory->BVH8Quad4iMB(this,BVH8Factory::BuildVariant::STATIC,BVH8Factory::IntersectVariant::ROBUST));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Quad4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST));
- break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Quad4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::FAST )); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Quad4iMB(this,BVH4Factory::BuildVariant::STATIC,BVH4Factory::IntersectVariant::ROBUST)); break;
- }
- }
- else if (device->quad_accel_mb == "bvh4.quad4imb") accels.add(device->bvh4_factory->BVH4Quad4iMB(this));
- #if defined (__TARGET_AVX__)
- else if (device->quad_accel_mb == "bvh8.quad4imb") accels.add(device->bvh8_factory->BVH8Quad4iMB(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown quad acceleration structure "+device->quad_accel_mb);
- #endif
- }
- void Scene::createHairAccel()
- {
- #if defined(EMBREE_GEOMETRY_HAIR)
- if (device->hair_accel == "default")
- {
- int mode = 2*(int)isCompact() + 1*(int)isRobust();
- if (isStatic())
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX2)) // only enable on HSW machines, for SNB this codepath is slower
- {
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh8_factory->BVH8OBBBezier1v(this)); break;
- case /*0b01*/ 1: accels.add(device->bvh8_factory->BVH8OBBBezier1v(this)); break;
- case /*0b10*/ 2: accels.add(device->bvh8_factory->BVH8OBBBezier1i(this)); break;
- case /*0b11*/ 3: accels.add(device->bvh8_factory->BVH8OBBBezier1i(this)); break;
- }
- }
- else
- #endif
- {
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh4_factory->BVH4OBBBezier1v(this)); break;
- case /*0b01*/ 1: accels.add(device->bvh4_factory->BVH4OBBBezier1v(this)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4OBBBezier1i(this)); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4OBBBezier1i(this)); break;
- }
- }
- }
- else
- {
- switch (mode) {
- case /*0b00*/ 0: accels.add(device->bvh4_factory->BVH4Bezier1v(this)); break;
- case /*0b01*/ 1: accels.add(device->bvh4_factory->BVH4Bezier1v(this)); break;
- case /*0b10*/ 2: accels.add(device->bvh4_factory->BVH4Bezier1i(this)); break;
- case /*0b11*/ 3: accels.add(device->bvh4_factory->BVH4Bezier1i(this)); break;
- }
- }
- }
- else if (device->hair_accel == "bvh4.bezier1v" ) accels.add(device->bvh4_factory->BVH4Bezier1v(this));
- else if (device->hair_accel == "bvh4.bezier1i" ) accels.add(device->bvh4_factory->BVH4Bezier1i(this));
- else if (device->hair_accel == "bvh4obb.bezier1v" ) accels.add(device->bvh4_factory->BVH4OBBBezier1v(this));
- else if (device->hair_accel == "bvh4obb.bezier1i" ) accels.add(device->bvh4_factory->BVH4OBBBezier1i(this));
- #if defined (__TARGET_AVX__)
- else if (device->hair_accel == "bvh8obb.bezier1v" ) accels.add(device->bvh8_factory->BVH8OBBBezier1v(this));
- else if (device->hair_accel == "bvh8obb.bezier1i" ) accels.add(device->bvh8_factory->BVH8OBBBezier1i(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown hair acceleration structure "+device->hair_accel);
- #endif
- }
- void Scene::createHairMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_HAIR)
- if (device->hair_accel_mb == "default")
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX2)) // only enable on HSW machines, on SNB this codepath is slower
- {
- accels.add(device->bvh8_factory->BVH8OBBBezier1iMB(this));
- }
- else
- #endif
- {
- accels.add(device->bvh4_factory->BVH4OBBBezier1iMB(this));
- }
- }
- else if (device->hair_accel_mb == "bvh4obb.bezier1imb") accels.add(device->bvh4_factory->BVH4OBBBezier1iMB(this));
- #if defined (__TARGET_AVX__)
- else if (device->hair_accel_mb == "bvh8obb.bezier1imb") accels.add(device->bvh8_factory->BVH8OBBBezier1iMB(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown motion blur hair acceleration structure "+device->tri_accel_mb);
- #endif
- }
- void Scene::createLineAccel()
- {
- #if defined(EMBREE_GEOMETRY_LINES)
- if (device->line_accel == "default")
- {
- if (isStatic())
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX) && !isCompact())
- accels.add(device->bvh8_factory->BVH8Line4i(this));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Line4i(this,BVH4Factory::BuildVariant::STATIC));
- }
- else
- {
- accels.add(device->bvh4_factory->BVH4Line4i(this,BVH4Factory::BuildVariant::DYNAMIC));
- }
- }
- else if (device->line_accel == "bvh4.line4i") accels.add(device->bvh4_factory->BVH4Line4i(this));
- #if defined (__TARGET_AVX__)
- else if (device->line_accel == "bvh8.line4i") accels.add(device->bvh8_factory->BVH8Line4i(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown line segment acceleration structure "+device->line_accel);
- #endif
- }
- void Scene::createLineMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_LINES)
- if (device->line_accel_mb == "default")
- {
- #if defined (__TARGET_AVX__)
- if (device->hasISA(AVX) && !isCompact())
- accels.add(device->bvh8_factory->BVH8Line4iMB(this));
- else
- #endif
- accels.add(device->bvh4_factory->BVH4Line4iMB(this));
- }
- else if (device->line_accel_mb == "bvh4.line4imb") accels.add(device->bvh4_factory->BVH4Line4iMB(this));
- #if defined (__TARGET_AVX__)
- else if (device->line_accel_mb == "bvh8.line4imb") accels.add(device->bvh8_factory->BVH8Line4iMB(this));
- #endif
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown motion blur line segment acceleration structure "+device->line_accel_mb);
- #endif
- }
- void Scene::createSubdivAccel()
- {
- #if defined(EMBREE_GEOMETRY_SUBDIV)
- if (device->subdiv_accel == "default")
- {
- if (isIncoherent(flags) && isStatic())
- accels.add(device->bvh4_factory->BVH4SubdivPatch1Eager(this));
- else
- accels.add(device->bvh4_factory->BVH4SubdivPatch1(this,true));
- }
- else if (device->subdiv_accel == "bvh4.subdivpatch1eager" ) accels.add(device->bvh4_factory->BVH4SubdivPatch1Eager(this));
- else if (device->subdiv_accel == "bvh4.subdivpatch1" ) accels.add(device->bvh4_factory->BVH4SubdivPatch1(this,false));
- else if (device->subdiv_accel == "bvh4.subdivpatch1cached") accels.add(device->bvh4_factory->BVH4SubdivPatch1(this,true));
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown subdiv accel "+device->subdiv_accel);
- #endif
- }
- void Scene::createSubdivMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_SUBDIV)
- if (device->subdiv_accel_mb == "default")
- {
- if (isIncoherent(flags) && isStatic())
- accels.add(device->bvh4_factory->BVH4SubdivPatch1MBlur(this,false));
- else
- accels.add(device->bvh4_factory->BVH4SubdivPatch1MBlur(this,true));
- }
- else if (device->subdiv_accel_mb == "bvh4.subdivpatch1" ) accels.add(device->bvh4_factory->BVH4SubdivPatch1MBlur(this,false));
- else if (device->subdiv_accel_mb == "bvh4.subdivpatch1cached") accels.add(device->bvh4_factory->BVH4SubdivPatch1MBlur(this,true));
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown subdiv mblur accel "+device->subdiv_accel_mb);
- #endif
- }
- void Scene::createUserGeometryAccel()
- {
- #if defined(EMBREE_GEOMETRY_USER)
- if (device->object_accel == "default")
- {
- if (isStatic()) {
- accels.add(device->bvh4_factory->BVH4UserGeometry(this,BVH4Factory::BuildVariant::STATIC));
- } else {
- accels.add(device->bvh4_factory->BVH4UserGeometry(this,BVH4Factory::BuildVariant::DYNAMIC));
- }
- }
- else if (device->object_accel == "bvh4.object") accels.add(device->bvh4_factory->BVH4UserGeometry(this));
- else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown user geometry accel "+device->object_accel);
- #endif
- }
- void Scene::createUserGeometryMBAccel()
- {
- #if defined(EMBREE_GEOMETRY_USER)
- accels.add(device->bvh4_factory->BVH4UserGeometryMB(this));
- #endif
- }
-
- Scene::~Scene ()
- {
- for (size_t i=0; i<geometries.size(); i++)
- delete geometries[i];
- #if defined(TASKING_TBB) || defined(TASKING_PPL)
- delete group; group = nullptr;
- #endif
- }
- void Scene::clear() {
- }
- #if defined(EMBREE_GEOMETRY_USER)
- unsigned Scene::newUserGeometry (RTCGeometryFlags gflags, size_t items, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
- return add(new UserGeometry(this,gflags,items,numTimeSteps));
- }
- unsigned Scene::newInstance (Scene* scene, size_t numTimeSteps)
- {
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
- return add(Instance::create(this,scene,numTimeSteps));
- }
- #endif
- unsigned Scene::newGeometryInstance (Geometry* geom_in)
- {
- Geometry* geom = new GeometryInstance(this,geom_in);
- unsigned id = add(geom);
- geom->id = id;
- return id;
- }
- #if defined(EMBREE_GEOMETRY_TRIANGLES)
- unsigned Scene::newTriangleMesh (RTCGeometryFlags gflags, size_t numTriangles, size_t numVertices, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
-
- return add(new TriangleMesh(this,gflags,numTriangles,numVertices,numTimeSteps));
- }
- #endif
- #if defined(EMBREE_GEOMETRY_QUADS)
- unsigned Scene::newQuadMesh (RTCGeometryFlags gflags, size_t numQuads, size_t numVertices, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
-
- return add(new QuadMesh(this,gflags,numQuads,numVertices,numTimeSteps));
- }
- #endif
- #if defined(EMBREE_GEOMETRY_SUBDIV)
- unsigned Scene::newSubdivisionMesh (RTCGeometryFlags gflags, size_t numFaces, size_t numEdges, size_t numVertices, size_t numEdgeCreases, size_t numVertexCreases, size_t numHoles, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
- #if defined(__TARGET_AVX__)
- if (device->hasISA(AVX))
- return add(new SubdivMeshAVX(this,gflags,numFaces,numEdges,numVertices,numEdgeCreases,numVertexCreases,numHoles,numTimeSteps));
- else
- #endif
- return add(new SubdivMesh(this,gflags,numFaces,numEdges,numVertices,numEdgeCreases,numVertexCreases,numHoles,numTimeSteps));
- }
- #endif
- #if defined(EMBREE_GEOMETRY_HAIR)
- unsigned Scene::newCurves (NativeCurves::SubType subtype, NativeCurves::Basis basis, RTCGeometryFlags gflags, size_t numCurves, size_t numVertices, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
-
- Geometry* geom = nullptr;
- #if defined(EMBREE_NATIVE_CURVE_BSPLINE)
- switch (basis) {
- case NativeCurves::BEZIER : geom = new CurvesBezier(this,subtype,basis,gflags,numCurves,numVertices,numTimeSteps); break;
- case NativeCurves::BSPLINE: geom = new NativeCurves(this,subtype,basis,gflags,numCurves,numVertices,numTimeSteps); break;
- }
- #else
- switch (basis) {
- case NativeCurves::BEZIER : geom = new NativeCurves (this,subtype,basis,gflags,numCurves,numVertices,numTimeSteps); break;
- case NativeCurves::BSPLINE: geom = new CurvesBSpline(this,subtype,basis,gflags,numCurves,numVertices,numTimeSteps); break;
- }
- #endif
- return add(geom);
- }
- #endif
- #if defined(EMBREE_GEOMETRY_LINES)
- unsigned Scene::newLineSegments (RTCGeometryFlags gflags, size_t numSegments, size_t numVertices, size_t numTimeSteps)
- {
- if (isStatic() && (gflags != RTC_GEOMETRY_STATIC)) {
- throw_RTCError(RTC_INVALID_OPERATION,"static scenes can only contain static geometries");
- return -1;
- }
- if (numTimeSteps == 0 || numTimeSteps > RTC_MAX_TIME_STEPS) {
- throw_RTCError(RTC_INVALID_OPERATION,"maximal number of timesteps exceeded");
- return -1;
- }
- return add(new LineSegments(this,gflags,numSegments,numVertices,numTimeSteps));
- }
- #endif
- unsigned Scene::add(Geometry* geometry)
- {
- Lock<SpinLock> lock(geometriesMutex);
- unsigned id = id_pool.allocate();
- if (id >= geometries.size())
- geometries.resize(id+1);
- geometries[id] = geometry;
- geometry->id = id;
- return id;
- }
- void Scene::deleteGeometry(size_t geomID)
- {
- Lock<SpinLock> lock(geometriesMutex);
-
- if (isStatic())
- throw_RTCError(RTC_INVALID_OPERATION,"rtcDeleteGeometry cannot get called in static scenes");
- if (geomID >= geometries.size())
- throw_RTCError(RTC_INVALID_OPERATION,"invalid geometry ID");
- Geometry* geometry = geometries[geomID];
- if (geometry == nullptr)
- throw_RTCError(RTC_INVALID_OPERATION,"invalid geometry");
-
- geometry->disable();
- accels.deleteGeometry(unsigned(geomID));
- id_pool.deallocate((unsigned)geomID);
- geometries[geomID] = nullptr;
- delete geometry;
- }
- void Scene::updateInterface()
- {
- /* update bounds */
- is_build = true;
- bounds = accels.bounds;
- intersectors = accels.intersectors;
- /* enable only algorithms choosen by application */
- if ((aflags & RTC_INTERSECT_STREAM) == 0)
- {
- intersectors.intersectorN = Accel::IntersectorN(&invalid_rtcIntersectN);
- if ((aflags & RTC_INTERSECT1) == 0) intersectors.intersector1 = Accel::Intersector1(&invalid_rtcIntersect1);
- if ((aflags & RTC_INTERSECT4) == 0) intersectors.intersector4 = Accel::Intersector4(&invalid_rtcIntersect4);
- if ((aflags & RTC_INTERSECT8) == 0) intersectors.intersector8 = Accel::Intersector8(&invalid_rtcIntersect8);
- if ((aflags & RTC_INTERSECT16) == 0) intersectors.intersector16 = Accel::Intersector16(&invalid_rtcIntersect16);
- }
- }
- void Scene::commit_task ()
- {
- progress_monitor_counter = 0;
- /* call preCommit function of each geometry */
- parallel_for(geometries.size(), [&] ( const size_t i ) {
- if (geometries[i]) geometries[i]->preCommit();
- });
- /* select fast code path if no intersection filter is present */
- accels.select(numIntersectionFiltersN+numIntersectionFilters4,
- numIntersectionFiltersN+numIntersectionFilters8,
- numIntersectionFiltersN+numIntersectionFilters16,
- numIntersectionFiltersN);
-
- /* build all hierarchies of this scene */
- accels.build();
- /* make static geometry immutable */
- if (isStatic()) accels.immutable();
- /* call postCommit function of each geometry */
- parallel_for(geometries.size(), [&] ( const size_t i ) {
- if (geometries[i]) geometries[i]->postCommit();
- });
-
- updateInterface();
- if (device->verbosity(2)) {
- std::cout << "created scene intersector" << std::endl;
- accels.print(2);
- std::cout << "selected scene intersector" << std::endl;
- intersectors.print(2);
- }
-
- setModified(false);
- }
- #if defined(TASKING_INTERNAL)
- void Scene::commit (size_t threadIndex, size_t threadCount, bool useThreadPool)
- {
- Lock<MutexSys> buildLock(buildMutex,false);
- /* allocates own taskscheduler for each build */
- Ref<TaskScheduler> scheduler = nullptr;
- {
- Lock<MutexSys> lock(schedulerMutex);
- scheduler = this->scheduler;
- if (scheduler == null) {
- buildLock.lock();
- this->scheduler = scheduler = new TaskScheduler;
- }
- }
- /* worker threads join build */
- if (!buildLock.isLocked()) {
- scheduler->join();
- return;
- }
- /* wait for all threads in rtcCommitThread mode */
- if (threadCount != 0)
- scheduler->wait_for_threads(threadCount);
- /* fast path for unchanged scenes */
- if (!isModified()) {
- scheduler->spawn_root([&]() { this->scheduler = nullptr; }, 1, useThreadPool);
- return;
- }
- /* report error if scene not ready */
- if (!ready()) {
- scheduler->spawn_root([&]() { this->scheduler = nullptr; }, 1, useThreadPool);
- throw_RTCError(RTC_INVALID_OPERATION,"not all buffers are unmapped");
- }
- /* initiate build */
- try {
- scheduler->spawn_root([&]() { commit_task(); this->scheduler = nullptr; }, 1, useThreadPool);
- }
- catch (...) {
- accels.clear();
- updateInterface();
- throw;
- }
- }
- #endif
- #if defined(TASKING_TBB) || defined(TASKING_PPL)
- void Scene::commit (size_t threadIndex, size_t threadCount, bool useThreadPool)
- {
- /* let threads wait for build to finish in rtcCommitThread mode */
- if (threadCount != 0) {
- #if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION_MAJOR < 8)
- throw_RTCError(RTC_INVALID_OPERATION,"rtcCommitThread not supported");
- #endif
- if (threadIndex > 0) {
- group_barrier.wait(threadCount); // FIXME: use barrier that waits in condition
- group->wait();
- return;
- }
- }
- /* try to obtain build lock */
- Lock<MutexSys> lock(buildMutex,buildMutex.try_lock());
- /* join hierarchy build */
- if (!lock.isLocked()) {
- #if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION_MAJOR < 8)
- throw_RTCError(RTC_INVALID_OPERATION,"join not supported");
- #endif
- #if USE_TASK_ARENA
- device->arena->execute([&]{ group->wait(); });
- #else
- group->wait();
- #endif
- while (!buildMutex.try_lock()) {
- __pause_cpu();
- yield();
- #if USE_TASK_ARENA
- device->arena->execute([&]{ group->wait(); });
- #else
- group->wait();
- #endif
- }
- buildMutex.unlock();
- return;
- }
- if (!isModified()) {
- if (threadCount) group_barrier.wait(threadCount);
- return;
- }
- if (!ready()) {
- if (threadCount) group_barrier.wait(threadCount);
- throw_RTCError(RTC_INVALID_OPERATION,"not all buffers are unmapped");
- return;
- }
- /* for best performance set FTZ and DAZ flags in the MXCSR control and status register */
- unsigned int mxcsr = _mm_getcsr();
- _mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6));
-
- try {
- #if defined(TASKING_TBB)
- #if TBB_INTERFACE_VERSION_MAJOR < 8
- tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits);
- #else
- tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits | tbb::task_group_context::fp_settings );
- #endif
- //ctx.set_priority(tbb::priority_high);
- #if USE_TASK_ARENA
- device->arena->execute([&]{
- #endif
- group->run([&]{
- tbb::parallel_for (size_t(0), size_t(1), size_t(1), [&] (size_t) { commit_task(); }, ctx);
- });
- if (threadCount) group_barrier.wait(threadCount);
- group->wait();
- #if USE_TASK_ARENA
- });
- #endif
-
- /* reset MXCSR register again */
- _mm_setcsr(mxcsr);
- #else
- group->run([&]{
- concurrency::parallel_for(size_t(0), size_t(1), size_t(1), [&](size_t) { commit_task(); });
- });
- if (threadCount) group_barrier.wait(threadCount);
- group->wait();
- #endif
- }
- catch (...) {
- /* reset MXCSR register again */
- _mm_setcsr(mxcsr);
-
- accels.clear();
- updateInterface();
- throw;
- }
- }
- #endif
- void Scene::setProgressMonitorFunction(RTCProgressMonitorFunc func, void* ptr)
- {
- static MutexSys mutex;
- mutex.lock();
- progress_monitor_function = func;
- progress_monitor_ptr = ptr;
- mutex.unlock();
- }
- void Scene::progressMonitor(double dn)
- {
- if (progress_monitor_function) {
- size_t n = size_t(dn) + progress_monitor_counter.fetch_add(size_t(dn));
- if (!progress_monitor_function(progress_monitor_ptr, n / (double(numPrimitives())))) {
- throw_RTCError(RTC_CANCELLED,"progress monitor forced termination");
- }
- }
- }
- }
|