Fix T51687: GPUmat evaluation of shader tree would crash uppon unknown/unsupported...
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 1 Jun 2017 10:18:57 +0000 (12:18 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 1 Jun 2017 10:18:57 +0000 (12:18 +0200)
Made this resilient to unknown types, for now. Supporting specific INT
sockets (through implicit conversion to GPU_FLOAT ones) is considered nice TODO.

source/blender/nodes/intern/node_exec.c
source/blender/nodes/shader/node_shader_util.c

index 2347564c6965df2fecf94fdf40fb1f6f35157112..0cf131adbdccc4cd0455750d177172f23e5a54e3 100644 (file)
@@ -78,7 +78,8 @@ void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack
 
 static void node_init_input_index(bNodeSocket *sock, int *index)
 {
-       if (sock->link && sock->link->fromsock) {
+       /* Only consider existing link if from socket is valid! */
+       if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) {
                sock->stack_index = sock->link->fromsock->stack_index;
        }
        else {
index 9bd43f331fbf4a4f40de1a89774d75e82eced1e3..5bc97f13b41125fd4a5088fdb21030723786e711 100644 (file)
@@ -142,28 +142,40 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
 {
        memset(gs, 0, sizeof(*gs));
        
-       nodestack_get_vec(gs->vec, type, ns);
-       gs->link = ns->data;
-       
-       if (type == SOCK_FLOAT)
-               gs->type = GPU_FLOAT;
-       else if (type == SOCK_VECTOR)
-               gs->type = GPU_VEC3;
-       else if (type == SOCK_RGBA)
-               gs->type = GPU_VEC4;
-       else if (type == SOCK_SHADER)
-               gs->type = GPU_VEC4;
-       else
+       if (ns == NULL) {
+               /* node_get_stack() will generate NULL bNodeStack pointers for unknown/unsuported types of sockets... */
+               zero_v4(gs->vec);
+               gs->link = NULL;
                gs->type = GPU_NONE;
+               gs->name = "";
+               gs->hasinput = false;
+               gs->hasoutput = false;
+               gs->sockettype = type;
+       }
+       else {
+               nodestack_get_vec(gs->vec, type, ns);
+               gs->link = ns->data;
        
-       gs->name = "";
-       gs->hasinput = ns->hasinput && ns->data;
-       /* XXX Commented out the ns->data check here, as it seems it's not always set,
-        *     even though there *is* a valid connection/output... But that might need
-        *     further investigation.
-        */
-       gs->hasoutput = ns->hasoutput /*&& ns->data*/;
-       gs->sockettype = ns->sockettype;
+               if (type == SOCK_FLOAT)
+                       gs->type = GPU_FLOAT;
+               else if (type == SOCK_VECTOR)
+                       gs->type = GPU_VEC3;
+               else if (type == SOCK_RGBA)
+                       gs->type = GPU_VEC4;
+               else if (type == SOCK_SHADER)
+                       gs->type = GPU_VEC4;
+               else
+                       gs->type = GPU_NONE;
+
+               gs->name = "";
+               gs->hasinput = ns->hasinput && ns->data;
+               /* XXX Commented out the ns->data check here, as it seems it's not always set,
+                *     even though there *is* a valid connection/output... But that might need
+                *     further investigation.
+                */
+               gs->hasoutput = ns->hasoutput /*&& ns->data*/;
+               gs->sockettype = ns->sockettype;
+       }
 }
 
 void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs)