Hay mucha buena literatura sobre el motor Quake: libros, innumerables artículos en Internet, blogs y wikis. Entre ellos, mis favoritos son
el Libro negro de programación de gráficos de Michael Abrash, publicado en 1997, y
Rocket Jump: Quake and the Golden Age of First-Person Shooters de David L. Craddock (2018).
Desafortunadamente, puede encontrar muy poca información sobre el equipo desarrollado alrededor de 1996, lo que permitió mejorar el renderizado 3D y, en particular, los gráficos del revolucionario software de identificación de juegos. Dentro de la arquitectura y el diseño de estas piezas de silicio se encuentra la historia de un duelo tecnológico entre el Rendition V1000 y el 3dfx Interactive Voodoo.
Después del lanzamiento de vQuake a principios de diciembre de 1996, parecía que Rendition se había hecho cargo. V1000 era una tarjeta rápida capaz de lanzar Quake con aceleración de hardware que, según el desarrollador, proporciona una velocidad de relleno de 25 megapíxeles / s
[1] . Justo antes de Navidad, Rendition se hizo cargo del mercado, permitiendo a los jugadores lanzar el juego con alta resolución, velocidad de cuadros y color de 16 bits
[2] . Pero, como lo ha demostrado la historia, la falla en el diseño del Vérité 1000 resultó ser fatal para la empresa innovadora.
Aplicaciones de tiempo y asesino seleccionadas correctamente
La idea de equipos especializados para la aceleración de gráficos no apareció de repente. En 1954, United Airlines tenía simuladores de vuelo para entrenar pilotos. El jugador más grande en el campo, Silicon Graphics, Inc. (SGI), apareció en 1982 y en ese momento ofrecía potentes estaciones de trabajo como Indy, O2 e Indigo². Sin embargo, los precios de estas máquinas no permitieron que las compraran los consumidores comunes (la Realidad Infinita SGI de 1993 se podía vender por $ 100,000, lo que equivale a $ 177,262 en 2019). La razón de la situación que surgió a finales de los 90 fue la combinación de tres factores.

En primer lugar, el precio de la RAM ha disminuido significativamente. Aunque hubo una gran escasez de RAM en 1995 (principalmente porque se recomendaron 8 MB de memoria para Microsoft Windows 95), durante el año el precio de la RAM cayó casi un 90%. Esto abrió perspectivas para tarjetas con buffers de cuadros increíblemente enormes (640x480 con color RGB de 16 bits) que pueden almacenar texturas localmente.
En segundo lugar, mayor rendimiento de RAM. FastPage RAM fue un paso adelante en comparación con DRAM, pero después del lanzamiento de EDO RAM, los retrasos disminuyeron en un 30% y el tiempo de acceso a RAM fue de 50 ns
[3] .
La tercera y última pieza del rompecabezas fueron las aplicaciones asesinas. La PC tiene CPU potentes, por ejemplo, Intel Pentium con una frecuencia de 166 MHz, que los desarrolladores utilizaron para crear juegos 3D de alta calidad. En 1996, todos hablaban de dos juegos: Tomb Raider de Core Design y Quake de id Software.
Rendition y V1000
Rendition Inc fue fundada en 1993. Dos años más tarde, en 1995, la compañía anunció la creación de la arquitectura V1000, que rápidamente obtuvo la licencia de cuatro OEM. Creative Labs 3D Blaster PCI, Sierra Screamin '3D, Canopus Total 3D e Intergraph Reactor fueron los primeros en aparecer en el mercado, y pronto MiRO se hizo cargo.
Reactor Intergraph. Imagen de vgamuseum.ru.Creative Labs 3D Blaster. Imagen del club "Retro Graphics Cards".Tenga en cuenta que el primer chip V1000-E fue reemplazado más tarde por un V1000L-P con menor consumo de energía y 20% más rápido
[4] .
MiroCrystal VRX. Imagen de vgamuseum.info.Canopus Total3D. Imagen de vgamuseum.ru.El nombre de las cartas cambió, pero las fichas utilizadas en ellas fueron las mismas. El único parámetro por el cual los fabricantes tuvieron que equilibrar el precio y el rendimiento fue la calidad instalada en la tarjeta RAM.
- Puerto VGA para conectarse a un monitor CRT.
- Ramdac, generalmente de Bt, pero a veces un chip AT&T.
- El núcleo de la tarjeta es un chip V1000-E, V1000-P o v1000-L.
- Ocho chips de 512 kibyte DRAM / EDO (4 mebibytes en total) para almacenar buffers de cuadros y texturas.
- 64 kb de EEPROM que contiene BIOS.
El V1000 tenía dos propiedades inherentes que es importante tener en cuenta porque 3dfx Voodoo (que analizaré más adelante) utilizó un enfoque radicalmente diferente.
En primer lugar, se suponía que la tarjeta era un reemplazo de lo que ya estaba instalado en el comprador. El chip soportaba renderizar tanto 2D como 3D en VGA, y gracias a los cambios de contexto, tenía un impresionante modo "3D en ventana". Por lo tanto, la tarjeta tenía un puerto VGA de salida única.
La segunda característica es la arquitectura de "gran hierro", basada en una sola CPU Mips que obtiene acceso a los 4 bytes de memoria. El bus de datos de 64 bits entre ellos no tenía propiedades especiales. Este diseño estandarizado facilitó la programación de la tarjeta usando el microcódigo de arranque (esto convirtió la tarjeta en la primera GPU para una PC, mucho antes de que Nvidia tuviera esta definición).
Programación V1000
El SDK
[5] vino con un conjunto de archivos de encabezado para interactuar con el lenguaje C (RRedline en Windows y Speedy3D en DOS). La representación del triángulo texturizado se parecía a lo que Vulkan con VRAM manual ofrece hoy. La API, capaz de representar triángulos texturizados basados en ángulos, también admite pruebas alfa, mezclas alfa y niebla.
#include <string.h> #include <windows.h> #include <redline.h> WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow){ int WIDTH=640, HEIGHT = 480; HWND hWndMain = ... ; // Setup Verite board and resolution/refresh rate v_handle verite; VL_OpenVerite(hWndMain, &verite); V_SetDisplayType(verite, V_FULLSCREEN_APP); V_SetDisplayMode(verite, WIDTH, HEIGHT, 16, 75); // Copy texture to VRAM bmp_info bmp = loadBMP("data\\rlogo.bmp"); v_memory memObj = V_AllocLockedMem(verite, bmp.linebytes*bmp.height); memcpy(V_GetMemoryObjectAddress(memObj), bmp.addr, bmp.linebytes*bmp.height); v_surface *display, *texture; VL_CreateSurface(verite, &display, V_SURFACE_PRIMARY, 2, V_PIXFMT_565, WIDTH, HEIGHT); VL_CreateSurface(verite, &texture, 0, 1, V_PIXFMT_565, bmp.width, bmp.height); v_cmdbuffer cmdbuffer = V_CreateCmdBuffer(verite, 0, 0); VL_LoadBuffer(&cmdbuffer, texture, 0, bmp.linebytes, bmp.width, bmp.height, memObj, 0); VL_InstallDstBuffer(&cmdbuffer, display); VL_InstallTextureMap(&cmdbuffer, texture); VL_SetSrcFunc(&cmdbuffer, V_SRCFUNC_REPLACE) // Clear screen to black VL_FillBuffer(&cmdbuffer, display, 1, 0, 0, display->width, display->height,0); // Populate cmd with triangle coo and textCoo v_kaxyzuvq vertex[3] = ... ; VL_Triangle(&cmdbuffer, V_FIFO_KAXYZUVQ, &vertex[0], &vertex[1], &vertex[2]); V_IssueCmdBuffer(verite, cmdbuffer); VL_SwapDisplaySurface(&cmdbuffer, display); }
RRedline cargó 128 KB de microcódigo en Vérité y tradujo llamadas C a llamadas de función de ensamblador V1000.
Un hecho interesante: el nombre de la API "RRedline" superó la frase "Rendition Ready" y muy probablemente fue elegido colectivamente. Sin embargo, el nombre Speedy3D fue idea de Walt Donovan.
De hecho, el v1000 era solo una CPU lenta (25 MHz), con una multiplicación de ciclo único de 32 * 32 (¡ocupando una parte sustancial del chip!), Una instrucción de ciclo único para calcular el valor inverso aproximado (es decir, la división entera aproximada de dos ciclos) y el conjunto habitual de instrucciones RISC. Ah, y también la instrucción de "carga bilineal", que leyó un bloque de memoria lineal de 2x2 y realizó un filtrado bilineal basado en valores fraccionales de u y v pasados a la instrucción. Al parecer, había un pequeño caché en el mapa, solo 4 píxeles. Por lo tanto, si aparecía un bloque 2x2 perfectamente coincidente, recibimos una reducción en la carga en el ancho de banda de la memoria.
No hubo soporte de hardware para Z-buffers. Por lo tanto, el software que se ejecutaba en v1000 tenía que leer Z, realizar una comparación y luego decidir si escribir o no.
- Walt Donovan (arquitecto de algoritmos)
Para enviar texturas y microcódigos a la tarjeta, el controlador utilizó DMA para transferir datos a través de PCI sin intervención de la CPU. En la práctica, muchas placas base no tenían el control del bus correctamente, por lo que los juegos tuvieron que volver al modo PCI FIFO, lo que afectó negativamente el rendimiento
[6] . Dentro de la tarjeta, todas las operaciones se realizaron en enteros de punto fijo de 32 bits.
Los desarrolladores decidieron que Rendition sería totalmente programable, pero no utilizaron ninguna canalización inteligente o sincronización rápida. Por lo tanto, si se necesitaran 25 instrucciones para grabar un píxel, entonces obtenemos solo 1 megapíxel / s. Si usa equipos con funcionalidad fija, puede crear un transportador que sea equivalente a estas 25 instrucciones y alcanzar 25 megapíxeles / s. Los empleados de 3dfx vinieron de SGI, por lo que eligieron el enfoque que resultó ser la decisión correcta: crear un motor de procesamiento triangular con funcionalidad fija y un subconjunto de funciones OpenGL para la administración en el equipo. Los desarrolladores de V1000 tuvieron una experiencia completamente diferente, no conocían OpenGL y, por lo tanto, decidieron que sería más correcto crear una CPU.
- Walt Donovan (arquitecto de algoritmos)
Además de todo este conjunto de funciones, la tarjeta también tenía un innovador sistema anti-aliasing, que tenía un efecto secundario divertido.
El algoritmo anti-aliasing utilizado en vQuake ha sido patentado (número de patente 6005580). Hubo una broma divertida sobre este algoritmo. Funcionó solo con triángulos, pero no con intervalos. Quake utilizó el concepto de "z-buffering perfecto", en el que los gráficos se dividieron en intervalos y se clasificaron visualmente utilizando BSP / PVS (partición de espacio binario / un conjunto de elementos potencialmente visibles). Por lo tanto, el motor creó un conjunto de intervalos que idealmente cubrían la pantalla sin superposiciones y píxeles faltantes, y para la representación, se requería una sola operación de escritura (¡sin búfer z!) En la memoria de la pantalla. Sin embargo, los datos iniciales para estos intervalos fueron triángulos. El algoritmo antialiasing buscó bordes de siluetas y los suavizó. (Para obtener más información sobre esta idea, consulte humus.name, entrada antialiasing geométrica posterior al proceso de marzo de 2011: ¡el autor inventó esta tecnología nuevamente!) Pero dado que el suavizado se realizó después de que se renderizó la pantalla (todos los intervalos ya estaban dibujados), el algoritmo conceptual tenía, aparentemente, una costilla o no. Lo pintó de todos modos. (¡Si se usara un z-buffer, solo se volverían a dibujar los bordes visibles!) En la práctica, esto no era un gran problema, porque BSP generalmente corta muy bien los triángulos invisibles.
¡Pero no con modelos de personajes! ¡Por lo tanto, vquake permitió al jugador ver personas escondidas detrás de puertas y paredes, creando una pequeña distorsión en las texturas!
- Walt Donovan (arquitecto de algoritmos)
vQuake
En el momento del lanzamiento de las cartas, admitían algunos buenos juegos. Sí, Descent II, Grand Prix Legends, IndyCar Racing II, Myst, Nascar Racing, EF2000 y Tomb Raider fueron buenos juegos, pero Quake fue el verdadero diamante en la corona, la venta más exigente y promotora. El software de identificación del juego recibió su propio puerto bajo Vérité llamado vQuake, lanzado el 2 de diciembre de 1996. Fue escrito por Walt Donovan y Stefan Share de Vérité en colaboración con id Abrash Michael.
El trabajo fue bastante laborioso, pero el puerto funcionó. Pentium 166Mhz, capaz de renderizar Quake a una resolución de 320x200 a 26 cuadros por segundo, podría saltar a 640x480 con filtrado bilineal y aún renderizar a 22 cuadros por segundo
[8] . En la práctica, los jugadores eligieron una resolución de 512x384, que se veía hermosa e hizo posible proporcionar 32 cuadros por segundo en la P166. Por un corto tiempo, vQuake ha sido sin duda la mejor forma de jugar Quake.
Renderizado de softwareVérité V1000Muchas gracias al usuario @swaaye del foro vogons.org por las capturas de pantalla de V1000 y Fruit Of the Dojo por su Quake de puerto de alta calidad y fácil de hackear en MacOSX [9] .Renderizado de softwareVérité V1000Defecto Z-buffer
Lo que le faltaba al V1000 (e indirectamente su sucesor V2200) era la aceleración de hardware del z-buffer. Tan pronto como el desarrollador incluyó una prueba de profundidad, la velocidad de llenado se redujo a 12.5 megapíxeles / sy la velocidad de fotogramas se redujo a la mitad. Como Stefan Podell explicó más tarde
[10] , vQuake (y todos los otros juegos) fueron portados al V1000 de tal manera que minimizara la lectura del z-buffer.
Los desarrolladores descubrieron que la única forma de garantizar la velocidad necesaria era transferir la parte principal del trabajo a la CPU. En el caso de vQuake, esto significaba que el mapa se usaría como un procesador de intervalo horizontal ultrarrápido que siempre escribe en el búfer z, pero z se lee y se compara solo cuando se representan enemigos. Y aunque los desarrolladores lograron crear buenos productos, las consecuencias de tal elección de arquitectura se mantuvieron durante mucho tiempo.
3dfx y drop Rendition
id Software lanzó GLQuake el 22 de enero de 1997. Fue implementado en base a miniGL (un subconjunto del estándar OpenGL 1.0, que, entre otras cosas, carecía de GL_LIGHT y GL_FOG). Este binario abrió la puerta a todas las tarjetas de PC aceleradas por hardware. En este sentido, las tarjetas Voodoo de 3dfx Interactive se distinguieron particularmente, su rendimiento sorprendente (41 fps en resolución 512x384 con color de 16 bits en P166
[11] ) se convirtió en el estándar de facto para los aceleradores 3D. La velocidad de llenado del V1000 de 25 megapíxeles / s, que una vez se compara favorablemente con el renderizado de software de Pentium, ahora parecía mediocre en un contexto de 50 megapíxeles / s de la tarjeta Voodoo, que ni siquiera se vio afectada por las pruebas z.
La respuesta de Rendition fue el V2x00 más poderoso, que paradójicamente empeoró la situación. Se anunció que, gracias al z-buffer de hardware, el V2x00 era el doble de rápido, sin embargo, no pudo mejorar ni siquiera la velocidad de cuadros en vQuake. Esta anomalía minó la confianza del cliente y afectó negativamente al desarrollador de vQuake Stefan Sharele, quien sintió que necesitaba explicar por qué el rendimiento de vQuake estaba limitado por la CPU en lugar de la GPU
[12] .
... mi reputación resultó estar contaminada por el hecho de que VQuake y VHexen2 no funcionaron más rápido en V2x00, así que debo explicar por qué sucedió esto.
[...]
Walt y Michael decidieron que, dado que Verite 1000 no funcionó muy bien en píxeles con Z-buffering, dejar que Pentium haga esta clasificación de intervalos reduciría la cantidad de píxeles que Verite necesita dibujar. Además, podríamos desactivar la función de comparación Z en Verite.
[...]
... cualquiera que sea el chip Verite, la CPU tuvo mucho trabajo.
- Stefan Podell
Además, hubo problemas significativos en la arquitectura del hardware, que inicialmente condujeron al fracaso de
[13] V2x00. Tomó varios meses solucionar el problema, e incluso después de eso, la placa aún funcionaba a una frecuencia de 50 MHz, mientras que NVidia NV3 y Voodoo2 ya alcanzaban los 100 MHz.
La tercera generación, basada en el V3300, podría cambiar el curso de la historia, pero salió demasiado tarde. El proyecto fue cancelado en 1998, después de que Rendition fuera adquirida por Micron Technology.
Mientras trabajábamos en Rendition, cometimos muchos errores. Fue posible lanzar v1000 unos meses antes (y no tener competidores durante estos meses) si desarrollamos el esquema nosotros mismos y no lo transferimos al fab. Además, el control de calidad del chip planteó preguntas. Un tipo de nuestra empresa pasó varios meses implementando descompresión mpeg en el lenguaje ensamblador V1000, pero no pudo hacerlo funcionar debido a errores impredecibles en el chip.
vQuake funcionó bien solo porque el v1000 no hizo mucho trabajo. "Renderizar esta lista de intervalos", "suavizar esta ventaja", eso es casi todo lo que hizo. Mike Abrash y yo pasamos demasiado tiempo haciendo Quake compatible con el V1000, por lo que este modelo no era adecuado a largo plazo.
- Walt Donovan (arquitecto de algoritmos)
Después del colapso de Rendition, 3dfx redobló sus esfuerzos para promover Voodoo2, cuyas características sobresalientes permitieron barrer a todos los competidores. El rey de los gráficos 3D en PC ha gobernado el mercado por un tiempo. Luego el juego continuó, aparecieron nuevos competidores en la escena, y entre ellos estaban el ATI canadiense y una compañía casi desconocida en ese momento llamada Nvidia.
Referencias
[1] Fuente:
Museo VGA, V1000 Texel Fillrate (MTexel / s) reportado como 25[2] Fuente:
John Carmack .plan 22 de agosto de 1996 "a 512 * 384 es casi el doble de rápido"[3] Fuente:
3dfx VOODOO1 Referencia Rev. 1.0[4] Fuente:
Revisión del V1000[5] Fuente:
Rendition Verite V1000 SDK[6] Fuente:
La inmadurez del bus PCI [...] causado por los errores de DMA a la superficie[7] Fuente:
Guía de programación de RRedline[8] Fuente:
puntos de referencia para comparar la Rendition Vérité V1000-E y V1000L-P[9] Fuente:
código fuente del puerto MacOSX X Quake en github.com[10] Fuente:
publicación BSS de Stephan Podell[11] Fuente:
Comparación de las tasas de cuadros en GLQuake usando Voodoo1[12] Fuente:
publicación de Stephan Podell BSS[13] Fuente:
wikipedia.com, sección Downfall