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