Files
DarkflameServer/dUgcServer/CMakeLists.txt
Aaron Kimbrell 07dbf30dc8 feat(ugc): ray_backend=hiprt traces on the GPU with HIPRT and Orochi (optional build)
HIPRT (MIT) behind the CMake option DLU_HIPRT (off): its headers come from its
SDK (HIPRT_ROOT, else ROCm's /opt/rocm) and are copied next to the servers; its
library is loaded when first used (hiprtew), as HIP or CUDA are by Orochi
(MIT, fetched pinned by hash; CUDA when its toolkit is found). The trace
kernels (nearest hit skipping the triangle a ray leaves, any hit) are compiled
the first time and kept in cache/hiprt. One GPU context for the process
(hiprt_device picks the GPU); the workers take turns on it. When HIPRT, the
GPU or a scene's upload fails, Embree is used instead, and the UGC server logs
why at start.

For a GPU the rays go in batches (UgcRays::Scene gets batch queries; the CPU
backends answer them a ray at a time):
- hidden faces: with a batch backend the paths are traced side by side, a
  bounce at a time (the path code split into Start, Scatter and Bounce, the one
  by one tracing unchanged); the same paths with the same random numbers, so
  the same triangles are decided (tested with builtin side by side)
- the occlusion bake and the denoised icons' traced occlusion always ask in
  batches (the same rays, the same results)

Its symbols are hidden: the servers export theirs (-rdynamic), and HIPRT's
library, which has an Orochi of its own, would otherwise call ours.

Check: configure with -DDLU_HIPRT=ON on a machine with ROCm (or HIPRT's SDK)
and an AMD RDNA or NVIDIA GPU; UgcServer --make-model x.lxfml out hiprt; the
UGC tests (hits, hidden faces and occlusion against builtin); a build without
it leaves everything as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 12:29:08 -05:00

74 lines
3.4 KiB
CMake

# The UGC server (docs/UgcServer.md), in folders by role:
# Bricks/ the client's brick data: primitives, Materials.xml, LU Toolbox's palette, the CDClient's module data
# Model/ player models built from LXFML, car and rocket module combinations, glitter
# Render/ the software rasterizer, ambient occlusion, hidden-face removal, rays, icon parameters and pose
# Formats/ the files written for the client and the dashboard (NIF, DDS, PNG, sd0)
# Processing/ the job queue and workers, the CPU budget, stored files
# UgcServer.cpp the server: settings, the master link, HTTP routes
# The pure part of the UGC server (brick data, meshes, rendering, file formats, storage), shared with the tests
set(DUGC_SOURCES
"Bricks/UgcBricks.cpp"
"Bricks/UgcPalette.cpp"
"Formats/UgcFormats.cpp"
"Model/UgcGlitter.cpp"
"Model/UgcModel.cpp"
"Model/UgcModular.cpp"
"Processing/UgcJobs.cpp"
"Processing/UgcStorage.cpp"
"Processing/UgcThrottle.cpp"
"Render/UgcHsr.cpp"
"Render/UgcIconParams.cpp"
"Render/UgcIconPose.cpp"
"Render/UgcRays.cpp"
"Render/UgcRender.cpp"
)
add_library(dUgc STATIC ${DUGC_SOURCES})
target_include_directories(dUgc PUBLIC "." "Bricks" "Formats" "Model" "Processing" "Render"
"${PROJECT_SOURCE_DIR}/thirdparty/MD5" "${PROJECT_SOURCE_DIR}/thirdparty/nlohmann")
target_link_libraries(dUgc PUBLIC dCommon glm::glm tinyxml2 MD5 PRIVATE embree)
# Intel Open Image Denoise, when built with DLU_OIDN (thirdparty/CMakeLists.txt): the denoise=oidn setting
if(DLU_OIDN)
target_link_libraries(dUgc PRIVATE OpenImageDenoise)
target_compile_definitions(dUgc PRIVATE DLU_OIDN)
endif()
# HIPRT and Orochi, when built with DLU_HIPRT (thirdparty/CMakeLists.txt): the ray_backend=hiprt setting
if(DLU_HIPRT)
target_sources(dUgc PRIVATE "Render/UgcRaysHiprt.cpp")
# hiprtew's function pointers have the names of HIPRT's functions: hidden, or HIPRT's library would call them
# instead of its own (the servers export their symbols)
if(NOT MSVC)
set_source_files_properties("Render/UgcRaysHiprt.cpp" PROPERTIES COMPILE_OPTIONS "-fvisibility=hidden")
endif()
target_include_directories(dUgc PRIVATE "${DLU_HIPRT_INCLUDE_DIR}")
target_link_libraries(dUgc PRIVATE dlu_orochi)
target_compile_definitions(dUgc PRIVATE DLU_HIPRT DLU_HIPRT_INCLUDE_DIR="${DLU_HIPRT_INCLUDE_DIR}")
endif()
add_executable(UgcServer "UgcServer.cpp" "Processing/UgcProcessor.cpp" "Bricks/UgcCdClient.cpp")
target_include_directories(UgcServer PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dClient"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
"${PROJECT_SOURCE_DIR}/dDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/dNet"
"${PROJECT_SOURCE_DIR}/dWeb"
"${PROJECT_SOURCE_DIR}/dServer"
"${PROJECT_SOURCE_DIR}/thirdparty"
"${PROJECT_SOURCE_DIR}/thirdparty/nlohmann"
)
target_compile_definitions(UgcServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")
target_link_libraries(UgcServer ${COMMON_LIBRARIES} dWeb dServer dUgc)
# Rendering is far too slow unoptimized (minutes a model instead of seconds), so it is optimized in every build type
if(NOT MSVC)
set_source_files_properties("Render/UgcRender.cpp" "Render/UgcHsr.cpp" "Render/UgcRays.cpp" "Model/UgcModel.cpp" "Bricks/UgcPalette.cpp" "Model/UgcGlitter.cpp" PROPERTIES COMPILE_OPTIONS "-O2")
endif()