--debug-gpu-shader: Dump GLSL shaders to disk
[blender.git] / source / blender / gpu / intern / gpu_shader.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 #include "MEM_guardedalloc.h"
29
30 #include "BLI_utildefines.h"
31 #include "BLI_math_base.h"
32 #include "BLI_math_vector.h"
33 #include "BLI_path_util.h"
34
35 #include "BKE_appdir.h"
36 #include "BKE_global.h"
37
38 #include "GPU_compositing.h"
39 #include "GPU_debug.h"
40 #include "GPU_extensions.h"
41 #include "GPU_glew.h"
42 #include "GPU_shader.h"
43 #include "GPU_texture.h"
44 #include "GPU_material.h"
45
46 /* TODO(sergey): Find better default values for this constants. */
47 #define MAX_DEFINE_LENGTH 1024
48 #define MAX_EXT_DEFINE_LENGTH 1024
49
50 /* Non-generated shaders */
51 extern char datatoc_gpu_shader_fire_frag_glsl[];
52 extern char datatoc_gpu_shader_smoke_vert_glsl[];
53 extern char datatoc_gpu_shader_smoke_frag_glsl[];
54 extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
55 extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
56 extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
57 extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
58 extern char datatoc_gpu_shader_fx_vert_glsl[];
59 extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
60 extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
61 extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
62 extern char datatoc_gpu_shader_fx_dof_hq_frag_glsl[];
63 extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[];
64 extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
65 extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
66 extern char datatoc_gpu_shader_fx_lib_glsl[];
67
68 static struct GPUShadersGlobal {
69         struct {
70                 GPUShader *vsm_store;
71                 GPUShader *sep_gaussian_blur;
72                 GPUShader *smoke;
73                 GPUShader *smoke_fire;
74                 GPUShader *smoke_coba;
75                 /* cache for shader fx. Those can exist in combinations so store them here */
76                 GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
77         } shaders;
78 } GG = {{NULL}};
79
80 /* GPUShader */
81
82 struct GPUShader {
83         GLuint program;  /* handle for full program (links shader stages below) */
84
85         GLuint vertex;   /* handle for vertex shader */
86         GLuint geometry; /* handle for geometry shader */
87         GLuint fragment; /* handle for fragment shader */
88
89         int totattrib;   /* total number of attributes */
90         int uniforms;    /* required uniforms */
91
92         void *uniform_interface; /* cached uniform interface for shader. Data depends on shader */
93 };
94
95 static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
96 {
97         int i;
98         int line = 1;
99
100         fprintf(stderr, "GPUShader: %s error:\n", task);
101
102         for (i = 0; i < totcode; i++) {
103                 const char *c, *pos, *end = code[i] + strlen(code[i]);
104
105                 if (G.debug & G_DEBUG) {
106                         fprintf(stderr, "===== shader string %d ====\n", i + 1);
107
108                         c = code[i];
109                         while ((c < end) && (pos = strchr(c, '\n'))) {
110                                 fprintf(stderr, "%2d  ", line);
111                                 fwrite(c, (pos + 1) - c, 1, stderr);
112                                 c = pos + 1;
113                                 line++;
114                         }
115                         
116                         fprintf(stderr, "%s", c);
117                 }
118         }
119         
120         fprintf(stderr, "%s\n", log);
121 }
122
123 static const char *gpu_shader_version(void)
124 {
125         if (GLEW_VERSION_3_2) {
126                 if (GLEW_ARB_compatibility) {
127                         return "#version 150 compatibility\n";
128                         /* highest version that is widely supported
129                          * gives us native geometry shaders!
130                          * use compatibility profile so we can continue using builtin shader input/output names
131                          */
132                 }
133                 else {
134                         return "#version 130\n";
135                         /* latest version that is compatible with existing shaders */
136                 }
137         }
138         else if (GLEW_VERSION_3_1) {
139                 if (GLEW_ARB_compatibility) {
140                         return "#version 140\n";
141                         /* also need the ARB_compatibility extension, handled below */
142                 }
143                 else {
144                         return "#version 130\n";
145                         /* latest version that is compatible with existing shaders */
146                 }
147         }
148         else if (GLEW_VERSION_3_0) {
149                 return "#version 130\n";
150                 /* GLSL 1.3 has modern syntax/keywords/datatypes so use if available
151                  * older features are deprecated but still available without compatibility extension or profile
152                  */
153         }
154         else {
155                 return "#version 120\n";
156                 /* minimum supported */
157         }
158 }
159
160
161 static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH], bool use_geometry_shader)
162 {
163         /* enable extensions for features that are not part of our base GLSL version
164          * don't use an extension for something already available!
165          */
166
167         if (GLEW_ARB_texture_query_lod) {
168                 /* a #version 400 feature, but we use #version 150 maximum so use extension */
169                 strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
170         }
171
172         if (use_geometry_shader && GPU_geometry_shader_support_via_extension()) {
173                 strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
174         }
175
176         if (GLEW_VERSION_3_1 && !GLEW_VERSION_3_2 && GLEW_ARB_compatibility) {
177                 strcat(defines, "#extension GL_ARB_compatibility: enable\n");
178         }
179
180         if (!GLEW_VERSION_3_1) {
181                 if (GLEW_ARB_draw_instanced) {
182                         strcat(defines, "#extension GL_ARB_draw_instanced: enable\n");
183                 }
184
185                 if (!GLEW_VERSION_3_0 && GLEW_EXT_gpu_shader4) {
186                         strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n");
187                         /* TODO: maybe require this? shaders become so much nicer */
188                 }
189         }
190 }
191
192 static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH],
193                                         bool use_opensubdiv,
194                                         bool use_new_shading)
195 {
196         /* some useful defines to detect GPU type */
197         if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
198                 strcat(defines, "#define GPU_ATI\n");
199                 if (GLEW_VERSION_3_0) {
200                         /* TODO(merwin): revisit this version check; GLEW_VERSION_3_0 means GL 3.0 or newer */
201                         strcat(defines, "#define CLIP_WORKAROUND\n");
202                 }
203         }
204         else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
205                 strcat(defines, "#define GPU_NVIDIA\n");
206         else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
207                 strcat(defines, "#define GPU_INTEL\n");
208
209         if (GPU_bicubic_bump_support())
210                 strcat(defines, "#define BUMP_BICUBIC\n");
211
212         if (GLEW_VERSION_3_0) {
213                 strcat(defines, "#define BIT_OPERATIONS\n");
214         }
215
216 #ifdef WITH_OPENSUBDIV
217         /* TODO(sergey): Check whether we actually compiling shader for
218          * the OpenSubdiv mesh.
219          */
220         if (use_opensubdiv) {
221                 strcat(defines, "#define USE_OPENSUBDIV\n");
222
223                 /* TODO(sergey): not strictly speaking a define, but this is
224                  * a global typedef which we don't have better place to define
225                  * in yet.
226                  */
227                 strcat(defines, "struct VertexData {\n"
228                                 "  vec4 position;\n"
229                                 "  vec3 normal;\n"
230                                 "  vec2 uv;"
231                                 "};\n");
232         }
233 #else
234         UNUSED_VARS(use_opensubdiv);
235 #endif
236
237         if (use_new_shading) {
238                 strcat(defines, "#define USE_NEW_SHADING\n");
239         }
240
241         return;
242 }
243
244 GPUShader *GPU_shader_create(const char *vertexcode,
245                              const char *fragcode,
246                              const char *geocode,
247                              const char *libcode,
248                              const char *defines,
249                              int input,
250                              int output,
251                              int number)
252 {
253         return GPU_shader_create_ex(vertexcode,
254                                     fragcode,
255                                     geocode,
256                                     libcode,
257                                     defines,
258                                     input,
259                                     output,
260                                     number,
261                                     GPU_SHADER_FLAGS_NONE);
262 }
263
264 #define DEBUG_SHADER_NONE ""
265 #define DEBUG_SHADER_VERTEX "vert"
266 #define DEBUG_SHADER_FRAGMENT "frag"
267 #define DEBUG_SHADER_GEOMETRY "geom"
268
269 /**
270  * Dump GLSL shaders to disk
271  *
272  * This is used for profiling shader performance externally and debug if shader code is correct.
273  * If called with no code, it simply bumps the shader index, so different shaders for the same
274  * program share the same index.
275  */
276 static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
277 {
278         if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
279                 return;
280         }
281
282         /* We use the same shader index for shaders in the same program.
283          * So we call this function once before calling for the invidual shaders. */
284         static int shader_index = 0;
285         if (code == NULL) {
286                 shader_index++;
287                 BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
288                 return;
289         }
290
291         /* Determine the full path of the new shader. */
292         char shader_path[FILE_MAX];
293
294         char file_name[512] = {'\0'};
295         sprintf(file_name, "%04d.%s", shader_index, extension);
296
297         BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
298
299         /* Write shader to disk. */
300         FILE *f = fopen(shader_path, "w");
301         if (f == NULL) {
302                 printf("Error writing to file: %s\n", shader_path);
303         }
304         for (int j = 0; j < num_shaders; j++) {
305                 fprintf(f, "%s", code[j]);
306         }
307         fclose(f);
308         printf("Shader file written to disk: %s\n", shader_path);
309 }
310
311 GPUShader *GPU_shader_create_ex(const char *vertexcode,
312                                 const char *fragcode,
313                                 const char *geocode,
314                                 const char *libcode,
315                                 const char *defines,
316                                 int input,
317                                 int output,
318                                 int number,
319                                 const int flags)
320 {
321 #ifdef WITH_OPENSUBDIV
322         /* TODO(sergey): used to add #version 150 to the geometry shader.
323          * Could safely be renamed to "use_geometry_code" since it's very
324          * likely any of geometry code will want to use GLSL 1.5.
325          */
326         bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0;
327 #else
328         UNUSED_VARS(flags);
329         bool use_opensubdiv = false;
330 #endif
331         GLint status;
332         GLchar log[5000];
333         GLsizei length = 0;
334         GPUShader *shader;
335         char standard_defines[MAX_DEFINE_LENGTH] = "";
336         char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
337
338         if (geocode && !GPU_geometry_shader_support())
339                 return NULL;
340
341         shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
342         gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
343
344         if (vertexcode)
345                 shader->vertex = glCreateShader(GL_VERTEX_SHADER);
346         if (fragcode)
347                 shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
348         if (geocode)
349                 shader->geometry = glCreateShader(GL_GEOMETRY_SHADER_EXT);
350
351         shader->program = glCreateProgram();
352
353         if (!shader->program ||
354             (vertexcode && !shader->vertex) ||
355             (fragcode && !shader->fragment) ||
356             (geocode && !shader->geometry))
357         {
358                 fprintf(stderr, "GPUShader, object creation failed.\n");
359                 GPU_shader_free(shader);
360                 return NULL;
361         }
362
363         gpu_shader_standard_defines(standard_defines,
364                                     use_opensubdiv,
365                                     (flags & GPU_SHADER_FLAGS_NEW_SHADING) != 0);
366         gpu_shader_standard_extensions(standard_extensions, geocode != NULL);
367
368         if (vertexcode) {
369                 const char *source[5];
370                 /* custom limit, may be too small, beware */
371                 int num_source = 0;
372
373                 source[num_source++] = gpu_shader_version();
374                 source[num_source++] = standard_extensions;
375                 source[num_source++] = standard_defines;
376
377                 if (defines) source[num_source++] = defines;
378                 source[num_source++] = vertexcode;
379
380                 gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
381
382                 glAttachShader(shader->program, shader->vertex);
383                 glShaderSource(shader->vertex, num_source, source, NULL);
384
385                 glCompileShader(shader->vertex);
386                 glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
387
388                 if (!status) {
389                         glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
390                         shader_print_errors("compile", log, source, num_source);
391
392                         GPU_shader_free(shader);
393                         return NULL;
394                 }
395         }
396
397         if (fragcode) {
398                 const char *source[7];
399                 int num_source = 0;
400
401                 source[num_source++] = gpu_shader_version();
402                 source[num_source++] = standard_extensions;
403                 source[num_source++] = standard_defines;
404
405 #ifdef WITH_OPENSUBDIV
406                 /* TODO(sergey): Move to fragment shader source code generation. */
407                 if (use_opensubdiv) {
408                         source[num_source++] =
409                                 "#ifdef USE_OPENSUBDIV\n"
410                                 "in block {\n"
411                                 "       VertexData v;\n"
412                                 "} inpt;\n"
413                                 "#endif\n";
414                 }
415 #endif
416
417                 if (defines) source[num_source++] = defines;
418                 if (libcode) source[num_source++] = libcode;
419                 source[num_source++] = fragcode;
420
421                 gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
422
423                 glAttachShader(shader->program, shader->fragment);
424                 glShaderSource(shader->fragment, num_source, source, NULL);
425
426                 glCompileShader(shader->fragment);
427                 glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
428
429                 if (!status) {
430                         glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
431                         shader_print_errors("compile", log, source, num_source);
432
433                         GPU_shader_free(shader);
434                         return NULL;
435                 }
436         }
437
438         if (geocode) {
439                 const char *source[6];
440                 int num_source = 0;
441
442                 source[num_source++] = gpu_shader_version();
443                 source[num_source++] = standard_extensions;
444                 source[num_source++] = standard_defines;
445
446                 if (defines) source[num_source++] = defines;
447                 source[num_source++] = geocode;
448
449                 gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
450
451                 glAttachShader(shader->program, shader->geometry);
452                 glShaderSource(shader->geometry, num_source, source, NULL);
453
454                 glCompileShader(shader->geometry);
455                 glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
456
457                 if (!status) {
458                         glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
459                         shader_print_errors("compile", log, source, num_source);
460
461                         GPU_shader_free(shader);
462                         return NULL;
463                 }
464                 
465                 if (!use_opensubdiv) {
466                         GPU_shader_geometry_stage_primitive_io(shader, input, output, number);
467                 }
468         }
469
470 #ifdef WITH_OPENSUBDIV
471         if (use_opensubdiv) {
472                 glBindAttribLocation(shader->program, 0, "position");
473                 glBindAttribLocation(shader->program, 1, "normal");
474                 GPU_shader_geometry_stage_primitive_io(shader,
475                                                        GL_LINES_ADJACENCY_EXT,
476                                                        GL_TRIANGLE_STRIP,
477                                                        4);
478         }
479 #endif
480
481         glLinkProgram(shader->program);
482         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
483         if (!status) {
484                 glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
485                 /* print attached shaders in pipeline order */
486                 if (vertexcode) shader_print_errors("linking", log, &vertexcode, 1);
487                 if (geocode) shader_print_errors("linking", log, &geocode, 1);
488                 if (libcode) shader_print_errors("linking", log, &libcode, 1);
489                 if (fragcode) shader_print_errors("linking", log, &fragcode, 1);
490
491                 GPU_shader_free(shader);
492                 return NULL;
493         }
494
495 #ifdef WITH_OPENSUBDIV
496         /* TODO(sergey): Find a better place for this. */
497         if (use_opensubdiv && GLEW_VERSION_4_1) {
498                 glProgramUniform1i(shader->program,
499                                    glGetUniformLocation(shader->program, "FVarDataOffsetBuffer"),
500                                    30);  /* GL_TEXTURE30 */
501
502                 glProgramUniform1i(shader->program,
503                                    glGetUniformLocation(shader->program, "FVarDataBuffer"),
504                                    31);  /* GL_TEXTURE31 */
505         }
506 #endif
507
508         return shader;
509 }
510
511 #undef DEBUG_SHADER_GEOMETRY
512 #undef DEBUG_SHADER_FRAGMENT
513 #undef DEBUG_SHADER_VERTEX
514 #undef DEBUG_SHADER_NONE
515
516 void GPU_shader_bind(GPUShader *shader)
517 {
518         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
519         glUseProgram(shader->program);
520         GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
521 }
522
523 void GPU_shader_unbind(void)
524 {
525         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
526         glUseProgram(0);
527         GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
528 }
529
530 void GPU_shader_free(GPUShader *shader)
531 {
532         if (shader->vertex)
533                 glDeleteShader(shader->vertex);
534         if (shader->geometry)
535                 glDeleteShader(shader->geometry);
536         if (shader->fragment)
537                 glDeleteShader(shader->fragment);
538         if (shader->program)
539                 glDeleteProgram(shader->program);
540
541         if (shader->uniform_interface)
542                 MEM_freeN(shader->uniform_interface);
543
544         MEM_freeN(shader);
545 }
546
547 int GPU_shader_get_uniform(GPUShader *shader, const char *name)
548 {
549         return glGetUniformLocation(shader->program, name);
550 }
551
552 void *GPU_shader_get_interface(GPUShader *shader)
553 {
554         return shader->uniform_interface;
555 }
556
557 void GPU_shader_set_interface(GPUShader *shader, void *interface)
558 {
559         shader->uniform_interface = interface;
560 }
561
562 void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
563 {
564         if (location == -1 || value == NULL)
565                 return;
566
567         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
568
569         if (length == 1) glUniform1fv(location, arraysize, value);
570         else if (length == 2) glUniform2fv(location, arraysize, value);
571         else if (length == 3) glUniform3fv(location, arraysize, value);
572         else if (length == 4) glUniform4fv(location, arraysize, value);
573         else if (length == 9) glUniformMatrix3fv(location, arraysize, 0, value);
574         else if (length == 16) glUniformMatrix4fv(location, arraysize, 0, value);
575
576         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
577 }
578
579 void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
580 {
581         if (location == -1)
582                 return;
583
584         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
585
586         if (length == 1) glUniform1iv(location, arraysize, value);
587         else if (length == 2) glUniform2iv(location, arraysize, value);
588         else if (length == 3) glUniform3iv(location, arraysize, value);
589         else if (length == 4) glUniform4iv(location, arraysize, value);
590
591         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
592 }
593
594 void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
595 {
596         if (location == -1)
597                 return;
598
599         GPU_CHECK_ERRORS_AROUND(glUniform1i(location, value));
600 }
601
602 void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
603 {
604         if (GPU_geometry_shader_support_via_extension()) {
605                 /* geometry shaders must provide this info themselves for #version 150 and up */
606                 glProgramParameteriEXT(shader->program, GL_GEOMETRY_INPUT_TYPE_EXT, input);
607                 glProgramParameteriEXT(shader->program, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
608                 glProgramParameteriEXT(shader->program, GL_GEOMETRY_VERTICES_OUT_EXT, number);
609         }
610 }
611
612 void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
613 {
614         GLenum arbnumber;
615         int number = GPU_texture_bound_number(tex);
616         int bindcode = GPU_texture_opengl_bindcode(tex);
617         int target = GPU_texture_target(tex);
618
619         if (number >= GPU_max_textures()) {
620                 fprintf(stderr, "Not enough texture slots.\n");
621                 return;
622         }
623                 
624         if (number == -1)
625                 return;
626
627         if (location == -1)
628                 return;
629
630         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
631
632         arbnumber = (GLenum)((GLuint)GL_TEXTURE0 + number);
633
634         if (number != 0) glActiveTexture(arbnumber);
635         if (bindcode != 0)
636                 glBindTexture(target, bindcode);
637         else
638                 GPU_invalid_tex_bind(target);
639         glUniform1i(location, number);
640         glEnable(target);
641         if (number != 0) glActiveTexture(GL_TEXTURE0);
642
643         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
644 }
645
646 int GPU_shader_get_attribute(GPUShader *shader, const char *name)
647 {
648         int index;
649         
650         GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocation(shader->program, name));
651
652         return index;
653 }
654
655 GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
656 {
657         GPUShader *retval = NULL;
658
659         switch (shader) {
660                 case GPU_SHADER_VSM_STORE:
661                         if (!GG.shaders.vsm_store)
662                                 GG.shaders.vsm_store = GPU_shader_create(
663                                         datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl,
664                                         NULL, NULL, NULL, 0, 0, 0);
665                         retval = GG.shaders.vsm_store;
666                         break;
667                 case GPU_SHADER_SEP_GAUSSIAN_BLUR:
668                         if (!GG.shaders.sep_gaussian_blur)
669                                 GG.shaders.sep_gaussian_blur = GPU_shader_create(
670                                         datatoc_gpu_shader_sep_gaussian_blur_vert_glsl,
671                                         datatoc_gpu_shader_sep_gaussian_blur_frag_glsl,
672                                         NULL, NULL, NULL, 0, 0, 0);
673                         retval = GG.shaders.sep_gaussian_blur;
674                         break;
675                 case GPU_SHADER_SMOKE:
676                         if (!GG.shaders.smoke)
677                                 GG.shaders.smoke = GPU_shader_create(
678                                         datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
679                                         NULL, NULL, NULL, 0, 0, 0);
680                         retval = GG.shaders.smoke;
681                         break;
682                 case GPU_SHADER_SMOKE_FIRE:
683                         if (!GG.shaders.smoke_fire)
684                                 GG.shaders.smoke_fire = GPU_shader_create(
685                                         datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_fire_frag_glsl,
686                                         NULL, NULL, NULL, 0, 0, 0);
687                         retval = GG.shaders.smoke_fire;
688                         break;
689                 case GPU_SHADER_SMOKE_COBA:
690                         if (!GG.shaders.smoke_coba)
691                                 GG.shaders.smoke_coba = GPU_shader_create(
692                                         datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
693                                         NULL, NULL, "#define USE_COBA;\n", 0, 0, 0);
694                         retval = GG.shaders.smoke_coba;
695                         break;
696         }
697
698         if (retval == NULL)
699                 printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
700
701         return retval;
702 }
703
704 #define MAX_DEFINES 100
705
706 GPUShader *GPU_shader_get_builtin_fx_shader(int effect, bool persp)
707 {
708         int offset;
709         char defines[MAX_DEFINES] = "";
710         /* avoid shaders out of range */
711         if (effect >= MAX_FX_SHADERS)
712                 return NULL;
713
714         offset = 2 * effect;
715
716         if (persp) {
717                 offset += 1;
718                 strcat(defines, "#define PERSP_MATRIX\n");
719         }
720
721         if (!GG.shaders.fx_shaders[offset]) {
722                 GPUShader *shader = NULL;
723
724                 switch (effect) {
725                         case GPU_SHADER_FX_SSAO:
726                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
727                                 break;
728
729                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
730                                 strcat(defines, "#define FIRST_PASS\n");
731                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
732                                 break;
733
734                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
735                                 strcat(defines, "#define SECOND_PASS\n");
736                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
737                                 break;
738
739                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
740                                 strcat(defines, "#define THIRD_PASS\n");
741                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
742                                 break;
743
744                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
745                                 strcat(defines, "#define FOURTH_PASS\n");
746                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
747                                 break;
748
749                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
750                                 strcat(defines, "#define FIFTH_PASS\n");
751                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
752                                 break;
753
754                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE:
755                                 strcat(defines, "#define FIRST_PASS\n");
756                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
757                                 break;
758
759                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO:
760                                 strcat(defines, "#define SECOND_PASS\n");
761                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl,
762                                                            defines, GL_POINTS, GL_TRIANGLE_STRIP, 4);
763                                 break;
764
765                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE:
766                                 strcat(defines, "#define THIRD_PASS\n");
767                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0);
768                                 break;
769
770                         case GPU_SHADER_FX_DEPTH_RESOLVE:
771                                 shader = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
772                                 break;
773                 }
774
775                 GG.shaders.fx_shaders[offset] = shader;
776                 GPU_fx_shader_init_interface(shader, effect);
777         }
778
779         return GG.shaders.fx_shaders[offset];
780 }
781
782
783 void GPU_shader_free_builtin_shaders(void)
784 {
785         int i;
786
787         if (GG.shaders.vsm_store) {
788                 GPU_shader_free(GG.shaders.vsm_store);
789                 GG.shaders.vsm_store = NULL;
790         }
791
792         if (GG.shaders.sep_gaussian_blur) {
793                 GPU_shader_free(GG.shaders.sep_gaussian_blur);
794                 GG.shaders.sep_gaussian_blur = NULL;
795         }
796
797         if (GG.shaders.smoke) {
798                 GPU_shader_free(GG.shaders.smoke);
799                 GG.shaders.smoke = NULL;
800         }
801
802         if (GG.shaders.smoke_fire) {
803                 GPU_shader_free(GG.shaders.smoke_fire);
804                 GG.shaders.smoke_fire = NULL;
805         }
806
807         if (GG.shaders.smoke_coba) {
808                 GPU_shader_free(GG.shaders.smoke_coba);
809                 GG.shaders.smoke_coba = NULL;
810         }
811
812         for (i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
813                 if (GG.shaders.fx_shaders[i]) {
814                         GPU_shader_free(GG.shaders.fx_shaders[i]);
815                         GG.shaders.fx_shaders[i] = NULL;
816                 }
817         }
818 }
819
820