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