Glide vs Direct3D: la guerra de APIs que decidió el futuro del gaming

¿Te fue útil?

Estás de guardia. Llega un parche “sencillo”. De pronto tu granja de compilación en Windows no puede reproducir un fallo que el laboratorio de QA ve al instante—solo con un controlador GPU específico, solo después de cargar un nivel, solo cuando la sincronización vertical está desactivada (v-sync).
Si ese dolor te suena moderno, felicidades: acabas de revivir los años 90, cuando las APIs gráficas no eran tanto abstracciones como armas políticas.

La pelea Glide vs Direct3D no fue solo por triángulos. Fue por quién poseía el tiempo del desarrollador, quién cargaba con la responsabilidad del driver y quién recibía las culpas cuando los fotogramas se convertían en confeti.
Esa batalla decidió cómo escalaría el gaming en PC—y aún enseña lecciones incómodas sobre plataformas, portabilidad y realidad operativa.

Lo que realmente estaba en juego (y por qué te debe importar)

La historia superficial es familiar: una API propietaria (Glide) construida para el hardware Voodoo de 3dfx frente a Direct3D de propósito general de Microsoft.
Pero “API” aquí no era un contrato ordenado. Era un canal de distribución, una elección de experiencia de desarrollador y una apuesta por la fiabilidad.

Glide ofrecía una interfaz estrecha alineada con el hardware: menos opciones, menos sorpresas y, en muchos casos, un rendimiento muy alto.
Direct3D ofrecía una abstracción amplia: más dispositivos, más drivers, más casos límite y, en última instancia, más alcance.

Si gestionas sistemas en producción, ya conoces el patrón.
La interfaz propietaria es la que hace que tu demo brille. La interfaz estandarizada es la que sobrevive al segundo proveedor, a la tercera actualización del SO y a la quinta reorganización del equipo.

El gaming a finales de los 90 fue un laboratorio caótico para ese compromiso.
El bando ganador no fue el que hacía los “mejores” triángulos.
Fue el que hacía posibles los triángulos en la mayor cantidad de máquinas con el menor drama continuo.

Glide en la práctica: rápido, estrecho y peligrosamente cómodo

Glide fue la API de 3dfx para hardware clase Voodoo. El detalle clave: fue diseñada para mapear limpiamente a lo que el hardware podía hacer, no para describir una “GPU ideal” abstracta.
Eso suena como una diferencia filosófica menor hasta que has publicado software.

Cuando la API se alinea con el hardware, obtienes menos “acantilados de rendimiento”. También obtienes menos “comportamientos indefinidos”, porque la API simplemente se niega a expresar muchas combinaciones peligrosas.
En términos operativos: Glide reducía el número de estados a los que el sistema podía entrar. La fiabilidad adora eso.

La estrechez de Glide también produjo una especie de dependencia del desarrollador. Los juegos se publicaban con “soporte Glide” como característica principal, y para los jugadores con una tarjeta Voodoo, a menudo se veía y funcionaba mejor que las alternativas.
El problema es qué ocurre cuando no tienes esa tarjeta. O cuando esa tarjeta se vuelve “de la generación anterior” en un mercado que se reinventa cada 12–18 meses.

Glide no era portable. No estaba pensada para serlo. Desde la perspectiva de 3dfx, eso no era un error; era el sentido.
Si construyes la mejor carretera y solo tus coches pueden circular por ella, no estás gestionando un sistema de transporte—estás gestionando una caseta de peaje.

Lo que Glide hizo bien (la parte que la gente idealiza)

  • Rendimiento predecible. Menos capas significaban menos sorpresas y menor sobrecarga de CPU, especialmente en una era en la que los CPUs luchaban por alimentar a las GPUs.
  • Modelo mental claro. Los desarrolladores podían razonar sobre lo que hacía la canalización Voodoo y escribir código que coincidiera con ello.
  • Menos permutaciones de drivers. Si apuntas a un único proveedor y a una familia de productos cerrada, tu matriz de pruebas se reduce dramáticamente.

Lo que Glide no hizo bien (la parte que se olvida)

  • Fragilidad de mercado. Tu “plataforma” es tan durable como el balance y la hoja de ruta del proveedor.
  • Bloqueo de desarrollador. El lock-in corta en dos direcciones: atrapa al estudio de juegos también, no solo al cliente.
  • Riesgo operativo. Si la única ruta de render aceptable es Glide y el proveedor no puede mantenerse al día (características, drivers, fabricación), te quedas enviando compromisos.

Direct3D en la práctica: desordenado, amplio e inevitable

Direct3D entró en la pelea con una desventaja: las versiones iniciales eran famosas por ser difíciles de usar e inconsistentes entre hardware.
Microsoft intentaba definir un contrato gráfico para un mercado que no había decidido siquiera qué significaba “aceleración 3D”.

Aquí está la ventaja injusta de Direct3D: residía dentro de Windows, y Windows era el mecanismo de distribución para el gaming en PC gustara o no.
Si querías lanzar un juego de mercado masivo para PC, querías la API que estaba presente en el SO objetivo sin un ritual adicional de instalaciones y oraciones de compatibilidad.

El modelo de Direct3D también encajaba con la realidad desordenada de un mundo con múltiples proveedores. En lugar de un objetivo de hardware, tenías muchos. En lugar de una pila de drivers, tenías una jungla.
Eso hacía que Direct3D pareciera más lenta y con más bugs a corto plazo. A largo plazo, la hacía sobrevivible.

El ángulo de la fiabilidad: donde Direct3D ganó silenciosamente

Direct3D creó un incentivo de ecosistema: los IHV (proveedores de GPU) tuvieron que hacer que sus drivers funcionaran con la API de Microsoft porque el mercado lo demandaba.
Eso traslada la carga lejos de cada estudio de juegos manteniendo rutas a medida y hacia los proveedores manteniendo compatibilidad y rendimiento para una interfaz compartida.

No fue bonito. Pero escaló. Una API estandarizada convierte el “caos por título” en “responsabilidad por driver”, y entonces el mercado castiga a los peores drivers.
No inmediatamente, ni siempre de forma justa, pero finalmente.

Chiste #1: Los bugs de drivers son como la purpurina—una vez abres la bolsa, los encontrarás en lugares no relacionados durante meses.

Hechos y contexto histórico que puedes usar en una pizarra

Algunos puntos concretos que importan cuando intentas entender por qué esta guerra terminó como terminó:

  1. Las tarjetas add-in 3dfx Voodoo inicialmente eran solo 3D. Muchos sistemas usaban una tarjeta 2D más una tarjeta Voodoo con un cable de paso.
  2. Glide estaba ligada al pipeline hardware de 3dfx. Ese acoplamiento estrecho ayudó al rendimiento pero limitó la portabilidad y la evolución de características.
  3. La reputación temprana de Direct3D sufrió por la fragmentación. Diferentes hardwares soportaban capacidades distintas; los desarrolladores veían resultados inconsistentes.
  4. “DirectX” agrupaba múltiples APIs multimedia. Para juegos, D3D se benefició de formar parte de una historia de plataforma más amplia: entrada, sonido y gráficos bajo un mismo paraguas.
  5. MiniGL existió como un hack pragmático. Algunos proveedores ofrecieron una capa OpenGL recortada adaptada a juegos específicos, mostrando cuán desesperado estaba el ecosistema por rutas viables.
  6. OpenGL de la era Quake aceleró expectativas. Incluso cuando Glide era rápido, la industria aprendió a valorar APIs que no dependieran de un solo proveedor.
  7. La calidad del driver se volvió una característica competitiva. Los proveedores que enviaban drivers D3D más rápidos y estables ganaron notoriedad y acuerdos OEM.
  8. 3dfx adquirió STB Systems. La integración vertical puede ser inteligente, pero también cambia las relaciones de canal y el riesgo de ejecución en un mercado rápido.
  9. 3dfx finalmente perdió la batalla de plataforma y fue adquirida por NVIDIA. La estrategia de API propietaria no sobrevivió a la empresa que la poseía.

Cómo terminó la guerra: economía, tooling y el “impuesto del driver”

La narrativa fácil es “Direct3D ganó por Microsoft”. Eso es cierto en el mismo sentido en que “el océano está mojado” es cierto: exacto, poco útil y falla en explicar el mecanismo.

El mecanismo fue el coste total de propiedad para desarrolladores y publishers.
Si diriges un estudio, no solo te importa el FPS pico en la mejor tarjeta. Te importa:

  • cuántas máquinas de clientes pueden ejecutar tu juego en absoluto,
  • con qué frecuencia se llenan tus líneas de soporte,
  • lo caro que es tu laboratorio de pruebas,
  • cuán arriesgada está tu fecha de envío cuando el mercado GPU cambia a mitad de proyecto.

Glide optimizaba la cima de la experiencia para un fragmento del mercado. Direct3D optimizó la amplitud de la experiencia a través de un mercado que crecía rápidamente.
Cuando los PCs se convirtieron en una plataforma de juego masiva, la amplitud venció a la pureza.

Existe un segundo mecanismo: herramientas e inercia del ecosistema. D3D mejoró. Microsoft iteró. Los proveedores se adaptaron. Los desarrolladores construyeron pipelines alrededor de ella.
Glide no tenía un “gradiente de presión” multivendedor para mantenerla honesta. Tenía la hoja de ruta de 3dfx, y cuando esa hoja de ruta falló, el destino de la API quedó sellado.

El “impuesto del driver” y quién lo paga

Toda pila gráfica paga un impuesto por el driver: peculiaridades de rendimiento, sobrecarga de validación de estados, detección de características y bugs específicos del proveedor.
La pregunta clave es dónde recae ese impuesto.

En un mundo de APIs propietarias, el impuesto se paga en costes de portado y clientes perdidos. En un mundo de APIs estandarizadas, el impuesto se paga en ingeniería de drivers y trabajo de conformidad.
Uno escala a través de todo el mercado; el otro se repite por título.

Lecciones operativas: lo que un SRE aprende de una guerra de APIs gráficas

Si entrecierras los ojos, las APIs gráficas son sistemas distribuidos. La aplicación, el runtime, el driver, el kernel y el microcódigo de la GPU tienen cada uno sus propios modos de fallo.
Tu “petición” es un fotograma. Tu “SLO” es la consistencia del tiempo de fotograma. Tu “incidente” es un crash, un reinicio del dispositivo o un stutter que marea a los jugadores.

La historia Glide vs Direct3D es un caso de estudio en gestionar el radio de explosión. Glide redujo la variabilidad estrechando los objetivos de hardware. Direct3D redujo la variabilidad estandarizando interfaces
y permitiendo que los proveedores compitieran en la implementación.

Ningún enfoque elimina la falla. La trasladan. Glide la traslada a la dependencia de mercado y al riesgo de plataforma. D3D la traslada al comportamiento de drivers y a la evolución de la API.

Una frase que sigue importando

Werner Vogels (CTO de Amazon) dijo: “Everything fails, all the time.”
En el mundo de los gráficos, eso es menos filosofía y más pronóstico.

Tres mini-historias corporativas desde las trincheras

Mini-historia 1: El incidente causado por una suposición equivocada

Un estudio de tamaño medio (llamémoslo Estudio A) lanzó un título de PC con una arquitectura de render doble: D3D para la mayoría de usuarios, más una “ruta rápida” para la tarjeta de un proveedor concreto.
La ruta del proveedor no se llamaba Glide, pero bien podría haber sido: asumía un conjunto estable de comportamientos hardware y peculiaridades de driver.

Tarde en el ciclo de lanzamiento, QA informó de crashes aleatorios en un subconjunto de máquinas después de hacer alt-tab. No reproducible en las máquinas de desarrollo del equipo, que eran todas de gama alta.
La firma del crash parecía un use-after-free dentro del renderer. El equipo lo trató como una condición de carrera en su motor.

La causa real: una suposición equivocada sobre la pérdida de dispositivo y la vida útil de recursos. La ruta específica del proveedor asumía que la “pérdida de dispositivo” era rara y que los recursos sobrevivirían
a un cambio de modo. En algunos drivers, alt-tab provocaba un reinicio del dispositivo que invalidaba texturas. El motor mantenía punteros a recursos que ya no eran válidos.

La solución no fue glamorosa. Implementaron un manejo robusto de pérdida de dispositivo en ambos renderers, hicieron explícita la propiedad de recursos y añadieron un arnés de pruebas para simular reinicios de dispositivo.
La tasa de crashes bajó. Los tickets de soporte disminuyeron. El rendimiento cayó ligeramente porque las rutas de validación y re-creación pasaron a ser código real, no deseos.

La lección: las “rutas rápidas” propietarias o específicas del proveedor tienden a desactivar silenciosamente los rieles de seguridad de los que no te dabas cuenta.
Las suposiciones son baratas; los incidentes no lo son.

Mini-historia 2: La optimización que se volvió en contra

Otra compañía (Publisher B con un equipo interno de motor) se obsesionó con la sobrecarga de draw-calls. Razonable. Apuntaban a una escena limitada por CPU.
Un ingeniero propuso “sombreado de estado”: rastrear el último estado GPU y omitir cambios de estado redundantes.

En papel, esto era una victoria. En microbenchmarks redujo las llamadas al driver y mejoró el tiempo de CPU. Se desplegó a producción.
Entonces comenzaron los informes de bugs: texturas que ocasionalmente “se quedaban” de objetos previos y algunos materiales se renderizaban con el modo de blending equivocado—solo en el driver de un IHV, solo después de largas sesiones de juego.

La raíz fue sutil. Su capa de sombreado asumía que si el motor no llamaba a “set state”, el estado del driver permanecía sin cambios. Pero el driver realizaba invalidaciones internas de estado
alrededor de eventos de paginación de recursos. El modelo del mundo del motor y el del driver divergieron.

La “optimización” se convirtió en una máquina de desincronización de estado. La retiraron y la reemplazaron con un enfoque más seguro: construir objetos de estado de pipeline inmutables cuando fuera posible,
y tolerar algunas llamadas redundantes cuando no.

El rendimiento volvió a ser “aceptable”, y la corrección volvió a ser “real”.
El equipo del motor aprendió una regla durable: puedes cachear estado en el límite de la API, pero solo si también posees cada evento que pueda invalidar ese estado. En gráficos, rara vez lo haces.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Un equipo de plataforma en una gran empresa (sí, las empresas también envían apps 3D) mantenía un producto de visualización basado en Windows usado en entornos regulados.
A sus clientes les disgustaban las sorpresas más de lo que les gustaban los FPS.

El equipo mantenía una matriz de compatibilidad: build del SO, familias de modelos GPU y versiones de driver validadas.
También hacían builds reproducibles con toolchains fijados y archivaban archivos de símbolos por cada lanzamiento.
Nada de esto era emocionante. Tampoco era opcional.

Un día, un cliente actualizó drivers GPU en toda una flota y reportó corrupción intermitente en el render. El driver del proveedor tenía una regresión en una ruta de shader específica.
Porque el equipo había fijado “drivers conocidos buenos” y podía comparar el comportamiento rápidamente, aislaron la regresión en horas en lugar de semanas.

Enviaron un aviso al cliente: retroceder a los drivers validados, más una solución temporal en runtime que evitaba la opción problemática de compilación de shader.
El cliente siguió operativo. El proveedor obtuvo un repro mínimo. Eventualmente llegó un driver arreglado.

La lección: las prácticas aburridas—fijar versiones, matrices, símbolos, builds reproducibles—no parecen progreso hasta el día en que previenen un outage de varias semanas disfrazado de “rareza gráfica”.

Tareas prácticas: comandos, salidas y decisiones (12+)

Estas son las clases de tareas que ejecutas cuando un pipeline de render está inestable o lento en máquinas Windows, agentes de CI o máquinas de usuario final.
El objetivo no es “recopilar datos”. El objetivo es: llegar a una decisión rápido.

Tarea 1: Identificar GPU y versión de driver (estación Linux o entorno tipo Steam Deck)

cr0x@server:~$ lspci -nn | grep -E "VGA|3D"
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184] (rev a1)

Significado de la salida: Tienes el proveedor, el PCI ID y la familia del modelo.

Decisión: Elige la rama de driver correcta y la lista de problemas conocidos para esa familia; no adivines basándote en “es NVIDIA”.

Tarea 2: Confirmar el driver de kernel cargado (Linux)

cr0x@server:~$ lsmod | egrep "nvidia|amdgpu|i915" | head
nvidia_drm             73728  4
nvidia_modeset       1114112  8
nvidia              56770560  345
drm_kms_helper        315392  2 nvidia_drm

Significado de la salida: Qué driver está realmente activo, no solo instalado.

Decisión: Si el módulo esperado no está presente, detén el análisis de rendimiento. Arregla la carga del driver primero.

Tarea 3: Inspeccionar el renderer y versión de OpenGL (útil al triagear ports/encapsuladores legacy)

cr0x@server:~$ glxinfo -B | egrep "OpenGL vendor|OpenGL renderer|OpenGL version"
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce GTX 1660/PCIe/SSE2
OpenGL version string: 4.6.0 NVIDIA 550.54.14

Significado de la salida: Confirma qué stack está proporcionando GL; a menudo se correlaciona con cómo se comportan capas de wrapper (como antiguas capas de emulación Glide).

Decisión: Si el renderer es “llvmpipe” o “Software Rasterizer”, estás renderizando por CPU; trata todos los números de tiempo de fotograma como sin sentido.

Tarea 4: Confirmar info de dispositivo y driver en Vulkan (análogo moderno para enumerar capacidades)

cr0x@server:~$ vulkaninfo --summary | head -n 12
VULKANINFO SUMMARY
==================
Vulkan Instance Version: 1.3.275

Devices:
--------
GPU0:
    apiVersion         = 1.3.275
    driverVersion      = 550.54.14
    vendorID           = 0x10de
    deviceName         = NVIDIA GeForce GTX 1660

Significado de la salida: Confirma el runtime, la versión de API y la versión de driver que afectarán a capas de traducción y compiladores de shaders.

Decisión: Si driverVersion está en la lista de conocidos problemáticos, haz rollback o fija la versión. No “optimices” alrededor de un driver roto salvo que sea imprescindible.

Tarea 5: Capturar la utilización GPU en tiempo real (NVIDIA)

cr0x@server:~$ nvidia-smi dmon -s pucm -d 1
# gpu   pwr gtemp mtemp    sm   mem   enc   dec  mclk  pclk
# Idx     W     C     C     %     %     %     %   MHz   MHz
    0    78    67     -    92    55     0     0  5000  1860
    0    81    68     -    94    58     0     0  5000  1860

Significado de la salida: “sm” cerca del 90% sugiere bound por GPU; “sm” bajo con CPU alta sugiere bound por CPU o por submit/driver.

Decisión: Si la GPU está saturada, deja de perseguir la sobrecarga de draw-calls y mira coste de shaders, overdraw, resolución y post-procesado.

Tarea 6: Comprobar saturación de CPU y presión de scheduling (Linux)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server) 	01/13/2026 	_x86_64_	(16 CPU)

11:32:20 AM  CPU   %usr %nice %sys %iowait %irq %soft  %steal %guest %gnice %idle
11:32:21 AM  all   68.50 0.00  9.12   0.20 0.00  0.88   0.00   0.00   0.00 21.30
11:32:21 AM    6   99.00 0.00  0.50   0.00 0.00  0.50   0.00   0.00   0.00  0.00

Significado de la salida: Un núcleo caliente al 99% a menudo indica un cuello de botella del hilo principal en la ruta de submit de render.

Decisión: Si un solo core está al máximo, prioriza batching, ordenación de estados y reducción de llamadas a la API—restricciones clásicas de la era D3D, aún reales hoy.

Tarea 7: Encontrar los mayores consumidores de CPU y conteo de hilos (Linux)

cr0x@server:~$ ps -eLo pid,tid,psr,pcpu,comm --sort=-pcpu | head
 4121  4121   6 98.7 game.exe
 4121  4128   3 22.1 game.exe
 4121  4135   9 10.4 game.exe
 2380  2380  11  4.0 Xorg
 3012  3012   1  1.9 pulseaudio

Significado de la salida: Muestra si estás limitado por un solo hilo o si un pool de workers está caliente.

Decisión: Si el TID principal domina, comienza con costos del hilo de render y de construcción de fotogramas. Si muchos hilos están calientes, busca contención o demasiado trabajo en background.

Tarea 8: Inspeccionar presión de memoria que causa stutter (Linux)

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 514232  61244 921440    0    0    12    18  420  980 72  9 19  0  0
 3  0      0 489120  61244 924880    0    0     8    24  500 1100 75  8 17  0  0
 5  1      0  50200  58000 890000    0    0  1200   900  900 3000 65 12 10 13  0

Significado de la salida: Un aumento de “b” (bloqueados) y de IO “bi/bo” junto con poca memoria libre puede significar que el streaming de texturas o el thrash del shader cache está pegando al disco.

Decisión: Si los picos de IO se correlacionan con stutter, aborda el streaming de assets, la ubicación del shader cache y los presupuestos de memoria antes de tocar “optimización” GPU.

Tarea 9: Confirmar latencia de disco para shader caches y streaming de assets (Linux)

cr0x@server:~$ iostat -xz 1 3
Linux 6.8.0 (server) 	01/13/2026 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          61.20    0.00    8.10    4.50    0.00   26.20

Device            r/s     w/s   rkB/s   wkB/s  avgqu-sz  await  %util
nvme0n1         120.0    90.0  4800.0  3500.0      2.10  6.20  78.00

Significado de la salida: “await” de varios ms y %util alto bajo carga puede crear stutter visible cuando la compilación de shaders o el streaming golpean el almacenamiento.

Decisión: Si el almacenamiento está caliente, mueve caches a medios más rápidos, reduce la compilación en runtime o precompila. No culpes a la GPU por el disco.

Tarea 10: Comprobar reinicios del driver GPU (TDR) desde logs (al analizar un volumen Windows offline)

cr0x@server:~$ grep -R "Display driver" -n /mnt/windows/Windows/Logs/System.evtx.txt | head
1842: Display driver nvlddmkm stopped responding and has successfully recovered.
3229: Display driver nvlddmkm stopped responding and has successfully recovered.

Significado de la salida: Clásico Timeout Detection and Recovery: el driver reinició la GPU después de un hang.

Decisión: Trátalo como un incidente de fiabilidad: reduce largas esperas de shader, evita cargas patológicas de GPU, verifica versiones de drivers. No “aumentes TdrDelay” como primera medida.

Tarea 11: Verificar qué DLLs carga un juego legacy o wrapper (artefactos Windows inspeccionados desde Linux)

cr0x@server:~$ strings -a /mnt/windows/Games/OldTitle/game.exe | egrep -i "glide|d3d|opengl|ddraw" | head
d3d8.dll
ddraw.dll
opengl32.dll
glide2x.dll

Significado de la salida: Confirma que la aplicación puede intentar múltiples backends de render, incluyendo shims de la era Glide.

Decisión: Si están presentes Glide y D3D, asegúrate de que la ruta seleccionada sea deliberada; fuerza un backend conocido bueno para reducir la variabilidad.

Tarea 12: Medir estabilidad del tiempo de fotograma, no solo FPS (usando MangoHud en Linux)

cr0x@server:~$ cat ~/.config/MangoHud/MangoHud.conf | egrep "fps|frametime|histogram" 
fps
frametime
histogram

Significado de la salida: Has activado métricas que muestran picos. El FPS promedio miente; los picos de tiempo de fotograma dicen la verdad.

Decisión: Si el histograma de frametime tiene colas largas, prioriza las fuentes de stutter: compilación de shaders, paginación, puntos de sincronización o picos de CPU.

Tarea 13: Detectar crecimiento y churn del shader cache (Linux)

cr0x@server:~$ du -sh ~/.cache/mesa_shader_cache ~/.cache/nvidia 2>/dev/null
1.8G	/home/cr0x/.cache/mesa_shader_cache
642M	/home/cr0x/.cache/nvidia

Significado de la salida: Caches grandes pueden indicar muchas variantes; el churn indica reconstrucciones que causan stutter.

Decisión: Si el cache es enorme o se reconstruye frecuentemente, reduce el número de permutaciones de shaders, precompila o arregla los disparadores de invalidación del cache (actualizaciones de driver, cambios de ruta).

Tarea 14: Confirmar que no estás ejecutando accidentalmente a través de una capa de traducción no intencionada

cr0x@server:~$ env | egrep "PROTON|DXVK|VKD3D|WINE" | head
PROTON_LOG=1
DXVK_HUD=0
VKD3D_CONFIG=none

Significado de la salida: El entorno indica si D3D está siendo traducido (p. ej., D3D9→Vulkan) lo que cambia perfiles de rendimiento y bugs.

Decisión: Si estás triageando un problema nativo de D3D pero ejecutas a través de traducción, para. Reproduce en el stack correcto primero.

Guía de diagnóstico rápido: encuentra el cuello de botella sin adivinar

Quieres una secuencia repetible que evite la trampa clásica: “cambié tres cosas y mejoró, por tanto soy un genio.”
No. Tuviste suerte. Haz esto en su lugar.

Primero: determina si es un crash, un hang/reinicio o “solo” rendimiento

  • Crash: el proceso sale; necesitas símbolos, volcados y pasos de repro.
  • Hang/reinicio (TDR): congelación de pantalla, recuperación del driver; enfócate en tareas largas de GPU y compilación de shaders.
  • Rendimiento: enfócate en el tiempo de fotograma, no en FPS; clasifica bound por CPU vs bound por GPU.

Segundo: clasifica CPU-bound vs GPU-bound en 2 minutos

  • Revisa la utilización GPU (Tarea 5) y si hay un núcleo al máximo (Tarea 6/7).
  • Reduce resolución o desactiva post-procesado caro.
  • Si bajar resolución no ayuda, probablemente estás bound por CPU/driver/submit.

Tercero: aislar “stutter” vs “lento”

  • Lento: tiempo de fotograma consistentemente alto, estable.
  • Stutter: mayormente bien, con picos periódicos.

El stutter es frecuentemente almacenamiento, compilación de shaders, paginación o sincronización (locks, fences, vsync). Usa las Tareas 8–9 y 13.

Cuarto: reduce tu matriz de pruebas deliberadamente

  • Elige un driver conocido bueno y uno conocido malo.
  • Reproduce en una máquina/perfil de usuario limpio (los shader caches importan).
  • Fija el backend de render (ruta D3D, wrapper, capa de traducción).

Quinto: solo entonces afina

Si afinas antes de poder reproducir de forma fiable, no estás optimizando. Estás apostando con gráficas.

Chiste #2: Si no puedes reproducir un bug gráfico, no es “heisenbug”—es “aún no tenemos un arnés de pruebas.”

Errores comunes: síntoma → causa raíz → solución

1) “Funciona rápido en mi GPU, los jugadores se quejan de que va lento”

Síntoma: Gran rendimiento en tu máquina dev; GPUs débiles van como caracoles.

Causa raíz: Tu contenido asume fill-rate y ancho de banda; estás bound por GPU en tiers inferiores.

Solución: Añade ajustes escalables que realmente reduzcan el coste por píxel (scaling de resolución, post más barato, reducción de overdraw). Valida usando utilización GPU (Tarea 5).

2) “Pérdida aleatoria de dispositivo / reinicio de driver tras un parche”

Síntoma: Pantalla negra periódica, mensaje de recuperación o terminación de la app.

Causa raíz: Shaders de larga duración, bucles infinitos o buffers de comandos grandes que disparan TDR.

Solución: Divide el trabajo en trozos más pequeños; simplifica o blinda shaders; valida con logs (Tarea 10) y reproduce con capas debug cuando sea posible.

3) “Stutter cada vez que aparece un efecto nuevo”

Síntoma: Suave, luego un pico al ver nuevos materiales/áreas.

Causa raíz: Compilación de shaders en runtime y pérdidas de cache.

Solución: Precompila shaders; precalienta caches; monitorea crecimiento del cache (Tarea 13) y latencia de almacenamiento (Tarea 9).

4) “Corrupción que desaparece al apagar una optimización”

Síntoma: Texturas o modos de blending incorrectos, intermitentes.

Causa raíz: Desincronización de caché/estado con el driver; comportamiento indefinido que depende de estado incidental.

Solución: Haz el estado de pipeline explícito; evita la elisión de estado ingeniosa a menos que puedas probar corrección bajo todas las invalidaciones.

5) “Solo falla en un proveedor”

Síntoma: Funciona en proveedor A, falla en proveedor B.

Causa raíz: Dependes de comportamiento indefinido o de un bug/quirk del driver.

Solución: Usa capas de validación y pruebas de conformidad; si es un bug del proveedor, crea un repro mínimo y despliega un workaround dirigido con gate por versión de driver.

6) “El rendimiento se desploma tras actualizar drivers”

Síntoma: Mismo build, driver nuevo, peor tiempo de fotograma.

Causa raíz: Regresión en el compilador de shaders, comportamiento del cache o scheduling.

Solución: Fija versiones de driver para QA y release; mantén una matriz de compatibilidad; prueba “conocido bueno” versus “último”.

7) “Alt-tab rompe el render o causa crash”

Síntoma: Pérdida de texturas, pantalla negra, crash tras cambios de foco.

Causa raíz: Manejo incorrecto de pérdida de dispositivo; recursos no re-creados o referenciados incorrectamente.

Solución: Implementa flujos robustos de reseteo de dispositivo y tracking explícito de vida de recursos; añade tests automatizados para pérdida de dispositivo y cambios de modo.

Listas de verificación / plan paso a paso

Checklist A: Enviar un renderer a través de diversidad de proveedores (lo que Direct3D obligó a aprender)

  1. Define tu matriz de soporte. Versiones de OS, familias GPU y ramas de driver que pruebas y anuncias.
  2. Fija y archiva. Versiones de toolchain, shaders, símbolos y artefactos de build por release.
  3. Construye una escena de prueba gráfica reproducible. Trayectoria de cámara determinista, orden de carga de assets determinista, semillas fijas.
  4. Mide tiempo de fotograma. Rastrea p50/p95/p99, no solo FPS promedio.
  5. Presupuesta permutaciones de shaders. Si un sistema de materiales puede generar 10.000 variantes, lo hará.
  6. Planifica la pérdida de dispositivo. Trátala como un evento normal, no como apocalipsis.
  7. Gatea workarounds. Checks de versión de driver y vendor IDs; registra claramente cuando un workaround está activo.
  8. Mantén un pipeline de repro mínimo. Cuando un bug de driver golpee, necesitas una reproducción pequeña y compartible rápido.

Checklist B: Depurar una regresión de rendimiento en una semana, no en un trimestre

  1. Reproduce en una máquina/perfil limpio.
  2. Confirma la selección de backend (Tareas 11/14).
  3. Clasifica CPU vs GPU bound (Tareas 5–7).
  4. Revisa fuentes de stutter: memoria/IO/shader cache (Tareas 8–9/13).
  5. Compara versiones de driver conocidas buenas vs malas.
  6. Biseca cambios en contenido y código por separado.
  7. Despliega mitigaciones tras flags; mide el impacto.
  8. Escribe el resultado en términos operativos: qué se rompió, por qué se rompió, cómo prevenir recurrencia.

Checklist C: Si debes soportar una “ruta rápida” propietaria (cómo hacerlo sin odiar la vida)

  1. Requiere tests de paridad: la ruta rápida debe pasar la misma suite de corrección.
  2. Construye un interruptor de muerte: flag de config, override de entorno, fallback seguro.
  3. Instrumenta la selección de backend e info de driver en telemetría.
  4. Limita el radio de explosión: habilita solo para combos hardware/driver conocidos buenos.
  5. Asigna un responsable. “Todos” lo poseen significa que nadie lo arregla.

Preguntas frecuentes (FAQ)

1) ¿Fue Glide técnicamente mejor que Direct3D?

En un sentido estrecho—mapear al hardware Voodoo y entregar rendimiento predecible—a menudo sí. En un sentido de plataforma—portabilidad, longevidad, diversidad de proveedores—no.
“Mejor” depende de si tu objetivo es rendimiento pico en un objetivo o sobrevivencia en todo el mercado.

2) ¿Por qué los desarrolladores apoyaron Glide si era propietaria?

Porque funcionaba y vendía copias. Si la versión que mejor se veía de tu juego corría en la tarjeta más popular, marketing te adoraba y los jugadores lo notaban.
En el corto plazo, fue una elección racional.

3) ¿Por qué ganó Direct3D aunque las primeras versiones fueron dolorosas?

Distribución y ecosistema. Direct3D venía con Windows y mejoró con el tiempo. Los proveedores tuvieron incentivo para optimizar drivers para ella. Las herramientas y la experiencia de desarrollador alcanzaron.
Glide no pudo sobrevivir al hardware vendor al que estaba atada.

4) ¿Dónde encaja OpenGL en esta historia?

OpenGL importó, especialmente para ciertos motores y por la herencia de estaciones de trabajo. Pero el impulso del gaming en Windows, los acuerdos OEM y el paquete DirectX empujaron a D3D al carril por defecto.
La industria también aprendió que “estándar” solo ayuda si los drivers son sólidos y las herramientas accesibles.

5) ¿Cuál es el equivalente moderno de Glide?

Extensiones específicas de proveedor, upscalers propietarios y APIs o características exclusivas de plataforma. Pueden ser excelentes. También conllevan riesgo de plataforma.
Úsalos con checks de capacidad y con un fallback limpio.

6) ¿Es Direct3D inherentemente más estable que las APIs propietarias?

No inherentemente. La estabilidad viene de la inversión del ecosistema, la validación y la disciplina operativa.
Las APIs estándar suelen atraer más esfuerzo de conformidad y pruebas más amplias, lo que suele ayudar con el tiempo.

7) Si estoy depurando stutter, ¿por qué sigues hablando de almacenamiento?

Porque el stutter frecuentemente ocurre cuando “la GPU esperó por otra cosa”. La compilación de shaders, la paginación y el streaming a menudo tocan disco.
Si tus picos de tiempo de fotograma coinciden con IO o reconstrucciones de cache, tu cuello de botella no es la GPU—es el pipeline alrededor de ella.

8) ¿Debería fijar versiones de driver GPU en entornos de producción?

Sí, si te importa la predictibilidad. Fija para configuraciones validadas y prueba “último” por separado para planificar actualizaciones en lugar de que te sorprendan.
Esto es especialmente importante para visualización empresarial, entornos esports y kioscos.

9) ¿Cuál es la mejor forma de evitar el desastre del “state shadowing”?

Trata el estado explícito del pipeline como la fuente de la verdad. Cuando debas cachear, asegúrate de poder invalidar correctamente en cada evento que importe: pérdida de dispositivo, eviction de recursos, cambios de contexto y comportamiento del driver.
Si no puedes modelar la invalidación, no finjas que puedes.

10) ¿Qué debo hacer si el problema solo se reproduce en el driver de un proveedor?

Primero, asume que dependes de comportamiento indefinido. Valida, reduce a un repro mínimo y solo entonces repórtalo como bug del driver.
En paralelo, despliega un workaround gateado por proveedor + versión de driver con logging claro para poder eliminarlo después.

Próximos pasos que no te harán perder la semana

Glide vs Direct3D no fue solo una guerra de APIs; fue un anticipo de cómo ganan las plataformas. La plataforma que reduce el dolor operativo a largo plazo gana, aunque sea torpe al principio.
Glide produjo la mejor versión de un juego en una clase de hardware. Direct3D lo hizo enviable a todo el mercado de PC.

Si estás construyendo o manteniendo hoy una pila de render, toma en serio las lecciones aburridas:

  • Decide tu matriz de soporte y hazla cumplir con drivers fijados y builds reproducibles.
  • Instrumenta el tiempo de fotograma y clasifica cuellos de botella rápidamente usando la guía.
  • Construye un arnés de repro mínimo para bugs de driver—tu yo futuro agradecerá a tu yo presente.
  • Usa rutas rápidas propietarias con cuidado: gateadas, probadas y con un interruptor de muerte.

El argumento de los 90 era “rápido vs compatible”. El argumento moderno es “rápido vs operable”.
Elige operable primero. Luego hazlo rápido.

← Anterior
Velocidad de restauración en Proxmox: ajustar PBS, elegir compresión y por qué las restauraciones son lentas
Siguiente →
Proxmox VFIO “device is in use”: separar dispositivos PCI del host de la manera correcta

Deja un comentario