Page MenuHome

Cycles: Fix usage of double floating precision in CNanoVDB
ClosedPublic

Authored by Sergey Sharybin (sergey) on Jan 19 2021, 11:07 AM.

Details

Summary

Double floating point precision is an extension of OpenCL, which might
not be implemented by certain drivers, such as Intel Xe graphics.

Cycles does not use double floating point precision, and there is no
need on keeping doubles unless there is an explicit decision to use
them.

This is a simple fix from Cycles side to replace double floating point
type with a type of same size and alignment rules. Inspired by Brecht
and Patrick.

Tested on NVidia Titan V and Radeon RX Vega M.

Diff Detail

Repository
rB Blender
Branch
cycles_nanovdb (branched from master)
Build Status
Buildable 12268
Build 12268: arc lint + arc unit

Event Timeline

Sergey Sharybin (sergey) requested review of this revision.Jan 19 2021, 11:07 AM
Sergey Sharybin (sergey) created this revision.

Problem is that volumes will still be converted to the NanoVDB structure (in cycles/render/image_vdb.cpp), despite the OpenCL kernels then not being able to interpret the data when compiled without WITH_NANOVDB (and therefore just not rendering volumes altogether).
So to disable NanoVDB selectively we'd have to somehow pass along the information that NanoVDB is not supported up to the image loader.

From the looks of it the double fields in NanoVDB are currently unused though (at least the way Cycles uses it), so it might indeed be easier to just do something like this in kernel_opencl_image.h:

#ifdef WITH_NANOVDB
#  ifndef __KERNEL_CL_KHR_FP64__
#    define double uint64_t
#  endif
#  include "nanovdb/CNanoVDB.h"
#  ifndef __KERNEL_CL_KHR_FP64__
#    undef double
#  endif
#endif
Max (maxim_d33) added a comment.EditedJan 19 2021, 3:33 PM

any details known if double datatype usage is justified,
like why not float ?

Problem is that volumes will still be converted to the NanoVDB structure

Ugh, missed that part.

From the looks of it the double fields in NanoVDB are currently unused though (at least the way Cycles uses it), so it might indeed be easier to just do something like this in kernel_opencl_image.h:

The doubles are indeed not used. The idea of placing define next to the # include "nanovdb/CNanoVDB.h" is better than do a global define. It will work for the current version of NanoVDB, but still feels fragile for the future. Is it the root we really want to follow?

One thing is I would suggest defining double to something like struct { uint64_t unused; }. This way we have better chance of catching moment when NanoVDB does require proper double floating point arithmetic.

@Max (maxim_d33) It's storing some matrices with double because the OpenVDB ones too are using double precision (so is done for the sake of preserving data, since it should be possible to do OpenVDB->NanoVDB->OpenVDB without data loss). But there are copies of the same matrices stored as float too, so the library user can decide which ones to use. In case of Cycles the single precision variants are used, so we really only need the double fields for correct data layout, but that could be achieved with some other placeholder type as well.

I think it's fine to do this workaround for now, considering that we lock in a specific NanoVDB version anyway. So if at one point we update to a newer version and things break (though I doubt that), things can be reevaluated.

I think a simple fix like this should be fine, no need to enable doubles on any OpenCL platform unless we actually plan to use them.

#ifdef WITH_NANOVDB
#  define double char[8]
#  include "nanovdb/CNanoVDB.h"
#  undef double
#endif

@Brecht Van Lommel (brecht), you patch seems all good to me. Do you want to commit it? Need help with testing?

I haven't tested it, would be convenient if you could verify it works and commit.

Used the idea of Patrick and Brecht.

Defined as a struct though, so that:

  • Alignment rules are the same as double.
  • All math operations are restricted.

Still need to test on TGL machine here.

Sergey Sharybin (sergey) retitled this revision from Cycles: Disable NanoVDB if OpenCL does not support doubles to Cycles: Fix usage of double floating precision in CNanoVDB.Jan 20 2021, 11:34 AM
Sergey Sharybin (sergey) edited the summary of this revision. (Show Details)
This revision is now accepted and ready to land.Jan 20 2021, 11:39 AM

I think it's fine to do this workaround for now, considering that we lock in a specific NanoVDB version anyway. So if at one point we update to a newer version and things break (though I doubt that), things can be reevaluated.

good suggestion.

Looks good for me as well.

With the patch kernels are compiled on the provided machine. During viewport rendering it fails to load the indirect_background kernels.
During image rendering it seems to work with the default cube.

I tested it on AMD Vega 64 with similar results (it fails loading a different kernel though) This also fails without this patch so seems ok to commit. It doesn't break what isn't already failing.