[Bf-committers] [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.

Lukas Tönne lukas.toenne at gmail.com
Fri May 10 16:38:06 CEST 2013


Hmm, i think this broke nested node groups :/

I'm getting warnings again: "Cycles shader graph: detected cycle in graph,
connection removed."
Here's a little test file, contains a bunch of nested vector math
functions, just start render: http://www.pasteall.org/blend/21270

Works correctly in 56649. I can have a look myself tomorrow if necessary.


On Fri, May 10, 2013 at 1:31 PM, Brecht Van Lommel <
brechtvanlommel at pandora.be> wrote:

> 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;
>
> _______________________________________________
> Bf-blender-cvs mailing list
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list