ClangFormat: apply to source, most of intern
[blender.git] / source / blender / gpu / intern / gpu_codegen.c
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
20 /** \file
21  * \ingroup gpu
22  *
23  * Convert material node-trees to GLSL.
24  */
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_customdata_types.h"
29 #include "DNA_image_types.h"
30 #include "DNA_material_types.h"
31 #include "DNA_node_types.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_hash_mm2a.h"
35 #include "BLI_link_utils.h"
36 #include "BLI_utildefines.h"
37 #include "BLI_dynstr.h"
38 #include "BLI_ghash.h"
39 #include "BLI_threads.h"
40
41 #include "PIL_time.h"
42
43 #include "GPU_extensions.h"
44 #include "GPU_glew.h"
45 #include "GPU_material.h"
46 #include "GPU_shader.h"
47 #include "GPU_texture.h"
48 #include "GPU_uniformbuffer.h"
49
50 #include "BLI_sys_types.h" /* for intptr_t support */
51
52 #include "gpu_codegen.h"
53
54 #include <string.h>
55 #include <stdarg.h>
56
57 extern char datatoc_gpu_shader_material_glsl[];
58 extern char datatoc_gpu_shader_geometry_glsl[];
59
60 static char *glsl_material_library = NULL;
61
62 /* -------------------- GPUPass Cache ------------------ */
63 /**
64  * Internal shader cache: This prevent the shader recompilation / stall when
65  * using undo/redo AND also allows for GPUPass reuse if the Shader code is the
66  * same for 2 different Materials. Unused GPUPasses are free by Garbage collection.
67  */
68
69 /* Only use one linklist that contains the GPUPasses grouped by hash. */
70 static GPUPass *pass_cache = NULL;
71 static SpinLock pass_cache_spin;
72
73 static uint32_t gpu_pass_hash(const char *frag_gen, const char *defs, GPUVertAttrLayers *attrs)
74 {
75   BLI_HashMurmur2A hm2a;
76   BLI_hash_mm2a_init(&hm2a, 0);
77   BLI_hash_mm2a_add(&hm2a, (uchar *)frag_gen, strlen(frag_gen));
78   if (attrs) {
79     for (int att_idx = 0; att_idx < attrs->totlayer; att_idx++) {
80       char *name = attrs->layer[att_idx].name;
81       BLI_hash_mm2a_add(&hm2a, (uchar *)name, strlen(name));
82     }
83   }
84   if (defs)
85     BLI_hash_mm2a_add(&hm2a, (uchar *)defs, strlen(defs));
86
87   return BLI_hash_mm2a_end(&hm2a);
88 }
89
90 /* Search by hash only. Return first pass with the same hash.
91  * There is hash collision if (pass->next && pass->next->hash == hash) */
92 static GPUPass *gpu_pass_cache_lookup(uint32_t hash)
93 {
94   BLI_spin_lock(&pass_cache_spin);
95   /* Could be optimized with a Lookup table. */
96   for (GPUPass *pass = pass_cache; pass; pass = pass->next) {
97     if (pass->hash == hash) {
98       BLI_spin_unlock(&pass_cache_spin);
99       return pass;
100     }
101   }
102   BLI_spin_unlock(&pass_cache_spin);
103   return NULL;
104 }
105
106 /* Check all possible passes with the same hash. */
107 static GPUPass *gpu_pass_cache_resolve_collision(GPUPass *pass,
108                                                  const char *vert,
109                                                  const char *geom,
110                                                  const char *frag,
111                                                  const char *defs,
112                                                  uint32_t hash)
113 {
114   BLI_spin_lock(&pass_cache_spin);
115   /* Collision, need to strcmp the whole shader. */
116   for (; pass && (pass->hash == hash); pass = pass->next) {
117     if ((defs != NULL) && (strcmp(pass->defines, defs) != 0)) { /* Pass */
118     }
119     else if ((geom != NULL) && (strcmp(pass->geometrycode, geom) != 0)) { /* Pass */
120     }
121     else if ((strcmp(pass->fragmentcode, frag) == 0) && (strcmp(pass->vertexcode, vert) == 0)) {
122       BLI_spin_unlock(&pass_cache_spin);
123       return pass;
124     }
125   }
126   BLI_spin_unlock(&pass_cache_spin);
127   return NULL;
128 }
129
130 /* -------------------- GPU Codegen ------------------ */
131
132 /* type definitions and constants */
133
134 #define MAX_FUNCTION_NAME 64
135 #define MAX_PARAMETER 32
136
137 typedef enum {
138   FUNCTION_QUAL_IN,
139   FUNCTION_QUAL_OUT,
140   FUNCTION_QUAL_INOUT,
141 } GPUFunctionQual;
142
143 typedef struct GPUFunction {
144   char name[MAX_FUNCTION_NAME];
145   eGPUType paramtype[MAX_PARAMETER];
146   GPUFunctionQual paramqual[MAX_PARAMETER];
147   int totparam;
148 } GPUFunction;
149
150 /* Indices match the eGPUType enum */
151 static const char *GPU_DATATYPE_STR[17] = {
152     "",
153     "float",
154     "vec2",
155     "vec3",
156     "vec4",
157     NULL,
158     NULL,
159     NULL,
160     NULL,
161     "mat3",
162     NULL,
163     NULL,
164     NULL,
165     NULL,
166     NULL,
167     NULL,
168     "mat4",
169 };
170
171 /* GLSL code parsing for finding function definitions.
172  * These are stored in a hash for lookup when creating a material. */
173
174 static GHash *FUNCTION_HASH = NULL;
175 #if 0
176 static char *FUNCTION_PROTOTYPES = NULL;
177 static GPUShader *FUNCTION_LIB = NULL;
178 #endif
179
180 static int gpu_str_prefix(const char *str, const char *prefix)
181 {
182   while (*str && *prefix) {
183     if (*str != *prefix)
184       return 0;
185
186     str++;
187     prefix++;
188   }
189
190   return (*prefix == '\0');
191 }
192
193 static char *gpu_str_skip_token(char *str, char *token, int max)
194 {
195   int len = 0;
196
197   /* skip a variable/function name */
198   while (*str) {
199     if (ELEM(*str, ' ', '(', ')', ',', ';', '\t', '\n', '\r'))
200       break;
201     else {
202       if (token && len < max - 1) {
203         *token = *str;
204         token++;
205         len++;
206       }
207       str++;
208     }
209   }
210
211   if (token)
212     *token = '\0';
213
214   /* skip the next special characters:
215    * note the missing ')' */
216   while (*str) {
217     if (ELEM(*str, ' ', '(', ',', ';', '\t', '\n', '\r'))
218       str++;
219     else
220       break;
221   }
222
223   return str;
224 }
225
226 static void gpu_parse_functions_string(GHash *hash, char *code)
227 {
228   GPUFunction *function;
229   eGPUType type;
230   GPUFunctionQual qual;
231   int i;
232
233   while ((code = strstr(code, "void "))) {
234     function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
235
236     code = gpu_str_skip_token(code, NULL, 0);
237     code = gpu_str_skip_token(code, function->name, MAX_FUNCTION_NAME);
238
239     /* get parameters */
240     while (*code && *code != ')') {
241       /* test if it's an input or output */
242       qual = FUNCTION_QUAL_IN;
243       if (gpu_str_prefix(code, "out "))
244         qual = FUNCTION_QUAL_OUT;
245       if (gpu_str_prefix(code, "inout "))
246         qual = FUNCTION_QUAL_INOUT;
247       if ((qual != FUNCTION_QUAL_IN) || gpu_str_prefix(code, "in "))
248         code = gpu_str_skip_token(code, NULL, 0);
249
250       /* test for type */
251       type = GPU_NONE;
252       for (i = 1; i < ARRAY_SIZE(GPU_DATATYPE_STR); i++) {
253         if (GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
254           type = i;
255           break;
256         }
257       }
258
259       if (!type && gpu_str_prefix(code, "samplerCube")) {
260         type = GPU_TEXCUBE;
261       }
262       if (!type && gpu_str_prefix(code, "sampler2DShadow")) {
263         type = GPU_SHADOW2D;
264       }
265       if (!type && gpu_str_prefix(code, "sampler1DArray")) {
266         type = GPU_TEX1D_ARRAY;
267       }
268       if (!type && gpu_str_prefix(code, "sampler2D")) {
269         type = GPU_TEX2D;
270       }
271       if (!type && gpu_str_prefix(code, "sampler3D")) {
272         type = GPU_TEX3D;
273       }
274
275       if (!type && gpu_str_prefix(code, "Closure")) {
276         type = GPU_CLOSURE;
277       }
278
279       if (type) {
280         /* add parameter */
281         code = gpu_str_skip_token(code, NULL, 0);
282         code = gpu_str_skip_token(code, NULL, 0);
283         function->paramqual[function->totparam] = qual;
284         function->paramtype[function->totparam] = type;
285         function->totparam++;
286       }
287       else {
288         fprintf(stderr, "GPU invalid function parameter in %s.\n", function->name);
289         break;
290       }
291     }
292
293     if (function->name[0] == '\0' || function->totparam == 0) {
294       fprintf(stderr, "GPU functions parse error.\n");
295       MEM_freeN(function);
296       break;
297     }
298
299     BLI_ghash_insert(hash, function->name, function);
300   }
301 }
302
303 #if 0
304 static char *gpu_generate_function_prototyps(GHash *hash)
305 {
306   DynStr *ds = BLI_dynstr_new();
307   GHashIterator *ghi;
308   GPUFunction *function;
309   char *name, *prototypes;
310   int a;
311
312   /* automatically generate function prototypes to add to the top of the
313    * generated code, to avoid have to add the actual code & recompile all */
314   ghi = BLI_ghashIterator_new(hash);
315
316   for (; !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) {
317     name = BLI_ghashIterator_getValue(ghi);
318     function = BLI_ghashIterator_getValue(ghi);
319
320     BLI_dynstr_appendf(ds, "void %s(", name);
321     for (a = 0; a < function->totparam; a++) {
322       if (function->paramqual[a] == FUNCTION_QUAL_OUT)
323         BLI_dynstr_append(ds, "out ");
324       else if (function->paramqual[a] == FUNCTION_QUAL_INOUT)
325         BLI_dynstr_append(ds, "inout ");
326
327       if (function->paramtype[a] == GPU_TEX2D)
328         BLI_dynstr_append(ds, "sampler2D");
329       else if (function->paramtype[a] == GPU_SHADOW2D)
330         BLI_dynstr_append(ds, "sampler2DShadow");
331       else
332         BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]);
333 #  if 0
334       BLI_dynstr_appendf(ds, " param%d", a);
335 #  endif
336
337       if (a != function->totparam - 1)
338         BLI_dynstr_append(ds, ", ");
339     }
340     BLI_dynstr_append(ds, ");\n");
341   }
342
343   BLI_dynstr_append(ds, "\n");
344
345   prototypes = BLI_dynstr_get_cstring(ds);
346   BLI_dynstr_free(ds);
347
348   return prototypes;
349 }
350 #endif
351
352 static GPUFunction *gpu_lookup_function(const char *name)
353 {
354   if (!FUNCTION_HASH) {
355     FUNCTION_HASH = BLI_ghash_str_new("GPU_lookup_function gh");
356     gpu_parse_functions_string(FUNCTION_HASH, glsl_material_library);
357   }
358
359   return BLI_ghash_lookup(FUNCTION_HASH, (const void *)name);
360 }
361
362 void gpu_codegen_init(void)
363 {
364   GPU_code_generate_glsl_lib();
365 }
366
367 void gpu_codegen_exit(void)
368 {
369   extern Material defmaterial; /* render module abuse... */
370
371   if (defmaterial.gpumaterial.first)
372     GPU_material_free(&defmaterial.gpumaterial);
373
374   if (FUNCTION_HASH) {
375     BLI_ghash_free(FUNCTION_HASH, NULL, MEM_freeN);
376     FUNCTION_HASH = NULL;
377   }
378
379   GPU_shader_free_builtin_shaders();
380
381   if (glsl_material_library) {
382     MEM_freeN(glsl_material_library);
383     glsl_material_library = NULL;
384   }
385
386 #if 0
387   if (FUNCTION_PROTOTYPES) {
388     MEM_freeN(FUNCTION_PROTOTYPES);
389     FUNCTION_PROTOTYPES = NULL;
390   }
391   if (FUNCTION_LIB) {
392     GPU_shader_free(FUNCTION_LIB);
393     FUNCTION_LIB = NULL;
394   }
395 #endif
396 }
397
398 /* GLSL code generation */
399
400 static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *tmp, int id)
401 {
402   char name[1024];
403
404   BLI_snprintf(name, sizeof(name), "%s%d", tmp, id);
405
406   if (from == to) {
407     BLI_dynstr_append(ds, name);
408   }
409   else if (to == GPU_FLOAT) {
410     if (from == GPU_VEC4)
411       BLI_dynstr_appendf(ds, "convert_rgba_to_float(%s)", name);
412     else if (from == GPU_VEC3)
413       BLI_dynstr_appendf(ds, "(%s.r + %s.g + %s.b) / 3.0", name, name, name);
414     else if (from == GPU_VEC2)
415       BLI_dynstr_appendf(ds, "%s.r", name);
416   }
417   else if (to == GPU_VEC2) {
418     if (from == GPU_VEC4)
419       BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, %s.a)", name, name, name, name);
420     else if (from == GPU_VEC3)
421       BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, 1.0)", name, name, name);
422     else if (from == GPU_FLOAT)
423       BLI_dynstr_appendf(ds, "vec2(%s, 1.0)", name);
424   }
425   else if (to == GPU_VEC3) {
426     if (from == GPU_VEC4)
427       BLI_dynstr_appendf(ds, "%s.rgb", name);
428     else if (from == GPU_VEC2)
429       BLI_dynstr_appendf(ds, "vec3(%s.r, %s.r, %s.r)", name, name, name);
430     else if (from == GPU_FLOAT)
431       BLI_dynstr_appendf(ds, "vec3(%s, %s, %s)", name, name, name);
432   }
433   else if (to == GPU_VEC4) {
434     if (from == GPU_VEC3)
435       BLI_dynstr_appendf(ds, "vec4(%s, 1.0)", name);
436     else if (from == GPU_VEC2)
437       BLI_dynstr_appendf(ds, "vec4(%s.r, %s.r, %s.r, %s.g)", name, name, name, name);
438     else if (from == GPU_FLOAT)
439       BLI_dynstr_appendf(ds, "vec4(%s, %s, %s, 1.0)", name, name, name);
440   }
441   else if (to == GPU_CLOSURE) {
442     if (from == GPU_VEC4)
443       BLI_dynstr_appendf(ds, "closure_emission(%s.rgb)", name);
444     else if (from == GPU_VEC3)
445       BLI_dynstr_appendf(ds, "closure_emission(%s.rgb)", name);
446     else if (from == GPU_VEC2)
447       BLI_dynstr_appendf(ds, "closure_emission(%s.rrr)", name);
448     else if (from == GPU_FLOAT)
449       BLI_dynstr_appendf(ds, "closure_emission(vec3(%s, %s, %s))", name, name, name);
450   }
451   else {
452     BLI_dynstr_append(ds, name);
453   }
454 }
455
456 static void codegen_print_datatype(DynStr *ds, const eGPUType type, float *data)
457 {
458   int i;
459
460   BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]);
461
462   for (i = 0; i < type; i++) {
463     BLI_dynstr_appendf(ds, "%.12f", data[i]);
464     if (i == type - 1)
465       BLI_dynstr_append(ds, ")");
466     else
467       BLI_dynstr_append(ds, ", ");
468   }
469 }
470
471 static int codegen_input_has_texture(GPUInput *input)
472 {
473   if (input->link)
474     return 0;
475   else
476     return (input->source == GPU_SOURCE_TEX);
477 }
478
479 const char *GPU_builtin_name(eGPUBuiltin builtin)
480 {
481   if (builtin == GPU_VIEW_MATRIX)
482     return "unfviewmat";
483   else if (builtin == GPU_OBJECT_MATRIX)
484     return "unfobmat";
485   else if (builtin == GPU_INVERSE_VIEW_MATRIX)
486     return "unfinvviewmat";
487   else if (builtin == GPU_INVERSE_OBJECT_MATRIX)
488     return "unfinvobmat";
489   else if (builtin == GPU_INVERSE_NORMAL_MATRIX)
490     return "unfinvnormat";
491   else if (builtin == GPU_LOC_TO_VIEW_MATRIX)
492     return "unflocaltoviewmat";
493   else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX)
494     return "unfinvlocaltoviewmat";
495   else if (builtin == GPU_VIEW_POSITION)
496     return "varposition";
497   else if (builtin == GPU_VIEW_NORMAL)
498     return "varnormal";
499   else if (builtin == GPU_OBCOLOR)
500     return "unfobcolor";
501   else if (builtin == GPU_AUTO_BUMPSCALE)
502     return "unfobautobumpscale";
503   else if (builtin == GPU_CAMERA_TEXCO_FACTORS)
504     return "unfcameratexfactors";
505   else if (builtin == GPU_PARTICLE_SCALAR_PROPS)
506     return "unfparticlescalarprops";
507   else if (builtin == GPU_PARTICLE_LOCATION)
508     return "unfparticleco";
509   else if (builtin == GPU_PARTICLE_VELOCITY)
510     return "unfparticlevel";
511   else if (builtin == GPU_PARTICLE_ANG_VELOCITY)
512     return "unfparticleangvel";
513   else if (builtin == GPU_OBJECT_INFO)
514     return "unfobjectinfo";
515   else if (builtin == GPU_VOLUME_DENSITY)
516     return "sampdensity";
517   else if (builtin == GPU_VOLUME_FLAME)
518     return "sampflame";
519   else if (builtin == GPU_VOLUME_TEMPERATURE)
520     return "unftemperature";
521   else if (builtin == GPU_BARYCENTRIC_TEXCO)
522     return "unfbarycentrictex";
523   else if (builtin == GPU_BARYCENTRIC_DIST)
524     return "unfbarycentricdist";
525   else
526     return "";
527 }
528
529 /* assign only one texid per buffer to avoid sampling the same texture twice */
530 static void codegen_set_texid(GHash *bindhash, GPUInput *input, int *texid, void *key)
531 {
532   if (BLI_ghash_haskey(bindhash, key)) {
533     /* Reuse existing texid */
534     input->texid = POINTER_AS_INT(BLI_ghash_lookup(bindhash, key));
535   }
536   else {
537     /* Allocate new texid */
538     input->texid = *texid;
539     (*texid)++;
540     input->bindtex = true;
541     BLI_ghash_insert(bindhash, key, POINTER_FROM_INT(input->texid));
542   }
543 }
544
545 static void codegen_set_unique_ids(ListBase *nodes)
546 {
547   GHash *bindhash;
548   GPUNode *node;
549   GPUInput *input;
550   GPUOutput *output;
551   int id = 1, texid = 0;
552
553   bindhash = BLI_ghash_ptr_new("codegen_set_unique_ids1 gh");
554
555   for (node = nodes->first; node; node = node->next) {
556     for (input = node->inputs.first; input; input = input->next) {
557       /* set id for unique names of uniform variables */
558       input->id = id++;
559
560       /* set texid used for settings texture slot */
561       if (codegen_input_has_texture(input)) {
562         input->bindtex = false;
563         if (input->ima) {
564           /* input is texture from image */
565           codegen_set_texid(bindhash, input, &texid, input->ima);
566         }
567         else if (input->coba) {
568           /* input is color band texture, check coba pointer */
569           codegen_set_texid(bindhash, input, &texid, input->coba);
570         }
571         else {
572           /* Either input->ima or input->coba should be non-NULL. */
573           BLI_assert(0);
574         }
575       }
576     }
577
578     for (output = node->outputs.first; output; output = output->next) {
579       /* set id for unique names of tmp variables storing output */
580       output->id = id++;
581     }
582   }
583
584   BLI_ghash_free(bindhash, NULL, NULL);
585 }
586
587 /**
588  * It will create an UBO for GPUMaterial if there is any GPU_DYNAMIC_UBO.
589  */
590 static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, ListBase *nodes)
591 {
592   GPUNode *node;
593   GPUInput *input;
594   const char *name;
595   int builtins = 0;
596   ListBase ubo_inputs = {NULL, NULL};
597
598   /* print uniforms */
599   for (node = nodes->first; node; node = node->next) {
600     for (input = node->inputs.first; input; input = input->next) {
601       if (input->source == GPU_SOURCE_TEX) {
602         /* create exactly one sampler for each texture */
603         if (codegen_input_has_texture(input) && input->bindtex) {
604           BLI_dynstr_appendf(ds,
605                              "uniform %s samp%d;\n",
606                              (input->coba) ? "sampler1DArray" : "sampler2D",
607                              input->texid);
608         }
609       }
610       else if (input->source == GPU_SOURCE_BUILTIN) {
611         /* only define each builtin uniform/varying once */
612         if (!(builtins & input->builtin)) {
613           builtins |= input->builtin;
614           name = GPU_builtin_name(input->builtin);
615
616           if (gpu_str_prefix(name, "samp")) {
617             if ((input->builtin == GPU_VOLUME_DENSITY) || (input->builtin == GPU_VOLUME_FLAME)) {
618               BLI_dynstr_appendf(ds, "uniform sampler3D %s;\n", name);
619             }
620           }
621           else if (gpu_str_prefix(name, "unf")) {
622             BLI_dynstr_appendf(ds, "uniform %s %s;\n", GPU_DATATYPE_STR[input->type], name);
623           }
624           else {
625             BLI_dynstr_appendf(ds, "in %s %s;\n", GPU_DATATYPE_STR[input->type], name);
626           }
627         }
628       }
629       else if (input->source == GPU_SOURCE_STRUCT) {
630         /* Add other struct here if needed. */
631         BLI_dynstr_appendf(ds, "Closure strct%d = CLOSURE_DEFAULT;\n", input->id);
632       }
633       else if (input->source == GPU_SOURCE_UNIFORM) {
634         if (!input->link) {
635           /* We handle the UBOuniforms separately. */
636           BLI_addtail(&ubo_inputs, BLI_genericNodeN(input));
637         }
638       }
639       else if (input->source == GPU_SOURCE_CONSTANT) {
640         BLI_dynstr_appendf(ds, "const %s cons%d = ", GPU_DATATYPE_STR[input->type], input->id);
641         codegen_print_datatype(ds, input->type, input->vec);
642         BLI_dynstr_append(ds, ";\n");
643       }
644       else if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
645         BLI_dynstr_appendf(ds, "in %s var%d;\n", GPU_DATATYPE_STR[input->type], input->attr_id);
646       }
647     }
648   }
649
650   /* Handle the UBO block separately. */
651   if ((material != NULL) && !BLI_listbase_is_empty(&ubo_inputs)) {
652     GPU_material_uniform_buffer_create(material, &ubo_inputs);
653
654     /* Inputs are sorted */
655     BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME);
656
657     for (LinkData *link = ubo_inputs.first; link; link = link->next) {
658       input = link->data;
659       BLI_dynstr_appendf(ds, "\t%s unf%d;\n", GPU_DATATYPE_STR[input->type], input->id);
660     }
661     BLI_dynstr_append(ds, "};\n");
662     BLI_freelistN(&ubo_inputs);
663   }
664
665   BLI_dynstr_append(ds, "\n");
666
667   return builtins;
668 }
669
670 static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
671 {
672   GPUNode *node;
673   GPUOutput *output;
674
675   for (node = nodes->first; node; node = node->next) {
676     /* declare temporary variables for node output storage */
677     for (output = node->outputs.first; output; output = output->next) {
678       if (output->type == GPU_CLOSURE) {
679         BLI_dynstr_appendf(ds, "\tClosure tmp%d;\n", output->id);
680       }
681       else {
682         BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", GPU_DATATYPE_STR[output->type], output->id);
683       }
684     }
685   }
686
687   BLI_dynstr_append(ds, "\n");
688 }
689
690 static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
691 {
692   GPUNode *node;
693   GPUInput *input;
694   GPUOutput *output;
695
696   for (node = nodes->first; node; node = node->next) {
697     BLI_dynstr_appendf(ds, "\t%s(", node->name);
698
699     for (input = node->inputs.first; input; input = input->next) {
700       if (input->source == GPU_SOURCE_TEX) {
701         BLI_dynstr_appendf(ds, "samp%d", input->texid);
702       }
703       else if (input->source == GPU_SOURCE_OUTPUT) {
704         codegen_convert_datatype(
705             ds, input->link->output->type, input->type, "tmp", input->link->output->id);
706       }
707       else if (input->source == GPU_SOURCE_BUILTIN) {
708         /* TODO(fclem) get rid of that. */
709         if (input->builtin == GPU_INVERSE_VIEW_MATRIX)
710           BLI_dynstr_append(ds, "viewinv");
711         else if (input->builtin == GPU_VIEW_MATRIX)
712           BLI_dynstr_append(ds, "viewmat");
713         else if (input->builtin == GPU_CAMERA_TEXCO_FACTORS)
714           BLI_dynstr_append(ds, "camtexfac");
715         else if (input->builtin == GPU_LOC_TO_VIEW_MATRIX)
716           BLI_dynstr_append(ds, "localtoviewmat");
717         else if (input->builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX)
718           BLI_dynstr_append(ds, "invlocaltoviewmat");
719         else if (input->builtin == GPU_BARYCENTRIC_DIST)
720           BLI_dynstr_append(ds, "barycentricDist");
721         else if (input->builtin == GPU_BARYCENTRIC_TEXCO)
722           BLI_dynstr_append(ds, "barytexco");
723         else if (input->builtin == GPU_OBJECT_MATRIX)
724           BLI_dynstr_append(ds, "objmat");
725         else if (input->builtin == GPU_INVERSE_OBJECT_MATRIX)
726           BLI_dynstr_append(ds, "objinv");
727         else if (input->builtin == GPU_INVERSE_NORMAL_MATRIX)
728           BLI_dynstr_append(ds, "norinv");
729         else if (input->builtin == GPU_VIEW_POSITION)
730           BLI_dynstr_append(ds, "viewposition");
731         else if (input->builtin == GPU_VIEW_NORMAL)
732           BLI_dynstr_append(ds, "facingnormal");
733         else
734           BLI_dynstr_append(ds, GPU_builtin_name(input->builtin));
735       }
736       else if (input->source == GPU_SOURCE_STRUCT) {
737         BLI_dynstr_appendf(ds, "strct%d", input->id);
738       }
739       else if (input->source == GPU_SOURCE_UNIFORM) {
740         BLI_dynstr_appendf(ds, "unf%d", input->id);
741       }
742       else if (input->source == GPU_SOURCE_CONSTANT) {
743         BLI_dynstr_appendf(ds, "cons%d", input->id);
744       }
745       else if (input->source == GPU_SOURCE_ATTR) {
746         BLI_dynstr_appendf(ds, "var%d", input->attr_id);
747       }
748
749       BLI_dynstr_append(ds, ", ");
750     }
751
752     for (output = node->outputs.first; output; output = output->next) {
753       BLI_dynstr_appendf(ds, "tmp%d", output->id);
754       if (output->next)
755         BLI_dynstr_append(ds, ", ");
756     }
757
758     BLI_dynstr_append(ds, ");\n");
759   }
760
761   BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id);
762   BLI_dynstr_append(ds, ";\n");
763 }
764
765 static char *code_generate_fragment(GPUMaterial *material,
766                                     ListBase *nodes,
767                                     GPUOutput *output,
768                                     int *rbuiltins)
769 {
770   DynStr *ds = BLI_dynstr_new();
771   char *code;
772   int builtins;
773
774 #if 0
775   BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
776 #endif
777
778   codegen_set_unique_ids(nodes);
779   *rbuiltins = builtins = codegen_process_uniforms_functions(material, ds, nodes);
780
781   if (builtins & GPU_BARYCENTRIC_TEXCO)
782     BLI_dynstr_append(ds, "in vec2 barycentricTexCo;\n");
783
784   if (builtins & GPU_BARYCENTRIC_DIST)
785     BLI_dynstr_append(ds, "flat in vec3 barycentricDist;\n");
786
787   BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n");
788
789   if (builtins & GPU_BARYCENTRIC_TEXCO) {
790     BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
791     BLI_dynstr_append(ds,
792                       "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n"
793                       "\t                      ? barycentricTexCo.x\n"
794                       "\t                      : 1.0 - barycentricTexCo.x,\n"
795                       "\t                      0.0);\n");
796     BLI_dynstr_append(ds, "#else\n");
797     BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n");
798     BLI_dynstr_append(ds, "#endif\n");
799   }
800   /* TODO(fclem) get rid of that. */
801   if (builtins & GPU_VIEW_MATRIX)
802     BLI_dynstr_append(ds, "\t#define viewmat ViewMatrix\n");
803   if (builtins & GPU_CAMERA_TEXCO_FACTORS)
804     BLI_dynstr_append(ds, "\t#define camtexfac CameraTexCoFactors\n");
805   if (builtins & GPU_OBJECT_MATRIX)
806     BLI_dynstr_append(ds, "\t#define objmat ModelMatrix\n");
807   if (builtins & GPU_INVERSE_OBJECT_MATRIX)
808     BLI_dynstr_append(ds, "\t#define objinv ModelMatrixInverse\n");
809   if (builtins & GPU_INVERSE_NORMAL_MATRIX)
810     BLI_dynstr_append(ds, "\t#define norinv NormalMatrixInverse\n");
811   if (builtins & GPU_INVERSE_VIEW_MATRIX)
812     BLI_dynstr_append(ds, "\t#define viewinv ViewMatrixInverse\n");
813   if (builtins & GPU_LOC_TO_VIEW_MATRIX)
814     BLI_dynstr_append(ds, "\t#define localtoviewmat ModelViewMatrix\n");
815   if (builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX)
816     BLI_dynstr_append(ds, "\t#define invlocaltoviewmat ModelViewMatrixInverse\n");
817   if (builtins & GPU_VIEW_NORMAL)
818     BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? viewNormal: -viewNormal;\n");
819   if (builtins & GPU_VIEW_POSITION)
820     BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
821
822   codegen_declare_tmps(ds, nodes);
823   codegen_call_functions(ds, nodes, output);
824
825   BLI_dynstr_append(ds, "}\n");
826
827   /* XXX This cannot go into gpu_shader_material.glsl because main() would be parsed and generate error */
828   /* Old glsl mode compat. */
829   BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n");
830   BLI_dynstr_append(ds, "out vec4 fragColor;\n");
831   BLI_dynstr_append(ds, "void main()\n");
832   BLI_dynstr_append(ds, "{\n");
833   BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n");
834   BLI_dynstr_append(ds, "\tfragColor = vec4(cl.radiance, cl.opacity);\n");
835   BLI_dynstr_append(ds, "}\n");
836   BLI_dynstr_append(ds, "#endif\n\n");
837
838   /* create shader */
839   code = BLI_dynstr_get_cstring(ds);
840   BLI_dynstr_free(ds);
841
842 #if 0
843   if (G.debug & G_DEBUG) printf("%s\n", code);
844 #endif
845
846   return code;
847 }
848
849 static const char *attr_prefix_get(CustomDataType type)
850 {
851   switch (type) {
852     case CD_ORCO:
853       return "orco";
854     case CD_MTFACE:
855       return "u";
856     case CD_TANGENT:
857       return "t";
858     case CD_MCOL:
859       return "c";
860     case CD_AUTO_FROM_NAME:
861       return "a";
862     default:
863       BLI_assert(false && "GPUVertAttr Prefix type not found : This should not happen!");
864       return "";
865   }
866 }
867
868 static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool use_geom)
869 {
870   DynStr *ds = BLI_dynstr_new();
871   GPUNode *node;
872   GPUInput *input;
873   char *code;
874   int builtins = 0;
875
876   /* Hairs uv and col attributes are passed by bufferTextures. */
877   BLI_dynstr_append(ds,
878                     "#ifdef HAIR_SHADER\n"
879                     "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n"
880                     "#else\n"
881                     "#define DEFINE_ATTR(type, attr) in type attr\n"
882                     "#endif\n");
883
884   for (node = nodes->first; node; node = node->next) {
885     for (input = node->inputs.first; input; input = input->next) {
886       if (input->source == GPU_SOURCE_BUILTIN) {
887         builtins |= input->builtin;
888       }
889       if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
890         /* XXX FIXME : see notes in mesh_render_data_create() */
891         /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
892         if (input->attr_type == CD_ORCO) {
893           /* OPTI : orco is computed from local positions, but only if no modifier is present. */
894           BLI_dynstr_append(ds, "uniform vec3 OrcoTexCoFactors[2];\n");
895           BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
896         }
897         else if (input->attr_name[0] == '\0') {
898           BLI_dynstr_appendf(ds,
899                              "DEFINE_ATTR(%s, %s);\n",
900                              GPU_DATATYPE_STR[input->type],
901                              attr_prefix_get(input->attr_type));
902           BLI_dynstr_appendf(
903               ds, "#define att%d %s\n", input->attr_id, attr_prefix_get(input->attr_type));
904         }
905         else {
906           uint hash = BLI_ghashutil_strhash_p(input->attr_name);
907           BLI_dynstr_appendf(ds,
908                              "DEFINE_ATTR(%s, %s%u);\n",
909                              GPU_DATATYPE_STR[input->type],
910                              attr_prefix_get(input->attr_type),
911                              hash);
912           BLI_dynstr_appendf(
913               ds, "#define att%d %s%u\n", input->attr_id, attr_prefix_get(input->attr_type), hash);
914           /* Auto attribute can be vertex color byte buffer.
915            * We need to know and convert them to linear space in VS. */
916           if (input->attr_type == CD_AUTO_FROM_NAME) {
917             BLI_dynstr_appendf(ds, "uniform bool ba%u;\n", hash);
918             BLI_dynstr_appendf(ds, "#define att%d_is_srgb ba%u\n", input->attr_id, hash);
919           }
920         }
921         BLI_dynstr_appendf(ds,
922                            "out %s var%d%s;\n",
923                            GPU_DATATYPE_STR[input->type],
924                            input->attr_id,
925                            use_geom ? "g" : "");
926       }
927     }
928   }
929
930   if (builtins & GPU_BARYCENTRIC_TEXCO) {
931     BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
932     BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo%s;\n", use_geom ? "g" : "");
933     BLI_dynstr_append(ds, "#endif\n");
934   }
935
936   if (builtins & GPU_BARYCENTRIC_DIST) {
937     BLI_dynstr_append(ds, "out vec3 barycentricPosg;\n");
938   }
939
940   BLI_dynstr_append(ds, "\n");
941
942   BLI_dynstr_append(ds,
943                     "#define USE_ATTR\n"
944                     "uniform mat3 NormalMatrix;\n"
945                     "uniform mat4 ModelMatrixInverse;\n"
946                     "uniform mat4 ModelMatrix;\n"
947                     "vec3 srgb_to_linear_attr(vec3 c) {\n"
948                     "\tc = max(c, vec3(0.0));\n"
949                     "\tvec3 c1 = c * (1.0 / 12.92);\n"
950                     "\tvec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));\n"
951                     "\treturn mix(c1, c2, step(vec3(0.04045), c));\n"
952                     "}\n\n");
953
954   /* Prototype because defined later. */
955   BLI_dynstr_append(ds,
956                     "vec2 hair_get_customdata_vec2(const samplerBuffer);\n"
957                     "vec3 hair_get_customdata_vec3(const samplerBuffer);\n"
958                     "vec4 hair_get_customdata_vec4(const samplerBuffer);\n"
959                     "vec3 hair_get_strand_pos(void);\n"
960                     "int hair_get_base_id(void);\n"
961                     "\n");
962
963   BLI_dynstr_append(ds, "void pass_attr(in vec3 position) {\n");
964
965   BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
966
967   if (builtins & GPU_BARYCENTRIC_TEXCO) {
968     /* To match cycles without breaking into individual segment we encode if we need to invert
969      * the first component into the second component. We invert if the barycentricTexCo.y
970      * is NOT 0.0 or 1.0. */
971     BLI_dynstr_append(ds, "\tint _base_id = hair_get_base_id();\n");
972     BLI_dynstr_appendf(
973         ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n", use_geom ? "g" : "");
974     BLI_dynstr_appendf(
975         ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : "");
976   }
977
978   if (builtins & GPU_BARYCENTRIC_DIST) {
979     BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n");
980   }
981
982   for (node = nodes->first; node; node = node->next) {
983     for (input = node->inputs.first; input; input = input->next) {
984       if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
985         if (input->attr_type == CD_TANGENT) {
986           /* Not supported by hairs */
987           BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", input->attr_id, use_geom ? "g" : "");
988         }
989         else if (input->attr_type == CD_ORCO) {
990           BLI_dynstr_appendf(ds,
991                              "\tvar%d%s = OrcoTexCoFactors[0] + (ModelMatrixInverse * "
992                              "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1];\n",
993                              input->attr_id,
994                              use_geom ? "g" : "");
995           /* TODO: fix ORCO with modifiers. */
996         }
997         else {
998           BLI_dynstr_appendf(ds,
999                              "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
1000                              input->attr_id,
1001                              use_geom ? "g" : "",
1002                              GPU_DATATYPE_STR[input->type],
1003                              input->attr_id);
1004         }
1005       }
1006     }
1007   }
1008
1009   BLI_dynstr_append(ds, "#else /* MESH_SHADER */\n");
1010
1011   /* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID
1012    * for MESH_SHADER because of indexed drawing. In this case a
1013    * geometry shader is needed. */
1014
1015   if (builtins & GPU_BARYCENTRIC_DIST) {
1016     BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n");
1017   }
1018
1019   for (node = nodes->first; node; node = node->next) {
1020     for (input = node->inputs.first; input; input = input->next) {
1021       if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
1022         if (input->attr_type == CD_TANGENT) { /* silly exception */
1023           BLI_dynstr_appendf(ds,
1024                              "\tvar%d%s.xyz = NormalMatrix * att%d.xyz;\n",
1025                              input->attr_id,
1026                              use_geom ? "g" : "",
1027                              input->attr_id);
1028           BLI_dynstr_appendf(
1029               ds, "\tvar%d%s.w = att%d.w;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
1030           /* Normalize only if vector is not null. */
1031           BLI_dynstr_appendf(ds,
1032                              "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
1033                              input->attr_id,
1034                              input->attr_id,
1035                              use_geom ? "g" : "",
1036                              input->attr_id,
1037                              use_geom ? "g" : "");
1038           BLI_dynstr_appendf(ds,
1039                              "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
1040                              input->attr_id,
1041                              use_geom ? "g" : "",
1042                              input->attr_id,
1043                              input->attr_id);
1044         }
1045         else if (input->attr_type == CD_ORCO) {
1046           BLI_dynstr_appendf(ds,
1047                              "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
1048                              input->attr_id,
1049                              use_geom ? "g" : "");
1050           /* See mesh_create_loop_orco() for explanation. */
1051           BLI_dynstr_appendf(ds,
1052                              "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
1053                              input->attr_id,
1054                              use_geom ? "g" : "");
1055         }
1056         else if (input->attr_type == CD_MCOL) {
1057           BLI_dynstr_appendf(ds,
1058                              "\tvar%d%s = srgb_to_linear_attr(att%d);\n",
1059                              input->attr_id,
1060                              use_geom ? "g" : "",
1061                              input->attr_id);
1062         }
1063         else if (input->attr_type == CD_AUTO_FROM_NAME) {
1064           BLI_dynstr_appendf(ds,
1065                              "\tvar%d%s = (att%d_is_srgb) ? srgb_to_linear_attr(att%d) : att%d;\n",
1066                              input->attr_id,
1067                              use_geom ? "g" : "",
1068                              input->attr_id,
1069                              input->attr_id,
1070                              input->attr_id);
1071         }
1072         else {
1073           BLI_dynstr_appendf(
1074               ds, "\tvar%d%s = att%d;\n", input->attr_id, use_geom ? "g" : "", input->attr_id);
1075         }
1076       }
1077     }
1078   }
1079   BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n");
1080
1081   BLI_dynstr_append(ds, "}\n");
1082
1083   if (use_geom) {
1084     /* XXX HACK: Eevee specific. */
1085     char *vert_new, *vert_new2;
1086     vert_new = BLI_str_replaceN(vert_code, "worldPosition", "worldPositiong");
1087     vert_new2 = vert_new;
1088     vert_new = BLI_str_replaceN(vert_new2, "viewPosition", "viewPositiong");
1089     MEM_freeN(vert_new2);
1090     vert_new2 = vert_new;
1091     vert_new = BLI_str_replaceN(vert_new2, "worldNormal", "worldNormalg");
1092     MEM_freeN(vert_new2);
1093     vert_new2 = vert_new;
1094     vert_new = BLI_str_replaceN(vert_new2, "viewNormal", "viewNormalg");
1095     MEM_freeN(vert_new2);
1096
1097     BLI_dynstr_append(ds, vert_new);
1098
1099     MEM_freeN(vert_new);
1100   }
1101   else {
1102     BLI_dynstr_append(ds, vert_code);
1103   }
1104
1105   code = BLI_dynstr_get_cstring(ds);
1106
1107   BLI_dynstr_free(ds);
1108
1109 #if 0
1110   if (G.debug & G_DEBUG) printf("%s\n", code);
1111 #endif
1112
1113   return code;
1114 }
1115
1116 static char *code_generate_geometry(ListBase *nodes, const char *geom_code, const char *defines)
1117 {
1118   DynStr *ds = BLI_dynstr_new();
1119   GPUNode *node;
1120   GPUInput *input;
1121   char *code;
1122   int builtins = 0;
1123
1124   /* XXX we should not make specific eevee cases here. */
1125   bool is_hair_shader = (strstr(defines, "HAIR_SHADER") != NULL);
1126
1127   /* Create prototype because attributes cannot be declared before layout. */
1128   BLI_dynstr_append(ds, "void pass_attr(in int vert);\n");
1129   BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2);\n");
1130   BLI_dynstr_append(ds, "#define USE_ATTR\n");
1131
1132   /* Generate varying declarations. */
1133   for (node = nodes->first; node; node = node->next) {
1134     for (input = node->inputs.first; input; input = input->next) {
1135       if (input->source == GPU_SOURCE_BUILTIN) {
1136         builtins |= input->builtin;
1137       }
1138       if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
1139         BLI_dynstr_appendf(ds, "in %s var%dg[];\n", GPU_DATATYPE_STR[input->type], input->attr_id);
1140         BLI_dynstr_appendf(ds, "out %s var%d;\n", GPU_DATATYPE_STR[input->type], input->attr_id);
1141       }
1142     }
1143   }
1144
1145   if (builtins & GPU_BARYCENTRIC_TEXCO) {
1146     BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
1147     BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n");
1148     BLI_dynstr_append(ds, "#endif\n");
1149
1150     BLI_dynstr_append(ds, "out vec2 barycentricTexCo;\n");
1151   }
1152
1153   if (builtins & GPU_BARYCENTRIC_DIST) {
1154     BLI_dynstr_append(ds, "in vec3 barycentricPosg[];\n");
1155     BLI_dynstr_append(ds, "flat out vec3 barycentricDist;\n");
1156   }
1157
1158   if (geom_code == NULL) {
1159     /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used.
1160      * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */
1161     if ((builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0 || is_hair_shader) {
1162       /* Early out */
1163       BLI_dynstr_free(ds);
1164       return NULL;
1165     }
1166     else {
1167       /* Force geom shader usage */
1168       /* TODO put in external file. */
1169       BLI_dynstr_append(ds, "layout(triangles) in;\n");
1170       BLI_dynstr_append(ds, "layout(triangle_strip, max_vertices=3) out;\n");
1171
1172       BLI_dynstr_append(ds, "in vec3 worldPositiong[];\n");
1173       BLI_dynstr_append(ds, "in vec3 viewPositiong[];\n");
1174       BLI_dynstr_append(ds, "in vec3 worldNormalg[];\n");
1175       BLI_dynstr_append(ds, "in vec3 viewNormalg[];\n");
1176
1177       BLI_dynstr_append(ds, "out vec3 worldPosition;\n");
1178       BLI_dynstr_append(ds, "out vec3 viewPosition;\n");
1179       BLI_dynstr_append(ds, "out vec3 worldNormal;\n");
1180       BLI_dynstr_append(ds, "out vec3 viewNormal;\n");
1181
1182       BLI_dynstr_append(ds, "void main(){\n");
1183
1184       if (builtins & GPU_BARYCENTRIC_DIST) {
1185         BLI_dynstr_append(ds,
1186                           "\tcalc_barycentric_distances(barycentricPosg[0], barycentricPosg[1], "
1187                           "barycentricPosg[2]);\n");
1188       }
1189
1190       BLI_dynstr_append(ds, "\tgl_Position = gl_in[0].gl_Position;\n");
1191       BLI_dynstr_append(ds, "\tpass_attr(0);\n");
1192       BLI_dynstr_append(ds, "\tEmitVertex();\n");
1193
1194       BLI_dynstr_append(ds, "\tgl_Position = gl_in[1].gl_Position;\n");
1195       BLI_dynstr_append(ds, "\tpass_attr(1);\n");
1196       BLI_dynstr_append(ds, "\tEmitVertex();\n");
1197
1198       BLI_dynstr_append(ds, "\tgl_Position = gl_in[2].gl_Position;\n");
1199       BLI_dynstr_append(ds, "\tpass_attr(2);\n");
1200       BLI_dynstr_append(ds, "\tEmitVertex();\n");
1201       BLI_dynstr_append(ds, "};\n");
1202     }
1203   }
1204   else {
1205     BLI_dynstr_append(ds, geom_code);
1206   }
1207
1208   if (builtins & GPU_BARYCENTRIC_DIST) {
1209     BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2) {\n");
1210     BLI_dynstr_append(ds, "\tvec3 edge21 = pos2 - pos1;\n");
1211     BLI_dynstr_append(ds, "\tvec3 edge10 = pos1 - pos0;\n");
1212     BLI_dynstr_append(ds, "\tvec3 edge02 = pos0 - pos2;\n");
1213     BLI_dynstr_append(ds, "\tvec3 d21 = normalize(edge21);\n");
1214     BLI_dynstr_append(ds, "\tvec3 d10 = normalize(edge10);\n");
1215     BLI_dynstr_append(ds, "\tvec3 d02 = normalize(edge02);\n");
1216
1217     BLI_dynstr_append(ds, "\tfloat d = dot(d21, edge02);\n");
1218     BLI_dynstr_append(ds, "\tbarycentricDist.x = sqrt(dot(edge02, edge02) - d * d);\n");
1219     BLI_dynstr_append(ds, "\td = dot(d02, edge10);\n");
1220     BLI_dynstr_append(ds, "\tbarycentricDist.y = sqrt(dot(edge10, edge10) - d * d);\n");
1221     BLI_dynstr_append(ds, "\td = dot(d10, edge21);\n");
1222     BLI_dynstr_append(ds, "\tbarycentricDist.z = sqrt(dot(edge21, edge21) - d * d);\n");
1223     BLI_dynstr_append(ds, "}\n");
1224   }
1225
1226   /* Generate varying assignments. */
1227   BLI_dynstr_append(ds, "void pass_attr(in int vert) {\n");
1228
1229   /* XXX HACK: Eevee specific. */
1230   if (geom_code == NULL) {
1231     BLI_dynstr_append(ds, "\tworldPosition = worldPositiong[vert];\n");
1232     BLI_dynstr_append(ds, "\tviewPosition = viewPositiong[vert];\n");
1233     BLI_dynstr_append(ds, "\tworldNormal = worldNormalg[vert];\n");
1234     BLI_dynstr_append(ds, "\tviewNormal = viewNormalg[vert];\n");
1235   }
1236
1237   if (builtins & GPU_BARYCENTRIC_TEXCO) {
1238     BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
1239     BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n");
1240     BLI_dynstr_append(ds, "#else\n");
1241     BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n");
1242     BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n");
1243     BLI_dynstr_append(ds, "#endif\n");
1244   }
1245
1246   for (node = nodes->first; node; node = node->next) {
1247     for (input = node->inputs.first; input; input = input->next) {
1248       if (input->source == GPU_SOURCE_ATTR && input->attr_first) {
1249         /* TODO let shader choose what to do depending on what the attribute is. */
1250         BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", input->attr_id, input->attr_id);
1251       }
1252     }
1253   }
1254   BLI_dynstr_append(ds, "}\n");
1255
1256   code = BLI_dynstr_get_cstring(ds);
1257   BLI_dynstr_free(ds);
1258
1259   return code;
1260 }
1261
1262 void GPU_code_generate_glsl_lib(void)
1263 {
1264   DynStr *ds;
1265
1266   /* only initialize the library once */
1267   if (glsl_material_library)
1268     return;
1269
1270   ds = BLI_dynstr_new();
1271
1272   BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
1273
1274   glsl_material_library = BLI_dynstr_get_cstring(ds);
1275
1276   BLI_dynstr_free(ds);
1277 }
1278
1279 /* GPU pass binding/unbinding */
1280
1281 GPUShader *GPU_pass_shader_get(GPUPass *pass)
1282 {
1283   return pass->shader;
1284 }
1285
1286 void GPU_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs, ListBase *nodes)
1287 {
1288   GPUNode *node;
1289   GPUInput *next, *input;
1290
1291   BLI_listbase_clear(inputs);
1292
1293   if (!shader)
1294     return;
1295
1296   for (node = nodes->first; node; node = node->next) {
1297     int z = 0;
1298     for (input = node->inputs.first; input; input = next, z++) {
1299       next = input->next;
1300
1301       /* attributes don't need to be bound, they already have
1302        * an id that the drawing functions will use. Builtins have
1303        * constant names. */
1304       if (ELEM(input->source, GPU_SOURCE_ATTR, GPU_SOURCE_BUILTIN)) {
1305         continue;
1306       }
1307
1308       if (input->source == GPU_SOURCE_TEX)
1309         BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
1310       else {
1311         BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
1312       }
1313
1314       if (input->source == GPU_SOURCE_TEX) {
1315         if (input->bindtex) {
1316           input->shaderloc = GPU_shader_get_uniform_ensure(shader, input->shadername);
1317           /* extract nodes */
1318           BLI_remlink(&node->inputs, input);
1319           BLI_addtail(inputs, input);
1320         }
1321       }
1322     }
1323   }
1324 }
1325
1326 /* Node Link Functions */
1327
1328 static GPUNodeLink *GPU_node_link_create(void)
1329 {
1330   GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
1331   link->users++;
1332
1333   return link;
1334 }
1335
1336 static void gpu_node_link_free(GPUNodeLink *link)
1337 {
1338   link->users--;
1339
1340   if (link->users < 0)
1341     fprintf(stderr, "GPU_node_link_free: negative refcount\n");
1342
1343   if (link->users == 0) {
1344     if (link->output)
1345       link->output->link = NULL;
1346     MEM_freeN(link);
1347   }
1348 }
1349
1350 /* Node Functions */
1351
1352 static GPUNode *GPU_node_begin(const char *name)
1353 {
1354   GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
1355
1356   node->name = name;
1357
1358   return node;
1359 }
1360
1361 static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType type)
1362 {
1363   GPUInput *input;
1364   GPUNode *outnode;
1365   const char *name;
1366
1367   if (link->link_type == GPU_NODE_LINK_OUTPUT) {
1368     outnode = link->output->node;
1369     name = outnode->name;
1370     input = outnode->inputs.first;
1371
1372     if ((STR_ELEM(name, "set_value", "set_rgb", "set_rgba")) && (input->type == type)) {
1373       input = MEM_dupallocN(outnode->inputs.first);
1374       if (input->link)
1375         input->link->users++;
1376       BLI_addtail(&node->inputs, input);
1377       return;
1378     }
1379   }
1380
1381   input = MEM_callocN(sizeof(GPUInput), "GPUInput");
1382   input->node = node;
1383   input->type = type;
1384
1385   switch (link->link_type) {
1386     case GPU_NODE_LINK_BUILTIN:
1387       input->source = GPU_SOURCE_BUILTIN;
1388       input->builtin = link->builtin;
1389       break;
1390     case GPU_NODE_LINK_OUTPUT:
1391       input->source = GPU_SOURCE_OUTPUT;
1392       input->link = link;
1393       link->users++;
1394       break;
1395     case GPU_NODE_LINK_COLORBAND:
1396       input->source = GPU_SOURCE_TEX;
1397       input->coba = link->coba;
1398       break;
1399     case GPU_NODE_LINK_IMAGE_BLENDER:
1400       input->source = GPU_SOURCE_TEX;
1401       input->ima = link->ima;
1402       input->iuser = link->iuser;
1403       input->image_isdata = link->image_isdata;
1404       break;
1405     case GPU_NODE_LINK_ATTR:
1406       input->source = GPU_SOURCE_ATTR;
1407       input->attr_type = link->attr_type;
1408       BLI_strncpy(input->attr_name, link->attr_name, sizeof(input->attr_name));
1409       break;
1410     case GPU_NODE_LINK_CONSTANT:
1411       input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT;
1412       break;
1413     case GPU_NODE_LINK_UNIFORM:
1414       input->source = GPU_SOURCE_UNIFORM;
1415       break;
1416     default:
1417       break;
1418   }
1419
1420   if (ELEM(input->source, GPU_SOURCE_CONSTANT, GPU_SOURCE_UNIFORM)) {
1421     memcpy(input->vec, link->data, type * sizeof(float));
1422   }
1423
1424   if (link->link_type != GPU_NODE_LINK_OUTPUT) {
1425     MEM_freeN(link);
1426   }
1427   BLI_addtail(&node->inputs, input);
1428 }
1429
1430 static const char *gpu_uniform_set_function_from_type(eNodeSocketDatatype type)
1431 {
1432   switch (type) {
1433     /* For now INT is supported as float. */
1434     case SOCK_INT:
1435     case SOCK_FLOAT:
1436       return "set_value";
1437     case SOCK_VECTOR:
1438       return "set_rgb";
1439     case SOCK_RGBA:
1440       return "set_rgba";
1441     default:
1442       BLI_assert(!"No gpu function for non-supported eNodeSocketDatatype");
1443       return NULL;
1444   }
1445 }
1446
1447 /**
1448  * Link stack uniform buffer.
1449  * This is called for the input/output sockets that are note connected.
1450  */
1451 static GPUNodeLink *gpu_uniformbuffer_link(GPUMaterial *mat,
1452                                            bNode *node,
1453                                            GPUNodeStack *stack,
1454                                            const int index,
1455                                            const eNodeSocketInOut in_out)
1456 {
1457   bNodeSocket *socket;
1458
1459   if (in_out == SOCK_IN) {
1460     socket = BLI_findlink(&node->inputs, index);
1461   }
1462   else {
1463     socket = BLI_findlink(&node->outputs, index);
1464   }
1465
1466   BLI_assert(socket != NULL);
1467   BLI_assert(socket->in_out == in_out);
1468
1469   if ((socket->flag & SOCK_HIDE_VALUE) == 0) {
1470     GPUNodeLink *link;
1471     switch (socket->type) {
1472       case SOCK_FLOAT: {
1473         bNodeSocketValueFloat *socket_data = socket->default_value;
1474         link = GPU_uniform(&socket_data->value);
1475         break;
1476       }
1477       case SOCK_VECTOR: {
1478         bNodeSocketValueVector *socket_data = socket->default_value;
1479         link = GPU_uniform(socket_data->value);
1480         break;
1481       }
1482       case SOCK_RGBA: {
1483         bNodeSocketValueRGBA *socket_data = socket->default_value;
1484         link = GPU_uniform(socket_data->value);
1485         break;
1486       }
1487       default:
1488         return NULL;
1489         break;
1490     }
1491
1492     if (in_out == SOCK_IN) {
1493       GPU_link(mat, gpu_uniform_set_function_from_type(socket->type), link, &stack->link);
1494     }
1495     return link;
1496   }
1497   return NULL;
1498 }
1499
1500 static void gpu_node_input_socket(
1501     GPUMaterial *material, bNode *bnode, GPUNode *node, GPUNodeStack *sock, const int index)
1502 {
1503   if (sock->link) {
1504     gpu_node_input_link(node, sock->link, sock->type);
1505   }
1506   else if ((material != NULL) &&
1507            (gpu_uniformbuffer_link(material, bnode, sock, index, SOCK_IN) != NULL)) {
1508     gpu_node_input_link(node, sock->link, sock->type);
1509   }
1510   else {
1511     gpu_node_input_link(node, GPU_constant(sock->vec), sock->type);
1512   }
1513 }
1514
1515 static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **link)
1516 {
1517   GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
1518
1519   output->type = type;
1520   output->node = node;
1521
1522   if (link) {
1523     *link = output->link = GPU_node_link_create();
1524     output->link->link_type = GPU_NODE_LINK_OUTPUT;
1525     output->link->output = output;
1526
1527     /* note: the caller owns the reference to the link, GPUOutput
1528      * merely points to it, and if the node is destroyed it will
1529      * set that pointer to NULL */
1530   }
1531
1532   BLI_addtail(&node->outputs, output);
1533 }
1534
1535 void GPU_inputs_free(ListBase *inputs)
1536 {
1537   GPUInput *input;
1538
1539   for (input = inputs->first; input; input = input->next) {
1540     if (input->link)
1541       gpu_node_link_free(input->link);
1542   }
1543
1544   BLI_freelistN(inputs);
1545 }
1546
1547 static void gpu_node_free(GPUNode *node)
1548 {
1549   GPUOutput *output;
1550
1551   GPU_inputs_free(&node->inputs);
1552
1553   for (output = node->outputs.first; output; output = output->next)
1554     if (output->link) {
1555       output->link->output = NULL;
1556       gpu_node_link_free(output->link);
1557     }
1558
1559   BLI_freelistN(&node->outputs);
1560   MEM_freeN(node);
1561 }
1562
1563 static void gpu_nodes_free(ListBase *nodes)
1564 {
1565   GPUNode *node;
1566
1567   while ((node = BLI_pophead(nodes))) {
1568     gpu_node_free(node);
1569   }
1570 }
1571
1572 /* vertex attributes */
1573
1574 void GPU_nodes_get_vertex_attrs(ListBase *nodes, GPUVertAttrLayers *attrs)
1575 {
1576   GPUNode *node;
1577   GPUInput *input;
1578   int a;
1579
1580   /* convert attributes requested by node inputs to an array of layers,
1581    * checking for duplicates and assigning id's starting from zero. */
1582
1583   memset(attrs, 0, sizeof(*attrs));
1584
1585   for (node = nodes->first; node; node = node->next) {
1586     for (input = node->inputs.first; input; input = input->next) {
1587       if (input->source == GPU_SOURCE_ATTR) {
1588         for (a = 0; a < attrs->totlayer; a++) {
1589           if (attrs->layer[a].type == input->attr_type &&
1590               STREQ(attrs->layer[a].name, input->attr_name)) {
1591             break;
1592           }
1593         }
1594
1595         if (a < GPU_MAX_ATTR) {
1596           if (a == attrs->totlayer) {
1597             input->attr_id = attrs->totlayer++;
1598             input->attr_first = true;
1599
1600             attrs->layer[a].type = input->attr_type;
1601             attrs->layer[a].attr_id = input->attr_id;
1602             BLI_strncpy(attrs->layer[a].name, input->attr_name, sizeof(attrs->layer[a].name));
1603           }
1604           else {
1605             input->attr_id = attrs->layer[a].attr_id;
1606           }
1607         }
1608       }
1609     }
1610   }
1611 }
1612
1613 /* varargs linking  */
1614
1615 GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
1616 {
1617   GPUNodeLink *link = GPU_node_link_create();
1618   link->link_type = GPU_NODE_LINK_ATTR;
1619   link->attr_name = name;
1620   /* Fall back to the UV layer, which matches old behavior. */
1621   if (type == CD_AUTO_FROM_NAME && name[0] == '\0') {
1622     link->attr_type = CD_MTFACE;
1623   }
1624   else {
1625     link->attr_type = type;
1626   }
1627   return link;
1628 }
1629
1630 GPUNodeLink *GPU_constant(float *num)
1631 {
1632   GPUNodeLink *link = GPU_node_link_create();
1633   link->link_type = GPU_NODE_LINK_CONSTANT;
1634   link->data = num;
1635   return link;
1636 }
1637
1638 GPUNodeLink *GPU_uniform(float *num)
1639 {
1640   GPUNodeLink *link = GPU_node_link_create();
1641   link->link_type = GPU_NODE_LINK_UNIFORM;
1642   link->data = num;
1643   return link;
1644 }
1645
1646 GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
1647 {
1648   GPUNodeLink *link = GPU_node_link_create();
1649   link->link_type = GPU_NODE_LINK_IMAGE_BLENDER;
1650   link->ima = ima;
1651   link->iuser = iuser;
1652   link->image_isdata = is_data;
1653   return link;
1654 }
1655
1656 GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row)
1657 {
1658   GPUNodeLink *link = GPU_node_link_create();
1659   link->link_type = GPU_NODE_LINK_COLORBAND;
1660   link->coba = gpu_material_ramp_texture_row_set(mat, size, pixels, row);
1661   MEM_freeN(pixels);
1662   return link;
1663 }
1664
1665 GPUNodeLink *GPU_builtin(eGPUBuiltin builtin)
1666 {
1667   GPUNodeLink *link = GPU_node_link_create();
1668   link->link_type = GPU_NODE_LINK_BUILTIN;
1669   link->builtin = builtin;
1670   return link;
1671 }
1672
1673 bool GPU_link(GPUMaterial *mat, const char *name, ...)
1674 {
1675   GPUNode *node;
1676   GPUFunction *function;
1677   GPUNodeLink *link, **linkptr;
1678   va_list params;
1679   int i;
1680
1681   function = gpu_lookup_function(name);
1682   if (!function) {
1683     fprintf(stderr, "GPU failed to find function %s\n", name);
1684     return false;
1685   }
1686
1687   node = GPU_node_begin(name);
1688
1689   va_start(params, name);
1690   for (i = 0; i < function->totparam; i++) {
1691     if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1692       linkptr = va_arg(params, GPUNodeLink **);
1693       gpu_node_output(node, function->paramtype[i], linkptr);
1694     }
1695     else {
1696       link = va_arg(params, GPUNodeLink *);
1697       gpu_node_input_link(node, link, function->paramtype[i]);
1698     }
1699   }
1700   va_end(params);
1701
1702   gpu_material_add_node(mat, node);
1703
1704   return true;
1705 }
1706
1707 bool GPU_stack_link(GPUMaterial *material,
1708                     bNode *bnode,
1709                     const char *name,
1710                     GPUNodeStack *in,
1711                     GPUNodeStack *out,
1712                     ...)
1713 {
1714   GPUNode *node;
1715   GPUFunction *function;
1716   GPUNodeLink *link, **linkptr;
1717   va_list params;
1718   int i, totin, totout;
1719
1720   function = gpu_lookup_function(name);
1721   if (!function) {
1722     fprintf(stderr, "GPU failed to find function %s\n", name);
1723     return false;
1724   }
1725
1726   node = GPU_node_begin(name);
1727   totin = 0;
1728   totout = 0;
1729
1730   if (in) {
1731     for (i = 0; !in[i].end; i++) {
1732       if (in[i].type != GPU_NONE) {
1733         gpu_node_input_socket(material, bnode, node, &in[i], i);
1734         totin++;
1735       }
1736     }
1737   }
1738
1739   if (out) {
1740     for (i = 0; !out[i].end; i++) {
1741       if (out[i].type != GPU_NONE) {
1742         gpu_node_output(node, out[i].type, &out[i].link);
1743         totout++;
1744       }
1745     }
1746   }
1747
1748   va_start(params, out);
1749   for (i = 0; i < function->totparam; i++) {
1750     if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1751       if (totout == 0) {
1752         linkptr = va_arg(params, GPUNodeLink **);
1753         gpu_node_output(node, function->paramtype[i], linkptr);
1754       }
1755       else
1756         totout--;
1757     }
1758     else {
1759       if (totin == 0) {
1760         link = va_arg(params, GPUNodeLink *);
1761         if (link->socket)
1762           gpu_node_input_socket(NULL, NULL, node, link->socket, -1);
1763         else
1764           gpu_node_input_link(node, link, function->paramtype[i]);
1765       }
1766       else
1767         totin--;
1768     }
1769   }
1770   va_end(params);
1771
1772   gpu_material_add_node(material, node);
1773
1774   return true;
1775 }
1776
1777 GPUNodeLink *GPU_uniformbuffer_link_out(GPUMaterial *mat,
1778                                         bNode *node,
1779                                         GPUNodeStack *stack,
1780                                         const int index)
1781 {
1782   return gpu_uniformbuffer_link(mat, node, stack, index, SOCK_OUT);
1783 }
1784
1785 /* Pass create/free */
1786
1787 static void gpu_nodes_tag(GPUNodeLink *link)
1788 {
1789   GPUNode *node;
1790   GPUInput *input;
1791
1792   if (!link->output)
1793     return;
1794
1795   node = link->output->node;
1796   if (node->tag)
1797     return;
1798
1799   node->tag = true;
1800   for (input = node->inputs.first; input; input = input->next)
1801     if (input->link)
1802       gpu_nodes_tag(input->link);
1803 }
1804
1805 void GPU_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
1806 {
1807   GPUNode *node, *next;
1808
1809   for (node = nodes->first; node; node = node->next)
1810     node->tag = false;
1811
1812   gpu_nodes_tag(outlink);
1813
1814   for (node = nodes->first; node; node = next) {
1815     next = node->next;
1816
1817     if (!node->tag) {
1818       BLI_remlink(nodes, node);
1819       gpu_node_free(node);
1820     }
1821   }
1822 }
1823
1824 static bool gpu_pass_is_valid(GPUPass *pass)
1825 {
1826   /* Shader is not null if compilation is successful. */
1827   return (pass->compiled == false || pass->shader != NULL);
1828 }
1829
1830 GPUPass *GPU_generate_pass(GPUMaterial *material,
1831                            GPUNodeLink *frag_outlink,
1832                            struct GPUVertAttrLayers *attrs,
1833                            ListBase *nodes,
1834                            int *builtins,
1835                            const char *vert_code,
1836                            const char *geom_code,
1837                            const char *frag_lib,
1838                            const char *defines)
1839 {
1840   char *vertexcode, *geometrycode, *fragmentcode;
1841   GPUPass *pass = NULL, *pass_hash = NULL;
1842
1843   /* prune unused nodes */
1844   GPU_nodes_prune(nodes, frag_outlink);
1845
1846   GPU_nodes_get_vertex_attrs(nodes, attrs);
1847
1848   /* generate code */
1849   char *fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output, builtins);
1850
1851   /* Cache lookup: Reuse shaders already compiled */
1852   uint32_t hash = gpu_pass_hash(fragmentgen, defines, attrs);
1853   pass_hash = gpu_pass_cache_lookup(hash);
1854
1855   if (pass_hash && (pass_hash->next == NULL || pass_hash->next->hash != hash)) {
1856     /* No collision, just return the pass. */
1857     MEM_freeN(fragmentgen);
1858     if (!gpu_pass_is_valid(pass_hash)) {
1859       /* Shader has already been created but failed to compile. */
1860       return NULL;
1861     }
1862     pass_hash->refcount += 1;
1863     return pass_hash;
1864   }
1865
1866   /* Either the shader is not compiled or there is a hash collision...
1867    * continue generating the shader strings. */
1868   char *tmp = BLI_strdupcat(frag_lib, glsl_material_library);
1869
1870   geometrycode = code_generate_geometry(nodes, geom_code, defines);
1871   vertexcode = code_generate_vertex(nodes, vert_code, (geometrycode != NULL));
1872   fragmentcode = BLI_strdupcat(tmp, fragmentgen);
1873
1874   MEM_freeN(fragmentgen);
1875   MEM_freeN(tmp);
1876
1877   if (pass_hash) {
1878     /* Cache lookup: Reuse shaders already compiled */
1879     pass = gpu_pass_cache_resolve_collision(
1880         pass_hash, vertexcode, geometrycode, fragmentcode, defines, hash);
1881   }
1882
1883   if (pass) {
1884     /* Cache hit. Reuse the same GPUPass and GPUShader. */
1885     if (!gpu_pass_is_valid(pass)) {
1886       /* Shader has already been created but failed to compile. */
1887       return NULL;
1888     }
1889
1890     MEM_SAFE_FREE(vertexcode);
1891     MEM_SAFE_FREE(fragmentcode);
1892     MEM_SAFE_FREE(geometrycode);
1893
1894     pass->refcount += 1;
1895   }
1896   else {
1897     /* We still create a pass even if shader compilation
1898      * fails to avoid trying to compile again and again. */
1899     pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
1900     pass->shader = NULL;
1901     pass->refcount = 1;
1902     pass->hash = hash;
1903     pass->vertexcode = vertexcode;
1904     pass->fragmentcode = fragmentcode;
1905     pass->geometrycode = geometrycode;
1906     pass->defines = (defines) ? BLI_strdup(defines) : NULL;
1907     pass->compiled = false;
1908
1909     BLI_spin_lock(&pass_cache_spin);
1910     if (pass_hash != NULL) {
1911       /* Add after the first pass having the same hash. */
1912       pass->next = pass_hash->next;
1913       pass_hash->next = pass;
1914     }
1915     else {
1916       /* No other pass have same hash, just prepend to the list. */
1917       BLI_LINKS_PREPEND(pass_cache, pass);
1918     }
1919     BLI_spin_unlock(&pass_cache_spin);
1920   }
1921
1922   return pass;
1923 }
1924
1925 static int count_active_texture_sampler(GPUShader *shader, char *source)
1926 {
1927   char *code = source;
1928   int samplers_id[64]; /* Remember this is per stage. */
1929   int sampler_len = 0;
1930
1931   while ((code = strstr(code, "uniform "))) {
1932     /* Move past "uniform". */
1933     code += 7;
1934     /* Skip following spaces. */
1935     while (*code == ' ') {
1936       code++;
1937     }
1938     /* Skip "i" from potential isamplers. */
1939     if (*code == 'i') {
1940       code++;
1941     }
1942     /* Skip following spaces. */
1943     if (gpu_str_prefix(code, "sampler")) {
1944       /* Move past "uniform". */
1945       code += 7;
1946       /* Skip sampler type suffix. */
1947       while (*code != ' ' && *code != '\0') {
1948         code++;
1949       }
1950       /* Skip following spaces. */
1951       while (*code == ' ') {
1952         code++;
1953       }
1954
1955       if (*code != '\0') {
1956         char sampler_name[64];
1957         code = gpu_str_skip_token(code, sampler_name, sizeof(sampler_name));
1958         int id = GPU_shader_get_uniform_ensure(shader, sampler_name);
1959
1960         if (id == -1) {
1961           continue;
1962         }
1963         /* Catch duplicates. */
1964         bool is_duplicate = false;
1965         for (int i = 0; i < sampler_len; ++i) {
1966           if (samplers_id[i] == id) {
1967             is_duplicate = true;
1968           }
1969         }
1970
1971         if (!is_duplicate) {
1972           samplers_id[sampler_len] = id;
1973           sampler_len++;
1974         }
1975       }
1976     }
1977   }
1978
1979   return sampler_len;
1980 }
1981
1982 static bool gpu_pass_shader_validate(GPUPass *pass)
1983 {
1984   if (pass->shader == NULL) {
1985     return false;
1986   }
1987
1988   /* NOTE: The only drawback of this method is that it will count a sampler
1989    * used in the fragment shader and only declared (but not used) in the vertex
1990    * shader as used by both. But this corner case is not happening for now. */
1991   int vert_samplers_len = count_active_texture_sampler(pass->shader, pass->vertexcode);
1992   int frag_samplers_len = count_active_texture_sampler(pass->shader, pass->fragmentcode);
1993
1994   int total_samplers_len = vert_samplers_len + frag_samplers_len;
1995
1996   /* Validate against opengl limit. */
1997   if ((frag_samplers_len > GPU_max_textures_frag()) ||
1998       (vert_samplers_len > GPU_max_textures_vert())) {
1999     return false;
2000   }
2001
2002   if (pass->geometrycode) {
2003     int geom_samplers_len = count_active_texture_sampler(pass->shader, pass->geometrycode);
2004     total_samplers_len += geom_samplers_len;
2005     if (geom_samplers_len > GPU_max_textures_geom()) {
2006       return false;
2007     }
2008   }
2009
2010   return (total_samplers_len <= GPU_max_textures());
2011 }
2012
2013 void GPU_pass_compile(GPUPass *pass, const char *shname)
2014 {
2015   if (!pass->compiled) {
2016     pass->shader = GPU_shader_create(
2017         pass->vertexcode, pass->fragmentcode, pass->geometrycode, NULL, pass->defines, shname);
2018
2019     /* NOTE: Some drivers / gpu allows more active samplers than the opengl limit.
2020      * We need to make sure to count active samplers to avoid undefined behavior. */
2021     if (!gpu_pass_shader_validate(pass)) {
2022       if (pass->shader != NULL) {
2023         fprintf(stderr, "GPUShader: error: too many samplers in shader.\n");
2024         GPU_shader_free(pass->shader);
2025       }
2026       pass->shader = NULL;
2027     }
2028     else if (!BLI_thread_is_main()) {
2029       /* For some Intel drivers, you must use the program at least once
2030        * in the rendering context that it is linked. */
2031       glUseProgram(GPU_shader_get_program(pass->shader));
2032       glUseProgram(0);
2033     }
2034
2035     pass->compiled = true;
2036   }
2037 }
2038
2039 void GPU_pass_release(GPUPass *pass)
2040 {
2041   BLI_assert(pass->refcount > 0);
2042   pass->refcount--;
2043 }
2044
2045 static void gpu_pass_free(GPUPass *pass)
2046 {
2047   BLI_assert(pass->refcount == 0);
2048   if (pass->shader) {
2049     GPU_shader_free(pass->shader);
2050   }
2051   MEM_SAFE_FREE(pass->fragmentcode);
2052   MEM_SAFE_FREE(pass->geometrycode);
2053   MEM_SAFE_FREE(pass->vertexcode);
2054   MEM_SAFE_FREE(pass->defines);
2055   MEM_freeN(pass);
2056 }
2057
2058 void GPU_pass_free_nodes(ListBase *nodes)
2059 {
2060   gpu_nodes_free(nodes);
2061 }
2062
2063 void GPU_pass_cache_garbage_collect(void)
2064 {
2065   static int lasttime = 0;
2066   const int shadercollectrate = 60; /* hardcoded for now. */
2067   int ctime = (int)PIL_check_seconds_timer();
2068
2069   if (ctime < shadercollectrate + lasttime)
2070     return;
2071
2072   lasttime = ctime;
2073
2074   BLI_spin_lock(&pass_cache_spin);
2075   GPUPass *next, **prev_pass = &pass_cache;
2076   for (GPUPass *pass = pass_cache; pass; pass = next) {
2077     next = pass->next;
2078     if (pass->refcount == 0) {
2079       /* Remove from list */
2080       *prev_pass = next;
2081       gpu_pass_free(pass);
2082     }
2083     else {
2084       prev_pass = &pass->next;
2085     }
2086   }
2087   BLI_spin_unlock(&pass_cache_spin);
2088 }
2089
2090 void GPU_pass_cache_init(void)
2091 {
2092   BLI_spin_init(&pass_cache_spin);
2093 }
2094
2095 void GPU_pass_cache_free(void)
2096 {
2097   BLI_spin_lock(&pass_cache_spin);
2098   while (pass_cache) {
2099     GPUPass *next = pass_cache->next;
2100     gpu_pass_free(pass_cache);
2101     pass_cache = next;
2102   }
2103   BLI_spin_unlock(&pass_cache_spin);
2104
2105   BLI_spin_end(&pass_cache_spin);
2106 }