Windows 응용 프로그램 개발자는 오랫동안 DirectX ®를 사용하여 하드웨어 가속에 의한 고품질의 3D 그래픽을 제공하고 있습니다. 이 기술이 발표된 1995년 이후 개발자들은 게임과 엔지니어링 애플리케이션을 위한 고품질의 3D 그래픽, 화려한 3D 그래픽 카드에 대한 투자를 아끼지 않는 열성적인 게임 팬들과 전문가를 위하여 제공하고 있습니다. 오늘은 아주 싼 PC에서도 충분히 리얼한 3D 그래픽 하드웨어를 제공합니다.

 

이런 그래픽 성능의 이점을 충분히 활용하기 위해 Windows Vista에는 여러 응용 프로그램과 서비스에 GPU 자원 공유를 가능하게 하는 DirectX를 위한 Windows Display Driver Model (WDDM) 인프라가 소개 되었습니다. 데스크톱 윈도우 매니저(DWM)는 이 기술을 사용하여 작업 전환을 3D로 애니메이션하고, 응용 프로그램 윈도우의 동적 썸네일 이미지를 표시하며 데스크톱 응용 프로그램의 Windows ® Aero ® 글래스 효과를 제공할 수 있었습니다.

 

Win32 개발자는 새로운 DirectX API 제품 군을 통해 GPU의 최신 기능을 활용하여 빠른 속도로 확장 가능한 고품질의 2D/3D 그래픽, 텍스트 및 이미지를 응용 프로그램에 추가할 수 있습니다. DirectX API는 최신 LCD 디스플레이 상에서 8 bpcc (bits per color component) 이상의 색상으로 데스크톱 및 윈도우 콘텐츠를 볼 수 있습니다.

 

또한 DirectX에서는 화상 처리 등의 일반적인 작업에 GPU의 병렬 처리를 사용하여 DirectX 10 하드웨어, DirectX 9 하드웨어, CPU 또는 원격 Windows 컴퓨터에 대해 렌더링을 수행할 수 있습니다. 이러한 기술은 GDI GDI+와의 상호 운용이 가능하도록 설계되었으며 개발자는 Win32 코드에 대한 기존 투자를 확실하게 살릴 수 있습니다.

이 향상된 그래픽 성능은 다음 COM 기반 API를 제공합니다.

  • Direct2D : 2D 그래픽 그리기.
  • DirectWrite : 텍스트 배치 및 렌더링.
  • Windows Imaging Comlionent : 이미지 처리 및 렌더링.
  • Direct3D ® 10 : 3D 그래픽 그리기.
  • Direct3D 11 : 3D 그래픽 그리기. 또한 텍셀레이션 등 차세대 GPU 기술의 사용이 예상됩니다. 제한적이지만 텍스처 스트리밍과 범용 컴퓨팅 등도 지원됩니다.
  • DirectX Graphics Infrastructure (DXGI) : 장치와 GPU 자원 관리 및 DirectX GDI간 상호 운용 성을 제공합니다.


Direct2D

Direct2D Direct3D 10을 기반으로 구축되고 Win32 개발자에게 차세대 그래픽 하드웨어의 성능을 살린 직접 실행 모드 해상도 독립적인 2D API를 제공합니다. 현재의 GDI / GDI + 응용 프로그램 및 Direct3D 10 응용 프로그램과의 상호 운용성도 확보되어 있습니다.  GDI GDI+ 보다 성능이 뛰어난 고품질의 2D 렌더링을 제공합니다.  Win32 개발자는 리소스와 관리를 제어할 수 있습니다.

 

 

DirectWrite

현재의 응용 프로그램은 높은 품질의 텍스트 렌더링 해상도와 무관한 윤곽선 글꼴, Unicode 텍스트 / 레이아웃의 완전 지원을 필요로 합니다. DirectX의 새로운 구성 요소인 DirectWrite 특징은 다음과 같습니다.

  • 문서 및 UI 텍스트 가독성을 강화하는 장치에 의존하지 않는 텍스트 레이아웃 시스템.
  • GDI, Direct2D 또는 응용 프로그램 고유의 렌더링 기술을 사용하여 고품질의 서브 픽셀 ClearTylie ® 텍스트 렌더링.
  • Direct2D와의 연계에 의한 하드웨어 지원 텍스트.
  • 멀티 포맷 텍스트 지원
  • OlienTylie ® 글꼴 고급 활판 인쇄 기능을 지원.
  • 지원되는 모든 언어로 텍스트 레이아웃 및 렌더링 지원.
  • GDI 호환 레이아웃 및 렌더링.

DirectWrite "다양한 글꼴을 다양한 위치에"이용하는 것을 허용하는 폰트 시스템입니다. 글꼴을 사용하기 위해 사용자가 별도의 설치 절차를 취할 필요가 없습니다.  글꼴 그룹의 구조적인 계층 구조가 개선되고 수동으로 또는 프로그래밍 방식으로 글꼴 검색이 용이합니다.  

 

API는 멀티 포맷 텍스트 측정, 드로잉 및 히트 테스트를 지원합니다.  Windows 7의 중요한 언어 인프라를 기반으로 하는 글로벌 응용 프로그램 및 지역화된 응용 프로그램에 대해 DirectWrite는 지원되는 모든 언어의 텍스트를 처리합니다. 또한 독자적인 레이아웃 처리와 Unicode / 그립 간의 변환 작업을 수행하는 개발자를 위해 낮은 수준의 그립 렌더링 API를 제공합니다.

 

 

Windows Imaging Component Windows Imaging Component

Windows Imaging Component Windows Vista에 추가된 이미지 또는 이미지 메타 데이터를 취급을 위한 확장성이 뛰어난 프레임 워크입니다.  Windows Imaging Component가 지원하는 이미지 포맷은 JPEG, PNG, TIFF 등이 포함됩니다. 지원되는 메타 데이터 형식은 XMP EXIF가 있습니다.  

 

Windows 7 Windows Imaging Component는 점진적 이미지 디코딩, 확장 PNG 기능, GIF 메타 데이터 외에 여러 APPn 세그먼트에 걸쳐 메타 데이터를 지원하여 준수 기준의 폭을 넓히고 있습니다.




Direct3D 11

Direct3D 11에서는 Direct3D 10 파이프라인 기능이 확장 되었습니다. Windows 7 게임과 고성능 3D 애플리케이션에 차세대 GPU와 멀티 코어 CPU에 효율적이고 강력하며 확장 가능한 액세스를 제공합니다.  

 

Direct3D 10의 기존 기능과 함께 몇 가지 새로운 기능이 채택되어있습니다.

패치와 서브 디비젼(다각형 분할) 표면 표현의 확장 가능한 동적 콘텐츠를 지원하기 위해 형상 및 하이 오더 서피스(고차원曲面) 텍셀레이션이 가능하게 되었습니다.

 

다중 스레드 처리는 멀티 코어 CPU가 제공하는 병렬 처리 성능을 최대한 활용하기 위한 궁리가 되어있습니다.  구체적으로는 응용 프로그램, 런타임 및 드라이버 호출을 여러 코어에 분산시킴으로써 프레임 당 잠재적인 렌더링 호출 횟수를 늘리고 있습니다. 또한 자원의 생성 및 관리가 다중 스레드에 최적화되어 보다 효율적인 동적 텍스처 관리를 통해 스트리밍이 가능하게 되었습니다.

 

Direct3D 11은 새로운 범용 연산 쉐이더가 만들어졌습니다. 기존의 쉐이더와 달리 이들은 프로그램 가능한 파이프라인 확장입니다. 응용 프로그램은 더 많은 작업을 CPU에 의존하지 않고 GPU 쪽에서만 진행할 수 있습니다.  Direct3D 10에 도입된 DrawAuto는 연산 쉐이더와 상호 작용하도록 향상되었습니다.

 

전문화의 복잡성을 완화하기 위하여 쉐이더에 국한의 동적 연결이 사용되는 점이랑 객체 지향 프로그래밍 개념(클래스, 인터페이스 등)이 도입되는 등 상위 레벨 쉐이더 언어 (HLSL : High Level Shading Language)에도 일부 개선 되고 있습니다.




Direct3D 10의 개량

Direct3D 10은 프로그래밍 가능한 쉐이더 스테이지와 불변 상태 개체 (고정 기능 스테이지 초기화)을 가진 쇄신되는 그래픽 파이프라인이 존재합니다. 이 상태 개체가 필요한 상태 변화의 횟수를 최소화하고 파이프라인을 단순화하여 성능을 향상시킵니다. 쉐이더 스테이지가 프로그램 가능하게 된 것으로 상위 레벨 쉐이더 언어 확장이 가능하고 무제한 쉐이더 명령 일반 쉐이더 리소스 및 정수 / 비트 연산을 지원하도록 합니다.

 

이 파이프라인은 또한 CPU 작업을 모두 GPU로 옮길 지오메트리 쉐이더 스테이지가 있습니다.  이 새로운 단계에 따라 형상을 만들고 데이터를 메모리로 전송하고, 형상을 연출하는 일련의 흐름을 CPU 개입 없이 할 수있습니다.

 

또한 성능을 강화하기 위하여 몇 가지 개선되어 있습니다. Predicated Rendering에서는 그리기 대상 지오메트리 양을 줄이는 오크루젼 컬링이 실행됩니다. 인스턴스화 API는 유사한 개체에 대한 다중 인스턴스를 그리는 것에 의해 GPU에 전달해야 하는 형상 양을 극적으로 감소시킵니다. 또한 텍스처 배열을 채택 GPU는 텍스처 스와핑을 CPU 개입 없이 수행할 수 있습니다.

 

Direct3D 10 Direct3D 11은 이러한 API를 사용하려면 구성을 확장하기 기능이 다수 존재합니다. Windows Advanced Rasterization Platform (warp)는 빠르고 확장 가능한 멀티 코어 CPU 렌더링 구현을 통해 Direct3D 10을 제공합니다. 이것에 의해 그래픽 하드웨어의 탑재되지 않은 시스템에서도 완벽한 기능의 그래픽 연출이 가능합니다.

 

Direct3D 10 Level 9라는 새로운 "기능 수준"추가에 의해 Direct3D 10 Direct3D 11 API Direct3D 9 종류의 하드웨어에서 사용할 수 있습니다. Direct3D 10 또는 Direct3D 11 응용 프로그램을 대상으로 하는 구성의 저변을 시장에 유통되는 거의 모든 컴퓨터 시스템에까지 퍼질 수 있습니다.

 

 

DirectX / GDI 상호 운용성

DirectX GDI를 모두 사용하여 공유 서피스에 렌더링하는 경우 Windows Vista에서는 데스크톱 윈도우 매니저 (DWM)가 설정되어 있는 경우와 그렇지 않은 경우 응용 프로그램의 동작을 달라집니다. 또한 DWM이 활성화 되어있을 때 DirectX GDI를 모두 사용하는 응용 프로그램을 실행하면 Windows Vista 용과 Windows XP에서 다르게 작동합니다.

따라서 많은 ISV Windows Vista에서 응용 프로그램을 실행하면 DWM을 사용하여 동작의 일관성을 확보해야 했습니다.  Windows 7에서 DirectX에 수행된 향상을 통해 이제부터 DWM을 사용하지 않고도 자유롭게 DirectX GDI를 혼합할 수 있습니다.

또한 Windows 7에서는 Direct3D 10 API를 보다 효율적으로 활용하여 DirectX GDI 간 상호 운용을 필요로 하는 경우에 성능이 향상됩니다.

 

 

 

출처 : http://msdn.microsoft.com/ja-jp/windows/dd459213.aspx#15

번역 : 최흥배


신고
by 흥배 2009.03.21 20:40
출처 giantjo님의 블로그 | 조진현
원문 http://blog.naver.com/giantjo/110043534104

 

텍스쳐 관리를 논하기에 앞서 GPU 측면에서 바라보는 메모리의 분류에서 언급하겠습니다.

 

 

 

GPU 입장에서 접근 가능한 하드웨어 메모리는 위의 그림처럼 AGP VRAM 으로

분류될 수 있습니다.

일반적으로 비디오 메모리란 용어를 개발자 입장에서 언급할 때는 바로 AGP + VRAM

이야기 합니다.

엄격히 구분해서 local VRAM Non-local VRAM 으로 부릅니다.



AGP 메모리는 System RAM 의 일정부분을 빌려서 GPU 가 접근 가능하도록 특화된

메모리 영역입니다.

AGP 메모리의 태생은 역시 오래 전 컴퓨터의 VRAM 의 부족으로 인해 탄생되었다고 합니다.

지금은 VRAM 이 넘치는 시대라고는 하지만, 저는 아직도 부족하다고 생각이 듭니다.^^

AGP 영역은 GPU 가 접근이 용이하도록 독립된 데이터 버스를 이용합니다.

거기다가 파이프라인 형식으로 데이터를 주고 받을 수 있습니다.

그러다 보니, 당연히 일반적인 데이터 전송보다는 상당히 빠르다고 할 수 있습니다.

( 당연히 VRAM 에서의 접근보다는 성능이 떨어질 것입니다. )

 

사실 오늘 날 쉐이더가 발전하면서 AGP 의 장점이 크게 묻혀졌다고 생각합니다.

일반적으로 GPU는 쓰기 능력이 CPU 에 비행 떨어집니다.

쓰기 능력이라함은 연산을 계산해서 저장하는 능력이 떨어진다는 겁니다.( CPU 에 비해서 )

흔히들 책에서 실시간으로 변하는 데이터의 경우( 파티클이나 스키닝 처리 등 ) 에는

AGP 메모리에 이들을 저장해 두고 연산을 처리해서 GPU 에게 처리를 맡기는 방법을

구현합니다.

요즘에는 쉐이더를 이용해서 이들 모두를 GPU 에서 처리하도록 처리하게 구조를

변경할 수도 있습니다.

사실 이는 최적화 문제에 따라 채택하는 방법이 다를 수 있습니다.

CPU 에서 스키닝과 같은 연산을 처리해서 얻을 수 있는 장점도 분명히 무시할 수 없습니다.

예를 들면, 하나의 캐릭터를 n번 렌더링 해야하는 경우 CPU 에서는 이 스키닝 연산을 한번만

처리하면 되지만, GPU n 번 스키닝 연산해야 합니다.( 물론 n 이 적은 숫자라면 GPU

훨씬 빠르게 처리할 수 있습니다. 제 생각에는 4번 정도까지는…… )

그래서 쓸모없는 공간이라고 단정하기는 어렵습니다.

 

이제부터 설명하는 비디오 메모리는 지금까지 설명한 AGP 메모리와 VRAM 을 통합한

메모리라는 것을 정의하고자 앞의 내용을 언급했습니다.

 

 

우리는 DirectX 가 사용하는 리소스 용법에 대해서 언급할 필요가 있습니다.

DirectX 가 사용하는 리소스 용법은 크게 3가지로 분류할 수 있습니다.

흔히들 많이 언급되는 POOL_DEFAULT, POOL_SYSTEM, POOL_MANAGED 이 바로

그것들입니다.( 이것말고도 POOL_SCRATCH 라는 것이 하나 더 있습니다.^^ )

이번에 관련 내용을 준비하면서 개인적으로 잘못 알고 있던 부분도 많아서,

이들에 대한 나름대로 이해한 것을 정의하면서 시작하겠습니다.

 

 

POOL_DEFAULT 의 경우는 GPU 가 접근가 접근 가능한 메모리에 위치시키는 개념입니다.

바로 비디오 메모리입니다.( AGP + VRAM )

 

POOL_SYSTEM 은 위의 그림에서 본다면 System RAM 상에 위치시키는 개념입니다.

이것은 GPU 가 접근할 수 있는 메모리가 아닙니다.

그래서 이 메모리와 대응되는 POOL_DEFAULT 메모리가 존재해야 하며,

Update 계열의 함수를 써서 System RAM 의 내용을 비디오 메모리로 전송해야 합니다.

 

마지막으로 남은 POOL_MANAGED 는 이 둘이 합쳐진 형태라고 생각이 됩니다.

먼저 System RAM 쪽에 데이터를 만들고, 필요에 의해서 DirectX 의 리소스 관리자에 의해서

비디오 메모리로 전송되는 구조입니다.

 

 

그러면 이제부터 텍스쳐에 한해서 문제를 풀어가겠습니다.

POOL_MANAGED 의 경우에는 텍스쳐 관리를 DirectX 에 의존해서 수행하게 됩니다.

DirectX 가 렌더링에 필요한 텍스쳐를 비디오 메모리에 로드해 줍니다.

이를 위해서 우리는 단순히 SetTexture() 와 유사한 API 를 사용합니다.

DirectX6 이전에는 이런 관리를 개발자가 모두 작성해야 했다고 합니다.

 

여기서 제가 설명할 부분은 이 텍스쳐 관리입니다.

도대체 텍스쳐 관리라는 것이 무엇일까요?

일단 이 텍스쳐 관리는 캐시 시스템으로 유지되는 것 같습니다.

비디오 메모리의 용량이 제한적이기 때문에, 필요한 텍스쳐만 우리는 메모리에 바인딩해서

렌더링 작업을 수행해야 합니다.


텍스쳐 관리 시스템의 주요 기능은

-       텍스쳐를 비디오 메모리에 부르는 기능

-       텍스쳐 메모리를 비우기

-       텍스쳐 메모리 관리하기 로 구분할 수 있습니다.


추가적으로

-       밉맵의 레벨 결정하는 단계.

-       대역폭을 줄이기 위한 실시간 압축과 해제 기능.

-       전처리 기능, 숨겨진 면 제거 기능 등.

 

등이 있을 수도 있습니다.

 

그러면 이제, 하나의 상황을 가정해 보겠습니다.

만약에 로드하려는 텍스쳐가 있는 상황에서 사용 가능한 비디오 메모리가 부족한 상태라면

DirectX 는 어떻게 동작할까요?

DirectX 는 이를 위해서 캐시 정책과 유사한 개념을 두어서 자동으로 관리를 해줍니다.

가장 유명한 캐시 정책은 LRU 기법과 MRU 기법이 있습니다.

LRU 기법은 리소스를 로딩할 때 시간 값을 기록해 두는 것이고,

MRU 는 그 리소스가 참조되는 카운터 값을 기록해 두는 것입니다.

 

DirectX 시스템은 아마도 LRU 기법으로 텍스쳐를 관리하는 것 같습니다.

이 상황에서는 가장 오래 전에 비디오 메모리에 올라왔던 텍스쳐 메모리를 제거할 것입니다.

이 제거 작업은 로드하려는 텍스쳐 메모리 용량이 확보될 때까지 수행할 것입니다.

 

앞서 살펴 보았듯이 DirectX 를 사용해서 리소스를 로딩할 때, 관리 방법을 지정해 줄 수

있었습니다. POOL_DEFAULT POOL_MANAGED 가 그것입니다.

DirectX 시스템의 관리에 의해서 자동으로 비디오 메모리 상에서 제거될 수 있는 텍스쳐는

POOL_MANAGED 로 로드한 텍스쳐들 뿐입니다.

, POOL_DEFAULT 로 생성된 텍스쳐들은 DirectX 에 의해서 자동으로 관리가 되지 않습니다.


POOL_MANAGED 로 생성된 텍스쳐들은 원본 데이터가 시스템 메모리에 존재합니다.

그러므로 언제든지 데이터를 비디오 메모리로 전송할 수 있습니다.

흔히들 얘기되는 ‘Lost Device’ 상황에서도 자동으로 관리된다는 의미가 바로 이 이유때문입니다.

반면, POOL_DEFAULT 는 비디오 메모리에 올라가 있는 것이 원본입니다.

‘Lost Device’ 상황이 발생하면, 유효한 비디오 메모리는 존재하지 않습니다.

그래서 개발자가 직접 이 내용을 복원해 주어야 하는 것입니다.

 

그러면 만약에 비디오 메모리 상에서 텍스쳐 캐싱 시스템을 만들어야 한다면 어떻게 해야 할까요?

자주 사용되는 텍스쳐들은 POOL_DEFAULT 로 만들어 두어서, 반드시 비디오 메모리 상에

있도록 해두면 효과적일 것이라 생각합니다.

물론 POOL_DEFAULT 로 사용되는 텍스쳐들이 POOL_MANAGED 를 사용하는 텍스쳐들보다

먼저 로딩 작업을 해야, 비디오 메모리에 안전하게 올라갈 수 있을 것입니다.

 

이 작업이 부담스러운 분들을 위해서, MS 가 친절하게 IDirect3DResource9::SetPriority() 라는

API 를 제공합니다. 리소스들에게 우선 순위를 두어서 제거 작업이 필요한 경우 참고할 것입니다.

 

참고로 반드시 POOL_DEFAULT 로 관리될 수 밖에 없는 렌더 타겟기법은 그래픽칩 상에

텍스쳐 메모리를 할당해서 렌더링 하기 때문에, 개발자가 직접 관리해 주어야 합니다.

( DDR 메모리라고 합니다 : DirectX9 셰이더 프로그래밍 책 참고 )

 

한번에 모든 비디오 메모리에 있는 리소스를 제거할 수 있는 API 함수도 존재합니다.

바로 IDirect3DDevice9::EvictManagedResources() 가 그것입니다.

이 때도 역시 DirectX 에 의해서 관리되는 리소스만 제거된 다는 것을 주의하셔야 합니다.

, POOL_MANAGED 만 제거됩니다.

API 는 장면이 크게 전환되는 경우 꽤나 유용합니다.

그리고 시스템 메모리에 있는 원본이 전송되어 비디오 메모리로 오기 때문에 시간이

소요될 수 있다는 것도 알아두셔야 합니다.

 

 

텍스쳐와 관련해서 성능 개선 방법을 정리해 보면,

매우 자주 사용되는 텍스쳐의 경우에는 POOL_DEFAULT 로 사용해야 할 것입니다.

이게 귀찮으면 리소스간 우선순위를 두어서 관리되는 형식으로 구축해야 할 것입니다.

 

그리고 보통 텍스쳐 별로 정렬을 가장 먼저해서, 렌더링 순서를 정할 것입니다.

( 텍스쳐 à 쉐이더   뭐 이런 순서일 것입니다 . )

이 때 텍스쳐 별로 정렬이 되어 있으면,

다음 프레임에서는 이 텍스쳐 정렬의 역순으로 렌더링 하도록 하면 좀 더 효율적일 수 있습니다.

물론 알파 관련한 소팅도 고려된 소팅이어야 합니다. 알파과 있는 부분부터 렌더링 하라는

얘기가 아닙니다. 알파가 없는 부분에 한해서 입니다.

AàBàC 순서를 CàBàA 로 렌더링 하는 겁니다.

왜냐하면 가장 최근에 렌더링 한 텍스쳐이기 때문에 다음 렌더링때 비디오 메모리 상에

있을 가능성이 아주 높기 때문입니다.

 

마지막으로 장면이 크게 변하는 경우에는 비디오 메모리를 비워주는 API 함수를 호출하면

더 효율적일 것입니다.

 

텍스쳐 관리 시스템을 직접 구현하셔도 됩니다.

POOL_DEFAULT POOL_SYSTEM 을 적절히 이용하셔야 할 것입니다.

하지만, 개인적으로 추천하고 싶지 않습니다.

MS 에서도 권장하는 부분이 아닙니다.

 

개인적으로 작성한 글이니 잘못된 지식일 수 있음을 유의하시기 바랍니다.




참고자료

 

http://blog.naver.com/jacking75/140030532889

http://blog.naver.com/yakswa?Redirect=Log&logNo=140003731301

http://number-none.com/blow/papers/implementing_a_texture_caching_system.pdf

gpg study 사이트

리얼타임 렌더링 2

Inside Direct3D

DirectX 셰이더 프로그래밍.



신고
by 흥배 2009.03.21 20:39
출처 giantjo님의 블로그 | 조진현
원문 http://blog.naver.com/giantjo/110043534104

 

텍스쳐 관리를 논하기에 앞서 GPU 측면에서 바라보는 메모리의 분류에서 언급하겠습니다.

 

 

 

GPU 입장에서 접근 가능한 하드웨어 메모리는 위의 그림처럼 AGP VRAM 으로

분류될 수 있습니다.

일반적으로 비디오 메모리란 용어를 개발자 입장에서 언급할 때는 바로 AGP + VRAM

이야기 합니다.

엄격히 구분해서 local VRAM Non-local VRAM 으로 부릅니다.



AGP 메모리는 System RAM 의 일정부분을 빌려서 GPU 가 접근 가능하도록 특화된

메모리 영역입니다.

AGP 메모리의 태생은 역시 오래 전 컴퓨터의 VRAM 의 부족으로 인해 탄생되었다고 합니다.

지금은 VRAM 이 넘치는 시대라고는 하지만, 저는 아직도 부족하다고 생각이 듭니다.^^

AGP 영역은 GPU 가 접근이 용이하도록 독립된 데이터 버스를 이용합니다.

거기다가 파이프라인 형식으로 데이터를 주고 받을 수 있습니다.

그러다 보니, 당연히 일반적인 데이터 전송보다는 상당히 빠르다고 할 수 있습니다.

( 당연히 VRAM 에서의 접근보다는 성능이 떨어질 것입니다. )

 

사실 오늘 날 쉐이더가 발전하면서 AGP 의 장점이 크게 묻혀졌다고 생각합니다.

일반적으로 GPU는 쓰기 능력이 CPU 에 비행 떨어집니다.

쓰기 능력이라함은 연산을 계산해서 저장하는 능력이 떨어진다는 겁니다.( CPU 에 비해서 )

흔히들 책에서 실시간으로 변하는 데이터의 경우( 파티클이나 스키닝 처리 등 ) 에는

AGP 메모리에 이들을 저장해 두고 연산을 처리해서 GPU 에게 처리를 맡기는 방법을

구현합니다.

요즘에는 쉐이더를 이용해서 이들 모두를 GPU 에서 처리하도록 처리하게 구조를

변경할 수도 있습니다.

사실 이는 최적화 문제에 따라 채택하는 방법이 다를 수 있습니다.

CPU 에서 스키닝과 같은 연산을 처리해서 얻을 수 있는 장점도 분명히 무시할 수 없습니다.

예를 들면, 하나의 캐릭터를 n번 렌더링 해야하는 경우 CPU 에서는 이 스키닝 연산을 한번만

처리하면 되지만, GPU n 번 스키닝 연산해야 합니다.( 물론 n 이 적은 숫자라면 GPU

훨씬 빠르게 처리할 수 있습니다. 제 생각에는 4번 정도까지는…… )

그래서 쓸모없는 공간이라고 단정하기는 어렵습니다.

 

이제부터 설명하는 비디오 메모리는 지금까지 설명한 AGP 메모리와 VRAM 을 통합한

메모리라는 것을 정의하고자 앞의 내용을 언급했습니다.

 

 

우리는 DirectX 가 사용하는 리소스 용법에 대해서 언급할 필요가 있습니다.

DirectX 가 사용하는 리소스 용법은 크게 3가지로 분류할 수 있습니다.

흔히들 많이 언급되는 POOL_DEFAULT, POOL_SYSTEM, POOL_MANAGED 이 바로

그것들입니다.( 이것말고도 POOL_SCRATCH 라는 것이 하나 더 있습니다.^^ )

이번에 관련 내용을 준비하면서 개인적으로 잘못 알고 있던 부분도 많아서,

이들에 대한 나름대로 이해한 것을 정의하면서 시작하겠습니다.

 

 

POOL_DEFAULT 의 경우는 GPU 가 접근가 접근 가능한 메모리에 위치시키는 개념입니다.

바로 비디오 메모리입니다.( AGP + VRAM )

 

POOL_SYSTEM 은 위의 그림에서 본다면 System RAM 상에 위치시키는 개념입니다.

이것은 GPU 가 접근할 수 있는 메모리가 아닙니다.

그래서 이 메모리와 대응되는 POOL_DEFAULT 메모리가 존재해야 하며,

Update 계열의 함수를 써서 System RAM 의 내용을 비디오 메모리로 전송해야 합니다.

 

마지막으로 남은 POOL_MANAGED 는 이 둘이 합쳐진 형태라고 생각이 됩니다.

먼저 System RAM 쪽에 데이터를 만들고, 필요에 의해서 DirectX 의 리소스 관리자에 의해서

비디오 메모리로 전송되는 구조입니다.

 

 

그러면 이제부터 텍스쳐에 한해서 문제를 풀어가겠습니다.

POOL_MANAGED 의 경우에는 텍스쳐 관리를 DirectX 에 의존해서 수행하게 됩니다.

DirectX 가 렌더링에 필요한 텍스쳐를 비디오 메모리에 로드해 줍니다.

이를 위해서 우리는 단순히 SetTexture() 와 유사한 API 를 사용합니다.

DirectX6 이전에는 이런 관리를 개발자가 모두 작성해야 했다고 합니다.

 

여기서 제가 설명할 부분은 이 텍스쳐 관리입니다.

도대체 텍스쳐 관리라는 것이 무엇일까요?

일단 이 텍스쳐 관리는 캐시 시스템으로 유지되는 것 같습니다.

비디오 메모리의 용량이 제한적이기 때문에, 필요한 텍스쳐만 우리는 메모리에 바인딩해서

렌더링 작업을 수행해야 합니다.


텍스쳐 관리 시스템의 주요 기능은

-       텍스쳐를 비디오 메모리에 부르는 기능

-       텍스쳐 메모리를 비우기

-       텍스쳐 메모리 관리하기 로 구분할 수 있습니다.


추가적으로

-       밉맵의 레벨 결정하는 단계.

-       대역폭을 줄이기 위한 실시간 압축과 해제 기능.

-       전처리 기능, 숨겨진 면 제거 기능 등.

 

등이 있을 수도 있습니다.

 

그러면 이제, 하나의 상황을 가정해 보겠습니다.

만약에 로드하려는 텍스쳐가 있는 상황에서 사용 가능한 비디오 메모리가 부족한 상태라면

DirectX 는 어떻게 동작할까요?

DirectX 는 이를 위해서 캐시 정책과 유사한 개념을 두어서 자동으로 관리를 해줍니다.

가장 유명한 캐시 정책은 LRU 기법과 MRU 기법이 있습니다.

LRU 기법은 리소스를 로딩할 때 시간 값을 기록해 두는 것이고,

MRU 는 그 리소스가 참조되는 카운터 값을 기록해 두는 것입니다.

 

DirectX 시스템은 아마도 LRU 기법으로 텍스쳐를 관리하는 것 같습니다.

이 상황에서는 가장 오래 전에 비디오 메모리에 올라왔던 텍스쳐 메모리를 제거할 것입니다.

이 제거 작업은 로드하려는 텍스쳐 메모리 용량이 확보될 때까지 수행할 것입니다.

 

앞서 살펴 보았듯이 DirectX 를 사용해서 리소스를 로딩할 때, 관리 방법을 지정해 줄 수

있었습니다. POOL_DEFAULT POOL_MANAGED 가 그것입니다.

DirectX 시스템의 관리에 의해서 자동으로 비디오 메모리 상에서 제거될 수 있는 텍스쳐는

POOL_MANAGED 로 로드한 텍스쳐들 뿐입니다.

, POOL_DEFAULT 로 생성된 텍스쳐들은 DirectX 에 의해서 자동으로 관리가 되지 않습니다.


POOL_MANAGED 로 생성된 텍스쳐들은 원본 데이터가 시스템 메모리에 존재합니다.

그러므로 언제든지 데이터를 비디오 메모리로 전송할 수 있습니다.

흔히들 얘기되는 ‘Lost Device’ 상황에서도 자동으로 관리된다는 의미가 바로 이 이유때문입니다.

반면, POOL_DEFAULT 는 비디오 메모리에 올라가 있는 것이 원본입니다.

‘Lost Device’ 상황이 발생하면, 유효한 비디오 메모리는 존재하지 않습니다.

그래서 개발자가 직접 이 내용을 복원해 주어야 하는 것입니다.

 

그러면 만약에 비디오 메모리 상에서 텍스쳐 캐싱 시스템을 만들어야 한다면 어떻게 해야 할까요?

자주 사용되는 텍스쳐들은 POOL_DEFAULT 로 만들어 두어서, 반드시 비디오 메모리 상에

있도록 해두면 효과적일 것이라 생각합니다.

물론 POOL_DEFAULT 로 사용되는 텍스쳐들이 POOL_MANAGED 를 사용하는 텍스쳐들보다

먼저 로딩 작업을 해야, 비디오 메모리에 안전하게 올라갈 수 있을 것입니다.

 

이 작업이 부담스러운 분들을 위해서, MS 가 친절하게 IDirect3DResource9::SetPriority() 라는

API 를 제공합니다. 리소스들에게 우선 순위를 두어서 제거 작업이 필요한 경우 참고할 것입니다.

 

참고로 반드시 POOL_DEFAULT 로 관리될 수 밖에 없는 렌더 타겟기법은 그래픽칩 상에

텍스쳐 메모리를 할당해서 렌더링 하기 때문에, 개발자가 직접 관리해 주어야 합니다.

( DDR 메모리라고 합니다 : DirectX9 셰이더 프로그래밍 책 참고 )

 

한번에 모든 비디오 메모리에 있는 리소스를 제거할 수 있는 API 함수도 존재합니다.

바로 IDirect3DDevice9::EvictManagedResources() 가 그것입니다.

이 때도 역시 DirectX 에 의해서 관리되는 리소스만 제거된 다는 것을 주의하셔야 합니다.

, POOL_MANAGED 만 제거됩니다.

API 는 장면이 크게 전환되는 경우 꽤나 유용합니다.

그리고 시스템 메모리에 있는 원본이 전송되어 비디오 메모리로 오기 때문에 시간이

소요될 수 있다는 것도 알아두셔야 합니다.

 

 

텍스쳐와 관련해서 성능 개선 방법을 정리해 보면,

매우 자주 사용되는 텍스쳐의 경우에는 POOL_DEFAULT 로 사용해야 할 것입니다.

이게 귀찮으면 리소스간 우선순위를 두어서 관리되는 형식으로 구축해야 할 것입니다.

 

그리고 보통 텍스쳐 별로 정렬을 가장 먼저해서, 렌더링 순서를 정할 것입니다.

( 텍스쳐 à 쉐이더   뭐 이런 순서일 것입니다 . )

이 때 텍스쳐 별로 정렬이 되어 있으면,

다음 프레임에서는 이 텍스쳐 정렬의 역순으로 렌더링 하도록 하면 좀 더 효율적일 수 있습니다.

물론 알파 관련한 소팅도 고려된 소팅이어야 합니다. 알파과 있는 부분부터 렌더링 하라는

얘기가 아닙니다. 알파가 없는 부분에 한해서 입니다.

AàBàC 순서를 CàBàA 로 렌더링 하는 겁니다.

왜냐하면 가장 최근에 렌더링 한 텍스쳐이기 때문에 다음 렌더링때 비디오 메모리 상에

있을 가능성이 아주 높기 때문입니다.

 

마지막으로 장면이 크게 변하는 경우에는 비디오 메모리를 비워주는 API 함수를 호출하면

더 효율적일 것입니다.

 

텍스쳐 관리 시스템을 직접 구현하셔도 됩니다.

POOL_DEFAULT POOL_SYSTEM 을 적절히 이용하셔야 할 것입니다.

하지만, 개인적으로 추천하고 싶지 않습니다.

MS 에서도 권장하는 부분이 아닙니다.

 

개인적으로 작성한 글이니 잘못된 지식일 수 있음을 유의하시기 바랍니다.




참고자료

 

http://blog.naver.com/jacking75/140030532889

http://blog.naver.com/yakswa?Redirect=Log&logNo=140003731301

http://number-none.com/blow/papers/implementing_a_texture_caching_system.pdf

gpg study 사이트

리얼타임 렌더링 2

Inside Direct3D

DirectX 셰이더 프로그래밍.



신고
by 흥배 2009.03.21 20:39
| 1 |