TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 31 READS

FPGA로 되살린 1990년대 부두 그래픽과 게이밍 PC

FPGA로 되살린 1990년대 부두 그래픽과 게이밍 PC
SOURCE IMAGE · HACKER NEWS

1990년대 후반, PC 게임을 즐기던 사람들에게 3dfx의 부두(Voodoo)는 하나의 세대 교체를 상징하는 하드웨어였다. 매끄러운 텍스처, 안개 효과, 그리고 무엇보다 부드러운 속도감은 소프트웨어 렌더링에 머물던 3D 게임의 인상을 단번에 바꿔놓았다. nand2mario라는 개발자가 최근 공개한 zSST 프로젝트는 바로 그 부두 그래픽스, 정확히는 SST-1 칩셋을 SystemVerilog로 다시 구현한 결과물이다. 그가 이전부터 만들어온 z486 CPU와 주변 PC 하드웨어를 결합하면 자일링스 KV260 보드의 프로그래머블 로직 위에서 돌아가는 도스 PC, 이른바 z486 XL이 완성된다. 실제로 툼레이더가 원래의 3dfx 렌더러로 구동되는 것이 확인됐다.

무엇을 구현했나

zSST는 부두의 핵심 기능 대부분을 담았다. 준비된 삼각형(prepared triangle) 처리, 텍스처 필터링과 밉매핑, 깊이·알파 테스트, 안개, 블렌딩, 디더링, 프레임버퍼 접근, 버퍼 스왑을 지원하며 고정소수점과 부동소수점 셋업 인터페이스를 모두 받아들인다. CPU와 렌더러는 KV260에서 100MHz로 동작한다. 이 보드는 로직, DSP 블록, 온칩 메모리, DDR 대역폭이 통합 설계를 감당할 만큼 넉넉하지만, 앞서 쓰이던 DE10-Nano에는 이 그래픽 추가 기능을 넣을 여유가 없었다고 한다. 다만 하드웨어 게임 테스트는 아직 툼레이더에 집중돼 있고, 폭넓은 호환성과 이후 세대 부두 지원은 향후 과제로 남아 있다.

이런 복원이 가능했던 배경에는 자료의 존재가 있다. 3dfx는 엔비디아가 2000년 12월 핵심 그래픽 자산을 인수하기 전인 1999년에 글라이드(Glide) 소스를 공개했고, 남아 있는 글라이드 소스와 SST-1 사양서는 소프트웨어가 어떻게 삼각형을 준비하고 픽셀 파이프라인을 설정하며 텍스처와 프레임버퍼를 관리하는지를 설명한다. 다만 사양서는 회로도가 아니라 동작 명세에 가까워, 레지스터에 값을 쓰면 무엇이 일어나야 하는지는 말해주되 구현 선택은 열어둔다. 그래서 저자는 86Box, MAME의 부두 작업, 그리고 특히 글라이드 트레이스와 참조 스크린샷을 제공한 SpinalVoodoo 같은 보존 프로젝트를 참고로 삼았다.

고정 파이프라인의 이점과 산술 경로

부두는 삼각형을 픽셀로 바꾸는 일에 집중하고 3D 계산 상당 부분은 호스트 CPU에 맡긴다. 명령 인터페이스는 놀랍도록 간결해 다섯 개의 주요 명령 레지스터가 가속기를 움직인다. CPU가 지오메트리 변환, 정점 조명, 클리핑, 화면 투영을 마치면 글라이드가 화면 공간 삼각형과 파라미터 기울기를 준비해 삼각형 명령을 쓴다. 이후 GeForce 256과 달리 SST-1에는 하드웨어 변환·조명 엔진이 없다는 점이 이 세대의 위치를 잘 보여준다. 래스터라이저가 삼각형 내부 픽셀을 찾아 색·깊이·텍스처 좌표를 보간하고, 텍스처 유닛이 텍셀을 가져와 필터링하며, 프레임버퍼 유닛이 색을 합성하고 가시성 테스트와 안개를 적용한 뒤 기록한다.

원본 카드는 이 일을 FBI(프레임버퍼 인터페이스)와 TREX라 불리는 텍스처 매핑 유닛(TMU) 두 개의 ASIC으로 나눈다. 50MHz 그래픽 클록에서 광고된 최고 성능은 클록당 텍스처가 입혀지고 깊이 테스트를 거친 픽셀 하나, 즉 초당 5천만 픽셀이다. 여기서 클록당 한 픽셀이란 한 픽셀이 한 클록에 끝난다는 뜻이 아니라, 서로 다른 단계가 서로 다른 픽셀을 동시에 처리해 파이프라인이 가득 차면 매 클록 한 픽셀을 받아 완성한다는 의미다. 소프트웨어 렌더러가 픽셀마다 수많은 명령을 실행하는 것과 달리, 전용 하드웨어는 이 작업을 픽셀 흐름 위에 겹쳐 처리한다. 흥미롭게도 SST-1은 소프트웨어가 IEEE 단정밀도 값을 제출할 수 있지만 렌더링 기계 자체는 대부분 고정소수점으로 움직이는 과도기에 있다. 예컨대 12.4 형식에서 화면 좌표 10.5는 정수 168로 저장된다.

진짜 어려움은 메모리에 있었다

저자는 zSST의 픽셀 파이프라인 구현 자체는 z486의 CPU 파이프라인에 비하면 비교적 수월했다고 말한다. 정작 어려운 것은 그 파이프라인을 굶기지 않고 계속 먹이는 일이었다. 바이리니어 샘플 하나에는 서로 다른 주소의 텍셀 네 개가 필요하고, 깊이 테스트와 블렌딩을 거치는 픽셀은 기존 깊이와 색을 읽은 뒤 새 값을 써야 한다. 이런 접근을 하나씩 처리하면 처리량이 순식간에 무너진다. 원본 부두는 FBI와 TMU에 각각 전용 64비트 메모리 경로를 두고, 텍스처 쪽은 4방향 인터리빙으로 짝·홀 열과 행 조합마다 뱅크를 배정해 2×2 창 어디서든 네 텍셀을 충돌 없이 병렬로 읽어냈다. 50MHz에서 각 경로는 이론상 400MB/s, 합쳐 800MB/s지만 서로 대역폭을 빌려 쓸 수 없는 전용 구조였다.

문제는 이 설계를 KV260에 그대로 옮길 수 없다는 점이다. 이 보드는 대역폭은 훨씬 크지만 렌더링 유닛에 붙은 전용 EDO 메모리가 없고, FPGA는 Zynq 프로세싱 시스템의 AXI 포트를 통해 공유 DDR에 접근한다. 여기서는 리눅스, FPGA로 구현된 PC, 디스플레이 스캔아웃이 같은 메모리를 두고 경쟁한다. 저자의 측정에 따르면 100MHz의 128비트 포트는 이론상 1.6GB/s지만, 요청 하나만 대기시킬 때 4KiB 읽기는 1,370MiB/s에 이르는 반면 64바이트 읽기는 189MiB/s에 그친다. 첫 데이터가 도착하기까지 약 280ns, 100MHz 기준 약 28클록이 걸리고 때로는 훨씬 더 길다.

그래서 zSST는 대역폭보다 대기 시간을 숨기는 데 집중한다. 인접한 화면 픽셀이 텍스처의 겹치는 부분을 자주 참조한다는 성질을 활용해 8KiB, 64바이트 라인 크기의 텍스처 캐시를 둬 최근에 가져온 텍셀을 재사용한다. 캐시 미스는 여전히 여러 클록이 걸리지만, 독립적인 텍스처 샘플은 그 미스를 기다릴 필요가 없다. zSST는 최대 여덟 개의 캐시 라인 페치를 동시에 진행하고, 데이터가 빠진 샘플은 리플레이 큐에 넣어 두었다가 도착하면 재시도하며, 프리페칭으로 미래의 읽기를 앞당긴다. 결국 이 프로젝트가 보여주는 교훈은 NES·SNES 시대 설계와 다르지 않다. 성능은 산술 회로가 아니라, 각 값이 언제 어디서 필요한지를 중심으로 메모리를 설계하는 데서 나온다는 것이다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://nand2mario.github.io/posts/2026/zsst-voodoo/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...