Merged changes in the trunk up to revision 55700.
[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_notDone(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         if (GPU_bicubic_bump_support()) {
684                 BLI_dynstr_append(ds, "/* These are needed for high quality bump mapping */\n"
685                                 "#version 130\n"
686                                 "#extension GL_ARB_texture_query_lod: enable\n"
687                                 "#define BUMP_BICUBIC\n");
688         }
689         BLI_dynstr_append(ds, datatoc_gpu_shader_material_glsl);
690
691
692         glsl_material_library = BLI_dynstr_get_cstring(ds);
693
694         BLI_dynstr_free(ds);
695 }
696
697
698 /* GPU pass binding/unbinding */
699
700 GPUShader *GPU_pass_shader(GPUPass *pass)
701 {
702         return pass->shader;
703 }
704
705 static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
706 {
707         GPUShader *shader = pass->shader;
708         GPUNode *node;
709         GPUInput *next, *input;
710         ListBase *inputs = &pass->inputs;
711         int extract, z;
712
713         memset(inputs, 0, sizeof(*inputs));
714
715         if (!shader)
716                 return;
717
718         GPU_shader_bind(shader);
719
720         for (node=nodes->first; node; node=node->next) {
721                 z = 0;
722                 for (input=node->inputs.first; input; input=next, z++) {
723                         next = input->next;
724
725                         /* attributes don't need to be bound, they already have
726                          * an id that the drawing functions will use */
727                         if (input->source == GPU_SOURCE_ATTRIB ||
728                             input->source == GPU_SOURCE_BUILTIN)
729                         {
730                                 continue;
731                         }
732
733                         if (input->ima || input->tex || input->prv)
734                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
735                         else
736                                 BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
737
738                         /* pass non-dynamic uniforms to opengl */
739                         extract = 0;
740
741                         if (input->ima || input->tex || input->prv) {
742                                 if (input->bindtex)
743                                         extract = 1;
744                         }
745                         else if (input->dynamicvec)
746                                 extract = 1;
747
748                         if (extract)
749                                 input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
750
751                         /* extract nodes */
752                         if (extract) {
753                                 BLI_remlink(&node->inputs, input);
754                                 BLI_addtail(inputs, input);
755                         }
756                 }
757         }
758
759         GPU_shader_unbind();
760 }
761
762 void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
763 {
764         GPUInput *input;
765         GPUShader *shader = pass->shader;
766         ListBase *inputs = &pass->inputs;
767
768         if (!shader)
769                 return;
770
771         GPU_shader_bind(shader);
772
773         /* now bind the textures */
774         for (input=inputs->first; input; input=input->next) {
775                 if (input->ima)
776                         input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
777                 else if (input->prv)
778                         input->tex = GPU_texture_from_preview(input->prv, mipmap);
779
780                 if (input->tex && input->bindtex) {
781                         GPU_texture_bind(input->tex, input->texid);
782                         GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
783                 }
784                         
785         }
786 }
787
788 void GPU_pass_update_uniforms(GPUPass *pass)
789 {
790         GPUInput *input;
791         GPUShader *shader = pass->shader;
792         ListBase *inputs = &pass->inputs;
793
794         if (!shader)
795                 return;
796
797         /* pass dynamic inputs to opengl, others were removed */
798         for (input=inputs->first; input; input=input->next)
799                 if (!(input->ima || input->tex || input->prv))
800                         GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
801                                 input->dynamicvec);
802 }
803
804 void GPU_pass_unbind(GPUPass *pass)
805 {
806         GPUInput *input;
807         GPUShader *shader = pass->shader;
808         ListBase *inputs = &pass->inputs;
809
810         if (!shader)
811                 return;
812
813         for (input=inputs->first; input; input=input->next) {
814                 if (input->tex && input->bindtex)
815                         GPU_texture_unbind(input->tex);
816
817                 if (input->ima || input->prv)
818                         input->tex = NULL;
819         }
820         
821         GPU_shader_unbind();
822 }
823
824 /* Node Link Functions */
825
826 static GPUNodeLink *GPU_node_link_create(int type)
827 {
828         GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
829         link->type = type;
830         link->users++;
831
832         return link;
833 }
834
835 static void GPU_node_link_free(GPUNodeLink *link)
836 {
837         link->users--;
838
839         if (link->users < 0)
840                 fprintf(stderr, "GPU_node_link_free: negative refcount\n");
841         
842         if (link->users == 0) {
843                 if (link->output)
844                         link->output->link = NULL;
845                 MEM_freeN(link);
846         }
847 }
848
849 /* Node Functions */
850
851 static GPUNode *GPU_node_begin(const char *name)
852 {
853         GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
854
855         node->name= name;
856
857         return node;
858 }
859
860 static void GPU_node_end(GPUNode *UNUSED(node))
861 {
862         /* empty */
863 }
864
865 static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
866 {
867         GPUInput *input;
868         GPUNode *outnode;
869         const char *name;
870
871         if (link->output) {
872                 outnode = link->output->node;
873                 name = outnode->name;
874
875                 if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
876                         input = MEM_dupallocN(outnode->inputs.first);
877                         input->type = type;
878                         if (input->link)
879                                 input->link->users++;
880                         BLI_addtail(&node->inputs, input);
881                         return;
882                 }
883         }
884         
885         input = MEM_callocN(sizeof(GPUInput), "GPUInput");
886         input->node = node;
887
888         if (link->builtin) {
889                 /* builtin uniform */
890                 input->type = type;
891                 input->source = GPU_SOURCE_BUILTIN;
892                 input->builtin = link->builtin;
893
894                 MEM_freeN(link);
895         }
896         else if (link->output) {
897                 /* link to a node output */
898                 input->type = type;
899                 input->source = GPU_SOURCE_TEX_PIXEL;
900                 input->link = link;
901                 link->users++;
902         }
903         else if (link->dynamictex) {
904                 /* dynamic texture, GPUTexture is updated/deleted externally */
905                 input->type = type;
906                 input->source = GPU_SOURCE_TEX;
907
908                 input->tex = link->dynamictex;
909                 input->textarget = GL_TEXTURE_2D;
910                 input->textype = type;
911                 input->dynamictex = 1;
912                 input->dynamicdata = link->ptr2;
913                 MEM_freeN(link);
914         }
915         else if (link->texture) {
916                 /* small texture created on the fly, like for colorbands */
917                 input->type = GPU_VEC4;
918                 input->source = GPU_SOURCE_TEX;
919                 input->textype = type;
920
921                 //input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
922                 input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL);
923                 input->textarget = GL_TEXTURE_2D;
924
925                 MEM_freeN(link->ptr1);
926                 MEM_freeN(link);
927         }
928         else if (link->image) {
929                 /* blender image */
930                 input->type = GPU_VEC4;
931                 input->source = GPU_SOURCE_TEX;
932
933                 if (link->image == LINK_IMAGE_PREVIEW)
934                         input->prv = link->ptr1;
935                 else {
936                         input->ima = link->ptr1;
937                         input->iuser = link->ptr2;
938                         input->image_isdata = link->image_isdata;
939                 }
940                 input->textarget = GL_TEXTURE_2D;
941                 input->textype = GPU_TEX2D;
942                 MEM_freeN(link);
943         }
944         else if (link->attribtype) {
945                 /* vertex attribute */
946                 input->type = type;
947                 input->source = GPU_SOURCE_ATTRIB;
948
949                 input->attribtype = link->attribtype;
950                 BLI_strncpy(input->attribname, link->attribname, sizeof(input->attribname));
951                 MEM_freeN(link);
952         }
953         else {
954                 /* uniform vector */
955                 input->type = type;
956                 input->source = GPU_SOURCE_VEC_UNIFORM;
957
958                 memcpy(input->vec, link->ptr1, type*sizeof(float));
959                 if (link->dynamic) {
960                         input->dynamicvec= link->ptr1;
961                         input->dynamictype= link->dynamictype;
962                         input->dynamicdata= link->ptr2;
963                 }
964                 MEM_freeN(link);
965         }
966
967         BLI_addtail(&node->inputs, input);
968 }
969
970 static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock)
971 {
972         GPUNodeLink *link;
973
974         if (sock->link) {
975                 gpu_node_input_link(node, sock->link, sock->type);
976         }
977         else {
978                 link = GPU_node_link_create(0);
979                 link->ptr1 = sock->vec;
980                 gpu_node_input_link(node, link, sock->type);
981         }
982 }
983
984 static void GPU_node_output(GPUNode *node, int type, const char *UNUSED(name), GPUNodeLink **link)
985 {
986         GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
987
988         output->type = type;
989         output->node = node;
990
991         if (link) {
992                 *link = output->link = GPU_node_link_create(type);
993                 output->link->output = output;
994
995                 /* note: the caller owns the reference to the linkfer, GPUOutput
996                  * merely points to it, and if the node is destroyed it will
997                  * set that pointer to NULL */
998         }
999
1000         BLI_addtail(&node->outputs, output);
1001 }
1002
1003 static void GPU_inputs_free(ListBase *inputs)
1004 {
1005         GPUInput *input;
1006
1007         for (input=inputs->first; input; input=input->next) {
1008                 if (input->link)
1009                         GPU_node_link_free(input->link);
1010                 else if (input->tex && !input->dynamictex)
1011                         GPU_texture_free(input->tex);
1012         }
1013
1014         BLI_freelistN(inputs);
1015 }
1016
1017 static void GPU_node_free(GPUNode *node)
1018 {
1019         GPUOutput *output;
1020
1021         GPU_inputs_free(&node->inputs);
1022
1023         for (output=node->outputs.first; output; output=output->next)
1024                 if (output->link) {
1025                         output->link->output = NULL;
1026                         GPU_node_link_free(output->link);
1027                 }
1028
1029         BLI_freelistN(&node->outputs);
1030         MEM_freeN(node);
1031 }
1032
1033 static void GPU_nodes_free(ListBase *nodes)
1034 {
1035         GPUNode *node;
1036
1037         while (nodes->first) {
1038                 node = nodes->first;
1039                 BLI_remlink(nodes, node);
1040                 GPU_node_free(node);
1041         }
1042 }
1043
1044 /* vertex attributes */
1045
1046 static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
1047 {
1048         GPUNode *node;
1049         GPUInput *input;
1050         int a;
1051
1052         /* convert attributes requested by node inputs to an array of layers,
1053          * checking for duplicates and assigning id's starting from zero. */
1054
1055         memset(attribs, 0, sizeof(*attribs));
1056
1057         for (node=nodes->first; node; node=node->next) {
1058                 for (input=node->inputs.first; input; input=input->next) {
1059                         if (input->source == GPU_SOURCE_ATTRIB) {
1060                                 for (a=0; a<attribs->totlayer; a++) {
1061                                         if (attribs->layer[a].type == input->attribtype &&
1062                                             strcmp(attribs->layer[a].name, input->attribname) == 0)
1063                                         {
1064                                                 break;
1065                                         }
1066                                 }
1067
1068                                 if (a < GPU_MAX_ATTRIB) {
1069                                         if (a == attribs->totlayer) {
1070                                                 input->attribid = attribs->totlayer++;
1071                                                 input->attribfirst = 1;
1072
1073                                                 attribs->layer[a].type = input->attribtype;
1074                                                 attribs->layer[a].attribid = input->attribid;
1075                                                 BLI_strncpy(attribs->layer[a].name, input->attribname,
1076                                                             sizeof(attribs->layer[a].name));
1077                                         }
1078                                         else {
1079                                                 input->attribid = attribs->layer[a].attribid;
1080                                         }
1081                                 }
1082                         }
1083                 }
1084         }
1085 }
1086
1087 static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
1088 {
1089         GPUNode *node;
1090         GPUInput *input;
1091         
1092         *builtin= 0;
1093
1094         for (node=nodes->first; node; node=node->next)
1095                 for (input=node->inputs.first; input; input=input->next)
1096                         if (input->source == GPU_SOURCE_BUILTIN)
1097                                 *builtin |= input->builtin;
1098 }
1099
1100 /* varargs linking  */
1101
1102 GPUNodeLink *GPU_attribute(int type, const char *name)
1103 {
1104         GPUNodeLink *link = GPU_node_link_create(0);
1105
1106         link->attribtype= type;
1107         link->attribname= name;
1108
1109         return link;
1110 }
1111
1112 GPUNodeLink *GPU_uniform(float *num)
1113 {
1114         GPUNodeLink *link = GPU_node_link_create(0);
1115
1116         link->ptr1= num;
1117         link->ptr2= NULL;
1118
1119         return link;
1120 }
1121
1122 GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
1123 {
1124         GPUNodeLink *link = GPU_node_link_create(0);
1125
1126         link->ptr1= num;
1127         link->ptr2= data;
1128         link->dynamic= 1;
1129         link->dynamictype = dynamictype;
1130
1131
1132         return link;
1133 }
1134
1135 GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
1136 {
1137         GPUNodeLink *link = GPU_node_link_create(0);
1138
1139         link->image= LINK_IMAGE_BLENDER;
1140         link->ptr1= ima;
1141         link->ptr2= iuser;
1142         link->image_isdata= isdata;
1143
1144         return link;
1145 }
1146
1147 GPUNodeLink *GPU_image_preview(PreviewImage *prv)
1148 {
1149         GPUNodeLink *link = GPU_node_link_create(0);
1150         
1151         link->image= LINK_IMAGE_PREVIEW;
1152         link->ptr1= prv;
1153         
1154         return link;
1155 }
1156
1157
1158 GPUNodeLink *GPU_texture(int size, float *pixels)
1159 {
1160         GPUNodeLink *link = GPU_node_link_create(0);
1161
1162         link->texture = 1;
1163         link->texturesize = size;
1164         link->ptr1= pixels;
1165
1166         return link;
1167 }
1168
1169 GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
1170 {
1171         GPUNodeLink *link = GPU_node_link_create(0);
1172
1173         link->dynamic = 1;
1174         link->dynamictex = tex;
1175         link->dynamictype = dynamictype;
1176         link->ptr2 = data;
1177
1178         return link;
1179 }
1180
1181 GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
1182 {
1183         GPUNodeLink *link = GPU_node_link_create(0);
1184
1185         link->builtin= builtin;
1186
1187         return link;
1188 }
1189
1190 int GPU_link(GPUMaterial *mat, const char *name, ...)
1191 {
1192         GPUNode *node;
1193         GPUFunction *function;
1194         GPUNodeLink *link, **linkptr;
1195         va_list params;
1196         int i;
1197
1198         function = GPU_lookup_function(name);
1199         if (!function) {
1200                 fprintf(stderr, "GPU failed to find function %s\n", name);
1201                 return 0;
1202         }
1203
1204         node = GPU_node_begin(name);
1205
1206         va_start(params, name);
1207         for (i=0; i<function->totparam; i++) {
1208                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1209                         linkptr= va_arg(params, GPUNodeLink**);
1210                         GPU_node_output(node, function->paramtype[i], "", linkptr);
1211                 }
1212                 else {
1213                         link= va_arg(params, GPUNodeLink*);
1214                         gpu_node_input_link(node, link, function->paramtype[i]);
1215                 }
1216         }
1217         va_end(params);
1218
1219         GPU_node_end(node);
1220
1221         gpu_material_add_node(mat, node);
1222
1223         return 1;
1224 }
1225
1226 int GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNodeStack *out, ...)
1227 {
1228         GPUNode *node;
1229         GPUFunction *function;
1230         GPUNodeLink *link, **linkptr;
1231         va_list params;
1232         int i, totin, totout;
1233
1234         function = GPU_lookup_function(name);
1235         if (!function) {
1236                 fprintf(stderr, "GPU failed to find function %s\n", name);
1237                 return 0;
1238         }
1239
1240         node = GPU_node_begin(name);
1241         totin = 0;
1242         totout = 0;
1243
1244         if (in) {
1245                 for (i = 0; in[i].type != GPU_NONE; i++) {
1246                         gpu_node_input_socket(node, &in[i]);
1247                         totin++;
1248                 }
1249         }
1250         
1251         if (out) {
1252                 for (i = 0; out[i].type != GPU_NONE; i++) {
1253                         GPU_node_output(node, out[i].type, out[i].name, &out[i].link);
1254                         totout++;
1255                 }
1256         }
1257
1258         va_start(params, out);
1259         for (i=0; i<function->totparam; i++) {
1260                 if (function->paramqual[i] != FUNCTION_QUAL_IN) {
1261                         if (totout == 0) {
1262                                 linkptr= va_arg(params, GPUNodeLink**);
1263                                 GPU_node_output(node, function->paramtype[i], "", linkptr);
1264                         }
1265                         else
1266                                 totout--;
1267                 }
1268                 else {
1269                         if (totin == 0) {
1270                                 link= va_arg(params, GPUNodeLink*);
1271                                 if (link->socket)
1272                                         gpu_node_input_socket(node, link->socket);
1273                                 else
1274                                         gpu_node_input_link(node, link, function->paramtype[i]);
1275                         }
1276                         else
1277                                 totin--;
1278                 }
1279         }
1280         va_end(params);
1281
1282         GPU_node_end(node);
1283
1284         gpu_material_add_node(mat, node);
1285         
1286         return 1;
1287 }
1288
1289 int GPU_link_changed(GPUNodeLink *link)
1290 {
1291         GPUNode *node;
1292         GPUInput *input;
1293         const char *name;
1294
1295         if (link->output) {
1296                 node = link->output->node;
1297                 name = node->name;
1298
1299                 if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
1300                         input = node->inputs.first;
1301                         return (input->link != NULL);
1302                 }
1303
1304                 return 1;
1305         }
1306         else
1307                 return 0;
1308 }
1309
1310 /* Pass create/free */
1311
1312 static void gpu_nodes_tag(GPUNodeLink *link)
1313 {
1314         GPUNode *node;
1315         GPUInput *input;
1316
1317         if (!link->output)
1318                 return;
1319
1320         node = link->output->node;
1321         if (node->tag)
1322                 return;
1323         
1324         node->tag= 1;
1325         for (input=node->inputs.first; input; input=input->next)
1326                 if (input->link)
1327                         gpu_nodes_tag(input->link);
1328 }
1329
1330 static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
1331 {
1332         GPUNode *node, *next;
1333
1334         for (node=nodes->first; node; node=node->next)
1335                 node->tag= 0;
1336
1337         gpu_nodes_tag(outlink);
1338
1339         for (node=nodes->first; node; node=next) {
1340                 next = node->next;
1341
1342                 if (!node->tag) {
1343                         BLI_remlink(nodes, node);
1344                         GPU_node_free(node);
1345                 }
1346         }
1347 }
1348
1349 GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
1350 {
1351         GPUShader *shader;
1352         GPUPass *pass;
1353         char *vertexcode, *fragmentcode;
1354
1355         /*if (!FUNCTION_LIB) {
1356                 GPU_nodes_free(nodes);
1357                 return NULL;
1358         }*/
1359
1360         /* prune unused nodes */
1361         gpu_nodes_prune(nodes, outlink);
1362
1363         gpu_nodes_get_vertex_attributes(nodes, attribs);
1364         gpu_nodes_get_builtin_flag(nodes, builtins);
1365
1366         /* generate code and compile with opengl */
1367         fragmentcode = code_generate_fragment(nodes, outlink->output, name);
1368         vertexcode = code_generate_vertex(nodes);
1369         shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library, NULL);
1370
1371         /* failed? */
1372         if (!shader) {
1373                 memset(attribs, 0, sizeof(*attribs));
1374                 memset(builtins, 0, sizeof(*builtins));
1375                 GPU_nodes_free(nodes);
1376                 return NULL;
1377         }
1378         
1379         /* create pass */
1380         pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
1381
1382         pass->output = outlink->output;
1383         pass->shader = shader;
1384         pass->fragmentcode = fragmentcode;
1385         pass->vertexcode = vertexcode;
1386         pass->libcode = glsl_material_library;
1387
1388         /* extract dynamic inputs and throw away nodes */
1389         GPU_nodes_extract_dynamic_inputs(pass, nodes);
1390         GPU_nodes_free(nodes);
1391
1392         return pass;
1393 }
1394
1395 void GPU_pass_free(GPUPass *pass)
1396 {
1397         GPU_shader_free(pass->shader);
1398         GPU_inputs_free(&pass->inputs);
1399         if (pass->fragmentcode)
1400                 MEM_freeN(pass->fragmentcode);
1401         if (pass->vertexcode)
1402                 MEM_freeN(pass->vertexcode);
1403         MEM_freeN(pass);
1404 }
1405