Blender  V3.3
cycles/kernel/device/cpu/image.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 #ifdef WITH_NANOVDB
7 # define NANOVDB_USE_INTRINSICS
8 # include <nanovdb/NanoVDB.h>
9 # include <nanovdb/util/SampleFromVoxels.h>
10 #endif
11 
13 
14 /* Make template functions private so symbols don't conflict between kernels with different
15  * instruction sets. */
16 namespace {
17 
18 #define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
19  { \
20  u[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f); \
21  u[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f); \
22  u[2] = ((-0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f / 6.0f); \
23  u[3] = (1.0f / 6.0f) * t * t * t; \
24  } \
25  (void)0
26 
27 ccl_device_inline float frac(float x, int *ix)
28 {
29  int i = float_to_int(x) - ((x < 0.0f) ? 1 : 0);
30  *ix = i;
31  return x - (float)i;
32 }
33 
34 template<typename TexT, typename OutT = float4> struct TextureInterpolator {
35 
36  static ccl_always_inline OutT zero()
37  {
38  if constexpr (std::is_same<OutT, float4>::value) {
39  return zero_float4();
40  }
41  else {
42  return 0.0f;
43  }
44  }
45 
47  {
48  return r;
49  }
50 
52  {
53  const float f = 1.0f / 255.0f;
54  return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
55  }
56 
57  static ccl_always_inline float read(uchar r)
58  {
59  return r * (1.0f / 255.0f);
60  }
61 
62  static ccl_always_inline float read(float r)
63  {
64  return r;
65  }
66 
68  {
69  return half4_to_float4_image(r);
70  }
71 
72  static ccl_always_inline float read(half r)
73  {
74  return half_to_float_image(r);
75  }
76 
78  {
79  return r * (1.0f / 65535.0f);
80  }
81 
83  {
84  const float f = 1.0f / 65535.0f;
85  return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
86  }
87 
88  /* Read 2D Texture Data
89  * Does not check if data request is in bounds. */
90  static ccl_always_inline OutT read(const TexT *data, int x, int y, int width, int height)
91  {
92  return read(data[y * width + x]);
93  }
94 
95  /* Read 2D Texture Data Clip
96  * Returns transparent black if data request is out of bounds. */
97  static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int width, int height)
98  {
99  if (x < 0 || x >= width || y < 0 || y >= height) {
100  return zero();
101  }
102  return read(data[y * width + x]);
103  }
104 
105  /* Read 3D Texture Data
106  * Does not check if data request is in bounds. */
107  static ccl_always_inline OutT
108  read(const TexT *data, int x, int y, int z, int width, int height, int depth)
109  {
110  return read(data[x + y * width + z * width * height]);
111  }
112 
113  /* Read 3D Texture Data Clip
114  * Returns transparent black if data request is out of bounds. */
115  static ccl_always_inline OutT
116  read_clip(const TexT *data, int x, int y, int z, int width, int height, int depth)
117  {
118  if (x < 0 || x >= width || y < 0 || y >= height || z < 0 || z >= depth) {
119  return zero();
120  }
121  return read(data[x + y * width + z * width * height]);
122  }
123 
124  /* Trilinear Interpolation */
125  static ccl_always_inline OutT
126  trilinear_lookup(const TexT *data,
127  float tx,
128  float ty,
129  float tz,
130  int ix,
131  int iy,
132  int iz,
133  int nix,
134  int niy,
135  int niz,
136  int width,
137  int height,
138  int depth,
139  OutT read(const TexT *, int, int, int, int, int, int))
140  {
141  OutT r = (1.0f - tz) * (1.0f - ty) * (1.0f - tx) *
142  read(data, ix, iy, iz, width, height, depth);
143  r += (1.0f - tz) * (1.0f - ty) * tx * read(data, nix, iy, iz, width, height, depth);
144  r += (1.0f - tz) * ty * (1.0f - tx) * read(data, ix, niy, iz, width, height, depth);
145  r += (1.0f - tz) * ty * tx * read(data, nix, niy, iz, width, height, depth);
146 
147  r += tz * (1.0f - ty) * (1.0f - tx) * read(data, ix, iy, niz, width, height, depth);
148  r += tz * (1.0f - ty) * tx * read(data, nix, iy, niz, width, height, depth);
149  r += tz * ty * (1.0f - tx) * read(data, ix, niy, niz, width, height, depth);
150  r += tz * ty * tx * read(data, nix, niy, niz, width, height, depth);
151  return r;
152  }
153 
155  static ccl_always_inline OutT
156  tricubic_lookup(const TexT *data,
157  float tx,
158  float ty,
159  float tz,
160  const int xc[4],
161  const int yc[4],
162  const int zc[4],
163  int width,
164  int height,
165  int depth,
166  OutT read(const TexT *, int, int, int, int, int, int))
167  {
168  float u[4], v[4], w[4];
169 
170  /* Some helper macros to keep code size reasonable.
171  * Lets the compiler inline all the matrix multiplications.
172  */
173 #define DATA(x, y, z) (read(data, xc[x], yc[y], zc[z], width, height, depth))
174 #define COL_TERM(col, row) \
175  (v[col] * (u[0] * DATA(0, col, row) + u[1] * DATA(1, col, row) + u[2] * DATA(2, col, row) + \
176  u[3] * DATA(3, col, row)))
177 #define ROW_TERM(row) \
178  (w[row] * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
179 
183  /* Actual interpolation. */
184  return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
185 
186 #undef COL_TERM
187 #undef ROW_TERM
188 #undef DATA
189  }
190 
191  static ccl_always_inline int wrap_periodic(int x, int width)
192  {
193  x %= width;
194  if (x < 0) {
195  x += width;
196  }
197  return x;
198  }
199 
200  static ccl_always_inline int wrap_clamp(int x, int width)
201  {
202  return clamp(x, 0, width - 1);
203  }
204 
205  /* ******** 2D interpolation ******** */
206 
207  static ccl_always_inline OutT interp_closest(const TextureInfo &info, float x, float y)
208  {
209  const int width = info.width;
210  const int height = info.height;
211  int ix, iy;
212  frac(x * (float)width, &ix);
213  frac(y * (float)height, &iy);
214  switch (info.extension) {
215  case EXTENSION_REPEAT:
216  ix = wrap_periodic(ix, width);
217  iy = wrap_periodic(iy, height);
218  break;
219  case EXTENSION_CLIP:
220  /* No samples are inside the clip region. */
221  if (ix < 0 || ix >= width || iy < 0 || iy >= height) {
222  return zero();
223  }
224  break;
225  case EXTENSION_EXTEND:
226  ix = wrap_clamp(ix, width);
227  iy = wrap_clamp(iy, height);
228  break;
229  default:
230  kernel_assert(0);
231  return zero();
232  }
233 
234  const TexT *data = (const TexT *)info.data;
235  return read((const TexT *)data, ix, iy, width, height);
236  }
237 
238  static ccl_always_inline OutT interp_linear(const TextureInfo &info, float x, float y)
239  {
240  const int width = info.width;
241  const int height = info.height;
242 
243  /* A -0.5 offset is used to center the linear samples around the sample point. */
244  int ix, iy;
245  int nix, niy;
246  const float tx = frac(x * (float)width - 0.5f, &ix);
247  const float ty = frac(y * (float)height - 0.5f, &iy);
248 
249  switch (info.extension) {
250  case EXTENSION_REPEAT:
251  ix = wrap_periodic(ix, width);
252  nix = wrap_periodic(ix + 1, width);
253 
254  iy = wrap_periodic(iy, height);
255  niy = wrap_periodic(iy + 1, height);
256  break;
257  case EXTENSION_CLIP:
258  /* No linear samples are inside the clip region. */
259  if (ix < -1 || ix >= width || iy < -1 || iy >= height) {
260  return zero();
261  }
262  nix = ix + 1;
263  niy = iy + 1;
264  break;
265  case EXTENSION_EXTEND:
266  nix = wrap_clamp(ix + 1, width);
267  ix = wrap_clamp(ix, width);
268  niy = wrap_clamp(iy + 1, height);
269  iy = wrap_clamp(iy, height);
270  break;
271  default:
272  kernel_assert(0);
273  return zero();
274  }
275 
276  const TexT *data = (const TexT *)info.data;
277  return (1.0f - ty) * (1.0f - tx) * read_clip(data, ix, iy, width, height) +
278  (1.0f - ty) * tx * read_clip(data, nix, iy, width, height) +
279  ty * (1.0f - tx) * read_clip(data, ix, niy, width, height) +
280  ty * tx * read_clip(data, nix, niy, width, height);
281  }
282 
283  static ccl_always_inline OutT interp_cubic(const TextureInfo &info, float x, float y)
284  {
285  const int width = info.width;
286  const int height = info.height;
287 
288  /* A -0.5 offset is used to center the cubic samples around the sample point. */
289  int ix, iy;
290  const float tx = frac(x * (float)width - 0.5f, &ix);
291  const float ty = frac(y * (float)height - 0.5f, &iy);
292 
293  int pix, piy;
294  int nix, niy;
295  int nnix, nniy;
296 
297  switch (info.extension) {
298  case EXTENSION_REPEAT:
299  ix = wrap_periodic(ix, width);
300  pix = wrap_periodic(ix - 1, width);
301  nix = wrap_periodic(ix + 1, width);
302  nnix = wrap_periodic(ix + 2, width);
303 
304  iy = wrap_periodic(iy, height);
305  piy = wrap_periodic(iy - 1, height);
306  niy = wrap_periodic(iy + 1, height);
307  nniy = wrap_periodic(iy + 2, height);
308  break;
309  case EXTENSION_CLIP:
310  /* No cubic samples are inside the clip region. */
311  if (ix < -2 || ix > width || iy < -2 || iy > height) {
312  return zero();
313  }
314 
315  pix = ix - 1;
316  nix = ix + 1;
317  nnix = ix + 2;
318 
319  piy = iy - 1;
320  niy = iy + 1;
321  nniy = iy + 2;
322  break;
323  case EXTENSION_EXTEND:
324  pix = wrap_clamp(ix - 1, width);
325  nix = wrap_clamp(ix + 1, width);
326  nnix = wrap_clamp(ix + 2, width);
327  ix = wrap_clamp(ix, width);
328 
329  piy = wrap_clamp(iy - 1, height);
330  niy = wrap_clamp(iy + 1, height);
331  nniy = wrap_clamp(iy + 2, height);
332  iy = wrap_clamp(iy, height);
333  break;
334  default:
335  kernel_assert(0);
336  return zero();
337  }
338 
339  const TexT *data = (const TexT *)info.data;
340  const int xc[4] = {pix, ix, nix, nnix};
341  const int yc[4] = {piy, iy, niy, nniy};
342  float u[4], v[4];
343 
344  /* Some helper macros to keep code size reasonable.
345  * Lets the compiler inline all the matrix multiplications.
346  */
347 #define DATA(x, y) (read_clip(data, xc[x], yc[y], width, height))
348 #define TERM(col) \
349  (v[col] * \
350  (u[0] * DATA(0, col) + u[1] * DATA(1, col) + u[2] * DATA(2, col) + u[3] * DATA(3, col)))
351 
354 
355  /* Actual interpolation. */
356  return TERM(0) + TERM(1) + TERM(2) + TERM(3);
357 #undef TERM
358 #undef DATA
359  }
360 
361  static ccl_always_inline OutT interp(const TextureInfo &info, float x, float y)
362  {
363  switch (info.interpolation) {
365  return interp_closest(info, x, y);
367  return interp_linear(info, x, y);
368  default:
369  return interp_cubic(info, x, y);
370  }
371  }
372 
373  /* ******** 3D interpolation ******** */
374 
376  float x,
377  float y,
378  float z)
379  {
380  const int width = info.width;
381  const int height = info.height;
382  const int depth = info.depth;
383  int ix, iy, iz;
384 
385  frac(x * (float)width, &ix);
386  frac(y * (float)height, &iy);
387  frac(z * (float)depth, &iz);
388 
389  switch (info.extension) {
390  case EXTENSION_REPEAT:
391  ix = wrap_periodic(ix, width);
392  iy = wrap_periodic(iy, height);
393  iz = wrap_periodic(iz, depth);
394  break;
395  case EXTENSION_CLIP:
396  /* No samples are inside the clip region. */
397  if (ix < 0 || ix >= width || iy < 0 || iy >= height || iz < 0 || iz >= depth) {
398  return zero();
399  }
400  break;
401  case EXTENSION_EXTEND:
402  ix = wrap_clamp(ix, width);
403  iy = wrap_clamp(iy, height);
404  iz = wrap_clamp(iz, depth);
405  break;
406  default:
407  kernel_assert(0);
408  return zero();
409  }
410 
411  const TexT *data = (const TexT *)info.data;
412  return read(data, ix, iy, iz, width, height, depth);
413  }
414 
416  float x,
417  float y,
418  float z)
419  {
420  const int width = info.width;
421  const int height = info.height;
422  const int depth = info.depth;
423  int ix, iy, iz;
424  int nix, niy, niz;
425 
426  /* A -0.5 offset is used to center the linear samples around the sample point. */
427  float tx = frac(x * (float)width - 0.5f, &ix);
428  float ty = frac(y * (float)height - 0.5f, &iy);
429  float tz = frac(z * (float)depth - 0.5f, &iz);
430 
431  switch (info.extension) {
432  case EXTENSION_REPEAT:
433  ix = wrap_periodic(ix, width);
434  nix = wrap_periodic(ix + 1, width);
435 
436  iy = wrap_periodic(iy, height);
437  niy = wrap_periodic(iy + 1, height);
438 
439  iz = wrap_periodic(iz, depth);
440  niz = wrap_periodic(iz + 1, depth);
441  break;
442  case EXTENSION_CLIP:
443  /* No linear samples are inside the clip region. */
444  if (ix < -1 || ix >= width || iy < -1 || iy >= height || iz < -1 || iz >= depth) {
445  return zero();
446  }
447 
448  nix = ix + 1;
449  niy = iy + 1;
450  niz = iz + 1;
451 
452  /* All linear samples are inside the clip region. */
453  if (ix >= 0 && nix < width && iy >= 0 && niy < height && iz >= 0 && niz < depth) {
454  break;
455  }
456 
457  /* The linear samples span the clip border.
458  * #read_clip is used to ensure proper interpolation across the clip border. */
459  return trilinear_lookup((const TexT *)info.data,
460  tx,
461  ty,
462  tz,
463  ix,
464  iy,
465  iz,
466  nix,
467  niy,
468  niz,
469  width,
470  height,
471  depth,
472  read_clip);
473  case EXTENSION_EXTEND:
474  nix = wrap_clamp(ix + 1, width);
475  ix = wrap_clamp(ix, width);
476 
477  niy = wrap_clamp(iy + 1, height);
478  iy = wrap_clamp(iy, height);
479 
480  niz = wrap_clamp(iz + 1, depth);
481  iz = wrap_clamp(iz, depth);
482  break;
483  default:
484  kernel_assert(0);
485  return zero();
486  }
487 
488  return trilinear_lookup((const TexT *)info.data,
489  tx,
490  ty,
491  tz,
492  ix,
493  iy,
494  iz,
495  nix,
496  niy,
497  niz,
498  width,
499  height,
500  depth,
501  read);
502  }
503 
504  /* Tricubic b-spline interpolation.
505  *
506  * TODO(sergey): For some unspeakable reason both GCC-6 and Clang-3.9 are
507  * causing stack overflow issue in this function unless it is inlined.
508  *
509  * Only happens for AVX2 kernel and global __KERNEL_SSE__ vectorization
510  * enabled.
511  */
512 #if defined(__GNUC__) || defined(__clang__)
513  static ccl_always_inline
514 #else
515  static ccl_never_inline
516 #endif
517  OutT
518  interp_3d_cubic(const TextureInfo &info, float x, float y, float z)
519  {
520  int width = info.width;
521  int height = info.height;
522  int depth = info.depth;
523  int ix, iy, iz;
524 
525  /* A -0.5 offset is used to center the cubic samples around the sample point. */
526  const float tx = frac(x * (float)width - 0.5f, &ix);
527  const float ty = frac(y * (float)height - 0.5f, &iy);
528  const float tz = frac(z * (float)depth - 0.5f, &iz);
529 
530  int pix, piy, piz;
531  int nix, niy, niz;
532  int nnix, nniy, nniz;
533 
534  switch (info.extension) {
535  case EXTENSION_REPEAT:
536  ix = wrap_periodic(ix, width);
537  pix = wrap_periodic(ix - 1, width);
538  nix = wrap_periodic(ix + 1, width);
539  nnix = wrap_periodic(ix + 2, width);
540 
541  iy = wrap_periodic(iy, height);
542  niy = wrap_periodic(iy + 1, height);
543  piy = wrap_periodic(iy - 1, height);
544  nniy = wrap_periodic(iy + 2, height);
545 
546  iz = wrap_periodic(iz, depth);
547  piz = wrap_periodic(iz - 1, depth);
548  niz = wrap_periodic(iz + 1, depth);
549  nniz = wrap_periodic(iz + 2, depth);
550  break;
551  case EXTENSION_CLIP: {
552  /* No cubic samples are inside the clip region. */
553  if (ix < -2 || ix > width || iy < -2 || iy > height || iz < -2 || iz > depth) {
554  return zero();
555  }
556 
557  pix = ix - 1;
558  nnix = ix + 2;
559  nix = ix + 1;
560 
561  piy = iy - 1;
562  niy = iy + 1;
563  nniy = iy + 2;
564 
565  piz = iz - 1;
566  niz = iz + 1;
567  nniz = iz + 2;
568 
569  /* All cubic samples are inside the clip region. */
570  if (pix >= 0 && nnix < width && piy >= 0 && nniy < height && piz >= 0 && nniz < depth) {
571  break;
572  }
573 
574  /* The Cubic samples span the clip border.
575  * read_clip is used to ensure proper interpolation across the clip border. */
576  const int xc[4] = {pix, ix, nix, nnix};
577  const int yc[4] = {piy, iy, niy, nniy};
578  const int zc[4] = {piz, iz, niz, nniz};
579  return tricubic_lookup(
580  (const TexT *)info.data, tx, ty, tz, xc, yc, zc, width, height, depth, read_clip);
581  }
582  case EXTENSION_EXTEND:
583  pix = wrap_clamp(ix - 1, width);
584  nix = wrap_clamp(ix + 1, width);
585  nnix = wrap_clamp(ix + 2, width);
586  ix = wrap_clamp(ix, width);
587 
588  piy = wrap_clamp(iy - 1, height);
589  niy = wrap_clamp(iy + 1, height);
590  nniy = wrap_clamp(iy + 2, height);
591  iy = wrap_clamp(iy, height);
592 
593  piz = wrap_clamp(iz - 1, depth);
594  niz = wrap_clamp(iz + 1, depth);
595  nniz = wrap_clamp(iz + 2, depth);
596  iz = wrap_clamp(iz, depth);
597  break;
598  default:
599  kernel_assert(0);
600  return zero();
601  }
602  const int xc[4] = {pix, ix, nix, nnix};
603  const int yc[4] = {piy, iy, niy, nniy};
604  const int zc[4] = {piz, iz, niz, nniz};
605  const TexT *data = (const TexT *)info.data;
606  return tricubic_lookup(data, tx, ty, tz, xc, yc, zc, width, height, depth, read);
607  }
608 
609  static ccl_always_inline OutT
610  interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp)
611  {
612  switch ((interp == INTERPOLATION_NONE) ? info.interpolation : interp) {
614  return interp_3d_closest(info, x, y, z);
616  return interp_3d_linear(info, x, y, z);
617  default:
618  return interp_3d_cubic(info, x, y, z);
619  }
620  }
621 };
622 
623 #ifdef WITH_NANOVDB
624 template<typename TexT, typename OutT = float4> struct NanoVDBInterpolator {
625 
626  typedef typename nanovdb::NanoGrid<TexT>::AccessorType AccessorType;
627 
628  static ccl_always_inline float read(float r)
629  {
630  return r;
631  }
632 
634  {
635  return make_float4(r[0], r[1], r[2], 1.0f);
636  }
637 
638  static ccl_always_inline OutT interp_3d_closest(const AccessorType &acc,
639  float x,
640  float y,
641  float z)
642  {
643  const nanovdb::Vec3f xyz(x, y, z);
644  return read(nanovdb::SampleFromVoxels<AccessorType, 0, false>(acc)(xyz));
645  }
646 
647  static ccl_always_inline OutT interp_3d_linear(const AccessorType &acc,
648  float x,
649  float y,
650  float z)
651  {
652  const nanovdb::Vec3f xyz(x - 0.5f, y - 0.5f, z - 0.5f);
653  return read(nanovdb::SampleFromVoxels<AccessorType, 1, false>(acc)(xyz));
654  }
655 
656  /* Tricubic b-spline interpolation. */
657 # if defined(__GNUC__) || defined(__clang__)
658  static ccl_always_inline
659 # else
660  static ccl_never_inline
661 # endif
662  OutT
663  interp_3d_cubic(const AccessorType &acc, float x, float y, float z)
664  {
665  int ix, iy, iz;
666  int nix, niy, niz;
667  int pix, piy, piz;
668  int nnix, nniy, nniz;
669 
670  /* A -0.5 offset is used to center the cubic samples around the sample point. */
671  const float tx = frac(x - 0.5f, &ix);
672  const float ty = frac(y - 0.5f, &iy);
673  const float tz = frac(z - 0.5f, &iz);
674 
675  pix = ix - 1;
676  piy = iy - 1;
677  piz = iz - 1;
678  nix = ix + 1;
679  niy = iy + 1;
680  niz = iz + 1;
681  nnix = ix + 2;
682  nniy = iy + 2;
683  nniz = iz + 2;
684 
685  const int xc[4] = {pix, ix, nix, nnix};
686  const int yc[4] = {piy, iy, niy, nniy};
687  const int zc[4] = {piz, iz, niz, nniz};
688  float u[4], v[4], w[4];
689 
690  /* Some helper macros to keep code size reasonable.
691  * Lets the compiler inline all the matrix multiplications.
692  */
693 # define DATA(x, y, z) (read(acc.getValue(nanovdb::Coord(xc[x], yc[y], zc[z]))))
694 # define COL_TERM(col, row) \
695  (v[col] * (u[0] * DATA(0, col, row) + u[1] * DATA(1, col, row) + u[2] * DATA(2, col, row) + \
696  u[3] * DATA(3, col, row)))
697 # define ROW_TERM(row) \
698  (w[row] * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
699 
703 
704  /* Actual interpolation. */
705  return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
706 
707 # undef COL_TERM
708 # undef ROW_TERM
709 # undef DATA
710  }
711 
712  static ccl_always_inline OutT
713  interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp)
714  {
715  using namespace nanovdb;
716 
717  NanoGrid<TexT> *const grid = (NanoGrid<TexT> *)info.data;
718  AccessorType acc = grid->getAccessor();
719 
720  switch ((interp == INTERPOLATION_NONE) ? info.interpolation : interp) {
722  return interp_3d_closest(acc, x, y, z);
724  return interp_3d_linear(acc, x, y, z);
725  default:
726  return interp_3d_cubic(acc, x, y, z);
727  }
728  }
729 };
730 #endif
731 
732 #undef SET_CUBIC_SPLINE_WEIGHTS
733 
735 {
736  const TextureInfo &info = kernel_data_fetch(texture_info, id);
737 
738  if (UNLIKELY(!info.data)) {
739  return zero_float4();
740  }
741 
742  switch (info.data_type) {
743  case IMAGE_DATA_TYPE_HALF: {
744  const float f = TextureInterpolator<half, float>::interp(info, x, y);
745  return make_float4(f, f, f, 1.0f);
746  }
747  case IMAGE_DATA_TYPE_BYTE: {
748  const float f = TextureInterpolator<uchar, float>::interp(info, x, y);
749  return make_float4(f, f, f, 1.0f);
750  }
751  case IMAGE_DATA_TYPE_USHORT: {
752  const float f = TextureInterpolator<uint16_t, float>::interp(info, x, y);
753  return make_float4(f, f, f, 1.0f);
754  }
755  case IMAGE_DATA_TYPE_FLOAT: {
756  const float f = TextureInterpolator<float, float>::interp(info, x, y);
757  return make_float4(f, f, f, 1.0f);
758  }
760  return TextureInterpolator<half4>::interp(info, x, y);
762  return TextureInterpolator<uchar4>::interp(info, x, y);
766  return TextureInterpolator<float4>::interp(info, x, y);
767  default:
768  assert(0);
769  return make_float4(
771  }
772 }
773 
775  int id,
776  float3 P,
778 {
779  const TextureInfo &info = kernel_data_fetch(texture_info, id);
780 
781  if (UNLIKELY(!info.data)) {
782  return zero_float4();
783  }
784 
785  if (info.use_transform_3d) {
786  P = transform_point(&info.transform_3d, P);
787  }
788  switch (info.data_type) {
789  case IMAGE_DATA_TYPE_HALF: {
790  const float f = TextureInterpolator<half, float>::interp_3d(info, P.x, P.y, P.z, interp);
791  return make_float4(f, f, f, 1.0f);
792  }
793  case IMAGE_DATA_TYPE_BYTE: {
794  const float f = TextureInterpolator<uchar, float>::interp_3d(info, P.x, P.y, P.z, interp);
795  return make_float4(f, f, f, 1.0f);
796  }
797  case IMAGE_DATA_TYPE_USHORT: {
798  const float f = TextureInterpolator<uint16_t, float>::interp_3d(info, P.x, P.y, P.z, interp);
799  return make_float4(f, f, f, 1.0f);
800  }
801  case IMAGE_DATA_TYPE_FLOAT: {
802  const float f = TextureInterpolator<float, float>::interp_3d(info, P.x, P.y, P.z, interp);
803  return make_float4(f, f, f, 1.0f);
804  }
806  return TextureInterpolator<half4>::interp_3d(info, P.x, P.y, P.z, interp);
808  return TextureInterpolator<uchar4>::interp_3d(info, P.x, P.y, P.z, interp);
810  return TextureInterpolator<ushort4>::interp_3d(info, P.x, P.y, P.z, interp);
812  return TextureInterpolator<float4>::interp_3d(info, P.x, P.y, P.z, interp);
813 #ifdef WITH_NANOVDB
815  const float f = NanoVDBInterpolator<float, float>::interp_3d(info, P.x, P.y, P.z, interp);
816  return make_float4(f, f, f, 1.0f);
817  }
819  return NanoVDBInterpolator<nanovdb::Vec3f>::interp_3d(info, P.x, P.y, P.z, interp);
821  const float f = NanoVDBInterpolator<nanovdb::FpN, float>::interp_3d(
822  info, P.x, P.y, P.z, interp);
823  return make_float4(f, f, f, 1.0f);
824  }
826  const float f = NanoVDBInterpolator<nanovdb::Fp16, float>::interp_3d(
827  info, P.x, P.y, P.z, interp);
828  return make_float4(f, f, f, 1.0f);
829  }
830 #endif
831  default:
832  assert(0);
833  return make_float4(
835  }
836 }
837 
838 } /* Namespace. */
839 
typedef float(TangentPoint)[2]
unsigned char uchar
Definition: BLI_sys_types.h:70
#define UNLIKELY(x)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
float float4[4]
return(oflags[bm->toolflag_index].f &oflag) !=0
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Definition: half.h:41
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
#define TERM(col)
#define SET_CUBIC_SPLINE_WEIGHTS(u, t)
#define ROW_TERM(row)
#define ccl_never_inline
Definition: defines.h:56
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
struct Vec3f Vec3f
ccl_device_inline float4 half4_to_float4_image(const half4 h)
Definition: half.h:116
ccl_device_inline float half_to_float_image(half h)
Definition: half.h:102
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
Definition: math_float2.h:232
ccl_device_inline float4 zero_float4()
Definition: math_float4.h:92
static float P(float k)
Definition: math_interp.c:25
#define make_float4(x, y, z, w)
Definition: metal/compat.h:205
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, int id, float3 P, InterpolationType interp)
ccl_device_inline float frac(float x, int *ix)
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, int id, float x, float y)
T clamp(const T &a, const T &min, const T &max)
#define ccl_always_inline
Definition: oneapi/compat.h:31
unsigned short uint16_t
Definition: stdint.h:79
static ccl_always_inline OutT interp_closest(const TextureInfo &info, float x, float y)
static ccl_always_inline float read(uchar r)
static ccl_always_inline OutT read(const TexT *data, int x, int y, int width, int height)
static ccl_always_inline OutT read(const TexT *data, int x, int y, int z, int width, int height, int depth)
static ccl_always_inline OutT interp(const TextureInfo &info, float x, float y)
static ccl_never_inline OutT interp_3d_cubic(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline OutT interp_linear(const TextureInfo &info, float x, float y)
static ccl_always_inline float4 read(uchar4 r)
static ccl_always_inline float read(float r)
static ccl_always_inline float4 read(float4 r)
static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int z, int width, int height, int depth)
static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int width, int height)
static ccl_always_inline OutT interp_3d_linear(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline OutT interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp)
static ccl_always_inline OutT interp_3d_closest(const TextureInfo &info, float x, float y, float z)
static ccl_always_inline float4 read(ushort4 r)
static ccl_always_inline int wrap_periodic(int x, int width)
static ccl_always_inline float4 read(half4 r)
static ccl_always_inline OutT trilinear_lookup(const TexT *data, float tx, float ty, float tz, int ix, int iy, int iz, int nix, int niy, int niz, int width, int height, int depth, OutT read(const TexT *, int, int, int, int, int, int))
static ccl_always_inline OutT interp_cubic(const TextureInfo &info, float x, float y)
static ccl_always_inline OutT tricubic_lookup(const TexT *data, float tx, float ty, float tz, const int xc[4], const int yc[4], const int zc[4], int width, int height, int depth, OutT read(const TexT *, int, int, int, int, int, int))
static ccl_always_inline int wrap_clamp(int x, int width)
static ccl_always_inline float read(half r)
static ccl_always_inline float read(uint16_t r)
uint64_t data
Definition: util/texture.h:74
uint data_type
Definition: util/texture.h:76
uint extension
Definition: util/texture.h:78
uint use_transform_3d
Definition: util/texture.h:82
uint interpolation
Definition: util/texture.h:78
Transform transform_3d
Definition: util/texture.h:83
Definition: half.h:64
ccl_device_inline int float_to_int(float f)
Definition: util/math.h:410
@ IMAGE_DATA_TYPE_BYTE
Definition: util/texture.h:34
@ IMAGE_DATA_TYPE_FLOAT
Definition: util/texture.h:33
@ IMAGE_DATA_TYPE_NANOVDB_FP16
Definition: util/texture.h:41
@ IMAGE_DATA_TYPE_FLOAT4
Definition: util/texture.h:30
@ IMAGE_DATA_TYPE_USHORT4
Definition: util/texture.h:36
@ IMAGE_DATA_TYPE_USHORT
Definition: util/texture.h:37
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
Definition: util/texture.h:38
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
Definition: util/texture.h:39
@ IMAGE_DATA_TYPE_HALF
Definition: util/texture.h:35
@ IMAGE_DATA_TYPE_BYTE4
Definition: util/texture.h:31
@ IMAGE_DATA_TYPE_HALF4
Definition: util/texture.h:32
@ IMAGE_DATA_TYPE_NANOVDB_FPN
Definition: util/texture.h:40
#define TEX_IMAGE_MISSING_R
Definition: util/texture.h:12
#define TEX_IMAGE_MISSING_B
Definition: util/texture.h:14
InterpolationType
Definition: util/texture.h:19
@ INTERPOLATION_LINEAR
Definition: util/texture.h:21
@ INTERPOLATION_NONE
Definition: util/texture.h:20
@ INTERPOLATION_CLOSEST
Definition: util/texture.h:22
@ EXTENSION_REPEAT
Definition: util/texture.h:63
@ EXTENSION_CLIP
Definition: util/texture.h:67
@ EXTENSION_EXTEND
Definition: util/texture.h:65
#define TEX_IMAGE_MISSING_A
Definition: util/texture.h:15
#define TEX_IMAGE_MISSING_G
Definition: util/texture.h:13