mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-26 06:32:49 +00:00
feat(ugc): ray_backend=embree-gpu traces on Intel GPUs with Embree's SYCL (optional build)
The third ray backend, so every machine has a library for it: Embree on x86 CPUs (embree), HIPRT on AMD and NVIDIA GPUs (hiprt), Embree through SYCL on Intel Arc and Xe GPUs (embree-gpu). - CMake option DLU_EMBREE_SYCL (off). dUgcServer/EmbreeSycl is a project of its own built by a SYCL compiler (DLU_SYCL_CXX; icpx through ONEAPI_ROOT or the path, or the open source DPC++'s clang++ through DPCPP_ROOT) as an external project: Embree 4.4 with EMBREE_SYCL_SUPPORT, linked statically and bound inside (-Bsymbolic, only its C functions exported, so it never meets the servers' own Embree), and the GPU kernels (nearest hit skipping a ray's triangle, any hit), into libdlu_embree_sycl next to the servers - UgcRaysEmbreeGpu loads it the first time embree-gpu is asked for; one GPU for the process (embree_gpu_device picks it), the workers take turns, the occlusion rays in batches as for hiprt - without the build, the library or a supported Intel GPU it falls back to embree and says why (the UGC server's log at start, --make-model on stderr) - the option names, the settings page, the dashboard's picker, /reprocessproperty Verified here: the default build and ctest; the SYCL build with the open source DPC++ 7.1.0 (compiles, links against oneAPI's libsycl.so.9, exports only its C functions); on this machine (no Intel GPU) it loads, finds no GPU and falls back to embree. Not verified: tracing on an Intel GPU (none here). Check: on a machine with an Intel Arc or Xe GPU and oneAPI, configure with -DDLU_EMBREE_SYCL=ON and run UgcServer --make-model x.lxfml out embree-gpu; the UGC tests then compare it with Embree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,9 @@
|
||||
#ifdef DLU_HIPRT
|
||||
#include "UgcRaysHiprt.h"
|
||||
#endif
|
||||
#ifdef DLU_EMBREE_SYCL
|
||||
#include "UgcRaysEmbreeGpu.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
using UgcRays::Hit;
|
||||
@@ -168,13 +171,17 @@ namespace UgcRays {
|
||||
}
|
||||
|
||||
std::string_view Name(eBackend backend) {
|
||||
return backend == eBackend::HIPRT ? "hiprt" : "embree";
|
||||
switch (backend) {
|
||||
case eBackend::HIPRT: return "hiprt";
|
||||
case eBackend::EMBREE_GPU: return "embree-gpu";
|
||||
default: return "embree";
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<eBackend> Parse(std::string_view name) {
|
||||
// builtin: the UGC server's own hierarchies, which Embree replaced (settings and options that name it)
|
||||
if (name == "builtin") return eBackend::EMBREE;
|
||||
for (const auto backend : { eBackend::EMBREE, eBackend::HIPRT }) {
|
||||
for (const auto backend : { eBackend::EMBREE, eBackend::HIPRT, eBackend::EMBREE_GPU }) {
|
||||
if (Name(backend) == name) return backend;
|
||||
}
|
||||
return std::nullopt;
|
||||
@@ -183,6 +190,9 @@ namespace UgcRays {
|
||||
bool Available(eBackend backend) {
|
||||
#ifdef DLU_HIPRT
|
||||
if (backend == eBackend::HIPRT) return UgcRaysHiprt::Available();
|
||||
#endif
|
||||
#ifdef DLU_EMBREE_SYCL
|
||||
if (backend == eBackend::EMBREE_GPU) return UgcRaysEmbreeGpu::Available();
|
||||
#endif
|
||||
return backend == eBackend::EMBREE;
|
||||
}
|
||||
@@ -196,7 +206,10 @@ namespace UgcRays {
|
||||
#ifdef DLU_HIPRT
|
||||
if (backend == eBackend::HIPRT) return UgcRaysHiprt::Problem();
|
||||
#endif
|
||||
return "the server was built without it (DLU_HIPRT)";
|
||||
#ifdef DLU_EMBREE_SYCL
|
||||
if (backend == eBackend::EMBREE_GPU) return UgcRaysEmbreeGpu::Problem();
|
||||
#endif
|
||||
return backend == eBackend::HIPRT ? "the server was built without it (DLU_HIPRT)" : "the server was built without it (DLU_EMBREE_SYCL)";
|
||||
}
|
||||
|
||||
std::unique_ptr<Scene> Make(eBackend backend, const UgcModel::Mesh& mesh) {
|
||||
@@ -206,16 +219,24 @@ namespace UgcRays {
|
||||
// A GPU that fails now (out of memory, ...) leaves the job to Embree
|
||||
if (auto scene = UgcRaysHiprt::Make(mesh)) return scene;
|
||||
return std::make_unique<EmbreeScene>(mesh);
|
||||
#endif
|
||||
#ifdef DLU_EMBREE_SYCL
|
||||
case eBackend::EMBREE_GPU:
|
||||
if (auto scene = UgcRaysEmbreeGpu::Make(mesh)) return scene;
|
||||
return std::make_unique<EmbreeScene>(mesh);
|
||||
#endif
|
||||
default: return std::make_unique<EmbreeScene>(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
void SetGpuDevice(int index) {
|
||||
void SetGpuDevice(eBackend backend, int index) {
|
||||
#ifdef DLU_HIPRT
|
||||
UgcRaysHiprt::SetDevice(index);
|
||||
#else
|
||||
(void)index;
|
||||
if (backend == eBackend::HIPRT) UgcRaysHiprt::SetDevice(index);
|
||||
#endif
|
||||
#ifdef DLU_EMBREE_SYCL
|
||||
if (backend == eBackend::EMBREE_GPU) UgcRaysEmbreeGpu::SetDevice(index);
|
||||
#endif
|
||||
(void)backend;
|
||||
(void)index;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user