Date: Thu, 24 Apr 2003 15:13:47 -0400
authorSam Lantinga <slouken@libsdl.org>
Tue, 22 Jul 2003 15:10:06 +0000
changeset 655 9c42ee1b7d77
parent 654 e92bcf2573cb
child 656 864e2d2a9a55
Date: Thu, 24 Apr 2003 15:13:47 -0400 From: Shawn Kirst Subject: SDL-1.2.5 patch to add ARB_multisample support Attached is a patch I have written for SDL-1.2.5 that adds ARB_multisample support. I only have the X11 and Win32 video patched. The Win32 patch also adds support for WGL_ARB_pixel_format, as it was required for getting a multisample capable pixel format. No additional GL header files are required to compile on either platform (though you need an up-to-date glx.h for X11). Requesting a multisample pixel format is made possible using SDL_GL_SetAttribute with the two new SDL_GLattr's I've added (SDL_GL_SAMPLE_BUFFERS and SDL_GL_SAMPLES). I've been using SDL in my projects for quite a while now, so I am happy to contribute back to the project. Now you can have and control FSAA in your SDL/GL apps at the application level!
WhatsNew
include/SDL_video.h
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/wincommon/SDL_wingl.c
src/video/wincommon/SDL_wingl_c.h
src/video/x11/SDL_x11gl.c
test/testgl.c
--- a/WhatsNew	Tue Jul 22 14:01:21 2003 +0000
+++ b/WhatsNew	Tue Jul 22 15:10:06 2003 +0000
@@ -6,6 +6,8 @@
 1.2.6:
 	Added SDL_LoadObject(), SDL_LoadFunction(), and SDL_UnloadObject()
 
+	Added SDL_GL_SAMPLE_BUFFERS and SDL_GL_SAMPLES for FSAA support
+
 1.2.5:
 	Added SDL_BUTTON_WHEELUP (4) and SDL_BUTTON_WHEELDOWN (5)
 
--- a/include/SDL_video.h	Tue Jul 22 14:01:21 2003 +0000
+++ b/include/SDL_video.h	Tue Jul 22 15:10:06 2003 +0000
@@ -217,7 +217,9 @@
     SDL_GL_ACCUM_GREEN_SIZE,
     SDL_GL_ACCUM_BLUE_SIZE,
     SDL_GL_ACCUM_ALPHA_SIZE,
-	SDL_GL_STEREO
+    SDL_GL_STEREO,
+    SDL_GL_SAMPLE_BUFFERS,
+    SDL_GL_SAMPLES
 } SDL_GLattr;
 
 /* flags for SDL_SetPalette() */
--- a/src/video/SDL_sysvideo.h	Tue Jul 22 14:01:21 2003 +0000
+++ b/src/video/SDL_sysvideo.h	Tue Jul 22 15:10:06 2003 +0000
@@ -304,6 +304,8 @@
 		int accum_blue_size;
 		int accum_alpha_size;
 		int stereo;
+		int sample_buffers;
+		int samples;
 		int driver_loaded;
 		char driver_path[256];
 		void* dll_handle;
--- a/src/video/SDL_video.c	Tue Jul 22 14:01:21 2003 +0000
+++ b/src/video/SDL_video.c	Tue Jul 22 15:10:06 2003 +0000
@@ -233,6 +233,8 @@
 	video->gl_config.accum_blue_size = 0;
 	video->gl_config.accum_alpha_size = 0;
 	video->gl_config.stereo = 0;
+	video->gl_config.sample_buffers = 0;
+	video->gl_config.samples = 0;
 	
 	/* Initialize the video subsystem */
 	memset(&vformat, 0, sizeof(vformat));
@@ -1420,6 +1422,12 @@
 		case SDL_GL_STEREO:
 			video->gl_config.stereo = value;
 			break;
+		case SDL_GL_SAMPLE_BUFFERS:
+			video->gl_config.sample_buffers = value;
+			break;
+		case SDL_GL_SAMPLES:
+			video->gl_config.samples = value;
+			break;
 		default:
 			SDL_SetError("Unknown OpenGL attribute");
 			retval = -1;
--- a/src/video/wincommon/SDL_wingl.c	Tue Jul 22 14:01:21 2003 +0000
+++ b/src/video/wincommon/SDL_wingl.c	Tue Jul 22 15:10:06 2003 +0000
@@ -25,6 +25,8 @@
  "@(#) $Id$";
 #endif
 
+#include <string.h>
+
 /* WGL implementation of SDL OpenGL support */
 
 #ifdef HAVE_OPENGL
@@ -77,12 +79,60 @@
 	return(status);
 }
 
+static int Init_WGL_ARB_extensions(_THIS)
+{
+	HWND hwnd;
+	HDC hdc;
+	HGLRC hglrc;
+	int pformat;
+	const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0;
+	
+	hwnd = CreateWindow(NULL, "PFormat", WS_POPUP | WS_DISABLED,
+	                    0, 0, 10, 10,
+	                    NULL, NULL, SDL_Instance,NULL);
+	hdc = GetDC(hwnd);
+
+	pformat = ChoosePixelFormat(hdc, &GL_pfd);
+	SetPixelFormat(hdc, pformat, &GL_pfd);
+
+	hglrc = this->gl_data->wglCreateContext(hdc);
+	this->gl_data->wglMakeCurrent(hdc, hglrc);
+
+	wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC))
+		this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
+
+	if(wglGetExtensionsStringARB && strstr(wglGetExtensionsStringARB(hdc),"WGL_ARB_pixel_format")) {
+		this->gl_data->wglChoosePixelFormatARB =
+			(BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
+			this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
+		this->gl_data->wglGetPixelFormatAttribivARB =
+			(BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
+			this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+		if( (this->gl_data->wglChoosePixelFormatARB != NULL) &&
+		    (this->gl_data->wglGetPixelFormatAttribivARB != NULL) )
+			this->gl_data->wgl_arb_pixel_format = 1;
+		else 
+			this->gl_data->wgl_arb_pixel_format = 0;
+	} else {
+		this->gl_data->wgl_arb_pixel_format = 0;
+	}
+	
+	this->gl_data->wglMakeCurrent(NULL, NULL);
+	this->gl_data->wglDeleteContext(hglrc);
+	ReleaseDC(hwnd, hdc);
+	DestroyWindow(hwnd);
+}
+
 int WIN_GL_SetupWindow(_THIS)
 {
 	int retval;
 #ifdef HAVE_OPENGL
 	int i;
-	int pixel_format;
+	unsigned int matching;
+	int iAttribs[64];
+	int *iAttr;
+	float fAttribs[1] = { 0 };
 
 	/* load the gl driver from a default path */
 	if ( ! this->gl_config.driver_loaded ) {
@@ -127,13 +177,90 @@
 		GL_pfd.cDepthBits = this->gl_config.depth_size;
 		GL_pfd.cStencilBits = this->gl_config.stencil_size;
 
+		/* initialize WGL_ARB_pixel_format */
+		Init_WGL_ARB_extensions(this);
+
+		/* setup WGL_ARB_pixel_format attribs */
+		iAttr = &iAttribs[0];
+
+		*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
+		*iAttr++ = GL_TRUE;
+		*iAttr++ = WGL_ACCELERATION_ARB;
+		*iAttr++ = WGL_FULL_ACCELERATION_ARB;
+		*iAttr++ = WGL_RED_BITS_ARB;
+		*iAttr++ = this->gl_config.red_size;
+		*iAttr++ = WGL_GREEN_BITS_ARB;
+		*iAttr++ = this->gl_config.green_size;
+		*iAttr++ = WGL_BLUE_BITS_ARB;
+		*iAttr++ = this->gl_config.blue_size;
+		
+		if ( this->gl_config.alpha_size ) {
+			*iAttr++ = WGL_ALPHA_BITS_ARB;
+			*iAttr++ = this->gl_config.alpha_size;
+		}
+
+		if ( this->gl_config.double_buffer ) {
+			*iAttr ++ = WGL_DOUBLE_BUFFER_ARB;
+			*iAttr ++ = GL_TRUE;
+		}
+
+		*iAttr++ = WGL_DEPTH_BITS_ARB;
+		*iAttr++ = this->gl_config.depth_size;
+
+		if ( this->gl_config.stencil_size ) {
+			*iAttr++ = WGL_STENCIL_BITS_ARB;
+			*iAttr++ = this->gl_config.stencil_size;
+		}
+
+		if ( this->gl_config.accum_red_size ) {
+			*iAttr++ = WGL_ACCUM_RED_BITS_ARB;
+			*iAttr++ = this->gl_config.accum_red_size;
+		}
+
+		if ( this->gl_config.accum_green_size ) {
+			*iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
+			*iAttr++ = this->gl_config.accum_green_size;
+		}
+
+		if ( this->gl_config.accum_blue_size ) {
+			*iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
+			*iAttr++ = this->gl_config.accum_blue_size;
+		}
+
+		if ( this->gl_config.accum_alpha_size ) {
+			*iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
+			*iAttr++ = this->gl_config.accum_alpha_size;
+		}
+
+		if ( this->gl_config.stereo ) {
+			*iAttr++ = WGL_STEREO_ARB;
+			*iAttr++ = this->gl_config.stereo;
+		}
+
+		if ( this->gl_config.sample_buffers ) {
+			*iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
+			*iAttr++ = this->gl_config.sample_buffers;
+		}
+
+		if ( this->gl_config.samples ) {
+			*iAttr++ = WGL_SAMPLES_ARB;
+			*iAttr++ = this->gl_config.samples;
+		}
+
+		*iAttr = 0;
+
 		/* Choose and set the closest available pixel format */
-		pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
+		if ( !this->gl_data->wgl_arb_pixel_format ||
+		     !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs, fAttribs, 1, &pixel_format, &matching) ||
+		     !matching ) {
+			pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
+			this->gl_data->wgl_arb_pixel_format = 0;
+		}
 		if ( !pixel_format ) {
 			SDL_SetError("No matching GL pixel format available");
 			return(-1);
 		}
-		if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
+		if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
 			if ( i == 0 ) {
 				/* First time through, try resetting the window */
 				if ( WIN_GL_ResetWindow(this) < 0 ) {
@@ -150,7 +277,7 @@
 	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
 
 	GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
-	if( GL_hrc == NULL ) {
+	if ( GL_hrc == NULL ) {
 		SDL_SetError("Unable to create GL context");
 		return(-1);
 	}
@@ -204,9 +331,66 @@
 int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
 {
 	int retval;
+	
+	if ( this->gl_data->wgl_arb_pixel_format ) {
+		int wgl_attrib;
+
+		switch(attrib) {
+		    case SDL_GL_RED_SIZE:
+			wgl_attrib = WGL_RED_BITS_ARB;
+			break;
+		    case SDL_GL_GREEN_SIZE:
+			wgl_attrib = WGL_GREEN_BITS_ARB;
+			break;
+		    case SDL_GL_BLUE_SIZE:
+			wgl_attrib = WGL_BLUE_BITS_ARB;
+			break;
+		    case SDL_GL_ALPHA_SIZE:
+			wgl_attrib = WGL_ALPHA_BITS_ARB;
+			break;
+		    case SDL_GL_DOUBLEBUFFER:
+			wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
+			break;
+		    case SDL_GL_BUFFER_SIZE:
+			wgl_attrib = WGL_COLOR_BITS_ARB;
+			break;
+		    case SDL_GL_DEPTH_SIZE:
+			wgl_attrib = WGL_DEPTH_BITS_ARB;
+			break;
+		    case SDL_GL_STENCIL_SIZE:
+			wgl_attrib = WGL_STENCIL_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_RED_SIZE:
+			wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_GREEN_SIZE:
+			wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_BLUE_SIZE:
+			wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_ALPHA_SIZE:
+			wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
+			break;
+		    case SDL_GL_STEREO:
+			wgl_attrib = WGL_STEREO_ARB;
+			break;
+		    case SDL_GL_SAMPLE_BUFFERS:
+			wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
+			break;
+		    case SDL_GL_SAMPLES:
+			wgl_attrib = WGL_SAMPLES_ARB;
+			break;
+		    default:
+			return(-1);
+		}
+		this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
+
+		return 0;
+	}
 
 	retval = 0;
-	switch( attrib ) {
+	switch ( attrib ) {
 	    case SDL_GL_RED_SIZE:
 		*value = GL_pfd.cRedBits;
 		break;
@@ -275,6 +459,8 @@
 		this->gl_data->wglCreateContext = NULL;
 		this->gl_data->wglDeleteContext = NULL;
 		this->gl_data->wglMakeCurrent = NULL;
+		this->gl_data->wglChoosePixelFormatARB = NULL;
+		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
 
 		this->gl_config.dll_handle = NULL;
 		this->gl_config.driver_loaded = 0;
@@ -304,6 +490,7 @@
 	WIN_GL_UnloadLibrary(this);
 
 	/* Load new function pointers */
+	memset(this->gl_data, 0, sizeof(*this->gl_data));
 	this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
 		GetProcAddress(handle, "wglGetProcAddress");
 	this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
--- a/src/video/wincommon/SDL_wingl_c.h	Tue Jul 22 14:01:21 2003 +0000
+++ b/src/video/wincommon/SDL_wingl_c.h	Tue Jul 22 15:10:06 2003 +0000
@@ -37,6 +37,8 @@
     PIXELFORMATDESCRIPTOR GL_pfd;
     HDC GL_hdc;
     HGLRC GL_hrc;
+    int pixel_format;
+    int wgl_arb_pixel_format;
 
     void * (WINAPI *wglGetProcAddress)(const char *proc);
 
@@ -45,7 +47,16 @@
     BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc);
 
     BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc);
-
+   
+    BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList,
+                                           const FLOAT *pfAttribFList,
+                                           UINT nMaxFormats, int *piFormats,
+                                           UINT *nNumFormats);
+    BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat,
+                                                int iLayerPlane,
+                                                UINT nAttributes, 
+                                                const int *piAttributes,
+                                                int *piValues);
 #endif /* HAVE_OPENGL */
 };
 
@@ -54,6 +65,7 @@
 #define GL_pfd		(this->gl_data->GL_pfd)
 #define GL_hdc		(this->gl_data->GL_hdc)
 #define GL_hrc		(this->gl_data->GL_hrc)
+#define pixel_format	(this->gl_data->pixel_format)
 
 /* OpenGL functions */
 extern int WIN_GL_SetupWindow(_THIS);
@@ -67,3 +79,63 @@
 extern void *WIN_GL_GetProcAddress(_THIS, const char* proc);
 #endif
 
+#ifdef HAVE_OPENGL
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB   0x2000
+#define WGL_DRAW_TO_WINDOW_ARB         0x2001
+#define WGL_DRAW_TO_BITMAP_ARB         0x2002
+#define WGL_ACCELERATION_ARB           0x2003
+#define WGL_NEED_PALETTE_ARB           0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB    0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB     0x2006
+#define WGL_SWAP_METHOD_ARB            0x2007
+#define WGL_NUMBER_OVERLAYS_ARB        0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB       0x2009
+#define WGL_TRANSPARENT_ARB            0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB  0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB            0x200C
+#define WGL_SHARE_STENCIL_ARB          0x200D
+#define WGL_SHARE_ACCUM_ARB            0x200E
+#define WGL_SUPPORT_GDI_ARB            0x200F
+#define WGL_SUPPORT_OPENGL_ARB         0x2010
+#define WGL_DOUBLE_BUFFER_ARB          0x2011
+#define WGL_STEREO_ARB                 0x2012
+#define WGL_PIXEL_TYPE_ARB             0x2013
+#define WGL_COLOR_BITS_ARB             0x2014
+#define WGL_RED_BITS_ARB               0x2015
+#define WGL_RED_SHIFT_ARB              0x2016
+#define WGL_GREEN_BITS_ARB             0x2017
+#define WGL_GREEN_SHIFT_ARB            0x2018
+#define WGL_BLUE_BITS_ARB              0x2019
+#define WGL_BLUE_SHIFT_ARB             0x201A
+#define WGL_ALPHA_BITS_ARB             0x201B
+#define WGL_ALPHA_SHIFT_ARB            0x201C
+#define WGL_ACCUM_BITS_ARB             0x201D
+#define WGL_ACCUM_RED_BITS_ARB         0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB       0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB        0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB       0x2021
+#define WGL_DEPTH_BITS_ARB             0x2022
+#define WGL_STENCIL_BITS_ARB           0x2023
+#define WGL_AUX_BUFFERS_ARB            0x2024
+#define WGL_NO_ACCELERATION_ARB        0x2025
+#define WGL_GENERIC_ACCELERATION_ARB   0x2026
+#define WGL_FULL_ACCELERATION_ARB      0x2027
+#define WGL_SWAP_EXCHANGE_ARB          0x2028
+#define WGL_SWAP_COPY_ARB              0x2029
+#define WGL_SWAP_UNDEFINED_ARB         0x202A
+#define WGL_TYPE_RGBA_ARB              0x202B
+#define WGL_TYPE_COLORINDEX_ARB        0x202C
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB         0x2041
+#define WGL_SAMPLES_ARB                0x2042
+#endif
+
+#endif
--- a/src/video/x11/SDL_x11gl.c	Tue Jul 22 14:01:21 2003 +0000
+++ b/src/video/x11/SDL_x11gl.c	Tue Jul 22 15:10:06 2003 +0000
@@ -122,6 +122,16 @@
 		attribs[i++] = GLX_STEREO;
 		attribs[i++] = this->gl_config.stereo;
 	}
+	
+	if( this->gl_config.sample_buffers ) {
+		attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
+		attribs[i++] = this->gl_config.sample_buffers;
+	}
+	
+	if( this->gl_config.samples ) {
+		attribs[i++] = GLX_SAMPLES_ARB;
+		attribs[i++] = this->gl_config.samples;
+	}
 
 #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */
 	attribs[i++] = GLX_X_VISUAL_TYPE;
@@ -229,7 +239,7 @@
 
 #ifdef HAVE_OPENGL
 
-static int ExtensionSupported(const char *extension, const char *all_extensions)
+static int ExtensionSupported(const char *extension)
 {
 	const GLubyte *extensions = NULL;
 	const GLubyte *start;
@@ -266,7 +276,6 @@
 int X11_GL_MakeCurrent(_THIS)
 {
 	int retval;
-	const char *glx_extensions;
 	
 	retval = 0;
 	if ( ! this->gl_data->glXMakeCurrent(GFX_Display,
@@ -276,7 +285,6 @@
 	}
 	XSync( GFX_Display, False );
 
-	
 	/* 
 	 * The context is now current, check for glXReleaseBuffersMESA() 
 	 * extension. If extension is _not_ supported, destroy the pointer 
@@ -296,10 +304,10 @@
 	 * 
 	 */
 	
-	glx_extensions = this->gl_data->glXQueryExtensionsString(GFX_Display, SDL_Screen);
-	if (!ExtensionSupported("glXReleaseBuffersMESA", glx_extensions)) this->gl_data->glXReleaseBuffersMESA = NULL;
-	
-	
+	if ( ! ExtensionSupported("glXReleaseBuffersMESA") ) {
+		this->gl_data->glXReleaseBuffersMESA = NULL;
+	}
+
 	/* More Voodoo X server workarounds... Grr... */
 	SDL_Lock_EventThread();
 	X11_CheckDGAMouse(this);
@@ -354,6 +362,12 @@
 	    case SDL_GL_STEREO:
 		glx_attrib = GLX_STEREO;
 		break;
+ 	    case SDL_GL_SAMPLE_BUFFERS:
+ 		glx_attrib = GLX_SAMPLE_BUFFERS_ARB;
+ 		break;
+ 	    case SDL_GL_SAMPLES:
+ 		glx_attrib = GLX_SAMPLES_ARB;
+ 		break;
 	    default:
 		return(-1);
 	}
--- a/test/testgl.c	Tue Jul 22 14:01:21 2003 +0000
+++ b/test/testgl.c	Tue Jul 22 15:10:06 2003 +0000
@@ -393,7 +393,7 @@
 }
 
 int RunGLTest( int argc, char* argv[],
-               int logo, int slowly, int bpp, float gamma, int noframe )
+               int logo, int slowly, int bpp, float gamma, int noframe, int fsaa )
 {
 	int i;
 	int rgb_size[3];
@@ -475,6 +475,10 @@
 	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
 	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
 	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+	if ( fsaa ) {
+		SDL_GL_SetAttribute( SDL_GL_SAMPLE_BUFFERS, 1 );
+		SDL_GL_SetAttribute( SDL_GL_SAMPLES, fsaa );
+	}
 	if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
 		fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
 		SDL_Quit();
@@ -499,6 +503,12 @@
 	printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
 	SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
 	printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
+	if ( fsaa ) {
+		SDL_GL_GetAttribute( SDL_GL_SAMPLE_BUFFERS, &value );
+		printf( "SDL_GL_SAMPLE_BUFFERS: requested 1, got %d\n", value );
+		SDL_GL_GetAttribute( SDL_GL_SAMPLES, &value );
+		printf( "SDL_GL_SAMPLES: requested %d, got %d\n", fsaa, value );
+	}
 
 	/* Set the window manager title bar */
 	SDL_WM_SetCaption( "SDL GL test", "testgl" );
@@ -700,6 +710,7 @@
 	int slowly;
 	float gamma = 0.0;
 	int noframe = 0;
+	int fsaa = 0;
 
 	logo = 0;
 	slowly = 0;
@@ -728,15 +739,18 @@
 		if ( strcmp(argv[i], "-noframe") == 0 ) {
  		       noframe = 1;
 		}
+		if ( strcmp(argv[i], "-fsaa") == 0 ) {
+ 		       ++fsaa;
+		}
 		if ( strncmp(argv[i], "-h", 2) == 0 ) {
  		       printf(
-"Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n] [-noframe]\n",
+"Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa]\n",
  			      argv[0]);
 			exit(0);
 		}
 	}
 	for ( i=0; i<numtests; ++i ) {
- 		RunGLTest(argc, argv, logo, slowly, bpp, gamma, noframe);
+ 		RunGLTest(argc, argv, logo, slowly, bpp, gamma, noframe, fsaa);
 	}
 	return 0;
 }