From 91c44fe88547ee4e4d78858d816068876a3db3c4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 29 Mar 2021 22:58:19 +0200 Subject: Cycles: disable NanoVDB for AMD OpenCL It is causing issue with AMD OpenCL drivers, due to a potential driver bug. Ref T84461 --- intern/cycles/blender/blender_image.cpp | 4 +- intern/cycles/blender/blender_image.h | 4 +- intern/cycles/blender/blender_volume.cpp | 2 +- intern/cycles/device/device.cpp | 2 + intern/cycles/device/device.h | 2 + intern/cycles/device/device_cpu.cpp | 1 + intern/cycles/device/device_cuda.cpp | 1 + intern/cycles/device/device_opencl.cpp | 3 + intern/cycles/device/opencl/device_opencl_impl.cpp | 4 +- intern/cycles/render/image.cpp | 18 +-- intern/cycles/render/image.h | 12 +- intern/cycles/render/image_oiio.cpp | 4 +- intern/cycles/render/image_oiio.h | 2 +- intern/cycles/render/image_sky.cpp | 2 +- intern/cycles/render/image_sky.h | 2 +- intern/cycles/render/image_vdb.cpp | 175 ++++++++++++--------- intern/cycles/render/image_vdb.h | 3 +- 17 files changed, 143 insertions(+), 98 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/blender_image.cpp b/intern/cycles/blender/blender_image.cpp index 459dc1779fb..3a9d159e461 100644 --- a/intern/cycles/blender/blender_image.cpp +++ b/intern/cycles/blender/blender_image.cpp @@ -29,7 +29,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image, int frame) { } -bool BlenderImageLoader::load_metadata(ImageMetaData &metadata) +bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) { metadata.width = b_image.size()[0]; metadata.height = b_image.size()[1]; @@ -171,7 +171,7 @@ BlenderPointDensityLoader::BlenderPointDensityLoader(BL::Depsgraph b_depsgraph, { } -bool BlenderPointDensityLoader::load_metadata(ImageMetaData &metadata) +bool BlenderPointDensityLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) { metadata.channels = 4; metadata.width = b_node.resolution(); diff --git a/intern/cycles/blender/blender_image.h b/intern/cycles/blender/blender_image.h index b58a159a6ba..fddbbfd9c37 100644 --- a/intern/cycles/blender/blender_image.h +++ b/intern/cycles/blender/blender_image.h @@ -27,7 +27,7 @@ class BlenderImageLoader : public ImageLoader { public: BlenderImageLoader(BL::Image b_image, int frame); - bool load_metadata(ImageMetaData &metadata) override; + bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override; bool load_pixels(const ImageMetaData &metadata, void *pixels, const size_t pixels_size, @@ -44,7 +44,7 @@ class BlenderPointDensityLoader : public ImageLoader { public: BlenderPointDensityLoader(BL::Depsgraph depsgraph, BL::ShaderNodeTexPointDensity b_node); - bool load_metadata(ImageMetaData &metadata) override; + bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override; bool load_pixels(const ImageMetaData &metadata, void *pixels, const size_t pixels_size, diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index 410f7a72cf5..0ff4de846e1 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -41,7 +41,7 @@ class BlenderSmokeLoader : public ImageLoader { mesh_texture_space(b_mesh, texspace_loc, texspace_size); } - bool load_metadata(ImageMetaData &metadata) override + bool load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) override { if (!b_domain) { return false; diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 94732cd1855..ed53fbb54ae 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -619,6 +619,7 @@ DeviceInfo Device::get_multi_device(const vector &subdevices, info.num = 0; info.has_half_images = true; + info.has_nanovdb = true; info.has_volume_decoupled = true; info.has_branched_path = true; info.has_adaptive_stop_per_sample = true; @@ -665,6 +666,7 @@ DeviceInfo Device::get_multi_device(const vector &subdevices, /* Accumulate device info. */ info.has_half_images &= device.has_half_images; + info.has_nanovdb &= device.has_nanovdb; info.has_volume_decoupled &= device.has_volume_decoupled; info.has_branched_path &= device.has_branched_path; info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample; diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 0a731969c79..b5468248e5a 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -78,6 +78,7 @@ class DeviceInfo { int num; bool display_device; /* GPU is used as a display device. */ bool has_half_images; /* Support half-float textures. */ + bool has_nanovdb; /* Support NanoVDB volumes. */ bool has_volume_decoupled; /* Decoupled volume shading. */ bool has_branched_path; /* Supports branched path tracing. */ bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */ @@ -99,6 +100,7 @@ class DeviceInfo { cpu_threads = 0; display_device = false; has_half_images = false; + has_nanovdb = false; has_volume_decoupled = false; has_branched_path = true; has_adaptive_stop_per_sample = false; diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index e2f9c7391da..0e3c771dbc3 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -1654,6 +1654,7 @@ void device_cpu_info(vector &devices) info.has_adaptive_stop_per_sample = true; info.has_osl = true; info.has_half_images = true; + info.has_nanovdb = true; info.has_profiling = true; info.denoisers = DENOISER_NLM; if (openimagedenoise_supported()) { diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index d9ffcceb06e..2e225ecfaf8 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -128,6 +128,7 @@ void device_cuda_info(vector &devices) info.num = num; info.has_half_images = (major >= 3); + info.has_nanovdb = true; info.has_volume_decoupled = false; info.has_adaptive_stop_per_sample = false; info.denoisers = DENOISER_NLM; diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 11376ee4883..9abb7cfb7fe 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -126,6 +126,9 @@ void device_opencl_info(vector &devices) /* Check OpenCL extensions */ info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos; + /* Disabled for now due to apparent AMD driver bug. */ + info.has_nanovdb = platform_name != "AMD Accelerated Parallel Processing"; + devices.push_back(info); num_devices++; } diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp index aee3b0fb64f..d378d32914c 100644 --- a/intern/cycles/device/opencl/device_opencl_impl.cpp +++ b/intern/cycles/device/opencl/device_opencl_impl.cpp @@ -2036,7 +2036,9 @@ string OpenCLDevice::kernel_build_options(const string *debug_src) # endif # ifdef WITH_NANOVDB - build_options += "-DWITH_NANOVDB "; + if (info.has_nanovdb) { + build_options += "-DWITH_NANOVDB "; + } # endif return build_options; diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 29a95beaf7e..27f9b7df1dd 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -303,7 +303,8 @@ ImageManager::ImageManager(const DeviceInfo &info) animation_frame = 0; /* Set image limits */ - has_half_images = info.has_half_images; + features.has_half_float = info.has_half_images; + features.has_nanovdb = info.has_nanovdb; } ImageManager::~ImageManager() @@ -347,7 +348,7 @@ void ImageManager::load_image_metadata(Image *img) metadata = ImageMetaData(); metadata.colorspace = img->params.colorspace; - if (img->loader->load_metadata(metadata)) { + if (img->loader->load_metadata(features, metadata)) { assert(metadata.type != IMAGE_DATA_NUM_TYPES); } else { @@ -356,15 +357,10 @@ void ImageManager::load_image_metadata(Image *img) metadata.detect_colorspace(); - /* No half textures on OpenCL, use full float instead. */ - if (!has_half_images) { - if (metadata.type == IMAGE_DATA_TYPE_HALF4) { - metadata.type = IMAGE_DATA_TYPE_FLOAT4; - } - else if (metadata.type == IMAGE_DATA_TYPE_HALF) { - metadata.type = IMAGE_DATA_TYPE_FLOAT; - } - } + assert(features.has_half_float || + (metadata.type != IMAGE_DATA_TYPE_HALF4 && metadata.type != IMAGE_DATA_TYPE_HALF)); + assert(features.has_nanovdb || (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT || + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3)); img->need_metadata = false; } diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index c802521db56..dede9513d5f 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -97,6 +97,13 @@ class ImageMetaData { void detect_colorspace(); }; +/* Information about supported features that Image loaders can use. */ +class ImageDeviceFeatures { + public: + bool has_half_float; + bool has_nanovdb; +}; + /* Image loader base class, that can be subclassed to load image data * from custom sources (file, memory, procedurally generated, etc). */ class ImageLoader { @@ -105,7 +112,7 @@ class ImageLoader { virtual ~ImageLoader(){}; /* Load metadata without actual image yet, should be fast. */ - virtual bool load_metadata(ImageMetaData &metadata) = 0; + virtual bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) = 0; /* Load actual image contents. */ virtual bool load_pixels(const ImageMetaData &metadata, @@ -212,7 +219,8 @@ class ImageManager { private: bool need_update_; - bool has_half_images; + + ImageDeviceFeatures features; thread_mutex device_mutex; thread_mutex images_mutex; diff --git a/intern/cycles/render/image_oiio.cpp b/intern/cycles/render/image_oiio.cpp index e9c87461822..4867efe6ac0 100644 --- a/intern/cycles/render/image_oiio.cpp +++ b/intern/cycles/render/image_oiio.cpp @@ -30,7 +30,7 @@ OIIOImageLoader::~OIIOImageLoader() { } -bool OIIOImageLoader::load_metadata(ImageMetaData &metadata) +bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) { /* Perform preliminary checks, with meaningful logging. */ if (!path_exists(filepath.string())) { @@ -76,7 +76,7 @@ bool OIIOImageLoader::load_metadata(ImageMetaData &metadata) } /* check if it's half float */ - if (spec.format == TypeDesc::HALF) { + if (spec.format == TypeDesc::HALF && features.has_half_float) { is_half = true; } diff --git a/intern/cycles/render/image_oiio.h b/intern/cycles/render/image_oiio.h index a234b968557..a6dbb168b65 100644 --- a/intern/cycles/render/image_oiio.h +++ b/intern/cycles/render/image_oiio.h @@ -26,7 +26,7 @@ class OIIOImageLoader : public ImageLoader { OIIOImageLoader(const string &filepath); ~OIIOImageLoader(); - bool load_metadata(ImageMetaData &metadata) override; + bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override; bool load_pixels(const ImageMetaData &metadata, void *pixels, diff --git a/intern/cycles/render/image_sky.cpp b/intern/cycles/render/image_sky.cpp index 0560907c63e..7f9b85836f8 100644 --- a/intern/cycles/render/image_sky.cpp +++ b/intern/cycles/render/image_sky.cpp @@ -40,7 +40,7 @@ SkyLoader::SkyLoader(float sun_elevation, SkyLoader::~SkyLoader(){}; -bool SkyLoader::load_metadata(ImageMetaData &metadata) +bool SkyLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) { metadata.width = 512; metadata.height = 128; diff --git a/intern/cycles/render/image_sky.h b/intern/cycles/render/image_sky.h index 686f4e5b885..89ff586e7fd 100644 --- a/intern/cycles/render/image_sky.h +++ b/intern/cycles/render/image_sky.h @@ -34,7 +34,7 @@ class SkyLoader : public ImageLoader { float ozone_density); ~SkyLoader(); - bool load_metadata(ImageMetaData &metadata) override; + bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override; bool load_pixels(const ImageMetaData &metadata, void *pixels, diff --git a/intern/cycles/render/image_vdb.cpp b/intern/cycles/render/image_vdb.cpp index 70b3de5a939..63e6214f1c8 100644 --- a/intern/cycles/render/image_vdb.cpp +++ b/intern/cycles/render/image_vdb.cpp @@ -34,7 +34,7 @@ VDBImageLoader::~VDBImageLoader() { } -bool VDBImageLoader::load_metadata(ImageMetaData &metadata) +bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) { #ifdef WITH_OPENVDB if (!grid) { @@ -56,55 +56,71 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) if (grid->isType()) { metadata.channels = 1; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast(grid)); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast(grid)); + } # endif } else if (grid->isType()) { metadata.channels = 3; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast(grid)); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast(grid)); + } # endif } else if (grid->isType()) { metadata.channels = 1; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { metadata.channels = 1; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { metadata.channels = 1; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { metadata.channels = 1; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::FloatGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { metadata.channels = 3; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::Vec3fGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::Vec3fGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { metadata.channels = 3; # ifdef WITH_NANOVDB - nanogrid = nanovdb::openToNanoVDB( - openvdb::Vec3fGrid(*openvdb::gridConstPtrCast(grid))); + if (features.has_nanovdb) { + nanogrid = nanovdb::openToNanoVDB( + openvdb::Vec3fGrid(*openvdb::gridConstPtrCast(grid))); + } # endif } else if (grid->isType()) { @@ -118,21 +134,25 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) } # 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; + if (nanogrid) { + 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 # endif + { + if (metadata.channels == 1) { + metadata.type = IMAGE_DATA_TYPE_FLOAT; + } + else { + metadata.type = IMAGE_DATA_TYPE_FLOAT4; + } + } /* Set transform from object space to voxel index. */ openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4(); @@ -143,13 +163,18 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) } } + Transform texture_to_index; # ifdef WITH_NANOVDB - Transform texture_to_index = transform_identity(); -# else - openvdb::Coord min = bbox.min(); - Transform texture_to_index = transform_translate(min.x(), min.y(), min.z()) * - transform_scale(dim.x(), dim.y(), dim.z()); + if (nanogrid) { + texture_to_index = transform_identity(); + } + else # endif + { + openvdb::Coord min = bbox.min(); + texture_to_index = transform_translate(min.x(), min.y(), min.z()) * + transform_scale(dim.x(), dim.y(), dim.z()); + } metadata.transform_3d = transform_inverse(index_to_object * texture_to_index); metadata.use_transform_3d = true; @@ -165,48 +190,52 @@ bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size { #ifdef WITH_OPENVDB # ifdef WITH_NANOVDB - memcpy(pixels, nanogrid.data(), nanogrid.size()); -# else - if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense( - bbox, (openvdb::Vec3f *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense( - bbox, (openvdb::Vec3f *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense( - bbox, (openvdb::Vec3f *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); - } - else if (grid->isType()) { - openvdb::tools::Dense dense(bbox, (float *)pixels); - openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + if (nanogrid) { + memcpy(pixels, nanogrid.data(), nanogrid.size()); } + else # endif + { + if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense( + bbox, (openvdb::Vec3f *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense( + bbox, (openvdb::Vec3f *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense( + bbox, (openvdb::Vec3f *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + else if (grid->isType()) { + openvdb::tools::Dense dense(bbox, (float *)pixels); + openvdb::tools::copyToDense(*openvdb::gridConstPtrCast(grid), dense); + } + } return true; #else (void)pixels; diff --git a/intern/cycles/render/image_vdb.h b/intern/cycles/render/image_vdb.h index 71d10cc39f5..763196f2a15 100644 --- a/intern/cycles/render/image_vdb.h +++ b/intern/cycles/render/image_vdb.h @@ -33,7 +33,8 @@ class VDBImageLoader : public ImageLoader { VDBImageLoader(const string &grid_name); ~VDBImageLoader(); - virtual bool load_metadata(ImageMetaData &metadata) override; + virtual bool load_metadata(const ImageDeviceFeatures &features, + ImageMetaData &metadata) override; virtual bool load_pixels(const ImageMetaData &metadata, void *pixels, -- cgit v1.2.3