블로그 이미지
차세대 개발 플랫폼인 .NET Framework 4.0 과 Visual Studio 2010 의 정보와 아티클을 제공하는 공식 팀 블로그 입니다. 엄준일(땡초)
« 2010/03 »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      


 
 

[JumpToDX11-11] DirectCompute 를 위한 한걸음!

DirectX 11 | 2010/02/11 09:00 | Posted by 조진현


앞선 시간을 통해서 GPGPU 를 위해서 마이크로소프트가 제공하는 플랫폼이
DirectCompute 라는 것이라고 말씀드렸습니다.
앞으로 DirectX11 을 지원하는 모든 그래픽카드들은 이 DirectCompute 를 지원할 것입니다.
그 이외에도 일부 DirectX10 을 지원하는 그래픽카드들도 지원을 하고 있습니다.


GPGPU 를 위해서 가장 기본적이고 핵심이 되는 기능은 무엇일까요?
저는 GPU 에서 처리된 메모리를 CPU 쪽의 메모리로 보내는 것이라고 생각합니다.
( 이는 개인 의견입니다.^^ )
즉, 그래픽카드에 있는 메모리를 메인메모리로 보내는 작업입니다.
DirectX9 세대까지는 이 작업이 불가능 했습니다.
예를 들면, 그래픽스 파이프라인 중간에 처리된 결과를 다시 가공할 수 있는 방법은
VertexShader 나 PixelShader 같은 쉐이더 스테이지 정도 뿐이였습니다.

하지만 DirectX10 부터는 이들에 대한 중간 결과를 메인메모리로 보내는 기능이 추가되어지면서,
GPGPU 의 시작을 알렸다고 생각합니다.
이 단순한 Copy 작업이 앞으로도 얼마나 유용하게 사용될 수 있을지는 기대가 상당합니다.



< DirectCompute 를 위한 ComputeShader >

DirectCompute 를 위해서 개발자가 할 일은 ComputeShader 를 작성하는 일입니다.
ComputeShader 는 HLSL 이라는 기존 DirectX 의 쉐이더 문법 구조로 작성을 합니다.




HLSL 코드는 DirectX 쉐이더 컴파일러인 FXC 나 API 를 통해서 컴파일 됩니다.
HLSL 은 결국 최적화된 IL 코드를 생성하게 되고,
이 IL 코드를 기반으로 런타임에 각각의 하드웨어에 최적화된 명령어들로 변환
되어져서 실행됩니다.


< GPGPU 에게 실행이란? >

GPGPU 를 활용해서 실행한다는 것은 하드웨어 내부적으로 어떻게 동작하도록 할까요?
앞선 시간에 GPU 는 병렬 처리에 최적화된 많은 SIMD 형태로 구성되어져 있다고 언급했었습니다.
결국 이들은 스레드들의 그룹으로써 실행합니다.
스레드들을 얼마나 많이 생성할 것인지를 개발자가 정해주면, 그에 맞게 연산을 수행합니다.

API 에서는 이들을 큰 그룹으로 나누어 줍니다.
큰 그룹으로 나누어 주는 API 는 ID3D11DeviceContext::Dispatch() 입니다.

ipImmediateContextPtr->Dispatch( 3, 2, 1 );

이렇게 큰 블럭 단위로 나누고 난 후에
ComputeShader HLSL 에서는 이들을 세부적인 스레들로 분할하는 문법을 지정합니다.

[numthreads(4, 4, 1)]
void MainCS( ... )
{
        ....
}




결과적으로 위의 그림처럼 스레드들이 생성되어서 병렬적으로 실행이 됩니다.
위에 나열된 숫자들은 스레드 ID 로써의 역활을 합니다.
즉, 어떤 스레드의 ID 가 MainCS 함수에 파라메터로 넘오오면,
그 ID 를 통해서 해당 버퍼에 값을 작성하게 됩니다.

아래에 간단한 예가 있습니다. 

[numthreads( 256,1,1) ]

void VectorAdd( uint3 id: SV_DispatchThreadID )
{

  gBufOut[id] = gBuf1[id] + gBuf2[id];

}


아무리 스레드들이 복잡하게 동작하더라도, 위와 같이 ID 를 통해서 제어한다면
그 어떤 작업도 문제없이 할 수 있습니다.

일단 먼저 어떻게 DirectCompute 가 실행되어지는지에 대해서 살펴보았습니다.
실행까지 가기 위해서는 일련의 절차를 거쳐야 합니다.
이들에 대해서는 앞으로 차근차근 살펴보겠습니다.



참고 자료
http://microsoftpdc.com/Sessions/P09-16
본 내용은 위의 PDC 를 참고해서 만들었습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

[JumpToDX11-10] GPGPU 를 위한 DirectCompute.

DirectX 11 | 2010/01/27 09:00 | Posted by 조진현


아주 오래 전 컴퓨터에는 GPU 라는 개념이 특별히 존재하지 않았습니다.
그저 화면에 얼마나 많은 픽셀을 나타낼 수 있는가 정도가 그래픽 카드의 성능을 나타내는 기준이였습니다.
그랬던 상황이 오늘 날에 이르게 된 것입니다.( 굳이 자세히 언급할 필요가 없을 것 같습니다.^^ )

오늘날의 GPU 의 성능은 가히 놀라울 정도입니다.
하지만 이런 놀라운 성능을 가진 GPU의 processing unit 들이 대부분의 시간을 놀면서 있다는 것이
우리의 신경에 거슬렸던 것입니다.
그래서 이들에게 일감을 분배시키기 위한 방안을 생각하게 되었고,
이를 배경으로 등장한 것이 바로 GPGPU 입니다.

GPU 를 활용한 일반적인 처리 방식을
GPGPU( General-purpose computing on graphics processing uints ) 라고 합니다.
범용성 있게 GPU 를 활용해서 처리하겠다는 것이지만,
사실 CPU 와 GPU 의 목적은 엄연히 다릅니다.

CPU 는 광범위한 영역에서도 효율적으로 이용될 수 있도록 설계를 된 것이지만,
GPU 는 그래픽 처리를 위한 산술 연산에 특화된 processing unit 입니다.
오늘 날 PC 는 멀티코어 형식이 많아지고 있는 추세인데,
하나의 CPU 는 기본적으로 특정 시간에 하나의 연산만 수행할 수 있습니다.
GPU 의 경우에는 병렬처리 형식에 완전히 특화된 형태입니다.
오늘날 GPU의 코어는 32개라고 합니다.
즉 32개가 연산이 동시에 실행될 수 있다는 얘기입니다.
아래 그림을 한번 보실까요?




GPU 에는 SIMD 라는 것이 굉장히 많은 것을 볼 수 있습니다.
SIMD( Single Instruction Multiple Data ) 라는 것은 병렬 프로세서의 한 종류입니다.
벡터 기반의 프로세서에서 주로 사용되는데,
하나의 명령어를 통해서 여러 개의 값을 동시에 계산할 수 있도록 해줍니다.
( http://ko.wikipedia.org/wiki/SIMD  --> 여기서 참고 했습니다^^ )

벡터 기반이라는 사실에 우리는 주목할 필요가 있습니다.
GPU 는 광범위한 목적으로 설계된 processing unit 이 아닙니다.
즉, GPGPU 를 활용하는 목적은 주로 수치 연산에만 국한된 이야기 입니다.
일반적인 로직으로 GPGPU 를 활용하는 것은 그리 좋은 선택이 아니라는 것입니다.
현재 GPGPU 가 활용되고 있는 영역은 이미지 프로세싱, 비디오 프로세싱, 시뮬레이션 등과 같이
많은 수학 연산이 필요한 영역입니다.
분명한 것은 이들 수치 연산에 국한된 모델이라 할지라도, 그 성능이 무척 매력적이라는 것입니다.

이런 GPGPU 활용을 위해서 마이크로소프트는 어떤 준비물을 가지고 등장했을까요?
그것이 바로 'DirectCompute' 라는 것입니다.^^
아래 그림을 한번 보실까요?



DirectCompute 외에도 친숙한 이름이 보이시나요?
개인적으로 현재 GPGPU 분야에서 가장 앞서 있다고 보여지는 CUDA 가 있습니다.
이것들에 대한 우열을 가리기는 어려운 문제입니다.
여러분이 처한 상황에서 최선의 선택을 하면 되는 것입니다.
그 중에 DirectCompute 도 하나의 선택지일 뿐입니다.
CUDA 도 굉장히 훌륭한 GPGPU 모델입니다.
( 사실 저도 CUDA 를 공부하면서 GPGPU 의 개념을 잡았습니다.^^ )
CUDA 는 제가 지금 언급하지 않아도 될 정도로 많은 정보들이 공개되어 있습니다.

DirectCompute 는 마이크로소프트에서 가지고 나온 GPGPU 모델입니다.
앞으로 OS 의 강력한 지원을 가지고 등장하게 될 것입니다.

사실 GPGPU 와 DirectCompute 는 매우 혼란스럽게 사용될 수 용어들입니다.
그래서 오늘은 이들 두 용어를 확실히 구분하는 것으로 마무리 하겠습니다.^^
다음 시간부터는 DirectCompute 에 대해서 조금씩 살펴보겠습니다.


참고 자료
http://microsoftpdc.com/Sessions/P09-16
본 내용은 위의 PDC 를 참고해서 만들었습니다.
크리에이티브 커먼즈 라이선스
Creative Commons License

[JumpToDX11-9] Multi-threaded Rendering 을 위한 API.

DirectX 11 | 2010/01/11 09:00 | Posted by 조진현



이번 시간에는 Multi-threaded Rendering 을 위한 API 들에 대해서 살펴보겠습니다.
기능 위주의 설명을 위해서 인자들에 대한 명시는 생략했습니다.
이점 주의해주시기 바랍니다.

ID3D11Device::CreateDeferredContext()

가장 먼저 살펴볼 것은 DeferredContext 의 생성입니다.
DeferredContext 는 스레드당 하나씩 생성되어질 수 있음을 앞선 시간을 통해서 언급했습니다.
또한 이 DeferredContext 는 Command List 들을 생성해서 가지고 있습니다.
즉, 렌더링이 가능한 상태라는 것입니다.
그런 기능을 우리는 Device 인터페이스를 통해서 생성합니다.
이것은 역시 Free thread 한 작업이기 때문에 Device 인터페이스를 이용합니다.

하나의 DeferredContext 는 thread-safe 합니다.
즉, 스레드 상에서 DeferredContext 가 관련 Command 들을 기록하는 것은 안전한 작업입니다.

간단한 사용 방법은 아래와 같습니다.
ID3D11DeviceContext* pDeferredContext = NULL;
hr = g_pd3dDevice->CreateDeferredContext(0, &pDeferredContext);


ID3D11DeviceContext::FinishCommandList()

신기하게도 우리는 이 API 호출 한번으로 CommandList 들을 기록하고 생성할 수 있습니다.
API 이름이 Finish 여서 Start나 Begin 계열의 API 를 검색해 보았지만, 없었습니다.^^
각각의 DeferredContext 별로 호출되기 때문에 DeviceContext 의 멤버함수로 되어 있습니다.
앞선 시간을 통해서 DeviceContext 는 ImmeidateContext 와 DeferredContext 로
분리될 수 있다고 언급했었습니다.
두 Context 모두 ID3D11DeviceContext 인터페이스를 사용하기 때문에 오해의 소지가 약간 있습니다.
FinishCommandList 는 DeferredContext 를 위한 API 임을 유념하시기 바랍니다.

간단한 사용 방법은 다음과 같습니다.
ID3D11CommandList* pd3dCommandList = NULL;
hr = pDeferredContext->FinishCommandList( FALSE, &pd3dCommandList );


ID3D11DeviceContext::ExecuteCommandList()

이 API는 DeferredContext 에 의해서 생성된 CommandList 들을 실행합니다.
역시나 ID3D11DeviceContext 의 멤버함수이기 때문에 혼란스러울 수 있습니다.
과연 ImmediateContext 가 이 함수를 호출할까요? 아니면, DeferredContext 일까요?

지난 시간들을 통해서 우리는 실제로 Multi-threaded Rendering 이라는 것은
CommandList 생성을 Multi-thread 기반으로 하는 것이라고 언급했었습니다.
그 이후에 실제 그래픽 카드로의 전송은 하나의 스레드만 할 수 있다고 했었습니다.
바로 그 사실입니다.
이 함수는 ImmediateContext 에 의해서 호출됩니다.
즉, 이 API 는 그래픽 카드로 해당 CommandList 들을 전송하는 것입니다.

간단한 사용 방법은 아래와 같습니다.
g_pImmediateContext->ExecuteCommandList( g_pd3dCommandList, TRUE );


이상 3가지 API 에 대해서 살펴보았습니다.
믿기지 않으시겠지만(?)
Multi-threaded Rendering 작업은 이 세가지 API로 할 수 있습니다.
나머지는 스레드 생성과 제어를 위한 작업이 결합되어야 할 것입니다.
일반적인 스레드 프로그래밍과 관련된 내용이라 이곳에서는 배제를 했습니다.
현재 DirectX SDK Sample 에는 'MultithreadedRendering11' 라는 것이 있습니다.( 2009 August 버전 기준 )
이것과 관련된 소스가 있으니 참고해서 보시면 좋을 것 같습니다.

이상으로 Multi-threaded Rendering 의 기본 개념 설명을 마치고자 합니다.
이 부분과 관련된 내용은 앞으로 정리가 되는대로 추가하거나 수정이 되어질 수 있을 것입니다.
다음 시간부터는 DirectX11 의 다른 주제를 가지고 돌아오겠습니다.^^
 
크리에이티브 커먼즈 라이선스
Creative Commons License

[d3dm 기초] 1. wm6.x 개발환경 세팅

DirectX 11/Direct3d Mobile | 2009/12/26 23:06 | Posted by 도플광어(圖佛光語)

<<연재 일시 중단>>

vs 2010 beta2 가 스마트기기 개발환경을 지원하고 있지 않은 관계로 연재를 일시 중단 합니다. 

미리 확인 하지 않고 연제를 시작한 점 사과드립니다.

차후에 스마트기기 개발환경이 지원되는 대로 다시 하도록 하겠습니다.

1.     들어가며

 

안녕하세요.

저는 이번에 vsts2010에 참여하게 된 이석준 이라고 합니다.

앞으로 잘 부탁 드리겠습니다.

이런 공인된 장소를 글을 쓰는 것은 첨이다 보니 무척 부담이 많이 밀려오는 군요.

혹시 잘못된 부분이나 미흡한 부분이 있으면 바로 지적해 주시면 감사하겠습니다.

(제가 국어가 약해서 가끔 안드로메다틱한 문법이 나올 수도 있으니 이해 안 되는 문장은 반드시 지적을 해주시면 감사하겠습니다. .; )

 

VS상의 윈도우모바일(이하 wm) 개발환경은 리눅스나 기타 임베디드 개발환경에 비해 빠르고, 편리하고, 쉽습니다. 기존의 win32api, .Net 코드를 쓸 수 있음은 물론 WTL,MFC등과도 많은 부분의 코드가 호환이 됩니다. 모바일이나 임베디드 에서는 대부분 3D 랜더러로 opengl-es가 많이 사용되는 것으로 알려져 있습니다.  그러나 게임을 만들 때는 direct3d를 많이 사용합니다. Direct3d Mobile 이하 D3dm 을 사용하면 기존의 Direct3d코드를 그대로 활용할 수 있는 장점이 있습니다.  지금부터 약 10회로 나누어서 wm6상에서의 개발환경부터 오픈소스공개 랜더엔진인  irrlicht3dd3dm용 드라이버까지 제작을 해보도록 하겠습니다.

 

2.     준비물

 

wm6sdk , active sync 두 가지가 필요합니다.

여기서 wm6sdk 은 소프웨어 개발킷 이므로 애뮬레이터와 샘플소스코드는 물론 VS용 라이브러리와 클래스위져드관련 환경파일들이 모두 포함된 형태입니다.

요즘 나오는 옴니아2등의 폰에는 6.1버전이라고 되 있는데요 따로 6.1sdk는 존재하지 않습니다. 검색해보시면 DDK가 나와있는 것을 볼 수 있는데요.

DDK sdk가 다른 점은 DDKVS관련 라이브러리 파일제외하고 에뮬레이터와 샘플소스 각종 유틸리티 툴이 업그래이된 것이라고 보시면 됩니다.

요약하자면 wm6sdk 설치후 원하시는 타겟의 DDK나 에물레이터 image를 받아서 먼저 SDK설치하신 다음에 설치 하시면 됩니다.




만약 특정스마트기기의 특정한 기능을 이용하고 싶으시면 이 위에 다시 해당 기기용 sdk를 설치해서 사용하시면 됩니다.

그러면 특정 스마트기기용 추가 API Set 이 설치됩니다.

 

active sync는 스마트기기와 VS개발환경간의 통신수단을 해주는 역할을 하므로 Sdk를 설치 하기 이전에 이것부터 설치를 해주셔야 합니다.


wm6가 설치된 스마트기기는 기본적으로 이미 설치되 있으니 개발 pc에서 설치를 한번 해주시면 됩니다.

 

3.     Hello wm6!!

 

모든 설치가 순조롭게 끝나고 새프로잭트->스마트기기(Smart Device) 항목이 나온다면 설치가 성공한 것 입니다.

그럼 간단한 프로그램부터 만들어 보도록 하죠. 아래와 같이 Smart Device->Win32 Smart Device Project를 선택합니다


 


그 다음 platforms 탭에서 windows mobile6 sdk를 추가 시켜줍니다.



 

자동 생성된
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 의 WM_PAINT에 아래와 같이 DrawText 함수를 추가 해 줍니다.

프로잭트 위져드 덕택에 자동으로 기본프레임웍까지 코드가 작성되서 나오니 편리 하지 않습니까? ^^;

 기존 데스크탑용 어플처럼 빌드후 실행하면 에뮬레이터로 필요한 파일이 전송된후(Deployment 설정 참고) 크로스 컴파일된 어플리캐이션이 실행됩니다.


 

4.    Deployment

데스크톱 어플개발시와는 다르게 프로잭트 속성 페이지에 Deployment라는 항목이 있습니다.

Additional Files항목에서는 스마트기기에서 어플리캐이션실행시 필요한 파일들을 정의해줍니다. (물론 에뮬레이터도 똑같은 스마트 기기로 추상화 됩니다.)

항목을 만드는 양식은 다음과 같습니다.

원본파일이름|원본파일이 있는 경로|파일이 카피될 원격경로|0

Remote Directory 에는 스마트기기에서 실행파일이 실행될 경로를 정해줍니다. 그러나 주의 할점은 어플상에서 파일을 참조할경우 경로는 여기서 지정해준 원격경로가 아닌 저장장치단위의 최상위디랙토리인 My Device/ 기준으로 경로를 잡게됩니다.

참고로 %CSIDL_PROGRAM_FILES% 는 My Device/Program files를 가리킵니다.

실행파일은 Deployment ->Additional Files에서 추가 하지않고 디버깅->Remote Executable 에 정해진 파일이 원격실행 디랙토리에 자동으로 카피가 됩니다.

5.     to be continued…

      다음에는 샘플로 제공된 basicApp를 분석해 간단한 이미지 뷰어를 만들어 보도록 하겠습니다.

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'DirectX 11 > Direct3d Mobile' 카테고리의 다른 글

[d3dm 기초] 1. wm6.x 개발환경 세팅  (4) 2009/12/26

[JumpToDX11-8] Deferred Contexts

DirectX 11 | 2009/12/02 09:00 | Posted by 조진현

멀티스레드 기반의 렌더링을 위해서 DirectX11 에서는 세가지를 중점에 두었습니다.

- 비동기적으로 자유스러운 리소스 로딩과 관리.
  ( 이들은 렌더링과 동시에 수행될 수 있어야 한다. )

- 멀티스레드 형식으로 렌더링 커맨드의 생성.
  ( 여러 스레드로 나누어서 렌더링 작업을 할 수 있어야 한다. )

- 디스플레이 리스트( Display lists )의 지원.


첫번째 리소스와 관련한 것을 지난 시간에 알아보았습니다.
이제는 실제 렌더링 작업에 대해 알아보아야 합니다.
그 실제 렌더링 작업을 위해서 우리는 새롭게 등장한 Deferred Context 라는 것을 살펴볼 것입니다.
Deferred Context 가 멀티스레드 기반의 렌더링에서 가장 중요한 키워드입니다.

< Device 의 분리 >
지난 세대의 DirectX는 모든 GPU 관련 내용의 처리는 Device 인터페이스를 통해서 수행했습니다.
즉 지난 회들에서 꾸준히 언급했던 것처럼,
Device 인터페이스를 통해서만 커맨드( Command ) 를 생성할 수 있었습니다.



오직 싱글코어 기반으로 설계된 지난 세대의 DirectX 였기 때문에,
위의 그림과 같은 상황이 연출되었습니다.
이들에 대한 내용은 지난 시간을 통해서 꾸준히 언급되었기 때문에, 더 자세한 언급은 하지 않겠습니다.

Device 인터페이스에 모든 작업이 집중되어 있었기 때문에,
이를 분리할 방법이 필요했습니다.
그 기준은 앞서 언급했듯이, 
그래픽카드에 보내는 작업이 Free threaded 한지였습니다.
결론적으로 얘기 드리면 DirectX11 에서는 기존의 Device 가 분리에 분리를 거듭했습니다.
그래서 아래와 같은 구조로 되었습니다.





DirectX11 에서 이제 개발자가 다루어야하는 커맨드 생성 인터페이스는 총 3가지입니다.
Device 는 Free threaded 한 API 만 사용하는 인터페이스입니다.
주로 리소스들이 포함됩니다.( 버퍼나 텍스쳐, 쉐이더 등 )

Device Context 는 실제로 렌더링과 관련된 인터페이스입니다.
렌더스테이트의 교체나 Draw 명령을 내리기 위해서는
반드시 Device Context 를 통해서 커맨드를 생성해야 합니다.
더 자세한 사항은
http://vsts2010.net/115 여기를 보시기 바랍니다.^^

Device Context 는 다시 두개로 분리될 수 있습니다.
Immediate Context 와 Deferred Context 가 바로 그것들입니다.

만약 멀티스레드 기반으로 렌더링 하고 싶지 않다면,
Deferred Context 는 사용하지 않으셔도 됩니다.
Deferred Context 의 유무가 바로 멀티스레드 기반의 렌더링이냐,
아니면 일반적인 렌더링이냐를 결정
합니다.
반면에 Immediate Context 는 반드시 한개만 존재해야 합니다.
이 인터페이스는 실제로 렌더링과 관련된 커맨드를 생성하기도 하지만,
생성된 커맨드를 그래픽 카드로 보내는 일
도 합니다.

< Deferred Context >

Deferred Context는 애플리케이션에서 여러개 생성될 수 있습니다.
하나의 스레드에 하나씩 Deferred Context 가 사용될 수 있으며, 이들은 Thread unsafe 합니다.
이렇게 하나의 스레드에 할당되어진 Deferred Context는 Display List 를 생성합니다.
이들은 GPU 가 바로 처리 가능한 커맨드들을 모아둔 버퍼라고 할 수 있습니다.
이렇게 Display List 를 미리 만들어둠으로써 성능을 크게 개선 시킬 수 있습니다.
일반적으로, CPU 가 커맨드를 생성시키는 시간이 꽤 오래 걸리기 때문입니다.
( 생성될 커맨드가 변화가 없다면, 이렇게 미리 만들어 두면 크게 도움이 되겠죠? ^^ )


사실 위의 그림은 개념적인 것입니다.
실제 소스레벨에서 Deferred Context 를 가리키는 인터페이스는 별도로 존재하지 않습니다.
Immediate Context 를 가리키는 인터페이스는 ID3D11DeviceContext 입니다.
Deferred Context 를 가리키는 인터페이스도 ID3D11DeviceContext 입니다.
즉, 둘 다 동일한 인터페이스를 통해서 처리되고 있는 것입니다.
실제 멤버 변수 선언들을 조금 나열해 보면 다음과 같습니다.

ID3D11Device*      m_ipGPU;
ID3D11DeviceContext*    m_ipImmediateContext;
ID3D11DeviceContext**  m_ippDeferredContextArray;

동일한 인터페이스 선언을 확인하셨습니까?
하지만 인터페이스가 동일하다고 해서, 이를 동일하게 생각해서는 안됩니다.
동일한 인터페이스를 사용하는 이유는
Deferred Context 는 Immediate Context 의 모든 기능을 지원한다는 의미로 받아들여야 합니다.
결과적으로 Device Context 는 아래의 그림과 같은 구조로 확장될 수 있습니다.




멀티스레드 기반으로 렌더링을 한다는 것은 엄밀히 말해서는 지원하지 않습니다.
정확히 말하자면, 멀티스레드 기반으로 커맨드를 생성해서
이들을 순차적으로 그래픽 카드로 보냅니다.

위의 그림이 이를 잘 표현하고 있습니다.

Deferred Context 는 각각의 스레드에 의해서 DisplayList 를 생성하고,
이들을 그래픽 카드에 보내기 위해 버퍼에 저장합니다.
그리고 실제로 그래픽카드에 커맨드를 보내기 위해서는
반드시 Immediate Context 를 통해야 합니다.
이때 Immediate Context 를 통해서 직접적으로 커맨드를 생성시킬 수 있습니다.

아무래도 렌더링이라는 작업은 순간순간의 렌더링 상태들에 의해서
결과가 변하기 때문에, 최종적으로 전송하는 작업만큼은 순차적으로 설계한 듯 합니다.
이로써 우리는 Deferred Context 를 사용할 준비가 되었습니다.^^



크리에이티브 커먼즈 라이선스
Creative Commons License

[JumpToDX11-7] 간편해진 리소스 처리.

DirectX 11 | 2009/11/18 15:00 | Posted by 조진현


이번 회의 설명을 위해서 API 를 다음과 같이 크게 나누어 보았습니다.

·        Thread unsafe API

·        Thread safe API

·        Free threaded API


Thread unsafe 한 경우에는 멀티스레드들이 동시에 호출할 수 있지만,
이들에 대한 안정성에 대해서는 전혀 보장하지 않습니다.
결과가 갑자기 이상할 수도 있고, 예측 불가능한 상황을 연출할 수도 있습니다.
주로 즉시즉시 상황을 만들어야 할때 사용될 수 있을 것입니다.

Thread safe 한 API 는 어떤 동기화 모델에 의해서 API 가 보호되어집니다.
여러 스레드에서 API 를 호출하더라도, 그들의 안정적인 동작을 보장한다는 의미입니다.
동기화 작업이 별도로 있기 때문에 느려질 수 있다는 단점이 있습니다.

Free threaded 한 API 는 여러 스레드에서 호출을 하더라도,
어떠한 동기화 모델 없이도 API 가 안정적으로 동작한다는 것을 의미합니다.
그렇기 때문에 아주 높은 성능 향상을 얻을 수 있습니다.

< 기존의 리소스 처리 >

멀티스레드 기반의 렌더링으로 가는 첫번째 길은 리소스 부분입니다.
PC 가 발전하면서 성능적으로나 용량적으로 많은 발전을 거듭했습니다.
더블어 게임에서 사용되는 리소스의 용량도 크게 증가했습니다.

멀티스레드 처리가 어느 정도 자리를 잡으면서,
현재 많은 게임들은 이들 리소스에 대한 처리를 별도의 스레드에서 처리하기도 합니다.




일반적인 텍스쳐 로딩 상황을 한번 가정해 보았습니다.
가장 먼저 로더 스레드가 특정한 파일을 읽습니다.
읽어둔 파일을 바탕으로 실제 메모리를 할당하기 위해서는 결국 Device 인터페이스를 통해야 합니다.
DirectX 에서 리소스 관련 메모리를 할당하는 것은
Device 인터페이스를 통해서만 가능하기 때문입니다.
커맨드(Command) 를 생성하는 권한은 오직 Device 인터페이스만이 가지고 있습니다.
( 지난 회를 참고하시기 바랍니다. )

멀티스레드 기반으로 리소스를 로딩하고 있지만,
실제로는 많은 부분이 메인스레드( 여기서는 Render Thread )에 의존하여 작업이 수행되고 있습니다.
리소스를 생성하기 위해서는 반드시 Create, Lock & Unlock 작업이 필요합니다.

< 여기서 잠깐...>
사실 위의 그림의 경우에는 일반적으로 사용되는 구조로 보기 어렵습니다.
그림은 거의 순차적인 처리 구조이기 때문에,
이런 경우라면 굳이 저렇게 사용할 필요가 없습니다.
실제로 많은 게임들은 텍스쳐가 아직 로딩 중이라면,
Default-Material 을 적용해서 폴리곤을 렌더링하도록 구현하기도 합니다.
즉, Render Thread 가 쉴새 없이 계속 커맨드를 생성하는 구조입니다.^^
그리고 위의 예는 간단한 설명을 위한 것입니다.
개발자분들마다 개성 강한 여러 방법들이 존재하시겠죠? ^^

 

 < 간편해진 리소스 관련 커맨드 생성 >

우리가 DirectX 에서 사용하는 대부분의 리소스 작업은 사실 Free Threaded 합니다.
리소스 처리를 위해서 특별한 동기화 처리가 API 레벨에서는 필요하지 않습니다.
( 개발자의 몫입니다. )
그런데 위의 그림처럼 그 동안은 커맨드를 생성해주는 인터페이스가 오직 하나였기 때문에
메인 스레드에 의존해서 처리할 수 밖에 없었습니다.

두번째 시간에 저는 Device와 DeviceContext 에 대해서 설명을 드렸습니다.
기억이 나지 않으시는 분들은 다시 살펴보시기 바랍니다.^^
요약해드리자면, DirectX11 에서는 Free threaded 한 API 와 그렇지 않은 API 들을 분리했습니다.
Free threaded 한 부분에 바로 리소스 처리가 있습니다.
앞서 우리는 Free threaded 의 이점에 대해서 짧게 언급했었습니다.

위의 그림에서,
이제는 Loader therad 는 굳이 메인 스레드( Render thread ) 에 의존하지 않아도,
순차적으로 리소스 관련 커맨드들을 생성시킬 수 있습니다.
커맨드들이 생성되는 순서는 Free threaded 한 경우에는 중요하지 않기 때문에,
빠른 속도로 처리
할 수 있습니다.
특히나, 메인스레드가 별도로 다른 작업을 수행해서 커맨드를 생성시키는 작업이 있다고 해도,
그것과는 별도로 커맨드 생성 작업을 수행할 수 있습니다.
( 커맨드 생성을 위한 대기 시간이 짧아졌다고 할 수 있습니다. )
이로써, 이제는 조금 더 멀티스레딩 형식에 가까워졌다고 할 수 있습니다.

리소스 처리를 이렇게 분리하는 것은
멀티스레드 기반으로 렌더링으로 가는 중요한 기반을 제공
해 주었습니다.

< 다음 회에서는.... >
다음 회부터는 이제 멀티스레드 기반으로 렌더링 관련 커맨드를 생성하는 것을 살펴볼 것입니다.


크리에이티브 커먼즈 라이선스
Creative Commons License

[DX11_#4]텍스트, 버튼 출력

DirectX 11 | 2009/11/10 22:08 | Posted by simon882


 DX9에서 DXUT라는 것은 SDK의 소스에서 그리크게 눈에 띄지 않았습니다.
DXUT라는 것은 DX에서 제공하는 프레임 워크라고 생각하시면 됩니다.
DX11의 모든 예제들이 DXUT를 이용해 작성이 되어있기 때문에 기본적인 구조를 익혀두시는 것이 좋습니다.
함수명만 보아도 함수의 용도를 한눈에 알 수 있기 때문에 보시는데 어려움은 없으실 것 입니다.

void InitApp()
{
    g_SettingsDlg.Init( &g_DialogResourceManager ); // 디바이스 Setting Dlg 초기화
    g_HUD.Init( &g_DialogResourceManager );  // Dlg기본 컨트롤 초기화
    g_SampleUI.Init( &g_DialogResourceManager );

    g_HUD.SetCallback( OnGUIEvent );   // 컨트롤 콜백함수 등록
    int iY = 30;
    int iYo = 26;
     아래와 같이 버튼 추가하고 버튼을 클릭하면 'OnGUIEvent'함수의 case문에서 해당하는 함수를 호출합니다.
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 0, iY, 170, 22 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 0, iY += iYo, 170, 22, VK_F3 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 0, iY += iYo, 170, 22, VK_F2 );

    g_SampleUI.SetCallback( OnGUIEvent );
    iY = 10;
}

void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
    switch( nControlID )
    {
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); // 전체화면, window모드 간의 toggle
            break;
        case IDC_TOGGLEREF:
            DXUTToggleREF();   // HAL과 reference device types 간의 toggle
            break;
        case IDC_CHANGEDEVICE:
            g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); // 디바이스 변경
            break;
    }
}


 이전과는 확연하게 다른 방법으로 텍스트를 출력하고 있습니다.
DX9에서 사용하던 'CD3DFont'를 사용하지 않고, 'CDXUTTextHelper'를 사용해 생성한 변수로 화면에 텍스트를 출력합니다.

[DX9]
CD3DFont* pFont;
pFont->DrawText( X, Y, color, str );


[DX11]
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 5, 5 ); // 출력 위치
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); // 폰트 색상
   
     아래와 같이 'DXUTGet'으로 시작되는 함수들을 이용해 여러가지 정보를 얻어올 수 있습니다.
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) ); // FrameStats출력
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );    // Device state출력
    g_pTxtHelper->DrawTextLine( L"Font Test" );      // 기본적인 텍스트 출력
    g_pTxtHelper->End();
}

이런 작업들을 거치면 아래와 같이 화면에 간단한 디바이스 정보와 버튼을 출력할 수 있습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

[JumpToDX11-6] 커맨드(Command)...

DirectX 11 | 2009/11/09 15:00 | Posted by 조진현


앞서 제 개인적인 판단에 DirectX11 의 큰 특징을 3가지 언급했었습니다.
( 테셀레이션, Compute Shader, Multi-threaded-rendering )
저는 이 세가지 중에서 멀티스레드 기반의 렌더링에 대해서
앞으로의 시간동안 글을 전개해 나갈 생각입니다.


< 커맨드를 생성하는 일 >


혹시 '커맨드(Command)' 라는 개념에 대해서 기억이 나시나요?
기억이 나지 않으신다면,
 [JumpToDX11-2]DeviceContext...넌 누구냣!! 편을 다시 읽어보시기 바랍니다.
요약을 해보자면,
API 를 통한 호출은 결국 하드웨어가 인식할 수 있는 커맨드 형태로 전달되어지게 됩니다.



지난 세대의 DirectX 는 이 모든 처리를 하나의 인터페이스를 통해서 처리했었습니다.
즉, 커맨드를 생성할 수 있는 인터페이스가 오직 하나였습니다.
그리고 그렇게 저장된 커맨드들을 그래픽카드는 순차적으로 실행만 합니다.

이를 멀티스레드 기반으로 처리하기 위해서는 사실 굉장한 노력을 해야합니다.
더 어려운 것은 멀티스레드 기반으로 처리 노력을 기울인다고 해도,
성능 향상에 대한 보장은 장담할 수 없습니다.
일반적으로 로직처리는 멀티스레드 기반으로 분산해서 처리하고는 있지만,
렌더링과 관련된 부분은 이러한 처리가 굉장히 어렵습니다.
( 렌더 스레드의 실행 중간에 렌더링 스테이트가 변하면 문제가 크겠죠? )

그래서 지난 세대의 DirectX 는 이러한 커맨드를 생성하는 부분은
단, 하나의 경로를 통해서만 가능했습니다.
그 동안 우리가 사용했던 IDirect3DDevice9 같은 인터페이스가 바로 이러한 역활을 했었습니다.
이 인터페이스는 실제로 API 를 통해서 하드웨어에게 명령 수행을 지시한다는 의미보다는,
API 를 하드웨어가 이해할 수 있는 커맨드로 변환해 주는 것에 더 가깝습니다.
그리고 그 커맨드를 통해서, 실제로 하드웨어가 실행
을 할 것입니다.

그런데 바로 이 커맨드를 생성하는 일, 누가 해주는 것일까요?
하드웨어가 이해할 수 있는 커맨드들은 드라이버( Driver )가 알고 있습니다.
드라이버는 Core API 나 런타임과 통신을 합니다.

"텍스쳐를 로딩해주세요~"
"메모리를 생성해주세요~"
"렌더링 스테이트를 설정해 주세요~"
"비디오 메모리에 리소스를 바인딩 시켜주세요~"

뭐 이런 식으로 API 를 사용하면,
이들과 관련된 커맨드를 생성하기 위해서 누군가 바쁘게 움직여줘야 할 것입니다.
그것은 바로 'CPU'
겠죠?

실제로 우리가 생성하는 커맨드들 이외에도 처리에 필요하면 커맨드가 더 많이 생성될 수도 있습니다.
예를 들면, 비디오 메모리가 가득찬 상태에서 어떤 리소스를 로드한다면
상황에 맞게 특정 리소스를 비디오 메모리에서 제거해야 합니다.
결국 커맨드들의 실행 중간에,
DirectX 의 리소스 매니져에 이를 요구할 수 있는 커맨드들이 생겨져서 더 붙여질 수도 있습니다.
만약 이런 경우라면, 처리 시간이 더 길어지게 되며,
뒤에 있는 커맨드들의 대기시간도 더 길어지게 됩니다.
전체적으로 작업 시간이 지연되는 것이죠.



< 멀티코어의 시대 >

바야흐로 멀티코어시대의 시대입니다.
이제는 CPU 의 성능적인 발전은 정체되었고,
PC 에 탑재되는 CPU 의 갯수가 성능을 좌우하는 시대입니다.

지금까지의 DirectX 는 싱글코어 기반으로 설계되었다고 지난 회에 언급했었습니다.
CPU 의 성능 발전이 지속적으로 상승 곡선을 그렸다면,
아마 렌더링을 멀티스레드로 할 위험(?)은 피할 수 있었을지도 모릅니다.^^

그 동안 DirectX 팀이 최적화 작업을 한다는 것은
API 호출에 대한 오버헤드를 줄이는 것이 가장 큰 일 중에 하나였습니다.
되도록이면 적은 CPU 사이클을 통해서 커맨드를 실행하게 하려고,
정말이지 많은 노력들을 해왔습니다.

그런데 CPU 가 여러개 탑재되고, GPU 가 발전하면서
놀고 있는 CPU 가 생겨나기 시작했고,
GPU 도 많은 시간을 놀면서 지내기 시작했습니다.
그래서 이들에 대한 활용에 대안으로 등장한 것이 바로
멀티 스레드 기반의 렌더링 작업과 Compute Shader 입니다.
멀티스레드 기반의 렌더링은 CPU 에게 렌더링 작업을 분산시키는 것이고,
Compute Shader 는 GPU 를 CPU 처럼 활용하는 것입니다.

제가 앞으로 언급할 것이 바로 멀티스레드 기반으로 렌더링하는 것입니다.
즉, CPU를 활용하는 것으로 볼 수 있습니다.
앞서 렌더링을 멀티스레드로 하는 것은 굉장히 위험한 일이라고 제가 언급했었는데,
이것이 어떻게 가능하냐구요?
네, 맞습니다.
사실 이것은 틀린 말입니다.
정확히는 커맨드를 멀티스레드 기반으로 생성하는 것이 
바로 멀티스레드 기반의 렌더링의 핵심
입니다.


< 다음 회에는... >
이번 시간에 커맨드에 대한 개념을 확실히 잡으셨는지 모르겠습니다.
다음 회 부터는 멀티스레드여서 행복(?)한 부분들을 하나씩 살펴보겠습니다.^^


 
크리에이티브 커먼즈 라이선스
Creative Commons License

[JumpToDX11-5] 새로운 시대를 여는 DirectX11...

DirectX 11 | 2009/11/02 15:00 | Posted by 조진현


한주만 쉰다는 것이, 죄송스럽게도 긴 휴식을 가지고 다시 등장습니다.
지난 시간까지 DirectX11 의 기본 API 를 간단히 언급했었습니다.
쉬는 사이에 안승근님께서 DirectX11과 관련된 기본적인 API 에 대한 글을 작성하기 시작하셨기 때문에
앞으로 기본적인 API 위주로 내용을 언급하지 않습니다.


< DirectX9 까지의 특징 >

DirectX는 Windows95 운영체제와 함께 처음 공개된 후에, 
어느덧 현세대까지 발전을 거듭했습니다.( 세월 참 빠르죠? ^^ )

너무 오랜 시간 전은 저도 잘 몰라서 DirectX7 버전부터의 가장 큰 변화를 하나씩 언급해 보겠습니다.
DirectX7 버전부터 변환과 라이팅(T&L) 을 위한 GPU가 활용되기 시작했고,
DirectX8 버전부터는 'Shader' 라는 GPU 를 활용한 프로그래밍이 도입되어서
현재 가장 개발자에게 주목받는 영역이 되었습니다.
개인적인 견해차이가 있겠지만, 저는 DirectX9 까지의 발전 과정 중에
가장 큰 변화로 바로 이 'GPU 의 활용'
이라고 생각하고 있습니다.

그러면 DirectX9 까지의 발전에서 변심(?)하지 않고,
저희를 언제나 반갑게(?) 맞이해 주었던 부분은 어떤 것이 있을까요? ^^
그것은 바로 API 를 설계할 때 항상 싱글 코어를 고려하고 만들었다는 것입니다.

또 다른 부분은 API 자체가 GPU 의 정점 처리 기능을 규정하고 있다는 것입니다.
언제나 '정점입력-->래스터라이즈-->픽셀처리-->디스플레이' 라는 큰 단계를
API 레벨에서 정의하고 있었습니다.
그 동안 우리는 이것은 Fixed pipeline 이라고 불렀습니다.
아래 이미지는 DirectX8 & 9 의 파이프라인입니다.



이미지 출처 : http://pc.watch.impress.co.jp/docs/column/kaigai/20090804_306876.html

사실 DirectX8 & 9 는 크게 차이가 없습니다.
파이프라인상에서 굳이 찾아야 한다면, 텍스쳐 메모리를 버텍스 쉐이더 단계에서도
참조할 수 있다는 정도일 뿐입니다.

간단히 제가 하고 싶은 말을 정리해 보자면,
'싱글코어 기반의 DirectX 의 시대는 이제 역사의 뒤로 사라지게 될 것이며,
GPU 는 더욱 복잡한 기능을 요구하게 될 것이다'
정도로 정리하겠습니다.
( 예언은 아니고, 이미 이렇게 되고 있는 상황이죠..^^ )


< 새로운 시대를 여는 DirectX11 >

아래는 DirectX11 의 파이프라인입니다.
잘 보시라고 그냥 크게 띄웁니다..^^


이미지 출처 : http://pc.watch.impress.co.jp/docs/column/kaigai/20090804_306876.html


DirectX11 의 가장 큰 특징을 저는 크게 3가지로 나누어 보았습니다.
  • GPU Tessellation.
  • Compute Shader.
  • Multi-threaded rendering.

사실 DirectX11 의 많은 부분은 X-Box360 에서 이미 사용되고 있습니다.
X-Box360 의 ComputeShader 지원은 모르겠으나, 나머지 두가지는 지원하고 있습니다.
X-360을 언급한 이유는 이들 기능이 이미 어느 정도 검증을 받은 기능이라는 점을 강조하고 싶어서 입니다.
( 물론 최신 버전이기 때문에 더 빨라지고, 더 좋아진 부분이 많습니다.^^ )

DirectX11 의 큰 패러다임은 '놀지마' 입니다.
이제는 멀티코어(CPU)와 GPU에게 최대한 많은 일을 시킬 수 있는 구조로
하드웨어를 구성했고, 그것을 기반으로 해서 런타임과 API 를 설계
하고 만들었습니다.

DirectX9 까지는 API 가 변화를 주도했다면,
이제는 DirectX API 변화를 하드웨어가 주도하고 있다고 볼 수 있습니다.
그러다보니 자연스럽게 API 도 더욱 하드웨어에 가깝게 설계되었습니다.
대표적으로 OutputMerge 를 지칭하는 OMxxxx 계열과
InputAssembler 를 지칭하는 IAxxxx 계열 등이 있습니다.

혹시 DirectX8-->9 로 포팅 작업을 하셨던 분들이 이 글을 읽으시는지 모르겠습니다만,
8-->9 의 변화는 API 차원에서 변화가 컸기 때문에 매우 단순했습니다.
하지만 이제는 하드웨어가 크게 변했기 때문에,
단순 포팅 작업 정도로 생각하시면 큰 오산입니다.
물론 단순히 API 만 교체해도 성능 향상을 얻을 수 있습니다.
DirectX11 은 하드웨어 오버헤드를 줄이기 위해 많은 최적화 작업을 수행했다고 합니다.

새로운 DirectX 의 시대가 왔다는 느낌이 드시나요? ^^

크리에이티브 커먼즈 라이선스
Creative Commons License

'DirectX 11' 카테고리의 다른 글

[DX11_#4]텍스트, 버튼 출력  (0) 2009/11/10
[JumpToDX11-6] 커맨드(Command)...  (0) 2009/11/09
[JumpToDX11-5] 새로운 시대를 여는 DirectX11...  (6) 2009/11/02
[DX11_#3]기본적인 설정  (0) 2009/10/22
[DX11_#2]D3D Buffer( 2 / 2 )  (0) 2009/10/13
[DX11_#1]D3D Buffer( 1 / 2 )  (0) 2009/09/22

[DX11_#3]기본적인 설정

DirectX 11 | 2009/10/22 23:58 | Posted by simon882

 DirectX SDK(August 2009)에 포함된 'EmptyProject11'을 기준으로 기본 적인 DirectX세팅에 대해서 설명 하겠습니다.

 아래와 같이 DXUT의 일반적인 설정을 하면 상황에 이벤트에 따라 해당 함수를 호출합니다.
키보드가 눌리면 Onkeyboard가 호출되고, DXUTCreateDevice로 디바이스를 생성하면 'ModifyDeviceSettings'함수가 호출되는 등 기본적으로 필요한 골격을 제공하고 있습니다.

DXUTSetCallbackFrameMove( OnFrameMove );
DXUTSetCallbackKeyboard( OnKeyboard );
DXUTSetCallbackMouse( OnMouse );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackDeviceRemoved( OnDeviceRemoved );

 DX9까지는 DX에 디파인된 버젼으로 어플리케이션에서 실행이 가능한 버젼인지 체크 후 버젼이 맞지 않으면 프로그램을 종료해 버렸습니다.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
     return E_FAIL;

 그러나 아래와 같이 초기화를 하면 어렵지 않게 각 버젼에 대해 깔끔하게 처리가 가능합니다.
여러개의 버젼을 세팅하는 것에 대해 저처럼 의아하게 생각하시는 분도 계실 것 입니다.
그러나 그저 DX9과 DX11을 같이 소스에 위치를 시키면, 하위 버젼에 대한 것들은 모두 알아서 삭제되고,
DX11의 콜백은 정상적으로 설정이 됩니다.(위 아래 순서를 바꿔도 상관 없이 이와 같이 동작 합니다.)

DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );

DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable );
DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice );
DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain );
DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender );
DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain );
DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice );

 첫번째 인자를 true로 설정하면 커맨드를 설정해 아래와 같은 기능을 사용 할 수 있습니다.
(각 버젼에 특화된 커맨드도 몇 가지 있습니다.)
'-fullscreen'=> 전체화면으로 설정
'-width:800 -height:600' => AppWindow의 넓이, 높이를 800x600으로 설정
(이 커맨드를 설정하면 DXUTCreateDevice의 화면 사이즈는 무시됩니다.)
 두번째 인자는 에러 메세지 박스 출력
 세번째 인자는 여분의 커맨드라인 파라메타세팅(default:NULL)
DXUTInit( true, true, NULL );

첫번째 인자가 true이면 전체 화면 모드에서 커서가 보이도록 설정.
두번째 인자가 true이면 전체 화면 모드에서 커서가 화면을 벗어나지 못하도록 설정.
(테스트 했을때 두개의 인자 모두 true와 false일때의 차이점을 느끼지 못했습니다.)
DXUTSetCursorSettings( true, true );

설정한 타이틀로 윈도우 생성
DXUTCreateWindow( L"EmptyProject11" );

 '하드웨어 레벨10'으로 디바이스를 생성
(Feature level관련은 조진현님의 글을 참고하시기 바랍니다.)
두번째 인자가 true이면 윈도우모드, false이면 풀스크린모드 입니다.
(테스트 했을때 false일때도 풀스크린 모드로 변경이 되지 않았습니다.)
세번째, 네번째 인자로 화면의 넓이 높이를 설정할 수 있습니다.
DXUTCreateDevice( D3D_FEATURE_LEVEL_10_0, true, 640, 480 );

DXUT 메인루프 실행
DXUTMainLoop();

 리턴되는 값으로 D3D초기화, 디바이스 상태 등을 알 수 있습니다.
'0'이면 정상이고, 그 이외의 값일경우 DX help파일에서 에러 내용을 확인하시기 바랍니다.
DXUTGetExitCode();

샘플을 실행하면, 예상대로 그저 윈도우안에 세팅된 타이틀과, 파란 화면만 덩그라니 출력됩니다.

첫 샘플 분석이기 때문에 최대한 간단한 함수까지 설명을 적었습니다.
다음 글 부터는 특이사항이 없는한 이번에 설명했던 함수에 대해서는 넘어가도록 하겠습니다.

 DXUTSetCursorSettings, DXUTCreateDevice함수의 설명과 테스트 결과가 다른 이유는 DirectX Help의 설명을 적었으나 테스트 결과 문서대로 동작하지 않았던 것 입니다.
 문제가 있는 것이 맞다면 다음 버젼에는 수정될 것으로 예상됩니다.

다음 글은 좀 더 화면에 보이는 것이 많은 것으로 올리도록 하겠습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License

'DirectX 11' 카테고리의 다른 글

[JumpToDX11-6] 커맨드(Command)...  (0) 2009/11/09
[JumpToDX11-5] 새로운 시대를 여는 DirectX11...  (6) 2009/11/02
[DX11_#3]기본적인 설정  (0) 2009/10/22
[DX11_#2]D3D Buffer( 2 / 2 )  (0) 2009/10/13
[DX11_#1]D3D Buffer( 1 / 2 )  (0) 2009/09/22
[JumpToDX11-4] ID3D11View  (0) 2009/09/07