From 528ae8885ebb8a2eebbc6726af3950ca4db38665 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 1 Jun 2017 12:18:57 +0200 Subject: [PATCH] Fix T51687: GPUmat evaluation of shader tree would crash uppon unknown/unsupported socket types. 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 | 3 +- .../blender/nodes/shader/node_shader_util.c | 52 ++++++++++++------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index 2347564c696..0cf131adbdc 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -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 { diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 9bd43f331fb..5bc97f13b41 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -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)