godot/thirdparty/embree/kernels/common/scene.cpp

// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "scene.h"

#include "../../common/tasking/taskscheduler.h"

#include "../bvh/bvh4_factory.h"
#include "../bvh/bvh8_factory.h"

#include "../../common/algorithms/parallel_reduce.h"

#if defined(EMBREE_SYCL_SUPPORT)
#  include "../sycl/rthwif_embree_builder.h"
#endif


namespace embree
{

  struct TaskGroup {};

  /* error raising rtcIntersect and rtcOccluded functions */
  void missing_rtcCommit()      {}
  void invalid_rtcIntersect1()  {}
  void invalid_rtcIntersect4()  {}
  void invalid_rtcIntersect8()  {}
  void invalid_rtcIntersect16() {}
  void invalid_rtcIntersectN()  {}

  Scene::Scene (Device* device)
    :{}

  Scene::~Scene() noexcept
  {}
  
  void Scene::printStatistics()
  {}

  void Scene::createTriangleAccel()
  {}

  void Scene::createTriangleMBAccel()
  {}

  void Scene::createQuadAccel()
  {}

  void Scene::createQuadMBAccel()
  {}

  void Scene::createHairAccel()
  {}

  void Scene::createHairMBAccel()
  {}

  void Scene::createSubdivAccel()
  {}

  void Scene::createSubdivMBAccel()
  {}

  void Scene::createUserGeometryAccel()
  {}

  void Scene::createUserGeometryMBAccel()
  {}

  void Scene::createInstanceAccel()
  {}

  void Scene::createInstanceMBAccel()
  {}

  void Scene::createInstanceExpensiveAccel()
  {}

  void Scene::createInstanceExpensiveMBAccel()
  {}

  void Scene::createInstanceArrayAccel()
  {}

  void Scene::createInstanceArrayMBAccel()
  {}


  void Scene::createGridAccel()
  {}

  void Scene::createGridMBAccel()
  {}

  void Scene::clear() {}

  unsigned Scene::bind(unsigned geomID, Ref<Geometry> geometry) 
  {}

  void Scene::detachGeometry(size_t geomID)
  {}

  void Scene::build_cpu_accels()
  {}

  void Scene::build_gpu_accels()
  {}

  void Scene::commit_task ()
  {}

  void Scene::setBuildQuality(RTCBuildQuality quality_flags_i)
  {}

  RTCBuildQuality Scene::getBuildQuality() const {}

  void Scene::setSceneFlags(RTCSceneFlags scene_flags_i)
  {}

  RTCSceneFlags Scene::getSceneFlags() const {}
                   
#if defined(TASKING_INTERNAL)

  void Scene::commit (bool join) 
  {}

#endif

#if defined(TASKING_TBB)

  void Scene::commit (bool join) 
  {    
#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION_MAJOR < 8)
    if (join)
      throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcJoinCommitScene not supported with this TBB version");
#endif

    /* try to obtain build lock */
    Lock<MutexSys> lock(buildMutex,buildMutex.try_lock());

    /* join hierarchy build */
    if (!lock.isLocked())
    {
#if !TASKING_TBB_USE_TASK_ISOLATION
      if (!join) 
        throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invoking rtcCommitScene from multiple threads is not supported with this TBB version");
#endif
      
      do {
        device->execute(join, [&](){ taskGroup->group.wait(); });

        pause_cpu();
        yield();
      } while (!buildMutex.try_lock());
      
      buildMutex.unlock();
      return;
    }   

    /* for best performance set FTZ and DAZ flags in the MXCSR control and status register */
    const unsigned int mxcsr = _mm_getcsr();
    _mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6));
    
    try {
#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);
      device->execute(join, [&]()
      {
        taskGroup->group.run([&]{
            tbb::parallel_for (size_t(0), size_t(1), size_t(1), [&] (size_t) { commit_task(); }, ctx);
          });
        taskGroup->group.wait();
      });

      /* reset MXCSR register again */
      _mm_setcsr(mxcsr);
    } 
    catch (...)
    {
      /* reset MXCSR register again */
      _mm_setcsr(mxcsr);
      
      accels_clear();
      throw;
    }
  }
#endif

#if defined(TASKING_PPL)

  void Scene::commit (bool join) 
  {
#if defined(TASKING_PPL)
    if (join)
      throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcJoinCommitScene not supported with PPL");
#endif

    /* try to obtain build lock */
    Lock<MutexSys> lock(buildMutex);

    checkIfModifiedAndSet ();
    if (!isModified()) {
      return;
    }

    /* for best performance set FTZ and DAZ flags in the MXCSR control and status register */
    const unsigned int mxcsr = _mm_getcsr();
    _mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6));
    
    try {

      taskGroup->group.run([&]{
          concurrency::parallel_for(size_t(0), size_t(1), size_t(1), [&](size_t) { commit_task(); });
        });
      taskGroup->group.wait();

       /* reset MXCSR register again */
      _mm_setcsr(mxcsr);
    } 
    catch (...)
    {
      /* reset MXCSR register again */
      _mm_setcsr(mxcsr);
      
      accels_clear();
      throw;
    }
  }
#endif

  void Scene::setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr) 
  {}

  void Scene::progressMonitor(double dn)
  {}
}