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