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