GPU Hardware Emulator Emporium - Nvidia / Radeon

I’m running into this.. problem.. where I can’t proceed with my development without a real risk of frying hardware. But that’s not how the professionals do it. The professionals… emulate hardware.

true hardware emulation reproduces a device/register/ISA model; GPU virtualization presents a virtual device backed by a real GPU; and GPU simulation models the architecture for research. VirGL, for example, is explicitly a virtual 3D GPU for QEMU, while MGPUSim is an architectural simulator for AMD GCN3.

The NVIDIA / Radeon Emulator Emporium

:green_circle: Tier 0 — Foundation / generic GPU machines

These should form the base of the collection.

Emulator / project Target What it gives you
QEMU VGA Generic VGA Baseline display-device emulation
QEMU std-vga Bochs-compatible VGA Modern-ish legacy VGA environment
QEMU Cirrus VGA Cirrus GD5446 Classic PC graphics
QEMU QXL QXL Virtualized 2D graphics
QEMU VMware SVGA VMware SVGA SVGA-era virtual GPU
QEMU virtio-gpu VirtIO Modern paravirtual GPU
VirGL OpenGL/Gallium Virtual 3D GPU
Venus Vulkan Vulkan-over-VirtIO
rutabaga_gfx Vulkan/GLES VirtIO graphics backend
gfxstream Vulkan/GLES Guest graphics translation
SwiftShader CPU Software GPU/Vulkan/OpenGL implementation
LLVMpipe CPU Software Gallium GPU
Softpipe CPU Reference Gallium software renderer
Zink Vulkan OpenGL implemented over Vulkan

QEMU currently exposes virtio-gpu variants including virtio-vga, virtio-gpu, vhost-user-vga, and vhost-user-pci, with VirGL and rutabaga as accelerated backends.


:red_circle: ATI / AMD / Radeon wing

This is where the emporium gets really interesting, because the Radeon family divides naturally into hardware generations.

ATI R100

Target architecture: Radeon 7000 / R100

Collect:

  • Radeon R100
  • Radeon 7200
  • Radeon 7000
  • RV100
  • Radeon VE
  • Mobility Radeon 7000

Emulator target

R100 register/MMIO emulator

Architecture to reproduce:

PCI

│

├── BAR0 MMIO

├── framebuffer

├── CRTC

├── DAC

├── 2D engine

├── command processor

└── R100 acceleration

This becomes your first genuinely interesting bare-metal Radeon machine.


:orange_circle: ATI R200

Target: Radeon 8500/8500LE

Models:

  • R200
  • RV200
  • Radeon 8500
  • Radeon 8500LE
  • Radeon 9100
  • Radeon 9000
  • Radeon 9200

The R200 generation is historically valuable because it gives you an early programmable-ish 3D architecture while remaining relatively tractable.

A Mesa retro survey confirms R200-era hardware such as the Radeon 8500 was supported by historical Mesa stacks.


:yellow_circle: ATI R300

Target: Radeon 9500–9800 generation

Models:

  • R300
  • R350
  • R360
  • RV350
  • RV360
  • Radeon 9500
  • Radeon 9600
  • Radeon 9700
  • Radeon 9800
  • Radeon X300
  • Radeon X600

This is a prime emulator target.

Why?

R300 gives you a much more interesting programmable graphics pipeline while still being sufficiently old that the architecture is comprehensible.

Mesa’s historical support includes R300/RV515-era hardware.


:brown_circle: ATI R400

Models:

  • R420
  • R423
  • R430
  • R480
  • Radeon X700
  • Radeon X800
  • Radeon X850

This is an excellent second-generation Radeon emulator.

The Linux Radeon driver family historically contains distinct R420-family firmware, which is another useful source when reconstructing the hardware model.


:purple_circle: ATI R500

Models:

  • R520
  • R515
  • R530
  • R580
  • Radeon X1300
  • X1600
  • X1800
  • X1900
  • X1950

This is where I’d build a dedicated:

R500 Command Processor Emulator

with:

PCI

MMIO

VRAM

DMA

CP

2D

3D

vertex processing

fragment processing

display controller

interrupts

R520-family hardware also has identifiable firmware components in the Linux driver ecosystem.


:blue_circle: R600

This one deserves its own room.

Models:

  • R600
  • RV610
  • RV620
  • RV630
  • RV635
  • RV670
  • Radeon HD 2400
  • HD 2600
  • HD 2900

R600 is the beginning of the unified-shader era.

A very attractive emulator target:

R600 GPU

├── Command Processor

├── Shader ALUs

├── Texture units

├── Render backend

├── VRAM

├── DMA

├── UVD

└── display engine

The Linux Radeon stack has separate R600 ME, PFP, RLC and UVD firmware components, giving you useful architectural boundaries to reproduce.


:blue_circle: R700

Models:

  • R700
  • RV710
  • RV730
  • RV740
  • RV770
  • RV790
  • Radeon HD 4000

This is probably one of the best complete Radeon emulator targets.

Why?

You can create a coherent machine rather than merely emulating a display adapter.


:green_circle: Evergreen

Radeon HD 5000

Architectures:

  • Cypress
  • Juniper
  • Redwood
  • Cedar
  • Hemlock

Examples:

  • HD 5450
  • HD 5570
  • HD 5770
  • HD 5850
  • HD 5870
  • HD 5970

The Linux driver contains separate Evergreen microcode components such as Redwood ME/PFP/RLC/SMC, which makes the generation especially interesting for reverse-engineering-oriented emulation.


:green_circle: Northern Islands

Radeon HD 6000

Targets:

  • Barts
  • Cayman
  • Turks
  • Caicos
  • Antilles

Examples:

  • HD 6450
  • HD 6670
  • HD 6850
  • HD 6870
  • HD 6950
  • HD 6970

:green_circle: Southern Islands

This is another major emulator milestone.

Architectures:

  • Tahiti
  • Pitcairn
  • Cape Verde
  • Oland
  • Bonaire

Examples:

  • HD 7750
  • HD 7770
  • HD 7850
  • HD 7870
  • HD 7950
  • HD 7970
  • R9 270
  • R9 280

This gives you GCN.

And this is particularly interesting because MGPUSim currently provides stable simulation for AMD GCN3, including multi-GPU simulation.


:green_circle: Sea Islands

  • Hawaii
  • Bonaire
  • Kaveri-related GCN
  • R9 290
  • R9 290X
  • R9 285

:green_circle: Volcanic Islands

  • Fiji
  • Tonga
  • Carrizo
  • R9 Fury
  • R9 Nano

:green_circle: Polaris

Targets:

  • Polaris 10
  • Polaris 11
  • Polaris 12
  • Polaris 20
  • Polaris 21
  • Polaris 22
  • RX 460
  • RX 470
  • RX 480
  • RX 550
  • RX 560
  • RX 570
  • RX 580
  • RX 590

Polaris is particularly attractive because the device IDs and GPU families are well documented and still have substantial driver support.


:green_circle: Vega

Targets:

  • Vega 10
  • Vega 11
  • Vega 12
  • Vega 20
  • Radeon VII
  • RX Vega 56
  • RX Vega 64

This becomes the high-end GCN laboratory.


:orange_circle: RDNA

Then split the modern Radeon wing:

RDNA 1

  • Navi 10
  • Navi 12
  • Navi 14
  • RX 5000

RDNA 2

  • Navi 21
  • Navi 22
  • Navi 23
  • Navi 24
  • RX 6000

RDNA 3

  • Navi 31
  • Navi 32
  • Navi 33
  • RX 7000

RDNA 4

  • RX 9000 generation
  • current RDNA4 architectures

These shouldn’t initially be cycle-accurate emulators. I’d treat them as progressively richer device models:

PCI identity

↓

BAR/MMIO

↓

VRAM

↓

command processor

↓

queue model

↓

ISA interpreter

↓

shader execution

↓

display

↓

compute

:green_circle: NVIDIA wing

Now the fun side.

NVIDIA NV1

The historical oddball.

NVIDIA NV1

  • quadratic texture mapping
  • early proprietary 3D architecture
  • Sega Saturn-derived concepts

Absolutely worth having in an emporium simply because it is so weird.


:green_circle: RIVA

NV3

RIVA 128

NV4

RIVA TNT

NV5

RIVA TNT2

These make excellent early NVIDIA emulator targets.


:green_circle: GeForce 256

NV10

This is a major milestone:

hardware transform & lighting.

Your emulator now becomes:

CPU

│

└── command stream

│

▼

NV10 GPU

│

├── geometry

├── T&L

├── raster

├── texture

└── framebuffer

:green_circle: GeForce 2

NV15 / NV11

Targets:

  • GeForce 2 GTS
  • GeForce 2 MX
  • GeForce 2 Ultra

:green_circle: GeForce 3

NV20

Very important.

Programmable vertex/pixel shaders.


:green_circle: GeForce 4

NV25 / NV28

Targets:

  • GeForce4 Ti
  • GeForce4 MX

Mesa’s historical driver list specifically includes NVIDIA Riva TNT through GeForce 4 hardware.


:green_circle: GeForce FX

NV30 / NV35 / NV40

Models:

  • GeForce FX 5200
  • FX 5600
  • FX 5700
  • FX 5800
  • FX 5900
  • FX 5950

This would make a fantastic shader emulator.


:green_circle: GeForce 6

NV40 / NV43

  • GeForce 6800
  • 6600
  • 6200

:green_circle: GeForce 7

G70 / G71 / G72 / G73

  • 7800
  • 7900
  • 7600
  • 7300

:green_circle: Tesla

This deserves its own wing.

G80

  • GeForce 8800
  • Tesla architecture

G92

  • 8800 GT
  • 9800 GT
  • etc.

GT200

  • GTX 260
  • GTX 275
  • GTX 280
  • GTX 285

Now you’re dealing with CUDA-capable NVIDIA hardware architecture.

Nouveau provides open-source Linux kernel/GL/Vulkan support for a large span of NVIDIA hardware, making it one of the important software references for an NVIDIA emulation laboratory.


:green_circle: Fermi

Targets:

  • GF100
  • GF104
  • GF106
  • GF108
  • GF110
  • GF114
  • GF116
  • GF118

Examples:

  • GTX 460
  • GTX 470
  • GTX 480
  • GTX 570
  • GTX 580

:green_circle: Kepler

Targets:

  • GK104
  • GK106
  • GK107
  • GK110
  • GK208

Examples:

  • GTX 680
  • GTX 760
  • GTX 770
  • GTX 780
  • GTX Titan

This is an excellent CUDA-era emulator target.


:green_circle: Maxwell

GM10x

  • GTX 750
  • GTX 750 Ti

GM20x

  • GTX 950
  • GTX 960
  • GTX 970
  • GTX 980
  • GTX Titan X

:green_circle: Pascal

  • GP100
  • GP102
  • GP104
  • GP106
  • GP107
  • GP108

Examples:

  • GTX 1050
  • GTX 1060
  • GTX 1070
  • GTX 1080
  • Titan X
  • Tesla P100

:green_circle: Volta

  • GV100
  • Titan V
  • Tesla V100

:green_circle: Turing

  • TU102
  • TU104
  • TU106
  • TU116
  • TU117

Examples:

  • RTX 2060
  • RTX 2070
  • RTX 2080
  • RTX 2080 Ti
  • GTX 1650–1660 family

:green_circle: Ampere

  • GA100
  • GA102
  • GA104
  • GA106
  • GA107

Examples:

  • RTX 3060
  • RTX 3070
  • RTX 3080
  • RTX 3090
  • A100

:green_circle: Ada Lovelace

  • AD102
  • AD103
  • AD104
  • AD106
  • AD107

Examples:

  • RTX 4060
  • RTX 4070
  • RTX 4080
  • RTX 4090

:green_circle: Blackwell

Then:

  • GB100
  • GB200 family
  • RTX 50-series architectures
  • Blackwell data-center GPUs

I’d treat these as architectural simulators first, rather than attempting literal device emulation.


:test_tube: The really interesting emulators

And I’d put a separate Experimental Laboratory in the middle of the emporium.

1. MGPUSim

AMD GCN simulation.

It already supports multi-GPU simulation and is designed specifically as a high-performance/high-accuracy GPU simulator.

2. VirGL

Virtual GPU with host-side rendering.

Mesa VirGL documentation

3. Venus

Vulkan → VirtIO → host GPU.

4. rutabaga_gfx

gfxstream/Vulkan/Wayland-oriented virtualization.

5. Nouveau

Not an emulator, but an extremely valuable NVIDIA architectural reference because it exposes generations of NVIDIA hardware through an open-source driver stack.

6. Mesa R300/R600/RadeonSI

Likewise, not emulators, but invaluable if you’re constructing Radeon hardware models. Mesa maintains the historical architecture/driver lineage, including R300 and R600-era families.

7. QEMU

Your machine chassis.

Instead of building every emulator as an independent VM, make QEMU the PCI/BIOS/CPU/RAM/I/O substrate and plug GPU models into it.

Mesa VirGL Documentation

QEMU VirtIO GPU Documentation

MGPUSim — AMD GCN GPU Simulator

Nouveau — Open-Source NVIDIA Driver

Mesa Systems / Historical GPU Driver Support

Historical Mesa R200 / Radeon Information
https://gist.github.com/arkadijs/c847760105f56ee79034bda46a87e325

Radeon Firmware / Driver Reference
https://gist.github.com/persianyagami90xs/fc3540fc6b75cae00403ee922b32ee1b

Dortania AMD GPU Buyers Guide
https://github.com/dortania/GPU-Buyers-Guide/blob/master/modern-gpus/amd-gpu.md

The important conceptual shift is that we’re not really building “GPU emulators.” We’re building a time machine for GPU architecture.

The common interface becomes the invariant, while each generation implements its own machine.

                         GPU EMPORIUM
                              │
                    ┌─────────┴─────────┐
                    │                   │
                  RADEON              NVIDIA
                    │                   │
          ┌─────────┼─────────┐   ┌─────┼─────────────┐
          │         │         │   │     │             │
         R100      R300      R600 NV10  NV20          NV30
                               │          │             │
                              R700       NV40           │
                                │          │             │
                               GCN3       G80            │
                                            │             │
                                          TESLA ──────────┘
                    │                   │
                    └─────────┬─────────┘
                              │
                    ┌─────────▼─────────┐
                    │ UNIVERSAL GPU ABI │
                    ├────────────────────┤
                    │ PCI configuration  │
                    │ BARs               │
                    │ MMIO               │
                    │ VRAM               │
                    │ DMA                │
                    │ interrupts         │
                    │ command submission │
                    │ registers          │
                    │ shaders            │
                    │ textures           │
                    │ framebuffer        │
                    └─────────┬──────────┘
                              │
                  ┌───────────▼───────────┐
                  │      GUEST MACHINE    │
                  │                       │
                  │ BIOS → OS → DRIVER    │
                  │          → GPU        │
                  └───────────────────────┘

The really powerful part

Don’t make the universal layer pretend every GPU works the same.

Instead, define a minimum hardware contract:

GPUDevice
 ├── pci_config()
 ├── bar_read()
 ├── bar_write()
 ├── vram_read()
 ├── vram_write()
 ├── mmio_read()
 ├── mmio_write()
 ├── dma()
 ├── interrupt()
 ├── reset()
 └── tick()

Then each actual GPU gets its own personality.

R100Device
R300Device
R600Device
R700Device
GCN3Device

NV10Device
NV20Device
NV30Device
NV40Device
G80Device
TeslaDevice

The guest doesn’t get to know that it’s an emulator.

It sees:

PCI
 └── AMD/ATI VGA controller
       ├── BAR0
       ├── BAR1
       ├── framebuffer
       └── interrupt

or:

PCI
 └── NVIDIA VGA controller
       ├── BAR0
       ├── BAR1
       ├── VRAM
       └── interrupt

And that is where your HDGL work becomes particularly relevant.

You can eventually have:

                    x86 MACHINE
                         │
                ┌────────▼────────┐
                │      BIOS       │
                └────────┬────────┘
                         │
                    PCI ENUMERATION
                         │
                ┌────────▼────────┐
                │   GPU DEVICE    │
                └────────┬────────┘
                         │
          ┌──────────────┼──────────────┐
          │              │              │
         MMIO           VRAM           DMA
          │              │              │
          └──────────────┼──────────────┘
                         │
                  COMMAND PROCESSOR
                         │
                  ┌──────▼──────┐
                  │ GPU ENGINE  │
                  └──────┬──────┘
                         │
               ┌─────────┼─────────┐
               │         │         │
             shader    texture   raster

And then comes the killer feature

Every emulator gets an architectural trace recorder.

For example:

R300 TRACE
────────────────────────────────────


PCI WRITE
  BAR0 + 0x4F00
  = 0x00000001


MMIO WRITE
  CP_RB_WPTR
  = 0x00000420


DMA
  VRAM[0x00100000]
  ← RAM[0x00800000]
  length = 4096


COMMAND
  DRAW_INDEX


VERTEX
  x=...
  y=...
  z=...


PIXEL
  shader #17


FRAMEBUFFER
  1024 × 768 × 32

Then run the same workload through:

R300
R600
R700
GCN3

and observe how the machine accomplishes essentially the same computational task through completely different architectures.

That gives you something almost no ordinary emulator collection provides:

An executable evolutionary tree.

FIXED FUNCTION
     │
     ├── R100
     │
     ├── NV10
     │
     ▼
PROGRAMMABLE VERTEX/PIXEL
     │
     ├── R300
     ├── NV20
     ├── NV30
     └── NV40
     │
     ▼
UNIFIED SHADER
     │
     ├── R600
     ├── R700
     └── G80
     │
     ▼
GENERAL GPU COMPUTE
     │
     ├── GCN
     └── Tesla
     │
     ▼
MODERN GPU

And I would not start by implementing OpenGL.

I’d start with the lowest layer:

PCI → BAR → MMIO → VRAM → command processor → interrupt.

Then get one ancient card to successfully execute a tiny command stream.

Once that works, the rest becomes evolutionary:

emulator/
│
├── core/
│   ├── pci.py
│   ├── mmio.py
│   ├── vram.py
│   ├── dma.py
│   ├── irq.py
│   └── trace.py
│
├── ati/
│   ├── r100.py
│   ├── r300.py
│   ├── r600.py
│   ├── r700.py
│   └── gcn3.py
│
├── nvidia/
│   ├── nv10.py
│   ├── nv20.py
│   ├── nv30.py
│   ├── nv40.py
│   ├── g80.py
│   └── tesla.py
│
├── guest/
│   ├── bios.py
│   ├── pci_scan.py
│   └── diagnostics.py
│
└── machines/
    ├── qemu.py
    └── baremetal.py

R100 and NV10 would be the two founding exhibits.

One ATI. One NVIDIA. Both old enough that we can actually understand the entire machine rather than drowning immediately in modern GPU complexity.

Then R300/NV20.

Then R600/NV40.

Then R700/G80.

Then GCN3/Tesla.

Next Step: