Blender V5.0
cycles/kernel/device/gpu/image.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/globals.h"
8
10
11ccl_device_inline float frac(const float x, ccl_private int *ix)
12{
13 int i = float_to_int(x) - ((x < 0.0f) ? 1 : 0);
14 *ix = i;
15 return x - (float)i;
16}
17
18/* w0, w1, w2, and w3 are the four cubic B-spline basis functions. */
19ccl_device float cubic_w0(const float a)
20{
21 return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
22}
23ccl_device float cubic_w1(const float a)
24{
25 return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
26}
27ccl_device float cubic_w2(const float a)
28{
29 return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
30}
31ccl_device float cubic_w3(const float a)
32{
33 return (1.0f / 6.0f) * (a * a * a);
34}
35
36/* g0 and g1 are the two amplitude functions. */
37ccl_device float cubic_g0(const float a)
38{
39 return cubic_w0(a) + cubic_w1(a);
40}
41ccl_device float cubic_g1(const float a)
42{
43 return cubic_w2(a) + cubic_w3(a);
44}
45
46/* h0 and h1 are the two offset functions */
47ccl_device float cubic_h0(const float a)
48{
49 return (cubic_w1(a) / cubic_g0(a)) - 1.0f;
50}
51ccl_device float cubic_h1(const float a)
52{
53 return (cubic_w3(a) / cubic_g1(a)) + 1.0f;
54}
55
56/* Fast bicubic texture lookup using 4 bilinear lookups, adapted from CUDA samples. */
57template<typename T>
59 float x,
60 float y)
61{
63
64 x = (x * info.width) - 0.5f;
65 y = (y * info.height) - 0.5f;
66
67 float px = floorf(x);
68 float py = floorf(y);
69 float fx = x - px;
70 float fy = y - py;
71
72 float g0x = cubic_g0(fx);
73 float g1x = cubic_g1(fx);
74 /* Note +0.5 offset to compensate for CUDA linear filtering convention. */
75 float x0 = (px + cubic_h0(fx) + 0.5f) / info.width;
76 float x1 = (px + cubic_h1(fx) + 0.5f) / info.width;
77 float y0 = (py + cubic_h0(fy) + 0.5f) / info.height;
78 float y1 = (py + cubic_h1(fy) + 0.5f) / info.height;
79
80 return cubic_g0(fy) * (g0x * ccl_gpu_tex_object_read_2D<T>(tex, x0, y0) +
81 g1x * ccl_gpu_tex_object_read_2D<T>(tex, x1, y0)) +
82 cubic_g1(fy) * (g0x * ccl_gpu_tex_object_read_2D<T>(tex, x0, y1) +
83 g1x * ccl_gpu_tex_object_read_2D<T>(tex, x1, y1));
84}
85
86ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, const int id, const float x, float y)
87{
88 const ccl_global TextureInfo &info = kernel_data_fetch(texture_info, id);
89
90 /* float4, byte4, ushort4 and half4 */
91 const int texture_type = info.data_type;
92 if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
93 texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4)
94 {
95 if (info.interpolation == INTERPOLATION_CUBIC || info.interpolation == INTERPOLATION_SMART) {
97 }
98 else {
101 }
102 }
103 /* float, byte and half */
104 else {
105 float f;
106
107 if (info.interpolation == INTERPOLATION_CUBIC || info.interpolation == INTERPOLATION_SMART) {
109 }
110 else {
113 }
114
115 return make_float4(f, f, f, 1.0f);
116 }
117}
118
nullptr float
ccl_device float cubic_g0(const float a)
ccl_device_noinline T kernel_tex_image_interp_bicubic(const ccl_global TextureInfo &info, float x, float y)
ccl_device float cubic_h1(const float a)
ccl_device float cubic_w3(const float a)
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(const float x, ccl_private int *ix)
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, const int id, const float x, float y)
ccl_device float cubic_g1(const float a)
ccl_device float cubic_w2(const float a)
ccl_device float cubic_h0(const float a)
ccl_device float cubic_w0(const float a)
ccl_device float cubic_w1(const float a)
#define kernel_data_fetch(name, index)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define ccl_global
#define ccl_device_noinline
ccl_device_forceinline T ccl_gpu_tex_object_read_2D(const ccl_gpu_tex_object_2D texobj, const float x, const float y)
#define CCL_NAMESPACE_END
CUtexObject ccl_gpu_tex_object_2D
ccl_device_forceinline float4 ccl_gpu_tex_object_read_2D< float4 >(const ccl_gpu_tex_object_2D texobj, const float x, const float y)
ccl_device_forceinline float ccl_gpu_tex_object_read_2D< float >(const ccl_gpu_tex_object_2D texobj, const float x, const float y)
ccl_device_inline int float_to_int(const float f)
Definition math_base.h:407
#define T
#define floorf
#define ccl_device
#define make_float4
i
Definition text_draw.cc:230
@ IMAGE_DATA_TYPE_FLOAT4
Definition texture.h:33
@ IMAGE_DATA_TYPE_USHORT4
Definition texture.h:39
@ IMAGE_DATA_TYPE_BYTE4
Definition texture.h:34
@ IMAGE_DATA_TYPE_HALF4
Definition texture.h:35
@ INTERPOLATION_SMART
Definition texture.h:27
@ INTERPOLATION_CUBIC
Definition texture.h:26