diff options
27 files changed, 596 insertions, 58 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a7353d0b914..741472128a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,7 @@ option(WITH_OPENVDB "Enable features relying on OpenVDB" ON) option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" ON) option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF) mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE) +option(WITH_NANOVDB "Enable usage of NanoVDB data structure for accelerated rendering on the GPU" OFF) # GHOST Windowing Library Options option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF) @@ -704,6 +705,9 @@ set_and_warn_dependency(WITH_TBB WITH_OPENIMAGEDENOISE OFF) set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF) set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF) +# NanoVDB requires OpenVDB to convert the data structure +set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF) + # OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled. set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF) diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index fa2b39fccd8..59c15a03119 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -117,7 +117,6 @@ if(WIN32) include(cmake/yamlcpp.cmake) # LCMS is an OCIO dep, but only if you build the apps, leaving it here for convenience # include(cmake/lcms.cmake) - endif() if(NOT WIN32 OR ENABLE_MINGW64) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 93e17f33284..1fb56c4d568 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -26,6 +26,7 @@ endif() message("HARVEST_TARGET = ${HARVEST_TARGET}") if(WIN32) + if(BUILD_MODE STREQUAL Release) add_custom_target(Harvest_Release_Results COMMAND # jpeg rename libfile + copy include @@ -145,6 +146,9 @@ harvest(openjpeg/lib openjpeg/lib "*.a") harvest(opensubdiv/include opensubdiv/include "*.h") harvest(opensubdiv/lib opensubdiv/lib "*.a") harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h") +if(WITH_NANOVDB) + harvest(openvdb/nanovdb nanovdb/include/nanovdb "*.h") +endif() harvest(openvdb/lib openvdb/lib "*.a") harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h") harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a") diff --git a/build_files/build_environment/cmake/openvdb.cmake b/build_files/build_environment/cmake/openvdb.cmake index f27d3f408a8..07d0297d5aa 100644 --- a/build_files/build_environment/cmake/openvdb.cmake +++ b/build_files/build_environment/cmake/openvdb.cmake @@ -54,6 +54,20 @@ set(OPENVDB_EXTRA_ARGS -DOPENVDB_CORE_STATIC=${OPENVDB_STATIC} -DOPENVDB_BUILD_BINARIES=Off -DCMAKE_DEBUG_POSTFIX=_d + # NanoVDB is header-only, so only need the install target + -DNANOVDB_BUILD_UNITTESTS=OFF + -DNANOVDB_BUILD_EXAMPLES=OFF + -DNANOVDB_BUILD_BENCHMARK=OFF + -DNANOVDB_BUILD_DOCS=OFF + -DNANOVDB_BUILD_TOOLS=OFF + -DNANOVDB_CUDA_KEEP_PTX=OFF + -DNANOVDB_USE_OPENGL=OFF + -DNANOVDB_USE_OPENGL=OFF + -DNANOVDB_USE_CUDA=OFF + -DNANOVDB_USE_TBB=OFF + -DNANOVDB_USE_OPTIX=OFF + -DNANOVDB_USE_OPENVDB=OFF + -DNANOVDB_ALLOW_FETCHCONTENT=OFF ) if(WIN32) @@ -74,12 +88,18 @@ else() ) endif() +if(WITH_NANOVDB) + set(OPENVDB_PATCH_FILE openvdb_nanovdb.diff) +else() + set(OPENVDB_PATCH_FILE openvdb.diff) +endif() + ExternalProject_Add(openvdb URL ${OPENVDB_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH MD5=${OPENVDB_HASH} PREFIX ${BUILD_DIR}/openvdb - PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb.diff + PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/${OPENVDB_PATCH_FILE} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openvdb ${DEFAULT_CMAKE_FLAGS} ${OPENVDB_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/openvdb ) @@ -96,11 +116,17 @@ add_dependencies( if(WIN32) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(openvdb after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/include ${HARVEST_TARGET}/openvdb/include + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/include/openvdb ${HARVEST_TARGET}/openvdb/include/openvdb COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/lib/openvdb.lib ${HARVEST_TARGET}/openvdb/lib/openvdb.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/bin/openvdb.dll ${HARVEST_TARGET}/openvdb/bin/openvdb.dll DEPENDEES install ) + if(WITH_NANOVDB) + ExternalProject_Add_Step(openvdb nanovdb_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/nanovdb ${HARVEST_TARGET}/nanovdb/include/nanovdb + DEPENDEES after_install + ) + endif() endif() if(BUILD_MODE STREQUAL Debug) ExternalProject_Add_Step(openvdb after_install diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 29e2ffc7ed8..d6b5762ccbc 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -21,6 +21,7 @@ if(WIN32) endif() option(WITH_WEBP "Enable building of oiio with webp support" OFF) option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF) +option(WITH_NANOVDB "Enable building of OpenVDB with NanoVDB included" OFF) set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with") if(NOT BUILD_MODE) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 48e37c93d00..244ca6dd49f 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -145,9 +145,15 @@ set(TBB_VERSION 2019_U9) set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz) set(TBB_HASH 26263622e9187212ec240dcf01b66207) -set(OPENVDB_VERSION 7.0.0) -set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz) -set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8) +if(WITH_NANOVDB) + set(OPENVDB_GIT_UID e62f7a0bf1e27397223c61ddeaaf57edf111b77f) + set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/${OPENVDB_GIT_UID}.tar.gz) + set(OPENVDB_HASH 90919510bc6ccd630fedc56f748cb199) +else() + set(OPENVDB_VERSION 7.0.0) + set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz) + set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8) +endif() set(IDNA_VERSION 2.9) set(CHARDET_VERSION 3.0.4) diff --git a/build_files/build_environment/patches/openvdb_nanovdb.diff b/build_files/build_environment/patches/openvdb_nanovdb.diff new file mode 100644 index 00000000000..50984e91f37 --- /dev/null +++ b/build_files/build_environment/patches/openvdb_nanovdb.diff @@ -0,0 +1,135 @@ +diff -Naur orig/cmake/FindIlmBase.cmake openvdb/cmake/FindIlmBase.cmake +--- orig/cmake/FindIlmBase.cmake 2019-12-06 12:11:33 -0700 ++++ openvdb/cmake/FindIlmBase.cmake 2020-08-12 12:48:44 -0600 +@@ -217,6 +217,8 @@ + set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") + endif() + list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_IlmBase_Version_Suffix}.lib") ++ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s.lib") ++ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s_d.lib") + else() + if(ILMBASE_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +diff -Naur orig/cmake/FindOpenEXR.cmake openvdb/cmake/FindOpenEXR.cmake +--- orig/cmake/FindOpenEXR.cmake 2019-12-06 12:11:33 -0700 ++++ openvdb/cmake/FindOpenEXR.cmake 2020-08-12 12:48:44 -0600 +@@ -210,6 +210,8 @@ + set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") + endif() + list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}.lib") ++ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s.lib") ++ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s_d.lib") + else() + if(OPENEXR_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +diff -Naur orig/openvdb/openvdb/CMakeLists.txt openvdb/openvdb/openvdb/CMakeLists.txt +--- orig/openvdb/openvdb/CMakeLists.txt 2019-12-06 12:11:33 -0700 ++++ openvdb/openvdb/openvdb/CMakeLists.txt 2020-08-12 14:12:26 -0600 +@@ -105,7 +105,9 @@ + # http://boost.2283326.n4.nabble.com/CMake-config-scripts-broken-in-1-70-td4708957.html + # https://github.com/boostorg/boost_install/commit/160c7cb2b2c720e74463865ef0454d4c4cd9ae7c + set(BUILD_SHARED_LIBS ON) +- set(Boost_USE_STATIC_LIBS OFF) ++ if(NOT WIN32) # blender links boost statically on windows ++ set(Boost_USE_STATIC_LIBS OFF) ++ endif() + endif() + + find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS iostreams system) +@@ -193,6 +195,7 @@ + if(OPENVDB_DISABLE_BOOST_IMPLICIT_LINKING) + add_definitions(-DBOOST_ALL_NO_LIB) + endif() ++ add_definitions(-D__TBB_NO_IMPLICIT_LINKAGE -DOPENVDB_OPENEXR_STATICLIB) + endif() + + # @todo Should be target definitions +@@ -383,7 +386,12 @@ + # imported targets. + + if(OPENVDB_CORE_SHARED) +- add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES}) ++ if(WIN32) ++ configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) ++ add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) ++ else() ++ add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES}) ++ endif() + endif() + + if(OPENVDB_CORE_STATIC) +diff -Naur orig/openvdb/openvdb/version.rc.in openvdb/openvdb/openvdb/version.rc.in +--- orig/openvdb/openvdb/version.rc.in 1969-12-31 17:00:00 -0700 ++++ openvdb/openvdb/openvdb/version.rc.in 2020-08-12 14:15:01 -0600 +@@ -0,0 +1,48 @@ ++#include <winver.h> ++ ++#define VER_FILEVERSION @OpenVDB_MAJOR_VERSION@,@OpenVDB_MINOR_VERSION@,@OpenVDB_PATCH_VERSION@,0 ++#define VER_FILEVERSION_STR "@OpenVDB_MAJOR_VERSION@.@OpenVDB_MINOR_VERSION@.@OpenVDB_PATCH_VERSION@.0\0" ++ ++#define VER_PRODUCTVERSION @OpenVDB_MAJOR_VERSION@,@OpenVDB_MINOR_VERSION@,@OpenVDB_PATCH_VERSION@,0 ++#define VER_PRODUCTVERSION_STR "@OpenVDB_MAJOR_VERSION@.@OpenVDB_MINOR_VERSION@\0" ++ ++#ifndef DEBUG ++#define VER_DEBUG 0 ++#else ++#define VER_DEBUG VS_FF_DEBUG ++#endif ++ ++VS_VERSION_INFO VERSIONINFO ++FILEVERSION VER_FILEVERSION ++PRODUCTVERSION VER_PRODUCTVERSION ++FILEFLAGSMASK VS_FFI_FILEFLAGSMASK ++FILEFLAGS (VER_DEBUG) ++FILEOS VOS__WINDOWS32 ++FILETYPE VFT_DLL ++FILESUBTYPE VFT2_UNKNOWN ++BEGIN ++ BLOCK "StringFileInfo" ++ BEGIN ++ BLOCK "040904E4" ++ BEGIN ++ VALUE "FileDescription", "OpenVDB" ++ VALUE "FileVersion", VER_FILEVERSION_STR ++ VALUE "InternalName", "OpenVDB" ++ VALUE "ProductName", "OpenVDB" ++ VALUE "ProductVersion", VER_PRODUCTVERSION_STR ++ END ++ END ++ ++ BLOCK "VarFileInfo" ++ BEGIN ++ /* The following line should only be modified for localized versions. */ ++ /* It consists of any number of WORD,WORD pairs, with each pair */ ++ /* describing a language,codepage combination supported by the file. */ ++ /* */ ++ /* For example, a file might have values "0x409,1252" indicating that it */ ++ /* supports English language (0x409) in the Windows ANSI codepage (1252). */ ++ ++ VALUE "Translation", 0x409, 1252 ++ ++ END ++END +diff -Naur openvdb-original/CMakeLists.txt openvdb/CMakeLists.txt +--- openvdb-original/CMakeLists.txt 2020-08-27 03:34:02.000000000 +0200 ++++ openvdb/CMakeLists.txt 2020-09-02 10:56:21.665735244 +0200 +@@ -68,6 +68,7 @@ + option(OPENVDB_INSTALL_HOUDINI_PYTHONRC [=[Install a Houdini startup script that sets + the visibilty of OpenVDB nodes and their native equivalents.]=] OFF) + option(OPENVDB_BUILD_MAYA_PLUGIN "Build the Maya plugin" OFF) ++option(OPENVDB_BUILD_NANOVDB "Build nanovdb" ON) + option(OPENVDB_ENABLE_RPATH "Build with RPATH information" ON) + option(OPENVDB_CXX_STRICT "Enable or disable pre-defined compiler warnings" OFF) + option(OPENVDB_CODE_COVERAGE "Enable code coverage. This also overrides CMAKE_BUILD_TYPE to Debug" OFF) +@@ -740,6 +741,10 @@ + add_subdirectory(openvdb_maya) + endif() + ++if(OPENVDB_BUILD_NANOVDB) ++ add_subdirectory(nanovdb) ++endif() ++ + ########################################################################## + + add_custom_target(uninstall +
\ No newline at end of file diff --git a/build_files/cmake/Modules/FindNanoVDB.cmake b/build_files/cmake/Modules/FindNanoVDB.cmake new file mode 100644 index 00000000000..95d76fb39af --- /dev/null +++ b/build_files/cmake/Modules/FindNanoVDB.cmake @@ -0,0 +1,49 @@ +# - Find NanoVDB library +# Find the native NanoVDB includes and library +# This module defines +# NANOVDB_INCLUDE_DIRS, where to find nanovdb.h, Set when +# NANOVDB_INCLUDE_DIR is found. +# NANOVDB_ROOT_DIR, The base directory to search for NanoVDB. +# This can also be an environment variable. +# NANOVDB_FOUND, If false, do not try to use NanoVDB. + +#============================================================================= +# Copyright 2020 Blender Foundation. +# +# Distributed under the OSI-approved BSD 3-Clause License, +# see accompanying file BSD-3-Clause-license.txt for details. +#============================================================================= + +# If NANOVDB_ROOT_DIR was defined in the environment, use it. +IF(NOT NANOVDB_ROOT_DIR AND NOT $ENV{NANOVDB_ROOT_DIR} STREQUAL "") + SET(NANOVDB_ROOT_DIR $ENV{NANOVDB_ROOT_DIR}) +ENDIF() + +SET(_nanovdb_SEARCH_DIRS + ${NANOVDB_ROOT_DIR} +) + +FIND_PATH(NANOVDB_INCLUDE_DIR + NAMES + nanovdb/NanoVDB.h + HINTS + ${_nanovdb_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +# handle the QUIETLY and REQUIRED arguments and set NANOVDB_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(NanoVDB DEFAULT_MSG + NANOVDB_INCLUDE_DIR) + +IF(NANOVDB_FOUND) + SET(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR}) +ENDIF(NANOVDB_FOUND) + +MARK_AS_ADVANCED( + NANOVDB_INCLUDE_DIR +) + +UNSET(_nanovdb_SEARCH_DIRS) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 394eac8d0d8..07b3e53de5c 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -323,6 +323,11 @@ if(WITH_OPENVDB) set(OPENVDB_DEFINITIONS) endif() +if(WITH_NANOVDB) + set(NANOVDB ${LIBDIR}/nanovdb) + set(NANOVDB_INCLUDE_DIR ${NANOVDB}/include) +endif() + if(WITH_LLVM) set(LLVM_ROOT_DIR ${LIBDIR}/llvm) if(EXISTS "${LLVM_ROOT_DIR}/bin/llvm-config") diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 58de3b34961..1aa96c8b842 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -264,6 +264,7 @@ endif() if(WITH_OPENVDB) find_package_wrapper(OpenVDB) find_package_wrapper(Blosc) + if(NOT OPENVDB_FOUND) set(WITH_OPENVDB OFF) set(WITH_OPENVDB_BLOSC OFF) @@ -274,6 +275,15 @@ if(WITH_OPENVDB) endif() endif() +if(WITH_NANOVDB) + find_package_wrapper(NanoVDB) + + if(NOT NANOVDB_FOUND) + set(WITH_NANOVDB OFF) + message(STATUS "NanoVDB not found, disabling it") + endif() +endif() + if(WITH_ALEMBIC) find_package_wrapper(Alembic) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 89c55d8b04f..2dd8d5f4600 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -535,6 +535,11 @@ if(WITH_OPENVDB) set(OPENVDB_DEFINITIONS -DNOMINMAX -D_USE_MATH_DEFINES) endif() +if(WITH_NANOVDB) + set(NANOVDB ${LIBDIR}/nanoVDB) + set(NANOVDB_INCLUDE_DIR ${NANOVDB}/include) +endif() + if(WITH_OPENIMAGEDENOISE) set(OPENIMAGEDENOISE ${LIBDIR}/OpenImageDenoise) set(OPENIMAGEDENOISE_LIBPATH ${LIBDIR}/OpenImageDenoise/lib) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index f9987ea8c0d..c77018cc686 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -270,6 +270,14 @@ if(WITH_CYCLES_EMBREE) ) endif() +if(WITH_NANOVDB) + add_definitions(-DWITH_NANOVDB) + include_directories( + SYSTEM + ${NANOVDB_INCLUDE_DIR} + ) +endif() + if(WITH_OPENSUBDIV) add_definitions(-DWITH_OPENSUBDIV) include_directories( diff --git a/intern/cycles/device/cuda/device_cuda_impl.cpp b/intern/cycles/device/cuda/device_cuda_impl.cpp index 3a2eb8df95b..01adf10f252 100644 --- a/intern/cycles/device/cuda/device_cuda_impl.cpp +++ b/intern/cycles/device/cuda/device_cuda_impl.cpp @@ -359,6 +359,10 @@ string CUDADevice::compile_kernel_get_common_cflags( cflags += " -D__SPLIT__"; } +# ifdef WITH_NANOVDB + cflags += " -DWITH_NANOVDB"; +# endif + return cflags; } @@ -1253,42 +1257,6 @@ void CUDADevice::tex_alloc(device_texture &mem) cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size)); } - /* Kepler+, bindless textures. */ - CUDA_RESOURCE_DESC resDesc; - memset(&resDesc, 0, sizeof(resDesc)); - - if (array_3d) { - resDesc.resType = CU_RESOURCE_TYPE_ARRAY; - resDesc.res.array.hArray = array_3d; - resDesc.flags = 0; - } - else if (mem.data_height > 0) { - resDesc.resType = CU_RESOURCE_TYPE_PITCH2D; - resDesc.res.pitch2D.devPtr = mem.device_pointer; - resDesc.res.pitch2D.format = format; - resDesc.res.pitch2D.numChannels = mem.data_elements; - resDesc.res.pitch2D.height = mem.data_height; - resDesc.res.pitch2D.width = mem.data_width; - resDesc.res.pitch2D.pitchInBytes = dst_pitch; - } - else { - resDesc.resType = CU_RESOURCE_TYPE_LINEAR; - resDesc.res.linear.devPtr = mem.device_pointer; - resDesc.res.linear.format = format; - resDesc.res.linear.numChannels = mem.data_elements; - resDesc.res.linear.sizeInBytes = mem.device_size; - } - - CUDA_TEXTURE_DESC texDesc; - memset(&texDesc, 0, sizeof(texDesc)); - texDesc.addressMode[0] = address_mode; - texDesc.addressMode[1] = address_mode; - texDesc.addressMode[2] = address_mode; - texDesc.filterMode = filter_mode; - texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES; - - cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL)); - /* Resize once */ const uint slot = mem.slot; if (slot >= texture_info.size()) { @@ -1299,8 +1267,51 @@ void CUDADevice::tex_alloc(device_texture &mem) /* Set Mapping and tag that we need to (re-)upload to device */ texture_info[slot] = mem.info; - texture_info[slot].data = (uint64_t)cmem->texobject; need_texture_info = true; + + if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT && + mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + /* Kepler+, bindless textures. */ + CUDA_RESOURCE_DESC resDesc; + memset(&resDesc, 0, sizeof(resDesc)); + + if (array_3d) { + resDesc.resType = CU_RESOURCE_TYPE_ARRAY; + resDesc.res.array.hArray = array_3d; + resDesc.flags = 0; + } + else if (mem.data_height > 0) { + resDesc.resType = CU_RESOURCE_TYPE_PITCH2D; + resDesc.res.pitch2D.devPtr = mem.device_pointer; + resDesc.res.pitch2D.format = format; + resDesc.res.pitch2D.numChannels = mem.data_elements; + resDesc.res.pitch2D.height = mem.data_height; + resDesc.res.pitch2D.width = mem.data_width; + resDesc.res.pitch2D.pitchInBytes = dst_pitch; + } + else { + resDesc.resType = CU_RESOURCE_TYPE_LINEAR; + resDesc.res.linear.devPtr = mem.device_pointer; + resDesc.res.linear.format = format; + resDesc.res.linear.numChannels = mem.data_elements; + resDesc.res.linear.sizeInBytes = mem.device_size; + } + + CUDA_TEXTURE_DESC texDesc; + memset(&texDesc, 0, sizeof(texDesc)); + texDesc.addressMode[0] = address_mode; + texDesc.addressMode[1] = address_mode; + texDesc.addressMode[2] = address_mode; + texDesc.filterMode = filter_mode; + texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES; + + cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL)); + + texture_info[slot].data = (uint64_t)cmem->texobject; + } + else { + texture_info[slot].data = (uint64_t)mem.device_pointer; + } } void CUDADevice::tex_free(device_texture &mem) diff --git a/intern/cycles/device/device_memory.cpp b/intern/cycles/device/device_memory.cpp index 8064d50d31f..9eee86b0814 100644 --- a/intern/cycles/device/device_memory.cpp +++ b/intern/cycles/device/device_memory.cpp @@ -166,6 +166,8 @@ device_texture::device_texture(Device *device, data_elements = 4; break; case IMAGE_DATA_TYPE_BYTE: + case IMAGE_DATA_TYPE_NANOVDB_FLOAT: + case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: data_type = TYPE_UCHAR; data_elements = 1; break; diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp index f0683d12f1f..ec699462bfe 100644 --- a/intern/cycles/device/opencl/device_opencl_impl.cpp +++ b/intern/cycles/device/opencl/device_opencl_impl.cpp @@ -2035,6 +2035,10 @@ string OpenCLDevice::kernel_build_options(const string *debug_src) build_options += "-D__KERNEL_DEBUG__ "; # endif +# ifdef WITH_NANOVDB + build_options += "-DWITH_NANOVDB "; +# endif + return build_options; } diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 6651dc2d59d..c9afbb48e7e 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -442,6 +442,12 @@ if(WITH_CYCLES_CUDA_BINARIES) set(cuda_flags ${cuda_flags} -D __KERNEL_DEBUG__) endif() + if(WITH_NANOVDB) + set(cuda_flags ${cuda_flags} + -D WITH_NANOVDB + -I "${NANOVDB_INCLUDE_DIR}") + endif() + if(WITH_CYCLES_CUBIN_COMPILER) string(SUBSTRING ${arch} 3 -1 CUDA_ARCH) @@ -527,8 +533,14 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES) set(cuda_flags ${cuda_flags} -D __KERNEL_DEBUG__) endif() - if(WITH_CYCLES_CUBIN_COMPILER) + if(WITH_NANOVDB) + set(cuda_flags ${cuda_flags} + -D WITH_NANOVDB + -I "${NANOVDB_INCLUDE_DIR}") + endif() + + if(WITH_CYCLES_CUBIN_COMPILER) # Needed to find libnvrtc-builtins.so. Can't do it from inside # cycles_cubin_cc since the env variable is read before main() if(APPLE) @@ -709,3 +721,17 @@ delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_SVM_HEADERS}" ${CYCLES_INSTAL delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_GEOM_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/geom) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_UTIL_HEADERS}" ${CYCLES_INSTALL_PATH}/source/util) delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_SPLIT_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/split) + + +if(WITH_NANOVDB) + set(SRC_NANOVDB_HEADERS + nanovdb/NanoVDB.h + nanovdb/CNanoVDB.h + ) + set(SRC_NANOVDB_UTIL_HEADERS + nanovdb/util/CSampleFromVoxels.h + nanovdb/util/SampleFromVoxels.h + ) + delayed_install(${NANOVDB_INCLUDE_DIR} "${SRC_NANOVDB_HEADERS}" ${CYCLES_INSTALL_PATH}/source/nanovdb) + delayed_install(${NANOVDB_INCLUDE_DIR} "${SRC_NANOVDB_UTIL_HEADERS}" ${CYCLES_INSTALL_PATH}/source/nanovdb/util) +endif() diff --git a/intern/cycles/kernel/kernel_compat_optix.h b/intern/cycles/kernel/kernel_compat_optix.h index 970f5cf864c..e58d8b2aa63 100644 --- a/intern/cycles/kernel/kernel_compat_optix.h +++ b/intern/cycles/kernel/kernel_compat_optix.h @@ -35,6 +35,7 @@ typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef unsigned short half; typedef unsigned long long CUtexObject; + #ifdef CYCLES_CUBIN_CC # define FLT_MIN 1.175494350822287507969e-38f # define FLT_MAX 340282346638528859811704183484516925440.0f diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h index f87501db258..347d0fec7f5 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h @@ -17,6 +17,11 @@ #ifndef __KERNEL_CPU_IMAGE_H__ #define __KERNEL_CPU_IMAGE_H__ +#ifdef WITH_NANOVDB +# include <nanovdb/NanoVDB.h> +# include <nanovdb/util/SampleFromVoxels.h> +#endif + CCL_NAMESPACE_BEGIN /* Make template functions private so symbols don't conflict between kernels with different @@ -470,6 +475,42 @@ template<typename T> struct TextureInterpolator { #undef SET_CUBIC_SPLINE_WEIGHTS }; +#ifdef WITH_NANOVDB +template<typename T> struct NanoVDBInterpolator { + static ccl_always_inline float4 read(float r) + { + return make_float4(r, r, r, 1.0f); + } + + static ccl_always_inline float4 read(nanovdb::Vec3f r) + { + return make_float4(r[0], r[1], r[2], 1.0f); + } + + static ccl_always_inline float4 + interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp) + { + nanovdb::NanoGrid<T> *const grid = (nanovdb::NanoGrid<T> *)info.data; + const nanovdb::NanoRoot<T> &root = grid->tree().root(); + + const nanovdb::Coord off(root.bbox().min()); + const nanovdb::Coord dim(root.bbox().dim()); + const nanovdb::Vec3f xyz(off[0] + x * dim[0], off[1] + y * dim[1], off[2] + z * dim[2]); + + typedef nanovdb::ReadAccessor<nanovdb::NanoRoot<T>> ReadAccessorT; + switch ((interp == INTERPOLATION_NONE) ? info.interpolation : interp) { + default: + case INTERPOLATION_LINEAR: + return read(nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz)); + case INTERPOLATION_CLOSEST: + return read(nanovdb::SampleFromVoxels<ReadAccessorT, 0, false>(root)(xyz)); + case INTERPOLATION_CUBIC: + return read(nanovdb::SampleFromVoxels<ReadAccessorT, 3, false>(root)(xyz)); + } + } +}; +#endif + ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y) { const TextureInfo &info = kernel_tex_fetch(__texture_info, id); @@ -526,6 +567,12 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, return TextureInterpolator<ushort4>::interp_3d(info, P.x, P.y, P.z, interp); case IMAGE_DATA_TYPE_FLOAT4: return TextureInterpolator<float4>::interp_3d(info, P.x, P.y, P.z, interp); +#ifdef WITH_NANOVDB + case IMAGE_DATA_TYPE_NANOVDB_FLOAT: + return NanoVDBInterpolator<float>::interp_3d(info, P.x, P.y, P.z, interp); + case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: + return NanoVDBInterpolator<nanovdb::Vec3f>::interp_3d(info, P.x, P.y, P.z, interp); +#endif default: assert(0); return make_float4( diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h index 1d425d132a1..5a005a3f65b 100644 --- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h +++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h @@ -14,6 +14,11 @@ * limitations under the License. */ +#ifdef WITH_NANOVDB +# include "nanovdb/NanoVDB.h" +# include "nanovdb/util/SampleFromVoxels.h" +#endif + /* w0, w1, w2, and w3 are the four cubic B-spline basis functions. */ ccl_device float cubic_w0(float a) { @@ -60,9 +65,10 @@ ccl_device float cubic_h1(float a) /* Fast bicubic texture lookup using 4 bilinear lookups, adapted from CUDA samples. */ template<typename T> -ccl_device T -kernel_tex_image_interp_bicubic(const TextureInfo &info, CUtexObject tex, float x, float y) +ccl_device T kernel_tex_image_interp_bicubic(const TextureInfo &info, float x, float y) { + CUtexObject tex = (CUtexObject)info.data; + x = (x * info.width) - 0.5f; y = (y * info.height) - 0.5f; @@ -84,9 +90,10 @@ kernel_tex_image_interp_bicubic(const TextureInfo &info, CUtexObject tex, float /* Fast tricubic texture lookup using 8 trilinear lookups. */ template<typename T> -ccl_device T kernel_tex_image_interp_bicubic_3d( - const TextureInfo &info, CUtexObject tex, float x, float y, float z) +ccl_device T kernel_tex_image_interp_bicubic_3d(const TextureInfo &info, float x, float y, float z) { + CUtexObject tex = (CUtexObject)info.data; + x = (x * info.width) - 0.5f; y = (y * info.height) - 0.5f; z = (z * info.depth) - 0.5f; @@ -118,19 +125,44 @@ ccl_device T kernel_tex_image_interp_bicubic_3d( g1y * (g0x * tex3D<T>(tex, x0, y1, z1) + g1x * tex3D<T>(tex, x1, y1, z1))); } +#ifdef WITH_NANOVDB +template<typename T> +ccl_device_inline T kernel_tex_image_interp_nanovdb( + const TextureInfo &info, float x, float y, float z, uint interpolation) +{ + nanovdb::NanoGrid<T> *const grid = (nanovdb::NanoGrid<T> *)info.data; + const nanovdb::NanoRoot<T> &root = grid->tree().root(); + + const nanovdb::Coord off(root.bbox().min()); + const nanovdb::Coord dim(root.bbox().dim()); + const nanovdb::Vec3f xyz(off[0] + x * dim[0], off[1] + y * dim[1], off[2] + z * dim[2]); + + typedef nanovdb::ReadAccessor<nanovdb::NanoRoot<T>> ReadAccessorT; + switch (interpolation) { + default: + case INTERPOLATION_LINEAR: + return nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz); + case INTERPOLATION_CLOSEST: + return nanovdb::SampleFromVoxels<ReadAccessorT, 0, false>(root)(xyz); + case INTERPOLATION_CUBIC: + return nanovdb::SampleFromVoxels<ReadAccessorT, 3, false>(root)(xyz); + } +} +#endif + ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y) { const TextureInfo &info = kernel_tex_fetch(__texture_info, id); - CUtexObject tex = (CUtexObject)info.data; /* float4, byte4, ushort4 and half4 */ const int texture_type = info.data_type; if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) { if (info.interpolation == INTERPOLATION_CUBIC) { - return kernel_tex_image_interp_bicubic<float4>(info, tex, x, y); + return kernel_tex_image_interp_bicubic<float4>(info, x, y); } else { + CUtexObject tex = (CUtexObject)info.data; return tex2D<float4>(tex, x, y); } } @@ -139,9 +171,10 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl float f; if (info.interpolation == INTERPOLATION_CUBIC) { - f = kernel_tex_image_interp_bicubic<float>(info, tex, x, y); + f = kernel_tex_image_interp_bicubic<float>(info, x, y); } else { + CUtexObject tex = (CUtexObject)info.data; f = tex2D<float>(tex, x, y); } @@ -164,16 +197,27 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, const float y = P.y; const float z = P.z; - CUtexObject tex = (CUtexObject)info.data; uint interpolation = (interp == INTERPOLATION_NONE) ? info.interpolation : interp; - const int texture_type = info.data_type; + +#ifdef WITH_NANOVDB + if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT) { + float f = kernel_tex_image_interp_nanovdb<float>(info, x, y, z, interpolation); + return make_float4(f, f, f, 1.0f); + } + if (texture_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + nanovdb::Vec3f f = kernel_tex_image_interp_nanovdb<nanovdb::Vec3f>( + info, x, y, z, interpolation); + return make_float4(f[0], f[1], f[2], 1.0f); + } +#endif if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) { if (interpolation == INTERPOLATION_CUBIC) { - return kernel_tex_image_interp_bicubic_3d<float4>(info, tex, x, y, z); + return kernel_tex_image_interp_bicubic_3d<float4>(info, x, y, z); } else { + CUtexObject tex = (CUtexObject)info.data; return tex3D<float4>(tex, x, y, z); } } @@ -181,9 +225,10 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, float f; if (interpolation == INTERPOLATION_CUBIC) { - f = kernel_tex_image_interp_bicubic_3d<float>(info, tex, x, y, z); + f = kernel_tex_image_interp_bicubic_3d<float>(info, x, y, z); } else { + CUtexObject tex = (CUtexObject)info.data; f = tex3D<float>(tex, x, y, z); } diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h index 9ab374d1fba..2f44f249c5f 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h +++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h @@ -14,6 +14,11 @@ * limitations under the License. */ +#ifdef WITH_NANOVDB +# include "nanovdb/CNanoVDB.h" +# include "nanovdb/util/CSampleFromVoxels.h" +#endif + /* For OpenCL we do manual lookup and interpolation. */ ccl_device_inline ccl_global TextureInfo *kernel_tex_info(KernelGlobals *kg, uint id) @@ -223,6 +228,67 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float3 P uint interpolation = (interp == INTERPOLATION_NONE) ? info->interpolation : interp; +#ifdef WITH_NANOVDB + if (info->data_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT) { + ccl_global cnanovdb_griddata *grid = + (ccl_global cnanovdb_griddata *)(kg->buffers[info->cl_buffer] + info->data); + const ccl_global cnanovdb_rootdataF *root = cnanovdb_treedata_rootF( + cnanovdb_griddata_tree(grid)); + + cnanovdb_Vec3F xyz; + xyz.mVec[0] = root->mBBox_min.mVec[0] + + x * (root->mBBox_max.mVec[0] - root->mBBox_min.mVec[0]); + xyz.mVec[1] = root->mBBox_min.mVec[1] + + y * (root->mBBox_max.mVec[1] - root->mBBox_min.mVec[1]); + xyz.mVec[2] = root->mBBox_min.mVec[2] + + z * (root->mBBox_max.mVec[2] - root->mBBox_min.mVec[2]); + + cnanovdb_readaccessor acc; + cnanovdb_readaccessor_init(&acc, root); + + float value; + switch (interpolation) { + default: + case INTERPOLATION_LINEAR: + value = cnanovdb_sampleF_trilinear(&acc, &xyz); + break; + case INTERPOLATION_CLOSEST: + value = cnanovdb_sampleF_nearest(&acc, &xyz); + break; + } + return make_float4(value, value, value, 1.0f); + } + if (info->data_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + ccl_global cnanovdb_griddata *grid = + (ccl_global cnanovdb_griddata *)(kg->buffers[info->cl_buffer] + info->data); + const ccl_global cnanovdb_rootdataF3 *root = cnanovdb_treedata_rootF3( + cnanovdb_griddata_tree(grid)); + + cnanovdb_Vec3F xyz; + xyz.mVec[0] = root->mBBox_min.mVec[0] + + x * (root->mBBox_max.mVec[0] - root->mBBox_min.mVec[0]); + xyz.mVec[1] = root->mBBox_min.mVec[1] + + y * (root->mBBox_max.mVec[1] - root->mBBox_min.mVec[1]); + xyz.mVec[2] = root->mBBox_min.mVec[2] + + z * (root->mBBox_max.mVec[2] - root->mBBox_min.mVec[2]); + + cnanovdb_readaccessor acc; + cnanovdb_readaccessor_init(&acc, root); + + cnanovdb_Vec3F value; + switch (interpolation) { + default: + case INTERPOLATION_LINEAR: + value = cnanovdb_sampleF3_trilinear(&acc, &xyz); + break; + case INTERPOLATION_CLOSEST: + value = cnanovdb_sampleF3_nearest(&acc, &xyz); + break; + } + return make_float4(value.mVec[0], value.mVec[1], value.mVec[2], 1.0f); + } +#endif + if (interpolation == INTERPOLATION_CLOSEST) { /* Closest interpolation. */ int ix, iy, iz; diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 43e66aa4e5b..9663e25cd93 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -144,6 +144,12 @@ if(WITH_OPENVDB) ) endif() +if(WITH_NANOVDB) + list(APPEND INC_SYS + ${NANOVDB_INCLUDE_DIRS} + ) +endif() + include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index fd6186d8f1e..e50e70c8591 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -73,6 +73,10 @@ const char *name_from_type(ImageDataType type) return "ushort4"; case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_TYPE_NANOVDB_FLOAT: + return "nanovdb_float"; + case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: + return "nanovdb_float3"; case IMAGE_DATA_NUM_TYPES: assert(!"System enumerator type, should never be used"); return ""; @@ -210,6 +214,7 @@ ImageMetaData::ImageMetaData() width(0), height(0), depth(0), + byte_size(0), type(IMAGE_DATA_NUM_TYPES), colorspace(u_colorspace_raw), colorspace_file_format(""), @@ -756,6 +761,16 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro pixels[0] = TEX_IMAGE_MISSING_R; } } +#ifdef WITH_NANOVDB + else if (type == IMAGE_DATA_TYPE_NANOVDB_FLOAT || type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3) { + thread_scoped_lock device_lock(device_mutex); + void *pixels = img->mem->alloc(img->metadata.byte_size, 0); + + if (pixels != NULL) { + img->loader->load_pixels(img->metadata, pixels, img->metadata.byte_size, false); + } + } +#endif { thread_scoped_lock device_lock(device_mutex); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index cb059256ce3..c9eccb3468a 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -77,6 +77,7 @@ class ImageMetaData { /* Set by ImageLoader.load_metadata(). */ int channels; size_t width, height, depth; + size_t byte_size; ImageDataType type; /* Optional color space, defaults to raw. */ diff --git a/intern/cycles/render/image_oiio.cpp b/intern/cycles/render/image_oiio.cpp index c4f95c6b4bc..e9c87461822 100644 --- a/intern/cycles/render/image_oiio.cpp +++ b/intern/cycles/render/image_oiio.cpp @@ -209,6 +209,8 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata, case IMAGE_DATA_TYPE_FLOAT4: oiio_load_pixels<TypeDesc::FLOAT, float>(metadata, in, (float *)pixels); break; + case IMAGE_DATA_TYPE_NANOVDB_FLOAT: + case IMAGE_DATA_TYPE_NANOVDB_FLOAT3: case IMAGE_DATA_NUM_TYPES: break; } diff --git a/intern/cycles/render/image_vdb.cpp b/intern/cycles/render/image_vdb.cpp index 3f7dd45ee88..fc2cfe9874e 100644 --- a/intern/cycles/render/image_vdb.cpp +++ b/intern/cycles/render/image_vdb.cpp @@ -20,6 +20,9 @@ # include <openvdb/openvdb.h> # include <openvdb/tools/Dense.h> #endif +#ifdef WITH_NANOVDB +# include <nanovdb/util/OpenToNanoVDB.h> +#endif CCL_NAMESPACE_BEGIN @@ -53,41 +56,84 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) /* Set data type. */ if (grid->isType<openvdb::FloatGrid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid)); +# endif } else if (grid->isType<openvdb::Vec3fGrid>()) { metadata.channels = 3; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid)); +# endif } else if (grid->isType<openvdb::BoolGrid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid))); +# endif } else if (grid->isType<openvdb::DoubleGrid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid))); +# endif } else if (grid->isType<openvdb::Int32Grid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid))); +# endif } else if (grid->isType<openvdb::Int64Grid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid))); +# endif } else if (grid->isType<openvdb::Vec3IGrid>()) { metadata.channels = 3; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid))); +# endif } else if (grid->isType<openvdb::Vec3dGrid>()) { metadata.channels = 3; +# ifdef WITH_NANOVDB + nanogrid = nanovdb::openToNanoVDB( + openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid))); +# endif } else if (grid->isType<openvdb::MaskGrid>()) { metadata.channels = 1; +# ifdef WITH_NANOVDB + return false; // Unsupported +# endif } else { return false; } +# ifdef WITH_NANOVDB + metadata.byte_size = nanogrid.size(); + if (metadata.channels == 1) { + metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT; + } + else { + metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3; + } +# else if (metadata.channels == 1) { metadata.type = IMAGE_DATA_TYPE_FLOAT; } else { metadata.type = IMAGE_DATA_TYPE_FLOAT4; } +# endif /* Set transform from object space to voxel index. */ openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4(); @@ -113,7 +159,10 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool) { -#ifdef WITH_OPENVDB +#if defined(WITH_NANOVDB) + memcpy(pixels, nanogrid.data(), nanogrid.size()); + return true; +#elif defined(WITH_OPENVDB) if (grid->isType<openvdb::FloatGrid>()) { openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels); openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid), dense); @@ -183,6 +232,9 @@ void VDBImageLoader::cleanup() /* Free OpenVDB grid memory as soon as we can. */ grid.reset(); #endif +#ifdef WITH_NANOVDB + nanogrid.reset(); +#endif } bool VDBImageLoader::is_vdb_loader() const diff --git a/intern/cycles/render/image_vdb.h b/intern/cycles/render/image_vdb.h index 4500cfbfb88..71d10cc39f5 100644 --- a/intern/cycles/render/image_vdb.h +++ b/intern/cycles/render/image_vdb.h @@ -20,6 +20,9 @@ #ifdef WITH_OPENVDB # include <openvdb/openvdb.h> #endif +#ifdef WITH_NANOVDB +# include <nanovdb/util/GridHandle.h> +#endif #include "render/image.h" @@ -55,6 +58,9 @@ class VDBImageLoader : public ImageLoader { openvdb::GridBase::ConstPtr grid; openvdb::CoordBBox bbox; #endif +#ifdef WITH_NANOVDB + nanovdb::GridHandle<> nanogrid; +#endif }; CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_texture.h b/intern/cycles/util/util_texture.h index 863c2ea3124..b445ab1488f 100644 --- a/intern/cycles/util/util_texture.h +++ b/intern/cycles/util/util_texture.h @@ -57,6 +57,8 @@ typedef enum ImageDataType { IMAGE_DATA_TYPE_HALF = 5, IMAGE_DATA_TYPE_USHORT4 = 6, IMAGE_DATA_TYPE_USHORT = 7, + IMAGE_DATA_TYPE_NANOVDB_FLOAT = 8, + IMAGE_DATA_TYPE_NANOVDB_FLOAT3 = 9, IMAGE_DATA_NUM_TYPES } ImageDataType; @@ -73,8 +75,8 @@ typedef enum ImageAlphaType { IMAGE_ALPHA_NUM_TYPES, } ImageAlphaType; -#define IMAGE_DATA_TYPE_SHIFT 3 -#define IMAGE_DATA_TYPE_MASK 0x7 +#define IMAGE_DATA_TYPE_SHIFT 4 +#define IMAGE_DATA_TYPE_MASK 0xF /* Extension types for textures. * |