Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





OpenGL - Acceso al buffer interno de la textura

Iniciado por fiero, 26 de Diciembre de 2007, 11:10:44 PM

« anterior - próximo »

fiero

Hola,

Estoy convirtiendo mis funciones DX a OpenGL y hay algunas cosas que no consigo hacer igual, por ejemplo, tener los buffers de la textura en memoria de sistema y memoria de video separados.

Solo he encontrado la extensión GL_APPLE_client_storage, que permite crear la textura manteniendo la copia original en memoria de sistema, con lo cual el driver OpenGL solo crea una copia en memoria de video. El problema es que esta extensión no es soportada por todos los drivers, incluso las tarjetas modernas.

Entonces, creando la textura de la forma habitual con glTexImage2D, ¿es posible obtener el puntero de memoria de sistema de la textura en OpenGL? Esto me posibilitaria modificar la textura en memoria de sistema, sin tener que tener dos copias (la mia y la de OpenGL)

saludos!
www.videopanoramas.com Videopanoramas 3D player

tamat

Por un stratos menos tenso

Pogacha

Creeria que no se puede (pero no tengo idea realmente)
Muchas implementaciones de OpenGL guardan una copia pero no tienen la obligación de hacerlo, es una implementación nada mas. En algunas implementaciones la copia queda en el formato original y luego se convierte al destino al atravezar el canal agp, pero en otras queda transformada al formato final desde un principio, o peor aun, cuando se pide un cambio de resolución esta es descargada del canal agp y luego subida nuevamente. Esto se puede ver cuando haces un cambio de resolución y OpenGL automaticamente ajusta las propiedades de las texturas, al volver a la resolución anterior las texturas han perdido calidad. Esto lo vi en placas Savage si mal no recuerdo ...

No se de tu implementación especifica, pero ten en cuenta que casi nadie se esta preocupando por eso ;)
Generalmente la copia en memoria se usa poco y el OS la suele llevar a disco cuando realmente es un problema.

Saludos

fiero

Cita de: "tamat"O_o! Eso se puede hacer en DX?!

Sí, se puede hacer. En DX, si creas las texturas con D3DPOOL_MANAGED, todo el trabajo lo hace el driver, así que te olvidas de las transacciones MEMSISTEMA<->MEMVIDEO. Sin embargo yo tenia muchos problemas de rendimiento, por ejemplo cuando tenia que cargar 200MB de texturas con una tarjeta de solo 64MB de video, así que tuve que hacerlo "a mano". Es decir, creo las texturas con D3DPOOL_SYSTEMMEM, y luego sus gemelas en VRAM con D3DPOOL_DEFAULT sólo si están dentro del frustum. Tambien modifico las texturas dinamicamente (carga de imagen mientras se usa la textura) y las actualizo en VRAM con UpdateTexture. Las transacciones se manejan por hardware, así que no hay problema de rendimiento.

Podeis ver un ejemplo de esto instalando mi plugin (solo windows) y luego viendo esto http://www.devalvr.com/paginas/soporte/compass.html . Este ejemplo crea las texturas en DX y luego las va actualizando a medida que se descarga el Jpeg de 12000x1648. Para hacer esto con OpenGL necesito tener dos copias de la textura en memoria de sistema, la mia que me sirve para actualizar la textura y la que hace OpenGL. Al menos todos los ejemplos que he visto de texturas dinámicas mantienen una copia aparte de la de OpenGL. El problema es cuando cargas una imagen de 20000x10000, en ese momento mantener dos copias es un poco bestial.

Todo seria más sencillo si tuviera acceso al puntero que usa OpenGL en memoria de sistema. O si pudiera decidir, como en DX, donde se crean las texturas. Como dice Pogacha, en la documentacion de OpenGL dice que "GL implementations normally maintain a copy of texture image data", o sea que en la mayoria de los casos tendré dos copias en RAM de lo mismo.

Se agradece qualquier idea  :wink:
www.videopanoramas.com Videopanoramas 3D player

Fran

No sé si esto te servirá xq es lento

glGetTexImage

Cuando quieras modificarla, te la traes, la modificas y la vuelvas a escribir con la instruccion contraria. Yo no conozco otra forma. Por cuestiones de velocidad, si me hace falta modificarla yo tengo dos copias.

fiero

Creo que al final tendré que dejar las dos copias, al menos mientras dure la carga/actualización de las texturas.

Muchas gracias por las respuestas!
www.videopanoramas.com Videopanoramas 3D player

Prompt

Cita de: "fiero"Entonces, creando la textura de la forma habitual con glTexImage2D, ¿es posible obtener el puntero de memoria de sistema de la textura en OpenGL? Esto me posibilitaria modificar la textura en memoria de sistema, sin tener que tener dos copias (la mia y la de OpenGL)

He entendido mal la pregunta, porque lo que quieres es tener el puntero a los texels de la tarjeta gráfica no de memoria de sistema. La pregunta sería ¿Es posible obtener el puntero en memoria de LA TARJETA GRAFICA de la textura en OpenGL? Bueno dejo la respuesta a lo que he creido entender en un principio :P

En OpenGL cuando creas una textura como bien dices con glTexImage2D si ves la especificación el último parametro es el puntero a los texels :) que... lo tienes ya en memoria dinamica oiga! :)

Veamos:

uint g_textureID_0;
CTexture miTextura("fiero.tga");

glGenTextures( 1, &g_textureID_0 );    // Le decimos a OpenGL que nos de un "id" libre donde colocar nuestra textura en la memoria de la tarjeta
glBindTexture( GL_TEXTURE_2D, g_textureID_0 );    // Le decimos que el contexto irá a parar a ese "id" o imaginemos ESPACIO LIBRE de memoria de la tarjeta

// Configuramos chorradas...
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// Enviamos a la tarjeta el contenido de texels con una configuración específica
glTexImage2D( GL_TEXTURE_2D, 0, 3, miTextura->sizeX, miTextura->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, miTextura->data );


Una vez comprendido como funciona la carga de texturas, si no borras la clase miTextura, su variable data tiene en memoria de sistema la misma copia que en la de la tarjeta. Ya que lo que hemos hecho es enviarle por la función glTexImage2D un puntero a esa variable para que copie el contenido.

Por consiguiente! siempre tienes una copia en memoria de sistema de lo que mandas a la tarjeta, ahora bien, otra cosa es que te carges la clase que contiene esos datos o no tengas un texture manager.

:) saludetes!

fiero

Hola Prompt,

Lo hago tal y como dices. A lo que me refiero con 2 copias es a que OpenGL no solo hace una copia de la textura en VRAM, sino que además hace otra copia en memoria de sistema. Con lo cual tienes dos copias de la misma textura en memoria de sistema, una la tuya, y otra la de OpenGL. Esto no es preocupante en la mayoria de aplicaciones, pero si tienes que cargar una textura de 400 MB, resulta que necesitas 800MB de ram.

Al final he encontrado una solución, aunque no sé si funcionará igual con todos los drivers OpenGL, tengo que hacer más pruebas. Lo que hago es directamente eliminar con glDeleteTextures los trozos de textura que no están dentro del frustum. Luego si entran dentro de la escena las vuelvo a crear con glTexImage2D. Nunca pensé que esto de andar creando y eliminando texturas fuera tan rápido, pero no tengo ninguna penalización en los FPS. Ahora cargando una textura de 350MB la aplicación me consume unos 420MB en vez de 700MB con toda la textura cargada en OpenGL.

Gracias por la respuestas!
saludos
www.videopanoramas.com Videopanoramas 3D player

Prompt

Ni me quiero imaginar que estarás haciendo :) ni que tarjeton tendras :P

Imagino que 1 de 2... o no es un juego o andas creando "mapas atlas" para un render rápido.

No tendras penalizaciones siempre y cuando no copes el BUS de la tarjeta. Es decir, que si tu BUS es... yo q se... 500 MB por segundo, pues no te penaliza si subes 400 MB cada segundo ( el refresco es cada segundo por ej ). Pero! ten en cuenta que te quedan 100.

De todas formas lo que comentas es ahorro de memoria de tarjeta y entiendo por VRAM y memoria de sistema, que no es memoria de la tarjeta grafica. En la memoria de GPU ( por llamarla así ) solo tienes una copia, con un id relacioado. Y parecias querer librarte de la copia de memoria de CPU ( llamemosla así ). Pero resulta q hablas de otra VRAM.

Que yo sepa, existen 3 copias:
- En HD.
- En memoria de CPU.
- En memoria de GPU.

- Se carga del HD a memoria de CPU y luego se pasa una copia a la memoria de la GPU. Si es formato DDS pues el paso es directo etc...

Te refieres a estas 3 "copias de texturas"?

Un saludo, y me alegro de que hayas encontrado la solución :)

fiero

Tengo un iMac con una ATI Mobility Radeon X1600 de 128 MB, no es la bomba, pero es bastante buena... creo :)

Si tienes Windows, podrás ver mi programa "en directo" en este ejemplo: http://www.devalvr.com/paginas/soporte/compass.html (mi programa es un visor 3D en forma de plugin para el navegador)

Olvidando la textura en el HD, una vez que la cargamos en la aplicación OpenGL, tenemos 3 copias de la textura:

1- En memoria de CPU (la que nosotros reservamos y manejamos)
2- En memoria de CPU (creada por glTexImage2D y manejada por OpenGL, sin acceso directo)
3- En memoria de GPU (creada por glTexImage2D y manejada por OpenGL, sin acceso directo)

Mi pregunta inicial era como acceder a la memoria 2, para poder eliminar mi copia 1. Pero ahora lo que hago es eliminar la 2 y 3 de las partes que no entran en el frustum y listo. Ya probaré con tarjetas más antiguas a ver como va. De todas formas trabajo descomponiendo la textura en trozos de 256x256, esto son solo 200KB, así que puede ser que las transferencias de memoria se hagan muy escalonadas, con lo cual no veo retrasos aunque mueva la cámara muy rápido. Por ejemplo, una textura de 10000x5000 la divido en 750 cachitos.

saludos!
www.videopanoramas.com Videopanoramas 3D player

marcode

Cita de: "fiero"
Olvidando la textura en el HD, una vez que la cargamos en la aplicación OpenGL, tenemos 3 copias de la textura:

1- En memoria de CPU (la que nosotros reservamos y manejamos)
2- En memoria de CPU (creada por glTexImage2D y manejada por OpenGL, sin acceso directo)
3- En memoria de GPU (creada por glTexImage2D y manejada por OpenGL, sin acceso directo)

¿Estás seguro que reside en la 2 y la 3 al mismo tiempo?, porque yo lo que creo que ocurre es que se crea en memoria de sistema a lo primero, y cuando se utiliza se mueve a la de vídeo y allí permanece a menos que deje de usarse en preferencia de otras texturas, en cuyo caso vuelve a ser movido por OpenGL a la memoria de sistema.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

fiero

Hola marcode,

Lo que hace OpenGL es una copia en memoria de sistema (2), y luego una copia en VRAM cuando se necesita (3), descargandola cuando no. Funciona como dices, excepto que no "mueve" la textura a VRAM, sino que copia la textura a VRAM cuando es necesario. Esto significa que la copia interna de OpenGL en memoria de sistema (la 2) siempre está ahí. Este comportamiento es igual que cuando se crea una textura en DX con D3DPOOL_MANAGED.

saludos!
www.videopanoramas.com Videopanoramas 3D player

marcode

Cita de: "fiero"Lo que hace OpenGL es una copia en memoria de sistema (2), y luego una copia en VRAM cuando se necesita (3), descargandola cuando no. Funciona como dices, excepto que no "mueve" la textura a VRAM, sino que copia la textura a VRAM cuando es necesario. Esto significa que la copia interna de OpenGL en memoria de sistema (la 2) siempre está ahí. Este comportamiento es igual que cuando se crea una textura en DX con D3DPOOL_MANAGED.

Creo que si no me muestras una fuente fiable que explique que eso ocurre así, no me voy a poder creer nunca que Las texturas se guarden por duplicado. Es ilógico e innecesario ese gasto de memoria.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

fiero

Si no vas a modificar la textura, puedes eliminar tu copia (la 1), así liberas RAM.

Las pruebas:

Apple añadió una extensión para poder mantener la copia del usuario como copia de memoria de sistema manejada por OpenGL, para así ahorrarse el duplicado http://www.opengl.org/registry/specs/APPLE/client_storage.txt (En el "Overview" está explicado muy claro). El problema es que esta estensión no es muy común en windows, al menos mis drivers ATI no la soportan.

saludos!
www.videopanoramas.com Videopanoramas 3D player

Zaelsius

Cita de: "marcode"Es ilógico e innecesario ese gasto de memoria.

Es una optimización muy común, con un coste espacial. Si no se hiciese así,  ¿qué pasaria cuando todas las texturas de una escena no pudiesen ser almacenadas a la vez en VRAM(cosa bastante normal)?. Habría que traer de vuelta las texturas de VRAM a RAM, perdiendo un tiempo precioso y afectando al rendimiento de la aplicación/juego. Es más rápido aumentar la cuota de uso de RAM y ahorrarte esas transferencias.






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.