// ======================================================================== // // Copyright 2009-2014 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 "sys/platform.h" #include "sys/ref.h" #include "sys/thread.h" #include "sys/sysinfo.h" #include "sys/sync/barrier.h" #include "sys/sync/mutex.h" #include "sys/sync/condition.h" #include "math/vec3.h" #include "math/bbox.h" #include "embree2/rtcore.h" #include "embree2/rtcore_ray.h" #include "../kernels/common/default.h" #include //#define DEFAULT_STACK_SIZE 2*1024*1024 //#define DEFAULT_STACK_SIZE 512*1024 #define DEFAULT_STACK_SIZE 0 namespace embree { #if !defined(__MIC__) RTCAlgorithmFlags aflags = (RTCAlgorithmFlags) (RTC_INTERSECT1 | RTC_INTERSECT4 | RTC_INTERSECT8); #else RTCAlgorithmFlags aflags = (RTCAlgorithmFlags) (RTC_INTERSECT1 | RTC_INTERSECT16); #endif /* configuration */ static std::string g_rtcore = ""; static size_t testN = 100000; //static size_t testN = 10000000; static size_t regressionN = 200; /* vertex and triangle layout */ struct Vertex { float x,y,z,a; }; #if defined(__MIC__) typedef Vec3fa Vertex3f; typedef Vec3fa Vertex3fa; #else typedef Vec3f Vertex3f; typedef Vec3fa Vertex3fa; #endif struct Triangle { int v0, v1, v2; }; std::vector g_threads; size_t numFailedTests = 0; atomic_t errorCounter = 0; #if defined(__WIN32__) # define GREEN(x) x # define RED(x) x #else # define GREEN(x) "\033[32m" x "\033[0m" # define RED(x) "\033[31m" x "\033[0m" #endif #define CountErrors() \ if (rtcGetError() != RTC_NO_ERROR) atomic_add(&errorCounter,1); #define AssertNoError() \ if (rtcGetError() != RTC_NO_ERROR) return false; #define AssertAnyError() \ if (rtcGetError() == RTC_NO_ERROR) return false; #define AssertError(code) \ if (rtcGetError() != code) return false; #define POSITIVE(name,test) { \ printf("%30s ...",name); \ bool ok = test; \ printf(" %s\n",ok ? GREEN("[PASSED]") : RED("[FAILED]")); \ fflush(stdout); \ numFailedTests += !ok; \ } #define NEGATIVE(name,test) { \ printf("%30s ... ",name); \ bool notok = test; \ printf(" %s\n",notok ? RED("[FAILED]") : GREEN("[PASSED]")); \ fflush(stdout); \ numFailedTests += notok; \ } const size_t numSceneFlags = 64; std::vector buffers; MutexSys g_mutex2; void* allocBuffer(size_t size) { g_mutex2.lock(); void* ptr = alignedMalloc(size); buffers.push_back(ptr); g_mutex2.unlock(); return ptr; } void clearBuffers() { for (size_t i=0; i= argc) THROW_RUNTIME_ERROR("command line parsing error"); regressionN = atoi(argv[++i]); } /* skip unknown command line parameter */ else { std::cerr << "unknown command line parameter: " << tag << " "; std::cerr << std::endl; } } } unsigned addPlane (RTCScene scene, RTCGeometryFlags flag, size_t num, const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy) { unsigned mesh = rtcNewTriangleMesh (scene, flag, 2*num*num, (num+1)*(num+1)); Vertex3fa* vertices = (Vertex3fa*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER); Triangle* triangles = (Triangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); for (size_t y=0; y<=num; y++) { for (size_t x=0; x<=num; x++) { Vec3fa p = p0+float(x)/float(num)*dx+float(y)/float(num)*dy; size_t i = y*(num+1)+x; vertices[i].x = p.x; vertices[i].y = p.y; vertices[i].z = p.z; } } for (size_t y=0; y= 1) rtcSetBuffer(scene,mesh,RTC_VERTEX_BUFFER0,vertices0 = (Vertex3f*) allocBuffer(numVertices*sizeof(Vertex3f)), 0, sizeof(Vertex3f)); if (numTimeSteps >= 2) rtcSetBuffer(scene,mesh,RTC_VERTEX_BUFFER1,vertices1 = (Vertex3f*) allocBuffer(numVertices*sizeof(Vertex3f)), 0, sizeof(Vertex3f)); Triangle* triangles = (Triangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); /* create sphere geometry */ size_t tri = 0; const float rcpNumTheta = 1.0f/float(numTheta); const float rcpNumPhi = 1.0f/float(numPhi); for (size_t phi=0; phi<=numPhi; phi++) { for (size_t theta=0; thetax = pos.x + r*sin(phif)*sin(thetaf); v->y = pos.y + r*cos(phif); v->z = pos.z + r*sin(phif)*cosThetaf; if (vertices1) { Vertex3f* v1 = &vertices1[phi*numTheta+theta]; const float cosThetaf = cos(thetaf); v1->x = motion + pos.x + r*sin(phif)*sin(thetaf); v1->y = motion + pos.y + r*cos(phif); v1->z = motion + pos.z + r*sin(phif)*cosThetaf; } } if (phi == 0) continue; for (size_t theta=1; theta<=numTheta; theta++) { int p00 = (phi-1)*numTheta+theta-1; int p01 = (phi-1)*numTheta+theta%numTheta; int p10 = phi*numTheta+theta-1; int p11 = phi*numTheta+theta%numTheta; if (phi > 1) { if (tri < numTriangles) { triangles[tri].v0 = p10; triangles[tri].v1 = p00; triangles[tri].v2 = p01; tri++; } } if (phi < numPhi) { if (tri < numTriangles) { triangles[tri].v0 = p11; triangles[tri].v1 = p10; triangles[tri].v2 = p01; tri++; } } } } //if (numTimeSteps >= 1) rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER0); //if (numTimeSteps >= 2) rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER1); rtcUnmapBuffer(scene,mesh,RTC_INDEX_BUFFER); return mesh; } /* adds a subdiv sphere to the scene */ unsigned int addSubdivSphere (RTCScene scene, RTCGeometryFlags flags, const Vec3fa& pos, const float r, size_t numPhi, float level, size_t maxFaces = -1, float motion = 0.0f) { size_t numTheta = 2*numPhi; vector_t vertices(numTheta*(numPhi+1)); std::vector indices; std::vector faces; std::vector offsets; /* create sphere geometry */ const float rcpNumTheta = rcp((float)numTheta); const float rcpNumPhi = rcp((float)numPhi); for (int phi=0; phi<=numPhi; phi++) { for (int theta=0; theta= 1) vertices0 = (Vec3fa*) rtcMapBuffer(scene,geomID,RTC_VERTEX_BUFFER0); if (numTimeSteps >= 2) vertices1 = (Vec3fa*) rtcMapBuffer(scene,geomID,RTC_VERTEX_BUFFER1); int* indices = (int*) rtcMapBuffer(scene,geomID,RTC_INDEX_BUFFER); for (size_t i=0; i= 1) rtcUnmapBuffer(scene,geomID,RTC_VERTEX_BUFFER0); if (numTimeSteps >= 2) rtcUnmapBuffer(scene,geomID,RTC_VERTEX_BUFFER1); rtcUnmapBuffer(scene,geomID,RTC_INDEX_BUFFER); return geomID; } unsigned addGarbageTriangles (RTCScene scene, RTCGeometryFlags flag, size_t numTriangles, bool motion) { /* create a triangulated sphere */ size_t numTimeSteps = motion ? 1 : 2; unsigned mesh = rtcNewTriangleMesh (scene, flag, numTriangles, 3*numTriangles,numTimeSteps); /* map triangle and vertex buffer */ if (numTimeSteps >= 1) { int* v = (int*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER0); for (size_t i=0; i<4*3*numTriangles; i++) v[i] = rand(); rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER0); } if (numTimeSteps >= 2) { int* v = (int*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER1); for (size_t i=0; i<4*3*numTriangles; i++) v[i] = rand(); rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER1); } Triangle* triangles = (Triangle*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); for (size_t i=0; i= 1) { int* v = (int*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER0); for (size_t i=0; i<4*4*numCurves; i++) v[i] = rand(); rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER0); } if (numTimeSteps >= 2) { int* v = (int*) rtcMapBuffer(scene,mesh,RTC_VERTEX_BUFFER1); for (size_t i=0; i<4*4*numCurves; i++) v[i] = rand(); rtcUnmapBuffer(scene,mesh,RTC_VERTEX_BUFFER1); } int* curves = (int*) rtcMapBuffer(scene,mesh,RTC_INDEX_BUFFER); for (size_t i=0; ilower.x = sphere->pos.x-sphere->r; bounds_o->lower.y = sphere->pos.y-sphere->r; bounds_o->lower.z = sphere->pos.z-sphere->r; bounds_o->upper.x = sphere->pos.x+sphere->r; bounds_o->upper.y = sphere->pos.y+sphere->r; bounds_o->upper.z = sphere->pos.z+sphere->r; } void IntersectFunc(void* ptr, RTCRay& ray, size_t item) { } void IntersectFunc4(const void* valid, void* ptr, RTCRay4& ray, size_t item) { } void IntersectFunc8(const void* valid, void* ptr, RTCRay8& ray, size_t item) { } void IntersectFunc16(const void* valid, void* ptr, RTCRay16& ray, size_t item) { } void OccludedFunc (void* ptr, RTCRay& ray, size_t item) { } void OccludedFunc4 (const void* valid, void* ptr, RTCRay4& ray, size_t item) { } void OccludedFunc8 (const void* valid, void* ptr, RTCRay8& ray, size_t item) { } void OccludedFunc16 (const void* valid, void* ptr, RTCRay16& ray, size_t item) { } unsigned addUserGeometryEmpty (RTCScene scene, Sphere* sphere) { BBox3fa bounds = sphere->bounds(); unsigned geom = rtcNewUserGeometry (scene,1); rtcSetBoundsFunction(scene,geom,(RTCBoundsFunc)BoundsFunc); rtcSetUserData(scene,geom,sphere); rtcSetIntersectFunction(scene,geom,IntersectFunc); rtcSetIntersectFunction4(scene,geom,IntersectFunc4); rtcSetIntersectFunction8(scene,geom,IntersectFunc8); rtcSetIntersectFunction16(scene,geom,&IntersectFunc16); rtcSetOccludedFunction(scene,geom,OccludedFunc); rtcSetOccludedFunction4(scene,geom,OccludedFunc4); rtcSetOccludedFunction8(scene,geom,OccludedFunc8); rtcSetOccludedFunction16(scene,geom,&OccludedFunc16); return geom; } BarrierSys g_barrier; volatile atomic_t g_atomic0; volatile atomic_t g_atomic1; void test_barrier_sys_thread(void* ptr) { for (size_t i=0; i<1000; i++) { atomic_add(&g_atomic0,+1); g_barrier.wait(); atomic_add(&g_atomic1,+1); g_barrier.wait(); atomic_add(&g_atomic0,-1); g_barrier.wait(); atomic_add(&g_atomic1,-1); g_barrier.wait(); } } bool test_barrier_sys () { size_t numThreads = getNumberOfLogicalThreads(); #if defined (__MIC__) numThreads -= 4; #endif g_barrier.init(numThreads); g_atomic0 = 0; g_atomic1 = 0; for (size_t i=1; i 0.00002; printf("%30s ... %s (%f%%)\n", ("watertight_"+type+"1").c_str(), failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_closed4(const std::string& type, const Vec3fa& pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); if (type == "sphere") addSphere(scene,RTC_GEOMETRY_STATIC,pos,2.0f,500); else if (type == "cube" ) addCube (scene,RTC_GEOMETRY_STATIC,pos,2.0f); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n", ("watertight_"+type+"4").c_str(), failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_closed8(const std::string& type, const Vec3fa& pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); if (type == "sphere") addSphere(scene,RTC_GEOMETRY_STATIC,pos,2.0f,500); else if (type == "cube" ) addCube (scene,RTC_GEOMETRY_STATIC,pos,2.0f); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n", ("watertight_"+type+"8").c_str(), failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_closed16(const std::string& type, const Vec3fa& pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); if (type == "sphere") addSphere(scene,RTC_GEOMETRY_STATIC,pos,2.0f,500); else if (type == "cube" ) addCube (scene,RTC_GEOMETRY_STATIC,pos,2.0f); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n", ("watertight_"+type+"16").c_str(), failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_plane1(float pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); unsigned geom = addPlane(scene,RTC_GEOMETRY_STATIC,500,Vec3fa(pos,-6.0f,-6.0f),Vec3fa(0.0f,12.0f,0.0f),Vec3fa(0.0f,0.0f,12.0f)); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n","watertight_plane1", failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_plane4(float pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); unsigned geom = addPlane(scene,RTC_GEOMETRY_STATIC,500,Vec3fa(pos,-6.0f,-6.0f),Vec3fa(0.0f,12.0f,0.0f),Vec3fa(0.0f,0.0f,12.0f)); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n","watertight_plane4", failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_plane8(float pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); unsigned geom = addPlane(scene,RTC_GEOMETRY_STATIC,500,Vec3fa(pos,-6.0f,-6.0f),Vec3fa(0.0f,12.0f,0.0f),Vec3fa(0.0f,0.0f,12.0f)); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n","watertight_plane8",failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_watertight_plane16(float pos) { RTCScene scene = rtcNewScene(RTC_SCENE_STATIC | RTC_SCENE_ROBUST,aflags); unsigned geom = addPlane(scene,RTC_GEOMETRY_STATIC,500,Vec3fa(pos,-6.0f,-6.0f),Vec3fa(0.0f,12.0f,0.0f),Vec3fa(0.0f,0.0f,12.0f)); rtcCommit (scene); size_t numFailures = 0; for (size_t i=0; i 0.00002; printf("%30s ... %s (%f%%)\n","watertight_plane16", failed ? RED("[FAILED]") : GREEN("[PASSED]"), 100.0f*failRate); fflush(stdout); numFailedTests += failed; } void rtcore_nan(const char* name, RTCSceneFlags sflags, RTCGeometryFlags gflags, int N) { size_t count = 1000/N; RTCScene scene = rtcNewScene(sflags,aflags); addSphere(scene,gflags,zero,2.0f,100); addHair (scene,gflags,zero,1.0f,1.0f,100); rtcCommit (scene); size_t numFailures = 0; double c0 = getSeconds(); for (size_t i=0; itask; if (thread->threadIndex > 0) { for (size_t i=0; isceneCount; i++) { task->barrier.wait(); if (thread->threadIndex < task->numActiveThreads) { rtcCommitThread(task->scene,thread->threadIndex,task->numActiveThreads); CountErrors(); for (size_t i=0; i<100; i++) shootRays(task->scene); } task->barrier.wait(); } delete thread; thread = NULL; return; } CountErrors(); int geom[1024]; int types[1024]; Sphere spheres[1024]; size_t numVertices[1024]; for (size_t i=0; i<1024; i++) { geom[i] = -1; types[i] = 0; numVertices[i] = 0; } for (size_t i=0; isceneCount; i++) { srand(task->sceneIndex*23565+i*3242); if (i%20 == 0) std::cout << "." << std::flush; RTCSceneFlags sflag = getSceneFlag(i); task->scene = rtcNewScene(sflag,aflags); vector_t spheres; CountErrors(); for (size_t j=0; j<10; j++) { Vec3fa pos = 100.0f*Vec3fa(drand48(),drand48(),drand48()); int type = rand()%6; #if !defined(__MIC__) switch (rand()%16) { case 0: pos = Vec3fa(nan); break; case 1: pos = Vec3fa(inf); break; case 2: pos = Vec3fa(1E30f); break; default: break; }; #endif size_t numPhi = rand()%100; if (type == 2) numPhi = rand()%10; size_t numTriangles = 2*2*numPhi*(numPhi-1); numTriangles = rand()%(numTriangles+1); switch (type) { case 0: addSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,numTriangles,0.0f); break; case 1: addSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,numTriangles,1.0f); break; case 2: addSubdivSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,4,numTriangles,0.0f); break; case 3: addHair (task->scene,RTC_GEOMETRY_STATIC,pos,1.0f,2.0f,numTriangles,0.0f); break; case 4: addHair (task->scene,RTC_GEOMETRY_STATIC,pos,1.0f,2.0f,numTriangles,1.0f); break; case 5: { Sphere* sphere = new Sphere(pos,2.0f); spheres.push_back(sphere); addUserGeometryEmpty(task->scene,sphere); break; } } CountErrors(); } if (thread->threadCount) { task->numActiveThreads = max(size_t(1),rand() % thread->threadCount); task->barrier.wait(); rtcCommitThread(task->scene,thread->threadIndex,task->numActiveThreads); } else { rtcCommit(task->scene); } CountErrors(); for (size_t i=0; i<100; i++) shootRays(task->scene); if (thread->threadCount) task->barrier.wait(); rtcDeleteScene (task->scene); CountErrors(); for (size_t i=0; itask; if (thread->threadIndex > 0) { for (size_t i=0; isceneCount; i++) { task->barrier.wait(); if (thread->threadIndex < task->numActiveThreads) { rtcCommitThread(task->scene,thread->threadIndex,task->numActiveThreads); CountErrors(); for (size_t i=0; i<100; i++) shootRays(task->scene); } task->barrier.wait(); } delete thread; thread = NULL; return; } task->scene = rtcNewScene(RTC_SCENE_DYNAMIC,aflags); CountErrors(); int geom[1024]; int types[1024]; Sphere spheres[1024]; size_t numVertices[1024]; for (size_t i=0; i<1024; i++) { geom[i] = -1; types[i] = 0; numVertices[i] = 0; } for (size_t i=0; isceneCount; i++) { srand(task->sceneIndex*23565+i*3242); if (i%20 == 0) std::cout << "." << std::flush; for (size_t j=0; j<40; j++) { int index = rand()%1024; if (geom[index] == -1) { int type = rand()%10; Vec3fa pos = 100.0f*Vec3fa(drand48(),drand48(),drand48()); #if !defined(__MIC__) switch (rand()%16) { case 0: pos = Vec3fa(nan); break; case 1: pos = Vec3fa(inf); break; case 2: pos = Vec3fa(1E30f); break; default: break; }; #endif size_t numPhi = rand()%100; if (type >= 3 || type <= 5) numPhi = rand()%10; size_t numTriangles = 2*2*numPhi*(numPhi-1); numTriangles = rand()%(numTriangles+1); types[index] = type; numVertices[index] = 2*numPhi*(numPhi+1); switch (type) { case 0: geom[index] = addSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,numTriangles,0.0f); break; case 1: geom[index] = addSphere(task->scene,RTC_GEOMETRY_DEFORMABLE,pos,2.0f,numPhi,numTriangles,0.0f); break; case 2: geom[index] = addSphere(task->scene,RTC_GEOMETRY_DYNAMIC,pos,2.0f,numPhi,numTriangles,0.0f); break; case 3: geom[index] = addSubdivSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,4,numTriangles,0.0f); break; case 4: geom[index] = addSubdivSphere(task->scene,RTC_GEOMETRY_DEFORMABLE,pos,2.0f,numPhi,4,numTriangles,0.0f); break; case 5: geom[index] = addSubdivSphere(task->scene,RTC_GEOMETRY_DYNAMIC,pos,2.0f,numPhi,4,numTriangles,0.0f); break; case 6: geom[index] = addSphere(task->scene,RTC_GEOMETRY_STATIC,pos,2.0f,numPhi,numTriangles,1.0f); break; case 7: geom[index] = addSphere(task->scene,RTC_GEOMETRY_DEFORMABLE,pos,2.0f,numPhi,numTriangles,1.0f); break; case 8: geom[index] = addSphere(task->scene,RTC_GEOMETRY_DYNAMIC,pos,2.0f,numPhi,numTriangles,1.0f); break; case 9: spheres[index] = Sphere(pos,2.0f); geom[index] = addUserGeometryEmpty(task->scene,&spheres[index]); break; }; CountErrors(); } else { switch (types[index]) { case 0: case 3: case 6: case 9: { rtcDeleteGeometry(task->scene,geom[index]); CountErrors(); geom[index] = -1; break; } case 1: case 2: case 4: case 5: case 7: case 8: { int op = rand()%2; switch (op) { case 0: { rtcDeleteGeometry(task->scene,geom[index]); CountErrors(); geom[index] = -1; break; } case 1: { Vertex3f* vertices = (Vertex3f*) rtcMapBuffer(task->scene,geom[index],RTC_VERTEX_BUFFER); for (size_t i=0; iscene,geom[index],RTC_VERTEX_BUFFER); if (types[index] == 7 || types[index] == 8) { Vertex3f* vertices = (Vertex3f*) rtcMapBuffer(task->scene,geom[index],RTC_VERTEX_BUFFER1); for (size_t i=0; iscene,geom[index],RTC_VERTEX_BUFFER1); } break; } } break; } } } } if (thread->threadCount) { task->numActiveThreads = max(size_t(1),rand() % thread->threadCount); task->barrier.wait(); rtcCommitThread(task->scene,thread->threadIndex,task->numActiveThreads); } else { rtcCommit(task->scene); } CountErrors(); for (size_t i=0; i<100; i++) shootRays(task->scene); if (thread->threadCount) task->barrier.wait(); } rtcDeleteScene (task->scene); CountErrors(); delete thread; thread = NULL; return; } bool rtcore_regression (thread_func func, bool userThreads) { errorCounter = 0; size_t sceneIndex = 0; while (sceneIndex < regressionN/5) { if (userThreads) { size_t numThreads = getNumberOfLogicalThreads(); #if defined (__MIC__) numThreads -= 4; #endif std::vector tasks; while (numThreads) { size_t N = max(size_t(1),rand()%numThreads); numThreads -= N; RegressionTask* task = new RegressionTask(sceneIndex++,5,N); tasks.push_back(task); for (size_t i=0; i