diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/CMakeLists.txt | 8 | ||||
-rw-r--r-- | intern/cycles/device/cuda/device_cuda_impl.cpp | 85 | ||||
-rw-r--r-- | intern/cycles/device/device_memory.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/device/opencl/device_opencl_impl.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 28 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_compat_optix.h | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h | 47 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h | 67 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h | 66 | ||||
-rw-r--r-- | intern/cycles/render/CMakeLists.txt | 6 | ||||
-rw-r--r-- | intern/cycles/render/image.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/render/image.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/image_oiio.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/image_vdb.cpp | 54 | ||||
-rw-r--r-- | intern/cycles/render/image_vdb.h | 6 | ||||
-rw-r--r-- | intern/cycles/util/util_texture.h | 6 |
16 files changed, 346 insertions, 52 deletions
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. * |