Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_extensions.c')
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c372
1 files changed, 298 insertions, 74 deletions
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index b4ffc978d11..b757aff4bdb 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -40,6 +40,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
+#include "BLI_math_vector.h"
#include "BKE_global.h"
@@ -76,6 +77,8 @@
*/
/* Non-generated shaders */
+extern char datatoc_gpu_program_smoke_frag_glsl[];
+extern char datatoc_gpu_program_smoke_color_frag_glsl[];
extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
@@ -93,6 +96,8 @@ extern char datatoc_gpu_shader_fx_lib_glsl[];
typedef struct GPUShaders {
GPUShader *vsm_store;
GPUShader *sep_gaussian_blur;
+ GPUProgram *smoke;
+ GPUProgram *smoke_colored;
/* cache for shader fx. Those can exist in combinations so store them here */
GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
} GPUShaders;
@@ -113,6 +118,9 @@ static struct GPUGlobal {
GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */
GPUTexture *invalid_tex_2D;
GPUTexture *invalid_tex_3D;
+ float dfdyfactors[2]; /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers
+ calculate dfdy in shader differently when drawing to an offscreen buffer. First
+ number is factor on screen and second is off-screen */
} GG = {1, 0};
/* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
@@ -144,10 +152,15 @@ int GPU_max_texture_size(void)
return GG.maxtexsize;
}
+void GPU_get_dfdy_factors(float fac[2])
+{
+ copy_v2_v2(fac, GG.dfdyfactors);
+}
+
void gpu_extensions_init(void)
{
GLint r, g, b;
- const char *vendor, *renderer;
+ const char *vendor, *renderer, *version;
/* glewIsSupported("GL_VERSION_2_0") */
@@ -164,10 +177,11 @@ void gpu_extensions_init(void)
glGetIntegerv(GL_RED_BITS, &r);
glGetIntegerv(GL_GREEN_BITS, &g);
glGetIntegerv(GL_BLUE_BITS, &b);
- GG.colordepth = r+g+b; /* assumes same depth for RGB */
+ GG.colordepth = r + g + b; /* assumes same depth for RGB */
vendor = (const char *)glGetString(GL_VENDOR);
renderer = (const char *)glGetString(GL_RENDERER);
+ version = (const char *)glGetString(GL_VERSION);
if (strstr(vendor, "ATI")) {
GG.device = GPU_DEVICE_ATI;
@@ -244,6 +258,27 @@ void gpu_extensions_init(void)
#endif
+ /* df/dy calculation factors, those are dependent on driver */
+ if ((strstr(vendor, "ATI") && strstr(version, "3.3.10750"))) {
+ GG.dfdyfactors[0] = 1.0;
+ GG.dfdyfactors[1] = -1.0;
+ }
+ else if (GG.device == GPU_DEVICE_INTEL && GG.os == GPU_OS_WIN &&
+ (strstr(version, "4.0.0 - Build 10.18.10.3308") ||
+ strstr(version, "4.0.0 - Build 9.18.10.3186") ||
+ strstr(version, "4.0.0 - Build 9.18.10.3165") ||
+ strstr(version, "3.1.0 - Build 9.17.10.3347") ||
+ strstr(version, "3.1.0 - Build 9.17.10.4101")))
+ {
+ GG.dfdyfactors[0] = -1.0;
+ GG.dfdyfactors[1] = 1.0;
+ }
+ else {
+ GG.dfdyfactors[0] = 1.0;
+ GG.dfdyfactors[1] = 1.0;
+ }
+
+
GPU_invalid_tex_init();
GPU_simple_shaders_init();
}
@@ -299,34 +334,34 @@ int GPU_color_depth(void)
static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
{
- const char *err= "unknown";
+ const char *err = "unknown";
switch (status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_INVALID_OPERATION:
- err= "Invalid operation";
+ err = "Invalid operation";
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
- err= "Incomplete attachment";
+ err = "Incomplete attachment";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
- err= "Unsupported framebuffer format";
+ err = "Unsupported framebuffer format";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
- err= "Missing attachment";
+ err = "Missing attachment";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
- err= "Attached images must have same dimensions";
+ err = "Attached images must have same dimensions";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
- err= "Attached images must have same format";
+ err = "Attached images must have same format";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
- err= "Missing draw buffer";
+ err = "Missing draw buffer";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
- err= "Missing read buffer";
+ err = "Missing read buffer";
break;
}
@@ -343,28 +378,28 @@ static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
/* GPUTexture */
struct GPUTexture {
- int w, h; /* width/height */
- int number; /* number for multitexture binding */
- int refcount; /* reference count */
- GLenum target; /* GL_TEXTURE_* */
- GLuint bindcode; /* opengl identifier for texture */
- int fromblender; /* we got the texture from Blender */
-
- GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
- int fb_attachment; /* slot the texture is attached to */
- int depth; /* is a depth texture? if 3D how deep? */
+ int w, h; /* width/height */
+ int number; /* number for multitexture binding */
+ int refcount; /* reference count */
+ GLenum target; /* GL_TEXTURE_* */
+ GLuint bindcode; /* opengl identifier for texture */
+ int fromblender; /* we got the texture from Blender */
+
+ GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
+ int fb_attachment; /* slot the texture is attached to */
+ int depth; /* is a depth texture? if 3D how deep? */
};
static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixels)
{
unsigned char *pixels, *p;
const float *fp = fpixels;
- const int len = 4*length;
+ const int len = 4 * length;
int a;
- p = pixels = MEM_callocN(sizeof(unsigned char)*len, "GPUTexturePixels");
+ p = pixels = MEM_callocN(sizeof(unsigned char) * len, "GPUTexturePixels");
- for (a=0; a<len; a++, p++, fp++)
+ for (a = 0; a < len; a++, p++, fp++)
*p = FTOCHAR((*fp));
return pixels;
@@ -372,7 +407,7 @@ static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixel
static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
{
- void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels");
+ void *pixels = MEM_callocN(sizeof(char) * 4 * w * h, "GPUTextureEmptyPixels");
if (target == GL_TEXTURE_1D)
glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
@@ -530,7 +565,8 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
GPUTexture *tex;
GLenum type, format, internalformat;
void *pixels = NULL;
- const float vfBorderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ int r_width;
+ bool rescale = false;
if (!GLEW_VERSION_1_2)
return NULL;
@@ -573,35 +609,90 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, const f
internalformat = GL_INTENSITY;
}
- //if (fpixels)
- // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
+ /* 3D textures are quite heavy, test if it's possible to create them first */
+ glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
+ glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
+
+ while (r_width == 0) {
+ rescale = true;
+ tex->w /= 2;
+ tex->h /= 2;
+ tex->depth /= 2;
+ glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
+ glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
+ }
- glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
+ /* really unlikely to happen but keep this just in case */
+ tex->w = max_ii(tex->w, 1);
+ tex->h = max_ii(tex->h, 1);
+ tex->depth = max_ii(tex->depth, 1);
+
+#if 0
+ if (fpixels)
+ pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
+#endif
GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
- if (fpixels) {
- if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
- /* clear first to avoid unitialized pixels */
- float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero");
- glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, format, type, zero);
- MEM_freeN(zero);
+ /* hardcore stuff, 3D texture rescaling - warning, this is gonna hurt your performance a lot, but we need it
+ * for gooseberry */
+ if (rescale && fpixels) {
+ unsigned int i, j, k;
+ unsigned int xf = w / tex->w, yf = h / tex->h, zf = depth / tex->depth;
+ float *tex3d = MEM_mallocN(channels * sizeof(float)*tex->w*tex->h*tex->depth, "tex3d");
+
+ GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
+
+ for (k = 0; k < tex->depth; k++) {
+ for (j = 0; j < tex->h; j++) {
+ for (i = 0; i < tex->w; i++) {
+ /* obviously doing nearest filtering here, it's going to be slow in any case, let's not make it worse */
+ float xb = i * xf;
+ float yb = j * yf;
+ float zb = k * zf;
+ unsigned int offset = k * (tex->w * tex->h) + i * tex->h + j;
+ unsigned int offset_orig = (zb) * (w * h) + (xb) * h + (yb);
+
+ if (channels == 4) {
+ tex3d[offset * 4] = fpixels[offset_orig * 4];
+ tex3d[offset * 4 + 1] = fpixels[offset_orig * 4 + 1];
+ tex3d[offset * 4 + 2] = fpixels[offset_orig * 4 + 2];
+ tex3d[offset * 4 + 3] = fpixels[offset_orig * 4 + 3];
+ }
+ else
+ tex3d[offset] = fpixels[offset_orig];
+ }
+ }
}
- glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
- GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, tex3d);
+
+ MEM_freeN(tex3d);
+ }
+ else {
+ if (fpixels) {
+ if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
+ /* clear first to avoid unitialized pixels */
+ float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero");
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
+ glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, GL_INTENSITY, GL_FLOAT, zero);
+ glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
+ MEM_freeN(zero);
+ }
+ else {
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, fpixels);
+ }
+
+ GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
+ }
}
- glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor);
- GPU_ASSERT_NO_GL_ERRORS("3D GL_TEXTURE_BORDER_COLOR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- GPU_ASSERT_NO_GL_ERRORS("3D GL_LINEAR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- GPU_ASSERT_NO_GL_ERRORS("3D GL_CLAMP_TO_BORDER");
if (pixels)
MEM_freeN(pixels);
@@ -682,7 +773,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
tex->refcount = 1;
tex->target = GL_TEXTURE_2D;
- prv->gputexture[0]= tex;
+ prv->gputexture[0] = tex;
if (!glIsTexture(tex->bindcode)) {
GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
@@ -972,7 +1063,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
if (!GLEW_EXT_framebuffer_object)
return NULL;
- fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
+ fb = MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
glGenFramebuffersEXT(1, &fb->object);
if (!fb->object) {
@@ -1065,8 +1156,7 @@ void GPU_framebuffer_texture_detach(GPUTexture *tex)
attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment;
}
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
- tex->target, 0, 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, tex->target, 0, 0);
tex->fb = NULL;
tex->fb_attachment = -1;
@@ -1116,7 +1206,7 @@ void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
return;
}
- for (i = 0 ; i < 4; i++) {
+ for (i = 0; i < 4; i++) {
if (fb->colortex[i]) {
attachments[numslots] = GL_COLOR_ATTACHMENT0_EXT + i;
numslots++;
@@ -1306,7 +1396,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
{
GPUOffScreen *ofs;
- ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
+ ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
ofs->fb = GPU_framebuffer_create();
if (!ofs->fb) {
@@ -1395,24 +1485,30 @@ int GPU_offscreen_height(const GPUOffScreen *ofs)
/* GPUShader */
struct GPUShader {
- GLhandleARB object; /* handle for full shader */
- GLhandleARB vertex; /* handle for vertex shader */
- GLhandleARB fragment; /* handle for fragment shader */
- GLhandleARB geometry; /* handle for geometry shader */
- GLhandleARB lib; /* handle for libment shader */
- int totattrib; /* total number of attributes */
- int uniforms; /* required uniforms */
+ GLhandleARB object; /* handle for full shader */
+ GLhandleARB vertex; /* handle for vertex shader */
+ GLhandleARB fragment; /* handle for fragment shader */
+ GLhandleARB geometry; /* handle for geometry shader */
+ GLhandleARB lib; /* handle for libment shader */
+ int totattrib; /* total number of attributes */
+ int uniforms; /* required uniforms */
+};
+
+struct GPUProgram {
+ GPUProgramType type;
+ GLuint prog;
};
-static void shader_print_errors(const char *task, char *log, const char **code, int totcode)
+
+static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
{
int i;
+ int line = 1;
fprintf(stderr, "GPUShader: %s error:\n", task);
for (i = 0; i < totcode; i++) {
const char *c, *pos, *end = code[i] + strlen(code[i]);
- int line = 1;
if ((G.debug & G_DEBUG)) {
fprintf(stderr, "===== shader string %d ====\n", i + 1);
@@ -1420,8 +1516,8 @@ static void shader_print_errors(const char *task, char *log, const char **code,
c = code[i];
while ((c < end) && (pos = strchr(c, '\n'))) {
fprintf(stderr, "%2d ", line);
- fwrite(c, (pos+1)-c, 1, stderr);
- c = pos+1;
+ fwrite(c, (pos + 1) - c, 1, stderr);
+ c = pos + 1;
line++;
}
@@ -1447,7 +1543,7 @@ static const char *gpu_shader_version(void)
static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
{
- /* need this extensions for high quality bump mapping */
+ /* need this extension for high quality bump mapping */
if (GPU_bicubic_bump_support())
strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
@@ -1478,6 +1574,70 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
return;
}
+void GPU_program_bind(GPUProgram *program)
+{
+ glEnable(program->type);
+ glBindProgramARB(program->type, program->prog);
+}
+
+void GPU_program_unbind(GPUProgram *program)
+{
+ glDisable(program->type);
+ glBindProgramARB(program->type, 0);
+}
+
+
+GPUProgram *GPU_program_shader_create(GPUProgramType type, const char *code)
+{
+ GPUProgram *program;
+ GLint error_pos, is_native;
+
+ if (!(GLEW_ARB_fragment_program && type == GPU_PROGRAM_TYPE_FRAGMENT))
+ return NULL;
+
+ program = MEM_callocN(sizeof(GPUProgram), "GPUProgram");
+
+ switch (type) {
+ case GPU_PROGRAM_TYPE_FRAGMENT:
+ program->type = GL_FRAGMENT_PROGRAM_ARB;
+ break;
+ }
+
+ /* create the object and set its code string */
+ glGenProgramsARB(1, &program->prog);
+ glBindProgramARB(program->type, program->prog);
+
+ glProgramStringARB(program->type, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(code), code);
+
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
+ glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &is_native);
+ if ((error_pos == -1) && (is_native == 1)) {
+ return program;
+ }
+ else {
+ /* glGetError is set before that, clear it */
+ while (glGetError() != GL_NO_ERROR)
+ ;
+ shader_print_errors("compile", (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB), &code, 1);
+ MEM_freeN(program);
+ }
+
+ return NULL;
+}
+
+void GPU_program_free(GPUProgram *program)
+{
+ glDeleteProgramsARB(1, &program->prog);
+ MEM_freeN(program);
+}
+
+void GPU_program_parameter_4f(GPUProgram *program, unsigned int location, float x, float y, float z, float w)
+{
+ glProgramLocalParameter4fARB(program->type, location, x, y, z, w);
+}
+
+
+
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)
{
GLint status;
@@ -1793,7 +1953,30 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
}
if (retval == NULL)
- printf("Unable to create a GPUShader for builtin shader: %d\n", shader);
+ printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
+
+ return retval;
+}
+
+GPUProgram *GPU_shader_get_builtin_program(GPUBuiltinProgram program)
+{
+ GPUProgram *retval = NULL;
+
+ switch (program) {
+ case GPU_PROGRAM_SMOKE:
+ if (!GG.shaders.smoke)
+ GG.shaders.smoke = GPU_program_shader_create(GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_frag_glsl);
+ retval = GG.shaders.smoke;
+ break;
+ case GPU_PROGRAM_SMOKE_COLORED:
+ if (!GG.shaders.smoke_colored)
+ GG.shaders.smoke_colored = GPU_program_shader_create(GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_color_frag_glsl);
+ retval = GG.shaders.smoke_colored;
+ break;
+ }
+
+ if (retval == NULL)
+ printf("Unable to create a GPUProgram for builtin program: %u\n", program);
return retval;
}
@@ -1818,7 +2001,7 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
if (!GG.shaders.fx_shaders[offset]) {
GPUShader *shader;
- switch(effects) {
+ switch (effects) {
case GPU_SHADER_FX_SSAO:
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);
break;
@@ -1879,24 +2062,63 @@ void GPU_shader_free_builtin_shaders(void)
int i;
if (GG.shaders.vsm_store) {
- MEM_freeN(GG.shaders.vsm_store);
+ GPU_shader_free(GG.shaders.vsm_store);
GG.shaders.vsm_store = NULL;
}
if (GG.shaders.sep_gaussian_blur) {
- MEM_freeN(GG.shaders.sep_gaussian_blur);
+ GPU_shader_free(GG.shaders.sep_gaussian_blur);
GG.shaders.sep_gaussian_blur = NULL;
}
+ if (GG.shaders.smoke) {
+ GPU_program_free(GG.shaders.smoke);
+ GG.shaders.smoke = NULL;
+ }
+
+ if (GG.shaders.smoke_colored) {
+ GPU_program_free(GG.shaders.smoke_colored);
+ GG.shaders.smoke_colored = NULL;
+ }
+
for (i = 0; i < 2 * MAX_FX_SHADERS; i++) {
if (GG.shaders.fx_shaders[i]) {
- MEM_freeN(GG.shaders.fx_shaders[i]);
+ GPU_shader_free(GG.shaders.fx_shaders[i]);
GG.shaders.fx_shaders[i] = NULL;
}
}
}
-#if 0
+bool GPU_mem_stats_supported(void)
+{
+ return (GLEW_NVX_gpu_memory_info || (GLEW_ATI_meminfo)) && (G.debug & G_DEBUG_GPU_MEM);
+}
+
+
+void GPU_mem_stats_get(int *totalmem, int *freemem)
+{
+ if (GLEW_NVX_gpu_memory_info) {
+ /* returned value in Kb */
+ glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, totalmem);
+
+ glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, freemem);
+ }
+ else if (GLEW_ATI_meminfo) {
+ int stats[4];
+
+ glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats);
+ *freemem = stats[0];
+ *totalmem = 0;
+ }
+ else {
+ *totalmem = 0;
+ *freemem = 0;
+ }
+}
+
+
+#if 0 /* unused */
+
/* GPUPixelBuffer */
typedef struct GPUPixelBuffer {
@@ -1922,7 +2144,7 @@ GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffe
return NULL;
pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
- pb->datasize = x*y*4*((halffloat)? 16: 8);
+ pb->datasize = x * y * 4 * (halffloat ? 16 : 8);
pb->numbuffers = numbuffers;
pb->halffloat = halffloat;
@@ -1950,10 +2172,13 @@ void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
GL_STREAM_DRAW_ARB);
pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
- /*memcpy(pixels, _oImage.data(), pb->datasize);*/
+
+# if 0
+ memcpy(pixels, _oImage.data(), pb->datasize);
+# endif
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
- fprintf(stderr, "Could not unmap opengl PBO\n");
+ fprintf(stderr, "Could not unmap OpenGL PBO\n");
break;
}
}
@@ -1971,7 +2196,7 @@ static int pixelbuffer_map_into_gpu(GLuint bindcode)
/* do stuff in pixels */
if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
- fprintf(stderr, "Could not unmap opengl PBO\n");
+ fprintf(stderr, "Could not unmap OpenGL PBO\n");
return 0;
}
@@ -1984,8 +2209,7 @@ static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLu
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
- glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
- GL_RGBA, type, NULL);
+ glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h, GL_RGBA, type, NULL);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
@@ -2000,12 +2224,12 @@ void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
pixelbuffer_map_into_gpu(pb->bindcode[0]);
}
else {
- pb->current = (pb->current+1)%pb->numbuffers;
- newbuffer = (pb->current+1)%pb->numbuffers;
+ pb->current = (pb->current + 1) % pb->numbuffers;
+ newbuffer = (pb->current + 1) % pb->numbuffers;
pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);
}
}
-#endif
+#endif /* unused */