Cleanup: remove redundant, invalid info from headers
[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 blender/gpu/intern/gpu_codegen.c
21  *  \ingroup gpu
22  *
23  * Convert material node-trees to GLSL.
24  */
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_customdata_types.h"
29 #include "DNA_image_types.h"
30 #include "DNA_material_types.h"
31
32 #include "BLI_blenlib.h"
33 #include "BLI_utildefines.h"
34 #include "BLI_dynstr.h"
35 #include "BLI_ghash.h"
36
37 #include "GPU_extensions.h"
38 #include "GPU_glew.h"
39 #include "GPU_material.h"
40 #include "GPU_shader.h"
41 #include "GPU_texture.h"
42
43 #include "BLI_sys_types.h" /* for intptr_t support */
44
45 #include "gpu_codegen.h"
46
47 #include <string.h>
48 #include <stdarg.h>
49
50 extern char datatoc_gpu_shader_material_glsl[];
51 extern char datatoc_gpu_shader_vertex_glsl[];
52 extern char datatoc_gpu_shader_vertex_world_glsl[];
53 extern char datatoc_gpu_shader_geometry_glsl[];
54
55 static char *glsl_material_library = NULL;
56
57
58 /* type definitions and constants */
59
60 enum {
61         MAX_FUNCTION_NAME = 64,
62 };
63 enum {
64         MAX_PARAMETER = 32,
65 };
66
67 typedef enum {
68         FUNCTION_QUAL_IN,
69         FUNCTION_QUAL_OUT,
70         FUNCTION_QUAL_INOUT
71 } GPUFunctionQual;
72
73 typedef struct GPUFunction {
74         char name[MAX_FUNCTION_NAME];
75         GPUType paramtype[MAX_PARAMETER];
76         GPUFunctionQual paramqual[MAX_PARAMETER];
77         int totparam;
78 } GPUFunction;
79
80 /* Indices match the GPUType enum */
81 static const char *GPU_DATATYPE_STR[17] = {
82         "", "float", "vec2", "vec3", "vec4",
83         NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4",
84 };
85
86 /* GLSL code parsing for finding function definitions.
87  * These are stored in a hash for lookup when creating a material. */
88
89 static GHash *FUNCTION_HASH = NULL;
90 #if 0
91 static char *FUNCTION_PROTOTYPES = NULL;
92 static GPUShader *FUNCTION_LIB = NULL;
93 #endif
94
95 static int gpu_str_prefix(const char *str, const char *prefix)
96 {
97         while (*str && *prefix) {
98                 if (*str != *prefix)
99                         return 0;
100
101                 str++;
102                 prefix++;
103         }
104
105         return (*prefix == '\0');
106 }
107
108 static char *gpu_str_skip_token(char *str, char *token, int max)
109 {
110         int len = 0;
111
112         /* skip a variable/function name */
113         while (*str) {
114                 if (ELEM(*str, ' ', '(', ')', ',', '\t', '\n', '\r'))
115                         break;
116                 else {
117                         if (token && len < max - 1) {
118                                 *token = *str;
119                                 token++;
120                                 len++;
121                         }
122                         str++;
123                 }
124         }
125
126         if (token)
127                 *token = '\0';
128
129         /* skip the next special characters:
130          * note the missing ')' */
131         while (*str) {
132                 if (ELEM(*str, ' ', '(', ',', '\t', '\n', '\r'))
133                         str++;
134                 else
135                         break;
136         }
137
138         return str;
139 }
140
141 static void gpu_parse_functions_string(GHash *hash, char *code)
142 {
143         GPUFunction *function;
144         GPUType type;
145         GPUFunctionQual qual;
146         int i;
147
148         while ((code = strstr(code, "void "))) {
149                 function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
150
151                 code = gpu_str_skip_token(code, NULL, 0);
152                 code = gpu_str_skip_token(code, function->name, MAX_FUNCTION_NAME);
153
154                 /* get parameters */
155                 while (*code && *code != ')') {
156                         /* test if it's an input or output */
157                         qual = FUNCTION_QUAL_IN;
158                         if (gpu_str_prefix(code, "out "))
159                                 qual = FUNCTION_QUAL_OUT;
160                         if (gpu_str_prefix(code, "inout "))
161                                 qual = FUNCTION_QUAL_INOUT;
162                         if ((qual != FUNCTION_QUAL_IN) || gpu_str_prefix(code, "in "))
163                                 code = gpu_str_skip_token(code, NULL, 0);
164
165                         /* test for type */
166                         type = GPU_NONE;
167                         for (i = 1; i <= 16; i++) {
168                                 if (GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
169                                         type = i;
170                                         break;
171                                 }
172                         }
173
174                         if (!type && gpu_str_prefix(code, "samplerCube")) {
175                                 type = GPU_TEXCUBE;
176                         }
177                         if (!type && gpu_str_prefix(code, "sampler2DShadow")) {
178                                 type = GPU_SHADOW2D;
179                         }
180                         if (!type && gpu_str_prefix(code, "sampler2D")) {
181                                 type = GPU_TEX2D;
182                         }
183
184                         if (type) {
185                                 /* add parameter */
186                                 code = gpu_str_skip_token(code, NULL, 0);
187                                 code = gpu_str_skip_token(code, NULL, 0);
188                                 function->paramqual[function->totparam] = qual;
189                                 function->paramtype[function->totparam] = type;
190                                 function->totparam++;
191                         }
192                         else {
193                                 fprintf(stderr, "GPU invalid function parameter in %s.\n", function->name);
194                                 break;
195                         }
196                 }
197
198                 if (function->name[0] == '\0' || function->totparam == 0) {
199                         fprintf(stderr, "GPU functions parse error.\n");
200                         MEM_freeN(function);
201                         break;
202                 }
203
204                 BLI_ghash_insert(hash, function->name, function);
205         }
206 }
207
208 #if 0
209 static char *gpu_generate_function_prototyps(GHash *hash)
210 {
211         DynStr *ds = BLI_dynstr_new();
212         GHashIterator *ghi;
213         GPUFunction *function;
214         char *name, *prototypes;
215         int a;
216
217         /* automatically generate function prototypes to add to the top of the
218          * generated code, to avoid have to add the actual code & recompile all */
219         ghi = BLI_ghashIterator_new(hash);
220
221         for (; !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) {
222                 name = BLI_ghashIterator_getValue(ghi);
223                 function = BLI_ghashIterator_getValue(ghi);
224
225                 BLI_dynstr_appendf(ds, "void %s(", name);
226                 for (a = 0; a < function->totparam; a++) {
227                         if (function->paramqual[a] == FUNCTION_QUAL_OUT)
228                                 BLI_dynstr_append(ds, "out ");
229                         else if (function->paramqual[a] == FUNCTION_QUAL_INOUT)
230                                 BLI_dynstr_append(ds, "inout ");
231
232                         if (function->paramtype[a] == GPU_TEX2D)
233                                 BLI_dynstr_append(ds, "sampler2D");
234                         else if (function->paramtype[a] == GPU_SHADOW2D)
235                                 BLI_dynstr_append(ds, "sampler2DShadow");
236                         else
237                                 BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]);
238 #  if 0
239                         BLI_dynstr_appendf(ds, " param%d", a);
240 #  endif
241
242                         if (a != function->totparam - 1)
243                                 BLI_dynstr_append(ds, ", ");
244                 }
245                 BLI_dynstr_append(ds, ");\n");
246         }
247
248         BLI_dynstr_append(ds, "\n");
249
250         prototypes = BLI_dynstr_get_cstring(ds);
251         BLI_dynstr_free(ds);
252
253         return prototypes;
254 }
255 #endif
256
257 static GPUFunction *gpu_lookup_function(const char *name)
258 {
259         if (!FUNCTION_HASH) {
260                 FUNCTION_HASH = BLI_ghash_str_new("GPU_lookup_function gh");
261                 gpu_parse_functions_string(FUNCTION_HASH, glsl_material_library);
262         }
263
264         return BLI_ghash_lookup(FUNCTION_HASH, (const void *)name);
265 }
266
267 void gpu_codegen_init(void)
268 {
269         GPU_code_generate_glsl_lib();
270 }
271
272 void gpu_codegen_exit(void)
273 {
274         extern Material defmaterial; /* render module abuse... */
275
276         if (defmaterial.gpumaterial.first)
277                 GPU_material_free(&defmaterial.gpumaterial);
278
279         if (FUNCTION_HASH) {
280                 BLI_ghash_free(FUNCTION_HASH, NULL, MEM_freeN);
281                 FUNCTION_HASH = NULL;
282         }
283
284         GPU_shader_free_builtin_shaders();
285
286         if (glsl_material_library) {
287                 MEM_freeN(glsl_material_library);
288                 glsl_material_library = NULL;
289         }
290
291 #if 0
292         if (FUNCTION_PROTOTYPES) {
293                 MEM_freeN(FUNCTION_PROTOTYPES);
294                 FUNCTION_PROTOTYPES = NULL;
295         }
296         if (FUNCTION_LIB) {
297                 GPU_shader_free(FUNCTION_LIB);
298                 FUNCTION_LIB = NULL;
299         }
300 #endif
301 }
302
303 /* GLSL code generation */
304
305 static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *tmp, int id)
306 {
307         char name[1024];
308
309         BLI_snprintf(name, sizeof(name), "%s%d", tmp, id);
310
311         if (from == to) {
312                 BLI_dynstr_append(ds, name);
313         }
314         else if (to == GPU_FLOAT) {
315                 if (from == GPU_VEC4)
316                         BLI_dynstr_appendf(ds, "convert_rgba_to_float(%s)", name);
317                 else if (from == GPU_VEC3)
318                         BLI_dynstr_appendf(ds, "(%s.r + %s.g + %s.b) / 3.0", name, name, name);
319                 else if (from == GPU_VEC2)
320                         BLI_dynstr_appendf(ds, "%s.r", name);
321         }
322         else if (to == GPU_VEC2) {
323                 if (from == GPU_VEC4)
324                         BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, %s.a)", name, name, name, name);
325                 else if (from == GPU_VEC3)
326                         BLI_dynstr_appendf(ds, "vec2((%s.r + %s.g + %s.b) / 3.0, 1.0)", name, name, name);
327                 else if (from == GPU_FLOAT)
328                         BLI_dynstr_appendf(ds, "vec2(%s, 1.0)", name);
329         }
330         else if (to == GPU_VEC3) {
331                 if (from == GPU_VEC4)
332                         BLI_dynstr_appendf(ds, "%s.rgb", name);
333                 else if (from == GPU_VEC2)
334                         BLI_dynstr_appendf(ds, "vec3(%s.r, %s.r, %s.r)", name, name, name);
335                 else if (from == GPU_FLOAT)
336                         BLI_dynstr_appendf(ds, "vec3(%s, %s, %s)", name, name, name);
337         }
338         else {
339                 if (from == GPU_VEC3)
340                         BLI_dynstr_appendf(ds, "vec4(%s, 1.0)", name);
341                 else if (from == GPU_VEC2)
342                         BLI_dynstr_appendf(ds, "vec4(%s.r, %s.r, %s.r, %s.g)", name, name, name, name);
343                 else if (from == GPU_FLOAT)
344                         BLI_dynstr_appendf(ds, "vec4(%s, %s, %s, 1.0)", name, name, name);
345         }
346 }
347
348 static void codegen_print_datatype(DynStr *ds, const GPUType type, float *data)
349 {
350         int i;
351
352         BLI_dynstr_appendf(ds, "%s(", GPU_DATATYPE_STR[type]);
353
354         for (i = 0; i < type; i++) {
355                 BLI_dynstr_appendf(ds, "%.12f", data[i]);
356                 if (i == type - 1)
357                         BLI_dynstr_append(ds, ")");
358                 else
359                         BLI_dynstr_append(ds, ", ");
360         }
361 }
362
363 static int codegen_input_has_texture(GPUInput *input)
364 {
365         if (input->link)
366                 return 0;
367         else if (input->ima || input->prv)
368                 return 1;
369         else
370                 return input->tex != NULL;
371 }
372
373 const char *GPU_builtin_name(GPUBuiltin builtin)
374 {
375         if (builtin == GPU_VIEW_MATRIX)
376                 return "unfviewmat";
377         else if (builtin == GPU_OBJECT_MATRIX)
378                 return "unfobmat";
379         else if (builtin == GPU_INVERSE_VIEW_MATRIX)
380                 return "unfinvviewmat";
381         else if (builtin == GPU_INVERSE_OBJECT_MATRIX)
382                 return "unfinvobmat";
383         else if (builtin == GPU_LOC_TO_VIEW_MATRIX)
384                 return "unflocaltoviewmat";
385         else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX)
386                 return "unfinvlocaltoviewmat";
387         else if (builtin == GPU_VIEW_POSITION)
388                 return "varposition";
389         else if (builtin == GPU_VIEW_NORMAL)
390                 return "varnormal";
391         else if (builtin == GPU_OBCOLOR)
392                 return "unfobcolor";
393         else if (builtin == GPU_AUTO_BUMPSCALE)
394                 return "unfobautobumpscale";
395         else if (builtin == GPU_CAMERA_TEXCO_FACTORS)
396                 return "unfcameratexfactors";
397         else if (builtin == GPU_PARTICLE_SCALAR_PROPS)
398                 return "unfparticlescalarprops";
399         else if (builtin == GPU_PARTICLE_LOCATION)
400                 return "unfparticleco";
401         else if (builtin == GPU_PARTICLE_VELOCITY)
402                 return "unfparticlevel";
403         else if (builtin == GPU_PARTICLE_ANG_VELOCITY)
404                 return "unfparticleangvel";
405         else if (builtin == GPU_OBJECT_INFO)
406                 return "unfobjectinfo";
407         else
408                 return "";
409 }
410
411 /* assign only one texid per buffer to avoid sampling the same texture twice */
412 static void codegen_set_texid(GHash *bindhash, GPUInput *input, int *texid, void *key)
413 {
414         if (BLI_ghash_haskey(bindhash, key)) {
415                 /* Reuse existing texid */
416                 input->texid = POINTER_AS_INT(BLI_ghash_lookup(bindhash, key));
417         }
418         else {
419                 /* Allocate new texid */
420                 input->texid = *texid;
421                 (*texid)++;
422                 input->bindtex = true;
423                 BLI_ghash_insert(bindhash, key, POINTER_FROM_INT(input->texid));
424         }
425 }
426
427 static void codegen_set_unique_ids(ListBase *nodes)
428 {
429         GHash *bindhash, *definehash;
430         GPUNode *node;
431         GPUInput *input;
432         GPUOutput *output;
433         int id = 1, texid = 0;
434
435         bindhash = BLI_ghash_ptr_new("codegen_set_unique_ids1 gh");
436         definehash = BLI_ghash_ptr_new("codegen_set_unique_ids2 gh");
437
438         for (node = nodes->first; node; node = node->next) {
439                 for (input = node->inputs.first; input; input = input->next) {
440                         /* set id for unique names of uniform variables */
441                         input->id = id++;
442                         input->bindtex = false;
443                         input->definetex = false;
444
445                         /* set texid used for settings texture slot with multitexture */
446                         if (codegen_input_has_texture(input) &&
447                             ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)))
448                         {
449                                 /* assign only one texid per buffer to avoid sampling
450                                  * the same texture twice */
451                                 if (input->link) {
452                                         /* input is texture from buffer */
453                                         codegen_set_texid(bindhash, input, &texid, input->link);
454                                 }
455                                 else if (input->ima) {
456                                         /* input is texture from image */
457                                         codegen_set_texid(bindhash, input, &texid, input->ima);
458                                 }
459                                 else if (input->prv) {
460                                         /* input is texture from preview render */
461                                         codegen_set_texid(bindhash, input, &texid, input->prv);
462                                 }
463                                 else if (input->tex) {
464                                         /* input is user created texture, check tex pointer */
465                                         codegen_set_texid(bindhash, input, &texid, input->tex);
466                                 }
467
468                                 /* make sure this pixel is defined exactly once */
469                                 if (input->source == GPU_SOURCE_TEX_PIXEL) {
470                                         if (input->ima) {
471                                                 if (!BLI_ghash_haskey(definehash, input->ima)) {
472                                                         input->definetex = true;
473                                                         BLI_ghash_insert(definehash, input->ima, POINTER_FROM_INT(input->texid));
474                                                 }
475                                         }
476                                         else {
477                                                 if (!BLI_ghash_haskey(definehash, input->link)) {
478                                                         input->definetex = true;
479                                                         BLI_ghash_insert(definehash, input->link, POINTER_FROM_INT(input->texid));
480                                                 }
481                                         }
482                                 }
483                         }
484                 }
485
486                 for (output = node->outputs.first; output; output = output->next)
487                         /* set id for unique names of tmp variables storing output */
488                         output->id = id++;
489         }
490
491         BLI_ghash_free(bindhash, NULL, NULL);
492         BLI_ghash_free(definehash, NULL, NULL);
493 }
494
495 static int codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
496 {
497         GPUNode *node;
498         GPUInput *input;
499         const char *name;
500         int builtins = 0;
501
502         /* print uniforms */
503         for (node = nodes->first; node; node = node->next) {
504                 for (input = node->inputs.first; input; input = input->next) {
505                         if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) {
506                                 /* create exactly one sampler for each texture */
507                                 if (codegen_input_has_texture(input) && input->bindtex) {
508                                         BLI_dynstr_appendf(ds, "uniform %s samp%d;\n",
509                                                 (input->textype == GPU_TEX2D) ? "sampler2D" :
510                                                 (input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow",
511                                                 input->texid);
512                                 }
513                         }
514                         else if (input->source == GPU_SOURCE_BUILTIN) {
515                                 /* only define each builtin uniform/varying once */
516                                 if (!(builtins & input->builtin)) {
517                                         builtins |= input->builtin;
518                                         name = GPU_builtin_name(input->builtin);
519
520                                         if (gpu_str_prefix(name, "unf")) {
521                                                 BLI_dynstr_appendf(ds, "uniform %s %s;\n",
522                                                         GPU_DATATYPE_STR[input->type], name);
523                                         }
524                                         else {
525                                                 BLI_dynstr_appendf(ds, "%s %s %s;\n",
526                                                         GLEW_VERSION_3_0 ? "in" : "varying",
527                                                         GPU_DATATYPE_STR[input->type], name);
528                                         }
529                                 }
530                         }
531                         else if (input->source == GPU_SOURCE_VEC_UNIFORM) {
532                                 if (input->dynamicvec) {
533                                         /* only create uniforms for dynamic vectors */
534                                         BLI_dynstr_appendf(ds, "uniform %s unf%d;\n",
535                                                 GPU_DATATYPE_STR[input->type], input->id);
536                                 }
537                                 else {
538                                         /* for others use const so the compiler can do folding */
539                                         BLI_dynstr_appendf(ds, "const %s cons%d = ",
540                                                 GPU_DATATYPE_STR[input->type], input->id);
541                                         codegen_print_datatype(ds, input->type, input->vec);
542                                         BLI_dynstr_append(ds, ";\n");
543                                 }
544                         }
545                         else if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
546 #ifdef WITH_OPENSUBDIV
547                                 bool skip_opensubdiv = input->attribtype == CD_TANGENT;
548                                 if (skip_opensubdiv) {
549                                         BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
550                                 }
551 #endif
552                                 BLI_dynstr_appendf(ds, "%s %s var%d;\n",
553                                         GLEW_VERSION_3_0 ? "in" : "varying",
554                                         GPU_DATATYPE_STR[input->type], input->attribid);
555 #ifdef WITH_OPENSUBDIV
556                                 if (skip_opensubdiv) {
557                                         BLI_dynstr_appendf(ds, "#endif\n");
558                                 }
559 #endif
560                         }
561                 }
562         }
563
564         BLI_dynstr_append(ds, "\n");
565
566         return builtins;
567 }
568
569 static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
570 {
571         GPUNode *node;
572         GPUInput *input;
573         GPUOutput *output;
574
575         for (node = nodes->first; node; node = node->next) {
576                 /* load pixels from textures */
577                 for (input = node->inputs.first; input; input = input->next) {
578                         if (input->source == GPU_SOURCE_TEX_PIXEL) {
579                                 if (codegen_input_has_texture(input) && input->definetex) {
580                                         BLI_dynstr_appendf(ds, "\tvec4 tex%d = texture2D(", input->texid);
581                                         BLI_dynstr_appendf(ds, "samp%d, gl_TexCoord[%d].st);\n",
582                                                            input->texid, input->texid);
583                                 }
584                         }
585                 }
586
587                 /* declare temporary variables for node output storage */
588                 for (output = node->outputs.first; output; output = output->next) {
589                         BLI_dynstr_appendf(ds, "\t%s tmp%d;\n",
590                                            GPU_DATATYPE_STR[output->type], output->id);
591                 }
592         }
593
594         BLI_dynstr_append(ds, "\n");
595 }
596
597 static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
598 {
599         GPUNode *node;
600         GPUInput *input;
601         GPUOutput *output;
602
603         for (node = nodes->first; node; node = node->next) {
604                 BLI_dynstr_appendf(ds, "\t%s(", node->name);
605
606                 for (input = node->inputs.first; input; input = input->next) {
607                         if (input->source == GPU_SOURCE_TEX) {
608                                 BLI_dynstr_appendf(ds, "samp%d", input->texid);
609                                 if (input->link)
610                                         BLI_dynstr_appendf(ds, ", gl_TexCoord[%d].st", input->texid);
611                         }
612                         else if (input->source == GPU_SOURCE_TEX_PIXEL) {
613                                 codegen_convert_datatype(ds, input->link->output->type, input->type,
614                                         "tmp", input->link->output->id);
615                         }
616                         else if (input->source == GPU_SOURCE_BUILTIN) {
617                                 if (input->builtin == GPU_VIEW_NORMAL)
618                                         BLI_dynstr_append(ds, "facingnormal");
619                                 else
620                                         BLI_dynstr_append(ds, GPU_builtin_name(input->builtin));
621                         }
622                         else if (input->source == GPU_SOURCE_VEC_UNIFORM) {
623                                 if (input->dynamicvec)
624                                         BLI_dynstr_appendf(ds, "unf%d", input->id);
625                                 else
626                                         BLI_dynstr_appendf(ds, "cons%d", input->id);
627                         }
628                         else if (input->source == GPU_SOURCE_ATTRIB) {
629                                 BLI_dynstr_appendf(ds, "var%d", input->attribid);
630                         }
631                         else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
632                                 if (input->oglbuiltin == GPU_MATCAP_NORMAL)
633                                         BLI_dynstr_append(ds, "gl_SecondaryColor");
634                                 else if (input->oglbuiltin == GPU_COLOR)
635                                         BLI_dynstr_append(ds, "gl_Color");
636                         }
637
638                         BLI_dynstr_append(ds, ", ");
639                 }
640
641                 for (output = node->outputs.first; output; output = output->next) {
642                         BLI_dynstr_appendf(ds, "tmp%d", output->id);
643                         if (output->next)
644                                 BLI_dynstr_append(ds, ", ");
645                 }
646
647                 BLI_dynstr_append(ds, ");\n");
648         }
649
650         BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
651         codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
652         BLI_dynstr_append(ds, ";\n");
653 }
654
655 static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
656 {
657         DynStr *ds = BLI_dynstr_new();
658         char *code;
659         int builtins;
660
661 #ifdef WITH_OPENSUBDIV
662         GPUNode *node;
663         GPUInput *input;
664 #endif
665
666
667 #if 0
668         BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
669 #endif
670
671         codegen_set_unique_ids(nodes);
672         builtins = codegen_print_uniforms_functions(ds, nodes);
673
674 #if 0
675         if (G.debug & G_DEBUG)
676                 BLI_dynstr_appendf(ds, "/* %s */\n", name);
677 #endif
678
679         BLI_dynstr_append(ds, "void main()\n{\n");
680
681         if (builtins & GPU_VIEW_NORMAL)
682                 BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing? varnormal: -varnormal;\n");
683
684         /* Calculate tangent space. */
685 #ifdef WITH_OPENSUBDIV
686         {
687                 bool has_tangent = false;
688                 for (node = nodes->first; node; node = node->next) {
689                         for (input = node->inputs.first; input; input = input->next) {
690                                 if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
691                                         if (input->attribtype == CD_TANGENT) {
692                                                 BLI_dynstr_appendf(ds, "#ifdef USE_OPENSUBDIV\n");
693                                                 BLI_dynstr_appendf(ds, "\t%s var%d;\n",
694                                                                    GPU_DATATYPE_STR[input->type],
695                                                                    input->attribid);
696                                                 if (has_tangent == false) {
697                                                         BLI_dynstr_appendf(ds, "\tvec3 Q1 = dFdx(inpt.v.position.xyz);\n");
698                                                         BLI_dynstr_appendf(ds, "\tvec3 Q2 = dFdy(inpt.v.position.xyz);\n");
699                                                         BLI_dynstr_appendf(ds, "\tvec2 st1 = dFdx(inpt.v.uv);\n");
700                                                         BLI_dynstr_appendf(ds, "\tvec2 st2 = dFdy(inpt.v.uv);\n");
701                                                         BLI_dynstr_appendf(ds, "\tvec3 T = normalize(Q1 * st2.t - Q2 * st1.t);\n");
702                                                 }
703                                                 BLI_dynstr_appendf(ds, "\tvar%d = vec4(T, 1.0);\n", input->attribid);
704                                                 BLI_dynstr_appendf(ds, "#endif\n");
705                                         }
706                                 }
707                         }
708                 }
709         }
710 #endif
711
712         codegen_declare_tmps(ds, nodes);
713         codegen_call_functions(ds, nodes, output);
714
715         BLI_dynstr_append(ds, "}\n");
716
717         /* create shader */
718         code = BLI_dynstr_get_cstring(ds);
719         BLI_dynstr_free(ds);
720
721 #if 0
722         if (G.debug & G_DEBUG) printf("%s\n", code);
723 #endif
724
725         return code;
726 }
727
728 static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
729 {
730         DynStr *ds = BLI_dynstr_new();
731         GPUNode *node;
732         GPUInput *input;
733         char *code;
734         char *vertcode = NULL;
735
736         for (node = nodes->first; node; node = node->next) {
737                 for (input = node->inputs.first; input; input = input->next) {
738                         if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
739 #ifdef WITH_OPENSUBDIV
740                                 bool skip_opensubdiv = ELEM(input->attribtype, CD_MTFACE, CD_TANGENT);
741                                 if (skip_opensubdiv) {
742                                         BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
743                                 }
744 #endif
745                                 BLI_dynstr_appendf(ds, "%s %s att%d;\n",
746                                         GLEW_VERSION_3_0 ? "in" : "attribute",
747                                         GPU_DATATYPE_STR[input->type], input->attribid);
748                                 BLI_dynstr_appendf(ds, "uniform int att%d_info;\n",  input->attribid);
749                                 BLI_dynstr_appendf(ds, "%s %s var%d;\n",
750                                         GLEW_VERSION_3_0 ? "out" : "varying",
751                                         GPU_DATATYPE_STR[input->type], input->attribid);
752 #ifdef WITH_OPENSUBDIV
753                                 if (skip_opensubdiv) {
754                                         BLI_dynstr_appendf(ds, "#endif\n");
755                                 }
756 #endif
757                         }
758                 }
759         }
760
761         BLI_dynstr_append(ds, "\n");
762
763         switch (type) {
764                 case GPU_MATERIAL_TYPE_MESH:
765                         vertcode = datatoc_gpu_shader_vertex_glsl;
766                         break;
767                 case GPU_MATERIAL_TYPE_WORLD:
768                         vertcode = datatoc_gpu_shader_vertex_world_glsl;
769                         break;
770                 default:
771                         fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n");
772                         break;
773         }
774
775         BLI_dynstr_append(ds, vertcode);
776
777         for (node = nodes->first; node; node = node->next)
778                 for (input = node->inputs.first; input; input = input->next)
779                         if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
780                                 if (input->attribtype == CD_TANGENT) { /* silly exception */
781 #ifdef WITH_OPENSUBDIV
782                                         BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
783 #endif
784                                         BLI_dynstr_appendf(
785                                                 ds, "\tvar%d.xyz = normalize(gl_NormalMatrix * att%d.xyz);\n",
786                                                 input->attribid, input->attribid);
787                                         BLI_dynstr_appendf(
788                                                 ds, "\tvar%d.w = att%d.w;\n",
789                                                 input->attribid, input->attribid);
790 #ifdef WITH_OPENSUBDIV
791                                         BLI_dynstr_appendf(ds, "#endif\n");
792 #endif
793                                 }
794                                 else {
795 #ifdef WITH_OPENSUBDIV
796                                         bool is_mtface = input->attribtype == CD_MTFACE;
797                                         if (is_mtface) {
798                                                 BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
799                                         }
800 #endif
801                                         BLI_dynstr_appendf(ds, "\tset_var_from_attr(att%d, att%d_info, var%d);\n",
802                                                            input->attribid, input->attribid, input->attribid);
803 #ifdef WITH_OPENSUBDIV
804                                         if (is_mtface) {
805                                                 BLI_dynstr_appendf(ds, "#endif\n");
806                                         }
807 #endif
808                                 }
809                         }
810                         /* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */
811                         else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
812                                 if (input->oglbuiltin == GPU_MATCAP_NORMAL) {
813                                         /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
814                                          * between shader stages and we want the full range of the normal */
815                                         BLI_dynstr_appendf(ds, "\tvec3 matcapcol = vec3(0.5) * varnormal + vec3(0.5);\n");
816                                         BLI_dynstr_appendf(ds, "\tgl_FrontSecondaryColor = vec4(matcapcol, 1.0);\n");
817                                 }
818                                 else if (input->oglbuiltin == GPU_COLOR) {
819                                         BLI_dynstr_appendf(ds, "\tgl_FrontColor = gl_Color;\n");
820                                 }
821                         }
822
823         BLI_dynstr_append(ds, "}\n");
824
825         code = BLI_dynstr_get_cstring(ds);
826
827         BLI_dynstr_free(ds);
828
829 #if 0
830         if (G.debug & G_DEBUG) printf("%s\n", code);
831 #endif
832
833         return code;
834 }
835
836 static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv)
837 {
838 #ifdef WITH_OPENSUBDIV
839         if (use_opensubdiv) {
840                 DynStr *ds = BLI_dynstr_new();
841                 GPUNode *node;
842                 GPUInput *input;
843                 char *code;
844
845                 /* Generate varying declarations. */
846                 for (node = nodes->first; node; node = node->next) {
847                         for (input = node->inputs.first; input; input = input->next) {
848                                 if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
849                                         if (input->attribtype == CD_MTFACE) {
850                                                 /* NOTE: For now we are using varying on purpose,
851                                                  * otherwise we are not able to write to the varying.
852                                                  */
853                                                 BLI_dynstr_appendf(ds, "%s %s var%d%s;\n",
854                                                                    "varying",
855                                                                    GPU_DATATYPE_STR[input->type],
856                                                                    input->attribid,
857                                                                    "");
858                                                 BLI_dynstr_appendf(ds, "uniform int fvar%d_offset;\n",
859                                                                    input->attribid);
860                                         }
861                                 }
862                         }
863                 }
864
865                 BLI_dynstr_append(ds, datatoc_gpu_shader_geometry_glsl);
866
867                 /* Generate varying assignments. */
868                 for (node = nodes->first; node; node = node->next) {
869                         for (input = node->inputs.first; input; input = input->next) {
870                                 if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
871                                         if (input->attribtype == CD_MTFACE) {
872                                                 BLI_dynstr_appendf(
873                                                         ds,
874                                                         "\tINTERP_FACE_VARYING_ATT_2(var%d, "
875                                                         "int(texelFetch(FVarDataOffsetBuffer, fvar%d_offset).r), st);\n",
876                                                         input->attribid,
877                                                         input->attribid);
878                                         }
879                                 }
880                         }
881                 }
882
883                 BLI_dynstr_append(ds, "}\n");
884                 code = BLI_dynstr_get_cstring(ds);
885                 BLI_dynstr_free(ds);
886
887                 //if (G.debug & G_DEBUG) printf("%s\n", code);
888
889                 return code;
890         }
891 #else
892         UNUSED_VARS(nodes, use_opensubdiv);
893 #endif
894         return NULL;
895 }
896
897 void GPU_code_generate_glsl_lib(void)
898 {
899         DynStr *ds;
900
901         /* only initialize the library once */
902         if (glsl_material_library)
903                 return;
904
905         ds = BLI_dynstr_new();
906
907         BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
908
909
910         glsl_material_library = BLI_dynstr_get_cstring(ds);
911
912         BLI_dynstr_free(ds);
913 }
914
915
916 /* GPU pass binding/unbinding */
917
918 GPUShader *GPU_pass_shader(GPUPass *pass)
919 {
920         return pass->shader;
921 }
922
923 static void gpu_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
924 {
925         GPUShader *shader = pass->shader;
926         GPUNode *node;
927         GPUInput *next, *input;
928         ListBase *inputs = &pass->inputs;
929         int extract, z;
930
931         memset(inputs, 0, sizeof(*inputs));
932
933         if (!shader)
934                 return;
935
936         GPU_shader_bind(shader);
937
938         for (node = nodes->first; node; node = node->next) {
939                 z = 0;
940                 for (input = node->inputs.first; input; input = next, z++) {
941                         next = input->next;
942
943                         /* attributes don't need to be bound, they already have
944                          * an id that the drawing functions will use */
945                         if (input->source == GPU_SOURCE_ATTRIB) {
946 #ifdef WITH_OPENSUBDIV
947                                 /* We do need mtface attributes for later, so we can
948                                  * update face-varuing variables offset in the texture
949                                  * buffer for proper sampling from the shader.
950                                  *
951                                  * We don't do anything about attribute itself, we
952                                  * only use it to learn which uniform name is to be
953                                  * updated.
954                                  *
955                                  * TODO(sergey): We can add ad extra uniform input
956                                  * for the offset, which will be purely internal and
957                                  * which would avoid having such an exceptions.
958                                  */
959                                 if (input->attribtype != CD_MTFACE) {
960                                         continue;
961                                 }
962 #else
963                                 continue;
964 #endif
965                         }
966                         if (input->source == GPU_SOURCE_BUILTIN ||
967                             input->source == GPU_SOURCE_OPENGL_BUILTIN)
968                         {
969                                 continue;
970                         }
971
972                         if (input->ima || input->tex || input->prv)
973                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
974                         else
975                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
976
977                         /* pass non-dynamic uniforms to opengl */
978                         extract = 0;
979
980                         if (input->ima || input->tex || input->prv) {
981                                 if (input->bindtex)
982                                         extract = 1;
983                         }
984                         else if (input->dynamicvec)
985                                 extract = 1;
986
987                         if (extract)
988                                 input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
989
990 #ifdef WITH_OPENSUBDIV
991                         if (input->source == GPU_SOURCE_ATTRIB &&
992                             input->attribtype == CD_MTFACE)
993                         {
994                                 extract = 1;
995                         }
996 #endif
997
998                         /* extract nodes */
999                         if (extract) {
1000                                 BLI_remlink(&node->inputs, input);
1001                                 BLI_addtail(inputs, input);
1002                         }
1003                 }
1004         }
1005
1006         GPU_shader_unbind();
1007 }
1008
1009 void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
1010 {
1011         GPUInput *input;
1012         GPUShader *shader = pass->shader;
1013         ListBase *inputs = &pass->inputs;
1014
1015         if (!shader)
1016                 return;
1017
1018         GPU_shader_bind(shader);
1019
1020         /* create the textures */
1021         for (input = inputs->first; input; input = input->next) {
1022                 if (input->ima)
1023                         input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, mipmap);
1024                 else if (input->prv)
1025                         input->tex = GPU_texture_from_preview(input->prv, mipmap);
1026         }
1027
1028         /* bind the textures, in second loop so texture binding during
1029          * create doesn't overwrite already bound textures */
1030         for (input = inputs->first; input; input = input->next) {
1031                 if (input->tex && input->bindtex) {
1032                         GPU_texture_bind(input->tex, input->texid);
1033                         GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
1034                 }
1035         }
1036 }
1037
1038 void GPU_pass_update_uniforms(GPUPass *pass)
1039 {
1040         GPUInput *input;
1041         GPUShader *shader = pass->shader;
1042         ListBase *inputs = &pass->inputs;
1043
1044         if (!shader)
1045                 return;
1046
1047         /* pass dynamic inputs to opengl, others were removed */
1048         for (input = inputs->first; input; input = input->next) {
1049                 if (!(input->ima || input->tex || input->prv)) {
1050                         if (input->dynamictype == GPU_DYNAMIC_MAT_HARD) {
1051                                 // The hardness is actually a short pointer, so we convert it here
1052                                 float val = (float)(*(short *)input->dynamicvec);
1053                                 GPU_shader_uniform_vector(shader, input->shaderloc, 1, 1, &val);
1054                         }
1055                         else {
1056                                 GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
1057                                         input->dynamicvec);
1058                         }
1059                 }
1060         }
1061 }
1062
1063 void GPU_pass_unbind(GPUPass *pass)
1064 {
1065         GPUInput *input;
1066         GPUShader *shader = pass->shader;
1067         ListBase *inputs = &pass->inputs;
1068
1069         if (!shader)
1070                 return;
1071
1072         for (input = inputs->first; input; input = input->next) {
1073                 if (input->tex && input->bindtex)
1074                         GPU_texture_unbind(input->tex);
1075
1076                 if (input->ima || input->prv)
1077                         input->tex = NULL;
1078         }
1079
1080         GPU_shader_unbind();
1081 }
1082
1083 /* Node Link Functions */
1084
1085 static GPUNodeLink *GPU_node_link_create(void)
1086 {
1087         GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
1088         link->type = GPU_NONE;
1089         link->users++;
1090
1091         return link;
1092 }
1093
1094 static void gpu_node_link_free(GPUNodeLink *link)
1095 {
1096         link->users--;
1097
1098         if (link->users < 0)
1099                 fprintf(stderr, "GPU_node_link_free: negative refcount\n");
1100
1101         if (link->users == 0) {
1102                 if (link->output)
1103                         link->output->link = NULL;
1104                 MEM_freeN(link);
1105         }
1106 }
1107
1108 /* Node Functions */
1109
1110 static GPUNode *GPU_node_begin(const char *name)
1111 {
1112         GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
1113
1114         node->name = name;
1115
1116         return node;
1117 }
1118
1119 static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType type)
1120 {
1121         GPUInput *input;
1122         GPUNode *outnode;
1123         const char *name;
1124
1125         if (link->output) {
1126                 outnode = link->output->node;
1127                 name = outnode->name;
1128                 input = outnode->inputs.first;
1129
1130                 if ((STREQ(name, "set_value") || STREQ(name, "set_rgb")) &&
1131                     (input->type == type))
1132                 {
1133                         input = MEM_dupallocN(outnode->inputs.first);
1134                         input->type = type;
1135                         if (input->link)
1136                                 input->link->users++;
1137                         BLI_addtail(&node->inputs, input);
1138                         return;
1139                 }
1140         }
1141
1142         input = MEM_callocN(sizeof(GPUInput), "GPUInput");
1143         input->node = node;
1144
1145         if (link->builtin) {
1146                 /* builtin uniform */
1147                 input->type = type;
1148                 input->source = GPU_SOURCE_BUILTIN;
1149                 input->builtin = link->builtin;
1150
1151                 MEM_freeN(link);
1152         }
1153         else if (link->oglbuiltin) {
1154                 /* builtin uniform */
1155                 input->type = type;
1156                 input->source = GPU_SOURCE_OPENGL_BUILTIN;
1157                 input->oglbuiltin = link->oglbuiltin;
1158
1159                 MEM_freeN(link);
1160         }
1161         else if (link->output) {
1162                 /* link to a node output */
1163                 input->type = type;
1164                 input->source = GPU_SOURCE_TEX_PIXEL;
1165                 input->link = link;
1166                 link->users++;
1167         }
1168         else if (link->dynamictex) {
1169                 /* dynamic texture, GPUTexture is updated/deleted externally */
1170                 input->type = type;
1171                 input->source = GPU_SOURCE_TEX;
1172
1173                 input->tex = link->dynamictex;
1174                 input->textarget = GL_TEXTURE_2D;
1175                 input->textype = type;
1176                 input->dynamictex = true;
1177                 input->dynamicdata = link->ptr2;
1178                 MEM_freeN(link);
1179         }
1180         else if (link->texture) {
1181                 /* small texture created on the fly, like for colorbands */
1182                 input->type = GPU_VEC4;
1183                 input->source = GPU_SOURCE_TEX;
1184                 input->textype = type;
1185
1186 #if 0
1187                 input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
1188 #endif
1189                 input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, GPU_HDR_NONE, NULL);
1190                 input->textarget = GL_TEXTURE_2D;
1191
1192                 MEM_freeN(link->ptr1);
1193                 MEM_freeN(link);
1194         }
1195         else if (link->image) {
1196                 /* blender image */
1197                 input->type = GPU_VEC4;
1198                 input->source = GPU_SOURCE_TEX;
1199
1200                 if (link->image == GPU_NODE_LINK_IMAGE_PREVIEW) {
1201                         input->prv = link->ptr1;
1202                         input->textarget = GL_TEXTURE_2D;
1203                         input->textype = GPU_TEX2D;
1204                 }
1205                 else if (link->image == GPU_NODE_LINK_IMAGE_BLENDER) {
1206                         input->ima = link->ptr1;
1207                         input->iuser = link->ptr2;
1208                         input->image_isdata = link->image_isdata;
1209                         input->textarget = GL_TEXTURE_2D;
1210                         input->textype = GPU_TEX2D;
1211                 }
1212                 else if (link->image == GPU_NODE_LINK_IMAGE_CUBE_MAP) {
1213                         input->ima = link->ptr1;
1214                         input->iuser = link->ptr2;
1215                         input->image_isdata = link->image_isdata;
1216                         input->textarget = GL_TEXTURE_CUBE_MAP;
1217                         input->textype = GPU_TEXCUBE;
1218                 }
1219                 MEM_freeN(link);
1220         }
1221         else if (link->attribtype) {
1222                 /* vertex attribute */
1223                 input->type = type;
1224                 input->source = GPU_SOURCE_ATTRIB;
1225
1226                 input->attribtype = link->attribtype;
1227                 BLI_strncpy(input->attribname, link->attribname, sizeof(input->attribname));
1228                 MEM_freeN(link);
1229         }
1230         else {
1231                 /* uniform vector */
1232                 input->type = type;
1233                 input->source = GPU_SOURCE_VEC_UNIFORM;
1234
1235                 memcpy(input->vec, link->ptr1, type * sizeof(float));
1236                 if (link->dynamic) {
1237                         input->dynamicvec = link->ptr1;
1238                         input->dynamictype = link->dynamictype;
1239                         input->dynamicdata = link->ptr2;
1240                 }
1241                 MEM_freeN(link);
1242         }
1243
1244         BLI_addtail(&node->inputs, input);
1245 }
1246
1247 static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock)
1248 {
1249         GPUNodeLink *link;
1250
1251         if (sock->link) {
1252                 gpu_node_input_link(node, sock->link, sock->type);
1253         }
1254         else {
1255                 link = GPU_node_link_create();
1256                 link->ptr1 = sock->vec;
1257                 gpu_node_input_link(node, link, sock->type);
1258         }
1259 }
1260
1261 static void gpu_node_output(GPUNode *node, const GPUType type, GPUNodeLink **link)
1262 {
1263         GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
1264
1265         output->type = type;
1266         output->node = node;
1267
1268         if (link) {
1269                 *link = output->link = GPU_node_link_create();
1270                 output->link->type = type;
1271                 output->link->output = output;
1272
1273                 /* note: the caller owns the reference to the link, GPUOutput
1274                  * merely points to it, and if the node is destroyed it will
1275                  * set that pointer to NULL */
1276         }
1277
1278         BLI_addtail(&node->outputs, output);
1279 }
1280
1281 static void gpu_inputs_free(ListBase *inputs)
1282 {
1283         GPUInput *input;
1284
1285         for (input = inputs->first; input; input = input->next) {
1286                 if (input->link)
1287                         gpu_node_link_free(input->link);
1288                 else if (input->tex && !input->dynamictex)
1289                         GPU_texture_free(input->tex);
1290         }
1291
1292         BLI_freelistN(inputs);
1293 }
1294
1295 static void gpu_node_free(GPUNode *node)
1296 {
1297         GPUOutput *output;
1298
1299         gpu_inputs_free(&node->inputs);
1300
1301         for (output = node->outputs.first; output; output = output->next)
1302                 if (output->link) {
1303                         output->link->output = NULL;
1304                         gpu_node_link_free(output->link);
1305                 }
1306
1307         BLI_freelistN(&node->outputs);
1308         MEM_freeN(node);
1309 }
1310
1311 static void gpu_nodes_free(ListBase *nodes)
1312 {
1313         GPUNode *node;
1314
1315         while ((node = BLI_pophead(nodes))) {
1316                 gpu_node_free(node);
1317         }
1318 }
1319
1320 /* vertex attributes */
1321
1322 static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
1323 {
1324         GPUNode *node;
1325         GPUInput *input;
1326         int a;
1327
1328         /* convert attributes requested by node inputs to an array of layers,
1329          * checking for duplicates and assigning id's starting from zero. */
1330
1331         memset(attribs, 0, sizeof(*attribs));
1332
1333         for (node = nodes->first; node; node = node->next) {
1334                 for (input = node->inputs.first; input; input = input->next) {
1335                         if (input->source == GPU_SOURCE_ATTRIB) {
1336                                 for (a = 0; a < attribs->totlayer; a++) {
1337                                         if (attribs->layer[a].type == input->attribtype &&
1338                                             STREQ(attribs->layer[a].name, input->attribname))
1339                                         {
1340                                                 break;
1341                                         }
1342                                 }
1343
1344                                 if (a < GPU_MAX_ATTRIB) {
1345                                         if (a == attribs->totlayer) {
1346                                                 input->attribid = attribs->totlayer++;
1347                                                 input->attribfirst = 1;
1348
1349                                                 attribs->layer[a].type = input->attribtype;
1350                                                 attribs->layer[a].attribid = input->attribid;
1351                                                 BLI_strncpy(attribs->layer[a].name, input->attribname,
1352                                                             sizeof(attribs->layer[a].name));
1353                                         }
1354                                         else {
1355                                                 input->attribid = attribs->layer[a].attribid;
1356                                         }
1357                                 }
1358                         }
1359                 }
1360         }
1361 }
1362
1363 static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
1364 {
1365         GPUNode *node;
1366         GPUInput *input;
1367
1368         *builtin = 0;
1369
1370         for (node = nodes->first; node; node = node->next)
1371                 for (input = node->inputs.first; input; input = input->next)
1372                         if (input->source == GPU_SOURCE_BUILTIN)
1373                                 *builtin |= input->builtin;
1374 }
1375
1376 /* varargs linking  */
1377
1378 GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
1379 {
1380         GPUNodeLink *link = GPU_node_link_create();
1381
1382         link->attribtype = type;
1383         link->attribname = name;
1384
1385         return link;
1386 }
1387
1388 GPUNodeLink *GPU_uniform(float *num)
1389 {
1390         GPUNodeLink *link = GPU_node_link_create();
1391
1392         link->ptr1 = num;
1393         link->ptr2 = NULL;
1394
1395         return link;
1396 }
1397
1398 GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data)
1399 {
1400         GPUNodeLink *link = GPU_node_link_create();
1401
1402         link->ptr1 = num;
1403         link->ptr2 = data;
1404         link->dynamic = true;
1405         link->dynamictype = dynamictype;
1406
1407
1408         return link;
1409 }
1410
1411 GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
1412 {
1413         GPUNodeLink *link = GPU_node_link_create();
1414
1415         link->image = GPU_NODE_LINK_IMAGE_BLENDER;
1416         link->ptr1 = ima;
1417         link->ptr2 = iuser;
1418         link->image_isdata = is_data;
1419
1420         return link;
1421 }
1422
1423 GPUNodeLink *GPU_cube_map(Image *ima, ImageUser *iuser, bool is_data)
1424 {
1425         GPUNodeLink *link = GPU_node_link_create();
1426
1427         link->image = GPU_NODE_LINK_IMAGE_CUBE_MAP;
1428         link->ptr1 = ima;
1429         link->ptr2 = iuser;
1430         link->image_isdata = is_data;
1431
1432         return link;
1433 }
1434
1435 GPUNodeLink *GPU_image_preview(PreviewImage *prv)
1436 {
1437         GPUNodeLink *link = GPU_node_link_create();
1438
1439         link->image = GPU_NODE_LINK_IMAGE_PREVIEW;
1440         link->ptr1 = prv;
1441
1442         return link;
1443 }
1444
1445
1446 GPUNodeLink *GPU_texture(int size, float *pixels)
1447 {
1448         GPUNodeLink *link = GPU_node_link_create();
1449
1450         link->texture = true;
1451         link->texturesize = size;
1452         link->ptr1 = pixels;
1453
1454         return link;
1455 }
1456
1457 GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, GPUDynamicType dynamictype, void *data)
1458 {
1459         GPUNodeLink *link = GPU_node_link_create();
1460
1461         link->dynamic = true;
1462         link->dynamictex = tex;
1463         link->dynamictype = dynamictype;
1464         link->ptr2 = data;
1465
1466         return link;
1467 }
1468
1469 GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
1470 {
1471         GPUNodeLink *link = GPU_node_link_create();
1472
1473         link->builtin = builtin;
1474
1475         return link;
1476 }
1477
1478 GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin)
1479 {
1480         GPUNodeLink *link = GPU_node_link_create();
1481
1482         link->oglbuiltin = builtin;
1483
1484         return link;
1485 }
1486
1487 bool GPU_link(GPUMaterial *mat, const char *name, ...)
1488 {
1489         GPUNode *node;
1490         GPUFunction *function;
1491         GPUNodeLink *link, **linkptr;
1492         va_list params;
1493         int i;
1494
1495         function = gpu_lookup_function(name);
1496         if (!function) {
1497                 fprintf(stderr, "GPU failed to find function %s\n", name);
1498                 return false;
1499         }
1500
1501         node = GPU_node_begin(name);
1502
1503         va_start(params, name);
1504         for (i = 0; i < function->totparam; i++) {
1505                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1506                         linkptr = va_arg(params, GPUNodeLink **);
1507                         gpu_node_output(node, function->paramtype[i], linkptr);
1508                 }
1509                 else {
1510                         link = va_arg(params, GPUNodeLink *);
1511                         gpu_node_input_link(node, link, function->paramtype[i]);
1512                 }
1513         }
1514         va_end(params);
1515
1516         gpu_material_add_node(mat, node);
1517
1518         return true;
1519 }
1520
1521 bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...)
1522 {
1523         GPUNode *node;
1524         GPUFunction *function;
1525         GPUNodeLink *link, **linkptr;
1526         va_list params;
1527         int i, totin, totout;
1528
1529         function = gpu_lookup_function(name);
1530         if (!function) {
1531                 fprintf(stderr, "GPU failed to find function %s\n", name);
1532                 return false;
1533         }
1534
1535         node = GPU_node_begin(name);
1536         totin = 0;
1537         totout = 0;
1538
1539         if (in) {
1540                 for (i = 0; in[i].type != GPU_NONE; i++) {
1541                         gpu_node_input_socket(node, &in[i]);
1542                         totin++;
1543                 }
1544         }
1545
1546         if (out) {
1547                 for (i = 0; out[i].type != GPU_NONE; i++) {
1548                         gpu_node_output(node, out[i].type, &out[i].link);
1549                         totout++;
1550                 }
1551         }
1552
1553         va_start(params, out);
1554         for (i = 0; i < function->totparam; i++) {
1555                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1556                         if (totout == 0) {
1557                                 linkptr = va_arg(params, GPUNodeLink **);
1558                                 gpu_node_output(node, function->paramtype[i], linkptr);
1559                         }
1560                         else
1561                                 totout--;
1562                 }
1563                 else {
1564                         if (totin == 0) {
1565                                 link = va_arg(params, GPUNodeLink *);
1566                                 if (link->socket)
1567                                         gpu_node_input_socket(node, link->socket);
1568                                 else
1569                                         gpu_node_input_link(node, link, function->paramtype[i]);
1570                         }
1571                         else
1572                                 totin--;
1573                 }
1574         }
1575         va_end(params);
1576
1577         gpu_material_add_node(mat, node);
1578
1579         return true;
1580 }
1581
1582 int GPU_link_changed(GPUNodeLink *link)
1583 {
1584         GPUNode *node;
1585         GPUInput *input;
1586         const char *name;
1587
1588         if (link->output) {
1589                 node = link->output->node;
1590                 name = node->name;
1591
1592                 if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) {
1593                         input = node->inputs.first;
1594                         return (input->link != NULL);
1595                 }
1596
1597                 return 1;
1598         }
1599         else
1600                 return 0;
1601 }
1602
1603 /* Pass create/free */
1604
1605 static void gpu_nodes_tag(GPUNodeLink *link)
1606 {
1607         GPUNode *node;
1608         GPUInput *input;
1609
1610         if (!link->output)
1611                 return;
1612
1613         node = link->output->node;
1614         if (node->tag)
1615                 return;
1616
1617         node->tag = true;
1618         for (input = node->inputs.first; input; input = input->next)
1619                 if (input->link)
1620                         gpu_nodes_tag(input->link);
1621 }
1622
1623 static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
1624 {
1625         GPUNode *node, *next;
1626
1627         for (node = nodes->first; node; node = node->next)
1628                 node->tag = false;
1629
1630         gpu_nodes_tag(outlink);
1631
1632         for (node = nodes->first; node; node = next) {
1633                 next = node->next;
1634
1635                 if (!node->tag) {
1636                         BLI_remlink(nodes, node);
1637                         gpu_node_free(node);
1638                 }
1639         }
1640 }
1641
1642 GPUPass *GPU_generate_pass(
1643         ListBase *nodes, GPUNodeLink *outlink,
1644         GPUVertexAttribs *attribs, int *builtins,
1645         const GPUMatType type, const char *UNUSED(name),
1646         const bool use_opensubdiv,
1647         const bool use_new_shading)
1648 {
1649         GPUShader *shader;
1650         GPUPass *pass;
1651         char *vertexcode, *geometrycode, *fragmentcode;
1652
1653 #if 0
1654         if (!FUNCTION_LIB) {
1655                 GPU_nodes_free(nodes);
1656                 return NULL;
1657         }
1658 #endif
1659
1660         /* prune unused nodes */
1661         gpu_nodes_prune(nodes, outlink);
1662
1663         gpu_nodes_get_vertex_attributes(nodes, attribs);
1664         gpu_nodes_get_builtin_flag(nodes, builtins);
1665
1666         /* generate code and compile with opengl */
1667         fragmentcode = code_generate_fragment(nodes, outlink->output);
1668         vertexcode = code_generate_vertex(nodes, type);
1669         geometrycode = code_generate_geometry(nodes, use_opensubdiv);
1670
1671         int flags = GPU_SHADER_FLAGS_NONE;
1672         if (use_opensubdiv) {
1673                 flags |= GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV;
1674         }
1675         if (use_new_shading) {
1676                 flags |= GPU_SHADER_FLAGS_NEW_SHADING;
1677         }
1678         shader = GPU_shader_create_ex(vertexcode,
1679                                       fragmentcode,
1680                                       geometrycode,
1681                                       glsl_material_library,
1682                                       NULL,
1683                                       0,
1684                                       0,
1685                                       0,
1686                                       flags);
1687
1688         /* failed? */
1689         if (!shader) {
1690                 if (fragmentcode)
1691                         MEM_freeN(fragmentcode);
1692                 if (vertexcode)
1693                         MEM_freeN(vertexcode);
1694                 memset(attribs, 0, sizeof(*attribs));
1695                 memset(builtins, 0, sizeof(*builtins));
1696                 gpu_nodes_free(nodes);
1697                 return NULL;
1698         }
1699
1700         /* create pass */
1701         pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
1702
1703         pass->output = outlink->output;
1704         pass->shader = shader;
1705         pass->fragmentcode = fragmentcode;
1706         pass->geometrycode = geometrycode;
1707         pass->vertexcode = vertexcode;
1708         pass->libcode = glsl_material_library;
1709
1710         /* extract dynamic inputs and throw away nodes */
1711         gpu_nodes_extract_dynamic_inputs(pass, nodes);
1712         gpu_nodes_free(nodes);
1713
1714         return pass;
1715 }
1716
1717 void GPU_pass_free(GPUPass *pass)
1718 {
1719         GPU_shader_free(pass->shader);
1720         gpu_inputs_free(&pass->inputs);
1721         if (pass->fragmentcode)
1722                 MEM_freeN(pass->fragmentcode);
1723         if (pass->geometrycode)
1724                 MEM_freeN(pass->geometrycode);
1725         if (pass->vertexcode)
1726                 MEM_freeN(pass->vertexcode);
1727         MEM_freeN(pass);
1728 }
1729
1730 void GPU_pass_free_nodes(ListBase *nodes)
1731 {
1732         gpu_nodes_free(nodes);
1733 }