Announcement

Collapse
No announcement yet.

flgrx driver eats a large amount of memory when the same texture is mapped many times

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • flgrx driver eats a large amount of memory when the same texture is mapped many times

    Hi,

    I have a problem with the fglrx driver. When doing simple things like showing a single texture, the driver takes somewhere between 300MB and 900MB. I think the memory is allocated from the kernel module, because the process shows small amount of memory used, but the free memory of the system decreases. I can see in /proc/meminfo that the "HighFree:" field decreases when I run a sample program. The decrease is relatively slow, at around 10MB/sec.

    I am attaching the sample program so that it is seen exactly what I am doing. The program requires a parameter that tells it how many lines from the image to transfer at once. I noticed, that when the texture is loaded in smaller chunks (800kB or so) the problem dissapears. Only when I load the texture with chunks of 1MB or more the problem is seen.

    In other words if the program is run with parameter 200 - no problem. If the parameter is 300 or more the problem appears.

    Can someone see if I am doing something wrong or is this a bug in the driver? Is there a workaround in this situation?
    Thanks, Venci

    My hardware:
    AMD Athlon Neo dual core 1.5GHz
    Video card: ATI RADEON E4690
    Memory: 3GB of RAM

    Software configuration:
    Debian Squeeze with linux 2.6.32 (32bit)
    Ati catalyst driver 11.8
    X.Org X Server 1.7.7
    KDE 4.4.5

    //compile with g++ -o mvplayer -lGL `sdl-config --libs` `sdl-config --cflags` -lSDL_image

    mvplayer.cpp
    #include <GL/glu.h>
    #include <string>
    #include <iostream>
    #include "SDL.h"
    #include <signal.h>
    #include "SDL_image.h"
    #include <cstdlib>
    #include <cmath>

    using namespace std;
    static unsigned int MainLoopSleepTime = 15000;

    void quitplayer(){ SDL_Quit(); exit(0); }

    void sighandler(int sig) { quitplayer(); }

    int main(int argc, char *argv[]) {

    if (argc < 2) {
    printf("mmoooo!\n");
    exit(-1);
    }

    const int dy0 = atoi(argv[1]);
    signal(SIGABRT, sighandler);
    signal(SIGTERM, sighandler);
    signal(SIGINT, sighandler);
    unsigned int nScreenWidth = 1280;
    unsigned int nScreenHeight = 1024;

    SDL_Init( SDL_INIT_EVERYTHING );

    if (!( SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO)){ return 1; }

    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_Surface* screen = SDL_SetVideoMode(nScreenWidth, nScreenHeight, 24, SDL_OPENGL);

    if ( screen == NULL ){
    fprintf(stderr, "Couldn't set GL mode: %s", SDL_GetError());
    SDL_Quit();
    return 1;
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, nScreenWidth, nScreenHeight, 0, 0, -10000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    glClearDepth(1.0f);
    glDepthFunc(GL_LEQUAL);
    glAlphaFunc(GL_GREATER,0.1f);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    SDL_Surface* image[4];
    image[0] = IMG_Load_RW(SDL_RWFromFile("Untitled-1_02.png", "rb"), 1);
    // image[1] = IMG_Load_RW(SDL_RWFromFile("Untitled-1_02.png", "rb"), 1);
    // image[2] = IMG_Load_RW(SDL_RWFromFile("Untitled-1_02.png", "rb"), 1);
    // image[3] = IMG_Load_RW(SDL_RWFromFile("Untitled-1_02.png", "rb"), 1);

    GLuint arrGlTexIds[100];
    srand(time(NULL));
    glGenTextures( 1, arrGlTexIds );
    glBindTexture(GL_TEXTURE_2D, arrGlTexIds[0]);
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, image[0]->w, image[0]->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image[0]->pixels); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R, GL_NEAREST);

    int sz = 3 * image[0]->w * dy0;
    printf("--> max transfer: %d %.3f MiB\n", sz, sz / pow(2.0,20));

    while(1) {
    // SDL_PumpEvents();
    glBindTexture(GL_TEXTURE_2D, arrGlTexIds[0]);
    for (int i=0; ; i++) {
    int dy = dy0; int y = dy0 * i;
    if ((y + dy) > image[0]->h) dy = image[0]->h - y;
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, image[0]->w, dy, GL_RGB, GL_UNSIGNED_BYTE, image[0]->pixels + 3*(image[0]->w * y));
    if ( y + dy >= image[0]->h ) break;
    }

    glBegin(GL_QUADS);
    glTexCoord2d(0.0,0.0);
    glVertex2i(0, 0);
    glTexCoord2d(1.0,0.0);
    glVertex2i(0 + image[0]->w, 0);
    glTexCoord2d(1.0,1.0);
    glVertex2i(0 + image[0]->w, 0 + image[0]->h);
    glTexCoord2d(0.0,1.0);
    glVertex2i(0, 0 + image[0]->h);
    glEnd();

    SDL_GL_SwapBuffers();

    usleep(10000);
    }
    }

  • #2
    What seems to work for me is setting
    Option "KernelModuleParm" "maxlockedmem=128"
    Option "MaxGARTSize" "128"

    Comment

    Working...
    X