Fix #136866: Voronoi 1D crashes GPU compositor

The GPU compositor crashes if 1D Voronoi is used. That's because the
vector input is unavailable in that mode, but the GPU material compiler
considers all inputs, even unavailable ones. So we need to link those
sockets to some arbitrary constant value.
This commit is contained in:
Omar Emara
2025-04-04 14:04:05 +02:00
parent cc84830abc
commit cc21dcb436
2 changed files with 21 additions and 0 deletions

View File

@@ -119,6 +119,11 @@ class ShaderOperation : public PixelOperation {
* material node graph. */
void link_node_inputs(DNode node);
/* Link the GPU stack of the given unavailable input to a constant zero value setter GPU node.
* The value is ignored since the socket is unavailable, but the GPU Material compiler expects
* all inputs to be linked, even unavailable ones. */
void link_node_input_unavailable(const DInputSocket input);
/* Link the GPU stack of the given unlinked input to a constant value setter GPU node that
* supplies the value of the unlinked input. The value is taken from the given origin input,
* which will be equal to the input in most cases, but can also be an unlinked input of a group

View File

@@ -131,7 +131,10 @@ void ShaderOperation::link_node_inputs(DNode node)
for (int i = 0; i < node->input_sockets().size(); i++) {
const DInputSocket input{node.context(), node->input_sockets()[i]};
/* The input is unavailable and unused, but it still needs to be linked as this is what the GPU
* material compiler expects. */
if (!input->is_available()) {
this->link_node_input_unavailable(input);
continue;
}
@@ -168,6 +171,19 @@ void ShaderOperation::link_node_inputs(DNode node)
}
}
void ShaderOperation::link_node_input_unavailable(const DInputSocket input)
{
ShaderNode &node = *shader_nodes_.lookup(input.node());
GPUNodeStack &stack = node.get_input(input->identifier);
/* Create a constant link with some zero value. The value is arbitrary and ignored. See the
* method description. */
zero_v4(stack.vec);
GPUNodeLink *link = GPU_constant(stack.vec);
GPU_link(material_, "set_value", link, &stack.link);
}
/* Initializes the vector value of the given GPU node stack from the default value of the given
* input socket. */
static void initialize_input_stack_value(const DInputSocket input, GPUNodeStack &stack)