[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56650] trunk/blender/intern/cycles/render : Fix #35272: cycles GPU crash with anisotropic shader in group node.

Brecht Van Lommel brechtvanlommel at pandora.be
Fri May 10 13:31:58 CEST 2013


Revision: 56650
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56650
Author:   blendix
Date:     2013-05-10 11:31:57 +0000 (Fri, 10 May 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/cycles/render/graph.cpp
    trunk/blender/intern/cycles/render/graph.h
    trunk/blender/intern/cycles/render/shader.cpp

Modified: trunk/blender/intern/cycles/render/graph.cpp
===================================================================
--- trunk/blender/intern/cycles/render/graph.cpp	2013-05-10 10:07:01 UTC (rev 56649)
+++ trunk/blender/intern/cycles/render/graph.cpp	2013-05-10 11:31:57 UTC (rev 56650)
@@ -312,10 +312,14 @@
 	}
 }
 
-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 @@
 			ShaderOutput *from = input->link;
 			
 			/* bypass the proxy node */
-			if (from) {
+			if(from) {
 				disconnect(input);
 				foreach(ShaderInput *to, links) {
 					disconnect(to);
@@ -345,6 +349,7 @@
 			}
 			
 			removed[proxy->id] = true;
+			any_node_removed = true;
 		}
 
 		/* remove useless mix closures nodes */
@@ -360,7 +365,7 @@
 
 				foreach(ShaderInput *input, inputs) {
 					disconnect(input);
-					if (output)
+					if(output)
 						connect(output, input);
 				}
 			}
@@ -378,33 +383,47 @@
 					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::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 @@
 			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());
 				}

Modified: trunk/blender/intern/cycles/render/graph.h
===================================================================
--- trunk/blender/intern/cycles/render/graph.h	2013-05-10 10:07:01 UTC (rev 56649)
+++ trunk/blender/intern/cycles/render/graph.h	2013-05-10 11:31:57 UTC (rev 56650)
@@ -239,6 +239,7 @@
 	void connect(ShaderOutput *from, ShaderInput *to);
 	void disconnect(ShaderInput *to);
 
+	void remove_unneeded_nodes();
 	void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
 
 protected:
@@ -247,7 +248,6 @@
 	void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
 	void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
 
-	void remove_proxy_nodes(vector<bool>& removed);
 	void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
 	void clean();
 	void bump_from_displacement();

Modified: trunk/blender/intern/cycles/render/shader.cpp
===================================================================
--- trunk/blender/intern/cycles/render/shader.cpp	2013-05-10 10:07:01 UTC (rev 56649)
+++ trunk/blender/intern/cycles/render/shader.cpp	2013-05-10 11:31:57 UTC (rev 56650)
@@ -66,6 +66,12 @@
 
 void Shader::set_graph(ShaderGraph *graph_)
 {
+	/* do this here already so that we can detect if mesh or object attributes
+	 * are needed, since the node attribute callbacks check if their sockets
+	 * are connected but proxy nodes should not count */
+	if(graph_)
+		graph_->remove_unneeded_nodes();
+
 	/* assign graph */
 	delete graph;
 	delete graph_bump;




More information about the Bf-blender-cvs mailing list