diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-06-29 18:10:42 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-06-29 18:10:42 +0300 |
commit | 58d6cbba6da31db8dc8a2b42d528b9a353081904 (patch) | |
tree | 04b57a2f809c6f08d84a082edf061f3ece631860 /source/blender/gpu/intern/gpu_extensions.c | |
parent | 94549adec4b6857fb6ec4cf77606da51ff7c26b7 (diff) | |
parent | 295d0c52a26730edc6d4ed1276e4051cce006be5 (diff) |
Merge branch 'master' into temp-ghash-setopstemp-ghash-setops
Diffstat (limited to 'source/blender/gpu/intern/gpu_extensions.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 372 |
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 */ |