Geometry Nodes: deterministic anonymous attribute lifetimes
Previously, the lifetimes of anonymous attributes were determined by reference counts which were non-deterministic when multiple threads are used. Now the lifetimes of anonymous attributes are handled more explicitly and deterministically. This is a prerequisite for any kind of caching, because caching the output of nodes that do things non-deterministically and have "invisible inputs" (reference counts) doesn't really work. For more details for how deterministic lifetimes are achieved, see D16858. No functional changes are expected. Small performance changes are expected as well (within few percent, anything larger regressions should be reported as bugs). Differential Revision: https://developer.blender.org/D16858
This commit is contained in:
@@ -884,12 +884,12 @@ static void find_side_effect_nodes_for_viewer_path(
|
||||
|
||||
/* Not only mark the viewer node as having side effects, but also all group nodes it is contained
|
||||
* in. */
|
||||
r_side_effect_nodes.add(compute_context_builder.hash(),
|
||||
&find_viewer_lf_node(*found_viewer_node));
|
||||
r_side_effect_nodes.add_non_duplicates(compute_context_builder.hash(),
|
||||
&find_viewer_lf_node(*found_viewer_node));
|
||||
compute_context_builder.pop();
|
||||
while (!compute_context_builder.is_empty()) {
|
||||
r_side_effect_nodes.add(compute_context_builder.hash(),
|
||||
&find_group_lf_node(*group_node_stack.pop()));
|
||||
r_side_effect_nodes.add_non_duplicates(compute_context_builder.hash(),
|
||||
&find_group_lf_node(*group_node_stack.pop()));
|
||||
compute_context_builder.pop();
|
||||
}
|
||||
}
|
||||
@@ -1124,12 +1124,11 @@ static GeometrySet compute_geometry(
|
||||
{
|
||||
const blender::nodes::GeometryNodeLazyFunctionGraphMapping &mapping = lf_graph_info.mapping;
|
||||
|
||||
Span<const lf::OutputSocket *> graph_inputs = mapping.group_input_sockets;
|
||||
Vector<const lf::InputSocket *> graph_outputs;
|
||||
for (const bNodeSocket *bsocket : output_node.input_sockets().drop_back(1)) {
|
||||
const lf::InputSocket &socket = mapping.dummy_socket_map.lookup(bsocket)->as_input();
|
||||
graph_outputs.append(&socket);
|
||||
}
|
||||
Vector<const lf::OutputSocket *> graph_inputs = mapping.group_input_sockets;
|
||||
graph_inputs.extend(mapping.group_output_used_sockets);
|
||||
graph_inputs.extend(mapping.attribute_set_by_geometry_output.values().begin(),
|
||||
mapping.attribute_set_by_geometry_output.values().end());
|
||||
Vector<const lf::InputSocket *> graph_outputs = mapping.standard_group_output_sockets;
|
||||
|
||||
Array<GMutablePointer> param_inputs(graph_inputs.size());
|
||||
Array<GMutablePointer> param_outputs(graph_outputs.size());
|
||||
@@ -1166,21 +1165,36 @@ static GeometrySet compute_geometry(
|
||||
blender::LinearAllocator<> allocator;
|
||||
Vector<GMutablePointer> inputs_to_destruct;
|
||||
|
||||
int input_index;
|
||||
LISTBASE_FOREACH_INDEX (bNodeSocket *, interface_socket, &btree.inputs, input_index) {
|
||||
if (interface_socket->type == SOCK_GEOMETRY && input_index == 0) {
|
||||
int input_index = -1;
|
||||
for (const int i : btree.interface_inputs().index_range()) {
|
||||
input_index++;
|
||||
const bNodeSocket &interface_socket = *btree.interface_inputs()[i];
|
||||
if (interface_socket.type == SOCK_GEOMETRY && input_index == 0) {
|
||||
param_inputs[input_index] = &input_geometry_set;
|
||||
continue;
|
||||
}
|
||||
|
||||
const CPPType *type = interface_socket->typeinfo->geometry_nodes_cpp_type;
|
||||
const CPPType *type = interface_socket.typeinfo->geometry_nodes_cpp_type;
|
||||
BLI_assert(type != nullptr);
|
||||
void *value = allocator.allocate(type->size(), type->alignment());
|
||||
initialize_group_input(*nmd, *interface_socket, input_index, value);
|
||||
initialize_group_input(*nmd, interface_socket, i, value);
|
||||
param_inputs[input_index] = {type, value};
|
||||
inputs_to_destruct.append({type, value});
|
||||
}
|
||||
|
||||
Array<bool> output_used_inputs(btree.interface_outputs().size(), true);
|
||||
for (const int i : btree.interface_outputs().index_range()) {
|
||||
input_index++;
|
||||
param_inputs[input_index] = &output_used_inputs[i];
|
||||
}
|
||||
|
||||
Array<blender::bke::AnonymousAttributeSet> attributes_to_propagate(
|
||||
mapping.attribute_set_by_geometry_output.size());
|
||||
for (const int i : attributes_to_propagate.index_range()) {
|
||||
input_index++;
|
||||
param_inputs[input_index] = &attributes_to_propagate[i];
|
||||
}
|
||||
|
||||
for (const int i : graph_outputs.index_range()) {
|
||||
const lf::InputSocket &socket = *graph_outputs[i];
|
||||
const CPPType &type = socket.type();
|
||||
|
||||
Reference in New Issue
Block a user