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