2023-06-14 16:52:36 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
2016-05-20 16:46:49 +02:00
|
|
|
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
#pragma once
|
2016-05-20 16:46:49 +02:00
|
|
|
|
2024-12-26 17:53:57 +01:00
|
|
|
#include "kernel/device/cpu/compat.h"
|
|
|
|
|
#include "kernel/device/cpu/globals.h"
|
|
|
|
|
|
|
|
|
|
#include "util/half.h"
|
|
|
|
|
|
2016-05-20 16:46:49 +02:00
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
2019-08-16 16:27:15 +02:00
|
|
|
/* Make template functions private so symbols don't conflict between kernels with different
|
|
|
|
|
* instruction sets. */
|
|
|
|
|
namespace {
|
|
|
|
|
|
2017-10-06 21:47:41 +02:00
|
|
|
#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
|
|
|
|
|
{ \
|
|
|
|
|
u[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f); \
|
|
|
|
|
u[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f); \
|
|
|
|
|
u[2] = ((-0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f / 6.0f); \
|
|
|
|
|
u[3] = (1.0f / 6.0f) * t * t * t; \
|
2018-11-09 12:08:51 +01:00
|
|
|
} \
|
|
|
|
|
(void)0
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device_inline float frac(const float x, int *ix)
|
2020-11-06 15:19:58 +01:00
|
|
|
{
|
|
|
|
|
int i = float_to_int(x) - ((x < 0.0f) ? 1 : 0);
|
|
|
|
|
*ix = i;
|
|
|
|
|
return x - (float)i;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-23 22:01:32 +01:00
|
|
|
template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
2020-11-06 15:19:58 +01:00
|
|
|
|
2022-03-23 22:46:17 +01:00
|
|
|
static ccl_always_inline OutT zero()
|
|
|
|
|
{
|
2024-12-26 17:53:59 +01:00
|
|
|
if constexpr (std::is_same_v<OutT, float4>) {
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero_float4();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline float4 read(const float4 r)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
|
|
|
|
return r;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline float4 read(const uchar4 r)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
const float f = 1.0f / 255.0f;
|
2017-10-06 21:47:41 +02:00
|
|
|
return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline float read(const uchar r)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
return r * (1.0f / 255.0f);
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline float read(const float r)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
return r;
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-10-06 21:47:41 +02:00
|
|
|
static ccl_always_inline float4 read(half4 r)
|
|
|
|
|
{
|
2021-10-21 19:25:38 +02:00
|
|
|
return half4_to_float4_image(r);
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-23 15:45:32 +01:00
|
|
|
static ccl_always_inline float read(half r)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
return half_to_float_image(r);
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline float read(const uint16_t r)
|
2018-07-05 12:37:52 +02:00
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
return r * (1.0f / 65535.0f);
|
2018-07-05 12:37:52 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-05 12:37:52 +02:00
|
|
|
static ccl_always_inline float4 read(ushort4 r)
|
|
|
|
|
{
|
2022-03-23 15:45:32 +01:00
|
|
|
const float f = 1.0f / 65535.0f;
|
2018-07-05 12:37:52 +02:00
|
|
|
return make_float4(r.x * f, r.y * f, r.z * f, r.w * f);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-17 16:01:39 +01:00
|
|
|
/* Read 2D Texture Data
|
|
|
|
|
* Does not check if data request is in bounds. */
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT
|
2025-05-27 21:30:45 +02:00
|
|
|
read(const TexT *data, const int x, int y, const int width, const int /*height*/)
|
2017-12-08 11:20:12 +01:00
|
|
|
{
|
2022-03-17 16:01:39 +01:00
|
|
|
return read(data[y * width + x]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Read 2D Texture Data Clip
|
|
|
|
|
* Returns transparent black if data request is out of bounds. */
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT
|
|
|
|
|
read_clip(const TexT *data, const int x, int y, const int width, const int height)
|
2022-03-17 16:01:39 +01:00
|
|
|
{
|
|
|
|
|
if (x < 0 || x >= width || y < 0 || y >= height) {
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2017-12-08 11:20:12 +01:00
|
|
|
}
|
|
|
|
|
return read(data[y * width + x]);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline int wrap_periodic(int x, const int width)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
|
|
|
|
x %= width;
|
2022-03-17 16:01:39 +01:00
|
|
|
if (x < 0) {
|
2017-10-06 21:47:41 +02:00
|
|
|
x += width;
|
2022-03-17 16:01:39 +01:00
|
|
|
}
|
2017-10-06 21:47:41 +02:00
|
|
|
return x;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline int wrap_clamp(const int x, const int width)
|
2017-10-06 21:47:41 +02:00
|
|
|
{
|
|
|
|
|
return clamp(x, 0, width - 1);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline int wrap_mirror(const int x, const int width)
|
2022-12-14 19:19:52 +01:00
|
|
|
{
|
|
|
|
|
const int m = abs(x + (x < 0)) % (2 * width);
|
2024-12-26 17:53:59 +01:00
|
|
|
if (m >= width) {
|
2022-12-14 19:19:52 +01:00
|
|
|
return 2 * width - m - 1;
|
2024-12-26 17:53:59 +01:00
|
|
|
}
|
2022-12-14 19:19:52 +01:00
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-07 17:45:37 +01:00
|
|
|
/* ******** 2D interpolation ******** */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT interp_closest(const TextureInfo &info, const float x, float y)
|
2017-12-07 17:45:37 +01:00
|
|
|
{
|
|
|
|
|
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:
|
2022-03-17 16:01:39 +01:00
|
|
|
/* No samples are inside the clip region. */
|
|
|
|
|
if (ix < 0 || ix >= width || iy < 0 || iy >= height) {
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2017-12-07 17:45:37 +01:00
|
|
|
}
|
2022-03-17 16:01:39 +01:00
|
|
|
break;
|
2017-12-07 17:45:37 +01:00
|
|
|
case EXTENSION_EXTEND:
|
|
|
|
|
ix = wrap_clamp(ix, width);
|
|
|
|
|
iy = wrap_clamp(iy, height);
|
|
|
|
|
break;
|
2022-12-14 19:19:52 +01:00
|
|
|
case EXTENSION_MIRROR:
|
|
|
|
|
ix = wrap_mirror(ix, width);
|
|
|
|
|
iy = wrap_mirror(iy, height);
|
|
|
|
|
break;
|
2017-12-07 17:45:37 +01:00
|
|
|
default:
|
|
|
|
|
kernel_assert(0);
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2022-03-17 16:01:39 +01:00
|
|
|
|
2022-03-23 15:45:32 +01:00
|
|
|
const TexT *data = (const TexT *)info.data;
|
2024-12-26 17:53:59 +01:00
|
|
|
return read(data, ix, iy, width, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT interp_linear(const TextureInfo &info, const float x, float y)
|
2017-12-07 17:45:37 +01:00
|
|
|
{
|
|
|
|
|
const int width = info.width;
|
|
|
|
|
const int height = info.height;
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
/* A -0.5 offset is used to center the linear samples around the sample point. */
|
|
|
|
|
int ix, iy;
|
|
|
|
|
int nix, niy;
|
2017-12-07 17:45:37 +01:00
|
|
|
const float tx = frac(x * (float)width - 0.5f, &ix);
|
|
|
|
|
const float ty = frac(y * (float)height - 0.5f, &iy);
|
2023-06-26 14:13:02 +02:00
|
|
|
const TexT *data = (const TexT *)info.data;
|
2022-03-17 16:01:39 +01:00
|
|
|
|
2017-12-07 17:45:37 +01:00
|
|
|
switch (info.extension) {
|
|
|
|
|
case EXTENSION_REPEAT:
|
|
|
|
|
ix = wrap_periodic(ix, width);
|
|
|
|
|
nix = wrap_periodic(ix + 1, width);
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
iy = wrap_periodic(iy, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
niy = wrap_periodic(iy + 1, height);
|
|
|
|
|
break;
|
|
|
|
|
case EXTENSION_CLIP:
|
2022-03-17 16:01:39 +01:00
|
|
|
/* No linear samples are inside the clip region. */
|
|
|
|
|
if (ix < -1 || ix >= width || iy < -1 || iy >= height) {
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2022-03-17 16:01:39 +01:00
|
|
|
}
|
2017-12-08 11:20:12 +01:00
|
|
|
nix = ix + 1;
|
2023-06-26 14:20:31 +02:00
|
|
|
niy = iy + 1;
|
2023-06-26 14:13:02 +02:00
|
|
|
return (1.0f - ty) * (1.0f - tx) * read_clip(data, ix, iy, width, height) +
|
2023-06-26 14:20:31 +02:00
|
|
|
(1.0f - ty) * tx * read_clip(data, nix, iy, width, height) +
|
|
|
|
|
ty * (1.0f - tx) * read_clip(data, ix, niy, width, height) +
|
|
|
|
|
ty * tx * read_clip(data, nix, niy, width, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
case EXTENSION_EXTEND:
|
|
|
|
|
nix = wrap_clamp(ix + 1, width);
|
|
|
|
|
ix = wrap_clamp(ix, width);
|
2022-03-17 16:01:39 +01:00
|
|
|
niy = wrap_clamp(iy + 1, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
iy = wrap_clamp(iy, height);
|
|
|
|
|
break;
|
2022-12-14 19:19:52 +01:00
|
|
|
case EXTENSION_MIRROR:
|
|
|
|
|
nix = wrap_mirror(ix + 1, width);
|
|
|
|
|
ix = wrap_mirror(ix, width);
|
|
|
|
|
niy = wrap_mirror(iy + 1, height);
|
|
|
|
|
iy = wrap_mirror(iy, height);
|
|
|
|
|
break;
|
2017-12-07 17:45:37 +01:00
|
|
|
default:
|
|
|
|
|
kernel_assert(0);
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
2022-03-17 16:01:39 +01:00
|
|
|
|
2023-06-26 14:13:02 +02:00
|
|
|
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);
|
2017-12-07 17:45:37 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT interp_cubic(const TextureInfo &info, const float x, float y)
|
2017-12-07 17:45:37 +01:00
|
|
|
{
|
|
|
|
|
const int width = info.width;
|
|
|
|
|
const int height = info.height;
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
/* A -0.5 offset is used to center the cubic samples around the sample point. */
|
|
|
|
|
int ix, iy;
|
2017-12-07 17:45:37 +01:00
|
|
|
const float tx = frac(x * (float)width - 0.5f, &ix);
|
|
|
|
|
const float ty = frac(y * (float)height - 0.5f, &iy);
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
int pix, piy;
|
|
|
|
|
int nix, niy;
|
|
|
|
|
int nnix, nniy;
|
|
|
|
|
|
2017-12-07 17:45:37 +01:00
|
|
|
switch (info.extension) {
|
|
|
|
|
case EXTENSION_REPEAT:
|
|
|
|
|
ix = wrap_periodic(ix, width);
|
|
|
|
|
pix = wrap_periodic(ix - 1, width);
|
|
|
|
|
nix = wrap_periodic(ix + 1, width);
|
|
|
|
|
nnix = wrap_periodic(ix + 2, width);
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
iy = wrap_periodic(iy, height);
|
|
|
|
|
piy = wrap_periodic(iy - 1, height);
|
|
|
|
|
niy = wrap_periodic(iy + 1, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
nniy = wrap_periodic(iy + 2, height);
|
|
|
|
|
break;
|
|
|
|
|
case EXTENSION_CLIP:
|
2022-03-17 16:01:39 +01:00
|
|
|
/* No cubic samples are inside the clip region. */
|
|
|
|
|
if (ix < -2 || ix > width || iy < -2 || iy > height) {
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2022-03-17 16:01:39 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-08 11:20:12 +01:00
|
|
|
pix = ix - 1;
|
|
|
|
|
nix = ix + 1;
|
|
|
|
|
nnix = ix + 2;
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
piy = iy - 1;
|
|
|
|
|
niy = iy + 1;
|
2017-12-08 11:20:12 +01:00
|
|
|
nniy = iy + 2;
|
|
|
|
|
break;
|
2017-12-07 17:45:37 +01:00
|
|
|
case EXTENSION_EXTEND:
|
|
|
|
|
pix = wrap_clamp(ix - 1, width);
|
|
|
|
|
nix = wrap_clamp(ix + 1, width);
|
|
|
|
|
nnix = wrap_clamp(ix + 2, width);
|
|
|
|
|
ix = wrap_clamp(ix, width);
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
piy = wrap_clamp(iy - 1, height);
|
|
|
|
|
niy = wrap_clamp(iy + 1, height);
|
|
|
|
|
nniy = wrap_clamp(iy + 2, height);
|
2017-12-07 17:45:37 +01:00
|
|
|
iy = wrap_clamp(iy, height);
|
|
|
|
|
break;
|
2022-12-14 19:19:52 +01:00
|
|
|
case EXTENSION_MIRROR:
|
|
|
|
|
pix = wrap_mirror(ix - 1, width);
|
|
|
|
|
nix = wrap_mirror(ix + 1, width);
|
|
|
|
|
nnix = wrap_mirror(ix + 2, width);
|
|
|
|
|
ix = wrap_mirror(ix, width);
|
|
|
|
|
|
|
|
|
|
piy = wrap_mirror(iy - 1, height);
|
|
|
|
|
niy = wrap_mirror(iy + 1, height);
|
|
|
|
|
nniy = wrap_mirror(iy + 2, height);
|
|
|
|
|
iy = wrap_mirror(iy, height);
|
|
|
|
|
break;
|
2017-12-07 17:45:37 +01:00
|
|
|
default:
|
|
|
|
|
kernel_assert(0);
|
2022-03-23 22:46:17 +01:00
|
|
|
return zero();
|
2017-12-07 17:45:37 +01:00
|
|
|
}
|
2022-03-17 16:01:39 +01:00
|
|
|
|
2022-03-23 15:45:32 +01:00
|
|
|
const TexT *data = (const TexT *)info.data;
|
2017-12-07 17:45:37 +01:00
|
|
|
const int xc[4] = {pix, ix, nix, nnix};
|
2017-12-08 11:20:12 +01:00
|
|
|
const int yc[4] = {piy, iy, niy, nniy};
|
2017-12-07 17:45:37 +01:00
|
|
|
float u[4], v[4];
|
2022-03-17 16:01:39 +01:00
|
|
|
|
|
|
|
|
/* Some helper macros to keep code size reasonable.
|
|
|
|
|
* Lets the compiler inline all the matrix multiplications.
|
2017-12-07 17:45:37 +01:00
|
|
|
*/
|
2022-03-17 16:01:39 +01:00
|
|
|
#define DATA(x, y) (read_clip(data, xc[x], yc[y], width, height))
|
2017-10-06 21:47:41 +02:00
|
|
|
#define TERM(col) \
|
2017-12-07 17:45:37 +01:00
|
|
|
(v[col] * \
|
|
|
|
|
(u[0] * DATA(0, col) + u[1] * DATA(1, col) + u[2] * DATA(2, col) + u[3] * DATA(3, col)))
|
2017-10-06 21:47:41 +02:00
|
|
|
|
2017-12-07 17:45:37 +01:00
|
|
|
SET_CUBIC_SPLINE_WEIGHTS(u, tx);
|
|
|
|
|
SET_CUBIC_SPLINE_WEIGHTS(v, ty);
|
2017-10-06 21:47:41 +02:00
|
|
|
|
2017-12-07 17:45:37 +01:00
|
|
|
/* Actual interpolation. */
|
|
|
|
|
return TERM(0) + TERM(1) + TERM(2) + TERM(3);
|
2017-10-06 21:47:41 +02:00
|
|
|
#undef TERM
|
|
|
|
|
#undef DATA
|
2017-12-07 17:45:37 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
static ccl_always_inline OutT interp(const TextureInfo &info, const float x, float y)
|
2017-12-07 17:45:37 +01:00
|
|
|
{
|
|
|
|
|
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);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-10-06 21:47:41 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-06 15:19:58 +01:00
|
|
|
#undef SET_CUBIC_SPLINE_WEIGHTS
|
|
|
|
|
|
2025-01-01 18:15:54 +01:00
|
|
|
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, const int id, const float x, float y)
|
2016-05-20 16:46:49 +02:00
|
|
|
{
|
2022-06-17 17:16:37 +02:00
|
|
|
const TextureInfo &info = kernel_data_fetch(texture_info, id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-23 15:45:32 +01:00
|
|
|
if (UNLIKELY(!info.data)) {
|
|
|
|
|
return zero_float4();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-26 17:31:33 +01:00
|
|
|
switch (info.data_type) {
|
2022-03-23 15:45:32 +01:00
|
|
|
case IMAGE_DATA_TYPE_HALF: {
|
|
|
|
|
const float f = TextureInterpolator<half, float>::interp(info, x, y);
|
|
|
|
|
return make_float4(f, f, f, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
case IMAGE_DATA_TYPE_BYTE: {
|
|
|
|
|
const float f = TextureInterpolator<uchar, float>::interp(info, x, y);
|
|
|
|
|
return make_float4(f, f, f, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
case IMAGE_DATA_TYPE_USHORT: {
|
|
|
|
|
const float f = TextureInterpolator<uint16_t, float>::interp(info, x, y);
|
|
|
|
|
return make_float4(f, f, f, 1.0f);
|
|
|
|
|
}
|
|
|
|
|
case IMAGE_DATA_TYPE_FLOAT: {
|
|
|
|
|
const float f = TextureInterpolator<float, float>::interp(info, x, y);
|
|
|
|
|
return make_float4(f, f, f, 1.0f);
|
|
|
|
|
}
|
Unlimited number of textures for Cycles
This patch allows for an unlimited number of textures in Cycles where the hardware allows. It replaces a number static arrays with dynamic arrays and changes the way the flat_slot indices are calculated. Eventually, I'd like to get to a point where there are only flat slots left and textures off all kinds are stored in a single array.
Note that the arrays in DeviceScene are changed from containing device_vector<T> objects to device_vector<T>* pointers. Ideally, I'd like to store objects, but dynamic resizing of a std:vector in pre-C++11 calls the copy constructor, which for a good reason is not implemented for device_vector. Once we require C++11 for Cycles builds, we can implement a move constructor for device_vector and store objects again.
The limits for CUDA Fermi hardware still apply.
Reviewers: tod_baudais, InsigMathK, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: dingto, smellslikedonkey
Differential Revision: https://developer.blender.org/D2650
2017-04-27 09:34:51 +02:00
|
|
|
case IMAGE_DATA_TYPE_HALF4:
|
2017-10-06 21:47:41 +02:00
|
|
|
return TextureInterpolator<half4>::interp(info, x, y);
|
Unlimited number of textures for Cycles
This patch allows for an unlimited number of textures in Cycles where the hardware allows. It replaces a number static arrays with dynamic arrays and changes the way the flat_slot indices are calculated. Eventually, I'd like to get to a point where there are only flat slots left and textures off all kinds are stored in a single array.
Note that the arrays in DeviceScene are changed from containing device_vector<T> objects to device_vector<T>* pointers. Ideally, I'd like to store objects, but dynamic resizing of a std:vector in pre-C++11 calls the copy constructor, which for a good reason is not implemented for device_vector. Once we require C++11 for Cycles builds, we can implement a move constructor for device_vector and store objects again.
The limits for CUDA Fermi hardware still apply.
Reviewers: tod_baudais, InsigMathK, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: dingto, smellslikedonkey
Differential Revision: https://developer.blender.org/D2650
2017-04-27 09:34:51 +02:00
|
|
|
case IMAGE_DATA_TYPE_BYTE4:
|
2017-10-06 21:47:41 +02:00
|
|
|
return TextureInterpolator<uchar4>::interp(info, x, y);
|
2018-07-05 12:37:52 +02:00
|
|
|
case IMAGE_DATA_TYPE_USHORT4:
|
|
|
|
|
return TextureInterpolator<ushort4>::interp(info, x, y);
|
Unlimited number of textures for Cycles
This patch allows for an unlimited number of textures in Cycles where the hardware allows. It replaces a number static arrays with dynamic arrays and changes the way the flat_slot indices are calculated. Eventually, I'd like to get to a point where there are only flat slots left and textures off all kinds are stored in a single array.
Note that the arrays in DeviceScene are changed from containing device_vector<T> objects to device_vector<T>* pointers. Ideally, I'd like to store objects, but dynamic resizing of a std:vector in pre-C++11 calls the copy constructor, which for a good reason is not implemented for device_vector. Once we require C++11 for Cycles builds, we can implement a move constructor for device_vector and store objects again.
The limits for CUDA Fermi hardware still apply.
Reviewers: tod_baudais, InsigMathK, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: dingto, smellslikedonkey
Differential Revision: https://developer.blender.org/D2650
2017-04-27 09:34:51 +02:00
|
|
|
case IMAGE_DATA_TYPE_FLOAT4:
|
2017-10-06 21:47:41 +02:00
|
|
|
return TextureInterpolator<float4>::interp(info, x, y);
|
2018-07-05 12:37:52 +02:00
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
return make_float4(
|
|
|
|
|
TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
|
Unlimited number of textures for Cycles
This patch allows for an unlimited number of textures in Cycles where the hardware allows. It replaces a number static arrays with dynamic arrays and changes the way the flat_slot indices are calculated. Eventually, I'd like to get to a point where there are only flat slots left and textures off all kinds are stored in a single array.
Note that the arrays in DeviceScene are changed from containing device_vector<T> objects to device_vector<T>* pointers. Ideally, I'd like to store objects, but dynamic resizing of a std:vector in pre-C++11 calls the copy constructor, which for a good reason is not implemented for device_vector. Once we require C++11 for Cycles builds, we can implement a move constructor for device_vector and store objects again.
The limits for CUDA Fermi hardware still apply.
Reviewers: tod_baudais, InsigMathK, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: dingto, smellslikedonkey
Differential Revision: https://developer.blender.org/D2650
2017-04-27 09:34:51 +02:00
|
|
|
}
|
2016-05-20 16:46:49 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-16 16:27:15 +02:00
|
|
|
} /* Namespace. */
|
|
|
|
|
|
2016-05-20 16:46:49 +02:00
|
|
|
CCL_NAMESPACE_END
|