/* * Small program triggering a memory leak in the Intel i965 DRI driver. After a * few seconds either X11 or the program itself is killed by the Linux kernel * Out-Of-Memory killer. * * Compile using: * $ gcc i965-texture-handling-mem-leak.c -o i965-texture-handling-mem-leak -lGL */ #include #include #include #include #include #include static void create_window (Display *dpy, const char *name, int x, int y, int width, int height, Window *window, GLXContext *context) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; GLXContext ctx; XVisualInfo *visinfo; XSizeHints sizehints; scrnum = DefaultScreen (dpy); root = RootWindow (dpy, scrnum); visinfo = glXChooseVisual (dpy, scrnum, attrib); if (!visinfo) { fprintf (stderr, "error: cannot get an RGB double-buffered visual\n"); exit (1); } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap (dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow (dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints (dpy, win, &sizehints); XSetStandardProperties (dpy, win, name, name, None, (char**) NULL, 0, &sizehints); ctx = glXCreateContext (dpy, visinfo, NULL, True); if (!ctx) { fprintf (stderr, "error: glXCreateContext failed\n"); exit (1); } XFree (visinfo); *window = win; *context = ctx; } static void loop (Display *dpy, Window win) { unsigned int tex, i; unsigned int *buffer; buffer = malloc (1024 * 1024 * 4); for (i = 0; i < 1024 * 1024; i++) buffer[i] = 0xFFFF0000; while (1) { static const float positions[12] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; static const float texcoords[8] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; static const unsigned char colors[16] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; static const unsigned short indices[4] = { 0, 1, 2, 3 }; while (XPending (dpy) > 0) { XEvent event; XNextEvent (dpy, &event); switch (event.type) { case Expose: break; case ConfigureNotify: glViewport (0, 0, event.xconfigure.width, event.xconfigure.height); break; default: break; } } /* Create a 1024x1024 RGBA texture */ glGenTextures (1, &tex); glBindTexture (GL_TEXTURE_2D, tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*) buffer); /* Render a texture mapped quad */ glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_COLOR_ARRAY); glEnableClientState (GL_TEXTURE_COORD_ARRAY); glVertexPointer (3, GL_FLOAT, 0, positions); glColorPointer (4, GL_UNSIGNED_BYTE, 0, colors); glTexCoordPointer (2, GL_FLOAT, 0, texcoords); glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, indices); glDisableClientState (GL_VERTEX_ARRAY); glDisableClientState (GL_COLOR_ARRAY); glDisableClientState (GL_TEXTURE_COORD_ARRAY); /* Delete the texture */ glBindTexture (GL_TEXTURE_2D, 0); glDeleteTextures (1, &tex); glXSwapBuffers (dpy, win); glClear (GL_COLOR_BUFFER_BIT); } free (buffer); } int main (int argc, char *argv[]) { Display *dpy; Window win; GLXContext ctx; dpy = XOpenDisplay (NULL); if (!dpy) { fprintf (stderr, "error: cannot open display\n"); return -1; } /* Create the X11 window and OpenGL context */ create_window (dpy, "i965 texture handling mem leak", 0, 0, 400, 400, &win, &ctx); XMapWindow (dpy, win); glXMakeCurrent (dpy, win, ctx); /* Initialize some states */ glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f); glMatrixMode (GL_MODELVIEW); glViewport (0, 0, 512, 512); glEnable (GL_TEXTURE_2D); /* Enter the rendering loop */ loop (dpy, win); glXDestroyContext (dpy, ctx); XDestroyWindow (dpy, win); XCloseDisplay (dpy); return 0; }