From a84c92fc73d3298c1456ffb26c1e73cd67b56e6d Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 14 Nov 2022 12:21:37 +0100 Subject: [PATCH] Fix T98989: Performance regression when using multiple bump nodes Ensure each graph material_function only evaluates the input links that are connected to it. Differential Revision: https://developer.blender.org/D16425 --- source/blender/gpu/intern/gpu_codegen.cc | 10 ++++++++++ source/blender/gpu/intern/gpu_node_graph.c | 2 +- source/blender/gpu/intern/gpu_node_graph.h | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 4adeac1b49a..42b2151e75b 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -620,11 +620,21 @@ void GPUCodegen::generate_graphs() std::stringstream eval_ss; eval_ss << "\n/* Generated Functions */\n\n"; LISTBASE_FOREACH (GPUNodeGraphFunctionLink *, func_link, &graph.material_functions) { + /* Untag every node in the graph to avoid serializing nodes from other functions */ + LISTBASE_FOREACH (GPUNode *, node, &graph.nodes) { + node->tag &= ~GPU_NODE_TAG_FUNCTION; + } + /* Tag only the nodes needed for the current function */ + gpu_nodes_tag(func_link->outlink, GPU_NODE_TAG_FUNCTION); char *fn = graph_serialize(GPU_NODE_TAG_FUNCTION, func_link->outlink); eval_ss << "float " << func_link->name << "() {\n" << fn << "}\n\n"; MEM_SAFE_FREE(fn); } output.material_functions = extract_c_str(eval_ss); + /* Leave the function tags as they were before serialization */ + LISTBASE_FOREACH (GPUNodeGraphFunctionLink *, funclink, &graph.material_functions) { + gpu_nodes_tag(funclink->outlink, GPU_NODE_TAG_FUNCTION); + } } LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph.attributes) { diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index c72e7097b33..14dfce6ce5e 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -890,7 +890,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph) /* Prune Unused Nodes */ -static void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag) +void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag) { GPUNode *node; diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index de0a0687b13..9f919f04160 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -66,7 +66,7 @@ typedef enum { GPU_NODE_TAG_COMPOSITOR = (1 << 6), } eGPUNodeTag; -ENUM_OPERATORS(eGPUNodeTag, GPU_NODE_TAG_FUNCTION) +ENUM_OPERATORS(eGPUNodeTag, GPU_NODE_TAG_COMPOSITOR) struct GPUNode { struct GPUNode *next, *prev; @@ -186,6 +186,7 @@ typedef struct GPUNodeGraph { /* Node Graph */ +void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag); void gpu_node_graph_prune_unused(GPUNodeGraph *graph); void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph);