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

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

#include "device.h"

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

#include "../hash.h"
#include "scene_triangle_mesh.h"
#include "scene_user_geometry.h"
#include "scene_instance.h"
#include "scene_curves.h"
#include "scene_subdiv_mesh.h"

#include "../subdiv/tessellation_cache.h"

#include "acceln.h"
#include "geometry.h"

#include "../geometry/cylinder.h"

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

#include "../../common/sys/alloc.h"

#if defined(EMBREE_SYCL_SUPPORT)
#  include "../level_zero/ze_wrapper.h"
#endif

namespace embree
{
  /*! some global variables that can be set via rtcSetParameter1i for debugging purposes */
  ssize_t Device::debug_int0 =;
  ssize_t Device::debug_int1 =;
  ssize_t Device::debug_int2 =;
  ssize_t Device::debug_int3 =;

  static MutexSys g_mutex;
  static std::map<Device*,size_t> g_cache_size_map;
  static std::map<Device*,size_t> g_num_threads_map;
  
  struct TaskArena
  {};

  Device::Device (const char* cfg) :{}

  Device::~Device ()
  {}

  std::string getEnabledTargets()
  {}

  std::string getEmbreeFeatures()
  {}

  void Device::print()
  {}

  void Device::setDeviceErrorCode(RTCError error)
  {}

  RTCError Device::getDeviceErrorCode()
  {}

  void Device::setThreadErrorCode(RTCError error)
  {}

  RTCError Device::getThreadErrorCode()
  {}

  void Device::process_error(Device* device, RTCError error, const char* str)
  {}

  void Device::memoryMonitor(ssize_t bytes, bool post)
  {}

  size_t getMaxNumThreads()
  {}

  size_t getMaxCacheSize()
  {}
 
  void Device::setCacheSize(size_t bytes) 
  {}

  void Device::initTaskingSystem(size_t numThreads) 
  {}

  void Device::exitTaskingSystem() 
  {}

  void Device::execute(bool join, const std::function<void()>& func)
  {}

  void Device::setProperty(const RTCDeviceProperty prop, ssize_t val)
  {}

  ssize_t Device::getProperty(const RTCDeviceProperty prop)
  {}

  void* Device::malloc(size_t size, size_t align) {}

  void Device::free(void* ptr) {}


#if defined(EMBREE_SYCL_SUPPORT)

  DeviceGPU::DeviceGPU(sycl::context sycl_context, const char* cfg)
    : Device(cfg), gpu_context(sycl_context)
  {
    /* initialize ZeWrapper */
    if (ZeWrapper::init() != ZE_RESULT_SUCCESS)
       throw_RTCError(RTC_ERROR_UNKNOWN, "cannot initialize ZeWrapper");
     
    /* take first device as default device */
    auto devices = gpu_context.get_devices();
    if (devices.size() == 0)
      throw_RTCError(RTC_ERROR_UNKNOWN, "SYCL context contains no device");
    gpu_device = devices[0];

    /* check if RTAS build extension is available */
    sycl::platform platform = gpu_device.get_platform();
    ze_driver_handle_t hDriver = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(platform);
    
    uint32_t count = 0;
    std::vector<ze_driver_extension_properties_t> extensions;
    ze_result_t result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data());
    if (result != ZE_RESULT_SUCCESS)
      throw_RTCError(RTC_ERROR_UNKNOWN, "zeDriverGetExtensionProperties failed");
    
    extensions.resize(count);
    result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data());
    if (result != ZE_RESULT_SUCCESS)
      throw_RTCError(RTC_ERROR_UNKNOWN, "zeDriverGetExtensionProperties failed");

#if defined(EMBREE_SYCL_L0_RTAS_BUILDER)
    bool ze_rtas_builder = false;
    for (uint32_t i=0; i<extensions.size(); i++)
    {
      if (strncmp("ZE_experimental_rtas_builder",extensions[i].name,sizeof(extensions[i].name)) == 0)
        ze_rtas_builder = true;
    }
    if (!ze_rtas_builder)
      throw_RTCError(RTC_ERROR_UNKNOWN, "ZE_experimental_rtas_builder extension not found");

    result = ZeWrapper::initRTASBuilder(hDriver,ZeWrapper::LEVEL_ZERO);
    if (result == ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE)
      throw_RTCError(RTC_ERROR_UNKNOWN, "cannot load ZE_experimental_rtas_builder extension");
    if (result != ZE_RESULT_SUCCESS)
      throw_RTCError(RTC_ERROR_UNKNOWN, "cannot initialize ZE_experimental_rtas_builder extension");
#else
    ZeWrapper::initRTASBuilder(hDriver,ZeWrapper::INTERNAL);
#endif

    if (State::verbosity(1))
    {
      if (ZeWrapper::rtas_builder == ZeWrapper::INTERNAL)
        std::cout << "  Internal RTAS Builder" << std::endl;
      else
        std::cout << "  Level Zero RTAS Builder" << std::endl;
    }

    /* check if extension library can get loaded */
    ze_rtas_parallel_operation_exp_handle_t hParallelOperation;
    result = ZeWrapper::zeRTASParallelOperationCreateExp(hDriver, &hParallelOperation);
    if (result == ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE)
      throw_RTCError(RTC_ERROR_UNKNOWN, "Level Zero RTAS Build Extension cannot get loaded");
    if (result == ZE_RESULT_SUCCESS)
      ZeWrapper::zeRTASParallelOperationDestroyExp(hParallelOperation);

    gpu_maxWorkGroupSize = getGPUDevice().get_info<sycl::info::device::max_work_group_size>();
    gpu_maxComputeUnits  = getGPUDevice().get_info<sycl::info::device::max_compute_units>();    

    if (State::verbosity(1))
    {
      sycl::platform platform = gpu_context.get_platform();
      std::cout << "  Platform              : " << platform.get_info<sycl::info::platform::name>() << std::endl;
      std::cout << "    Device              : " << getGPUDevice().get_info<sycl::info::device::name>() << std::endl;
      std::cout << "    Max Work Group Size : " << gpu_maxWorkGroupSize << std::endl;
      std::cout << "    Max Compute Units   : " << gpu_maxComputeUnits  << std::endl;
      std::cout << std::endl;
    }
    
    dispatchGlobalsPtr = zeRTASInitExp(gpu_device, gpu_context);
  }

  DeviceGPU::~DeviceGPU()
  {
    rthwifCleanup(this,dispatchGlobalsPtr,gpu_context);
  }

  void DeviceGPU::enter() {
    enableUSMAllocEmbree(&gpu_context,&gpu_device);
  }

  void DeviceGPU::leave() {
    disableUSMAllocEmbree();
  }

  void* DeviceGPU::malloc(size_t size, size_t align) {
    return alignedSYCLMalloc(&gpu_context,&gpu_device,size,align,EMBREE_USM_SHARED_DEVICE_READ_ONLY);
  }

  void DeviceGPU::free(void* ptr) {
    alignedSYCLFree(&gpu_context,ptr);
  }

  void DeviceGPU::setSYCLDevice(const sycl::device sycl_device_in) {
    gpu_device = sycl_device_in;
  }
  
#endif

  DeviceEnterLeave::DeviceEnterLeave (RTCDevice hdevice)
    :{}
  
  DeviceEnterLeave::DeviceEnterLeave (RTCScene hscene)
    :{}
  
  DeviceEnterLeave::DeviceEnterLeave (RTCGeometry hgeometry)
    :{}
  
  DeviceEnterLeave::DeviceEnterLeave (RTCBuffer hbuffer)
    :{}
  
  DeviceEnterLeave::~DeviceEnterLeave() {}
}