diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_blend.c | 42 | ||||
-rw-r--r-- | src/gallium/state_trackers/python/SConscript | 13 | ||||
-rwxr-xr-x | src/gallium/state_trackers/python/retrace/interpreter.py | 20 | ||||
-rw-r--r-- | src/gallium/state_trackers/python/samples/tri.py | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/python/st_device.c | 8 | ||||
-rw-r--r-- | src/gallium/state_trackers/python/st_hardpipe_winsys.c | 181 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/SConscript | 1 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/shared/stw_extgallium.c | 79 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/shared/stw_extgallium.h | 47 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c | 7 | ||||
-rw-r--r-- | src/mesa/main/attrib.c | 8 | ||||
-rw-r--r-- | src/mesa/main/imports.c | 125 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 7 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 23 |
14 files changed, 472 insertions, 91 deletions
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index e134e443374..b1e18805c70 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -72,6 +72,24 @@ do { \ R[3] = A[3] - B[3]; \ } while (0) +/** Add and limit result to ceiling of 1.0 */ +#define VEC4_ADD_SAT(R, A, B) \ +do { \ + R[0] = A[0] + B[0]; if (R[0] > 1.0f) R[0] = 1.0f; \ + R[1] = A[1] + B[1]; if (R[1] > 1.0f) R[1] = 1.0f; \ + R[2] = A[2] + B[2]; if (R[2] > 1.0f) R[2] = 1.0f; \ + R[3] = A[3] + B[3]; if (R[3] > 1.0f) R[3] = 1.0f; \ +} while (0) + +/** Subtract and limit result to floor of 0.0 */ +#define VEC4_SUB_SAT(R, A, B) \ +do { \ + R[0] = A[0] - B[0]; if (R[0] < 0.0f) R[0] = 0.0f; \ + R[1] = A[1] - B[1]; if (R[1] < 0.0f) R[1] = 0.0f; \ + R[2] = A[2] - B[2]; if (R[2] < 0.0f) R[2] = 0.0f; \ + R[3] = A[3] - B[3]; if (R[3] < 0.0f) R[3] = 0.0f; \ +} while (0) + #define VEC4_MUL(R, A, B) \ do { \ R[0] = A[0] * B[0]; \ @@ -676,19 +694,19 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) */ switch (softpipe->blend->rgb_func) { case PIPE_BLEND_ADD: - VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */ - VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */ - VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */ + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ break; case PIPE_BLEND_SUBTRACT: - VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */ - VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */ - VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */ + VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ break; case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */ - VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */ - VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */ + VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ break; case PIPE_BLEND_MIN: VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ @@ -709,13 +727,13 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) */ switch (softpipe->blend->alpha_func) { case PIPE_BLEND_ADD: - VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */ + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ break; case PIPE_BLEND_SUBTRACT: - VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */ + VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ break; case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */ + VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ break; case PIPE_BLEND_MIN: VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 1581182aec2..ec385e7c447 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -15,6 +15,19 @@ if 'python' in env['statetrackers']: env.Append(CPPPATH = '.') + if env['platform'] == 'windows': + env.Append(LIBS = [ + 'opengl32', + 'gdi32', + 'user32', + 'kernel32', + ]) + else: + env.Append(LIBS = [ + 'GL', + 'X11', + ]) + pyst = env.ConvenienceLibrary( target = 'pyst', source = [ diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 5885e162c28..6f0bd6ae52a 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -456,6 +456,7 @@ class Context(Object): x, y, z, w = unpack_from(format, data, offset) sys.stdout.write('\tCONST[%2u] = {%10.4f, %10.4f, %10.4f, %10.4f}\n' % (index, x, y, z, w)) index += 1 + sys.stdout.flush() def set_constant_buffer(self, shader, index, buffer): if buffer is not None: @@ -537,6 +538,7 @@ class Context(Object): sys.stdout.write('\t\t{' + ', '.join(map(str, values)) + '},\n') assert len(values) == velem.nr_components sys.stdout.write('\t},\n') + sys.stdout.flush() def dump_indices(self, ibuf, isize, start, count): if not self.interpreter.verbosity(2): @@ -564,6 +566,7 @@ class Context(Object): minindex = min(minindex, index) maxindex = max(maxindex, index) sys.stdout.write('\t},\n') + sys.stdout.flush() return minindex, maxindex @@ -591,6 +594,20 @@ class Context(Object): self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) self._set_dirty() + def surface_copy(self, dest, destx, desty, src, srcx, srcy, width, height): + if dest is not None and src is not None: + if self.interpreter.options.all: + self.interpreter.present(src, 'surface_copy_src', srcx, srcy, width, height) + self.real.surface_copy(dest, destx, desty, src, srcx, srcy, width, height) + if dest in self.cbufs: + self._set_dirty() + flags = gallium.PIPE_FLUSH_FRAME + else: + flags = 0 + self.flush(flags) + if self.interpreter.options.all: + self.interpreter.present(dest, 'surface_copy_dest', destx, desty, width, height) + def is_texture_referenced(self, texture, face, level): #return self.real.is_texture_referenced(format, texture, face, level) pass @@ -660,7 +677,7 @@ class Interpreter(parser.TraceDumper): self.interpret_call(call) def handle_call(self, call): - if self.options.stop and call.no >= self.options.stop: + if self.options.stop and call.no > self.options.stop: sys.exit(0) if (call.klass, call.method) in self.ignore_calls: @@ -670,6 +687,7 @@ class Interpreter(parser.TraceDumper): if self.verbosity(1): parser.TraceDumper.handle_call(self, call) + sys.stdout.flush() args = [(str(name), self.interpret_arg(arg)) for name, arg in call.args] diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index 4b9659861df..b721e0b5750 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -139,7 +139,7 @@ def test(dev): tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET, ).get_surface() zbuf = dev.texture_create( - PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z16_UNORM, width, height, tex_usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL, ).get_surface() diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 8246b378ce0..ea7d18738f6 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -44,8 +44,14 @@ static void st_device_really_destroy(struct st_device *st_dev) { - if(st_dev->screen) + if(st_dev->screen) { + /* FIXME: Don't really destroy until we keep track of every single + * reference or we end up causing a segmentation fault every time + * python exits. */ +#if 0 st_dev->screen->destroy(st_dev->screen); +#endif + } FREE(st_dev); } diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c index 8b33c70fd71..43aaaabf2a1 100644 --- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -28,31 +28,206 @@ /** * @file - * Stub for hardware pipe driver support. + * Get a hardware accelerated Gallium screen/context from the OpenGL driver. */ #include "pipe/p_compiler.h" +#ifdef PIPE_OS_WINDOWS +#include <windows.h> +#include <GL/gl.h> +#else +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <GL/gl.h> +#include <GL/glx.h> +#endif + #include "st_winsys.h" +typedef struct pipe_screen * (GLAPIENTRY *PFNGETGALLIUMSCREENMESAPROC) (void); +typedef struct pipe_context * (GLAPIENTRY* PFNCREATEGALLIUMCONTEXTMESAPROC) (void); + +static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL; +static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL; + + /* XXX: Force init_gallium symbol to be linked */ extern void init_gallium(void); void (*force_init_gallium_linkage)(void) = &init_gallium; +#ifdef PIPE_OS_WINDOWS + +static INLINE boolean +st_hardpipe_load(void) +{ + WNDCLASS wc; + HWND hwnd; + HGLRC hglrc; + HDC hdc; + PIXELFORMATDESCRIPTOR pfd; + int iPixelFormat; + + if(pfnGetGalliumScreenMESA && pfnCreateGalliumContextMESA) + return TRUE; + + memset(&wc, 0, sizeof wc); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = "gallium"; + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow(wc.lpszClassName, "gallium", 0, 0, 0, 0, 0, NULL, 0, wc.hInstance, NULL); + if (!hwnd) + return FALSE; + + hdc = GetDC(hwnd); + if (!hdc) + return FALSE; + + pfd.cColorBits = 3; + pfd.cRedBits = 1; + pfd.cGreenBits = 1; + pfd.cBlueBits = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.iLayerType = PFD_MAIN_PLANE; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + + iPixelFormat = ChoosePixelFormat(hdc, &pfd); + if (!iPixelFormat) { + pfd.dwFlags |= PFD_DOUBLEBUFFER; + iPixelFormat = ChoosePixelFormat(hdc, &pfd); + } + if (!iPixelFormat) + return FALSE; + + SetPixelFormat(hdc, iPixelFormat, &pfd); + hglrc = wglCreateContext(hdc); + if (!hglrc) + return FALSE; + + if (!wglMakeCurrent(hdc, hglrc)) + return FALSE; + + pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)wglGetProcAddress("wglGetGalliumScreenMESA"); + if(!pfnGetGalliumScreenMESA) + return FALSE; + + pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)wglGetProcAddress("wglCreateGalliumContextMESA"); + if(!pfnCreateGalliumContextMESA) + return FALSE; + + DestroyWindow(hwnd); + + return TRUE; +} + +#else + +static INLINE boolean +st_hardpipe_load(void) +{ + Display *dpy; + int scrnum; + Window root; + int attribSingle[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None }; + int attribDouble[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None }; + XVisualInfo *visinfo; + GLXContext ctx = NULL; + XSetWindowAttributes attr; + unsigned long mask; + int width = 100, height = 100; + Window win; + + dpy = XOpenDisplay(NULL); + if (!dpy) + return FALSE; + + scrnum = 0; + + root = RootWindow(dpy, scrnum); + + visinfo = glXChooseVisual(dpy, scrnum, attribSingle); + if (!visinfo) + visinfo = glXChooseVisual(dpy, scrnum, attribDouble); + if (!visinfo) + return FALSE; + + ctx = glXCreateContext( dpy, visinfo, NULL, True ); + + if (!ctx) + return FALSE; + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask; + + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow(dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr); + + if (!glXMakeCurrent(dpy, win, ctx)) + return FALSE; + + pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXGetGalliumScreenMESA"); + if(!pfnGetGalliumScreenMESA) + return FALSE; + + pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXCreateGalliumContextMESA"); + if(!pfnCreateGalliumContextMESA) + return FALSE; + + glXDestroyContext(dpy, ctx); + XFree(visinfo); + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + + return TRUE; +} + +#endif + + static struct pipe_screen * st_hardpipe_screen_create(void) { - return st_softpipe_winsys.screen_create(); + if(st_hardpipe_load()) + return pfnGetGalliumScreenMESA(); + else + return st_softpipe_winsys.screen_create(); } static struct pipe_context * st_hardpipe_context_create(struct pipe_screen *screen) { - return st_softpipe_winsys.context_create(screen); + if(st_hardpipe_load()) { + if(screen == pfnGetGalliumScreenMESA()) + return pfnCreateGalliumContextMESA(); + else + return NULL; + } + else + return st_softpipe_winsys.context_create(screen); } diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index a0866574876..69b88618ecb 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -29,6 +29,7 @@ if env['platform'] in ['windows']: 'shared/stw_extensionsstring.c', 'shared/stw_extswapinterval.c', 'shared/stw_getprocaddress.c', + 'shared/stw_extgallium.c', 'shared/stw_arbpixelformat.c', 'shared/stw_tls.c', ] diff --git a/src/gallium/state_trackers/wgl/shared/stw_extgallium.c b/src/gallium/state_trackers/wgl/shared/stw_extgallium.c new file mode 100644 index 00000000000..fc22737d7e3 --- /dev/null +++ b/src/gallium/state_trackers/wgl/shared/stw_extgallium.c @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_screen.h" +#include "stw_public.h" +#include "stw_device.h" +#include "stw_winsys.h" + +#ifdef DEBUG +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + + +struct pipe_screen * APIENTRY +wglGetGalliumScreenMESA(void) +{ + return stw_dev ? stw_dev->screen : NULL; +} + + +/* XXX: Unify with stw_create_layer_context */ +struct pipe_context * APIENTRY +wglCreateGalliumContextMESA(void) +{ + struct pipe_screen *screen = NULL; + struct pipe_context *pipe = NULL; + + if(!stw_dev) + return NULL; + + screen = stw_dev->screen; + +#ifdef DEBUG + /* Unwrap screen */ + if(stw_dev->trace_running) + screen = trace_screen(screen)->screen; +#endif + + pipe = stw_dev->stw_winsys->create_context( screen ); + if (pipe == NULL) + goto no_pipe; + +#ifdef DEBUG + /* Wrap context */ + if(stw_dev->trace_running) + pipe = trace_context_create(stw_dev->screen, pipe); +#endif + + return pipe; + +no_pipe: + return NULL; +} diff --git a/src/gallium/state_trackers/wgl/shared/stw_extgallium.h b/src/gallium/state_trackers/wgl/shared/stw_extgallium.h new file mode 100644 index 00000000000..cc35f2bb7fe --- /dev/null +++ b/src/gallium/state_trackers/wgl/shared/stw_extgallium.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_EXTGALLIUM_H_ +#define STW_EXTGALLIUM_H_ + + +#include <windows.h> + + +struct pipe_screen; +struct pipe_context; + + +struct pipe_screen * APIENTRY +wglGetGalliumScreenMESA(void); + + +struct pipe_context * APIENTRY +wglCreateGalliumContextMESA(void); + + +#endif /* STW_EXTGALLIUM_H_ */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c index 54cc0389059..879ced925a5 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c +++ b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c @@ -34,6 +34,7 @@ #include "glapi/glapi.h" #include "stw_public.h" +#include "stw_extgallium.h" struct stw_extension_entry { @@ -60,6 +61,10 @@ static const struct stw_extension_entry stw_extension_entries[] = { STW_EXTENSION_ENTRY( wglGetSwapIntervalEXT ), STW_EXTENSION_ENTRY( wglSwapIntervalEXT ), + /* WGL_EXT_gallium ? */ + STW_EXTENSION_ENTRY( wglGetGalliumScreenMESA ), + STW_EXTENSION_ENTRY( wglCreateGalliumContextMESA ), + { NULL, NULL } }; @@ -75,7 +80,7 @@ stw_get_proc_address( return entry->proc; if (lpszProc[0] == 'g' && lpszProc[1] == 'l') - return (PROC) _glapi_get_proc_address( lpszProc ); + return (PROC) _glapi_get_proc_address( lpszProc ); return NULL; } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 476a24434cc..cb49c4cb076 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -849,7 +849,6 @@ pop_texture_group(GLcontext *ctx, struct texture_state *texstate) /* Restore texture object state for each target */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { const struct gl_texture_object *obj = NULL; - GLfloat bordColor[4]; GLenum target; obj = &texstate->SavedObj[u][tgt]; @@ -875,12 +874,7 @@ pop_texture_group(GLcontext *ctx, struct texture_state *texstate) _mesa_BindTexture(target, obj->Name); - bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]); - bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]); - bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]); - bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]); - - _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor); + _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, obj->BorderColor); _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS); _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT); diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 3fb67083a2d..1722579e82c 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -1021,6 +1021,22 @@ output_if_debug(const char *prefixString, const char *outputString, } } +static const char *error_string( GLenum error ); + +static void flush_delayed_errors( GLcontext *ctx ) +{ + char s2[MAXSTRING]; + + if (ctx->ErrorDebugCount) { + _mesa_snprintf(s2, MAXSTRING, "%d similar %s errors", + ctx->ErrorDebugCount, + error_string(ctx->ErrorValue)); + + output_if_debug("Mesa: ", s2, GL_TRUE); + + ctx->ErrorDebugCount = 0; + } +} /** * Report a warning (a recoverable error condition) to stderr if @@ -1034,10 +1050,12 @@ _mesa_warning( GLcontext *ctx, const char *fmtString, ... ) { char str[MAXSTRING]; va_list args; - (void) ctx; va_start( args, fmtString ); (void) vsnprintf( str, MAXSTRING, fmtString, args ); va_end( args ); + + if (ctx) + flush_delayed_errors( ctx ); output_if_debug("Mesa warning", str, GL_TRUE); } @@ -1065,6 +1083,31 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) fprintf(stderr, "Please report at bugzilla.freedesktop.org\n"); } +static const char *error_string( GLenum error ) +{ + switch (error) { + case GL_NO_ERROR: + return "GL_NO_ERROR"; + case GL_INVALID_VALUE: + return "GL_INVALID_VALUE"; + case GL_INVALID_ENUM: + return "GL_INVALID_ENUM"; + case GL_INVALID_OPERATION: + return "GL_INVALID_OPERATION"; + case GL_STACK_OVERFLOW: + return "GL_STACK_OVERFLOW"; + case GL_STACK_UNDERFLOW: + return "GL_STACK_UNDERFLOW"; + case GL_OUT_OF_MEMORY: + return "GL_OUT_OF_MEMORY"; + case GL_TABLE_TOO_LARGE: + return "GL_TABLE_TOO_LARGE"; + case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: + return "GL_INVALID_FRAMEBUFFER_OPERATION"; + default: + return "unknown"; + } +} /** * Record an OpenGL state error. These usually occur when the user @@ -1081,74 +1124,46 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) void _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) { - const char *debugEnv; - GLboolean debug; + static GLint debug = -1; - debugEnv = _mesa_getenv("MESA_DEBUG"); + /* Check debug environment variable only once: + */ + if (debug == -1) { + const char *debugEnv = _mesa_getenv("MESA_DEBUG"); #ifdef DEBUG - if (debugEnv && _mesa_strstr(debugEnv, "silent")) - debug = GL_FALSE; - else - debug = GL_TRUE; + if (debugEnv && _mesa_strstr(debugEnv, "silent")) + debug = GL_FALSE; + else + debug = GL_TRUE; #else - if (debugEnv) - debug = GL_TRUE; - else - debug = GL_FALSE; + if (debugEnv) + debug = GL_TRUE; + else + debug = GL_FALSE; #endif + } - if (debug) { - va_list args; - char where[MAXSTRING]; - const char *errstr; - - va_start( args, fmtString ); - vsnprintf( where, MAXSTRING, fmtString, args ); - va_end( args ); - - switch (error) { - case GL_NO_ERROR: - errstr = "GL_NO_ERROR"; - break; - case GL_INVALID_VALUE: - errstr = "GL_INVALID_VALUE"; - break; - case GL_INVALID_ENUM: - errstr = "GL_INVALID_ENUM"; - break; - case GL_INVALID_OPERATION: - errstr = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - errstr = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - errstr = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - errstr = "GL_OUT_OF_MEMORY"; - break; - case GL_TABLE_TOO_LARGE: - errstr = "GL_TABLE_TOO_LARGE"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: - errstr = "GL_INVALID_FRAMEBUFFER_OPERATION"; - break; - default: - errstr = "unknown"; - break; + if (debug) { + if (ctx->ErrorValue == error && + ctx->ErrorDebugFmtString == fmtString) { + ctx->ErrorDebugCount++; } - - { + else { char s[MAXSTRING], s2[MAXSTRING]; va_list args; + + flush_delayed_errors( ctx ); + va_start(args, fmtString); vsnprintf(s, MAXSTRING, fmtString, args); va_end(args); - _mesa_snprintf(s2, MAXSTRING, "%s in %s", errstr, s); + _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s); output_if_debug("Mesa: User error", s2, GL_TRUE); + + ctx->ErrorDebugFmtString = fmtString; + ctx->ErrorDebugCount = 0; } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d7e7d2ac21e..d0309f5e90d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2986,6 +2986,13 @@ struct __GLcontextRec #endif GLenum ErrorValue; /**< Last error code */ + + /** + * Recognize and silence repeated error debug messages in buggy apps. + */ + const char *ErrorDebugFmtString; + GLuint ErrorDebugCount; + GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 909189f9d39..15f84b66382 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -237,14 +237,12 @@ do_memcpy(void *dest, const void *src, size_t n) } -static int -logbase2(int n) +static INLINE unsigned +logbase2(unsigned n) { - GLint i = 1, log2 = 0; - while (n > i) { - i *= 2; - log2++; - } + unsigned log2 = 0; + while (n >>= 1) + ++log2; return log2; } @@ -950,8 +948,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* Image is stored in hardware format in a buffer managed by the * kernel. Need to explicitly map and unmap it. */ + unsigned face = _mesa_tex_target_to_face(target); - st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, PIPE_TRANSFER_READ); texImage->Data = st_texture_image_map(ctx->st, stImage, 0, @@ -1080,13 +1079,15 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, * from uploading the buffer under us. */ if (stImage->pt) { + unsigned face = _mesa_tex_target_to_face(target); + if (format == GL_DEPTH_COMPONENT && pf_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; - st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, transfer_usage); texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, transfer_usage, @@ -1213,7 +1214,9 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, int y; if (stImage->pt) { - st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, + unsigned face = _mesa_tex_target_to_face(target); + + st_teximage_flush_before_map(ctx->st, stImage->pt, face, level, PIPE_TRANSFER_WRITE); texImage->Data = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE, |