Fix #163829: Cycles: Crash with bump from displacement and emission

The changes in 7ee94c067c did not properly handle the case where SVM
nodes evaluation has some feature disabled. The full SVM node data must
always be skipped.

Pull Request: https://projects.blender.org/blender/blender/pulls/164019
This commit is contained in:
Brecht Van Lommel 2026-09-17 16:40:39 +02:00 • committed by Brecht Van Lommel
parent ceaeebc06e
commit c737da4117
6 changed files with 163 additions and 67 deletions

View file

@ -116,6 +116,8 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
while (true) {
const uint node_type = kernel_data_fetch(svm_nodes, offset++);
/* NOTE: Every case must always read its full node struct regardless of enabled features,
* so that the offset advances past the SVM node data. */
switch (node_type) {
SVM_CASE(NODE_END)
return;
@ -145,19 +147,23 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
}
break;
SVM_CASE(NODE_CLOSURE_EMISSION)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
const ccl_global SVMNodeClosureEmission &bsdf_node = svm_node_get<SVMNodeClosureEmission>(
kg, &offset);
svm_node_closure_emission(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_emission(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
}
}
break;
SVM_CASE(NODE_CLOSURE_BACKGROUND)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_background(
sd, stack, closure_weight, svm_node_get<SVMNodeClosureBackground>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeClosureBackground>(kg, &offset);
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_background(sd, stack, closure_weight, node);
}
}
break;
SVM_CASE(NODE_CLOSURE_SET_WEIGHT)
@ -169,10 +175,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
stack, &closure_weight, svm_node_get<SVMNodeClosureWeight>(kg, &offset));
break;
SVM_CASE(NODE_EMISSION_WEIGHT)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_emission_weight(
stack, &closure_weight, svm_node_get<SVMNodeEmissionWeight>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeEmissionWeight>(kg, &offset);
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_emission_weight(stack, &closure_weight, node);
}
}
break;
SVM_CASE(NODE_MIX_CLOSURE)
@ -198,18 +206,24 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_geometry<float3>(kg, sd, stack, svm_node_get<SVMNodeGeometry>(kg, &offset));
break;
SVM_CASE(NODE_GEOMETRY_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_geometry<dual3>(kg, sd, stack, svm_node_get<SVMNodeGeometry>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeGeometry>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_geometry<dual3>(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_CONVERT)
svm_node_convert<float, float3>(kg, stack, svm_node_get<SVMNodeConvert>(kg, &offset));
break;
SVM_CASE(NODE_CONVERT_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_convert<dual1, dual3>(kg, stack, svm_node_get<SVMNodeConvert>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeConvert>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_convert<dual1, dual3>(kg, stack, node);
}
}
break;
SVM_CASE(NODE_TEX_COORD)
@ -219,55 +233,74 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
}
break;
SVM_CASE(NODE_TEX_COORD_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
const ccl_global auto &node = svm_node_get<SVMNodeTexCoord>(kg, &offset);
offset = svm_node_tex_coord_derivative(kg, sd, path_visibility, stack, node, offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
offset = svm_node_tex_coord_derivative(kg, sd, path_visibility, stack, node, offset);
}
else {
offset = svm_node_tex_coord_skip(node, offset);
}
}
break;
SVM_CASE(NODE_VALUE_F)
svm_node_value_f<float>(stack, svm_node_get<SVMNodeValueF>(kg, &offset));
break;
SVM_CASE(NODE_VALUE_F_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_value_f<dual1>(stack, svm_node_get<SVMNodeValueF>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeValueF>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_value_f<dual1>(stack, node);
}
}
break;
SVM_CASE(NODE_VALUE_V)
svm_node_value_v<float3>(stack, svm_node_get<SVMNodeValueV>(kg, &offset));
break;
SVM_CASE(NODE_VALUE_V_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_value_v<dual3>(stack, svm_node_get<SVMNodeValueV>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeValueV>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_value_v<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_ATTR)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
const ccl_global auto &node = svm_node_get<SVMNodeAttr>(kg, &offset);
IF_KERNEL_NODES_FEATURE(VOLUME)
{
#ifdef __VOLUME__
svm_node_attr_volume(kg, sd, stack, svm_node_get<SVMNodeAttr>(kg, &offset));
svm_node_attr_volume(kg, sd, stack, node);
#endif
}
else {
svm_node_attr_surface(kg, sd, stack, svm_node_get<SVMNodeAttr>(kg, &offset));
}
else {
svm_node_attr_surface(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_ATTR_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_attr_derivative(kg, sd, stack, svm_node_get<SVMNodeAttr>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeAttr>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_attr_derivative(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_VERTEX_COLOR)
svm_node_vertex_color(kg, sd, stack, svm_node_get<SVMNodeVertexColor>(kg, &offset));
break;
SVM_CASE(NODE_VERTEX_COLOR_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_vertex_color_derivative(
kg, sd, stack, svm_node_get<SVMNodeVertexColor>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeVertexColor>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_vertex_color_derivative(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_SET_DISPLACEMENT)
@ -286,19 +319,24 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_tex_image<float3>(kg, sd, stack, svm_node_get<SVMNodeTexImage>(kg, &offset));
break;
SVM_CASE(NODE_TEX_IMAGE_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_image<dual3>(kg, sd, stack, svm_node_get<SVMNodeTexImage>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeTexImage>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_image<dual3>(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_TEX_IMAGE_BOX)
svm_node_tex_image_box<float3>(kg, sd, stack, svm_node_get<SVMNodeTexImageBox>(kg, &offset));
break;
SVM_CASE(NODE_TEX_IMAGE_BOX_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_image_box<dual3>(
kg, sd, stack, svm_node_get<SVMNodeTexImageBox>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeTexImageBox>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_image_box<dual3>(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_TEX_NOISE)
@ -309,21 +347,30 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
kg, sd, stack, svm_node_get<SVMNodeSetBump>(kg, &offset));
break;
SVM_CASE(NODE_CLOSURE_SET_NORMAL)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_set_normal(sd, stack, svm_node_get<SVMNodeClosureSetNormal>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeClosureSetNormal>(kg, &offset);
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_set_normal(sd, stack, node);
}
}
break;
SVM_CASE(NODE_ENTER_BUMP_EVAL)
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_enter_bump_eval(kg, sd, stack, svm_node_get<SVMNodeEnterBumpEval>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeEnterBumpEval>(kg, &offset);
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_enter_bump_eval(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_LEAVE_BUMP_EVAL)
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_leave_bump_eval(sd, stack, svm_node_get<SVMNodeLeaveBumpEval>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeLeaveBumpEval>(kg, &offset);
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_leave_bump_eval(sd, stack, node);
}
}
break;
SVM_CASE(NODE_HSV)
@ -340,28 +387,34 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_layer_weight(sd, stack, svm_node_get<SVMNodeLayerWeight>(kg, &offset));
break;
SVM_CASE(NODE_CLOSURE_VOLUME)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_closure_volume<type>(
kg, sd, stack, closure_weight, svm_node_get<SVMNodeClosureVolume>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeClosureVolume>(kg, &offset);
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_closure_volume<type>(kg, sd, stack, closure_weight, node);
}
}
break;
SVM_CASE(NODE_VOLUME_COEFFICIENTS)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
const ccl_global SVMNodeVolumeCoefficients &bsdf_node =
svm_node_get<SVMNodeVolumeCoefficients>(kg, &offset);
svm_node_volume_coefficients<type>(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_volume_coefficients<type>(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
}
}
break;
SVM_CASE(NODE_PRINCIPLED_VOLUME)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
const ccl_global SVMNodePrincipledVolume &bsdf_node =
svm_node_get<SVMNodePrincipledVolume>(kg, &offset);
svm_node_principled_volume<type>(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_principled_volume<type>(
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
}
}
break;
SVM_CASE(NODE_MATH)
@ -377,9 +430,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_vector_math<float3>(stack, svm_node_get<SVMNodeVectorMath>(kg, &offset));
break;
SVM_CASE(NODE_VECTOR_MATH_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_vector_math<dual3>(stack, svm_node_get<SVMNodeVectorMath>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeVectorMath>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_vector_math<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_RGB_RAMP)
@ -423,18 +479,24 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_texture_mapping<float3>(stack, svm_node_get<SVMNodeTextureMapping>(kg, &offset));
break;
SVM_CASE(NODE_TEXTURE_MAPPING_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_texture_mapping<dual3>(stack, svm_node_get<SVMNodeTextureMapping>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeTextureMapping>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_texture_mapping<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_MAPPING)
svm_node_mapping<float3>(stack, svm_node_get<SVMNodeMapping>(kg, &offset));
break;
SVM_CASE(NODE_MAPPING_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_mapping<dual3>(stack, svm_node_get<SVMNodeMapping>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeMapping>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_mapping<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_MIN_MAX)
@ -448,10 +510,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
kg, sd, stack, svm_node_get<SVMNodeTexEnvironment>(kg, &offset));
break;
SVM_CASE(NODE_TEX_ENVIRONMENT_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_environment<dual3>(
kg, sd, stack, svm_node_get<SVMNodeTexEnvironment>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeTexEnvironment>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tex_environment<dual3>(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_TEX_SKY)
@ -503,9 +567,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_tangent<float3>(kg, sd, stack, svm_node_get<SVMNodeTangent>(kg, &offset));
break;
SVM_CASE(NODE_TANGENT_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tangent<dual3>(kg, sd, stack, svm_node_get<SVMNodeTangent>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeTangent>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_tangent<dual3>(kg, sd, stack, node);
}
}
break;
SVM_CASE(NODE_NORMAL_MAP)
@ -531,18 +598,24 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_separate_vector<float3>(stack, svm_node_get<SVMNodeSeparateVector>(kg, &offset));
break;
SVM_CASE(NODE_SEPARATE_VECTOR_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_separate_vector<dual3>(stack, svm_node_get<SVMNodeSeparateVector>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeSeparateVector>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_separate_vector<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_COMBINE_VECTOR)
svm_node_combine_vector<float3>(stack, svm_node_get<SVMNodeCombineVector>(kg, &offset));
break;
SVM_CASE(NODE_COMBINE_VECTOR_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_combine_vector<dual3>(stack, svm_node_get<SVMNodeCombineVector>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeCombineVector>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_combine_vector<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_GET_VECTOR_COMPONENT)
@ -550,10 +623,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
svm_node_get<SVMNodeGetVectorComponent>(kg, &offset));
break;
SVM_CASE(NODE_GET_VECTOR_COMPONENT_DERIVATIVE)
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_get_vector_component<dual3>(stack,
svm_node_get<SVMNodeGetVectorComponent>(kg, &offset));
const ccl_global auto &node = svm_node_get<SVMNodeGetVectorComponent>(kg, &offset);
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_get_vector_component<dual3>(stack, node);
}
}
break;
SVM_CASE(NODE_VECTOR_ROTATE)

View file

@ -189,6 +189,15 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
return offset;
}
ccl_device_inline int svm_node_tex_coord_skip(const ccl_global SVMNodeTexCoord &ccl_restrict node,
int offset)
{
if (node.texco_type == NODE_TEXCO_OBJECT_WITH_TRANSFORM) {
offset += sizeof(PackedTransform) / sizeof(uint);
}
return offset;
}
ccl_device_noinline int svm_node_tex_coord_derivative(
KernelGlobals kg,
ccl_private ShaderData *sd,

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4c9ba2f1b75c54ead5d17ea13d33ffc7a78b830d99aacc37d7c58bd22afe615f
size 134966

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c814b4fa0597046d59f65d67e3f9941f21d728596c619da155d57c54f02f3e6
size 34180

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:afaab9f3ff4d2574e06a845014207deaca79b23f127889998f00f048da393fb4
size 25632

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4d3bd7e73940a1c143fcd57e8434c7ead88cc501a87ff18404f2a18ea8976c28
size 28090