diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_node_graph.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_node_graph.c | 165 |
1 files changed, 105 insertions, 60 deletions
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index 1338c5312c2..a305413905b 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -75,9 +75,26 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType if (STR_ELEM(name, "set_value", "set_rgb", "set_rgba") && (input->type == type)) { input = MEM_dupallocN(outnode->inputs.first); + + switch (input->source) { + case GPU_SOURCE_ATTR: + input->attr->users++; + break; + case GPU_SOURCE_UNIFORM_ATTR: + input->uniform_attr->users++; + break; + case GPU_SOURCE_TEX: + case GPU_SOURCE_TEX_TILED_MAPPING: + input->texture->users++; + break; + default: + break; + } + if (input->link) { input->link->users++; } + BLI_addtail(&node->inputs, input); return; } @@ -95,6 +112,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType break; case GPU_NODE_LINK_IMAGE: case GPU_NODE_LINK_IMAGE_TILED: + case GPU_NODE_LINK_IMAGE_SKY: case GPU_NODE_LINK_COLORBAND: input->source = GPU_SOURCE_TEX; input->texture = link->texture; @@ -162,7 +180,7 @@ static const char *gpu_uniform_set_function_from_type(eNodeSocketDatatype type) * This is called for the input/output sockets that are not connected. */ static GPUNodeLink *gpu_uniformbuffer_link(GPUMaterial *mat, - bNode *node, + const bNode *node, GPUNodeStack *stack, const int index, const eNodeSocketInOut in_out) @@ -179,39 +197,25 @@ static GPUNodeLink *gpu_uniformbuffer_link(GPUMaterial *mat, BLI_assert(socket != NULL); BLI_assert(socket->in_out == in_out); - if ((socket->flag & SOCK_HIDE_VALUE) == 0) { - GPUNodeLink *link; - switch (socket->type) { - case SOCK_FLOAT: { - bNodeSocketValueFloat *socket_data = socket->default_value; - link = GPU_uniform(&socket_data->value); - break; - } - case SOCK_VECTOR: { - bNodeSocketValueVector *socket_data = socket->default_value; - link = GPU_uniform(socket_data->value); - break; - } - case SOCK_RGBA: { - bNodeSocketValueRGBA *socket_data = socket->default_value; - link = GPU_uniform(socket_data->value); - break; - } - default: - return NULL; - break; - } + if (socket->flag & SOCK_HIDE_VALUE) { + return NULL; + } - if (in_out == SOCK_IN) { - GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link); - } - return link; + if (!ELEM(socket->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA)) { + return NULL; } - return NULL; + + GPUNodeLink *link = GPU_uniform(stack->vec); + + if (in_out == SOCK_IN) { + GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link); + } + + return link; } static void gpu_node_input_socket( - GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index) + GPUMaterial *material, const bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index) { if (sock->link) { gpu_node_input_link(node, sock->link, sock->type); @@ -289,7 +293,7 @@ struct GHash *GPU_uniform_attr_list_hash_new(const char *info) return BLI_ghash_new(uniform_attr_list_hash, uniform_attr_list_cmp, info); } -void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src) +void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, const GPUUniformAttrList *src) { dest->count = src->count; dest->hash_code = src->hash_code; @@ -317,24 +321,20 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph) LISTBASE_FOREACH (GPUUniformAttr *, attr, &attrs->list) { attr->id = next_id++; - - attrs->hash_code ^= BLI_ghashutil_strhash_p(attr->name); - - if (attr->use_dupli) { - attrs->hash_code ^= BLI_ghashutil_uinthash(attr->id); - } + attrs->hash_code ^= BLI_ghashutil_uinthash(attr->hash_code + (1 << (attr->id + 1))); } } /* Attributes and Textures */ -static char attr_prefix_get(eCustomDataType type) +static char attr_prefix_get(GPUMaterialAttribute *attr) { - switch (type) { + if (attr->is_default_color) { + return 'c'; + } + switch (attr->type) { case CD_TANGENT: return 't'; - case CD_MCOL: - return 'c'; case CD_AUTO_FROM_NAME: return 'a'; case CD_HAIRLENGTH: @@ -353,7 +353,7 @@ static void attr_input_name(GPUMaterialAttribute *attr) STRNCPY(attr->input_name, "orco"); } else { - attr->input_name[0] = attr_prefix_get(attr->type); + attr->input_name[0] = attr_prefix_get(attr); attr->input_name[1] = '\0'; if (attr->name[0] != '\0') { /* XXX FIXME: see notes in mesh_render_data_create() */ @@ -365,13 +365,15 @@ static void attr_input_name(GPUMaterialAttribute *attr) /** Add a new varying attribute of given type and name. Returns NULL if out of slots. */ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, eCustomDataType type, - const char *name) + const char *name, + const bool is_default_color) { /* Find existing attribute. */ int num_attributes = 0; GPUMaterialAttribute *attr = graph->attributes.first; for (; attr; attr = attr->next) { - if (attr->type == type && STREQ(attr->name, name)) { + if (attr->type == type && STREQ(attr->name, name) && + attr->is_default_color == is_default_color) { break; } num_attributes++; @@ -380,6 +382,7 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, /* Add new requested attribute if it's within GPU limits. */ if (attr == NULL) { attr = MEM_callocN(sizeof(*attr), __func__); + attr->is_default_color = is_default_color; attr->type = type; STRNCPY(attr->name, name); attr_input_name(attr); @@ -413,7 +416,13 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph, if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) { attr = MEM_callocN(sizeof(*attr), __func__); STRNCPY(attr->name, name); + { + char attr_name_esc[sizeof(attr->name) * 2]; + BLI_str_escape(attr_name_esc, attr->name, sizeof(attr_name_esc)); + SNPRINTF(attr->name_id_prop, "[\"%s\"]", attr_name_esc); + } attr->use_dupli = use_dupli; + attr->hash_code = BLI_ghashutil_strhash_p(attr->name) << 1 | (attr->use_dupli ? 0 : 1); attr->id = -1; BLI_addtail(&attrs->list, attr); attrs->count++; @@ -430,6 +439,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, Image *ima, ImageUser *iuser, struct GPUTexture **colorband, + struct GPUTexture **sky, GPUNodeLinkType link_type, eGPUSamplerState sampler_state) { @@ -437,7 +447,8 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, int num_textures = 0; GPUMaterialTexture *tex = graph->textures.first; for (; tex; tex = tex->next) { - if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) { + if (tex->ima == ima && tex->colorband == colorband && tex->sky == sky && + tex->sampler_state == sampler_state) { break; } num_textures++; @@ -452,6 +463,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, tex->iuser_available = true; } tex->colorband = colorband; + tex->sky = sky; tex->sampler_state = sampler_state; BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures); if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) { @@ -471,7 +483,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const char *name) { GPUNodeGraph *graph = gpu_material_node_graph(mat); - GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name); + GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name, false); if (type == CD_ORCO) { /* OPTI: orco might be computed from local positions and needs object infos. */ @@ -490,6 +502,21 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const c return link; } +GPUNodeLink *GPU_attribute_default_color(GPUMaterial *mat) +{ + GPUNodeGraph *graph = gpu_material_node_graph(mat); + GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, CD_AUTO_FROM_NAME, "", true); + if (attr == NULL) { + static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f}; + return GPU_constant(zero_data); + } + attr->is_default_color = true; + GPUNodeLink *link = gpu_node_link_create(); + link->link_type = GPU_NODE_LINK_ATTR; + link->attr = attr; + return link; +} + GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, const eCustomDataType type, const char *name, @@ -502,16 +529,21 @@ GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, return link; } -GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli) +GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, + const char *name, + bool use_dupli, + uint32_t *r_hash) { GPUNodeGraph *graph = gpu_material_node_graph(mat); GPUUniformAttr *attr = gpu_node_graph_add_uniform_attribute(graph, name, use_dupli); /* Dummy fallback if out of slots. */ if (attr == NULL) { + *r_hash = 0; static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f}; return GPU_constant(zero_data); } + *r_hash = attr->hash_code; GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_UNIFORM_ATTR; @@ -552,7 +584,24 @@ GPUNodeLink *GPU_image(GPUMaterial *mat, GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_IMAGE; link->texture = gpu_node_graph_add_texture( - graph, ima, iuser, NULL, link->link_type, sampler_state); + graph, ima, iuser, NULL, NULL, link->link_type, sampler_state); + return link; +} + +GPUNodeLink *GPU_image_sky(GPUMaterial *mat, + int width, + int height, + const float *pixels, + float *layer, + eGPUSamplerState sampler_state) +{ + struct GPUTexture **sky = gpu_material_sky_texture_layer_set(mat, width, height, pixels, layer); + + GPUNodeGraph *graph = gpu_material_node_graph(mat); + GPUNodeLink *link = gpu_node_link_create(); + link->link_type = GPU_NODE_LINK_IMAGE_SKY; + link->texture = gpu_node_graph_add_texture( + graph, NULL, NULL, NULL, sky, link->link_type, sampler_state); return link; } @@ -565,7 +614,7 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_IMAGE_TILED; link->texture = gpu_node_graph_add_texture( - graph, ima, iuser, NULL, link->link_type, sampler_state); + graph, ima, iuser, NULL, NULL, link->link_type, sampler_state); return link; } @@ -575,7 +624,7 @@ GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iu GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING; link->texture = gpu_node_graph_add_texture( - graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX); + graph, ima, iuser, NULL, NULL, link->link_type, GPU_SAMPLER_MAX); return link; } @@ -588,7 +637,7 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro GPUNodeLink *link = gpu_node_link_create(); link->link_type = GPU_NODE_LINK_COLORBAND; link->texture = gpu_node_graph_add_texture( - graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX); + graph, NULL, NULL, colorband, NULL, link->link_type, GPU_SAMPLER_MAX); return link; } @@ -630,7 +679,7 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...) } static bool gpu_stack_link_v(GPUMaterial *material, - bNode *bnode, + const bNode *bnode, const char *name, GPUNodeStack *in, GPUNodeStack *out, @@ -702,7 +751,7 @@ static bool gpu_stack_link_v(GPUMaterial *material, } bool GPU_stack_link(GPUMaterial *material, - bNode *bnode, + const bNode *bnode, const char *name, GPUNodeStack *in, GPUNodeStack *out, @@ -716,14 +765,6 @@ bool GPU_stack_link(GPUMaterial *material, return valid; } -GPUNodeLink *GPU_uniformbuf_link_out(GPUMaterial *mat, - bNode *node, - GPUNodeStack *stack, - const int index) -{ - return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT); -} - /* Node Graph */ static void gpu_inputs_free(ListBase *inputs) @@ -784,6 +825,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph) { BLI_freelistN(&graph->outlink_aovs); BLI_freelistN(&graph->material_functions); + BLI_freelistN(&graph->outlink_compositor); gpu_node_graph_free_nodes(graph); BLI_freelistN(&graph->textures); @@ -836,6 +878,9 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph) LISTBASE_FOREACH (GPUNodeGraphFunctionLink *, funclink, &graph->material_functions) { gpu_nodes_tag(funclink->outlink, GPU_NODE_TAG_FUNCTION); } + LISTBASE_FOREACH (GPUNodeGraphOutputLink *, compositor_link, &graph->outlink_compositor) { + gpu_nodes_tag(compositor_link->outlink, GPU_NODE_TAG_COMPOSITOR); + } for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) { next = node->next; |