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.
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
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
Cita de: PogachaSegú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.
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?
Cita de: DraKKaRSe 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
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.
Welcome to the jungle!!! ©
(uoh)
Cita de: XamPero, 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;
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).
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. ¬¬
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.
Cita de: XamEntiendo 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 ;)
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.
Si, porque es un conazo tener que averiguar cuando se han "perdido" y tener que recargarlas....
OpenGL rulez...
En realidad OpenGL no guarda copia, esto lo decide el driver o implementación, en la savage 4 creo o no se que placa de la que tenia antes, OpenGL subia la textura a video y cuando no la usaba mas la bajaba a memoria ram, dejando solo una copia ... pero tal vez por optimización o algo así se ha cambiado para estas placas.
Saludos
Que yo sepa OpenGL no tiene forma de saber cuando pierde el device, entre otras cosas por que nunca lo pierde, OpenGL siempre esta "ahi".
Por otro lado no creo que gurade una copia de la textura en memoria siempre, probablemente se limite a subirla de la Ram de video y a bajarla cuando sea necesario, no veo por que tener una copia, por si acaso, si el driver puede controlar cuando ocurre eso.
Saludos.
PD: A veces los programas consumen mucha memoria y punto, usa menos texturas u optimiza por otro lado, quiza usar DirectX te permita controlar mejor este aspecto, por que te deja mas cerca del "metal", pero para gustos los colores.
http://oss.sgi.com/projects/ogl-sample/reg...ent_storage.txtCitarGL implementations normally maintain a copy of texture image
data supplied clients when any of the various texturing commands, such as
TexImage2D, are invoked.
Eso es lo que dice SGI, por supuesto, cada implementación luego hará lo que quiera. Supongo que mantener la copia hace que que el descarte de texturas sea más rápido, al no tener que moverlas de nuevo a la memoria del sistema.
Es posible que incluso se sigan diferentes políticas para texturas pequeñas o grandes, quien sabe..
El enlace en cuestión habla sobre una extensión de Apple B) :
CitarThis extension eliminates GL's internal copy of
the texture image data and allows a client to maintain this data locally for
textures when the UNPACK_CLIENT_STORAGE_APPLE pixel storage parameter is
TRUE at the time of texture specification. Local texture data storage is
especially useful in cases where clients maintain internal copies of
textures used in any case.
Que es útil por ejemplo a la hora de renderizar vídeo con OpenGL.
PD: Alguien con mucho tiempo que se mire los sources de los drivers OpenGL de ATI para Linux, a ver qué hacen :lol:
Según la información aportada por ZaelSiuS en :
Citar
http://oss.sgi.com/projects/ogl-sample/reg...ent_storage.txt
Parece ser que los drivers sí mantienen en la memoria de sistema una copia de las texturas que tienen en la memoria de video. De hecho la extensión a la que hace referencia (GL_APPLE_client_storage) le permite al cliente hacerse responsable de esa copia en la memoria de sistema de las texturas almacenadas en la memoria de video. Pero vamos, sea memoria gestionada por el driver o memoria gestionada por el cliente la copia seguiría ahí.
No sé hasta que punto puede resultar útil mantener en memoria de sistema una copia de una textura ya almacenada en la memoria de video. En el caso de tener que hacer algún intercambio de texturas podría tener algún sentido (aunque tampoco mucho, si vas a sacar una textura de la memoria de video para meter otra en su lugar se podría reutilizar el espacio en memoria de sistema de esta útlima - por supuesto ambas deberían tener el mismo tamaño- y sólo tendrías que utilizar memoria de sistema para las texturas que no entrasen en la memoria de video. De hecho yo siempre he asumido que el driver de OpenGl funcionaba así), pero en el caso de no tener que hacer ningún intercambio de texturas no tiene ninguno. Si una aplicación requiere 100 Megas de texturas, y la tarjeta de video puede almacenarlas todas para qué mantener una copia de éstas en la memoria de sistema. En todo caso debería ser algo parametrizable.
el sistema de texturas en opengl no se como va, pero desde directx si le dices que la quieres en la memoria de video, la memoria ram no crece (por lo menos en mi ordenador), con lo que yo veo que es mas de opengl que de otra cosa
saludos