Merging r46111 through r46136 from trunk into soc-2011-tomato
[blender-staging.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_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "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_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "codegen_set_unique_ids1 gh");
379         definehash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "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                                 if (input->link) {
392                                         /* input is texture from buffer, assign only one texid per
393                                          * buffer to avoid sampling the same texture twice */
394                                         if (!BLI_ghash_haskey(bindhash, input->link)) {
395                                                 input->texid = texid++;
396                                                 input->bindtex = 1;
397                                                 BLI_ghash_insert(bindhash, input->link, SET_INT_IN_POINTER(input->texid));
398                                         }
399                                         else
400                                                 input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->link));
401                                 }
402                                 else if (input->ima) {
403                                         /* input is texture from image, assign only one texid per
404                                          * buffer to avoid sampling the same texture twice */
405                                         if (!BLI_ghash_haskey(bindhash, input->ima)) {
406                                                 input->texid = texid++;
407                                                 input->bindtex = 1;
408                                                 BLI_ghash_insert(bindhash, input->ima, SET_INT_IN_POINTER(input->texid));
409                                         }
410                                         else
411                                                 input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima));
412                                 }
413                                 else {
414                                         if (!BLI_ghash_haskey(bindhash, input->tex)) {
415                                                 /* input is user created texture, check tex pointer */
416                                                 input->texid = texid++;
417                                                 input->bindtex = 1;
418                                                 BLI_ghash_insert(bindhash, input->tex, SET_INT_IN_POINTER(input->texid));
419                                         }
420                                         else
421                                                 input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->tex));
422                                 }
423
424                                 /* make sure this pixel is defined exactly once */
425                                 if (input->source == GPU_SOURCE_TEX_PIXEL) {
426                                         if (input->ima) {
427                                                 if (!BLI_ghash_haskey(definehash, input->ima)) {
428                                                         input->definetex = 1;
429                                                         BLI_ghash_insert(definehash, input->ima, SET_INT_IN_POINTER(input->texid));
430                                                 }
431                                         }
432                                         else {
433                                                 if (!BLI_ghash_haskey(definehash, input->link)) {
434                                                         input->definetex = 1;
435                                                         BLI_ghash_insert(definehash, input->link, SET_INT_IN_POINTER(input->texid));
436                                                 }
437                                         }
438                                 }
439                         }
440                 }
441
442                 for (output=node->outputs.first; output; output=output->next)
443                         /* set id for unique names of tmp variables storing output */
444                         output->id = id++;
445         }
446
447         BLI_ghash_free(bindhash, NULL, NULL);
448         BLI_ghash_free(definehash, NULL, NULL);
449 }
450
451 static void codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
452 {
453         GPUNode *node;
454         GPUInput *input;
455         const char *name;
456         int builtins = 0;
457
458         /* print uniforms */
459         for (node=nodes->first; node; node=node->next) {
460                 for (input=node->inputs.first; input; input=input->next) {
461                         if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) {
462                                 /* create exactly one sampler for each texture */
463                                 if (codegen_input_has_texture(input) && input->bindtex)
464                                         BLI_dynstr_appendf(ds, "uniform %s samp%d;\n",
465                                                 (input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow",
466                                                 input->texid);
467                         }
468                         else if (input->source == GPU_SOURCE_BUILTIN) {
469                                 /* only define each builting uniform/varying once */
470                                 if (!(builtins & input->builtin)) {
471                                         builtins |= input->builtin;
472                                         name = GPU_builtin_name(input->builtin);
473
474                                         if (gpu_str_prefix(name, "unf")) {
475                                                 BLI_dynstr_appendf(ds, "uniform %s %s;\n",
476                                                         GPU_DATATYPE_STR[input->type], name);
477                                         }
478                                         else {
479                                                 BLI_dynstr_appendf(ds, "varying %s %s;\n",
480                                                         GPU_DATATYPE_STR[input->type], name);
481                                         }
482                                 }
483                         }
484                         else if (input->source == GPU_SOURCE_VEC_UNIFORM) {
485                                 if (input->dynamicvec) {
486                                         /* only create uniforms for dynamic vectors */
487                                         BLI_dynstr_appendf(ds, "uniform %s unf%d;\n",
488                                                 GPU_DATATYPE_STR[input->type], input->id);
489                                 }
490                                 else {
491                                         /* for others use const so the compiler can do folding */
492                                         BLI_dynstr_appendf(ds, "const %s cons%d = ",
493                                                 GPU_DATATYPE_STR[input->type], input->id);
494                                         codegen_print_datatype(ds, input->type, input->vec);
495                                         BLI_dynstr_append(ds, ";\n");
496                                 }
497                         }
498                         else if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
499                                 BLI_dynstr_appendf(ds, "varying %s var%d;\n",
500                                         GPU_DATATYPE_STR[input->type], input->attribid);
501                         }
502                 }
503         }
504
505         BLI_dynstr_append(ds, "\n");
506 }
507
508 static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
509 {
510         GPUNode *node;
511         GPUInput *input;
512         GPUOutput *output;
513
514         for (node=nodes->first; node; node=node->next) {
515                 /* load pixels from textures */
516                 for (input=node->inputs.first; input; input=input->next) {
517                         if (input->source == GPU_SOURCE_TEX_PIXEL) {
518                                 if (codegen_input_has_texture(input) && input->definetex) {
519                                         BLI_dynstr_appendf(ds, "\tvec4 tex%d = texture2D(", input->texid);
520                                         BLI_dynstr_appendf(ds, "samp%d, gl_TexCoord[%d].st);\n",
521                                                 input->texid, input->texid);
522                                 }
523                         }
524                 }
525
526                 /* declare temporary variables for node output storage */
527                 for (output=node->outputs.first; output; output=output->next)
528                         BLI_dynstr_appendf(ds, "\t%s tmp%d;\n",
529                                 GPU_DATATYPE_STR[output->type], output->id);
530         }
531
532         BLI_dynstr_append(ds, "\n");
533 }
534
535 static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
536 {
537         GPUNode *node;
538         GPUInput *input;
539         GPUOutput *output;
540
541         for (node=nodes->first; node; node=node->next) {
542                 BLI_dynstr_appendf(ds, "\t%s(", node->name);
543                 
544                 for (input=node->inputs.first; input; input=input->next) {
545                         if (input->source == GPU_SOURCE_TEX) {
546                                 BLI_dynstr_appendf(ds, "samp%d", input->texid);
547                                 if (input->link)
548                                         BLI_dynstr_appendf(ds, ", gl_TexCoord[%d].st", input->texid);
549                         }
550                         else if (input->source == GPU_SOURCE_TEX_PIXEL) {
551                                 codegen_convert_datatype(ds, input->link->output->type, input->type,
552                                         "tmp", input->link->output->id);
553                         }
554                         else if (input->source == GPU_SOURCE_BUILTIN)
555                                 BLI_dynstr_appendf(ds, "%s", GPU_builtin_name(input->builtin));
556                         else if (input->source == GPU_SOURCE_VEC_UNIFORM) {
557                                 if (input->dynamicvec)
558                                         BLI_dynstr_appendf(ds, "unf%d", input->id);
559                                 else
560                                         BLI_dynstr_appendf(ds, "cons%d", input->id);
561                         }
562                         else if (input->source == GPU_SOURCE_ATTRIB)
563                                 BLI_dynstr_appendf(ds, "var%d", input->attribid);
564
565                         BLI_dynstr_append(ds, ", ");
566                 }
567
568                 for (output=node->outputs.first; output; output=output->next) {
569                         BLI_dynstr_appendf(ds, "tmp%d", output->id);
570                         if (output->next)
571                                 BLI_dynstr_append(ds, ", ");
572                 }
573
574                 BLI_dynstr_append(ds, ");\n");
575         }
576
577         BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
578         codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
579         BLI_dynstr_append(ds, ";\n");
580 }
581
582 static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *UNUSED(name))
583 {
584         DynStr *ds = BLI_dynstr_new();
585         char *code;
586
587         /*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/
588
589         codegen_set_unique_ids(nodes);
590         codegen_print_uniforms_functions(ds, nodes);
591
592         //if (G.debug & G_DEBUG)
593         //      BLI_dynstr_appendf(ds, "/* %s */\n", name);
594
595         BLI_dynstr_append(ds, "void main(void)\n");
596         BLI_dynstr_append(ds, "{\n");
597
598         codegen_declare_tmps(ds, nodes);
599         codegen_call_functions(ds, nodes, output);
600
601         BLI_dynstr_append(ds, "}\n");
602
603         /* create shader */
604         code = BLI_dynstr_get_cstring(ds);
605         BLI_dynstr_free(ds);
606
607         //if (G.debug & G_DEBUG) printf("%s\n", code);
608
609         return code;
610 }
611
612 static char *code_generate_vertex(ListBase *nodes)
613 {
614         DynStr *ds = BLI_dynstr_new();
615         GPUNode *node;
616         GPUInput *input;
617         char *code;
618         
619         for (node=nodes->first; node; node=node->next) {
620                 for (input=node->inputs.first; input; input=input->next) {
621                         if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
622                                 BLI_dynstr_appendf(ds, "attribute %s att%d;\n",
623                                         GPU_DATATYPE_STR[input->type], input->attribid);
624                                 BLI_dynstr_appendf(ds, "varying %s var%d;\n",
625                                         GPU_DATATYPE_STR[input->type], input->attribid);
626                         }
627                 }
628         }
629
630         BLI_dynstr_append(ds, "\n");
631         BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl);
632
633         for (node=nodes->first; node; node=node->next)
634                 for (input=node->inputs.first; input; input=input->next)
635                         if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
636                                 if (input->attribtype == CD_TANGENT) { /* silly exception */
637                                         BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid);
638                                         BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid);
639                                 }
640                                 else
641                                         BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid);
642                         }
643
644         BLI_dynstr_append(ds, "}\n\n");
645
646         code = BLI_dynstr_get_cstring(ds);
647
648         BLI_dynstr_free(ds);
649
650         //if (G.debug & G_DEBUG) printf("%s\n", code);
651
652         return code;
653 }
654
655 int GPU_bicubic_bump_support(void)
656 {
657         return GLEW_ARB_texture_query_lod && GLEW_VERSION_3_0;
658 }
659
660 void GPU_code_generate_glsl_lib(void)
661 {
662         DynStr *ds;
663
664         /* only initialize the library once */
665         if (glsl_material_library)
666                 return;
667
668         ds = BLI_dynstr_new();
669
670         if (GPU_bicubic_bump_support()) {
671                 BLI_dynstr_append(ds, "/* These are needed for high quality bump mapping */\n"
672                                 "#version 130\n"
673                                 "#extension GL_ARB_texture_query_lod: enable\n"
674                                 "#define BUMP_BICUBIC\n");
675         }
676         BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
677
678
679         glsl_material_library = BLI_dynstr_get_cstring(ds);
680
681         BLI_dynstr_free(ds);
682 }
683
684
685 /* GPU pass binding/unbinding */
686
687 GPUShader *GPU_pass_shader(GPUPass *pass)
688 {
689         return pass->shader;
690 }
691
692 static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
693 {
694         GPUShader *shader = pass->shader;
695         GPUNode *node;
696         GPUInput *next, *input;
697         ListBase *inputs = &pass->inputs;
698         int extract, z;
699
700         memset(inputs, 0, sizeof(*inputs));
701
702         if (!shader)
703                 return;
704
705         GPU_shader_bind(shader);
706
707         for (node=nodes->first; node; node=node->next) {
708                 z = 0;
709                 for (input=node->inputs.first; input; input=next, z++) {
710                         next = input->next;
711
712                         /* attributes don't need to be bound, they already have
713                          * an id that the drawing functions will use */
714                         if (input->source == GPU_SOURCE_ATTRIB ||
715                             input->source == GPU_SOURCE_BUILTIN)
716                         {
717                                 continue;
718                         }
719
720                         if (input->ima || input->tex)
721                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
722                         else
723                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
724
725                         /* pass non-dynamic uniforms to opengl */
726                         extract = 0;
727
728                         if (input->ima || input->tex) {
729                                 if (input->bindtex)
730                                         extract = 1;
731                         }
732                         else if (input->dynamicvec)
733                                 extract = 1;
734
735                         if (extract)
736                                 input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
737
738                         /* extract nodes */
739                         if (extract) {
740                                 BLI_remlink(&node->inputs, input);
741                                 BLI_addtail(inputs, input);
742                         }
743                 }
744         }
745
746         GPU_shader_unbind(shader);
747 }
748
749 void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
750 {
751         GPUInput *input;
752         GPUShader *shader = pass->shader;
753         ListBase *inputs = &pass->inputs;
754
755         if (!shader)
756                 return;
757
758         GPU_shader_bind(shader);
759
760         /* now bind the textures */
761         for (input=inputs->first; input; input=input->next) {
762                 if (input->ima)
763                         input->tex = GPU_texture_from_blender(input->ima, input->iuser, time, mipmap);
764
765                 if (input->tex && input->bindtex) {
766                         GPU_texture_bind(input->tex, input->texid);
767                         GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
768                 }
769         }
770 }
771
772 void GPU_pass_update_uniforms(GPUPass *pass)
773 {
774         GPUInput *input;
775         GPUShader *shader = pass->shader;
776         ListBase *inputs = &pass->inputs;
777
778         if (!shader)
779                 return;
780
781         /* pass dynamic inputs to opengl, others were removed */
782         for (input=inputs->first; input; input=input->next)
783                 if (!(input->ima || input->tex))
784                         GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
785                                 input->dynamicvec);
786 }
787
788 void GPU_pass_unbind(GPUPass *pass)
789 {
790         GPUInput *input;
791         GPUShader *shader = pass->shader;
792         ListBase *inputs = &pass->inputs;
793
794         if (!shader)
795                 return;
796
797         for (input=inputs->first; input; input=input->next) {
798                 if (input->tex && input->bindtex)
799                         GPU_texture_unbind(input->tex);
800
801                 if (input->ima)
802                         input->tex = NULL;
803         }
804         
805         GPU_shader_unbind(shader);
806 }
807
808 /* Node Link Functions */
809
810 static GPUNodeLink *GPU_node_link_create(int type)
811 {
812         GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
813         link->type = type;
814         link->users++;
815
816         return link;
817 }
818
819 static void GPU_node_link_free(GPUNodeLink *link)
820 {
821         link->users--;
822
823         if (link->users < 0)
824                 fprintf(stderr, "GPU_node_link_free: negative refcount\n");
825         
826         if (link->users == 0) {
827                 if (link->output)
828                         link->output->link = NULL;
829                 MEM_freeN(link);
830         }
831 }
832
833 /* Node Functions */
834
835 static GPUNode *GPU_node_begin(const char *name)
836 {
837         GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
838
839         node->name= name;
840
841         return node;
842 }
843
844 static void GPU_node_end(GPUNode *UNUSED(node))
845 {
846         /* empty */
847 }
848
849 static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
850 {
851         GPUInput *input;
852         GPUNode *outnode;
853         const char *name;
854
855         if (link->output) {
856                 outnode = link->output->node;
857                 name = outnode->name;
858
859                 if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
860                         input = MEM_dupallocN(outnode->inputs.first);
861                         input->type = type;
862                         if (input->link)
863                                 input->link->users++;
864                         BLI_addtail(&node->inputs, input);
865                         return;
866                 }
867         }
868         
869         input = MEM_callocN(sizeof(GPUInput), "GPUInput");
870         input->node = node;
871
872         if (link->builtin) {
873                 /* builtin uniform */
874                 input->type = type;
875                 input->source = GPU_SOURCE_BUILTIN;
876                 input->builtin = link->builtin;
877
878                 MEM_freeN(link);
879         }
880         else if (link->output) {
881                 /* link to a node output */
882                 input->type = type;
883                 input->source = GPU_SOURCE_TEX_PIXEL;
884                 input->link = link;
885                 link->users++;
886         }
887         else if (link->dynamictex) {
888                 /* dynamic texture, GPUTexture is updated/deleted externally */
889                 input->type = type;
890                 input->source = GPU_SOURCE_TEX;
891
892                 input->tex = link->dynamictex;
893                 input->textarget = GL_TEXTURE_2D;
894                 input->textype = type;
895                 input->dynamictex = 1;
896                 input->dynamicdata = link->ptr2;
897                 MEM_freeN(link);
898         }
899         else if (link->texture) {
900                 /* small texture created on the fly, like for colorbands */
901                 input->type = GPU_VEC4;
902                 input->source = GPU_SOURCE_TEX;
903                 input->textype = type;
904
905                 //input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
906                 input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL);
907                 input->textarget = GL_TEXTURE_2D;
908
909                 MEM_freeN(link->ptr1);
910                 MEM_freeN(link);
911         }
912         else if (link->image) {
913                 /* blender image */
914                 input->type = GPU_VEC4;
915                 input->source = GPU_SOURCE_TEX;
916
917                 input->ima = link->ptr1;
918                 input->iuser = link->ptr2;
919                 input->textarget = GL_TEXTURE_2D;
920                 input->textype = GPU_TEX2D;
921                 MEM_freeN(link);
922         }
923         else if (link->attribtype) {
924                 /* vertex attribute */
925                 input->type = type;
926                 input->source = GPU_SOURCE_ATTRIB;
927
928                 input->attribtype = link->attribtype;
929                 BLI_strncpy(input->attribname, link->attribname, sizeof(input->attribname));
930                 MEM_freeN(link);
931         }
932         else {
933                 /* uniform vector */
934                 input->type = type;
935                 input->source = GPU_SOURCE_VEC_UNIFORM;
936
937                 memcpy(input->vec, link->ptr1, type*sizeof(float));
938                 if (link->dynamic) {
939                         input->dynamicvec= link->ptr1;
940                         input->dynamictype= link->dynamictype;
941                         input->dynamicdata= link->ptr2;
942                 }
943                 MEM_freeN(link);
944         }
945
946         BLI_addtail(&node->inputs, input);
947 }
948
949 static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock)
950 {
951         GPUNodeLink *link;
952
953         if (sock->link) {
954                 gpu_node_input_link(node, sock->link, sock->type);
955         }
956         else {
957                 link = GPU_node_link_create(0);
958                 link->ptr1 = sock->vec;
959                 gpu_node_input_link(node, link, sock->type);
960         }
961 }
962
963 static void GPU_node_output(GPUNode *node, int type, const char *UNUSED(name), GPUNodeLink **link)
964 {
965         GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
966
967         output->type = type;
968         output->node = node;
969
970         if (link) {
971                 *link = output->link = GPU_node_link_create(type);
972                 output->link->output = output;
973
974                 /* note: the caller owns the reference to the linkfer, GPUOutput
975                  * merely points to it, and if the node is destroyed it will
976                  * set that pointer to NULL */
977         }
978
979         BLI_addtail(&node->outputs, output);
980 }
981
982 static void GPU_inputs_free(ListBase *inputs)
983 {
984         GPUInput *input;
985
986         for (input=inputs->first; input; input=input->next) {
987                 if (input->link)
988                         GPU_node_link_free(input->link);
989                 else if (input->tex && !input->dynamictex)
990                         GPU_texture_free(input->tex);
991         }
992
993         BLI_freelistN(inputs);
994 }
995
996 static void GPU_node_free(GPUNode *node)
997 {
998         GPUOutput *output;
999
1000         GPU_inputs_free(&node->inputs);
1001
1002         for (output=node->outputs.first; output; output=output->next)
1003                 if (output->link) {
1004                         output->link->output = NULL;
1005                         GPU_node_link_free(output->link);
1006                 }
1007
1008         BLI_freelistN(&node->outputs);
1009         MEM_freeN(node);
1010 }
1011
1012 static void GPU_nodes_free(ListBase *nodes)
1013 {
1014         GPUNode *node;
1015
1016         while (nodes->first) {
1017                 node = nodes->first;
1018                 BLI_remlink(nodes, node);
1019                 GPU_node_free(node);
1020         }
1021 }
1022
1023 /* vertex attributes */
1024
1025 static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
1026 {
1027         GPUNode *node;
1028         GPUInput *input;
1029         int a;
1030
1031         /* convert attributes requested by node inputs to an array of layers,
1032          * checking for duplicates and assigning id's starting from zero. */
1033
1034         memset(attribs, 0, sizeof(*attribs));
1035
1036         for (node=nodes->first; node; node=node->next) {
1037                 for (input=node->inputs.first; input; input=input->next) {
1038                         if (input->source == GPU_SOURCE_ATTRIB) {
1039                                 for (a=0; a<attribs->totlayer; a++) {
1040                                         if (attribs->layer[a].type == input->attribtype &&
1041                                             strcmp(attribs->layer[a].name, input->attribname) == 0)
1042                                         {
1043                                                 break;
1044                                         }
1045                                 }
1046
1047                                 if (a == attribs->totlayer && a < GPU_MAX_ATTRIB) {
1048                                         input->attribid = attribs->totlayer++;
1049                                         input->attribfirst = 1;
1050
1051                                         attribs->layer[a].type = input->attribtype;
1052                                         attribs->layer[a].attribid = input->attribid;
1053                                         BLI_strncpy(attribs->layer[a].name, input->attribname,
1054                                                 sizeof(attribs->layer[a].name));
1055                                 }
1056                                 else
1057                                         input->attribid = attribs->layer[a].attribid;
1058                         }
1059                 }
1060         }
1061 }
1062
1063 static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
1064 {
1065         GPUNode *node;
1066         GPUInput *input;
1067         
1068         *builtin= 0;
1069
1070         for (node=nodes->first; node; node=node->next)
1071                 for (input=node->inputs.first; input; input=input->next)
1072                         if (input->source == GPU_SOURCE_BUILTIN)
1073                                 *builtin |= input->builtin;
1074 }
1075
1076 /* varargs linking  */
1077
1078 GPUNodeLink *GPU_attribute(int type, const char *name)
1079 {
1080         GPUNodeLink *link = GPU_node_link_create(0);
1081
1082         link->attribtype= type;
1083         link->attribname= name;
1084
1085         return link;
1086 }
1087
1088 GPUNodeLink *GPU_uniform(float *num)
1089 {
1090         GPUNodeLink *link = GPU_node_link_create(0);
1091
1092         link->ptr1= num;
1093         link->ptr2= NULL;
1094
1095         return link;
1096 }
1097
1098 GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
1099 {
1100         GPUNodeLink *link = GPU_node_link_create(0);
1101
1102         link->ptr1= num;
1103         link->ptr2= data;
1104         link->dynamic= 1;
1105         link->dynamictype = dynamictype;
1106
1107
1108         return link;
1109 }
1110
1111 GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser)
1112 {
1113         GPUNodeLink *link = GPU_node_link_create(0);
1114
1115         link->image= 1;
1116         link->ptr1= ima;
1117         link->ptr2= iuser;
1118
1119         return link;
1120 }
1121
1122 GPUNodeLink *GPU_texture(int size, float *pixels)
1123 {
1124         GPUNodeLink *link = GPU_node_link_create(0);
1125
1126         link->texture = 1;
1127         link->texturesize = size;
1128         link->ptr1= pixels;
1129
1130         return link;
1131 }
1132
1133 GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
1134 {
1135         GPUNodeLink *link = GPU_node_link_create(0);
1136
1137         link->dynamic = 1;
1138         link->dynamictex = tex;
1139         link->dynamictype = dynamictype;
1140         link->ptr2 = data;
1141
1142         return link;
1143 }
1144
1145 GPUNodeLink *GPU_socket(GPUNodeStack *sock)
1146 {
1147         GPUNodeLink *link = GPU_node_link_create(0);
1148
1149         link->socket= sock;
1150
1151         return link;
1152 }
1153
1154 GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
1155 {
1156         GPUNodeLink *link = GPU_node_link_create(0);
1157
1158         link->builtin= builtin;
1159
1160         return link;
1161 }
1162
1163 int GPU_link(GPUMaterial *mat, const char *name, ...)
1164 {
1165         GPUNode *node;
1166         GPUFunction *function;
1167         GPUNodeLink *link, **linkptr;
1168         va_list params;
1169         int i;
1170
1171         function = GPU_lookup_function(name);
1172         if (!function) {
1173                 fprintf(stderr, "GPU failed to find function %s\n", name);
1174                 return 0;
1175         }
1176
1177         node = GPU_node_begin(name);
1178
1179         va_start(params, name);
1180         for (i=0; i<function->totparam; i++) {
1181                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1182                         linkptr= va_arg(params, GPUNodeLink**);
1183                         GPU_node_output(node, function->paramtype[i], "", linkptr);
1184                 }
1185                 else {
1186                         link= va_arg(params, GPUNodeLink*);
1187                         gpu_node_input_link(node, link, function->paramtype[i]);
1188                 }
1189         }
1190         va_end(params);
1191
1192         GPU_node_end(node);
1193
1194         gpu_material_add_node(mat, node);
1195
1196         return 1;
1197 }
1198
1199 int GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...)
1200 {
1201         GPUNode *node;
1202         GPUFunction *function;
1203         GPUNodeLink *link, **linkptr;
1204         va_list params;
1205         int i, totin, totout;
1206
1207         function = GPU_lookup_function(name);
1208         if (!function) {
1209                 fprintf(stderr, "GPU failed to find function %s\n", name);
1210                 return 0;
1211         }
1212
1213         node = GPU_node_begin(name);
1214         totin = 0;
1215         totout = 0;
1216
1217         if (in) {
1218                 for (i = 0; in[i].type != GPU_NONE; i++) {
1219                         gpu_node_input_socket(node, &in[i]);
1220                         totin++;
1221                 }
1222         }
1223         
1224         if (out) {
1225                 for (i = 0; out[i].type != GPU_NONE; i++) {
1226                         GPU_node_output(node, out[i].type, out[i].name, &out[i].link);
1227                         totout++;
1228                 }
1229         }
1230
1231         va_start(params, out);
1232         for (i=0; i<function->totparam; i++) {
1233                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1234                         if (totout == 0) {
1235                                 linkptr= va_arg(params, GPUNodeLink**);
1236                                 GPU_node_output(node, function->paramtype[i], "", linkptr);
1237                         }
1238                         else
1239                                 totout--;
1240                 }
1241                 else {
1242                         if (totin == 0) {
1243                                 link= va_arg(params, GPUNodeLink*);
1244                                 if (link->socket)
1245                                         gpu_node_input_socket(node, link->socket);
1246                                 else
1247                                         gpu_node_input_link(node, link, function->paramtype[i]);
1248                         }
1249                         else
1250                                 totin--;
1251                 }
1252         }
1253         va_end(params);
1254
1255         GPU_node_end(node);
1256
1257         gpu_material_add_node(mat, node);
1258         
1259         return 1;
1260 }
1261
1262 int GPU_link_changed(GPUNodeLink *link)
1263 {
1264         GPUNode *node;
1265         GPUInput *input;
1266         const char *name;
1267
1268         if (link->output) {
1269                 node = link->output->node;
1270                 name = node->name;
1271
1272                 if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
1273                         input = node->inputs.first;
1274                         return (input->link != NULL);
1275                 }
1276
1277                 return 1;
1278         }
1279         else
1280                 return 0;
1281 }
1282
1283 /* Pass create/free */
1284
1285 static void gpu_nodes_tag(GPUNodeLink *link)
1286 {
1287         GPUNode *node;
1288         GPUInput *input;
1289
1290         if (!link->output)
1291                 return;
1292
1293         node = link->output->node;
1294         if (node->tag)
1295                 return;
1296         
1297         node->tag= 1;
1298         for (input=node->inputs.first; input; input=input->next)
1299                 if (input->link)
1300                         gpu_nodes_tag(input->link);
1301 }
1302
1303 static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
1304 {
1305         GPUNode *node, *next;
1306
1307         for (node=nodes->first; node; node=node->next)
1308                 node->tag= 0;
1309
1310         gpu_nodes_tag(outlink);
1311
1312         for (node=nodes->first; node; node=next) {
1313                 next = node->next;
1314
1315                 if (!node->tag) {
1316                         BLI_remlink(nodes, node);
1317                         GPU_node_free(node);
1318                 }
1319         }
1320 }
1321
1322 GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
1323 {
1324         GPUShader *shader;
1325         GPUPass *pass;
1326         char *vertexcode, *fragmentcode;
1327
1328         /*if (!FUNCTION_LIB) {
1329                 GPU_nodes_free(nodes);
1330                 return NULL;
1331         }*/
1332
1333         /* prune unused nodes */
1334         gpu_nodes_prune(nodes, outlink);
1335
1336         gpu_nodes_get_vertex_attributes(nodes, attribs);
1337         gpu_nodes_get_builtin_flag(nodes, builtins);
1338
1339         /* generate code and compile with opengl */
1340         fragmentcode = code_generate_fragment(nodes, outlink->output, name);
1341         vertexcode = code_generate_vertex(nodes);
1342         shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library); /*FUNCTION_LIB);*/
1343
1344         /* failed? */
1345         if (!shader) {
1346                 memset(attribs, 0, sizeof(*attribs));
1347                 memset(builtins, 0, sizeof(*builtins));
1348                 GPU_nodes_free(nodes);
1349                 return NULL;
1350         }
1351         
1352         /* create pass */
1353         pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
1354
1355         pass->output = outlink->output;
1356         pass->shader = shader;
1357         pass->fragmentcode = fragmentcode;
1358         pass->vertexcode = vertexcode;
1359         pass->libcode = glsl_material_library;
1360
1361         /* extract dynamic inputs and throw away nodes */
1362         GPU_nodes_extract_dynamic_inputs(pass, nodes);
1363         GPU_nodes_free(nodes);
1364
1365         return pass;
1366 }
1367
1368 void GPU_pass_free(GPUPass *pass)
1369 {
1370         GPU_shader_free(pass->shader);
1371         GPU_inputs_free(&pass->inputs);
1372         if (pass->fragmentcode)
1373                 MEM_freeN(pass->fragmentcode);
1374         if (pass->vertexcode)
1375                 MEM_freeN(pass->vertexcode);
1376         MEM_freeN(pass);
1377 }
1378