Introducción
En
este artículo se describe la historia del estado actual
para del soporte de gráficos 3D compatibles con OpenGL en AROS.
Situación a mediados de 2008
En
el mundo del código abierto, la implementación compatible
con el API de OpenGL más conocida es la librería Mesa3D.
Una librería utilizada en Linux o BSD , implementada de tal modo
que portarla a otra sistema sea lo más sencillo posible. Nick
Andrews fue el artífice de la librería Mesa3D para AROS.
Este port está basado en el de StormMesa creado para AmigaOS.
Estaba
basado en la versión 6.5 de Mesa3D y emplea un controlador por
sfotware para AROS que emplea la función gráfica
WritePixelArray para generar imágenes en ventanas y pantallas de
AROS. A pesar de ser el primer intento de ofrecer el API OpenGL,
presentaba varios contratiempos.
En
primer lugar, mientras que la CPU x86 corría a 1,6 GHz, no era
aún suficiente para que el controlador por software rindiese lo
necesario hasta para que los juegos más sencillos fueran
jugables. Segundo, el port de Mesa3D estaba disponible como
librería linkada estáticamente, por ello las
aplicaciones linkadas con esta librería, se debían
publicar de nuevo si aparecía un nuevo avance de Mesa3D. Debido
a estos problemas, se excluyó el port de la librería
Mesa3D de los nightly builds de AROS, no estando tampoco disponible
para desarrolladores terceras partes.
La versión Mesa 7.0
A
mediados de 2008, me fui interesando por los gráficos 3D OpenGL
bajo AROS. Se trataba de una motivación bastante inocente -
pretendía correr en AROS el juego MMORPG Eternal Lands de modo
que fuera el primer sistema Amiguero en tener un juego MMORPG. Sin
embargo había un problema - Eternal Lands es un juego OpenGL, y
AROS carecía de soporte OpenGL (de serie).
El
primer paso fue recuperar el código de Mesa3D del respositorio
de AROS. Tras hablar con Nick y después de varias sesiones de
pruebas y fallos, compilé el port existente solamente para darme
cuenta de que el cliente de Eternal Lands precisa funciones OpenGL no
disponibles en Mesa3D 6.5 . Debía portar la versión
más reciente disponible, la 7.0.
Pero
las cosas no eran tan sencillas. Las interfaces internas fueron
modificadas y el controlador de AROS que funcionaba con la
versión Mesa3D 6.5, ya no lo hacía con la 7.0. Esto me
llevó a escribir las primeras líneas de código de
Mesa para AROS. Tomando como cimientos el controlador de Nick,
implementé un nuevo controlador compatible con la versión
7.0. También modifiqué el modo de dibujado,
acelerándolo a expensas de un mayor consumo de memoria. Cuando
todo compiló sin problemas y vi "Gears" en pantalla,
volví al interés por el cliente Eternal Lands...
...
todo para descubrir que el rendimiento no era siquiera aceptable. En
una CPU a 1.6 GHz rendía de 1 a 4 cuadros, mientras que
usuarios con CPUs más potentes obtenían hasta 15 cuadros
por segundo como máximo. Al principio pensé que
serían errores obvios en el código, pero al ampliar la
búsqueda llegué a la conclusión de que no
había nada erróneo. Lo que consume tanto tiempo son las
miles y miles de operaciones de coma flotante - algo para lo que una
GPU no va a tener problemas, y que una FPU apenas puede manejar.
De
un modo eventual publiqué un cliente Eternal Lands para AROS que
era jugable en mi equipo, pero debido a las simplificaciones y
trucos llevados a cabo la calidad gráfica era muy pobre.
Retiré la versión 7.0 de Mesa3D, eliminando su
disponibilidad para terceras partes.
Mesa como librería compartida
El
año siguiente me centré en varios elementos de AROS. Por
Julio de 2009 sin embargo, inspirado por algunos prototipos de Nick,
comencé a pensar en publicar mesa como librería
compartida. La razón era que mientras que por entonces no
disponíamos de controladores por hardware para aplicaciones
OpenGL, se podrían tener en un futuro. Si ofrecíamos
Mesa3D como librería compartida, los programadores
podrían comenzar a trabajar en aplicaciones 3D que
aprovecharían las ventajas de "futuribles" controladores por
hardware.
Lo
primero por hacer era portar la última versión de Mesa3D
(7.5). Eran pocos los cambios requeridos y enseguida publicamos una
versión de la librería linkada estáticamente. En
este momento las cosas se pusieron interesantes.
Mesa3D
hace uso de una variable global para representar un contexto de
generación de imágenes. Así funciona en Linux y
otros sistemas, puesto que el subsistema de librerías
compartidas de estos sistemas se encarga automáticamente de
generar copias de dichos objetos globales para cada usuario de la
librería. En AROS no sucede así -aquí la misma
librería debe implementarse de manera que se encargue ella de
los objetos de los clientes. Suponía un serio problema. Mesa3D
presupone que exista un contexto de generación global, pero el
contexto debe ser entonces diferente para cada cliente.
La
solución partió de una idea de Nick y del trabajo de
Staff Verhaegen en ABI V1. Consistía en crear este contexto de
generación global mediante un cliente de la librería
Mesa3D para luego hacerlo disponible a la librería en el
registro de la CPU. Aunque haya cambios de tarea durante la
ejecución de código de la librería Mesa3D, el
registro de CPU queda preservado y restaurado más tarde. De este
modo ABI V1 hace que la base de la librería este disponible para
todas las funciones.
En
Agosto de 2009 se publicó la versión compartida de
mesa.library. Desde entonces el desarrollo se aceleró.
Gallium3D controlador softpipe
Otra
de las sugerencias de Nick fue Gallium3D. Se trata de una novedosa
arquitectura de controlador 3D que se suponía sería
tremendamente portable e independiente de sistema. Alentado por el
éxito de la librería Mesa3D me centré en el
controlador softpipe de Gallium3D. Es un controlador por software,
semejante al controlador que teníamos en AROS. Pero pensé
que al ser una nueva arquitectura, el controlador sería
más rápido que el que estábamos empleando.
Comencé a portarlo tomando Xlib binding como ejemplo para AROS.
Pronto me topé con el primer obstáculo.
Gallium3D
softpipe utliza comandos SSE para acelerar los cálculos de coma
flotante. El problema sin embargo, es que la versión linux-i386
de AROS que empleaba para casi todos los desarrollos no soportaba el
almacenado del estado de los registros SSE. Cada vez que se
hacían llamadas a un comando SSE, el controlador se colgaba. Lo
positivo es que la versión de AROS pc-i386 sí que
tenía soporte para estas instrucciones, y al cabo de unos
días porté esta funcionalidad a la versión
linux-i386.
El
trabajo restante no supuso grandes problemas y a finales de Septiembre
de 2009, el controlador softpipe funcionaba.
Era
dos veces más lento que el controlador original de AROS. No
había lugar para el fracaso, así que sólo
había que seguir una dirección - intentar portar estos
"extremadamente portables e independientes " controladores por hardware.
Controlador Gallium3D nouveau - Botín Gallium3D
La
primera decisión fue - qué controlador había que
portar: Intel, nVidia o Radeon. Por entonces, no tenía ni remota
idea de cómo funcionaban las tarjetas gráficas de modo
que parecía un trabajo gigantesco. Elegí nVidia porque
siempre me gustaron esas tarjetas... o quizá por el nombre.
Fuese el motivo que fuese, con la perspectiva del paso del tiempo
me doy cuenta de que eran los controladores más sencillos de
portar - ideales para comenzar.
Lo
primero que descubrí fue que los controladores nVidia de la
librería Mesa3D no se hablan directamente con el hardware.
Requieren otra capa - denominada (D)irect (R)endering (M)anager. Los
controladores Mesa3D compilaron sin problemas puesto que el
código drm era específico del SO. La segunda
decisión que tomé fue - portar drm o crearlo desde cero
para AROS. En principio quise crearlo desde cero basándome en
nvidia.hidd, pero según me adentraba en el código, me
daba cuenta de que no era la opción acertada. En primer lugar,
el código drm contenía soporte para bajo nivel e
inicialización de toda la familia de tarjetas nVidia -
algo que no existe por ahora en nvidia.hidd. En segundo lugar, el
código drm para nVidia está en fase beta aún y
contiene muchos errores. Aunque tuviera tiempo de reescribirlo desde el
comienzo, actualizar a una nueva de versión de códigos
drm sería una auténtica pesadilla. Así
decidí portar drm a AROS.
Como
el objetivo era portar el código drm para aprovechar las
ventajas de futuras actualizaciones, debería facilitarme la
aplicación de tales actualizaciones. Por eso pensé en
modificar el código lo mínimo posible - implementando
funciones del kernel Linux requeridas por ese código. Por
fortuna eran pocas las funciones necesarias a implementar - muchas
menos de las que yo esperaba.
Realizado
el trabajo, y tras varias pruebas con tarjetas nVidia, publiqué
una versión alpha de mesa.library con aceleración por
hardware en Enero de 2010. Ofrecía soporte para las familias
GeForce
5XXX, 6XXX y 7XXX . A los pocos días, ya se habían
portado varios juegos 3D, demostrando el potencial de la
aceleración 3D en AROS incluso con unos controladores en estado
alpha carentes de algunas funcionalidades.
Añadiendo soporte AGP
Tras
la primera versión, me tomé un tiempo de descanso en el
botín para trabajar en algo que había atrapado mi
interés. Durante los tres primeros meses de trabajo con los
controladores nVidia, aprendí lo suficiente sobre aspectos de
bajo nivel como para comprender cómo funcionaban los
controladores con tarjetas PCI. Lo que me intrigaba era cómo
funcionaban los controladores con el bus AGP.
Me
llevó cierto tiempo estudiar los códigos AGP de Linux. El
código varía en función de los fabricantes de
placas, pero contaba con partes en común que aparentemente
resultaban sencillas - más de lo que pensaba.
La
primera vez traté de hacer funcionar AGP en una placa madre SiS.
Cotejando los fuentes de Linux, implementé soporte nativo en AROS y en
una semana tenía una GeForce 6200 funcionando en modo AGP. Tras este
avance, solicité colaboración a la comunidad AROS para ofrecer soporte
de otros chipsets.
Podía aprender de los fuentes de Linux, pero no podía hacer todas las
pruebas en mi equipo. Gracias a la respuesta de la comunidad, incluí
soporte para chips VIA e Intel. Aprendí bastante sobre cachés de CPU lo
que me ayudó bastante a la hora de solventar algunos problemas
persistentes en el controlador nVidia.
En Febrero de 2009 se incluyó soporte AGP en mesa.library y fue publicado en la comunidad AROS.
Hacer que funcione, y hacerlo bien...
El
resultado publicado, si bien funcionaba y era de utilidad para la
comunidad AROS, desde el punto de vista del diseño de software era poco
aceptable. El controlador por hardware estaba unido físicamente a
mesa.library y lo que es peor - funcionaba en paralelo al controlador
VESA existente, quizá por mera casualidad.
Debía extraer el controlador hardware en un módulo aparte siguiente el
sistema de controladores HIDD de AROS. El rasterizador de software
(softpipe) debía posicionarse en otro módulo e incorporar una lógica
para cuando utilizar el controlador por hardware y cuando volver al
controlador por software.
El
punto natural de separación entre Mesa y el controlador Gallium3D es la
interfaz de Gallium3D. Mesa incorpora un tracker de estado que opera
sobre la interfaz de Gallium3D. Se compone de una serie de estructuras
con punteros a funciones - una forma muy decente para modelar
interfaces en C. Pero este modo no está en la línea del concepto OOP
del sistema HIDD. Observando la complejidad de la interfaz Gallium3D y
los frecuentes cambios, rechacé la idea de reescribir el sistema HIDD -
sería una pesadilla mantener nuevas versiones de Mesa y Gallium3D. En
su lugar, opté por una sencilla interfaz HIDD que ofreciera solamente
dos funciones principales -
crear un nuevo pipe_screen Gallium3D y blit pipe_surface a BitMap.
Una vez que Mesa o cualquier cliente Gallium adquiriese pipe_screen
mediante el sistema HIDD, seguiría utilizándolo directamente tal y como
fue diseñado Gallium3D. Un equilibrio perfecto entre seguir el modelo
de diseño de AROS, y facilitar la simplicidad del sistema a la hora de
incluir nuevas versiones.
El controlador 2D
El
controlador 3D por hardware ya era un módulo separado pero seguía
funcionando sólo en modo VESA. Pronto comprendí que sería incapaz de
unir el controlador nouveau 3D con el controlador 2D nVidia de AROS.
Tendría que ofrecer un nuevo controlador nVidia basado en DRM backbone.
Pensé que sería un largo trabajo - lo bueno es que no fue así.
Para
comprobar que el controlador 3D funcionaba, porté una gran parte de
código DRM a AROS. Al escribir el controlador 2D resultó que casi todo
cuadraba. Restaba la inicialización de BIOS y soporte para lectura de
datos vía I2C. Era sencillo añadir estos componentes y rápidamente tuve
una versión del controlador 2D. Era tremendamente lento...todas las
operaciones se realizaban pixel a pixel -
sin tipo alguno de aceleración. Hoy es una de las características del
sistema de controladores 2D de AROS - esta clase implementa todas las
operaciones complejas por medio de los métodos PutPixel/GetPixel -
aunque es lento, posibilita la creación de un controlador en poco
tiempo.
Una
vez estabilizado el controlador, reemplacé las funciones "por pixel"
con sus versiones aceleradas. La implementación se basaba en el
controlador AROS existente y en el controlador EXA X86. En poco tiempo
la comunidad AROS contaba con un controlador 2D acelerado por hardware
que funcionaba en tarjetas nVidia desde la GeForce 1 hasta la más nueva
GTS250. Gracias al equipo nouveau por vuestro trabajo, por hacerlo
código libre y permitir que AROS lo arpoveche.
Unos
días después, finalicé el trabajo integrando el controlador 3D en el
controlador 2D. Gracias a este cambio se pudo añadir soporte para la
familia GeForce 8XXX y superiores. El código estaba presente, pero no
funcionaba en modo VESA. Al hacerlo funcionar en una tarjeta controlada
por DRM se pudo utlizar correctamente la aceleración 3D.
El 30 de Mayo de 2010, se publicaron dichos módulos.
Estado final
AROS
cuenta con nuevos componentes que aprovechan la potencia de las tarjetas gráficas nVidia modernas:
- mesa.library - implementación del API OpenGL
- gallium.library - módulo empleado por clientes Gallium3D para adquirir objetos pipe_screen. Por ahora empleado por mesa.library, pero en un futuro - quién sabe ¿ Quizá OpenVG, OpenCL y Cairo?
- nouveau.hidd - controlador 2D y 3D para tarjetas nVidia
- softpipe.hidd - controlador por software utilizable en sistemas no nVidia
Aunque
el trabajo de este botín ha finalizado, tengo intención de seguir
portando nuevas versiones de estos componentes. Siempre que sean
desarrollados por sus respectivos equipos, se incorporarán en AROS.
Traducción - Lizard7
No hay comentarios:
Publicar un comentario