Cleanup: spelling
[blender-staging.git] / source / blender / gpu / intern / gpu_extensions.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_extensions.c
29  *  \ingroup gpu
30  *
31  * Wrap OpenGL features such as textures, shaders and GLSL
32  * with checks for drivers and GPU support.
33  */
34
35
36 #include "DNA_image_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_utildefines.h"
42 #include "BLI_math_base.h"
43 #include "BLI_math_vector.h"
44
45 #include "BKE_global.h"
46
47 #include "GPU_glew.h"
48 #include "GPU_debug.h"
49 #include "GPU_draw.h"
50 #include "GPU_extensions.h"
51 #include "GPU_compositing.h"
52 #include "GPU_simple_shader.h"
53
54 #include "intern/gpu_private.h"
55
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59
60 #ifdef WIN32
61 #  include "BLI_winstuff.h"
62 #endif
63
64 /* TODO(sergey): Find better default values for this constants. */
65 #define MAX_DEFINE_LENGTH 1024
66 #define MAX_EXT_DEFINE_LENGTH 1024
67
68 /* Extensions support */
69
70 /* extensions used:
71  * - texture border clamp: 1.3 core
72  * - fragment shader: 2.0 core
73  * - framebuffer object: ext specification
74  * - multitexture 1.3 core
75  * - arb non power of two: 2.0 core
76  * - pixel buffer objects? 2.1 core
77  * - arb draw buffers? 2.0 core
78  */
79
80 /* Non-generated shaders */
81 extern char datatoc_gpu_program_smoke_frag_glsl[];
82 extern char datatoc_gpu_program_smoke_color_frag_glsl[];
83 extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
84 extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
85 extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
86 extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
87 extern char datatoc_gpu_shader_fx_vert_glsl[];
88 extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
89 extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
90 extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
91 extern char datatoc_gpu_shader_fx_dof_hq_frag_glsl[];
92 extern char datatoc_gpu_shader_fx_dof_hq_vert_glsl[];
93 extern char datatoc_gpu_shader_fx_dof_hq_geo_glsl[];
94 extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
95 extern char datatoc_gpu_shader_fx_lib_glsl[];
96
97 typedef struct GPUShaders {
98         GPUShader *vsm_store;
99         GPUShader *sep_gaussian_blur;
100         GPUProgram *smoke;
101         GPUProgram *smoke_colored;
102         /* cache for shader fx. Those can exist in combinations so store them here */
103         GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
104 } GPUShaders;
105
106 static struct GPUGlobal {
107         GLint maxtexsize;
108         GLint maxtextures;
109         GLuint currentfb;
110         int glslsupport;
111         int extdisabled;
112         int colordepth;
113         int npotdisabled; /* ATI 3xx-5xx (and more) chipsets support NPoT partially (== not enough) */
114         int dlistsdisabled; /* Legacy ATI driver does not support display lists well */
115         GPUDeviceType device;
116         GPUOSType os;
117         GPUDriverType driver;
118         GPUShaders shaders;
119         GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */
120         GPUTexture *invalid_tex_2D;
121         GPUTexture *invalid_tex_3D;
122         float dfdyfactors[2]; /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers
123                                  calculate dfdy in shader differently when drawing to an offscreen buffer. First
124                                  number is factor on screen and second is off-screen */
125 } GG = {1, 0};
126
127 /* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
128 #define GPU_FB_MAX_SLOTS 4
129
130 struct GPUFrameBuffer {
131         GLuint object;
132         GPUTexture *colortex[GPU_FB_MAX_SLOTS];
133         GPUTexture *depthtex;
134 };
135
136
137 /* GPU Types */
138
139 bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
140 {
141         return (GG.device & device) && (GG.os & os) && (GG.driver & driver);
142 }
143
144 /* GPU Extensions */
145
146 void GPU_extensions_disable(void)
147 {
148         GG.extdisabled = 1;
149 }
150
151 int GPU_max_texture_size(void)
152 {
153         return GG.maxtexsize;
154 }
155
156 void GPU_get_dfdy_factors(float fac[2])
157 {
158         copy_v2_v2(fac, GG.dfdyfactors);
159 }
160
161 void gpu_extensions_init(void)
162 {
163         GLint r, g, b;
164         const char *vendor, *renderer, *version;
165
166         /* glewIsSupported("GL_VERSION_2_0") */
167
168         if (GLEW_ARB_multitexture)
169                 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &GG.maxtextures);
170
171         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize);
172
173         GG.glslsupport = 1;
174         if (!GLEW_ARB_multitexture) GG.glslsupport = 0;
175         if (!GLEW_ARB_vertex_shader) GG.glslsupport = 0;
176         if (!GLEW_ARB_fragment_shader) GG.glslsupport = 0;
177
178         glGetIntegerv(GL_RED_BITS, &r);
179         glGetIntegerv(GL_GREEN_BITS, &g);
180         glGetIntegerv(GL_BLUE_BITS, &b);
181         GG.colordepth = r + g + b; /* assumes same depth for RGB */
182
183         vendor = (const char *)glGetString(GL_VENDOR);
184         renderer = (const char *)glGetString(GL_RENDERER);
185         version = (const char *)glGetString(GL_VERSION);
186
187         if (strstr(vendor, "ATI")) {
188                 GG.device = GPU_DEVICE_ATI;
189                 GG.driver = GPU_DRIVER_OFFICIAL;
190         }
191         else if (strstr(vendor, "NVIDIA")) {
192                 GG.device = GPU_DEVICE_NVIDIA;
193                 GG.driver = GPU_DRIVER_OFFICIAL;
194         }
195         else if (strstr(vendor, "Intel") ||
196                 /* src/mesa/drivers/dri/intel/intel_context.c */
197                 strstr(renderer, "Mesa DRI Intel") ||
198                 strstr(renderer, "Mesa DRI Mobile Intel")) {
199                 GG.device = GPU_DEVICE_INTEL;
200                 GG.driver = GPU_DRIVER_OFFICIAL;
201         }
202         else if (strstr(renderer, "Mesa DRI R") || (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI "))) {
203                 GG.device = GPU_DEVICE_ATI;
204                 GG.driver = GPU_DRIVER_OPENSOURCE;
205         }
206         else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) {
207                 GG.device = GPU_DEVICE_NVIDIA;
208                 GG.driver = GPU_DRIVER_OPENSOURCE;
209         }
210         else if (strstr(vendor, "Mesa")) {
211                 GG.device = GPU_DEVICE_SOFTWARE;
212                 GG.driver = GPU_DRIVER_SOFTWARE;
213         }
214         else if (strstr(vendor, "Microsoft")) {
215                 GG.device = GPU_DEVICE_SOFTWARE;
216                 GG.driver = GPU_DRIVER_SOFTWARE;
217         }
218         else if (strstr(renderer, "Apple Software Renderer")) {
219                 GG.device = GPU_DEVICE_SOFTWARE;
220                 GG.driver = GPU_DRIVER_SOFTWARE;
221         }
222         else {
223                 GG.device = GPU_DEVICE_ANY;
224                 GG.driver = GPU_DRIVER_ANY;
225         }
226
227         if (GG.device == GPU_DEVICE_ATI) {
228                 /* ATI 9500 to X2300 cards support NPoT textures poorly
229                  * Incomplete list http://dri.freedesktop.org/wiki/ATIRadeon
230                  * New IDs from MESA's src/gallium/drivers/r300/r300_screen.c
231                  */
232                 /* This list is close enough to those using the legacy driver which
233                  * has a bug with display lists and glVertexAttrib 
234                  */
235                 if (strstr(renderer, "R3") || strstr(renderer, "RV3") ||
236                     strstr(renderer, "R4") || strstr(renderer, "RV4") ||
237                     strstr(renderer, "RS4") || strstr(renderer, "RC4") ||
238                     strstr(renderer, "R5") || strstr(renderer, "RV5") ||
239                     strstr(renderer, "RS600") || strstr(renderer, "RS690") ||
240                     strstr(renderer, "RS740") || strstr(renderer, "X1") ||
241                     strstr(renderer, "X2") || strstr(renderer, "Radeon 9") ||
242                     strstr(renderer, "RADEON 9"))
243                 {
244                         GG.npotdisabled = 1;
245                         GG.dlistsdisabled = 1;
246                 }
247         }
248
249         /* make sure double side isn't used by default and only getting enabled in places where it's
250          * really needed to prevent different unexpected behaviors like with intel gme965 card (sergey) */
251         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
252
253 #ifdef _WIN32
254         GG.os = GPU_OS_WIN;
255 #elif defined(__APPLE__)
256         GG.os = GPU_OS_MAC;
257 #else
258         GG.os = GPU_OS_UNIX;
259 #endif
260
261
262         /* df/dy calculation factors, those are dependent on driver */
263         if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) {
264                 GG.dfdyfactors[0] = 1.0;
265                 GG.dfdyfactors[1] = -1.0;
266         }
267         else if (GG.device == GPU_DEVICE_INTEL && GG.os == GPU_OS_WIN  &&
268                 (strstr(version, "4.0.0 - Build 10.18.10.3308") ||
269                  strstr(version, "4.0.0 - Build 9.18.10.3186") ||
270                  strstr(version, "4.0.0 - Build 9.18.10.3165") ||
271                  strstr(version, "3.1.0 - Build 9.17.10.3347") ||
272                  strstr(version, "3.1.0 - Build 9.17.10.4101")))
273         {
274                 GG.dfdyfactors[0] = -1.0;
275                 GG.dfdyfactors[1] = 1.0;
276         }
277         else {
278                 GG.dfdyfactors[0] = 1.0;
279                 GG.dfdyfactors[1] = 1.0;
280         }
281
282
283         GPU_invalid_tex_init();
284         GPU_simple_shaders_init();
285 }
286
287 void gpu_extensions_exit(void)
288 {
289         GPU_simple_shaders_exit();
290         GPU_invalid_tex_free();
291 }
292
293 bool GPU_glsl_support(void)
294 {
295         return !GG.extdisabled && GG.glslsupport;
296 }
297
298 bool GPU_non_power_of_two_support(void)
299 {
300         if (GG.npotdisabled)
301                 return false;
302
303         return GLEW_ARB_texture_non_power_of_two;
304 }
305
306 bool GPU_vertex_buffer_support(void)
307 {
308         return GLEW_ARB_vertex_buffer_object || GLEW_VERSION_1_5;
309 }
310
311 bool GPU_display_list_support(void)
312 {
313         return !GG.dlistsdisabled;
314 }
315
316 bool GPU_bicubic_bump_support(void)
317 {
318         return GLEW_ARB_texture_query_lod && GLEW_VERSION_3_0;
319 }
320
321 bool GPU_geometry_shader_support(void)
322 {
323         return GLEW_EXT_geometry_shader4 || GLEW_VERSION_3_2;
324 }
325
326 bool GPU_instanced_drawing_support(void)
327 {
328         return GLEW_ARB_draw_instanced;
329 }
330
331 int GPU_color_depth(void)
332 {
333         return GG.colordepth;
334 }
335
336 static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
337 {
338         const char *err = "unknown";
339
340         switch (status) {
341                 case GL_FRAMEBUFFER_COMPLETE_EXT:
342                         break;
343                 case GL_INVALID_OPERATION:
344                         err = "Invalid operation";
345                         break;
346                 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
347                         err = "Incomplete attachment";
348                         break;
349                 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
350                         err = "Unsupported framebuffer format";
351                         break;
352                 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
353                         err = "Missing attachment";
354                         break;
355                 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
356                         err = "Attached images must have same dimensions";
357                         break;
358                 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
359                         err = "Attached images must have same format";
360                         break;
361                 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
362                         err = "Missing draw buffer";
363                         break;
364                 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
365                         err = "Missing read buffer";
366                         break;
367         }
368
369         if (err_out) {
370                 BLI_snprintf(err_out, 256, "GPUFrameBuffer: framebuffer incomplete error %d '%s'",
371                         (int)status, err);
372         }
373         else {
374                 fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d '%s'\n",
375                         (int)status, err);
376         }
377 }
378
379 /* GPUTexture */
380
381 struct GPUTexture {
382         int w, h;           /* width/height */
383         int number;         /* number for multitexture binding */
384         int refcount;       /* reference count */
385         GLenum target;      /* GL_TEXTURE_* */
386         GLuint bindcode;    /* opengl identifier for texture */
387         int fromblender;    /* we got the texture from Blender */
388
389         GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
390         int fb_attachment;  /* slot the texture is attached to */
391         int depth;          /* is a depth texture? if 3D how deep? */
392 };
393
394 static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixels)
395 {
396         unsigned char *pixels, *p;
397         const float *fp = fpixels;
398         const int len = 4 * length;
399         int a;
400
401         p = pixels = MEM_callocN(sizeof(unsigned char) * len, "GPUTexturePixels");
402
403         for (a = 0; a < len; a++, p++, fp++)
404                 *p = FTOCHAR((*fp));
405
406         return pixels;
407 }
408
409 static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
410 {
411         void *pixels = MEM_callocN(sizeof(char) * 4 * w * h, "GPUTextureEmptyPixels");
412
413         if (target == GL_TEXTURE_1D)
414                 glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
415         else
416                 glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
417         
418         MEM_freeN(pixels);
419 }
420
421 static GPUTexture *GPU_texture_create_nD(
422         int w, int h, int n, const float *fpixels, int depth, GPUHDRType hdr_type, int components,
423         char err_out[256])
424 {
425         GPUTexture *tex;
426         GLenum type, format, internalformat;
427         void *pixels = NULL;
428
429         if (depth && !GLEW_ARB_depth_texture)
430                 return NULL;
431
432         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
433         tex->w = w;
434         tex->h = h;
435         tex->number = -1;
436         tex->refcount = 1;
437         tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
438         tex->depth = depth;
439         tex->fb_attachment = -1;
440
441         glGenTextures(1, &tex->bindcode);
442
443         if (!tex->bindcode) {
444                 if (err_out) {
445                         BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
446                                 (int)glGetError());
447                 }
448                 else {
449                         fprintf(stderr, "GPUTexture: texture create failed: %d\n",
450                                 (int)glGetError());
451                 }
452                 GPU_texture_free(tex);
453                 return NULL;
454         }
455
456         if (!GPU_non_power_of_two_support()) {
457                 tex->w = power_of_2_max_i(tex->w);
458                 tex->h = power_of_2_max_i(tex->h);
459         }
460
461         tex->number = 0;
462         glBindTexture(tex->target, tex->bindcode);
463
464         if (depth) {
465                 type = GL_UNSIGNED_BYTE;
466                 format = GL_DEPTH_COMPONENT;
467                 internalformat = GL_DEPTH_COMPONENT;
468         }
469         else {
470                 type = GL_FLOAT;
471
472                 if (components == 4) {
473                         format = GL_RGBA;
474                         switch (hdr_type) {
475                                 case GPU_HDR_NONE:
476                                         internalformat = GL_RGBA8;
477                                         break;
478                                 case GPU_HDR_HALF_FLOAT:
479                                         internalformat = GL_RGBA16F;
480                                         break;
481                                 case GPU_HDR_FULL_FLOAT:
482                                         internalformat = GL_RGBA32F;
483                                         break;
484                                 default:
485                                         break;
486                         }
487                 }
488                 else if (components == 2) {
489                         format = GL_RG;
490                         switch (hdr_type) {
491                                 case GPU_HDR_NONE:
492                                         internalformat = GL_RG8;
493                                         break;
494                                 case GPU_HDR_HALF_FLOAT:
495                                         internalformat = GL_RG16F;
496                                         break;
497                                 case GPU_HDR_FULL_FLOAT:
498                                         internalformat = GL_RG32F;
499                                         break;
500                                 default:
501                                         break;
502                         }
503                 }
504
505                 if (fpixels && hdr_type == GPU_HDR_NONE) {
506                         type = GL_UNSIGNED_BYTE;
507                         pixels = GPU_texture_convert_pixels(w*h, fpixels);
508                 }
509         }
510
511         if (tex->target == GL_TEXTURE_1D) {
512                 glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, NULL);
513
514                 if (fpixels) {
515                         glTexSubImage1D(tex->target, 0, 0, w, format, type,
516                                 pixels ? pixels : fpixels);
517
518                         if (tex->w > w)
519                                 GPU_glTexSubImageEmpty(tex->target, format, w, 0,
520                                         tex->w-w, 1);
521                 }
522         }
523         else {
524                 glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
525                              format, type, NULL);
526
527                 if (fpixels) {
528                         glTexSubImage2D(tex->target, 0, 0, 0, w, h,
529                                 format, type, pixels ? pixels : fpixels);
530
531                         if (tex->w > w)
532                                 GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
533                         if (tex->h > h)
534                                 GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
535                 }
536         }
537
538         if (pixels)
539                 MEM_freeN(pixels);
540
541         if (depth) {
542                 glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
543                 glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
544                 glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
545                 glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
546                 glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);  
547         }
548         else {
549                 glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
550                 glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
551         }
552
553         if (tex->target != GL_TEXTURE_1D) {
554                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
555                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
556         }
557         else
558                 glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
559
560         return tex;
561 }
562
563
564 GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const float *fpixels)
565 {
566         GPUTexture *tex;
567         GLenum type, format, internalformat;
568         void *pixels = NULL;
569         int r_width;
570         bool rescale = false;
571
572         if (!GLEW_VERSION_1_2)
573                 return NULL;
574
575         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
576         tex->w = w;
577         tex->h = h;
578         tex->depth = depth;
579         tex->number = -1;
580         tex->refcount = 1;
581         tex->target = GL_TEXTURE_3D;
582
583         glGenTextures(1, &tex->bindcode);
584
585         if (!tex->bindcode) {
586                 fprintf(stderr, "GPUTexture: texture create failed: %d\n",
587                         (int)glGetError());
588                 GPU_texture_free(tex);
589                 return NULL;
590         }
591
592         if (!GPU_non_power_of_two_support()) {
593                 tex->w = power_of_2_max_i(tex->w);
594                 tex->h = power_of_2_max_i(tex->h);
595                 tex->depth = power_of_2_max_i(tex->depth);
596         }
597
598         tex->number = 0;
599         glBindTexture(tex->target, tex->bindcode);
600
601         GPU_ASSERT_NO_GL_ERRORS("3D glBindTexture");
602
603         type = GL_FLOAT;
604         if (channels == 4) {
605                 format = GL_RGBA;
606                 internalformat = GL_RGBA;
607         }
608         else {
609                 format = GL_RED;
610                 internalformat = GL_INTENSITY;
611         }
612
613         /* 3D textures are quite heavy, test if it's possible to create them first */
614         glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
615         glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
616
617         while (r_width == 0) {
618                 rescale = true;
619                 tex->w /= 2;
620                 tex->h /= 2;
621                 tex->depth /= 2;
622                 glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
623                 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
624         }
625
626         /* really unlikely to happen but keep this just in case */
627         tex->w = max_ii(tex->w, 1);
628         tex->h = max_ii(tex->h, 1);
629         tex->depth = max_ii(tex->depth, 1);
630
631 #if 0
632         if (fpixels)
633                 pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
634 #endif
635
636         GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
637
638         /* hardcore stuff, 3D texture rescaling - warning, this is gonna hurt your performance a lot, but we need it
639          * for gooseberry */
640         if (rescale && fpixels) {
641                 unsigned int i, j, k;
642                 unsigned int xf = w / tex->w, yf = h / tex->h, zf = depth / tex->depth;
643                 float *tex3d = MEM_mallocN(channels * sizeof(float)*tex->w*tex->h*tex->depth, "tex3d");
644
645                 GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
646
647                 for (k = 0; k < tex->depth; k++) {
648                         for (j = 0; j < tex->h; j++) {
649                                 for (i = 0; i < tex->w; i++) {
650                                         /* obviously doing nearest filtering here, it's going to be slow in any case, let's not make it worse */
651                                         float xb = i * xf;
652                                         float yb = j * yf;
653                                         float zb = k * zf;
654                                         unsigned int offset = k * (tex->w * tex->h) + i * tex->h + j;
655                                         unsigned int offset_orig = (zb) * (w * h) + (xb) * h + (yb);
656
657                                         if (channels == 4) {
658                                                 tex3d[offset * 4] = fpixels[offset_orig * 4];
659                                                 tex3d[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
660                                                 tex3d[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
661                                                 tex3d[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
662                                         }
663                                         else
664                                                 tex3d[offset] = fpixels[offset_orig];
665                                 }
666                         }
667                 }
668
669                 glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, tex3d);
670
671                 MEM_freeN(tex3d);
672         }
673         else {
674                 if (fpixels) {
675                         if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
676                                 /* clear first to avoid unitialized pixels */
677                                 float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero");
678                                 glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
679                                 glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, GL_INTENSITY, GL_FLOAT, zero);
680                                 glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
681                                 MEM_freeN(zero);
682                         }
683                         else {
684                                 glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
685                         }
686
687                         GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
688                 }
689         }
690
691
692         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
693         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
694         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
695         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
696         glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
697
698         if (pixels)
699                 MEM_freeN(pixels);
700
701         GPU_texture_unbind(tex);
702
703         return tex;
704 }
705
706 GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data, double time, int mipmap)
707 {
708         GPUTexture *tex;
709         GLint w, h, border, lastbindcode, bindcode;
710
711         glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
712
713         GPU_update_image_time(ima, time);
714         /* this binds a texture, so that's why to restore it with lastbindcode */
715         bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, is_data);
716
717         if (ima->gputexture) {
718                 ima->gputexture->bindcode = bindcode;
719                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
720                 return ima->gputexture;
721         }
722
723         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
724         tex->bindcode = bindcode;
725         tex->number = -1;
726         tex->refcount = 1;
727         tex->target = GL_TEXTURE_2D;
728         tex->fromblender = 1;
729
730         ima->gputexture= tex;
731
732         if (!glIsTexture(tex->bindcode)) {
733                 GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
734         }
735         else {
736                 glBindTexture(GL_TEXTURE_2D, tex->bindcode);
737                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
738                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
739                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
740
741                 tex->w = w - border;
742                 tex->h = h - border;
743         }
744
745         glBindTexture(GL_TEXTURE_2D, lastbindcode);
746
747         return tex;
748 }
749
750 GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
751 {
752         GPUTexture *tex = prv->gputexture[0];
753         GLint w, h, lastbindcode;
754         GLuint bindcode = 0;
755         
756         glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
757         
758         if (tex)
759                 bindcode = tex->bindcode;
760         
761         /* this binds a texture, so that's why to restore it */
762         if (bindcode == 0) {
763                 GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], mipmap, 0, NULL);
764         }
765         if (tex) {
766                 tex->bindcode = bindcode;
767                 glBindTexture(GL_TEXTURE_2D, lastbindcode);
768                 return tex;
769         }
770
771         tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
772         tex->bindcode = bindcode;
773         tex->number = -1;
774         tex->refcount = 1;
775         tex->target = GL_TEXTURE_2D;
776         
777         prv->gputexture[0] = tex;
778         
779         if (!glIsTexture(tex->bindcode)) {
780                 GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
781         }
782         else {
783                 glBindTexture(GL_TEXTURE_2D, tex->bindcode);
784                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
785                 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
786                 
787                 tex->w = w;
788                 tex->h = h;
789         }
790         
791         glBindTexture(GL_TEXTURE_2D, lastbindcode);
792         
793         return tex;
794
795 }
796
797 GPUTexture *GPU_texture_create_1D(int w, const float *fpixels, char err_out[256])
798 {
799         GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, GPU_HDR_NONE, 4, err_out);
800
801         if (tex)
802                 GPU_texture_unbind(tex);
803         
804         return tex;
805 }
806
807 GPUTexture *GPU_texture_create_2D(int w, int h, const float *fpixels, GPUHDRType hdr, char err_out[256])
808 {
809         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, hdr, 4, err_out);
810
811         if (tex)
812                 GPU_texture_unbind(tex);
813         
814         return tex;
815 }
816
817 GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
818 {
819         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, err_out);
820
821         if (tex)
822                 GPU_texture_unbind(tex);
823         
824         return tex;
825 }
826
827 /**
828  * A shadow map for VSM needs two components (depth and depth^2)
829  */
830 GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256])
831 {
832         GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, GPU_HDR_FULL_FLOAT, 2, err_out);
833
834         if (tex) {
835                 /* Now we tweak some of the settings */
836                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
837                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
838
839                 GPU_texture_unbind(tex);
840         }
841
842         return tex;
843 }
844
845 GPUTexture *GPU_texture_create_2D_procedural(int w, int h, const float *pixels, bool repeat, char err_out[256])
846 {
847         GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
848
849         if (tex) {
850                 /* Now we tweak some of the settings */
851                 if (repeat) {
852                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
853                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
854                 }
855                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
856                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
857
858                 GPU_texture_unbind(tex);
859         }
860
861         return tex;
862 }
863
864 GPUTexture *GPU_texture_create_1D_procedural(int w, const float *pixels, char err_out[256])
865 {
866         GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
867
868         if (tex) {
869                 /* Now we tweak some of the settings */
870                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
871                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
872                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
873
874                 GPU_texture_unbind(tex);
875         }
876
877         return tex;
878 }
879
880 void GPU_invalid_tex_init(void)
881 {
882         const float color[4] = {1.0f, 0.0f, 1.0f, 1.0f};
883         GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL);
884         GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, GPU_HDR_NONE, NULL);
885         GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, 4, color);
886 }
887
888 void GPU_invalid_tex_bind(int mode)
889 {
890         switch (mode) {
891                 case GL_TEXTURE_1D:
892                         glBindTexture(GL_TEXTURE_1D, GG.invalid_tex_1D->bindcode);
893                         break;
894                 case GL_TEXTURE_2D:
895                         glBindTexture(GL_TEXTURE_2D, GG.invalid_tex_2D->bindcode);
896                         break;
897                 case GL_TEXTURE_3D:
898                         glBindTexture(GL_TEXTURE_3D, GG.invalid_tex_3D->bindcode);
899                         break;
900         }
901 }
902
903 void GPU_invalid_tex_free(void)
904 {
905         if (GG.invalid_tex_1D)
906                 GPU_texture_free(GG.invalid_tex_1D);
907         if (GG.invalid_tex_2D)
908                 GPU_texture_free(GG.invalid_tex_2D);
909         if (GG.invalid_tex_3D)
910                 GPU_texture_free(GG.invalid_tex_3D);
911 }
912
913
914 void GPU_texture_bind(GPUTexture *tex, int number)
915 {
916         GLenum arbnumber;
917
918         if (number >= GG.maxtextures) {
919                 fprintf(stderr, "Not enough texture slots.");
920                 return;
921         }
922
923         if ((G.debug & G_DEBUG)) {
924                 if (tex->fb && tex->fb->object == GG.currentfb) {
925                         fprintf(stderr, "Feedback loop warning!: Attempting to bind texture attached to current framebuffer!\n");
926                 }
927         }
928
929         if (number < 0)
930                 return;
931
932         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Bind");
933
934         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
935         if (number != 0) glActiveTextureARB(arbnumber);
936         if (tex->bindcode != 0) {
937                 glBindTexture(tex->target, tex->bindcode);
938         }
939         else
940                 GPU_invalid_tex_bind(tex->target);
941         glEnable(tex->target);
942         if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
943
944         tex->number = number;
945
946         GPU_ASSERT_NO_GL_ERRORS("Post Texture Bind");
947 }
948
949 void GPU_texture_unbind(GPUTexture *tex)
950 {
951         GLenum arbnumber;
952
953         if (tex->number >= GG.maxtextures) {
954                 fprintf(stderr, "Not enough texture slots.");
955                 return;
956         }
957
958         if (tex->number == -1)
959                 return;
960         
961         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
962
963         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
964         if (tex->number != 0) glActiveTextureARB(arbnumber);
965         glBindTexture(tex->target, 0);
966         glDisable(tex->target);
967         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
968
969         tex->number = -1;
970
971         GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
972 }
973
974 void GPU_texture_filter_mode(GPUTexture *tex, bool compare, bool use_filter)
975 {
976         GLenum arbnumber;
977
978         if (tex->number >= GG.maxtextures) {
979                 fprintf(stderr, "Not enough texture slots.");
980                 return;
981         }
982
983         if (tex->number == -1)
984                 return;
985
986         GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
987
988         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
989         if (tex->number != 0) glActiveTextureARB(arbnumber);
990
991         if (tex->depth) {
992                 if (compare)
993                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
994                 else
995                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
996         }
997
998         if (use_filter) {
999                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1000                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1001         }
1002         else {
1003                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1004                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1005         }
1006         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
1007
1008         GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
1009 }
1010
1011 void GPU_texture_free(GPUTexture *tex)
1012 {
1013         tex->refcount--;
1014
1015         if (tex->refcount < 0)
1016                 fprintf(stderr, "GPUTexture: negative refcount\n");
1017         
1018         if (tex->refcount == 0) {
1019                 if (tex->fb)
1020                         GPU_framebuffer_texture_detach(tex);
1021                 if (tex->bindcode && !tex->fromblender)
1022                         glDeleteTextures(1, &tex->bindcode);
1023
1024                 MEM_freeN(tex);
1025         }
1026 }
1027
1028 void GPU_texture_ref(GPUTexture *tex)
1029 {
1030         tex->refcount++;
1031 }
1032
1033 int GPU_texture_target(const GPUTexture *tex)
1034 {
1035         return tex->target;
1036 }
1037
1038 int GPU_texture_opengl_width(const GPUTexture *tex)
1039 {
1040         return tex->w;
1041 }
1042
1043 int GPU_texture_opengl_height(const GPUTexture *tex)
1044 {
1045         return tex->h;
1046 }
1047
1048 int GPU_texture_opengl_bindcode(const GPUTexture *tex)
1049 {
1050         return tex->bindcode;
1051 }
1052
1053 GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
1054 {
1055         return tex->fb;
1056 }
1057
1058 /* GPUFrameBuffer */
1059
1060 GPUFrameBuffer *GPU_framebuffer_create(void)
1061 {
1062         GPUFrameBuffer *fb;
1063
1064         if (!GLEW_EXT_framebuffer_object)
1065                 return NULL;
1066         
1067         fb = MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
1068         glGenFramebuffersEXT(1, &fb->object);
1069
1070         if (!fb->object) {
1071                 fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
1072                         (int)glGetError());
1073                 GPU_framebuffer_free(fb);
1074                 return NULL;
1075         }
1076
1077         /* make sure no read buffer is enabled, so completeness check will not fail. We set those at binding time */
1078         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1079         glReadBuffer(GL_NONE);
1080         glDrawBuffer(GL_NONE);
1081         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1082         
1083         return fb;
1084 }
1085
1086 int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
1087 {
1088         GLenum attachment;
1089         GLenum error;
1090
1091         if (slot >= GPU_FB_MAX_SLOTS) {
1092                 fprintf(stderr, "Attaching to index %d framebuffer slot unsupported in blender use at most %d\n", slot, GPU_FB_MAX_SLOTS);
1093                 return 0;
1094         }
1095
1096         if ((G.debug & G_DEBUG)) {
1097                 if (tex->number != -1) {
1098                         fprintf(stderr, "Feedback loop warning!: Attempting to attach texture to framebuffer while still bound to texture unit for drawing!");
1099                 }
1100         }
1101
1102         if (tex->depth)
1103                 attachment = GL_DEPTH_ATTACHMENT_EXT;
1104         else
1105                 attachment = GL_COLOR_ATTACHMENT0_EXT + slot;
1106
1107         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1108         GG.currentfb = fb->object;
1109
1110         /* Clean glError buffer. */
1111         while (glGetError() != GL_NO_ERROR) {}
1112
1113         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, 
1114                 tex->target, tex->bindcode, 0);
1115
1116         error = glGetError();
1117
1118         if (error == GL_INVALID_OPERATION) {
1119                 GPU_framebuffer_restore();
1120                 GPU_print_framebuffer_error(error, err_out);
1121                 return 0;
1122         }
1123
1124         if (tex->depth)
1125                 fb->depthtex = tex;
1126         else
1127                 fb->colortex[slot] = tex;
1128
1129         tex->fb= fb;
1130         tex->fb_attachment = slot;
1131
1132         return 1;
1133 }
1134
1135 void GPU_framebuffer_texture_detach(GPUTexture *tex)
1136 {
1137         GLenum attachment;
1138         GPUFrameBuffer *fb;
1139
1140         if (!tex->fb)
1141                 return;
1142
1143         fb = tex->fb;
1144
1145         if (GG.currentfb != fb->object) {
1146                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1147                 GG.currentfb = tex->fb->object;
1148         }
1149
1150         if (tex->depth) {
1151                 fb->depthtex = NULL;
1152                 attachment = GL_DEPTH_ATTACHMENT_EXT;
1153         }
1154         else {
1155                 BLI_assert(fb->colortex[tex->fb_attachment] == tex);
1156                 fb->colortex[tex->fb_attachment] = NULL;
1157                 attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment;
1158         }
1159
1160         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, tex->target, 0, 0);
1161
1162         tex->fb = NULL;
1163         tex->fb_attachment = -1;
1164 }
1165
1166 void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
1167 {
1168         if (!tex->fb) {
1169                 fprintf(stderr, "Error, texture not bound to framebuffer!");
1170                 return;
1171         }
1172
1173         /* push attributes */
1174         glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
1175         glDisable(GL_SCISSOR_TEST);
1176
1177         /* bind framebuffer */
1178         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
1179
1180         if (tex->depth) {
1181                 glDrawBuffer(GL_NONE);
1182                 glReadBuffer(GL_NONE);
1183         }
1184         else {
1185                 /* last bound prevails here, better allow explicit control here too */
1186                 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
1187                 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
1188         }
1189         
1190         /* push matrices and set default viewport and matrix */
1191         glViewport(0, 0, tex->w, tex->h);
1192         GG.currentfb = tex->fb->object;
1193
1194         glMatrixMode(GL_PROJECTION);
1195         glPushMatrix();
1196         glMatrixMode(GL_MODELVIEW);
1197         glPushMatrix();
1198 }
1199
1200 void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
1201 {
1202         int numslots = 0, i;
1203         GLenum attachments[4];
1204         
1205         if (!fb->colortex[slot]) {
1206                 fprintf(stderr, "Error, framebuffer slot empty!");
1207                 return;
1208         }
1209         
1210         for (i = 0; i < 4; i++) {
1211                 if (fb->colortex[i]) {
1212                         attachments[numslots] = GL_COLOR_ATTACHMENT0_EXT + i;
1213                         numslots++;
1214                 }
1215         }
1216         
1217         /* push attributes */
1218         glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
1219         glDisable(GL_SCISSOR_TEST);
1220
1221         /* bind framebuffer */
1222         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1223
1224         /* last bound prevails here, better allow explicit control here too */
1225         glDrawBuffers(numslots, attachments);
1226         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1227
1228         /* push matrices and set default viewport and matrix */
1229         glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
1230         GG.currentfb = fb->object;
1231
1232         glMatrixMode(GL_PROJECTION);
1233         glPushMatrix();
1234         glMatrixMode(GL_MODELVIEW);
1235         glPushMatrix();
1236 }
1237
1238
1239 void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
1240 {
1241         /* restore matrix */
1242         glMatrixMode(GL_PROJECTION);
1243         glPopMatrix();
1244         glMatrixMode(GL_MODELVIEW);
1245         glPopMatrix();
1246
1247         /* restore attributes */
1248         glPopAttrib();
1249 }
1250
1251 void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
1252 {
1253         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1254         /* last bound prevails here, better allow explicit control here too */
1255         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1256         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
1257
1258         /* push matrices and set default viewport and matrix */
1259         glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
1260         GG.currentfb = fb->object;
1261         GG.currentfb = fb->object;
1262 }
1263
1264 bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
1265 {
1266         GLenum status;
1267         
1268         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1269         GG.currentfb = fb->object;
1270         
1271         /* Clean glError buffer. */
1272         while (glGetError() != GL_NO_ERROR) {}
1273         
1274         status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
1275         
1276         if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1277                 GPU_framebuffer_restore();
1278                 GPU_print_framebuffer_error(status, err_out);
1279                 return false;
1280         }
1281         
1282         return true;
1283 }
1284
1285 void GPU_framebuffer_free(GPUFrameBuffer *fb)
1286 {
1287         int i;
1288         if (fb->depthtex)
1289                 GPU_framebuffer_texture_detach(fb->depthtex);
1290
1291         for (i = 0; i < GPU_FB_MAX_SLOTS; i++) {
1292                 if (fb->colortex[i]) {
1293                         GPU_framebuffer_texture_detach(fb->colortex[i]);
1294                 }
1295         }
1296
1297         if (fb->object) {
1298                 glDeleteFramebuffersEXT(1, &fb->object);
1299
1300                 if (GG.currentfb == fb->object) {
1301                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1302                         GG.currentfb = 0;
1303                 }
1304         }
1305
1306         MEM_freeN(fb);
1307 }
1308
1309 void GPU_framebuffer_restore(void)
1310 {
1311         if (GG.currentfb != 0) {
1312                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1313                 GG.currentfb = 0;
1314         }
1315 }
1316
1317 void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex)
1318 {
1319         const float scaleh[2] = {1.0f / GPU_texture_opengl_width(blurtex), 0.0f};
1320         const float scalev[2] = {0.0f, 1.0f / GPU_texture_opengl_height(tex)};
1321
1322         GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
1323         int scale_uniform, texture_source_uniform;
1324
1325         if (!blur_shader)
1326                 return;
1327
1328         scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU");
1329         texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource");
1330                 
1331         /* Blurring horizontally */
1332
1333         /* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
1334          * pushing unnecessary matrices onto the OpenGL stack. */
1335         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
1336         glDrawBuffer(GL_COLOR_ATTACHMENT0);
1337         
1338         /* avoid warnings from texture binding */
1339         GG.currentfb = blurfb->object;
1340
1341         GPU_shader_bind(blur_shader);
1342         GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
1343         GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
1344         glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
1345
1346         /* Peparing to draw quad */
1347         glMatrixMode(GL_MODELVIEW);
1348         glLoadIdentity();
1349         glMatrixMode(GL_TEXTURE);
1350         glLoadIdentity();
1351         glMatrixMode(GL_PROJECTION);
1352         glLoadIdentity();
1353
1354         glDisable(GL_DEPTH_TEST);
1355
1356         GPU_texture_bind(tex, 0);
1357
1358         /* Drawing quad */
1359         glBegin(GL_QUADS);
1360         glTexCoord2d(0, 0); glVertex2f(1, 1);
1361         glTexCoord2d(1, 0); glVertex2f(-1, 1);
1362         glTexCoord2d(1, 1); glVertex2f(-1, -1);
1363         glTexCoord2d(0, 1); glVertex2f(1, -1);
1364         glEnd();
1365
1366         /* Blurring vertically */
1367
1368         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
1369         glDrawBuffer(GL_COLOR_ATTACHMENT0);
1370         
1371         GG.currentfb = fb->object;
1372         
1373         glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex));
1374         GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
1375         GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
1376         GPU_texture_bind(blurtex, 0);
1377
1378         glBegin(GL_QUADS);
1379         glTexCoord2d(0, 0); glVertex2f(1, 1);
1380         glTexCoord2d(1, 0); glVertex2f(-1, 1);
1381         glTexCoord2d(1, 1); glVertex2f(-1, -1);
1382         glTexCoord2d(0, 1); glVertex2f(1, -1);
1383         glEnd();
1384
1385         GPU_shader_unbind();
1386 }
1387
1388 /* GPUOffScreen */
1389
1390 struct GPUOffScreen {
1391         GPUFrameBuffer *fb;
1392         GPUTexture *color;
1393         GPUTexture *depth;
1394 };
1395
1396 GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
1397 {
1398         GPUOffScreen *ofs;
1399
1400         ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
1401
1402         ofs->fb = GPU_framebuffer_create();
1403         if (!ofs->fb) {
1404                 GPU_offscreen_free(ofs);
1405                 return NULL;
1406         }
1407
1408         ofs->depth = GPU_texture_create_depth(width, height, err_out);
1409         if (!ofs->depth) {
1410                 GPU_offscreen_free(ofs);
1411                 return NULL;
1412         }
1413
1414         if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
1415                 GPU_offscreen_free(ofs);
1416                 return NULL;
1417         }
1418
1419         ofs->color = GPU_texture_create_2D(width, height, NULL, GPU_HDR_NONE, err_out);
1420         if (!ofs->color) {
1421                 GPU_offscreen_free(ofs);
1422                 return NULL;
1423         }
1424
1425         if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
1426                 GPU_offscreen_free(ofs);
1427                 return NULL;
1428         }
1429         
1430         /* check validity at the very end! */
1431         if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) {
1432                 GPU_offscreen_free(ofs);
1433                 return NULL;            
1434         }
1435
1436         GPU_framebuffer_restore();
1437
1438         return ofs;
1439 }
1440
1441 void GPU_offscreen_free(GPUOffScreen *ofs)
1442 {
1443         if (ofs->fb)
1444                 GPU_framebuffer_free(ofs->fb);
1445         if (ofs->color)
1446                 GPU_texture_free(ofs->color);
1447         if (ofs->depth)
1448                 GPU_texture_free(ofs->depth);
1449         
1450         MEM_freeN(ofs);
1451 }
1452
1453 void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
1454 {
1455         glDisable(GL_SCISSOR_TEST);
1456         if (save)
1457                 GPU_texture_bind_as_framebuffer(ofs->color);
1458         else {
1459                 GPU_framebuffer_bind_no_save(ofs->fb, 0);
1460         }
1461 }
1462
1463 void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
1464 {
1465         if (restore)
1466                 GPU_framebuffer_texture_unbind(ofs->fb, ofs->color);
1467         GPU_framebuffer_restore();
1468         glEnable(GL_SCISSOR_TEST);
1469 }
1470
1471 void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
1472 {
1473         glReadPixels(0, 0, ofs->color->w, ofs->color->h, GL_RGBA, type, pixels);
1474 }
1475
1476 int GPU_offscreen_width(const GPUOffScreen *ofs)
1477 {
1478         return ofs->color->w;
1479 }
1480
1481 int GPU_offscreen_height(const GPUOffScreen *ofs)
1482 {
1483         return ofs->color->h;
1484 }
1485
1486 /* GPUShader */
1487
1488 struct GPUShader {
1489         GLhandleARB object;   /* handle for full shader */
1490         GLhandleARB vertex;   /* handle for vertex shader */
1491         GLhandleARB fragment; /* handle for fragment shader */
1492         GLhandleARB geometry; /* handle for geometry shader */
1493         GLhandleARB lib;      /* handle for libment shader */
1494         int totattrib;        /* total number of attributes */
1495         int uniforms;         /* required uniforms */
1496 };
1497
1498 struct GPUProgram {
1499         GPUProgramType type;
1500         GLuint prog;
1501 };
1502
1503
1504 static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
1505 {
1506         int i;
1507         int line = 1;
1508
1509         fprintf(stderr, "GPUShader: %s error:\n", task);
1510
1511         for (i = 0; i < totcode; i++) {
1512                 const char *c, *pos, *end = code[i] + strlen(code[i]);
1513
1514                 if ((G.debug & G_DEBUG)) {
1515                         fprintf(stderr, "===== shader string %d ====\n", i + 1);
1516
1517                         c = code[i];
1518                         while ((c < end) && (pos = strchr(c, '\n'))) {
1519                                 fprintf(stderr, "%2d  ", line);
1520                                 fwrite(c, (pos + 1) - c, 1, stderr);
1521                                 c = pos + 1;
1522                                 line++;
1523                         }
1524                         
1525                         fprintf(stderr, "%s", c);
1526                 }
1527         }
1528         
1529         fprintf(stderr, "%s\n", log);
1530 }
1531
1532 static const char *gpu_shader_version(bool use_opensubdiv)
1533 {
1534 #ifdef WITH_OPENSUBDIV
1535         if (use_opensubdiv) {
1536                 return "#version 130\n";
1537         }
1538 #else
1539         UNUSED_VARS(use_opensubdiv);
1540 #endif
1541
1542         /* turn on glsl 1.30 for bicubic bump mapping and ATI clipping support */
1543         if (GLEW_VERSION_3_0 &&
1544             (GPU_bicubic_bump_support() || GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)))
1545         {
1546                 return "#version 130\n";
1547         }
1548
1549         return "";
1550 }
1551
1552
1553 static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH], bool use_opensubdiv)
1554 {
1555 #ifdef WITH_OPENSUBDIV
1556         if (use_opensubdiv) {
1557                 strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n"
1558                                 "#extension GL_ARB_gpu_shader5 : enable\n"
1559                                 "#extension GL_ARB_explicit_attrib_location : require\n");
1560         }
1561         else if (GPU_bicubic_bump_support())
1562                 strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
1563 #else
1564         /* need this extension for high quality bump mapping */
1565         if (GPU_bicubic_bump_support())
1566                 strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
1567         (void) use_opensubdiv;
1568 #endif
1569
1570         if (GPU_geometry_shader_support())
1571                 strcat(defines, "#extension GL_EXT_geometry_shader4: enable\n");
1572
1573         if (GPU_instanced_drawing_support()) {
1574                 strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n");
1575                 strcat(defines, "#extension GL_ARB_draw_instanced: enable\n");
1576         }
1577 }
1578
1579 static void gpu_shader_standard_defines(bool use_opensubdiv,
1580                                         char defines[MAX_DEFINE_LENGTH])
1581 {
1582         /* some useful defines to detect GPU type */
1583         if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
1584                 strcat(defines, "#define GPU_ATI\n");
1585                 if (GLEW_VERSION_3_0)
1586                         strcat(defines, "#define CLIP_WORKAROUND\n");
1587         }
1588         else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
1589                 strcat(defines, "#define GPU_NVIDIA\n");
1590         else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
1591                 strcat(defines, "#define GPU_INTEL\n");
1592
1593         if (GPU_bicubic_bump_support())
1594                 strcat(defines, "#define BUMP_BICUBIC\n");
1595
1596 #ifdef WITH_OPENSUBDIV
1597         /* TODO(sergey): Check whether we actually compiling shader for
1598          * the OpenSubdiv mesh.
1599          */
1600         if (use_opensubdiv) {
1601                 strcat(defines, "#define USE_OPENSUBDIV\n");
1602
1603                 /* TODO(sergey): not strictly speaking a define, but this is
1604                  * a global typedef which we don't have better place to define
1605                  * in yet.
1606                  */
1607                 strcat(defines, "struct VertexData {\n"
1608                                 "  vec4 position;\n"
1609                                 "  vec3 normal;\n"
1610                                 "  vec2 uv;"
1611                                 "};\n");
1612         }
1613 #else
1614         UNUSED_VARS(use_opensubdiv);
1615 #endif
1616
1617         return;
1618 }
1619
1620 void GPU_program_bind(GPUProgram *program)
1621 {
1622         glEnable(program->type);
1623         glBindProgramARB(program->type, program->prog);
1624 }
1625
1626 void GPU_program_unbind(GPUProgram *program)
1627 {
1628         glDisable(program->type);
1629         glBindProgramARB(program->type, 0);
1630 }
1631
1632
1633 GPUProgram *GPU_program_shader_create(GPUProgramType type, const char *code)
1634 {
1635         GPUProgram *program;
1636         GLint error_pos, is_native;
1637
1638         if (!(GLEW_ARB_fragment_program && type == GPU_PROGRAM_TYPE_FRAGMENT))
1639                 return NULL;
1640
1641         program = MEM_callocN(sizeof(GPUProgram), "GPUProgram");
1642
1643         switch (type) {
1644                 case GPU_PROGRAM_TYPE_FRAGMENT:
1645                         program->type = GL_FRAGMENT_PROGRAM_ARB;
1646                         break;
1647         }
1648
1649         /* create the object and set its code string */
1650         glGenProgramsARB(1, &program->prog);
1651         glBindProgramARB(program->type, program->prog);
1652
1653         glProgramStringARB(program->type, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(code), code);
1654
1655         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
1656         glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &is_native);
1657         if ((error_pos == -1) && (is_native == 1)) {
1658                 return program;
1659         }
1660         else {
1661                 /* glGetError is set before that, clear it */
1662                 while (glGetError() != GL_NO_ERROR)
1663                         ;
1664                 shader_print_errors("compile", (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB), &code, 1);
1665                 MEM_freeN(program);
1666         }
1667
1668         return NULL;
1669 }
1670
1671 void GPU_program_free(GPUProgram *program)
1672 {
1673         glDeleteProgramsARB(1, &program->prog);
1674         MEM_freeN(program);
1675 }
1676
1677 void GPU_program_parameter_4f(GPUProgram *program, unsigned int location, float x, float y, float z, float w)
1678 {
1679         glProgramLocalParameter4fARB(program->type, location, x, y, z, w);
1680 }
1681
1682
1683
1684 GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines, int input, int output, int number)
1685 {
1686 #ifdef WITH_OPENSUBDIV
1687         /* TODO(sergey): used to add #version 150 to the geometry shader.
1688          * Could safely be renamed to "use_geometry_code" since it's very
1689          * likely any of geometry code will want to use GLSL 1.5.
1690          */
1691         bool use_opensubdiv = geocode != NULL;
1692 #else
1693         bool use_opensubdiv = false;
1694 #endif
1695         GLint status;
1696         GLcharARB log[5000];
1697         GLsizei length = 0;
1698         GPUShader *shader;
1699         char standard_defines[MAX_DEFINE_LENGTH] = "";
1700         char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
1701
1702         if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader || (geocode && !GPU_geometry_shader_support()))
1703                 return NULL;
1704
1705         shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
1706
1707         if (vertexcode)
1708                 shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
1709         if (fragcode)
1710                 shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1711         if (geocode)
1712                 shader->geometry = glCreateShaderObjectARB(GL_GEOMETRY_SHADER_EXT);
1713
1714         shader->object = glCreateProgramObjectARB();
1715
1716         if (!shader->object ||
1717             (vertexcode && !shader->vertex) ||
1718             (fragcode && !shader->fragment) ||
1719             (geocode && !shader->geometry))
1720         {
1721                 fprintf(stderr, "GPUShader, object creation failed.\n");
1722                 GPU_shader_free(shader);
1723                 return NULL;
1724         }
1725
1726         gpu_shader_standard_defines(use_opensubdiv, standard_defines);
1727         gpu_shader_standard_extensions(standard_extensions, use_opensubdiv);
1728
1729         if (vertexcode) {
1730                 const char *source[5];
1731                 /* custom limit, may be too small, beware */
1732                 int num_source = 0;
1733
1734                 source[num_source++] = gpu_shader_version(use_opensubdiv);
1735                 source[num_source++] = standard_extensions;
1736                 source[num_source++] = standard_defines;
1737
1738                 if (defines) source[num_source++] = defines;
1739                 source[num_source++] = vertexcode;
1740
1741                 glAttachObjectARB(shader->object, shader->vertex);
1742                 glShaderSourceARB(shader->vertex, num_source, source, NULL);
1743
1744                 glCompileShaderARB(shader->vertex);
1745                 glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1746
1747                 if (!status) {
1748                         glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
1749                         shader_print_errors("compile", log, source, num_source);
1750
1751                         GPU_shader_free(shader);
1752                         return NULL;
1753                 }
1754         }
1755
1756         if (fragcode) {
1757                 const char *source[7];
1758                 int num_source = 0;
1759
1760                 source[num_source++] = gpu_shader_version(use_opensubdiv);
1761                 source[num_source++] = standard_extensions;
1762                 source[num_source++] = standard_defines;
1763
1764 #ifdef WITH_OPENSUBDIV
1765                 /* TODO(sergey): Move to fragment shader source code generation. */
1766                 if (use_opensubdiv) {
1767                         source[num_source++] =
1768                                 "#ifdef USE_OPENSUBDIV\n"
1769                                 "in block {\n"
1770                                 "       VertexData v;\n"
1771                                 "} inpt;\n"
1772                                 "#endif\n";
1773                 }
1774 #endif
1775
1776                 if (defines) source[num_source++] = defines;
1777                 if (libcode) source[num_source++] = libcode;
1778                 source[num_source++] = fragcode;
1779
1780                 glAttachObjectARB(shader->object, shader->fragment);
1781                 glShaderSourceARB(shader->fragment, num_source, source, NULL);
1782
1783                 glCompileShaderARB(shader->fragment);
1784                 glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1785
1786                 if (!status) {
1787                         glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
1788                         shader_print_errors("compile", log, source, num_source);
1789
1790                         GPU_shader_free(shader);
1791                         return NULL;
1792                 }
1793         }
1794
1795         if (geocode) {
1796                 const char *source[6];
1797                 int num_source = 0;
1798
1799                 source[num_source++] = gpu_shader_version(use_opensubdiv);
1800                 source[num_source++] = standard_extensions;
1801                 source[num_source++] = standard_defines;
1802
1803                 if (defines) source[num_source++] = defines;
1804                 source[num_source++] = geocode;
1805
1806                 glAttachObjectARB(shader->object, shader->geometry);
1807                 glShaderSourceARB(shader->geometry, num_source, source, NULL);
1808
1809                 glCompileShaderARB(shader->geometry);
1810                 glGetObjectParameterivARB(shader->geometry, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1811
1812                 if (!status) {
1813                         glGetInfoLogARB(shader->geometry, sizeof(log), &length, log);
1814                         shader_print_errors("compile", log, source, num_source);
1815
1816                         GPU_shader_free(shader);
1817                         return NULL;
1818                 }
1819                 
1820                 if (!use_opensubdiv) {
1821                         GPU_shader_geometry_stage_primitive_io(shader, input, output, number);
1822                 }
1823         }
1824
1825
1826 #if 0
1827         if (lib && lib->lib)
1828                 glAttachObjectARB(shader->object, lib->lib);
1829 #endif
1830
1831 #ifdef WITH_OPENSUBDIV
1832         if (use_opensubdiv) {
1833                 glBindAttribLocation(shader->object, 0, "position");
1834                 glBindAttribLocation(shader->object, 1, "normal");
1835                 GPU_shader_geometry_stage_primitive_io(shader,
1836                                                        GL_LINES_ADJACENCY_EXT,
1837                                                        GL_TRIANGLE_STRIP,
1838                                                        4);
1839
1840         }
1841 #endif
1842
1843         glLinkProgramARB(shader->object);
1844         glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
1845         if (!status) {
1846                 glGetInfoLogARB(shader->object, sizeof(log), &length, log);
1847                 if (fragcode) shader_print_errors("linking", log, &fragcode, 1);
1848                 else if (vertexcode) shader_print_errors("linking", log, &vertexcode, 1);
1849                 else if (libcode) shader_print_errors("linking", log, &libcode, 1);
1850                 else if (geocode) shader_print_errors("linking", log, &geocode, 1);
1851
1852                 GPU_shader_free(shader);
1853                 return NULL;
1854         }
1855
1856 #ifdef WITH_OPENSUBDIV
1857         /* TODO(sergey): Find a better place for this. */
1858         if (use_opensubdiv && GLEW_VERSION_4_1) {
1859                 glProgramUniform1i(shader->object,
1860                                    glGetUniformLocation(shader->object, "FVarDataBuffer"),
1861                                    31);  /* GL_TEXTURE31 */
1862         }
1863 #endif
1864
1865         return shader;
1866 }
1867
1868 #if 0
1869 GPUShader *GPU_shader_create_lib(const char *code)
1870 {
1871         GLint status;
1872         GLcharARB log[5000];
1873         GLsizei length = 0;
1874         GPUShader *shader;
1875
1876         if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
1877                 return NULL;
1878
1879         shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
1880
1881         shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1882
1883         if (!shader->lib) {
1884                 fprintf(stderr, "GPUShader, object creation failed.\n");
1885                 GPU_shader_free(shader);
1886                 return NULL;
1887         }
1888
1889         glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
1890
1891         glCompileShaderARB(shader->lib);
1892         glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
1893
1894         if (!status) {
1895                 glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
1896                 shader_print_errors("compile", log, code);
1897
1898                 GPU_shader_free(shader);
1899                 return NULL;
1900         }
1901
1902         return shader;
1903 }
1904 #endif
1905
1906 void GPU_shader_bind(GPUShader *shader)
1907 {
1908         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
1909         glUseProgramObjectARB(shader->object);
1910         GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
1911 }
1912
1913 void GPU_shader_unbind(void)
1914 {
1915         GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
1916         glUseProgramObjectARB(0);
1917         GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
1918 }
1919
1920 void GPU_shader_free(GPUShader *shader)
1921 {
1922         if (shader->lib)
1923                 glDeleteObjectARB(shader->lib);
1924         if (shader->vertex)
1925                 glDeleteObjectARB(shader->vertex);
1926         if (shader->fragment)
1927                 glDeleteObjectARB(shader->fragment);
1928         if (shader->object)
1929                 glDeleteObjectARB(shader->object);
1930         MEM_freeN(shader);
1931 }
1932
1933 int GPU_shader_get_uniform(GPUShader *shader, const char *name)
1934 {
1935         return glGetUniformLocationARB(shader->object, name);
1936 }
1937
1938 void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
1939 {
1940         if (location == -1 || value == NULL)
1941                 return;
1942
1943         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
1944
1945         if (length == 1) glUniform1fvARB(location, arraysize, value);
1946         else if (length == 2) glUniform2fvARB(location, arraysize, value);
1947         else if (length == 3) glUniform3fvARB(location, arraysize, value);
1948         else if (length == 4) glUniform4fvARB(location, arraysize, value);
1949         else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
1950         else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
1951
1952         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
1953 }
1954
1955 void GPU_shader_uniform_vector_int(GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
1956 {
1957         if (location == -1)
1958                 return;
1959
1960         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
1961
1962         if (length == 1) glUniform1ivARB(location, arraysize, value);
1963         else if (length == 2) glUniform2ivARB(location, arraysize, value);
1964         else if (length == 3) glUniform3ivARB(location, arraysize, value);
1965         else if (length == 4) glUniform4ivARB(location, arraysize, value);
1966
1967         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
1968 }
1969
1970 void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
1971 {
1972         if (location == -1)
1973                 return;
1974
1975         GPU_CHECK_ERRORS_AROUND(glUniform1iARB(location, value));
1976 }
1977
1978 void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int output, int number)
1979 {
1980         glProgramParameteriEXT(shader->object, GL_GEOMETRY_INPUT_TYPE_EXT, input);
1981         glProgramParameteriEXT(shader->object, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
1982         glProgramParameteriEXT(shader->object, GL_GEOMETRY_VERTICES_OUT_EXT, number);
1983 }
1984
1985 void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
1986 {
1987         GLenum arbnumber;
1988
1989         if (tex->number >= GG.maxtextures) {
1990                 fprintf(stderr, "Not enough texture slots.");
1991                 return;
1992         }
1993                 
1994         if (tex->number == -1)
1995                 return;
1996
1997         if (location == -1)
1998                 return;
1999
2000         GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
2001
2002         arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
2003
2004         if (tex->number != 0) glActiveTextureARB(arbnumber);
2005         if (tex->bindcode != 0)
2006                 glBindTexture(tex->target, tex->bindcode);
2007         else
2008                 GPU_invalid_tex_bind(tex->target);
2009         glUniform1iARB(location, tex->number);
2010         glEnable(tex->target);
2011         if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
2012
2013         GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
2014 }
2015
2016 int GPU_shader_get_attribute(GPUShader *shader, const char *name)
2017 {
2018         int index;
2019         
2020         GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocationARB(shader->object, name));
2021
2022         return index;
2023 }
2024
2025 GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
2026 {
2027         GPUShader *retval = NULL;
2028
2029         switch (shader) {
2030                 case GPU_SHADER_VSM_STORE:
2031                         if (!GG.shaders.vsm_store)
2032                                 GG.shaders.vsm_store = GPU_shader_create(datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl, NULL, NULL, NULL, 0, 0, 0);
2033                         retval = GG.shaders.vsm_store;
2034                         break;
2035                 case GPU_SHADER_SEP_GAUSSIAN_BLUR:
2036                         if (!GG.shaders.sep_gaussian_blur)
2037                                 GG.shaders.sep_gaussian_blur = GPU_shader_create(datatoc_gpu_shader_sep_gaussian_blur_vert_glsl, datatoc_gpu_shader_sep_gaussian_blur_frag_glsl, NULL, NULL, NULL, 0, 0, 0);
2038                         retval = GG.shaders.sep_gaussian_blur;
2039                         break;
2040         }
2041
2042         if (retval == NULL)
2043                 printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
2044
2045         return retval;
2046 }
2047
2048 GPUProgram *GPU_shader_get_builtin_program(GPUBuiltinProgram program)
2049 {
2050         GPUProgram *retval = NULL;
2051
2052         switch (program) {
2053                 case GPU_PROGRAM_SMOKE:
2054                         if (!GG.shaders.smoke)
2055                                 GG.shaders.smoke = GPU_program_shader_create(GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_frag_glsl);
2056                         retval = GG.shaders.smoke;
2057                         break;
2058                 case GPU_PROGRAM_SMOKE_COLORED:
2059                         if (!GG.shaders.smoke_colored)
2060                                 GG.shaders.smoke_colored = GPU_program_shader_create(GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_color_frag_glsl);
2061                         retval = GG.shaders.smoke_colored;
2062                         break;
2063         }
2064
2065         if (retval == NULL)
2066                 printf("Unable to create a GPUProgram for builtin program: %u\n", program);
2067
2068         return retval;
2069 }
2070
2071 #define MAX_DEFINES 100
2072
2073 GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
2074 {
2075         int offset;
2076         char defines[MAX_DEFINES] = "";
2077         /* avoid shaders out of range */
2078         if (effects >= MAX_FX_SHADERS)
2079                 return NULL;
2080
2081         offset = 2 * effects;
2082
2083         if (persp) {
2084                 offset += 1;
2085                 strcat(defines, "#define PERSP_MATRIX\n");
2086         }
2087
2088         if (!GG.shaders.fx_shaders[offset]) {
2089                 GPUShader *shader;
2090
2091                 switch (effects) {
2092                         case GPU_SHADER_FX_SSAO:
2093                                 GG.shaders.fx_shaders[offset] = 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);
2094                                 break;
2095
2096                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
2097                                 strcat(defines, "#define FIRST_PASS\n");
2098                                 GG.shaders.fx_shaders[offset] = 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);
2099                                 break;
2100
2101                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
2102                                 strcat(defines, "#define SECOND_PASS\n");
2103                                 GG.shaders.fx_shaders[offset] = 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);
2104                                 break;
2105
2106                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
2107                                 strcat(defines, "#define THIRD_PASS\n");
2108                                 GG.shaders.fx_shaders[offset] = 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);
2109                                 break;
2110
2111                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
2112                                 strcat(defines, "#define FOURTH_PASS\n");
2113                                 GG.shaders.fx_shaders[offset] = 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);
2114                                 break;
2115
2116                         case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
2117                                 strcat(defines, "#define FIFTH_PASS\n");
2118                                 GG.shaders.fx_shaders[offset] = 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);
2119                                 break;
2120
2121                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE:
2122                                 strcat(defines, "#define FIRST_PASS\n");
2123                                 GG.shaders.fx_shaders[offset] = 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);
2124                                 break;
2125
2126                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO:
2127                                 strcat(defines, "#define SECOND_PASS\n");
2128                                 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,
2129                                                                                    defines, GL_POINTS, GL_TRIANGLE_STRIP, 4);
2130                                 GG.shaders.fx_shaders[offset] = shader;
2131                                 break;
2132
2133                         case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE:
2134                                 strcat(defines, "#define THIRD_PASS\n");
2135                                 GG.shaders.fx_shaders[offset] = 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);
2136                                 break;
2137
2138                         case GPU_SHADER_FX_DEPTH_RESOLVE:
2139                                 GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0);
2140                 }
2141         }
2142
2143         return GG.shaders.fx_shaders[offset];
2144 }
2145
2146
2147 void GPU_shader_free_builtin_shaders(void)
2148 {
2149         int i;
2150
2151         if (GG.shaders.vsm_store) {
2152                 GPU_shader_free(GG.shaders.vsm_store);
2153                 GG.shaders.vsm_store = NULL;
2154         }
2155
2156         if (GG.shaders.sep_gaussian_blur) {
2157                 GPU_shader_free(GG.shaders.sep_gaussian_blur);
2158                 GG.shaders.sep_gaussian_blur = NULL;
2159         }
2160
2161         if (GG.shaders.smoke) {
2162                 GPU_program_free(GG.shaders.smoke);
2163                 GG.shaders.smoke = NULL;
2164         }
2165
2166         if (GG.shaders.smoke_colored) {
2167                 GPU_program_free(GG.shaders.smoke_colored);
2168                 GG.shaders.smoke_colored = NULL;
2169         }
2170
2171         for (i = 0; i < 2 * MAX_FX_SHADERS; i++) {
2172                 if (GG.shaders.fx_shaders[i]) {
2173                         GPU_shader_free(GG.shaders.fx_shaders[i]);
2174                         GG.shaders.fx_shaders[i] = NULL;
2175                 }
2176         }
2177 }
2178
2179 bool GPU_mem_stats_supported(void)
2180 {
2181         return (GLEW_NVX_gpu_memory_info || (GLEW_ATI_meminfo)) && (G.debug & G_DEBUG_GPU_MEM);
2182 }
2183
2184
2185 void GPU_mem_stats_get(int *totalmem, int *freemem)
2186 {
2187         if (GLEW_NVX_gpu_memory_info) {
2188                 /* returned value in Kb */
2189                 glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem);
2190
2191                 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem);
2192         }
2193         else if (GLEW_ATI_meminfo) {
2194                 int stats[4];
2195
2196                 glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats);
2197                 *freemem = stats[0];
2198                 *totalmem = 0;
2199         }
2200         else {
2201                 *totalmem = 0;
2202                 *freemem = 0;
2203         }
2204 }
2205
2206
2207 #if 0 /* unused */
2208
2209 /* GPUPixelBuffer */
2210
2211 typedef struct GPUPixelBuffer {
2212         GLuint bindcode[2];
2213         GLuint current;
2214         int datasize;
2215         int numbuffers;
2216         int halffloat;
2217 } GPUPixelBuffer;
2218
2219 void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
2220 {
2221         if (pb->bindcode[0])
2222                 glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
2223         MEM_freeN(pb);
2224 }
2225
2226 GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
2227 {
2228         GPUPixelBuffer *pb;
2229
2230         if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
2231                 return NULL;
2232         
2233         pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
2234         pb->datasize = x * y * 4 * (halffloat ? 16 : 8);
2235         pb->numbuffers = numbuffers;
2236         pb->halffloat = halffloat;
2237
2238         glGenBuffersARB(pb->numbuffers, pb->bindcode);
2239
2240         if (!pb->bindcode[0]) {
2241                 fprintf(stderr, "GPUPixelBuffer allocation failed\n");
2242                 GPU_pixelbuffer_free(pb);
2243                 return NULL;
2244         }
2245
2246         return pb;
2247 }
2248
2249 void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
2250 {
2251         void *pixels;
2252         int i;
2253
2254         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
2255
2256         for (i = 0; i < pb->numbuffers; i++) {
2257                 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
2258                 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
2259                 GL_STREAM_DRAW_ARB);
2260
2261                 pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
2262
2263 #  if 0
2264                 memcpy(pixels, _oImage.data(), pb->datasize);
2265 #  endif
2266
2267                 if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
2268                         fprintf(stderr, "Could not unmap OpenGL PBO\n");
2269                         break;
2270                 }
2271         }
2272
2273         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
2274 }
2275
2276 static int pixelbuffer_map_into_gpu(GLuint bindcode)
2277 {
2278         void *pixels;
2279
2280         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
2281         pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
2282
2283         /* do stuff in pixels */
2284
2285         if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
2286                 fprintf(stderr, "Could not unmap OpenGL PBO\n");
2287                 return 0;
2288         }
2289         
2290         return 1;
2291 }
2292
2293 static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
2294 {
2295         GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
2296         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
2297         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
2298
2299         glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h, GL_RGBA, type, NULL);
2300
2301         glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
2302         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
2303 }
2304
2305 void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
2306 {
2307         int newbuffer;
2308
2309         if (pb->numbuffers == 1) {
2310                 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
2311                 pixelbuffer_map_into_gpu(pb->bindcode[0]);
2312         }
2313         else {
2314                 pb->current = (pb->current + 1) % pb->numbuffers;
2315                 newbuffer = (pb->current + 1) % pb->numbuffers;
2316
2317                 pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
2318                 pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);
2319         }
2320 }
2321 #endif /* unused */
2322