안녕하세요. 알콜코더 민군입니다. ^^

이번에 올리는 아티클은 일본의 게임 기술 분석가(?)로 유명한 '니시카와 젠지'씨의 저서 '게임 개발자가 되기 위한 3D 그래픽스 기술' 이라는 책에 나온 부분을 발췌, 번역해 보았습니다.

 

DX11에서 변경된 부분에 대해서 쉽고 간결하게 설명하고 있어서 공부하시는 분들에게 큰 도움이 될 것 같은 내용이라서 직접 번역해서 발췌 하였습니다.

 

DX11 이전의 DX10까지의 역사에 대해서는 알로샤님의 블로그에 매우 잘 번역이 되어 있습니다. 이전의 내용은 그 쪽을 참조하여 주시면 이해하는데 큰 도움이 될겁니다.

 

그리고, 그 후에 마이크로소프트는 Window7의 릴리즈와 동시에 DirectX 11을 릴리즈한다.

DirectX 11은 DirectX 9 대응 GPU, DirectX 10.x 대응 GPU 양쪽 모두를지원한다. 다만, 사용 가능한 API나 하드웨어 가속되는 기능은 각 베이스 구조에 의존한다. 즉, DirectX11의 풀구조를 실제로 구현한 것은 DirectX11 지원 GPU이지만, 모든 구조/기능이 아닌 DirectX 9/10.x 지원 GPU에서도 DirectX 11은 이용 가능하다…즉 하위 호환성을 보증하는 것이다. DirectX 10이 DirectX 9 지원 GPU를 지원하지 않는것과는 조금 상황이 다르다는 것이 재미있다.

DirectX11에서의 프로그래머블 셰이더는 Shader Model 5.0(SM 5.0)로의 버전업이 이루어져서, 새로운 4개의 셰이더 스테이지가 추가 되었다. 4개 중에서 3개는 프로그래머블 셰이더이고, 1개가 고정기능 셰이더가 추가 되었다. 새로운 프로그래머블 셰이더는 [헐 셰이더](Hull Shader)[도메인 셰이더](Domain Shader), [계산 셰이더](Compute Shader)이고, 고정기능 셰이더는 [테셸레이터](Tessellator)이다. 각각의 기능에 관해서는 Chapter 2와 Chapter 6에서 설명한다.

(역주* 물론 위 챕터들은 번역하지 않았습니다.. -_-;)

 

이것으로 DirectX 11의 그래픽스 파이프라인에 주어진 셰이더 스테이지는 정점 셰이더->헐 셰이더->테셸레이터->도메인 셰이더->지오메트리 셰이더->픽셀 셰이더->계산 셰이더라고하는 흐름이 되었다. 현행 게임기인 XBOX360과 PS3에 정점 셰이더와 픽셀 셰이더밖에 없다는 것을 생각해보면, 상당히 복잡한 진화를 한것이 되었다.

 

 

SM5.0은 새로운 셰이더가 추가 되었을 뿐만 아니라, 프로그래머빌리티가 향상된 것도 주목할만한 부분이다.

우선 첫번째로, 셰이더 프로그램에 서브 루틴의 사용이 가능하게 되어서, 동적링크(Dynamic Shader Linkage)가 지원된다.

DirectX 10까지는 똑 같은 기능의 셰이더라 할지라도 사용하는 변수셋트(예를 들어 광원의 종류와 개수)가 다를 경우등에서는 별도의 셰이더로 만들지 않으면 안되었다. 이 때문에 거의 기능이 똑같은데도 셰이더의 수가 알게 모르게 증가하게 되어, 셰이더의 관리가 어려워지는 패해가 발생하였다. DirectX 11에서는 셰이더의 기능 블록을 모듈화하는 것이 가능해져서, 각각을 흔히 C언어에서 이야기하는 함수포인터식으로 호출하는 것이 가능해졌기 때문에 효율 좋은 다기능 셰이더를 구성할 수 있게 되었다.

또한 각종 버퍼, 텍스쳐, 정수버퍼, 텍스쳐의 샘플러등의 셰이더의 입력 리소스에 대해서 인덱스 참조가 가능해졌다. 단지 지정 인덱스값은 정수로 한정되었다.

64비트 배정도부동소수점에 관해서는, 현행의 DirectX 10.x 지원 GPU에서도 DirectX와는 별개로 각 제조사 독자의 GPGPU모드에 한해서는 이미 지원되고 있었지만, DirectX 11에서는 Direct3D 그래픽스의 구조로 정식 지원이 된다. 다만 지원은 필수가 아니라, [옵션 지원]이라는 위치이다. 그래서 노트북용 GPU, 메인스트림 이하의 통합 칩셋GPU, 혹은 일부의 제조사의 GPU에서는 이것을 지원하지 않을 가능성이 있다.

부동소수점관련에서는, 이외에 32비트 부동소수점(FP32)와 16비트 부동소수점(FP16)의 상호 형 변환이 하드웨어 레벨에서 지원된다.

DirectX 10 때에 충실화가 이루어졌던 논리계산명령도 더욱 확장되었다.

새로 추가된 Gather()명령도 재미있다. 이것은 1개의 텍스쳐 명령으로 동시에 4곳의 텍셀의 값을 읽어 낼 수 있는 명령이다. 이것은 이전에 ATI RADEON X1900계열에서 지원되고 있던 [Fetch4]기능을 일반화시켜서 DirectX 11의 표준구조로 집어넣은 것이다. RADEON X1900의 Fetch4는 1개의 텍스쳐에 대해서 4 텍셀을 읽어낼 수 있는 기능으로, NVIDIA의 뎁스버퍼(Depth Buffer)의 특수참조기능 [NVIDIA SHADOW] 기능의 대항 기능이라고 하는 역할이었지만, SM 5.0의 Gather() 명령은 임의의 개수의 텍스쳐의 4군데 위치로부터 임의의 요소(a/R/G/B)를 읽어 내는 것이 가능하게 되었다. 이것은 구체적으로는 앞에 이야기한것처럼 뎁스쉐도우계열의 그림자생성의 고효율 실행은 물론이고, 최근 유행하고 있는 스크린 스페이스 엠비언트 오클루젼(SSAO:Screen Space Ambient Occlusion)과 같은 심도갚을 이용한 복잡한 포스트 프로세싱의 고효율화 실행에 도움이 된다.

DirectX 11에서는 뒤에 설명하는 DirectX 계산 셰이더의 지원에 싱크로하는 형태로, GPGPU적인 잠재 가능성이 픽셀 셰이더에도 추가되었다. 이것이 DirectX 11의 픽셀셰이더에 신기능으로 추가된 [Unordered Access View](UAV)라고 하는 신개념이다. Unordered Access 라는 것은 랜덤 액세스라는 뜻이다. 즉 픽셀 셰이더로부터 비디오 메모리로의 랜덤 액세스가 가능해진 것이다. 지금까지 픽셀 셰이더는 별수 없이 그 픽셀 좌표에 대응하는 비디오 메모리로의 쓰기(출력)밖에 되지 않았지만, 이 제약이 없어지게 된것이다.

UAV는 원래 DirectX 계산 셰이더를 위해서 확장된 개념이기 때문에, 당연히 DirectX 계산 셰이더에서도 이용 가능하다. 이 UAV로 인해서 값을 확산하는 것 같은 스캐터(산란) 형태의 필터 처리, A-Buffer같은 멀티 레이어형의 특수한 프레임퍼버에서 렌더링 순서에 의존하지 않고 반투명렌더링(OIT:Order Independent Transparency)등을 구현 가능하게 되었다.

A-Buffer의 개념도.
"A"에는 anti-aliased、area-averaged(영역평균화)、accumulation(연산)이라는 복수의 의미가 들어 있다.

 

이 UAV 도입에 의해서, DirectX 11/SM 5.0에서는 멀티렌러타겟(MRT:Multi Render Target)의 개수는 DirectX 10 때의 10개 그대로지만, 픽셀 셰이더에서는 8MRT와는 별대로 UAV 1개가 이용 가능하게 되었다. 또한 DirectX 계산 셰이더는 8UAV까지 이용 가능하다.

픽셀 셰이더와 DirectX 계산 셰이더에서 랜덤 메모리 액세스가 가능하게 된 관계로, 귀찮아 진 것이 복수 스레드로부터의 동일한 메모리 어드레스 엑세스의 관리다. 실행 타이밍에 의해 메모리의 내용이 변경되어버릴 가능성이 생기기 때문에, 이것은 멀티 스레드 프로그램에서 일어나는 디버그 곤란한 현상이 생길 수 밖에 없다. 그래서 DirectX 11에 있어서 픽셀 셰이더와 DirectX 계산 셰이더에서는 Atomic Operation(단위조작)을 지원하는 명령이 추가되었다.

 

이런 것들을 보면 DirectX 11은 새로운 프로그래머블 셰이더가 추가되고, 거기에 GPGPU지원으로 인한 기능강화가 픽셀 셰이더에 대해서 이루어 졌다는 느낌으로, 덕분에 복잡도가 상당히 높아지게 되었다. 이 복잡한 처리체계(파이프라인구조)는 CPU와 비교도 되지 않을 정도이다.

PS3, XBOX360등의 지금 세대(사실상 DirectX9 세대) 게임기의 다음 세대의 게임기등은 DirectX 10을 넘어서, DirectX 11 새대 이후의 아키텍쳐를 채용하게 되지 않을까.