Game Dev/Scrap

D3D Resources 분석

AKer 2008. 10. 24. 10:48
반응형
관련 포스트 : http://aker.tistory.com/56



D3D Resources 

Direct3D는 리소스를 생성하거나 수정할 때 많은 수의 Flag를 지원한다. 그것으로 어떻게 리소스를 사용할 것인지 결정하며, Direct3D가 비디오카드 드라이버와 어떤식으로 동작하는지 그리고 최적화 된 렌더링을 위하여 어느곳에 위치하는지를 결정한다. 여기에서 이야기할 가장 중요한 3가지의 Flag는 다음과 같다. 

  • Memory pool - 어느곳에 리소스가 위치 할것인가? 
  • Usage - 어떤 방법으로 리소스를 사용할것인가?
  • Lock flags - 데이터가 Lock될 경우에 어떻게 작동할것인가?



Memory Pool 

버텍스 버퍼, 인덱스 버퍼, 텍스쳐 등을 생성할 때 Direct3D는 새로운 리소스를 어디에 위치할것인지에 대한 메모리 클래스를 필요로한다. 이것은 Pool 같은 개념이며 Direct3D는 다음과 같이 정의한다.

  • D3DPOOL_DEFAULT 
  • D3DPOOL_MANAGED 
  • D3DPOOL_SYSTEMMEM 
  • D3DPOOL_SCRATCH

각각은 다음과 같다.

1. D3DPOOL_DEFAULT 
리소스는, 리소스에 대해서 요구된 사용 방법으로 가장 적합한 메모리 풀에 놓여진다. 일반적으로 비디오 메모리 혹은 Fast AGP메모리에 위치시킨다. 만일 리소스가 텍스쳐이고 이것이 Dynamic 텍스쳐가 아니라면 Lock 할수 없다. 다른 리소스 가령 Back Buffer, Render Target, 버텍스 버퍼, 인덱스 버퍼들은 Lock 가능하다. 그러나 퍼포먼스에 대하여 패널티를 갖게된다. 만일 Direct3D 디바이스가 소실 (Lost) 될 경우 D3DPOOL_DEFAULT로 생성된것 들은 반드시 Reset 전에 Release되야 한다. 그리고 디바이스를 다시 얻었을때 다시 생성해야 한다. 리소스는 항상 Write only라는것을 기억하라. 

주의: Default 리소스가 생성될때 생성되어있는 Managed 리소스는 Default 리소스에게 공간을 만들어 주기 위하여 비디오 카드 메모리로부터 제거 될수 있다. 이러한 이유로 Managed 리소스를 생성하기 전에 Default 리소스를 생성하거나 Non-Managed 리소스를 생성하기전에 EvictManagedResources()를 호출 하는 것이 좋다. Managed 리소스를 생성한 후에 어떠한 Non-Managed 리소스를 생성하려 하지 마라. 만일 꼭 생성하여야 한다면 EvictManagedResources()를 먼저 호출하라. 하지만 속도를 기대하지는 마라. 

2. D3DPOOL_MANAGED 
이것은 많이 사용되는 메모리 풀이다. Direct3D는 리소스의 복사본을 시스템 메모리에 유지한다. 그리고 필요한 경우에 비디오 메모리로 복사하거나 AGP 메모리로 복사한다. 이것의 장점은 디바이스가 소실될 경우에 리소스를 해제하거나 재생성할 필요가 없다는것이다. 또 다른 장점은 Managed로 생성된 모든 리소스들은 Lock이 가능하다는 것이다. Direct3D는 시스템메모리의 복사본을 Lock하고 요구되어질때 디바이스 메모리로 복사를 한다. Managed 메모리는 비디오 카드 내의 최적화 된 리소스 위치를 Direct3D가 사용할 수 있으므로 자주 사용되는 방법이다. 모든것들을 Managed로 사용하는 것에 대한 충고는 나중에 원하면 다시 퍼포먼스를 조정하라는 것이다. (이것이 최고가 아니므로 조정할 수 있으면 조정하라는 뜻, 조정의 여지가 많다는 뜻) 

3. D3DPOOL_SYSTEMMEM 
일반적으로 리소스를 시스템 메모리에 위치시키거나 적어도 Non device assessable RAM에 위치 시킨다. 이것은 바로 렌더하고자 하지 않은 것들을 위하여 사용된다. 이 리소스는 Lock이 가능하고 디바이스가 소실되어도 다시 생성할 필요가 없다. 이 리소스 풀의 한가지 사용용도는 D3DPOOL_DEFAULT로 만들어지고 UpdateSurface() 또는 UpdateTexture()에 사용되어지는 Surface 또는 텍스쳐에 복사하는것이다. 

4. D3DPOOL_SCRATCH 
리소스를 시스템 메모리에 위치시킨다. 이 리소스는 Lock 가능하며 디바이스 소실 때 재생성하지 않아도 된다. 이 리소스 타입을 사용하는 최대 장점은 비디오 카드에서 텍스쳐가 2의 승수 제한을 피할 수 있다는 것이다. 그래서 만일 당신이 2의 승수가 아닌 텍스쳐를 로드한다면 이 Pool을 사용하여 로드하라. 이 방법의 단점은 디바이스에서 엑세스 할수 없는 것과 렌더링 하는동안 사용할수 없다는 것이다. 이 메모리풀은 일반적으로 Pre-Processing Data에 사용된다. (예를들어 Scratch memory surface에 큰 텍스쳐를 로드하고 그것을 작은 조각으로 자르거나 디바이스의 텍스처로 그것을 생성하고자 할때)

Summary 
D3DPOOL_MANAGED은 가장 빈번하게 사용된다, 복사본은 비디오카드와 Direct3D와 협력하여 최적화된곳에 위치하게 된다. 이 메모리는 Lock 할 수 있고 조작할 수 있고 재생성하지 않아도 된다. 만일 D3DPOOL_DEFAULT을 사용하고 싶다면 Managed 객체를 만들기 전에 사용하거나 EvictManagedResources()를 호출하라. D3DPOOL_SYSTEMMEM 리소스들은 Update 되는 서피스나 텍스처에 유용하다. D3DPOOL_SCRATCH는 그래픽 디바이스로부터 제한되지 않고 조작할 수 있는 곳에 위치하게된다. 



Resource Usage Hints 

리소스를 생성할 때 Direct3D는 리소스를 어떻게 사용할것인지에 대하여 Flag를 제공한다. 그리고 거기에는 Direct3D가 어떻게 작동할지에 대한 어떠한 보증도 하지 않는다. 그럼에도 불구하고 이것은 렌더링의 퍼포먼스를 최적화하는데 유용한 메카니즘이다. Direct3D는 다음과 같은 Flag를 제공한다.

  • D3DUSAGE_AUTOGENMIPMAP 
  • D3DUSAGE_DEPTHSTENCIL 
  • D3DUSAGE_DMAP 
  • D3DUSAGE_DONOTCLIP 
  • D3DUSAGE_DYNAMIC 
  • D3DUSAGE_NPATCHES 
  • D3DUSAGE_POINTS 
  • D3DUSAGE_RTPATCHES 
  • D3DUSAGE_RENDERTARGET 
  • D3DUSAGE_SOFTWAREPROCESSING 
  • D3DUSAGE_WRITEONLY

D3DUSAGE_DYNAMIC 
Surface를 제외한 어떤 다른 리소스를 위하여 제공될수 있다. 리소스가 정기적으로 사용될 것이면 (예: 매프레임 쓰기작업) 이 Flag를 사용한다. Direct3D는 일반적으로 리소스를 APG 메모리에 위치한다. 만일 이 Flag를 사용하지 않는다면 Direct3D는 리소스를 static으로 간주할것이다. (예: 리소스가 설정후 바뀌지 않음) D3DPOOL_MANAGED으로 생성된 리소스에 대하여 dynamic 사용은 불가하다, D3DPOOL_DEFAULT를 사용하여야 한다. 이것의 뜻은 Direct3D와 비디오카드는 리소스를 가장 좋은 위치에 넣는 것을 결정한다는것이다. 일반적으로 AGP 메모리에 버텍스버퍼를 그리고 AGP 메모리 혹은 비디오 메모리에 인덱스버퍼를 위치시킨다. 만일 가능하다면 가장 좋은 결과를 위하여 D3DUSAGE_WRITEONLY Flag와 같이 사용하라. 만일 당신이 Lock 한다면 차라리 static 보다 dynamic으로 설정하라. 

D3DUSAGE_WRITEONLY 
오직 버텍스, 인덱스버퍼에 지정할수 있다. Direct3D 에게 리소스를 쓰기작업만 하고 읽기작업은 하지 않음을 지정한다. 만일 당신이 리소스로부터 읽기 작업을 절대로 하지 않는다면 이 Flag는 디바이스가 렌더링을 위한 리소스 선정에서 굉장한 속도증가를 제공하여 준다. 만일 이 Flag를 사용하고 리소스로부터 읽기 작업을 수행하면 작업은 실패한다. D3DPOOL_DEFAULT로 생성한 리소스는 반드시 Write only를 설정하라. 아니면 퍼포먼스는 많이 하락할것이다. 

D3DUSAGE_SOFTWAREPROCESSING 
버텍스 프로세싱을 하드웨어가 아닌 소프트웨어로 처리함을 지정한다. 디바이스를 하드웨어를 사용하지 않고 소프트웨어를 통하여 처리할때 사용한다.

D3DUSAGE_AUTOGENMIPMAP 
텍스쳐리소스에 대하여 자동으로 밉맵을 생성할때 사용한다. 이 사용법은 D3DPOOL_SYSTEMMEM 내의 리소스에 대해서는 유효하지 않다. 

D3DUSAGE_DEPTHSTENCIL 
리소스가 Depth Stencil 버퍼임을 나타낸다. D3DPOOL_DEFAULT로 생성한 리소스에만 사용된다. 

D3DUSAGE_DMAP 
텍스쳐 리소스가 Displacement Map임을 나타낸다. 

D3DUSAGE_DONOTCLIP 
버텍스버퍼가 클리핑이 필요하지 않을 때를 지정한다. 이것은 이미 변환 완료된 (D3DFVF_XYZRHW) 버텍스와 같은것에 유용하다. 클리핑 Flag는 뷰공간 밖에 렌더링할때 사용된다 그래서 이것을 사용하면 Off-Screen에 렌더하지 않음을 보장해야 한다. D3DRS_CLIPPING 렌더링 스테이트가 FALSE 로 설정되지 않으면 안 된다. 

D3DUSAGE_NPATCHES 
N 패치의 드로잉에 정점 버퍼를 사용할 때 설정한다. 

D3DUSAGE_POINTS 
드로우 포인트 스프라이트를 위하여 사용되는 인덱스 버텍스 버퍼를 사용함을 나타낸다. 만일 디바이스가 하드웨어 포인트 스프라이트를 사용할수 없으면 이것의 리소스는 시스템 메모리에 위치하게 된다. 

D3DUSAGE_RTPATCHES 
고차원 기본도형의 드로잉에 정점 버퍼를 사용할 때에 설정한다. 

D3DUSAGE_RENDERTARGET 
리소스는 렌더테겟으로 사용된다. 예로 Scene을 여기에 렌더하는것. (거율효과에 유용) 이것은 텍스쳐와 Surface에만 사용가능하고 D3DPOOL_DEFAULT 메모리 풀을 사용한 리소스에만 사용 가능하다. 



Locking and reading / writing flags 

리소스를 Lock 할 때 그리고 읽거나 쓸 때, 퍼포먼스의 최적화를 위하여 Direct3D는 Flag를 제공한다. 이 Flag는 다음과 같다. 

  • D3DLOCK_DISCARD 
  • D3DLOCK_NO_DIRTY_UPDATE 
  • D3DLOCK_NOSYSLOCK 
  • D3DLOCK_READONLY 
  • D3DLOCK_NOOVERWRITE

1. D3DLOCK_DISCARD 
버텍스 , 인덱스, 텍스쳐에 사용되어 진다. Lock 된 리소스에 대하여 Write only작업을 수행하는데 어플리케이션이 모든 부분에 대하여 덮어쓰기를 수행함을 지정한다. dynamic 리소스에 대하여만 사용되어진다. 반드시 자료의 부분이 아닌 모든부분에 대하여 업데이트를 수행하여야 한다. (버려지기 때문) 이 Flag는 큰 성능 향샹을 기대할 수 있다. Direct3D의 버텍스버퍼와 인덱스버퍼의 기존 내용은 버려진다. 그리고 새로운 리소스가 들어오지 않을 때까지 기존의 내용으로 렌더링된다. 만일 많은 양의 discard를 매 프레임 수행하면 AGP 메모리의 사용량은 새로운 리소스를 만드는것처럼 증가한다. 

2. D3DLOCK_NO_DIRTY_UPDATE 
리소스를 Lock 할때 기본적으로 이것을 'dirty'로 설정한다. 이 뜻은 카드의 메모리는 업데이트가 필요하다는것이다. 

3. D3DLOCK_NOSYSLOCK 
이것은 16비트 윈도우(95/98/ME)에 한하여 관련있다. Lock이 수행되는 동안 크리티컬 섹션은 디스플레이 모드가 바뀌는것을 허락하지 않는다. 이것은 그 시간 동안 다른 작업이 수행되는것을 가능하게 해준다. 

4. D3DLOCK_READONLY 
리소스에 절대로 쓰기작업을 하지않는다는 것을 지정한다.

5. D3DLOCK_NOOVERWRITE 
인덱스버퍼, 버텍스버퍼의 데이터에 덮어쓰기를 하지 않는다는 것을 지정한다. 이것은 드라이버가 버퍼를 유지하는 것을 허락하고 사용하지 않으면 드라이버는 Lock 프로세스가 종료되기 전에 렌더링을 종료하는 것을 필요하게 된다. 만일 한 프레임에 버퍼를 추가하기 위하여 여러번 Lock하는 경우 이 Flag가 사용된다. 이것은 한 루프에서 간혹 버퍼에 계속 추가되는 텍스트 렌더링이나 스프라이트를 렌더링할 때 사용되는 테크닉이다. 예로 버퍼가 있고 어떠한 요소를 끝이 될때까지 추가할때 끝이되면 D3DLOCK_DISCARD를 행하고 처음부터 시작한다. (Batching)
반응형

'Game Dev > Scrap' 카테고리의 다른 글

Visual Studio 정규식  (1) 2009.02.02
Crysis Next Gen Effects PPT  (0) 2009.01.07
Debugging Memory Corruption in Game Development  (0) 2008.10.17
Developement Resource on the WEB  (0) 2008.10.07