Blender  V3.3
gpu_node_graph.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "MEM_guardedalloc.h"
14 
15 #include "DNA_node_types.h"
16 
17 #include "BLI_ghash.h"
18 #include "BLI_listbase.h"
19 #include "BLI_string.h"
20 #include "BLI_utildefines.h"
21 
22 #include "GPU_texture.h"
23 #include "GPU_vertex_format.h"
24 
25 #include "gpu_material_library.h"
26 #include "gpu_node_graph.h"
27 
28 /* Node Link Functions */
29 
31 {
32  GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
33  link->users++;
34 
35  return link;
36 }
37 
38 static void gpu_node_link_free(GPUNodeLink *link)
39 {
40  link->users--;
41 
42  if (link->users < 0) {
43  fprintf(stderr, "gpu_node_link_free: negative refcount\n");
44  }
45 
46  if (link->users == 0) {
47  if (link->output) {
48  link->output->link = NULL;
49  }
50  MEM_freeN(link);
51  }
52 }
53 
54 /* Node Functions */
55 
56 static GPUNode *gpu_node_create(const char *name)
57 {
58  GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
59 
60  node->name = name;
61 
62  return node;
63 }
64 
66 {
67  GPUInput *input;
68  GPUNode *outnode;
69  const char *name;
70 
71  if (link->link_type == GPU_NODE_LINK_OUTPUT) {
72  outnode = link->output->node;
73  name = outnode->name;
74  input = outnode->inputs.first;
75 
76  if (STR_ELEM(name, "set_value", "set_rgb", "set_rgba") && (input->type == type)) {
77  input = MEM_dupallocN(outnode->inputs.first);
78  if (input->link) {
79  input->link->users++;
80  }
81  BLI_addtail(&node->inputs, input);
82  return;
83  }
84  }
85 
86  input = MEM_callocN(sizeof(GPUInput), "GPUInput");
87  input->node = node;
88  input->type = type;
89 
90  switch (link->link_type) {
92  input->source = GPU_SOURCE_OUTPUT;
93  input->link = link;
94  link->users++;
95  break;
99  input->source = GPU_SOURCE_TEX;
100  input->texture = link->texture;
101  break;
104  input->texture = link->texture;
105  break;
106  case GPU_NODE_LINK_ATTR:
107  input->source = GPU_SOURCE_ATTR;
108  input->attr = link->attr;
109  /* Fail-safe handling if the same attribute is used with different data-types for
110  * some reason (only really makes sense with float/vec2/vec3/vec4 though). This
111  * can happen if mixing the generic Attribute node with specialized ones. */
112  CLAMP_MIN(input->attr->gputype, type);
113  break;
115  input->source = GPU_SOURCE_UNIFORM_ATTR;
116  input->uniform_attr = link->uniform_attr;
117  break;
120  break;
122  input->source = GPU_SOURCE_UNIFORM;
123  break;
126  /* NOTE(@fclem): End of function call is the return variable set during codegen. */
127  SNPRINTF(input->function_call, "dF_branch_incomplete(%s(), ", link->function_name);
128  break;
129  default:
130  break;
131  }
132 
134  memcpy(input->vec, link->data, type * sizeof(float));
135  }
136 
137  if (link->link_type != GPU_NODE_LINK_OUTPUT) {
138  MEM_freeN(link);
139  }
140  BLI_addtail(&node->inputs, input);
141 }
142 
144 {
145  switch (type) {
146  /* For now INT is supported as float. */
147  case SOCK_INT:
148  case SOCK_FLOAT:
149  return "set_value";
150  case SOCK_VECTOR:
151  return "set_rgb";
152  case SOCK_RGBA:
153  return "set_rgba";
154  default:
155  BLI_assert_msg(0, "No gpu function for non-supported eNodeSocketDatatype");
156  return NULL;
157  }
158 }
159 
165  bNode *node,
166  GPUNodeStack *stack,
167  const int index,
168  const eNodeSocketInOut in_out)
169 {
170  bNodeSocket *socket;
171 
172  if (in_out == SOCK_IN) {
173  socket = BLI_findlink(&node->inputs, index);
174  }
175  else {
176  socket = BLI_findlink(&node->outputs, index);
177  }
178 
179  BLI_assert(socket != NULL);
180  BLI_assert(socket->in_out == in_out);
181 
182  if ((socket->flag & SOCK_HIDE_VALUE) == 0) {
183  GPUNodeLink *link;
184  switch (socket->type) {
185  case SOCK_FLOAT: {
186  bNodeSocketValueFloat *socket_data = socket->default_value;
187  link = GPU_uniform(&socket_data->value);
188  break;
189  }
190  case SOCK_VECTOR: {
191  bNodeSocketValueVector *socket_data = socket->default_value;
192  link = GPU_uniform(socket_data->value);
193  break;
194  }
195  case SOCK_RGBA: {
196  bNodeSocketValueRGBA *socket_data = socket->default_value;
197  link = GPU_uniform(socket_data->value);
198  break;
199  }
200  default:
201  return NULL;
202  break;
203  }
204 
205  if (in_out == SOCK_IN) {
206  GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link);
207  }
208  return link;
209  }
210  return NULL;
211 }
212 
214  GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index)
215 {
216  if (sock->link) {
217  gpu_node_input_link(node, sock->link, sock->type);
218  }
219  else if ((material != NULL) &&
220  (gpu_uniformbuffer_link(material, bnode, sock, index, SOCK_IN) != NULL)) {
221  gpu_node_input_link(node, sock->link, sock->type);
222  }
223  else {
224  gpu_node_input_link(node, GPU_constant(sock->vec), sock->type);
225  }
226 }
227 
228 static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **link)
229 {
230  GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
231 
232  output->type = type;
233  output->node = node;
234 
235  if (link) {
236  *link = output->link = gpu_node_link_create();
237  output->link->link_type = GPU_NODE_LINK_OUTPUT;
238  output->link->output = output;
239 
240  /* NOTE: the caller owns the reference to the link, GPUOutput
241  * merely points to it, and if the node is destroyed it will
242  * set that pointer to NULL */
243  }
244 
245  BLI_addtail(&node->outputs, output);
246 }
247 
248 /* Uniform Attribute Functions */
249 
250 static int uniform_attr_sort_cmp(const void *a, const void *b)
251 {
252  const GPUUniformAttr *attr_a = a, *attr_b = b;
253 
254  int cmps = strcmp(attr_a->name, attr_b->name);
255  if (cmps != 0) {
256  return cmps > 0 ? 1 : 0;
257  }
258 
259  return (attr_a->use_dupli && !attr_b->use_dupli);
260 }
261 
262 static unsigned int uniform_attr_list_hash(const void *key)
263 {
264  const GPUUniformAttrList *attrs = key;
265  return attrs->hash_code;
266 }
267 
268 static bool uniform_attr_list_cmp(const void *a, const void *b)
269 {
270  const GPUUniformAttrList *set_a = a, *set_b = b;
271 
272  if (set_a->hash_code != set_b->hash_code || set_a->count != set_b->count) {
273  return true;
274  }
275 
276  GPUUniformAttr *attr_a = set_a->list.first, *attr_b = set_b->list.first;
277 
278  for (; attr_a && attr_b; attr_a = attr_a->next, attr_b = attr_b->next) {
279  if (!STREQ(attr_a->name, attr_b->name) || attr_a->use_dupli != attr_b->use_dupli) {
280  return true;
281  }
282  }
283 
284  return attr_a || attr_b;
285 }
286 
287 struct GHash *GPU_uniform_attr_list_hash_new(const char *info)
288 {
290 }
291 
293 {
294  dest->count = src->count;
295  dest->hash_code = src->hash_code;
296  BLI_duplicatelist(&dest->list, &src->list);
297 }
298 
300 {
301  set->count = 0;
302  set->hash_code = 0;
303  BLI_freelistN(&set->list);
304 }
305 
307 {
308  GPUUniformAttrList *attrs = &graph->uniform_attrs;
309  BLI_assert(attrs->count == BLI_listbase_count(&attrs->list));
310 
311  /* Sort the attributes by name to ensure a stable order. */
313 
314  /* Compute the indices and the hash code. */
315  int next_id = 0;
316  attrs->hash_code = 0;
317 
318  LISTBASE_FOREACH (GPUUniformAttr *, attr, &attrs->list) {
319  attr->id = next_id++;
320 
321  attrs->hash_code ^= BLI_ghashutil_strhash_p(attr->name);
322 
323  if (attr->use_dupli) {
324  attrs->hash_code ^= BLI_ghashutil_uinthash(attr->id);
325  }
326  }
327 }
328 
329 /* Attributes and Textures */
330 
332 {
333  if (attr->is_default_color) {
334  return 'c';
335  }
336  switch (attr->type) {
337  case CD_TANGENT:
338  return 't';
339  case CD_AUTO_FROM_NAME:
340  return 'a';
341  case CD_HAIRLENGTH:
342  return 'l';
343  default:
344  BLI_assert_msg(0, "GPUVertAttr Prefix type not found : This should not happen!");
345  return '\0';
346  }
347 }
348 
350 {
351  /* NOTE: Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.cc */
352  if (attr->type == CD_ORCO) {
353  /* OPTI: orco is computed from local positions, but only if no modifier is present. */
354  STRNCPY(attr->input_name, "orco");
355  }
356  else {
357  attr->input_name[0] = attr_prefix_get(attr);
358  attr->input_name[1] = '\0';
359  if (attr->name[0] != '\0') {
360  /* XXX FIXME: see notes in mesh_render_data_create() */
362  }
363  }
364 }
365 
369  const char *name,
370  const bool is_default_color)
371 {
372  /* Find existing attribute. */
373  int num_attributes = 0;
374  GPUMaterialAttribute *attr = graph->attributes.first;
375  for (; attr; attr = attr->next) {
376  if (attr->type == type && STREQ(attr->name, name) &&
377  attr->is_default_color == is_default_color) {
378  break;
379  }
380  num_attributes++;
381  }
382 
383  /* Add new requested attribute if it's within GPU limits. */
384  if (attr == NULL) {
385  attr = MEM_callocN(sizeof(*attr), __func__);
386  attr->is_default_color = is_default_color;
387  attr->type = type;
388  STRNCPY(attr->name, name);
389  attr_input_name(attr);
390  attr->id = num_attributes;
391  BLI_addtail(&graph->attributes, attr);
392  }
393 
394  if (attr != NULL) {
395  attr->users++;
396  }
397 
398  return attr;
399 }
400 
403  const char *name,
404  bool use_dupli)
405 {
406  /* Find existing attribute. */
407  GPUUniformAttrList *attrs = &graph->uniform_attrs;
408  GPUUniformAttr *attr = attrs->list.first;
409 
410  for (; attr; attr = attr->next) {
411  if (STREQ(attr->name, name) && attr->use_dupli == use_dupli) {
412  break;
413  }
414  }
415 
416  /* Add new requested attribute if it's within GPU limits. */
417  if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) {
418  attr = MEM_callocN(sizeof(*attr), __func__);
419  STRNCPY(attr->name, name);
420  attr->use_dupli = use_dupli;
421  attr->id = -1;
422  BLI_addtail(&attrs->list, attr);
423  attrs->count++;
424  }
425 
426  if (attr != NULL) {
427  attr->users++;
428  }
429 
430  return attr;
431 }
432 
434  Image *ima,
435  ImageUser *iuser,
436  struct GPUTexture **colorband,
437  GPUNodeLinkType link_type,
438  eGPUSamplerState sampler_state)
439 {
440  /* Find existing texture. */
441  int num_textures = 0;
442  GPUMaterialTexture *tex = graph->textures.first;
443  for (; tex; tex = tex->next) {
444  if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) {
445  break;
446  }
447  num_textures++;
448  }
449 
450  /* Add new requested texture. */
451  if (tex == NULL) {
452  tex = MEM_callocN(sizeof(*tex), __func__);
453  tex->ima = ima;
454  if (iuser != NULL) {
455  tex->iuser = *iuser;
456  tex->iuser_available = true;
457  }
458  tex->colorband = colorband;
459  tex->sampler_state = sampler_state;
460  BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
462  BLI_snprintf(
463  tex->tiled_mapping_name, sizeof(tex->tiled_mapping_name), "tsamp%d", num_textures);
464  }
465  BLI_addtail(&graph->textures, tex);
466  }
467 
468  tex->users++;
469 
470  return tex;
471 }
472 
473 /* Creating Inputs */
474 
476 {
479 
480  if (type == CD_ORCO) {
481  /* OPTI: orco might be computed from local positions and needs object infos. */
483  }
484 
485  /* Dummy fallback if out of slots. */
486  if (attr == NULL) {
487  static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
488  return GPU_constant(zero_data);
489  }
490 
493  link->attr = attr;
494  return link;
495 }
496 
498 {
501  if (attr == NULL) {
502  static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
503  return GPU_constant(zero_data);
504  }
505  attr->is_default_color = true;
508  link->attr = attr;
509  return link;
510 }
511 
513  const eCustomDataType type,
514  const char *name,
515  eGPUDefaultValue default_value)
516 {
517  GPUNodeLink *link = GPU_attribute(mat, type, name);
518  if (link->link_type == GPU_NODE_LINK_ATTR) {
519  link->attr->default_value = default_value;
520  }
521  return link;
522 }
523 
524 GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli)
525 {
528 
529  /* Dummy fallback if out of slots. */
530  if (attr == NULL) {
531  static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
532  return GPU_constant(zero_data);
533  }
534 
537  link->uniform_attr = attr;
538  return link;
539 }
540 
541 GPUNodeLink *GPU_constant(const float *num)
542 {
545  link->data = num;
546  return link;
547 }
548 
549 GPUNodeLink *GPU_uniform(const float *num)
550 {
553  link->data = num;
554  return link;
555 }
556 
558 {
561  link->function_name = function_name;
562  return link;
563 }
564 
566  Image *ima,
567  ImageUser *iuser,
568  eGPUSamplerState sampler_state)
569 {
574  graph, ima, iuser, NULL, link->link_type, sampler_state);
575  return link;
576 }
577 
579  Image *ima,
580  ImageUser *iuser,
581  eGPUSamplerState sampler_state)
582 {
587  graph, ima, iuser, NULL, link->link_type, sampler_state);
588  return link;
589 }
590 
592 {
597  graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX);
598  return link;
599 }
600 
601 GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
602 {
603  struct GPUTexture **colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
604  MEM_freeN(pixels);
605 
610  graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX);
611  return link;
612 }
613 
614 /* Creating Nodes */
615 
616 bool GPU_link(GPUMaterial *mat, const char *name, ...)
617 {
619  GPUNode *node;
620  GPUFunction *function;
621  GPUNodeLink *link, **linkptr;
622  va_list params;
623  int i;
624 
625  function = gpu_material_library_use_function(graph->used_libraries, name);
626  if (!function) {
627  fprintf(stderr, "GPU failed to find function %s\n", name);
628  return false;
629  }
630 
631  node = gpu_node_create(name);
632 
633  va_start(params, name);
634  for (i = 0; i < function->totparam; i++) {
635  if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
636  linkptr = va_arg(params, GPUNodeLink **);
637  gpu_node_output(node, function->paramtype[i], linkptr);
638  }
639  else {
640  link = va_arg(params, GPUNodeLink *);
641  gpu_node_input_link(node, link, function->paramtype[i]);
642  }
643  }
644  va_end(params);
645 
646  BLI_addtail(&graph->nodes, node);
647 
648  return true;
649 }
650 
652  bNode *bnode,
653  const char *name,
654  GPUNodeStack *in,
655  GPUNodeStack *out,
656  va_list params)
657 {
659  GPUNode *node;
660  GPUFunction *function;
661  GPUNodeLink *link, **linkptr;
662  int i, totin, totout;
663 
664  function = gpu_material_library_use_function(graph->used_libraries, name);
665  if (!function) {
666  fprintf(stderr, "GPU failed to find function %s\n", name);
667  return false;
668  }
669 
670  node = gpu_node_create(name);
671  totin = 0;
672  totout = 0;
673 
674  if (in) {
675  for (i = 0; !in[i].end; i++) {
676  if (in[i].type != GPU_NONE) {
677  gpu_node_input_socket(material, bnode, node, &in[i], i);
678  totin++;
679  }
680  }
681  }
682 
683  if (out) {
684  for (i = 0; !out[i].end; i++) {
685  if (out[i].type != GPU_NONE) {
686  gpu_node_output(node, out[i].type, &out[i].link);
687  totout++;
688  }
689  }
690  }
691 
692  for (i = 0; i < function->totparam; i++) {
693  if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
694  if (totout == 0) {
695  linkptr = va_arg(params, GPUNodeLink **);
696  gpu_node_output(node, function->paramtype[i], linkptr);
697  }
698  else {
699  totout--;
700  }
701  }
702  else {
703  if (totin == 0) {
704  link = va_arg(params, GPUNodeLink *);
705  if (link->socket) {
706  gpu_node_input_socket(NULL, NULL, node, link->socket, -1);
707  }
708  else {
709  gpu_node_input_link(node, link, function->paramtype[i]);
710  }
711  }
712  else {
713  totin--;
714  }
715  }
716  }
717 
718  BLI_addtail(&graph->nodes, node);
719 
720  return true;
721 }
722 
724  bNode *bnode,
725  const char *name,
726  GPUNodeStack *in,
727  GPUNodeStack *out,
728  ...)
729 {
730  va_list params;
731  va_start(params, out);
732  bool valid = gpu_stack_link_v(material, bnode, name, in, out, params);
733  va_end(params);
734 
735  return valid;
736 }
737 
739  bNode *node,
740  GPUNodeStack *stack,
741  const int index)
742 {
743  return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT);
744 }
745 
746 /* Node Graph */
747 
749 {
750  GPUInput *input;
751 
752  for (input = inputs->first; input; input = input->next) {
753  if (input->source == GPU_SOURCE_ATTR) {
754  input->attr->users--;
755  }
756  else if (input->source == GPU_SOURCE_UNIFORM_ATTR) {
757  input->uniform_attr->users--;
758  }
760  input->texture->users--;
761  }
762 
763  if (input->link) {
764  gpu_node_link_free(input->link);
765  }
766  }
767 
769 }
770 
772 {
773  GPUOutput *output;
774 
775  gpu_inputs_free(&node->inputs);
776 
777  for (output = node->outputs.first; output; output = output->next) {
778  if (output->link) {
779  output->link->output = NULL;
780  gpu_node_link_free(output->link);
781  }
782  }
783 
784  BLI_freelistN(&node->outputs);
785  MEM_freeN(node);
786 }
787 
789 {
790  GPUNode *node;
791 
792  while ((node = BLI_pophead(&graph->nodes))) {
794  }
795 
796  graph->outlink_surface = NULL;
797  graph->outlink_volume = NULL;
798  graph->outlink_displacement = NULL;
799  graph->outlink_thickness = NULL;
800 }
801 
803 {
804  BLI_freelistN(&graph->outlink_aovs);
805  BLI_freelistN(&graph->material_functions);
807 
808  BLI_freelistN(&graph->textures);
809  BLI_freelistN(&graph->attributes);
810  GPU_uniform_attr_list_free(&graph->uniform_attrs);
811 
812  if (graph->used_libraries) {
813  BLI_gset_free(graph->used_libraries, NULL);
814  graph->used_libraries = NULL;
815  }
816 }
817 
818 /* Prune Unused Nodes */
819 
820 static void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag)
821 {
822  GPUNode *node;
823 
824  if (!link || !link->output) {
825  return;
826  }
827 
828  node = link->output->node;
829  if (node->tag & tag) {
830  return;
831  }
832 
833  node->tag |= tag;
834  LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
835  if (input->link) {
836  gpu_nodes_tag(input->link, tag);
837  }
838  }
839 }
840 
842 {
843  LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
844  node->tag = GPU_NODE_TAG_NONE;
845  }
846 
847  gpu_nodes_tag(graph->outlink_surface, GPU_NODE_TAG_SURFACE);
848  gpu_nodes_tag(graph->outlink_volume, GPU_NODE_TAG_VOLUME);
849  gpu_nodes_tag(graph->outlink_displacement, GPU_NODE_TAG_DISPLACEMENT);
850  gpu_nodes_tag(graph->outlink_thickness, GPU_NODE_TAG_THICKNESS);
851 
852  LISTBASE_FOREACH (GPUNodeGraphOutputLink *, aovlink, &graph->outlink_aovs) {
853  gpu_nodes_tag(aovlink->outlink, GPU_NODE_TAG_AOV);
854  }
855  LISTBASE_FOREACH (GPUNodeGraphFunctionLink *, funclink, &graph->material_functions) {
856  gpu_nodes_tag(funclink->outlink, GPU_NODE_TAG_FUNCTION);
857  }
858 
859  for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
860  next = node->next;
861 
862  if (node->tag == GPU_NODE_TAG_NONE) {
863  BLI_remlink(&graph->nodes, node);
865  }
866  }
867 
868  for (GPUMaterialAttribute *attr = graph->attributes.first, *next = NULL; attr; attr = next) {
869  next = attr->next;
870  if (attr->users == 0) {
871  BLI_freelinkN(&graph->attributes, attr);
872  }
873  }
874 
875  for (GPUMaterialTexture *tex = graph->textures.first, *next = NULL; tex; tex = next) {
876  next = tex->next;
877  if (tex->users == 0) {
878  BLI_freelinkN(&graph->textures, tex);
879  }
880  }
881 
882  GPUUniformAttrList *uattrs = &graph->uniform_attrs;
883 
884  LISTBASE_FOREACH_MUTABLE (GPUUniformAttr *, attr, &uattrs->list) {
885  if (attr->users == 0) {
886  BLI_freelinkN(&uattrs->list, attr);
887  uattrs->count--;
888  }
889  }
890 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
unsigned int BLI_ghashutil_uinthash(unsigned int key)
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:689
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:221
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STR_ELEM(...)
Definition: BLI_string.h:539
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define ELEM(...)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
eCustomDataType
@ CD_HAIRLENGTH
@ CD_AUTO_FROM_NAME
@ CD_TANGENT
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_HIDE_VALUE
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_RGBA
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
eGPUDefaultValue
Definition: GPU_material.h:120
@ GPU_MATFLAG_OBJECT_INFO
Definition: GPU_material.h:82
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
Definition: gpu_material.c:596
eGPUType
Definition: GPU_material.h:45
@ GPU_MAX_CONSTANT_DATA
Definition: GPU_material.h:55
@ GPU_NONE
Definition: GPU_material.h:48
@ GPU_CLOSURE
Definition: GPU_material.h:64
#define GPU_MAX_UNIFORM_ATTR
Definition: GPU_shader.h:391
eGPUSamplerState
Definition: GPU_texture.h:25
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
static const int GPU_SAMPLER_MAX
Definition: GPU_texture.h:52
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint max_len)
#define GPU_MAX_SAFE_ATTR_NAME
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
OperationNode * node
Depsgraph * graph
Material material
SyclQueue void void * src
SyclQueue void * dest
GPUNodeGraph * gpu_material_node_graph(GPUMaterial *material)
Definition: gpu_material.c:569
GPUTexture ** gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row)
Definition: gpu_material.c:99
GPUFunction * gpu_material_library_use_function(struct GSet *used_libraries, const char *name)
@ FUNCTION_QUAL_OUT
GPUNodeLink * GPU_image_tiled(GPUMaterial *mat, Image *ima, ImageUser *iuser, eGPUSamplerState sampler_state)
static GPUMaterialAttribute * gpu_node_graph_add_attribute(GPUNodeGraph *graph, eCustomDataType type, const char *name, const bool is_default_color)
void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src)
struct GHash * GPU_uniform_attr_list_hash_new(const char *info)
GPUNodeLink * GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
GPUNodeLink * GPU_attribute_default_color(GPUMaterial *mat)
GPUNodeLink * GPU_image(GPUMaterial *mat, Image *ima, ImageUser *iuser, eGPUSamplerState sampler_state)
static void gpu_node_input_socket(GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index)
GPUNodeLink * GPU_differentiate_float_function(const char *function_name)
static const char * gpu_uniform_set_function_from_type(eNodeSocketDatatype type)
GPUNodeLink * GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli)
static bool gpu_stack_link_v(GPUMaterial *material, bNode *bnode, const char *name, GPUNodeStack *in, GPUNodeStack *out, va_list params)
static void gpu_node_free(GPUNode *node)
static void gpu_inputs_free(ListBase *inputs)
static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **link)
GPUNodeLink * GPU_uniformbuf_link_out(GPUMaterial *mat, bNode *node, GPUNodeStack *stack, const int index)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, const eCustomDataType type, const char *name)
GPUNodeLink * GPU_attribute_with_default(GPUMaterial *mat, const eCustomDataType type, const char *name, eGPUDefaultValue default_value)
static GPUNode * gpu_node_create(const char *name)
static GPUNodeLink * gpu_uniformbuffer_link(GPUMaterial *mat, bNode *node, GPUNodeStack *stack, const int index, const eNodeSocketInOut in_out)
GPUNodeLink * GPU_constant(const float *num)
static GPUNodeLink * gpu_node_link_create(void)
void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph)
static void gpu_node_link_free(GPUNodeLink *link)
GPUNodeLink * GPU_uniform(const float *num)
bool GPU_stack_link(GPUMaterial *material, bNode *bnode, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType type)
static GPUMaterialTexture * gpu_node_graph_add_texture(GPUNodeGraph *graph, Image *ima, ImageUser *iuser, struct GPUTexture **colorband, GPUNodeLinkType link_type, eGPUSamplerState sampler_state)
void GPU_uniform_attr_list_free(GPUUniformAttrList *set)
static unsigned int uniform_attr_list_hash(const void *key)
void gpu_node_graph_free(GPUNodeGraph *graph)
void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
static void gpu_nodes_tag(GPUNodeLink *link, eGPUNodeTag tag)
static GPUUniformAttr * gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph, const char *name, bool use_dupli)
static void attr_input_name(GPUMaterialAttribute *attr)
static bool uniform_attr_list_cmp(const void *a, const void *b)
static char attr_prefix_get(GPUMaterialAttribute *attr)
static int uniform_attr_sort_cmp(const void *a, const void *b)
void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUNodeLink * GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iuser)
eGPUNodeTag
@ GPU_NODE_TAG_NONE
@ GPU_NODE_TAG_SURFACE
@ GPU_NODE_TAG_DISPLACEMENT
@ GPU_NODE_TAG_VOLUME
@ GPU_NODE_TAG_FUNCTION
@ GPU_NODE_TAG_THICKNESS
@ GPU_NODE_TAG_AOV
@ GPU_SOURCE_CONSTANT
@ GPU_SOURCE_FUNCTION_CALL
@ GPU_SOURCE_ATTR
@ GPU_SOURCE_UNIFORM
@ GPU_SOURCE_OUTPUT
@ GPU_SOURCE_TEX_TILED_MAPPING
@ GPU_SOURCE_UNIFORM_ATTR
@ GPU_SOURCE_STRUCT
@ GPU_SOURCE_TEX
GPUNodeLinkType
@ GPU_NODE_LINK_UNIFORM
@ GPU_NODE_LINK_ATTR
@ GPU_NODE_LINK_IMAGE
@ GPU_NODE_LINK_IMAGE_TILED
@ GPU_NODE_LINK_CONSTANT
@ GPU_NODE_LINK_IMAGE_TILED_MAPPING
@ GPU_NODE_LINK_COLORBAND
@ GPU_NODE_LINK_UNIFORM_ATTR
@ GPU_NODE_LINK_OUTPUT
@ GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static ulong * next
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static bNodeSocketTemplate inputs[]
eGPUDefaultValue default_value
Definition: GPU_material.h:279
struct GPUMaterialAttribute * next
Definition: GPU_material.h:274
struct GPUNodeLink * link
Definition: GPU_material.h:106
eGPUType type
Definition: GPU_material.h:104
float vec[4]
Definition: GPU_material.h:105
ListBase inputs
const char * name
GPUNodeLink * link
GPUNode * node
unsigned int count
Definition: GPU_material.h:321
unsigned int hash_code
Definition: GPU_material.h:321
struct GPUUniformAttr * next
Definition: GPU_material.h:306
void * first
Definition: DNA_listBase.h:31
struct ImageUser iuser
struct Image * ima
void * default_value