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