Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-12-08 14:44:32 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-12-08 14:44:32 +0300
commitd46305f7413f394a0b424662d816c96723b5e5bb (patch)
tree672c3b79846ec133f0582b77c32e50b1500c2516 /intern
parent0467ddc6744668706263515732b7dc6d1616bf89 (diff)
parent2e8914549b677dd0101ea17f64183a98db281510 (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h275
1 files changed, 150 insertions, 125 deletions
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
index 37ba0f692be..56c38d8101c 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
@@ -63,6 +63,16 @@ template<typename T> struct TextureInterpolator {
return make_float4(f, f, f, 1.0f);
}
+ static ccl_always_inline float4 read(const T *data,
+ int x, int y,
+ int width, int height)
+ {
+ if(x < 0 || y < 0 || x >= width || y >= height) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ return read(data[y * width + x]);
+ }
+
static ccl_always_inline int wrap_periodic(int x, int width)
{
x %= width;
@@ -83,145 +93,159 @@ template<typename T> struct TextureInterpolator {
return x - (float)i;
}
- static ccl_always_inline float4 interp(const TextureInfo& info, float x, float y)
- {
- if(UNLIKELY(!info.data))
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ /* ******** 2D interpolation ******** */
+ static ccl_always_inline float4 interp_closest(const TextureInfo& info,
+ float x, float y)
+ {
const T *data = (const T*)info.data;
- int width = info.width;
- int height = info.height;
- int ix, iy, nix, niy;
-
- if(info.interpolation == INTERPOLATION_CLOSEST) {
- frac(x*(float)width, &ix);
- frac(y*(float)height, &iy);
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy;
+ frac(x*(float)width, &ix);
+ frac(y*(float)height, &iy);
+ switch(info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ break;
+ case EXTENSION_CLIP:
+ if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- return read(data[ix + iy*width]);
+ }
+ ATTR_FALLTHROUGH;
+ case EXTENSION_EXTEND:
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
- else if(info.interpolation == INTERPOLATION_LINEAR) {
- float tx = frac(x*(float)width - 0.5f, &ix);
- float ty = frac(y*(float)height - 0.5f, &iy);
-
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
-
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
+ return read(data[ix + iy*width]);
+ }
- float4 r = (1.0f - ty)*(1.0f - tx)*read(data[ix + iy*width]);
- r += (1.0f - ty)*tx*read(data[nix + iy*width]);
- r += ty*(1.0f - tx)*read(data[ix + niy*width]);
- r += ty*tx*read(data[nix + niy*width]);
+ static ccl_always_inline float4 interp_linear(const TextureInfo& info,
+ float x, float y)
+ {
+ const T *data = (const T*)info.data;
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy, nix, niy;
+ const float tx = frac(x*(float)width - 0.5f, &ix);
+ const float ty = frac(y*(float)height - 0.5f, &iy);
+ switch(info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ break;
+ case EXTENSION_CLIP:
+ nix = ix + 1;
+ niy = iy + 1;
+ break;
+ case EXTENSION_EXTEND:
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ return (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, width, height) +
+ (1.0f - ty) * tx * read(data, nix, iy, width, height) +
+ ty * (1.0f - tx) * read(data, ix, niy, width, height) +
+ ty * tx * read(data, nix, niy, width, height);
+ }
- return r;
+ static ccl_always_inline float4 interp_cubic(const TextureInfo& info,
+ float x, float y)
+ {
+ const T *data = (const T*)info.data;
+ const int width = info.width;
+ const int height = info.height;
+ int ix, iy, nix, niy;
+ const float tx = frac(x*(float)width - 0.5f, &ix);
+ const float ty = frac(y*(float)height - 0.5f, &iy);
+ int pix, piy, nnix, nniy;
+ switch(info.extension) {
+ case EXTENSION_REPEAT:
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+ pix = wrap_periodic(ix-1, width);
+ piy = wrap_periodic(iy-1, height);
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+ nnix = wrap_periodic(ix+2, width);
+ nniy = wrap_periodic(iy+2, height);
+ break;
+ case EXTENSION_CLIP:
+ pix = ix - 1;
+ piy = iy - 1;
+ nix = ix + 1;
+ niy = iy + 1;
+ nnix = ix + 2;
+ nniy = iy + 2;
+ break;
+ case EXTENSION_EXTEND:
+ pix = wrap_clamp(ix-1, width);
+ piy = wrap_clamp(iy-1, height);
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+ nnix = wrap_clamp(ix+2, width);
+ nniy = wrap_clamp(iy+2, height);
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+ break;
+ default:
+ kernel_assert(0);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
- else {
- /* Bicubic b-spline interpolation. */
- float tx = frac(x*(float)width - 0.5f, &ix);
- float ty = frac(y*(float)height - 0.5f, &iy);
- int pix, piy, nnix, nniy;
- switch(info.extension) {
- case EXTENSION_REPEAT:
- ix = wrap_periodic(ix, width);
- iy = wrap_periodic(iy, height);
-
- pix = wrap_periodic(ix-1, width);
- piy = wrap_periodic(iy-1, height);
-
- nix = wrap_periodic(ix+1, width);
- niy = wrap_periodic(iy+1, height);
-
- nnix = wrap_periodic(ix+2, width);
- nniy = wrap_periodic(iy+2, height);
- break;
- case EXTENSION_CLIP:
- if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- ATTR_FALLTHROUGH;
- case EXTENSION_EXTEND:
- pix = wrap_clamp(ix-1, width);
- piy = wrap_clamp(iy-1, height);
-
- nix = wrap_clamp(ix+1, width);
- niy = wrap_clamp(iy+1, height);
-
- nnix = wrap_clamp(ix+2, width);
- nniy = wrap_clamp(iy+2, height);
-
- ix = wrap_clamp(ix, width);
- iy = wrap_clamp(iy, height);
- break;
- default:
- kernel_assert(0);
- return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
-
- const int xc[4] = {pix, ix, nix, nnix};
- const int yc[4] = {width * piy,
- width * iy,
- width * niy,
- width * nniy};
- float u[4], v[4];
- /* Some helper macro to keep code reasonable size,
- * let compiler to inline all the matrix multiplications.
- */
-#define DATA(x, y) (read(data[xc[x] + yc[y]]))
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {piy, iy, niy, nniy};
+ float u[4], v[4];
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
+#define DATA(x, y) (read(data, xc[x], yc[y], width, height))
#define TERM(col) \
- (v[col] * (u[0] * DATA(0, col) + \
- u[1] * DATA(1, col) + \
- u[2] * DATA(2, col) + \
- u[3] * DATA(3, col)))
+ (v[col] * (u[0] * DATA(0, col) + \
+ u[1] * DATA(1, col) + \
+ u[2] * DATA(2, col) + \
+ u[3] * DATA(3, col)))
- SET_CUBIC_SPLINE_WEIGHTS(u, tx);
- SET_CUBIC_SPLINE_WEIGHTS(v, ty);
-
- /* Actual interpolation. */
- return TERM(0) + TERM(1) + TERM(2) + TERM(3);
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ /* Actual interpolation. */
+ return TERM(0) + TERM(1) + TERM(2) + TERM(3);
#undef TERM
#undef DATA
+ }
+
+ static ccl_always_inline float4 interp(const TextureInfo& info,
+ float x, float y)
+ {
+ if(UNLIKELY(!info.data)) {
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ switch(info.interpolation) {
+ case INTERPOLATION_CLOSEST:
+ return interp_closest(info, x, y);
+ case INTERPOLATION_LINEAR:
+ return interp_linear(info, x, y);
+ default:
+ return interp_cubic(info, x, y);
}
}
- static ccl_always_inline float4 interp_3d_closest(const TextureInfo& info, float x, float y, float z)
+ /* ******** 3D interpolation ******** */
+
+ static ccl_always_inline float4 interp_3d_closest(const TextureInfo& info,
+ float x, float y, float z)
{
int width = info.width;
int height = info.height;
@@ -259,7 +283,8 @@ template<typename T> struct TextureInterpolator {
return read(data[ix + iy*width + iz*width*height]);
}
- static ccl_always_inline float4 interp_3d_linear(const TextureInfo& info, float x, float y, float z)
+ static ccl_always_inline float4 interp_3d_linear(const TextureInfo& info,
+ float x, float y, float z)
{
int width = info.width;
int height = info.height;