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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-10 15:31:57 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-10 15:31:57 +0400
commite46551246ca305d0b723a7fb0e955e4852b1efdc (patch)
treeae97b719a75391e53868d0e4e8e8fedf83c0b2cb /intern/cycles/render/graph.cpp
parent4392fc6f1d4950ab0e0e60aae1bd5dea5baf26de (diff)
Fix #35272: cycles GPU crash with anisotropic shader in group node.
Problem was that due to group proxy node the anisotropic node did not detect early enough that it needs generated texture coordinate data to generate the tangent. Now the proxy nodes are removed earlier.
Diffstat (limited to 'intern/cycles/render/graph.cpp')
-rw-r--r--intern/cycles/render/graph.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index b026f07ce56..f081e2db7af 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -312,10 +312,14 @@ void ShaderGraph::copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNod
}
}
-void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
+void ShaderGraph::remove_unneeded_nodes()
{
+ vector<bool> removed(nodes.size(), false);
+ bool any_node_removed = false;
+
+ /* find and unlink proxy nodes */
foreach(ShaderNode *node, nodes) {
- if (node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
+ if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
ProxyNode *proxy = static_cast<ProxyNode*>(node);
ShaderInput *input = proxy->inputs[0];
ShaderOutput *output = proxy->outputs[0];
@@ -327,7 +331,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
ShaderOutput *from = input->link;
/* bypass the proxy node */
- if (from) {
+ if(from) {
disconnect(input);
foreach(ShaderInput *to, links) {
disconnect(to);
@@ -345,6 +349,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
}
removed[proxy->id] = true;
+ any_node_removed = true;
}
/* remove useless mix closures nodes */
@@ -360,7 +365,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
+ if(output)
connect(output, input);
}
}
@@ -378,33 +383,47 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
vector<ShaderInput*> inputs = mix->outputs[0]->links;
foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
+ if(sock->link)
+ disconnect(sock);
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
- connect(output, input);
+ if(output)
+ connect(output, input);
}
}
/* Factor 1.0 */
- else if (mix->inputs[0]->value.x == 1.0f) {
+ else if(mix->inputs[0]->value.x == 1.0f) {
ShaderOutput *output = mix->inputs[2]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
+ if(sock->link)
+ disconnect(sock);
foreach(ShaderInput *input, inputs) {
disconnect(input);
- if (output)
+ if(output)
connect(output, input);
}
}
}
}
}
+
+ /* remove nodes */
+ if (any_node_removed) {
+ list<ShaderNode*> newnodes;
+
+ foreach(ShaderNode *node, nodes) {
+ if(!removed[node->id])
+ newnodes.push_back(node);
+ else
+ delete node;
+ }
+
+ nodes = newnodes;
+ }
}
void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
@@ -433,27 +452,17 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b
void ShaderGraph::clean()
{
+ /* remove proxy and unnecessary mix nodes */
+ remove_unneeded_nodes();
+
/* we do two things here: find cycles and break them, and remove unused
* nodes that don't feed into the output. how cycles are broken is
* undefined, they are invalid input, the important thing is to not crash */
- vector<bool> removed(nodes.size(), false);
vector<bool> visited(nodes.size(), false);
vector<bool> on_stack(nodes.size(), false);
list<ShaderNode*> newnodes;
-
- /* remove proxy nodes */
- remove_proxy_nodes(removed);
-
- foreach(ShaderNode *node, nodes) {
- if(!removed[node->id])
- newnodes.push_back(node);
- else
- delete node;
- }
- nodes = newnodes;
- newnodes.clear();
/* break cycles */
break_cycles(output(), visited, on_stack);
@@ -464,7 +473,7 @@ void ShaderGraph::clean()
foreach(ShaderInput *to, node->inputs) {
ShaderOutput *from = to->link;
- if (from) {
+ if(from) {
to->link = NULL;
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}