diff options
author | Geraldine Chua <chua.gsk@gmail.com> | 2018-08-12 12:14:29 +0300 |
---|---|---|
committer | Geraldine Chua <chua.gsk@gmail.com> | 2018-08-12 12:14:29 +0300 |
commit | 57beb92ccec7d4952636231fc54b106aacb17d55 (patch) | |
tree | 63db554f7ea2ad0eb6920ef0ce7780997d9aefad | |
parent | aa20e7b88f02544458467868423f48e878034e52 (diff) |
Minor bug-fixes and optimizations.
* Change most instances of division and modulo with TILE_SIZE to bit shifting. Much more efficient since TILE_SIZE should be a
power of 2.
* Added intialization for some Mesh members. Previously had motion blur randomly toggle on and off otherwise.
* Fixed issue where voxel to tile correspondence is different between external VDBs and internal sparse grids. The fix requires
generating a new VDB grid which may be too memory intensive. Better method would be translating grids in place.
* Fixed misc OpenVDB to grid conversion issues.
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h | 20 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h | 18 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/render/openvdb.cpp | 47 | ||||
-rw-r--r-- | intern/cycles/util/util_sparse_grid.h | 16 | ||||
-rw-r--r-- | intern/cycles/util/util_texture.h | 4 |
8 files changed, 70 insertions, 58 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 99f233524a4..6374c18d6fb 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -437,10 +437,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, Scene::MotionType need_motion = scene->need_motion(); if(need_motion != Scene::MOTION_NONE && object->mesh) { Mesh *mesh = object->mesh; - mesh->motion_steps = 0; - mesh->use_motion_blur = false; - mesh->use_volume_motion_blur = false; - uint motion_steps; if(scene->need_motion() == Scene::MOTION_BLUR) { diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h index bd5594b60f9..82f04300127 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h @@ -92,18 +92,18 @@ struct TextureInterpolator { const int *offsets, int x, int y, int z) { - int tix = x / TILE_SIZE, itix = x % TILE_SIZE, - tiy = y / TILE_SIZE, itiy = y % TILE_SIZE, - tiz = z / TILE_SIZE, itiz = z % TILE_SIZE; - int tile_index = tix + s_info.tiled_w * (tiy + tiz * s_info.tiled_h); - int sparse_index = offsets[tile_index]; - if(sparse_index < 0) { + int tile_start = offsets[(x >> TILE_INDEX_SHIFT) + + s_info.tiled_w + * ((y >> TILE_INDEX_SHIFT) + + (z >> TILE_INDEX_SHIFT) + * s_info.tiled_h)]; + if(tile_start < 0) { return make_float4(0.0f); } - int itiw = (x > s_info.div_w) ? s_info.remain_w : TILE_SIZE; - int itih = (y > s_info.div_h) ? s_info.remain_h : TILE_SIZE; - int in_tile_index = itix + itiw * (itiy + itiz * itih); - return read(data[sparse_index + in_tile_index]); + return read(data[tile_start + (x & TILE_INDEX_MASK) + + ((x > s_info.div_w) ? s_info.remain_w : TILE_SIZE) + * ((y & TILE_INDEX_MASK) + (z & TILE_INDEX_MASK) + * ((y > s_info.div_h) ? s_info.remain_h : TILE_SIZE))]); } static ccl_always_inline float4 read_data(const T *data, diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h index c1c302de598..097c984d63f 100644 --- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h +++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h @@ -67,22 +67,21 @@ ccl_device bool sparse_coordinates(const SparseTextureInfo *s_info, float &fx, f modff(fy, &iy); modff(fz, &iz); int x = int(ix), y = int(iy), z = int(iz); - int tix = x / TILE_SIZE, sx = (x % TILE_SIZE) + SPARSE_PAD, - tiy = y / TILE_SIZE, sy = (y % TILE_SIZE) + SPARSE_PAD, - tiz = z / TILE_SIZE, sz = (z % TILE_SIZE) + SPARSE_PAD; - int tile = tix + s_info->tiled_w * (tiy + tiz * s_info->tiled_h); + int tile = (x >> TILE_INDEX_SHIFT) + s_info->tiled_w + * ((y >> TILE_INDEX_SHIFT) + (z >> TILE_INDEX_SHIFT) * s_info->tiled_h); int start_x = offsets[tile]; if(start_x < 0) { return false; } + int in_tile_x = (x & TILE_INDEX_MASK) + SPARSE_PAD; if(x >= TILE_SIZE) { if(offsets[tile - 1] > -1) { - sx -= SPARSE_PAD; + in_tile_x -= SPARSE_PAD; } } - fx += float(start_x + sx); - fy += float(sy); - fz += float(sz); + fx += float(start_x + in_tile_x); + fy += float((y & TILE_INDEX_MASK) + SPARSE_PAD); + fz += float((z & TILE_INDEX_MASK) + SPARSE_PAD); return true; } diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h index 00bb0686b98..8f20251afd7 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h +++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h @@ -96,18 +96,16 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, const int *offsets, int id, int x, int y, int z) { - int tix = x / TILE_SIZE, itix = x % TILE_SIZE, - tiy = y / TILE_SIZE, itiy = y % TILE_SIZE, - tiz = z / TILE_SIZE, itiz = z % TILE_SIZE; - int tile_index = tix + s_info->tiled_w * (tiy + tiz * s_info->tiled_h); - int sparse_index = offsets[tile_index]; - if(sparse_index < 0) { + int tile_start = offsets[(x >> TILE_INDEX_SHIFT) + s_info->tiled_w + * ((y >> TILE_INDEX_SHIFT) + (z >> TILE_INDEX_SHIFT) * s_info->tiled_h)]; + if(tile_start < 0) { return make_float4(0.0f); } - int itiw = (x > s_info.div_w) ? s_info.remain_w : TILE_SIZE; - int itih = (y > s_info.div_h) ? s_info.remain_h : TILE_SIZE; - int in_tile_index = itix + itiw * (itiy + itiz * itih); - return svm_image_texture_read(kg, info, id, sparse_index + in_tile_index); + int index = tile_start + (x & TILE_INDEX_MASK) + + ((x > s_info.div_w) ? s_info.remain_w : TILE_SIZE) + * ((y & TILE_INDEX_MASK) + (z & TILE_INDEX_MASK) + * ((y > s_info.div_h) ? s_info.remain_h : TILE_SIZE)); + return svm_image_texture_read(kg, info, id, index); } ccl_device_inline float4 svm_image_texture_read_2d(KernelGlobals *kg, int id, int x, int y) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 955c7c57db5..d6bde6e5d9e 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -457,6 +457,10 @@ Mesh::Mesh() subd_params = NULL; patch_table = NULL; + + motion_steps = 0; + use_motion_blur = false; + use_volume_motion_blur = false; } Mesh::~Mesh() diff --git a/intern/cycles/render/openvdb.cpp b/intern/cycles/render/openvdb.cpp index 0420879ad92..a3dba94c6b3 100644 --- a/intern/cycles/render/openvdb.cpp +++ b/intern/cycles/render/openvdb.cpp @@ -20,7 +20,7 @@ namespace { /* Misc internal helper functions. */ -template <typename T> bool gte_any(const T &a, const float &b) { return float(a) > b; } +template <typename T> bool gte_any(const T &a, const float &b) { return float(a) >= b; } template <> bool gte_any(const openvdb::math::Vec3d &a, const float &b) { return float(a.x()) >= b || float(a.y()) >= b || float(a.z()) >= b; @@ -60,9 +60,9 @@ template <> void copy(float *des, const openvdb::math::Vec3s *src) const int get_tile_index(const openvdb::math::Coord &start, const openvdb::math::Coord &tiled_res) { - return compute_index(start.x() / TILE_SIZE, - start.y() / TILE_SIZE, - start.z() / TILE_SIZE, + return compute_index(start.x() >> TILE_INDEX_SHIFT, + start.y() >> TILE_INDEX_SHIFT, + start.z() >> TILE_INDEX_SHIFT, tiled_res.x(), tiled_res.y()); } @@ -201,7 +201,8 @@ bool get_grid(const string &filepath, } template <typename GridType, typename T> -bool validate_and_process_grid(typename GridType::Ptr grid) +bool validate_and_process_grid(typename GridType::Ptr &grid, + const openvdb::math::Coord min_bound) { using namespace openvdb; @@ -218,6 +219,17 @@ bool validate_and_process_grid(typename GridType::Ptr grid) } } + /* Translate grid to start at origin. */ + if(min_bound[0] != 0 || min_bound[1] != 0 || min_bound[2] != 0) { + typename GridType::Ptr new_grid = GridType::create(); + math::Mat4d xform = math::Mat4d::identity(); + math::Vec3d translation(-min_bound[0], -min_bound[1], -min_bound[2]); + xform.setTranslation(translation); + tools::GridTransformer transformer(xform); + transformer.transformGrid<tools::PointSampler, GridType>(*grid, *new_grid); + grid = new_grid; + } + /* Need to account for external grids with a non-zero background value. * May have strange results depending on the grid. */ const T background_value = grid->background(); @@ -246,7 +258,7 @@ void image_load_preprocess(openvdb::GridBase::Ptr grid_base, using namespace openvdb; typename GridType::Ptr grid = gridPtrCast<GridType>(grid_base); - if(!validate_and_process_grid<GridType, T>(grid)) { + if(!validate_and_process_grid<GridType, T>(grid, min_bound)) { return; } @@ -264,10 +276,10 @@ void image_load_preprocess(openvdb::GridBase::Ptr grid_base, const typename GridType::TreeType::LeafNodeType *leaf = iter.getLeaf(); const T *data = leaf->buffer().data(); - for(int i = 0; i < TILE_SIZE * TILE_SIZE * TILE_SIZE * channels; ++i) { + for(int i = 0; i < TILE_SIZE * TILE_SIZE * TILE_SIZE; ++i) { if(gte_any(data[i], threshold)) { - const math::Coord tile_start = leaf->getNodeBoundingBox().getStart() - min_bound; - sparse_indexes->at(get_tile_index(tile_start, tiled_res)) = 0; + const math::Coord tile_start = leaf->getNodeBoundingBox().getStart(); + sparse_indexes->at(get_tile_index(tile_start, tiled_res)) = voxel_count; /* Calculate how many voxels are in this tile. */ voxel_count += coord_product(get_tile_dim(tile_start, resolution, remainder)); break; @@ -303,7 +315,7 @@ void image_load_dense(openvdb::GridBase::Ptr grid_base, using namespace openvdb; typename GridType::Ptr grid = gridPtrCast<GridType>(grid_base); - if(!validate_and_process_grid<GridType, T>(grid)) { + if(!validate_and_process_grid<GridType, T>(grid, min_bound)) { return; } @@ -318,7 +330,7 @@ void image_load_dense(openvdb::GridBase::Ptr grid_base, for (typename GridType::TreeType::LeafCIter iter = grid->tree().cbeginLeaf(); iter; ++iter) { const typename GridType::TreeType::LeafNodeType *leaf = iter.getLeaf(); const T *leaf_data = leaf->buffer().data(); - const math::Coord tile_start = leaf->getNodeBoundingBox().getStart() - min_bound; + const math::Coord tile_start = leaf->getNodeBoundingBox().getStart(); const math::Coord tile_dim = get_tile_dim(tile_start, resolution, remainder); for (int k = 0; k < tile_dim.z(); ++k) { @@ -330,7 +342,7 @@ void image_load_dense(openvdb::GridBase::Ptr grid_base, resolution.x(), resolution.y()); /* Index computation by coordinates is reversed in VDB grids. */ - int leaf_index = compute_index(k, j, i, tile_dim.z(), tile_dim.y()); + int leaf_index = compute_index(k, j, i, TILE_SIZE, TILE_SIZE); copy(data + data_index, leaf_data + leaf_index); } } @@ -349,7 +361,7 @@ void image_load_sparse(openvdb::GridBase::Ptr grid_base, using namespace openvdb; typename GridType::Ptr grid = gridPtrCast<GridType>(grid_base); - if(!validate_and_process_grid<GridType, T>(grid)) { + if(!validate_and_process_grid<GridType, T>(grid, min_bound)) { return; } @@ -364,21 +376,20 @@ void image_load_sparse(openvdb::GridBase::Ptr grid_base, for (typename GridType::TreeType::LeafCIter iter = grid->tree().cbeginLeaf(); iter; ++iter) { const typename GridType::TreeType::LeafNodeType *leaf = iter.getLeaf(); - const math::Coord tile_start = leaf->getNodeBoundingBox().getStart() - min_bound; + const math::Coord tile_start = leaf->getNodeBoundingBox().getStart(); int tile_index = get_tile_index(tile_start, tiled_res); - if(sparse_indexes->at(tile_index) == -1) { + if(sparse_indexes->at(tile_index) < 0) { continue; } - sparse_indexes->at(tile_index) = voxel_count / channels; + float *data_tile = data + sparse_indexes->at(tile_index); const math::Coord tile_dim = get_tile_dim(tile_start, resolution, remainder); const T *leaf_tile = leaf->buffer().data(); - float *data_tile = data + voxel_count; for(int k = 0; k < tile_dim.z(); ++k) { for(int j = 0; j < tile_dim.y(); ++j) { for(int i = 0; i < tile_dim.x(); ++i, ++voxel_count) { - int data_index = compute_index(i, j, k, tile_dim.x(), tile_dim.y()); + int data_index = compute_index(i, j, k, tile_dim.x(), tile_dim.y()) * channels; /* Index computation by coordinates is reversed in VDB grids. */ int leaf_index = compute_index(k, j, i, TILE_SIZE, TILE_SIZE); copy(data_tile + data_index, leaf_tile + leaf_index); diff --git a/intern/cycles/util/util_sparse_grid.h b/intern/cycles/util/util_sparse_grid.h index 4e84b41e7bb..b12f1fb9451 100644 --- a/intern/cycles/util/util_sparse_grid.h +++ b/intern/cycles/util/util_sparse_grid.h @@ -52,7 +52,7 @@ const inline int compute_index(const size_t x, const size_t y, const size_t z, const inline int get_tile_res(const size_t res) { - return (res / TILE_SIZE) + (res % TILE_SIZE != 0); + return (res >> TILE_INDEX_SHIFT) + ((res & TILE_INDEX_MASK) != 0); } const inline int compute_index(const int *offsets, @@ -61,9 +61,9 @@ const inline int compute_index(const int *offsets, { /* Get coordinates of voxel's tile in tiled image space and coordinates of * voxel in tile space. */ - int tix = x / TILE_SIZE, itix = x % TILE_SIZE, - tiy = y / TILE_SIZE, itiy = y % TILE_SIZE, - tiz = z / TILE_SIZE, itiz = z % TILE_SIZE; + int tix = x >> TILE_INDEX_SHIFT, itix = x & TILE_INDEX_MASK, + tiy = y >> TILE_INDEX_SHIFT, itiy = y & TILE_INDEX_MASK, + tiz = z >> TILE_INDEX_SHIFT, itiz = z & TILE_INDEX_MASK; /* Get flat index of voxel's tile. */ int tile = compute_index(tix, tiy, tiz, get_tile_res(width), @@ -79,7 +79,7 @@ const inline int compute_index(const int *offsets, } /* If the tile is the last tile in a direction and the end is truncated, we * have to recalulate itiN with the truncated length. */ - int remainder_w = width % TILE_SIZE, remainder_h = height % TILE_SIZE; + int remainder_w = width & TILE_INDEX_MASK, remainder_h = height & TILE_INDEX_MASK; int itiw = (x > width - remainder_w) ? remainder_w : TILE_SIZE; int itih = (y > height - remainder_h) ? remainder_h : TILE_SIZE; /* Get flat index of voxel in tile space. */ @@ -95,9 +95,9 @@ const inline int compute_index_pad(const int *offsets, /* Get coordinates of voxel's tile in tiled image space and coordinates of * voxel in tile space. In-tile y and z coordinates assume a pad on * the tile's minimum bound. */ - int tix = x / TILE_SIZE, sx = (x % TILE_SIZE) + SPARSE_PAD, - tiy = y / TILE_SIZE, sy = (y % TILE_SIZE) + SPARSE_PAD, - tiz = z / TILE_SIZE, sz = (z % TILE_SIZE) + SPARSE_PAD; + int tix = x >> TILE_INDEX_SHIFT, sx = (x & TILE_INDEX_MASK) + SPARSE_PAD, + tiy = y >> TILE_INDEX_SHIFT, sy = (y & TILE_INDEX_MASK) + SPARSE_PAD, + tiz = z >> TILE_INDEX_SHIFT, sz = (z & TILE_INDEX_MASK) + SPARSE_PAD; /* Get flat index of voxel's tile. */ int tile = compute_index(tix, tiy, tiz, get_tile_res(width), diff --git a/intern/cycles/util/util_texture.h b/intern/cycles/util/util_texture.h index ae5a5926c91..3695242d458 100644 --- a/intern/cycles/util/util_texture.h +++ b/intern/cycles/util/util_texture.h @@ -113,6 +113,10 @@ typedef struct TextureInfo { /* Sparse tile size and padding settings. */ #define TILE_SIZE 8 +/* For bit operations instead of division/modulo of TILE_SIZE */ +#define TILE_INDEX_SHIFT 3 +#define TILE_INDEX_MASK 0x7 + #define SPARSE_PAD 1 #define PADDED_TILE (TILE_SIZE + SPARSE_PAD * 2) |