Fix #152126: Cycles HIP: RDNA4 has rendering artifacts in volumes

The regression is caused by c0ad7c16dc.

Seems to be compiler issue. Hinting to unroll the loop solves the problem,
but introduces performance regression. So instead revert the code to the old
state for the HIP platform.

Additionally, move the weighting per-row weighting into the outter loop.
This requires an extra variable, but less multiplications.

Pull Request: https://projects.blender.org/blender/blender/pulls/152321
This commit is contained in:
Sergey Sharybin 2026-01-06 11:48:49 +01:00 • committed by Sergey Sharybin
parent 4ffeec7d11
commit cfc8cb55db

View file

@ -26,7 +26,7 @@ namespace {
#ifdef WITH_NANOVDB
/* Cubic interpolation weights. */
ccl_device_inline void fill_cubic_weights(float3 w[4], float3 t)
ccl_device_forceinline void fill_cubic_weights(float3 w[4], float3 t)
{
w[0] = (((-1.0f / 6.0f) * t + 0.5f) * t - 0.5f) * t + (1.0f / 6.0f);
w[1] = ((0.5f * t - 1.0f) * t) * t + (2.0f / 3.0f);
@ -118,6 +118,38 @@ ccl_device OutT kernel_tex_image_interp_trilinear_nanovdb(ccl_private Acc &acc,
template<typename OutT, typename Acc>
ccl_device OutT kernel_tex_image_interp_tricubic_nanovdb(ccl_private Acc &acc, const float3 P)
{
# if defined(__KERNEL_HIP__)
/* Explicitly unroll for HIP compiler to unroll the loop. Without this the render result is wrong
* on a specific platform/compiler combinations. ALso don't rely on the `unroll` hint as it has
* a performance impact. See #152126 and discussion/benchmark in !152321. */
const float3 floor_P = floor(P);
const float3 t = P - floor_P;
const int3 index = make_int3(floor_P);
const int xc[4] = {index.x - 1, index.x, index.x + 1, index.x + 2};
const int yc[4] = {index.y - 1, index.y, index.y + 1, index.y + 2};
const int zc[4] = {index.z - 1, index.z, index.z + 1, index.z + 2};
float3 weight[4];
fill_cubic_weights(weight, t);
# define DATA(x, y, z) (OutT(acc.getValue(make_int3(xc[x], yc[y], zc[z]))))
# define COL_TERM(col, row) \
(weight[col].y * (weight[0].x * DATA(0, col, row) + weight[1].x * DATA(1, col, row) + \
weight[2].x * DATA(2, col, row) + weight[3].x * DATA(3, col, row)))
# define ROW_TERM(row) \
(weight[row].z * (COL_TERM(0, row) + COL_TERM(1, row) + COL_TERM(2, row) + COL_TERM(3, row)))
/* Actual interpolation. */
return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
# undef COL_TERM
# undef ROW_TERM
# undef DATA
# else
const float3 floor_P = floor(P);
const float3 t = P - floor_P;
const int3 index = make_int3(floor_P) - make_int3(1);
@ -128,15 +160,18 @@ ccl_device OutT kernel_tex_image_interp_tricubic_nanovdb(ccl_private Acc &acc, c
OutT result = make_zero<OutT>();
for (int k = 0; k < 4; k++) {
OutT col_term_acc = make_zero<OutT>();
for (int j = 0; j < 4; j++) {
result += w[k].z * (w[j].y * (w[0].x * (OutT(acc.getValue(index + make_int3(0, j, k)))) +
w[1].x * (OutT(acc.getValue(index + make_int3(1, j, k)))) +
w[2].x * (OutT(acc.getValue(index + make_int3(2, j, k)))) +
w[3].x * (OutT(acc.getValue(index + make_int3(3, j, k))))));
col_term_acc += w[j].y * (w[0].x * (OutT(acc.getValue(index + make_int3(0, j, k)))) +
w[1].x * (OutT(acc.getValue(index + make_int3(1, j, k)))) +
w[2].x * (OutT(acc.getValue(index + make_int3(2, j, k)))) +
w[3].x * (OutT(acc.getValue(index + make_int3(3, j, k)))));
}
result += w[k].z * col_term_acc;
}
return result;
# endif
}
template<typename OutT, typename T>