Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-12-03 19:19:04 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-12-03 19:19:11 +0300
commit65779b022dc14e4dff107e925817968fc93570f1 (patch)
tree54eea39e778742ebc0903a4c8e0076c1a38951d2
parent95eca49e545dbe100a400bf84ec0a95e0091289a (diff)
Fix T58280: Blender 2.8 hangs when the LookDev mode is enabled
The hang was due to the nodes being "evaluated" for every incomming link. Solution: only evaluate once per nodetree. Also merge the tagging of SSS and SSR into one traversal only.
-rw-r--r--source/blender/makesdna/DNA_node_types.h2
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c87
2 files changed, 39 insertions, 50 deletions
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a776fbbc3a6..fe921cf96ac 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -221,7 +221,7 @@ typedef struct bNode {
* and replacing all uses with per-instance data.
*/
short preview_xsize, preview_ysize; /* reserved size of the preview rect */
- short pad2[2];
+ short tmp_flag, pad2; /* Used at runtime when going through the tree. Initialize before use. */
struct uiBlock *block; /* runtime during drawing */
float ssr_id; /* XXX: eevee only, id of screen space reflection layer, needs to be a float to feed GPU_uniform. */
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 7fe5b7df37d..6a8fce76fa7 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -66,8 +66,11 @@
#include "node_shader_util.h"
-static void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node);
-static void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node);
+typedef struct nTreeTags {
+ float ssr_id, sss_id;
+} nTreeTags;
+
+static void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tags);
static bool shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
{
@@ -633,27 +636,42 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
ntreeUpdateTree(G.main, ntree);
}
-static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
+static bool ntree_tag_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
{
+ /* Don't evaluate nodes more than once. */
+ if (fromnode->tmp_flag) {
+ return true;
+ }
+ fromnode->tmp_flag = 1;
+
switch (fromnode->type) {
case NODE_GROUP:
/* Recursive */
if (fromnode->id != NULL) {
bNodeTree *ntree = (bNodeTree *)fromnode->id;
bNode *group_output = ntree_group_output_node(ntree);
- ntree_shader_tag_ssr_node(ntree, group_output);
+ ntree_shader_tag_nodes(ntree, group_output, (nTreeTags *)userdata);
}
break;
case SH_NODE_BSDF_ANISOTROPIC:
case SH_NODE_EEVEE_SPECULAR:
- case SH_NODE_BSDF_PRINCIPLED:
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
- fromnode->ssr_id = (*(float *)userdata);
- (*(float *)userdata) += 1;
+ fromnode->ssr_id = ((nTreeTags *)userdata)->ssr_id;
+ ((nTreeTags *)userdata)->ssr_id += 1;
+ break;
+ case SH_NODE_SUBSURFACE_SCATTERING:
+ fromnode->sss_id = ((nTreeTags *)userdata)->sss_id;
+ ((nTreeTags *)userdata)->sss_id += 1;
+ break;
+ case SH_NODE_BSDF_PRINCIPLED:
+ fromnode->ssr_id = ((nTreeTags *)userdata)->ssr_id;
+ fromnode->sss_id = ((nTreeTags *)userdata)->sss_id;
+ ((nTreeTags *)userdata)->sss_id += 1;
+ ((nTreeTags *)userdata)->ssr_id += 1;
break;
default:
- /* We could return false here but since we (will)
+ /* We could return false here but since we
* allow the use of Closure as RGBA, we can have
* Bsdf nodes linked to other Bsdf nodes. */
break;
@@ -663,9 +681,9 @@ static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *
}
/* EEVEE: Scan the ntree to set the Screen Space Reflection
- * layer id of every specular node.
+ * layer id of every specular node AND the Subsurface Scattering id of every SSS node.
*/
-void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node)
+void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tags)
{
if (output_node == NULL) {
return;
@@ -673,45 +691,12 @@ void ntree_shader_tag_ssr_node(bNodeTree *ntree, bNode *output_node)
/* Make sure sockets links pointers are correct. */
ntreeUpdateTree(G.main, ntree);
- float lobe_id = 1;
- nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_id, true);
-}
-
-static bool ntree_tag_sss_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
-{
- switch (fromnode->type) {
- case NODE_GROUP:
- /* Recursive */
- if (fromnode->id != NULL) {
- bNodeTree *ntree = (bNodeTree *)fromnode->id;
- bNode *group_output = ntree_group_output_node(ntree);
- ntree_shader_tag_sss_node(ntree, group_output);
- }
- break;
- case SH_NODE_BSDF_PRINCIPLED:
- case SH_NODE_SUBSURFACE_SCATTERING:
- fromnode->sss_id = (*(float *)userdata);
- (*(float *)userdata) += 1;
- break;
- default:
- break;
- }
-
- return true;
-}
-
-/* EEVEE: Scan the ntree to set the Subsurface Scattering id of every SSS node.
- */
-void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node)
-{
- if (output_node == NULL) {
- return;
+ /* Reset visit flag. */
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ node->tmp_flag = 0;
}
- /* Make sure sockets links pointers are correct. */
- ntreeUpdateTree(G.main, ntree);
- float sss_id = 1;
- nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_id, true);
+ nodeChainIter(ntree, output_node, ntree_tag_bsdf_cb, tags, true);
}
/* This one needs to work on a local tree. */
@@ -727,8 +712,12 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat, bool *has_sur
*/
ntree_shader_relink_displacement(localtree, output);
- ntree_shader_tag_ssr_node(localtree, output);
- ntree_shader_tag_sss_node(localtree, output);
+ /* TODO(fclem): consider moving this to the gpu shader tree evaluation. */
+ nTreeTags tags = {
+ .ssr_id = 1.0,
+ .sss_id = 1.0
+ };
+ ntree_shader_tag_nodes(localtree, output, &tags);
exec = ntreeShaderBeginExecTree(localtree);
ntreeExecGPUNodes(exec, mat, 1);