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