Historia de 3dfx Voodoo1

imagen

Este es el segundo artículo de la serie "Tarjetas 3D del terremoto de finales de los años 90 en las que trabajó". En la primera parte, examinamos la Rendition Vérité 1000 de finales de 1996 y un puerto de juego especial llamado vQuake. La interpretación logró derrotar a todos en el mercado de Quake. Durante un breve período de tiempo, siguió siendo la única placa capaz de lanzar el éxito de taquilla de id Software con aceleración de hardware.

Pero todo eso cambió en enero de 1997, cuando id Software lanzó una nueva versión de Quake llamada GLQuake. Dado que el puerto se creó con miniGL (un subconjunto del estándar OpenGL 1.1), cualquier fabricante de aceleradores de hardware podría escribir controladores miniGL y participar en la carrera de la tarjeta 3D. Desde ese momento, la posibilidad de competencia estaba abierta a todos. El objetivo era generar tantos fotogramas por segundo como sea posible. La recompensa fue la fama y el dinero de los clientes. Habiendo estudiado brevemente la historia, uno puede entender que las dos autoridades de esa época sin duda consideraron a los reyes de la montaña dos productores.

Hasta ahora, no hay duda al respecto: el mundo de Quake está gobernado por Voodoo. Y dado que Quake gobierna el mundo de los juegos, comprar 3Dfx Voodoo es casi inevitable para los jugadores.

- Tom's Hardware, 30 de noviembre de 1997

3DFX Voodoo 1
- El estándar por el cual se miden todas las otras tarjetas.

- John Carmack .plan archivo. 12 de febrero de 1998 [2]

Simplemente mirando las especificaciones [3] , que establecían una tasa de relleno de 50 megapíxeles / s, inmediatamente quise estudiar esta tarjeta y entender qué hizo 3dfx para crear un producto tan poderoso.

3dfx Interactive


Ross Smith, Scott Sellers y Gary Tarolli se conocieron cuando trabajaron juntos en SGI [4] . Después de trabajar un poco en Pellucid, donde intentaron vender tableros IrisVision para PC (en 1994, estos tableros costaron $ 4000 cada uno), sus colegas fundaron su propia compañía con el apoyo de Gordy Campbell TechFarm. 3dfx Interactive, con sede en San José, California, fue fundada en 1994.

Inicialmente, la compañía tenía la intención de crear potentes sistemas de hardware para máquinas recreativas, pero cambió su curso desarrollando placas para PC. Había tres razones para esto.

  1. Bastante bajo precio de RAM.
  2. Comenzando con FastPage RAM y luego EDO RAM, la latencia en RAM ha disminuido en un 30%. Ahora la memoria podría funcionar con una frecuencia de hasta 50 MHz.
  3. Los juegos en 3D (o en pseudo-3D) se han vuelto cada vez más populares. El éxito de juegos como DOOM, Descent y Wing Commander III ha demostrado que está a punto de surgir un mercado para los aceleradores 3D.

Los fundadores de la compañía se dieron cuenta de que necesitaban crear algo poderoso, diseñado para juegos y con un precio minorista en el rango de 300-400 dólares. En 1996, la compañía anunció la creación de la arquitectura SST1 (llamada así por los fundadores - Sellers-Smith-Tarolli-1), que pronto recibió licencia de varios fabricantes de equipos originales como Diamond, Canopus, Innovision y ColorMAX. Para su creación surgió el nombre comercial "Voodoo1", haciendo hincapié en su rendimiento mágico.

Como en el caso del V1000, al crear tarjetas, los fabricantes solo podían cambiar el tipo de RAM seleccionado (EDO o DRAM), el color de las placas y la disposición física de los chips. Casi todo lo demás estaba estandarizado.


Diamond Monster 3D, imagen tomada de vgamuseum.info.


Canopus Pure3D, imagen tomada de vgamuseum.info.


BIOSTAR Venus 3D, imagen tomada de vgamuseum.info.


ORCHID Righteous 3D, imagen tomada de vgamuseum.info.


Al mirar la placa SST1, fue sorprendente lo diferente que era de sus competidores: Rendition Verite 1000 y NVidia NV1.

En primer lugar, 3dfx dio un paso audaz, abandonando el soporte de renderizado 2D. Voodoo1 tenía dos puertos VGA, uno utilizado como salida y el otro como entrada. La tarjeta fue desarrollada como una adición, tomó como entrada la salida de una tarjeta VGA bidimensional, ya instalada en la computadora. Cuando el usuario trabajó con el sistema operativo (DOS o Windows), Voodoo1 simplemente redirigió la señal desde su entrada VGA a la salida VGA. Al cambiar al modo 3D, Voodoo1 tomó el control de la salida VGA e ignoró la señal de su entrada VGA. Algunas placas tenían un interruptor mecánico que hacía clic al cambiar entre los modos 2D y 3D. Esta decisión significó que la tarjeta solo se puede utilizar para el renderizado a pantalla completa, no había modo de "ventana".

El segundo aspecto notable de SST1 fue que no estaba hecho de una CPU, sino de dos ASIC no programables (Circuito integrado de aplicación específica, Circuitos integrados de propósito especial). Si camina por las huellas de los neumáticos, puede ver que cada uno de los chips etiquetados como "TMU" y "FBI" tiene su propia RAM. En la tarjeta de memoria, 4 mebibytes de RAM se dividieron en partes iguales: 2 mebibytes TMU para almacenar texturas y 2 mebibytes FBI para almacenar el búfer de color y el z-buffer, mientras que los valores se almacenaron respectivamente como RGBA de 16 bits y entero de 16 bits / medio flotante. Una tarjeta de memoria con 4 mebibytes soporta una resolución de hasta 640x480 (2 buffers de color (640x480x2) para doble buffer + 1 buffer de profundidad (640x480x2) = 1 843 200). Los modelos posteriores con 4 mebibytes de RAM del FBI permitieron el uso de resoluciones de hasta 800x600 (2x800x600x2 + 800x600x2 = 2,880,000).

Tubería de renderizado SST1


El transportador no se describe en detalle en las especificaciones. Según mi interpretación, la vida de un triángulo constaba de cinco etapas.


  1. Se crea un triángulo y se transforma en el procesador principal de la computadora (generalmente Pentium). Dichas operaciones incluyen la multiplicación por la matriz del espacio modelo / proyección, truncamiento, división de perspectiva de vértice, corte de coordenadas homogéneas y transformación del campo de visión. Al final de este proceso, solo quedan triángulos visibles del espacio de la pantalla (debido al recorte, un triángulo puede resultar ser dos).
  2. Usando el comando triangleCMD, los triángulos se transfieren a través del bus PCI a la interfaz Frame Buffer (FBI). Se convierten en consultas de cadena de trama creadas por la Unidad de asignación de textura. Para cada elemento de la línea de trama (llamado fragmento), la TMU realiza hasta cuatro consultas de búsqueda por píxel si el desarrollador requiere un filtrado bilineal. La división de perspectiva fragmentada también se realiza en TMU.
  3. TMU envía fragmentos al FBI como un valor de color RGBA texturizado de 16 bits + valor z de 16 bits.
  4. El FBI realiza pruebas de fragmentos en el búfer z, comparándolos con RAM dedicada, que almacena valores RGBA y valores z del búfer de trama.
  5. Finalmente, la iluminación se aplica al fragmento en función de su atributo de color y una búsqueda en la tabla de niebla de 64 elementos. Si se requiere mezclar, el FBI combina el fragmento resultante con lo que ya está en el búfer de color.

Dato interesante: si eres un entusiasta del 3D, probablemente conozcas el código de raíz cuadrada inversa rápida, que se hizo famoso gracias al código original de Quake 3:

float Q_rsqrt(float number) { long i; float x2, y; const float threehalfs = 1.5f; x2 = number * 0.5f; y = number; i = * (long*) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration return y; } 

En busca de [5] la fuente Q_rsqrt Rys for Software contactó a Gary Tarolli, quien dijo que utilizó este código mientras todavía trabajaba en SGI. Por lo tanto, es justo suponer que también se usó en la tubería SST1.

Algo no coincide


Habiendo familiarizado con el transportador y sabiendo que cada componente (TMU, FBI, EDO RAM) opera a una frecuencia de 50 MHz, podemos entender que hay algún tipo de error en los cálculos y que la tarjeta no puede alcanzar una velocidad de 50 megapíxeles / s. Dos problemas tuvieron que ser resueltos aquí.

Primero, la TMU tuvo que leer cuatro texels para realizar el filtrado de textura bilineal. Esto significa que se requieren cuatro ciclos de acceso a RAM, lo que llevaría a una falta de datos para TMU y una tasa de llenado de 50/4 = 12.5 megapíxeles / s.

Hay otro cuello de botella en el nivel del FBI. Si la comprobación del búfer z está habilitada, antes de escribir o descartar el valor z entrante del fragmento debe compararse con lo que ya está en el búfer z. Si la prueba fue exitosa, entonces se debe registrar el valor. Estas son dos operaciones con RAM, lo que condujo a una disminución en la tasa de llenado a la mitad: 50/2 = 25 megapíxeles / s.

TMU intercalado de cuatro vías


La solución al problema de las cuatro muestras en la etapa TMU se menciona en la especificación SST1.

El entrelazado completo se implementa en la ruta de datos de la memoria de textura, lo que permite que un solo banco acceda a los datos independientemente de la dirección utilizada para acceder a los datos en otros bancos.

- Especificación SST1

No indica si el bus utiliza multiplexación de direcciones, o buses de datos y direcciones comunes. Es más fácil averiguarlo si los dibuja sin multiplexación y sin separación.


Independientemente de los detalles, la arquitectura TMU permitió recibir 4 texels de 16 bits por ciclo. Si los datos de entrada llegan a la frecuencia correcta, la TMU puede realizar una división por fragmentos por w, y luego generar el valor z del fragmento (16 bits) y el color del fragmento (16 bits), que se transmitieron al FBI.

FBI intercalado de dos vías


La solución al problema de dos operaciones de acceso a RAM en la etapa del FBI tampoco se describe en la especificación. Sin embargo, el documento menciona una tasa de relleno de 100 megapíxeles / s lograda con glClear debido a la capacidad de grabar dos píxeles por ciclo, y esto nos hace comprender que aquí se utilizó el entrelazado bidireccional.


El FBI leyó y escribió dos píxeles a la vez (2 x 1 píxeles que consisten en color de 16 bits y z de 16 bits = 64 bits). Para hacer esto, la dirección de 21 bits genera dos direcciones de 20 bits, en las que se descarta el bit menos significativo para leer / escribir dos píxeles en orden. Dado que el algoritmo de línea de trama necesario para escribir / leer en líneas horizontales se mueve de izquierda a derecha, leer dos píxeles ordinales a la vez funcionó muy bien.

Bus de 64 bits TMU-> FBI


La pieza final del rompecabezas es el bus FBI-TMU de 64 bits. Casi nada está escrito al respecto en la especificación, pero su comportamiento puede ser entendido por los datos que consume el FBI. Dado que el FBI procesa dos píxeles a la vez, es razonable suponer que la TMU no envía texels lo más rápido posible, sino que los combina dos como dos colores de 16 bits + valor z de 16 bits.

Programando Voodoo1


En el nivel más bajo, la programación de Voodoo1 se realizó utilizando registros mapeados en memoria. La API consta de un número sorprendentemente pequeño de comandos, solo hay cinco de ellos: TRIANGLECMD (con un punto fijo), FTRIANGLECMD (con un punto flotante), NOPCMD (no-op), FASTFILLCMD (limpieza del búfer) y SWAPBUFFERCMD relacionados con la carga de registros de datos para mezclar configuraciones, Prueba z, descargas de color de niebla y más. La carga de textura en VRAM se realizó a través de 8 mebibytes de RAM de PCI de solo escritura con mapeo de memoria.

(Real) Programación Voodoo1


Los desarrolladores programaron Voodoo1 a través de la API Glide [6] . La lógica de diseño de API se inspiró en IRIS GL / OpenGL, usó una máquina de estado y prefijos para todo (solo se usó "gr" en lugar de "gl", y los programadores necesitaban controlar VRAM, como ahora se hace en Vulkan).

 #include <glide.h> void main( void ) { GrHwConfiguration hwconfig; grGlideInit(void); grSstSelect( 0 ); grSstQueryHardware(&hwconfig); grSstSelect(0); grSstWinOpen(null, GR_RESOLUTION_640x480, GR_REFRESH_60HZ, GR_COLORFORMAT_RGBA, GR_ORIGIN_LOWER_LEFT, 2, 0); grBufferClear(0, 0, 0); GrVertex A, B, C; ... // Init A, B, and C. guColorCombineFunction( GR_COLORCOMBINE_ITRGB ); grDrawTriangle(&A, &B, &C); grBufferSwap( 1 ); grGlideShutdown(); } 

MiniGL "estándar"


Aunque MiniGL era un subconjunto del estándar OpenGL 1.1, nunca se publicó una especificación para él. MiniGL era "solo esas características que usa Quake". Al ejecutar objdump para el binario quake.exe, es fácil crear una lista "oficial".

  $ objdump -p glquake.exe |  grep "gl"

 glAlphaFunc glDepthMask glLoadIdentity glShadeModel
 glBegin glDepthRange glLoadMatrixf glTexCoord2f
 glBlendFunc glDisable glMatrixMode glTexEnvf
 glClear glDrawBuffer glOrtho glTexImage2D
 glClearColor glEnable glPolygonMode glTexParameterf
 glColor3f glEnd glPopMatrix glTexSubImage2D
 glColor3ubv glFinish glPushMatrix glTranslatef
 glColor4f glFrustum glReadBuffer glVertex2f
 glColor4fv glGetFloatv glReadPixels glVertex3f
 glCullFace glGetString glRotatef glVertex3fv
 glDepthFunc glHint glScalef glViewport 


Si comenzó a aprender OpenGL recientemente, debería estar intrigado por nombres de funciones como glColor3f, glTexCoord2f, glVertex3f, glTranslatef, glBegin y glEnd. Se utilizaron para un modo llamado "Modo inmediato", en el que la coordenada de vértice, la coordenada de textura, la manipulación de la matriz y el color se indicaban mediante una llamada de función a la vez.

Así es como "en esos días" se dibujó uno con textura y sombreado por el triángulo de Gouraud.

 void Render { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glBindTexture(GL_TEXTURE_2D, 1); // Assume a texture was loaded in textureId=1 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_TRIANGLES); glColor3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-0.25f,0.0f); glColor3f(0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f,-0.25f,0.0f); glColor3f(0.5f, 0.5f, 0.5f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.75f,0.25f,0.0f); glEnd(); 

GLQuake


Se suponía que la tasa de relleno máxima teórica de 50 megapíxeles / s proporcionaría casi 50 fotogramas por segundo en una resolución de 640x480. Sin embargo, dado que Quake combinó dos capas de texturas por superficie (una para el color y la otra para el mapa de luz), SST1 tuvo que dibujar cada cuadro dos veces con una mezcla adicional en la segunda pasada. Como resultado, Quake corrió a 26 fps en el P166Mhz.

Al reducir la resolución a 512x384 en la misma máquina, fue posible lograr 41 fps suaves [7] , que en ese momento no podía ser proporcionado por ningún competidor.

imagen

Renderizado de software

imagen

GLOCAKE VOODOO1



Dato interesante: SST1 no era para todos. A algunas personas les gustaron los píxeles y encontraron que el filtrado bilineal era "borroso". Otros estaban molestos por la pérdida de la corrección gamma.

Glquake parece una mierda. Creo que alguien puede discutir esto, pero admitámoslo: se ve horrible, especialmente en las tarjetas NVidia. En las placas 3dfx, no todo es tan malo ... pero los colores siguen siendo borrosos. En TNT2, la imagen es asquerosa; ella es demasiado oscura y sombría.

- @Frib, Guía no oficial de Glquake & QW [8]

3fdx Voodoo 2



Si dijera que las reglas 3dfx en el mercado desde 1996 hasta 1998, esto sería un eufemismo. Después de SST1, la tecnología Voodoo 2 elevó el listón aún más gracias a la RAM EDO de 100 MHz, ASIC con una frecuencia de 90 MHz, y no solo una, sino dos TMU, que permiten renderizar un marco Quake de múltiples texturas (color + iluminación) en una sola pasada [9] . Esta tecnología era un verdadero monstruo, e incluso las tarjetas gráficas parecían lujosas.

La velocidad de llenado en Voodoo 2 casi se duplicó, alcanzando los 90 megapíxeles / s. Los puntos de referencia de Quake se han disparado a unos impresionantes 80 fps en el Pentium II 266 MMX (en comparación con 56 fps con Voodoo1), llegando esencialmente a los límites de la lógica del juego y las capacidades de monitor.

imagen

Super Voodoo 2 12MB, imagen tomada de vgamuseum.info.

Desafortunadamente, después del lanzamiento de Voodoo3 en 1999, la historia de 3dfx dio un giro brusco. Comenzó a esforzarse por desarrollar sus propias tarjetas universales y dejó de vender tecnología OEM, ante la creciente competencia.

Esta transición no se completó como se esperaba, y el rendimiento de Voodoo3 fue decepcionante en comparación con GeForce 256 de NVidia, capaz de proporcionar teselación e iluminación de hardware (Pentium hizo esta parte en la tubería).

En respuesta a NVidia, 3dfx canceló el desarrollo de Voodoo4 para comenzar a construir Voodoo5 con la tecnología VSA-100 (arquitectura escalable de Voodoo). El resultado fue inesperado: después del lanzamiento de "Napalm" (el nombre en clave de la tarjeta), se topó con tarjetas NVidia GeForce 2 y ATI Radeon más potentes. Al final, el 28 de marzo de 2000, 3dfx se declaró en quiebra y fue comprado por NVidia.

Para aquellos que vivieron a finales de los 90 y tuvieron el placer de jugar Voodoo1 o Voodoo2, 3dfx sigue siendo una empresa emblemática que simboliza la excelencia. Se convirtió en una oda al merecido éxito logrado a través del coraje, el talento excepcional y el trabajo duro. Gracias chicos

Referencias


[1] Fuente: La historia de la Rendition Vérité 1000

[2] Fuente: John Carmack .plan. 12 de febrero de 1998

[3] Fuente: SST-1, MOTOR GRÁFICO DE ALTO RENDIMIENTO PARA LA ACELERACIÓN DE JUEGOS 3D

[4] Fuente: Panel de Historia Oral 3dfx

[5] Fuente: Origen de Quake3 Fast InvSqrt ()

[6] Fuente: Guía de programación Glide

[7] Fuente: Comparación de las velocidades de fotogramas en GLQuake usando tarjetas 3D Voodoo y Voodoo 2

[8] Fuente: Frib, Glof no oficial y guía QW

[9] Fuente: GRÁFICOS VOODOO2 MOTOR GRÁFICO DE ALTO RENDIMIENTO PARA LA ACELERACIÓN DE JUEGOS 3D

Source: https://habr.com/ru/post/446860/


All Articles