Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Texturas En Memoria De Video

Iniciado por Lord Trancos 2, 12 de Julio de 2005, 10:50:36 PM

« anterior - próximo »

Lord Trancos 2

 Me acabo de dar cuenta de que mi juegecillo chupa un monton de RAM y resulta que es (o al menos todo parece indicarlo) pq las texturas se estan cargando en memoria del sistema (y no en la memoria de video).

El problema es que no encuentro donde decirle a OpenGL que quiero la textura en memoria de video, ya que ni en gluBuild2DMipmaps, ni en glTexImage2D (que son las funciones que uso) encuentro un parametro donde indicarselo.

pd. Uso SDL en combinacion con OpenGL.
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Lord Trancos 2

 Ahora que lo pienso.... en DirectX cada vez que cambiaba de pantalla completa al escritorio de windows, al restaurar la aplicacion debia de volver a cargar las texturas, mientras que en OpenGL no me sucede.

¿Se guarda acaso OpenGL (o los drivers) una copia de las texturas (en memoria del sistema) para restaurarlas automaticamente cuando sea necesario?  O_O
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Pogacha

 Según leí una vez, OpenGL administra donde tener la textura, si en memoria de video o memoria virtual (según su cantidad de uso), cuando una textura es utilizada mucho la sube por el canal agp a la vram y si esta pasa un tiempo sin usarse la baja a memoria ram y windows se encarga de mantenerla en ram o disco según su uso y disponibilidad. Algo así como una cache de texturas  :P .

Saludos

Lord Trancos 2

Cita de: "Pogacha"Según leí una vez, OpenGL administra donde tener la textura, si en memoria de video o memoria virtual (según su cantidad de uso), cuando una textura es utilizada mucho la sube por el canal agp a la vram y si esta pasa un tiempo sin usarse la baja a memoria ram y windows se encarga de mantenerla en ram o disco según su uso y disponibilidad. Algo así como una cache de texturas  :P .

Saludos
Pues vaya... :(

Por una parte me alegro (mas sencillo) pero por otra parte es una putada no tener nada de control sobre la gestion que se esta haciendo de la memoria de video y la del sistema.
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

DraKKaR

 Se supone ke el driver es lo suficientemente inteligente para hacer ese control de la residencia de las texturas. Y si lo hace por tí, ¿para qué quejarnos?

Lord Trancos 2

Cita de: "DraKKaR"Se supone ke el driver es lo suficientemente inteligente para hacer ese control de la residencia de las texturas. Y si lo hace por tí, ¿para qué quejarnos?
No se,.... tal vez pq no me gusta ver como mi aplicacion chupa 80mb de RAM, cuando el 90% de ese consumo podria estar en la tarjeta de video....  :P  
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Xam

 Hola !!

Antes de nada me voy a presentar. Posiblemente lo suyo sería utilizar un nuevo post para ello, pero lo voy a hacer aquí.

Lo mío es la programación de cualquier cosa relacionada con motores 3d y tecnología gráfica. También sé sobre otras
áreas, pero se puede decir que es ésta la que más domino.

LLevaba ya un tiempo leyendo el foro y era cuestión de tiempo que algún día participara. Y por lo visto va a ser hoy.

Dejando a un lado la presentación, voy al grano. Como te ha comentado Pogacha y DraKKar se supone que el driver se
encarga de la gestión de las texturas de manera más o menos óptima (en cuanto a transferencia entre los distintos tipo
de memoria al menos). Según esto el driver se encargaría de cargar en memoria de video todas las texturas posibles y el
resto las almacenaría en la memoria de sistema para ir realizando intercambios (cuando fuera necesario) de las mismas.
Esto debería ser así, por lo menos en la teoría. Tengo un proyecto a corto plazo para verificar que esto es cierto, supongo
que cuando lo acabe podré arrojar más luz sobre el tema.

Pero, así de pronto, viendo el problema que tienes y asumiendo que el driver hace lo que tiene que hacer. Miraría si después
de cargar una textura de disco y pasarla a OpenGl (glTexImage2d( ... ), ...) liberas la memoria de sistema utilizada para
almacenarla. De no ser así, posiblemente ahí tendrías la razón de por qué la aplicación requiere tanta memoria de sistema.

Espero que ahora que ya he superado lo de la primera participación, participar algo más.







NeLo

 Welcome to the jungle!!! ©

(uoh)  
Drowning deep in my sea of loathing

Lord Trancos 2

 
Cita de: "Xam"Pero, así de pronto, viendo el problema que tienes y asumiendo que el driver hace lo que tiene que hacer. Miraría si después
de cargar una textura de disco y pasarla a OpenGl (glTexImage2d( ... ), ...) liberas la memoria de sistema utilizada para
almacenarla. De no ser así, posiblemente ahí tendrías la razón de por qué la aplicación requiere tanta memoria de sistema.
Fue lo primero que pense, pero no hay ningun fallo por ese lado.
Estoy liberando la memoria correctamente.


function TE_Load_DefaultCB(_fn: pChar; _tag: longint): GLuint; stdcall;

var
 _surf : PSDL_Surface;
 _tga : TTGA;

 _width, _height : integer;
 _format : cardinal;
 _data   : pointer;
 _ccomp  : byte;

begin
 Result := 0;

 TGA_Reset(_tga);

 // first try to load as BMP
 _surf := SDL_LoadBMP(_fn);
 if (_surf = nil) then
 begin
   // now try to load as TGA
   _tga := TGA_Load(_fn);
   if not _tga.ok then exit;

   // change order
   TGA_ChangeOrder(_tga, C_TGA_ORDER_TOP_LEFT);

   // it's a TGA file
   _width  := _tga.header.ImageSpec.ImageWidth;
   _height := _tga.header.ImageSpec.ImageHeight;
   _format := GL_BGRA_EXT;
   _ccomp  := 4;
   _data   := _tga.data;
 end else begin
            // it's a BMP file
            _width  := _surf.w;
            _height := _surf.h;
            _format := GL_BGR_EXT;
            _ccomp  := 3;
            _data   := _surf.pixels;
          end;

 // create Texture
 glGenTextures(1, @Result);

 // bind texture
 glBindTexture(GL_TEXTURE_2D, Result);

 // clamp ?
 if (_tag and C_TE_DEFCB_NOREPEAT <> 0) then
 begin
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 end else
 begin
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 end;

 // filter and mipmaps
 if ((_tag and C_TE_DEFCB_NOMIPMAPS) = 0) then
 begin
   // Filtering
   if (_tag and C_TE_DEFCB_NOFILTER = 0) then
   begin
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   end else
   begin
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   end;

   // Generate The MipMapped Texture
   gluBuild2DMipmaps(GL_TEXTURE_2D, _ccomp, _width, _height, _format,
                     GL_UNSIGNED_BYTE, _data);
 end else
 begin
   // Filtering
   if (_tag and C_TE_DEFCB_NOFILTER = 0) then
   begin
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   end else
   begin
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   end;

   // Generate Texture
   glTexImage2D(GL_TEXTURE_2D, 0, _ccomp, _width, _height, 0, _format,
                GL_UNSIGNED_BYTE, _data);
 end;

 // free surface or TGA
 if _tga.ok then TGA_Free(_tga);
 if _surf <> NIL then SDL_FreeSurface(_surf);
end;
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Xam

 Vale.

Yo sigo creyendo que el driver hace lo que debería.

No sé, a ciegas es un poco dificil saber lo que puede ser. Revisa si, por alguna razón, cargas las texturas más de una
vez (asumo que cargas las texturas al principio y luego para utilizarlas las referencias con el identificador obtenido de
glGenTextures( ... )).

Otra cosa. He mirado el código (uff, cuánto hace que no veía algo en Pascal) y he visto que utilizas la función
gluBuild2dMipmaps( ... ) para obtener los niveles de detalle de las texturas. Esta función realiza una copia de los datos
que le pasas para obtener y cargar en OpenGl la textura original y los niveles de detalle de la misma. A lo mejor esta
función no libera la memoria que reserva después de cargar la textura y sus niveles de detalle en OpenGl. Ejecuta la
aplicación sin niveles de detalle en las texturas a ver cuánta memoria te consume (un conjunto completo de niveles de
detalle para una textura -lo que calcula gluBuild2dMipmaps( ... )- ocupa, aproximadamente, la tercera parte del tamano
original de la textura).


Lord Trancos 2

 No... no es problema del "manager" de texturas. Las texturas solo se cargan 1 vez, despues simplemente se incrementa un contador para al liberarlas saber cuando hay que hacerlo realmente.

Con glGenTextures el programa me chupa 47mb, sin glGenTextures chupa 42mb.

De todos modos, yo lo que creo es que el driver si carga las texturas de video, pero se guarda una copia en la memoria del sistema. En directX podia perder el "device", directX me informaba y yo volvia a cargar la texturas.

En OpenGL esto NO me sucede. Asi que la unica forma que tiene de perder el "device", y que al recuperarlo no se "note" (aqui no ha pasado nada...) es q el driver se guarde una copia de las imagenes en memoria del sistema. ¬¬
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Xam

 Entiendo lo que dices. Pero me parece muy raro que el driver se guarde en memoria de sistema la misma cantidad de memoria que ocupan las texturas en memoria de video por si las moscas se produce una pérdida del "device". La solución más sensata a la pérdida del "device" es la que comentas que usa DirectX.

Por lo visto no parece que sea ningún problema típico asociado a ese síntoma. Te podría dar algunas ideas más para que probases. Pero creo que lo mejor va a ser que me dedique a hacer algunos experimentos relacionados con el tema antes de seguir dando palos de ciego. Ya te contaré las conclusiones a las que llegue.

Por cierto, aquí:
Citar
Con glGenTextures el programa me chupa 47mb, sin glGenTextures chupa 42mb
Supongo que te refieres al uso o no de gluBuidl2dMipmaps ( ...). Relacionado con esto, no sé si sabes que existe una extensión (SGIS_generate_mipmap) que te permite calcular los niveles de detalle para una textura también de forma automática. Esta extensión ha pasado a formar parte del núcleo de OpenGl a partir de la versión 1.4. Si tu aplicación requiere al menos esa versión de OpenGl o una superior, yo dejaría de utilizar la función gluBuild2dMipmaps( ... ) y aprovecharía la funcionalidad proporcionada directamente por OpenGl.

Lord Trancos 2

 
Cita de: "Xam"Entiendo lo que dices. Pero me parece muy raro que el driver se guarde en memoria de sistema la misma cantidad de memoria que ocupan las texturas en memoria de video por si las moscas se produce una pérdida del "device". La solución más sensata a la pérdida del "device" es la que comentas que usa DirectX.
¿Conoces algun modo por el cual averiguar si OpenGL ha perdido el device?

Si no existe ese modo (yo no lo he encontrado), no tiene nada de raro la "chapuza" de guardarse las texturas en memoria de video.

edit: ansioso espero tus tests ;)
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

Zaelsius

 No siempre van a caber todas las texturas que usa el juego en memoria de vídeo, luego es totalmente lógico y normal que se guarde una copia en memoria del sistema.

DirectX debería emplear un mecanismo similar *internamente* por el mismo motivo.

TheAzazel

 Si, porque es un conazo tener que averiguar cuando se han "perdido" y tener que recargarlas....

OpenGL rulez...






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.