From 2af7637f207c420af602f43e514b1b20e7cfc718 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 14 Jan 2016 12:24:09 +0500 Subject: [PATCH] Cycles: Add option to directly link against CUDA libraries The main purpose of such linking is to make Blender compatible with NVidia's debuggers and profilers which are doing some LD_PRELOAD magic to intercept some function calls. Such magic conflicts with our CUDA wrangler magic and causes segmentation faults. The option is disabled by default, so there's no affect on any of artists. In order to make Blender linked directly against CUDA library use the WITH_CUDA_DYNLOAD CMake option (it's marked as advanced). --- CMakeLists.txt | 7 +++- build_files/cmake/macros.cmake | 6 +++- extern/CMakeLists.txt | 4 ++- intern/cycles/app/CMakeLists.txt | 7 +++- intern/cycles/cmake/external_libs.cmake | 2 +- intern/cycles/device/CMakeLists.txt | 9 ++++- intern/cycles/device/device_cuda.cpp | 46 ++++++++++++++++++++++++- source/blenderplayer/CMakeLists.txt | 6 +++- 8 files changed, 79 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d9d515d1e5..73d219e0e1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,6 +399,9 @@ mark_as_advanced(WITH_CYCLES_LOGGING) mark_as_advanced(WITH_CYCLES_DEBUG) mark_as_advanced(WITH_CYCLES_WERROR) +option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON) +mark_as_advanced(WITH_CUDA_DYNLOAD) + # LLVM option(WITH_LLVM "Use LLVM" OFF) if(APPLE) @@ -2906,7 +2909,9 @@ if(WITH_BLENDER OR WITH_PLAYER) elseif(WITH_CYCLES_STANDALONE) add_subdirectory(intern/cycles) add_subdirectory(extern/clew) - add_subdirectory(extern/cuew) + if(WITH_CUDA_DYNLOAD) + add_subdirectory(extern/cuew) + endif() if(NOT WITH_SYSTEM_GLEW) add_subdirectory(extern/glew) endif() diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index cacc741966f..a8e17c3b5ef 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -478,7 +478,11 @@ function(setup_liblinks # We put CLEW and CUEW here because OPENSUBDIV_LIBRARIES dpeends on them.. if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV) target_link_libraries(${target} "extern_clew") - target_link_libraries(${target} "extern_cuew") + if(WITH_CUDA_DYNLOAD) + target_link_libraries(${target} "extern_cuew") + else() + target_link_libraries(${target} ${CUDA_CUDA_LIBRARY}) + endif() endif() #system libraries with no dependencies such as platform link libs or opengl should go last diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 632b68ef074..82b13cc114b 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -74,7 +74,9 @@ endif() if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV) add_subdirectory(clew) - add_subdirectory(cuew) + if(WITH_CUDA_DYNLOAD) + add_subdirectory(cuew) + endif() endif() if(WITH_MOD_BOOLEAN) diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt index 95bc517ae00..41233287279 100644 --- a/intern/cycles/app/CMakeLists.txt +++ b/intern/cycles/app/CMakeLists.txt @@ -29,9 +29,14 @@ set(LIBRARIES ${TIFF_LIBRARY} ${PTHREADS_LIBRARIES} extern_clew - extern_cuew ) +if(WITH_CUDA_DYNLOAD) + list(APPEND LIBRARIES extern_cuew) +else() + list(APPEND LIBRARIES ${CUDA_CUDA_LIBRARY}) +endif() + if(WITH_CYCLES_OSL) list(APPEND LIBRARIES cycles_kernel_osl) endif() diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index 56ab8bed6e8..fc75efa7755 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -37,7 +37,7 @@ endif() ########################################################################### # CUDA -if(WITH_CYCLES_CUDA_BINARIES) +if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DUNLOAD) find_package(CUDA) # Try to auto locate CUDA toolkit if(CUDA_FOUND) message(STATUS "CUDA nvcc = ${CUDA_NVCC_EXECUTABLE}") diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index b0fa283c1d8..220b16bb45b 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -11,10 +11,17 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_DIR} - ../../../extern/cuew/include ../../../extern/clew/include ) +if(WITH_CUDA_DYNLOAD) + list(APPEND INC ../../../extern/cuew/include) + add_definitions(-DWITH_CUDA_DYNLOAD) +else() + list(APPEND INC_SYS ${CUDA_TOOLKIT_INCLUDE}) + add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}") +endif() + set(SRC device.cpp device_cpu.cpp diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 5c9ca3454c6..88f1a86d6ac 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -23,7 +23,13 @@ #include "buffers.h" -#include "cuew.h" +#ifdef WITH_CUDA_DYNLOAD +# include "cuew.h" +#else +# include "util_opengl.h" +# include +# include +#endif #include "util_debug.h" #include "util_logging.h" #include "util_map.h" @@ -42,6 +48,40 @@ CCL_NAMESPACE_BEGIN +#ifndef WITH_CUDA_DYNLOAD + +/* Transparently implement some functions, so majority of the file does not need + * to worry about difference between dynamically loaded and linked CUDA at all. + */ + +namespace { + +const char *cuewErrorString(CUresult result) +{ + /* We can only give error code here without major code duplication, that + * should be enough since dynamic loading is only being disabled by folks + * who knows what they're doing anyway. + * + * NOTE: Avoid call from several threads. + */ + static string error; + error = string_printf("%d", result); + return error.c_str(); +} + +const char *cuewCompilerPath(void) +{ + return CYCLES_CUDA_NVCC_EXECUTABLE; +} + +int cuewCompilerVersion(void) +{ + return (CUDA_VERSION / 100) + (CUDA_VERSION % 100 / 10); +} + +} /* namespace */ +#endif /* WITH_CUDA_DYNLOAD */ + class CUDADevice : public Device { public: @@ -1100,6 +1140,7 @@ public: bool device_cuda_init(void) { +#ifdef WITH_CUDA_DYNLOAD static bool initialized = false; static bool result = false; @@ -1133,6 +1174,9 @@ bool device_cuda_init(void) } return result; +#else /* WITH_CUDA_DYNLOAD */ + return true; +#endif /* WITH_CUDA_DYNLOAD */ } Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index f630befdf5f..e8c710e68ae 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -255,5 +255,9 @@ setup_liblinks(blenderplayer) # We put CLEW and CUEW here because OPENSUBDIV_LIBRARIES dpeends on them.. if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV) target_link_libraries(blenderplayer "extern_clew") - target_link_libraries(blenderplayer "extern_cuew") + if(WITH_CUDA_DYNLOAD) + target_link_libraries(blenderplayer "extern_cuew") + else() + target_link_libraries(${target} ${CUDA_CUDA_LIBRARY}) + endif() endif()