https://github.com/eazuooz/YamYam_Engine/commit/7ac7ef2842181f6eb9f79e8afb22d3878c06cd32
YamYam Engine 기준으로 작성된 DX12 프레임 루프와 GPU 동기화 아키텍처 문서. Editor 빌드(
#define WITH_EDITOR)와 Game 빌드의 구조적 차이, 그리고 Fence가 왜 필요한지를 처음부터 순서대로 설명한다.
DirectX 12를 처음 접할 때 가장 큰 충격은 이것이다.
mCommandList->DrawIndexedInstanced(...); // 이 줄은 GPU가 즉시 실행하지 않는다
이 코드는 GPU에게 "지금 그려라"를 명령하는 게 아니다. CommandList라는 녹화 테이프에
그 명령을 기록하는 것이다. GPU가 실제로 그리기 시작하는 시점은 나중에 ExecuteCommandLists()를
호출할 때다.
CPU 시점: GPU 시점:
DrawIndexedInstanced() 호출 ← 아직 아무 것도 안 함
ExecuteCommandLists() 호출 ← 이제 GPU가 실행 시작
CPU는 계속 다음 작업 진행 ← GPU는 비동기로 처리 중
여기서 문제가 생긴다. CPU는 빠르게 다음 프레임을 준비하려 하는데, GPU는 아직 이전 프레임을 처리하고 있다. 이 타이밍을 맞추는 장치가 바로 Fence다.
Fence는 CPU와 GPU 사이에 놓인 단방향 신호 깃발이다.
DirectX 12에서 **Fence(펜스)**는 CPU와 GPU 사이의 '교통 정리'를 담당하는 동기화 객체입니다. 작업을 기다려야 하는 핵심 이유는 CPU와 GPU가 서로 다른 속도로 독립적으로 작동하기 때문입니다.

CPU GPU
| |
| mCommandQueue->Signal(fence, N)|
|-------------------------------->| "N번 깃발 꽂아줘"
| |
| (CPU는 계속 다른 일 함) | ... GPU 작업 중 ...
| |
| | [GPU가 N까지 처리 완료]
| | fence->GetCompletedValue() == N
| |
| (CPU가 N 이상인지 확인 가능) |
Signal(fence, N)은 GPU에게 "네가 여기까지 실행을 완료하면, fence의 값을 N으로 만들어줘"
라고 예약하는 것이다. CPU는 나중에 fence->GetCompletedValue()로 GPU가 어디까지 왔는지
언제든지 폴링할 수 있다.