Blender  V2.93
gpu_node_graph.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include <stdio.h>
27 #include <string.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "DNA_node_types.h"
32 
33 #include "BLI_ghash.h"
34 #include "BLI_listbase.h"
35 #include "BLI_string.h"
36 #include "BLI_utildefines.h"
37 
38 #include "GPU_texture.h"
39 
40 #include "gpu_material_library.h"
41 #include "gpu_node_graph.h"
42 
43 /* Node Link Functions */
44 
46 {
47  GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
48  link->users++;
49 
50  return link;
51 }
52 
53 static void gpu_node_link_free(GPUNodeLink *link)
54 {
55  link->users--;
56 
57  if (link->users < 0) {
58  fprintf(stderr, "gpu_node_link_free: negative refcount\n");
59  }
60 
61  if (link->users == 0) {
62  if (link->output) {
63  link->output->link = NULL;
64  }
65  MEM_freeN(link);
66  }
67 }
68 
69 /* Node Functions */
70 
71 static GPUNode *gpu_node_create(const char *name)
72 {
73  GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
74 
75  node->name = name;
76 
77  return node;
78 }
79 
81 {
82  GPUInput *input;
83  GPUNode *outnode;
84  const char *name;
85 
86  if (link->link_type == GPU_NODE_LINK_OUTPUT) {
87  outnode = link->output->node;
88  name = outnode->name;
89  input = outnode->inputs.first;
90 
91  if ((STR_ELEM(name, "set_value", "set_rgb", "set_rgba")) && (input->type == type)) {
92  input = MEM_dupallocN(outnode->inputs.first);
93  if (input->link) {
94  input->link->users++;
95  }
96  BLI_addtail(&node->inputs, input);
97  return;
98  }
99  }
100 
101  input = MEM_callocN(sizeof(GPUInput), "GPUInput");
102  input->node = node;
103  input->type = type;
104 
105  switch (link->link_type) {
107  input->source = GPU_SOURCE_BUILTIN;
108  input->builtin = link->builtin;
109  break;
111  input->source = GPU_SOURCE_OUTPUT;
112  input->link = link;
113  link->users++;
114  break;
115  case GPU_NODE_LINK_IMAGE:
118  input->source = GPU_SOURCE_TEX;
119  input->texture = link->texture;
120  break;
123  input->texture = link->texture;
124  break;
127  input->volume_grid = link->volume_grid;
128  break;
131  input->volume_grid = link->volume_grid;
132  break;
133  case GPU_NODE_LINK_ATTR:
134  input->source = GPU_SOURCE_ATTR;
135  input->attr = link->attr;
136  /* Fail-safe handling if the same attribute is used with different data-types for
137  * some reason (only really makes sense with float/vec2/vec3/vec4 though). This
138  * can happen if mixing the generic Attribute node with specialized ones. */
139  CLAMP_MIN(input->attr->gputype, type);
140  break;
143  input->uniform_attr = link->uniform_attr;
144  break;
147  break;
149  input->source = GPU_SOURCE_UNIFORM;
150  break;
151  default:
152  break;
153  }
154 
156  memcpy(input->vec, link->data, type * sizeof(float));
157  }
158 
159  if (link->link_type != GPU_NODE_LINK_OUTPUT) {
160  MEM_freeN(link);
161  }
162  BLI_addtail(&node->inputs, input);
163 }
164 
166 {
167  switch (type) {
168  /* For now INT is supported as float. */
169  case SOCK_INT:
170  case SOCK_FLOAT:
171  return "set_value";
172  case SOCK_VECTOR:
173  return "set_rgb";
174  case SOCK_RGBA:
175  return "set_rgba";
176  default:
177  BLI_assert(!"No gpu function for non-supported eNodeSocketDatatype");
178  return NULL;
179  }
180 }
181 
187  bNode *node,
188  GPUNodeStack *stack,
189  const int index,
190  const eNodeSocketInOut in_out)
191 {
192  bNodeSocket *socket;
193 
194  if (in_out == SOCK_IN) {
195  socket = BLI_findlink(&node->inputs, index);
196  }
197  else {
198  socket = BLI_findlink(&node->outputs, index);
199  }
200 
201  BLI_assert(socket != NULL);
202  BLI_assert(socket->in_out == in_out);
203 
204  if ((socket->flag & SOCK_HIDE_VALUE) == 0) {
205  GPUNodeLink *link;
206  switch (socket->type) {
207  case SOCK_FLOAT: {
208  bNodeSocketValueFloat *socket_data = socket->default_value;
209  link = GPU_uniform(&socket_data->value);
210  break;
211  }
212  case SOCK_VECTOR: {
213  bNodeSocketValueVector *socket_data = socket->default_value;
214  link = GPU_uniform(socket_data->value);
215  break;
216  }
217  case SOCK_RGBA: {
218  bNodeSocketValueRGBA *socket_data = socket->default_value;
219  link = GPU_uniform(socket_data->value);
220  break;
221  }
222  default:
223  return NULL;
224  break;
225  }
226 
227  if (in_out == SOCK_IN) {
228  GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link);
229  }
230  return link;
231  }
232  return NULL;
233 }
234 
236  GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index)
237 {
238  if (sock->link) {
239  gpu_node_input_link(node, sock->link, sock->type);
240  }
241  else if ((material != NULL) &&
242  (gpu_uniformbuffer_link(material, bnode, sock, index, SOCK_IN) != NULL)) {
243  gpu_node_input_link(node, sock->link, sock->type);
244  }
245  else {
246  gpu_node_input_link(node, GPU_constant(sock->vec), sock->type);
247  }
248 }
249 
250 static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **link)
251 {
252  GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
253 
254  output->type = type;
255  output->node = node;
256 
257  if (link) {
258  *link = output->link = gpu_node_link_create();
259  output->link->link_type = GPU_NODE_LINK_OUTPUT;
260  output->link->output = output;
261 
262  /* note: the caller owns the reference to the link, GPUOutput
263  * merely points to it, and if the node is destroyed it will
264  * set that pointer to NULL */
265  }
266 
267  BLI_addtail(&node->outputs, output);
268 }
269 
270 /* Uniform Attribute Functions */
271 
272 static int uniform_attr_sort_cmp(const void *a, const void *b)
273 {
274  const GPUUniformAttr *attr_a = a, *attr_b = b;
275 
276  int cmps = strcmp(attr_a->name, attr_b->name);
277  if (cmps != 0) {
278  return cmps > 0 ? 1 : 0;
279  }
280 
281  return (attr_a->use_dupli && !attr_b->use_dupli);
282 }
283 
284 static unsigned int uniform_attr_list_hash(const void *key)
285 {
286  const GPUUniformAttrList *attrs = key;
287  return attrs->hash_code;
288 }
289 
290 static bool uniform_attr_list_cmp(const void *a, const void *b)
291 {
292  const GPUUniformAttrList *set_a = a, *set_b = b;
293 
294  if (set_a->hash_code != set_b->hash_code || set_a->count != set_b->count) {
295  return true;
296  }
297 
298  GPUUniformAttr *attr_a = set_a->list.first, *attr_b = set_b->list.first;
299 
300  for (; attr_a && attr_b; attr_a = attr_a->next, attr_b = attr_b->next) {
301  if (!STREQ(attr_a->name, attr_b->name) || attr_a->use_dupli != attr_b->use_dupli) {
302  return true;
303  }
304  }
305 
306  return attr_a || attr_b;
307 }
308 
309 struct GHash *GPU_uniform_attr_list_hash_new(const char *info)
310 {
312 }
313 
315 {
316  dest->count = src->count;
317  dest->hash_code = src->hash_code;
318  BLI_duplicatelist(&dest->list, &src->list);
319 }
320 
322 {
323  set->count = 0;
324  set->hash_code = 0;
325  BLI_freelistN(&set->list);
326 }
327 
329 {
330  GPUUniformAttrList *attrs = &graph->uniform_attrs;
331  BLI_assert(attrs->count == BLI_listbase_count(&attrs->list));
332 
333  /* Sort the attributes by name to ensure a stable order. */
335 
336  /* Compute the indices and the hash code. */
337  int next_id = 0;
338  attrs->hash_code = 0;
339 
340  LISTBASE_FOREACH (GPUUniformAttr *, attr, &attrs->list) {
341  attr->id = next_id++;
342 
343  attrs->hash_code ^= BLI_ghashutil_strhash_p(attr->name);
344 
345  if (attr->use_dupli) {
346  attrs->hash_code ^= BLI_ghashutil_uinthash(attr->id);
347  }
348  }
349 }
350 
351 /* Attributes and Textures */
352 
356  const char *name)
357 {
358  /* Fall back to the UV layer, which matches old behavior. */
359  if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
360  type = CD_MTFACE;
361  }
362 
363  /* Find existing attribute. */
364  int num_attributes = 0;
365  GPUMaterialAttribute *attr = graph->attributes.first;
366  for (; attr; attr = attr->next) {
367  if (attr->type == type && STREQ(attr->name, name)) {
368  break;
369  }
370  num_attributes++;
371  }
372 
373  /* Add new requested attribute if it's within GPU limits. */
374  if (attr == NULL && num_attributes < GPU_MAX_ATTR) {
375  attr = MEM_callocN(sizeof(*attr), __func__);
376  attr->type = type;
377  STRNCPY(attr->name, name);
378  attr->id = num_attributes;
379  BLI_addtail(&graph->attributes, attr);
380  }
381 
382  if (attr != NULL) {
383  attr->users++;
384  }
385 
386  return attr;
387 }
388 
391  const char *name,
392  bool use_dupli)
393 {
394  /* Find existing attribute. */
395  GPUUniformAttrList *attrs = &graph->uniform_attrs;
396  GPUUniformAttr *attr = attrs->list.first;
397 
398  for (; attr; attr = attr->next) {
399  if (STREQ(attr->name, name) && attr->use_dupli == use_dupli) {
400  break;
401  }
402  }
403 
404  /* Add new requested attribute if it's within GPU limits. */
405  if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) {
406  attr = MEM_callocN(sizeof(*attr), __func__);
407  STRNCPY(attr->name, name);
408  attr->use_dupli = use_dupli;
409  attr->id = -1;
410  BLI_addtail(&attrs->list, attr);
411  attrs->count++;
412  }
413 
414  if (attr != NULL) {
415  attr->users++;
416  }
417 
418  return attr;
419 }
420 
422  Image *ima,
423  ImageUser *iuser,
424  struct GPUTexture **colorband,
425  GPUNodeLinkType link_type,
426  eGPUSamplerState sampler_state)
427 {
428  /* Find existing texture. */
429  int num_textures = 0;
430  GPUMaterialTexture *tex = graph->textures.first;
431  for (; tex; tex = tex->next) {
432  if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) {
433  break;
434  }
435  num_textures++;
436  }
437 
438  /* Add new requested texture. */
439  if (tex == NULL) {
440  tex = MEM_callocN(sizeof(*tex), __func__);
441  tex->ima = ima;
442  tex->iuser = iuser;
443  tex->colorband = colorband;
444  tex->sampler_state = sampler_state;
445  BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
447  BLI_snprintf(
448  tex->tiled_mapping_name, sizeof(tex->tiled_mapping_name), "tsamp%d", num_textures);
449  }
450  BLI_addtail(&graph->textures, tex);
451  }
452 
453  tex->users++;
454 
455  return tex;
456 }
457 
459  const char *name,
460  eGPUVolumeDefaultValue default_value)
461 {
462  /* Find existing volume grid. */
463  int num_grids = 0;
464  GPUMaterialVolumeGrid *grid = graph->volume_grids.first;
465  for (; grid; grid = grid->next) {
466  if (STREQ(grid->name, name) && grid->default_value == default_value) {
467  break;
468  }
469  num_grids++;
470  }
471 
472  /* Add new requested volume grid. */
473  if (grid == NULL) {
474  grid = MEM_callocN(sizeof(*grid), __func__);
475  grid->name = BLI_strdup(name);
476  grid->default_value = default_value;
477  BLI_snprintf(grid->sampler_name, sizeof(grid->sampler_name), "vsamp%d", num_grids);
478  BLI_snprintf(grid->transform_name, sizeof(grid->transform_name), "vtfm%d", num_grids);
479  BLI_addtail(&graph->volume_grids, grid);
480  }
481 
482  grid->users++;
483 
484  return grid;
485 }
486 
487 /* Creating Inputs */
488 
489 GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name)
490 {
493 
494  /* Dummy fallback if out of slots. */
495  if (attr == NULL) {
496  static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
497  return GPU_constant(zero_data);
498  }
499 
502  link->attr = attr;
503  return link;
504 }
505 
506 GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli)
507 {
510 
511  /* Dummy fallback if out of slots. */
512  if (attr == NULL) {
513  static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f};
514  return GPU_constant(zero_data);
515  }
516 
519  link->uniform_attr = attr;
520  return link;
521 }
522 
523 GPUNodeLink *GPU_constant(const float *num)
524 {
527  link->data = num;
528  return link;
529 }
530 
531 GPUNodeLink *GPU_uniform(const float *num)
532 {
535  link->data = num;
536  return link;
537 }
538 
540  Image *ima,
541  ImageUser *iuser,
542  eGPUSamplerState sampler_state)
543 {
548  graph, ima, iuser, NULL, link->link_type, sampler_state);
549  return link;
550 }
551 
553  Image *ima,
554  ImageUser *iuser,
555  eGPUSamplerState sampler_state)
556 {
561  graph, ima, iuser, NULL, link->link_type, sampler_state);
562  return link;
563 }
564 
566 {
571  graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX);
572  return link;
573 }
574 
575 GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
576 {
577  struct GPUTexture **colorband = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
578  MEM_freeN(pixels);
579 
584  graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX);
585  return link;
586 }
587 
589  const char *name,
590  eGPUVolumeDefaultValue default_value)
591 {
592  /* NOTE: this could be optimized by automatically merging duplicate
593  * lookups of the same attribute. */
597  link->volume_grid = gpu_node_graph_add_volume_grid(graph, name, default_value);
598 
599  GPUNodeLink *transform_link = gpu_node_link_create();
601  transform_link->volume_grid = link->volume_grid;
602  transform_link->volume_grid->users++;
603 
604  /* Two special cases, where we adjust the output values of smoke grids to
605  * bring the into standard range without having to modify the grid values. */
606  if (STREQ(name, "color")) {
607  GPU_link(mat, "node_attribute_volume_color", link, transform_link, &link);
608  }
609  else if (STREQ(name, "temperature")) {
610  GPU_link(mat, "node_attribute_volume_temperature", link, transform_link, &link);
611  }
612  else {
613  GPU_link(mat, "node_attribute_volume", link, transform_link, &link);
614  }
615 
616  return link;
617 }
618 
620 {
623  link->builtin = builtin;
624  return link;
625 }
626 
627 /* Creating Nodes */
628 
629 bool GPU_link(GPUMaterial *mat, const char *name, ...)
630 {
631  GSet *used_libraries = gpu_material_used_libraries(mat);
632  GPUNode *node;
633  GPUFunction *function;
634  GPUNodeLink *link, **linkptr;
635  va_list params;
636  int i;
637 
638  function = gpu_material_library_use_function(used_libraries, name);
639  if (!function) {
640  fprintf(stderr, "GPU failed to find function %s\n", name);
641  return false;
642  }
643 
644  node = gpu_node_create(name);
645 
646  va_start(params, name);
647  for (i = 0; i < function->totparam; i++) {
648  if (function->paramqual[i] != FUNCTION_QUAL_IN) {
649  linkptr = va_arg(params, GPUNodeLink **);
650  gpu_node_output(node, function->paramtype[i], linkptr);
651  }
652  else {
653  link = va_arg(params, GPUNodeLink *);
654  gpu_node_input_link(node, link, function->paramtype[i]);
655  }
656  }
657  va_end(params);
658 
660  BLI_addtail(&graph->nodes, node);
661 
662  return true;
663 }
664 
666  bNode *bnode,
667  const char *name,
668  GPUNodeStack *in,
669  GPUNodeStack *out,
670  ...)
671 {
672  GSet *used_libraries = gpu_material_used_libraries(material);
673  GPUNode *node;
674  GPUFunction *function;
675  GPUNodeLink *link, **linkptr;
676  va_list params;
677  int i, totin, totout;
678 
679  function = gpu_material_library_use_function(used_libraries, name);
680  if (!function) {
681  fprintf(stderr, "GPU failed to find function %s\n", name);
682  return false;
683  }
684 
685  node = gpu_node_create(name);
686  totin = 0;
687  totout = 0;
688 
689  if (in) {
690  for (i = 0; !in[i].end; i++) {
691  if (in[i].type != GPU_NONE) {
692  gpu_node_input_socket(material, bnode, node, &in[i], i);
693  totin++;
694  }
695  }
696  }
697 
698  if (out) {
699  for (i = 0; !out[i].end; i++) {
700  if (out[i].type != GPU_NONE) {
701  gpu_node_output(node, out[i].type, &out[i].link);
702  totout++;
703  }
704  }
705  }
706 
707  va_start(params, out);
708  for (i = 0; i < function->totparam; i++) {
709  if (function->paramqual[i] != FUNCTION_QUAL_IN) {
710  if (totout == 0) {
711  linkptr = va_arg(params, GPUNodeLink **);
712  gpu_node_output(node, function->paramtype[i], linkptr);
713  }
714  else {
715  totout--;
716  }
717  }
718  else {
719  if (totin == 0) {
720  link = va_arg(params, GPUNodeLink *);
721  if (link->socket) {
722  gpu_node_input_socket(NULL, NULL, node, link->socket, -1);
723  }
724  else {
725  gpu_node_input_link(node, link, function->paramtype[i]);
726  }
727  }
728  else {
729  totin--;
730  }
731  }
732  }
733  va_end(params);
734 
736  BLI_addtail(&graph->nodes, node);
737 
738  return true;
739 }
740 
742  bNode *node,
743  GPUNodeStack *stack,
744  const int index)
745 {
746  return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT);
747 }
748 
749 /* Node Graph */
750 
752 {
753  GPUInput *input;
754 
755  for (input = inputs->first; input; input = input->next) {
756  if (input->source == GPU_SOURCE_ATTR) {
757  input->attr->users--;
758  }
759  else if (input->source == GPU_SOURCE_UNIFORM_ATTR) {
760  input->uniform_attr->users--;
761  }
763  input->texture->users--;
764  }
766  input->volume_grid->users--;
767  }
768 
769  if (input->link) {
770  gpu_node_link_free(input->link);
771  }
772  }
773 
775 }
776 
778 {
779  GPUOutput *output;
780 
781  gpu_inputs_free(&node->inputs);
782 
783  for (output = node->outputs.first; output; output = output->next) {
784  if (output->link) {
785  output->link->output = NULL;
786  gpu_node_link_free(output->link);
787  }
788  }
789 
790  BLI_freelistN(&node->outputs);
791  MEM_freeN(node);
792 }
793 
794 /* Free intermediate node graph. */
796 {
797  GPUNode *node;
798 
799  while ((node = BLI_pophead(&graph->nodes))) {
801  }
802 
803  graph->outlink = NULL;
804 }
805 
806 /* Free both node graph and requested attributes and textures. */
808 {
809  BLI_freelistN(&graph->outlink_aovs);
811 
812  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, grid, &graph->volume_grids) {
813  MEM_SAFE_FREE(grid->name);
814  }
815  BLI_freelistN(&graph->volume_grids);
816  BLI_freelistN(&graph->textures);
817  BLI_freelistN(&graph->attributes);
818  GPU_uniform_attr_list_free(&graph->uniform_attrs);
819 }
820 
821 /* Prune Unused Nodes */
822 
823 static void gpu_nodes_tag(GPUNodeLink *link)
824 {
825  GPUNode *node;
826  GPUInput *input;
827 
828  if (!link->output) {
829  return;
830  }
831 
832  node = link->output->node;
833  if (node->tag) {
834  return;
835  }
836 
837  node->tag = true;
838  for (input = node->inputs.first; input; input = input->next) {
839  if (input->link) {
840  gpu_nodes_tag(input->link);
841  }
842  }
843 }
844 
846 {
847  LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
848  node->tag = false;
849  }
850 
851  gpu_nodes_tag(graph->outlink);
852  LISTBASE_FOREACH (GPUNodeGraphOutputLink *, aovlink, &graph->outlink_aovs) {
853  gpu_nodes_tag(aovlink->outlink);
854  }
855 
856  for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
857  next = node->next;
858 
859  if (!node->tag) {
860  BLI_remlink(&graph->nodes, node);
862  }
863  }
864 
865  for (GPUMaterialAttribute *attr = graph->attributes.first, *next = NULL; attr; attr = next) {
866  next = attr->next;
867  if (attr->users == 0) {
868  BLI_freelinkN(&graph->attributes, attr);
869  }
870  }
871 
872  for (GPUMaterialTexture *tex = graph->textures.first, *next = NULL; tex; tex = next) {
873  next = tex->next;
874  if (tex->users == 0) {
875  BLI_freelinkN(&graph->textures, tex);
876  }
877  }
878 
879  for (GPUMaterialVolumeGrid *grid = graph->volume_grids.first, *next = NULL; grid; grid = next) {
880  next = grid->next;
881  if (grid->users == 0) {
882  MEM_SAFE_FREE(grid->name);
883  BLI_freelinkN(&graph->volume_grids, grid);
884  }
885  }
886 
887  GPUUniformAttrList *uattrs = &graph->uniform_attrs;
888 
889  LISTBASE_FOREACH_MUTABLE (GPUUniformAttr *, attr, &uattrs->list) {
890  if (attr->users == 0) {
891  BLI_freelinkN(&uattrs->list, attr);
892  uattrs->count--;
893  }
894  }
895 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct GSet GSet
Definition: BLI_ghash.h:189
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:718
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:257
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
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:188
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
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:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
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:218
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:70
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)
CustomDataType
@ CD_AUTO_FROM_NAME
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
eGPUBuiltin
Definition: GPU_material.h:86
eGPUType
Definition: GPU_material.h:59
@ GPU_MAX_CONSTANT_DATA
Definition: GPU_material.h:69
@ GPU_NONE
Definition: GPU_material.h:62
@ GPU_CLOSURE
Definition: GPU_material.h:80
eGPUVolumeDefaultValue
Definition: GPU_material.h:132
#define GPU_MAX_UNIFORM_ATTR
Definition: GPU_shader.h:423
#define GPU_MAX_ATTR
Definition: GPU_shader.h:420
eGPUSamplerState
Definition: GPU_texture.h:40
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
static const int GPU_SAMPLER_MAX
Definition: GPU_texture.h:58
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define output
OperationNode * node
Depsgraph * graph
Material material
GSet * gpu_material_used_libraries(GPUMaterial *material)
Definition: gpu_material.c:613
GPUNodeGraph * gpu_material_node_graph(GPUMaterial *material)
Definition: gpu_material.c:608
GPUTexture ** gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row)
Definition: gpu_material.c:121
GPUFunction * gpu_material_library_use_function(GSet *used_libraries, const char *name)
@ FUNCTION_QUAL_IN
GPUNodeLink * GPU_image_tiled(GPUMaterial *mat, Image *ima, ImageUser *iuser, eGPUSamplerState sampler_state)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name)
GPUNodeLink * GPU_builtin(eGPUBuiltin builtin)
static GPUMaterialAttribute * gpu_node_graph_add_attribute(GPUNodeGraph *graph, CustomDataType type, const char *name)
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_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)
static const char * gpu_uniform_set_function_from_type(eNodeSocketDatatype type)
GPUNodeLink * GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli)
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)
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 void gpu_nodes_tag(GPUNodeLink *link)
GPUNodeLink * GPU_volume_grid(GPUMaterial *mat, const char *name, eGPUVolumeDefaultValue default_value)
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 GPUUniformAttr * gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph, const char *name, bool use_dupli)
static bool uniform_attr_list_cmp(const void *a, const void *b)
static GPUMaterialVolumeGrid * gpu_node_graph_add_volume_grid(GPUNodeGraph *graph, const char *name, eGPUVolumeDefaultValue default_value)
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)
@ GPU_SOURCE_CONSTANT
@ GPU_SOURCE_ATTR
@ GPU_SOURCE_VOLUME_GRID_TRANSFORM
@ GPU_SOURCE_UNIFORM
@ GPU_SOURCE_VOLUME_GRID
@ GPU_SOURCE_OUTPUT
@ GPU_SOURCE_TEX_TILED_MAPPING
@ GPU_SOURCE_BUILTIN
@ 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_BUILTIN
@ GPU_NODE_LINK_VOLUME_GRID_TRANSFORM
@ GPU_NODE_LINK_VOLUME_GRID
@ GPU_NODE_LINK_COLORBAND
@ GPU_NODE_LINK_UNIFORM_ATTR
@ GPU_NODE_LINK_OUTPUT
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong * next
static unsigned a[3]
Definition: RandGen.cpp:92
static bNodeSocketTemplate inputs[]
struct GPUUniformAttr * uniform_attr
GPUNode * node
GPUNodeLink * link
eGPUDataSource source
struct GPUMaterialAttribute * attr
eGPUBuiltin builtin
struct GPUMaterialVolumeGrid * volume_grid
float vec[16]
struct GPUMaterialTexture * texture
struct GPUInput * next
eGPUType type
struct GPUMaterialAttribute * next
Definition: GPU_material.h:233
struct GPUMaterialVolumeGrid * next
Definition: GPU_material.h:253
eGPUVolumeDefaultValue default_value
Definition: GPU_material.h:255
struct GPUNodeLink * link
Definition: GPU_material.h:119
eGPUType type
Definition: GPU_material.h:117
float vec[4]
Definition: GPU_material.h:118
ListBase inputs
const char * name
GPUNodeLink * link
GPUNode * node
unsigned int count
Definition: GPU_material.h:281
unsigned int hash_code
Definition: GPU_material.h:281
struct GPUUniformAttr * next
Definition: GPU_material.h:266
void * first
Definition: DNA_listBase.h:47
struct ImageUser iuser
struct Image * ima
void * default_value