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();
      }
Beispiel #2
0
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();
}
Beispiel #3
0
  /*! 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();
  }
Beispiel #4
0
  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
  }
Beispiel #6
0
  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++;
  }
Beispiel #7
0
  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);
    }
  }