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