void Slave::renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags ) { Ref<RenderTask> renderTask = new RenderTask;//(fb,tiledRenderer->createRenderJob(fb)); renderTask->fb = fb; renderTask->renderer = tiledRenderer; renderTask->numTiles_x = divRoundUp(fb->size.x,TILE_SIZE); renderTask->numTiles_y = divRoundUp(fb->size.y,TILE_SIZE); renderTask->channelFlags = channelFlags; tiledRenderer->beginFrame(fb); /*! iw: using a local sync event for now; "in theory" we should be able to attach something like a sync event to the frame buffer, just trigger the task here, and let somebody else sync on the framebuffer once it is needed; alas, I'm currently running into some issues with the embree taks system when trying to do so, and thus am reverting to this fully-synchronous version for now */ // renderTask->fb->frameIsReadyEvent = TaskScheduler::EventSync(); TaskScheduler::EventSync sync; renderTask->task = embree::TaskScheduler::Task (&sync, // (&renderTask->fb->frameIsReadyEvent, renderTask->_run,renderTask.ptr, renderTask->numTiles_x*renderTask->numTiles_y, renderTask->_finish,renderTask.ptr, "LocalTiledLoadBalancer::RenderTask"); TaskScheduler::addTask(-1, TaskScheduler::GLOBAL_BACK, &renderTask->task); sync.sync(); }
void launch_renderTile (int numTiles, int* pixels, const int width, const int height, const float time, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p, const int numTilesX, const int numTilesY) { TaskScheduler::EventSync event; RenderTileTask parms(pixels,width,height,time,vx,vy,vz,p,numTilesX,numTilesY); TaskScheduler::Task task(&event,(TaskScheduler::runFunction)renderTile_parallel,&parms,numTiles,NULL,NULL,"render"); TaskScheduler::addTask(-1,TaskScheduler::GLOBAL_FRONT,&task); event.sync(); }
/*! render a frame via the tiled load balancer */ void InterleavedTiledLoadBalancer::renderFrame(Renderer *tiledRenderer, FrameBuffer *fb, const uint32 channelFlags) { Assert(tiledRenderer); Assert(fb); Ref<RenderTask> renderTask = new RenderTask; renderTask->fb = fb; renderTask->renderer = tiledRenderer; renderTask->numTiles_x = divRoundUp(fb->size.x,TILE_SIZE); renderTask->numTiles_y = divRoundUp(fb->size.y,TILE_SIZE); size_t numTiles_total = renderTask->numTiles_x*renderTask->numTiles_y; renderTask->numTiles_mine = (numTiles_total / numDevices) + (numTiles_total % numDevices > deviceID); renderTask->channelFlags = channelFlags; renderTask->deviceID = deviceID; renderTask->numDevices = numDevices; tiledRenderer->beginFrame(fb); /*! iw: using a local sync event for now; "in theory" we should be able to attach something like a sync event to the frame buffer, just trigger the task here, and let somebody else sync on the framebuffer once it is needed; alas, I'm currently running into some issues with the embree taks system when trying to do so, and thus am reverting to this fully-synchronous version for now */ TaskScheduler::EventSync sync; renderTask->task = embree::TaskScheduler::Task (&sync, // (&renderTask->fb->frameIsReadyEvent, renderTask->_run,renderTask.ptr, renderTask->numTiles_mine, renderTask->_finish,renderTask.ptr, "InterleavedTiledLoadBalancer::RenderTask"); // PRINT(renderTask->numTiles_mine); TaskScheduler::addTask(-1, TaskScheduler::GLOBAL_BACK, &renderTask->task); sync.sync(); }
void rtcBuildAccel(RTCGeometry* geom, const char* builderTy) { double t0 = getSeconds(); TaskScheduler::EventSync event; geom->build(&event,builderTy); event.sync(); double dt = getSeconds()-t0; /* output statistics */ if (g_verbose > 0) { std::ostringstream stream; size_t numTriangles = geom->size(); stream.setf(std::ios::fixed, std::ios::floatfield); stream.precision(0); stream << "triangles = " << numTriangles << std::endl; stream << "build time = " << dt*1000.0f << " ms" << std::endl; stream.precision(3); stream << "build performance = " << double(numTriangles)/dt*1E-6 << " Mtris/s" << std::endl; stream << "memory pool = " << double(Alloc::global.size())*1E-6 << " MB" << std::endl; std::cout << stream.str(); geom->accel->print(); } }
DebugRenderer::RenderJob::RenderJob (Ref<DebugRenderer> renderer, const Ref<Camera>& camera, const Ref<BackendScene>& scene, const Ref<ToneMapper>& toneMapper, Ref<SwapChain > swapchain, int accumulate) : renderer(renderer), camera(camera), scene(scene), toneMapper(toneMapper), swapchain(swapchain), accumulate(accumulate) { this->tileID = 0; this->atomicNumRays = 0; numTilesX = ((int)swapchain->getWidth() +TILE_SIZE-1)/TILE_SIZE; numTilesY = ((int)swapchain->getHeight()+TILE_SIZE-1)/TILE_SIZE; rcpWidth = rcp(float(swapchain->getWidth())); rcpHeight = rcp(float(swapchain->getHeight())); this->framebuffer = swapchain->buffer(); this->framebuffer->startRendering(numTilesX*numTilesY); #if 1 TaskScheduler::EventSync event; TaskScheduler::Task task(&event,_renderTile,this,TaskScheduler::getNumThreads(),_finish,this,"render::tile"); TaskScheduler::addTask(-1,TaskScheduler::GLOBAL_BACK,&task); event.sync(); #else new (&task) TaskScheduler::Task (NULL,_renderTile,this,TaskScheduler::getNumThreads(),_finish,this,"render::tile"); TaskScheduler::addTask(-1,TaskScheduler::GLOBAL_BACK,&task); #endif }
void Scene::build (size_t threadIndex, size_t threadCount) { /* all user worker threads properly enter and leave the tasking system */ LockStepTaskScheduler::Init init(threadIndex,threadCount,&lockstep_scheduler); if (threadIndex != 0) return; /* allow only one build at a time */ Lock<MutexSys> lock(mutex); if (isStatic() && isBuild()) { process_error(RTC_INVALID_OPERATION,"static geometries cannot get committed twice"); return; } if (!ready()) { process_error(RTC_INVALID_OPERATION,"not all buffers are unmapped"); return; } /* verify geometry in debug mode */ #if 0 && defined(DEBUG) // FIXME: enable for (size_t i=0; i<geometries.size(); i++) { if (geometries[i]) { if (!geometries[i]->verify()) { process_error(RTC_INVALID_OPERATION,"invalid geometry specified"); return; } } } #endif /* select fast code path if no intersection filter is present */ accels.select(numIntersectionFilters4,numIntersectionFilters8,numIntersectionFilters16); /* if user provided threads use them */ if (threadCount) accels.build(threadIndex,threadCount); /* otherwise use our own threads */ else { TaskScheduler::EventSync event; new (&task) TaskScheduler::Task(&event,_task_build_parallel,this,TaskScheduler::getNumThreads(),NULL,NULL,"scene_build"); TaskScheduler::addTask(-1,TaskScheduler::GLOBAL_FRONT,&task); event.sync(); } /* make static geometry immutable */ if (isStatic()) { accels.immutable(); for (size_t i=0; i<geometries.size(); i++) if (geometries[i]) geometries[i]->immutable(); } /* delete geometry that is scheduled for delete */ for (size_t i=0; i<geometries.size(); i++) { Geometry* geom = geometries[i]; if (geom == NULL || geom->state != Geometry::ERASING) continue; remove(geom); } /* update bounds */ bounds = accels.bounds; intersectors = accels.intersectors; is_build = true; /* enable only algorithms choosen by application */ if ((aflags & RTC_INTERSECT1) == 0) { intersectors.intersector1.intersect = NULL; intersectors.intersector1.occluded = NULL; } if ((aflags & RTC_INTERSECT4) == 0) { intersectors.intersector4.intersect = NULL; intersectors.intersector4.occluded = NULL; } if ((aflags & RTC_INTERSECT8) == 0) { intersectors.intersector8.intersect = NULL; intersectors.intersector8.occluded = NULL; } if ((aflags & RTC_INTERSECT16) == 0) { intersectors.intersector16.intersect = NULL; intersectors.intersector16.occluded = NULL; } if (g_verbose >= 2) { std::cout << "created scene intersector" << std::endl; accels.print(2); std::cout << "selected scene intersector" << std::endl; intersectors.print(2); } /* update commit counter */ commitCounter++; }
void Scene::build () { Lock<MutexSys> lock(mutex); if (isStatic() && isBuild()) { process_error(RTC_INVALID_OPERATION,"static geometries cannot get committed twice"); return; } if (!ready()) { process_error(RTC_INVALID_OPERATION,"not all buffers are unmapped"); return; } /* verify geometry in debug mode */ #if defined(DEBUG) for (size_t i=0; i<geometries.size(); i++) { if (geometries[i]) { if (!geometries[i]->verify()) { process_error(RTC_INVALID_OPERATION,"invalid geometry specified"); return; } } } #endif /* select fast code path if no intersection filter is present */ accels.select(numIntersectionFilters4,numIntersectionFilters8,numIntersectionFilters16); /* spawn build task */ TaskScheduler::EventSync event; new (&task) TaskScheduler::Task(&event,NULL,NULL,1,_task_build,this,"scene_build"); TaskScheduler::addTask(-1,TaskScheduler::GLOBAL_FRONT,&task); event.sync(); /* make static geometry immutable */ if (isStatic()) { accels.immutable(); for (size_t i=0; i<geometries.size(); i++) geometries[i]->immutable(); } /* delete geometry that is scheduled for delete */ for (size_t i=0; i<geometries.size(); i++) { Geometry* geom = geometries[i]; if (geom == NULL || geom->state != Geometry::ERASING) continue; remove(geom); } /* update bounds */ bounds = accels.bounds; intersectors = accels.intersectors; is_build = true; /* enable only algorithms choosen by application */ if ((aflags & RTC_INTERSECT1) == 0) { intersectors.intersector1.intersect = NULL; intersectors.intersector1.occluded = NULL; } if ((aflags & RTC_INTERSECT4) == 0) { intersectors.intersector4.intersect = NULL; intersectors.intersector4.occluded = NULL; } if ((aflags & RTC_INTERSECT8) == 0) { intersectors.intersector8.intersect = NULL; intersectors.intersector8.occluded = NULL; } if ((aflags & RTC_INTERSECT16) == 0) { intersectors.intersector16.intersect = NULL; intersectors.intersector16.occluded = NULL; } if (g_verbose >= 2) { std::cout << "created scene intersector" << std::endl; accels.print(2); std::cout << "selected scene intersector" << std::endl; intersectors.print(2); } }