Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

codingfarm

Direct3D의 초기화 - 장치(Device)와 장치 문맥(Device Context) 생성 본문

computer graphics/DirectX11

Direct3D의 초기화 - 장치(Device)와 장치 문맥(Device Context) 생성

scarecrow1992 2020. 11. 28. 17:38

Direct3D 초기화의 시작은 direct3D 11 장치(ID3D11Device)와 그 문맥(ID3D11Device Context)를 생성하는 것이다. 이 두 인터페이스는 Direct3D의 주된 인터페이스로, 물리적인 그래픽 장치 하드웨어에 대한 소프트웨어 제어기라고 생각하면 될 것이다. 즉, 응용 프로그램은 이 인터페이스들을 통해서 하드웨어에게 할 일(GPU 메모리에 자원 할당, 후면 버퍼 지우기, 자원을 여러 파이프 라인 단계에 묶기, 기하구조 그리기 등)을 지시한다. 좀 더 구체적으로 말하면,

 

1. ID3D11Device 인터페이스는 기능 지원 점검과 자원 할당에 쓰인다.

2. ID3D11DeviceContext 인터페이스는 렌더 대상을 설정하고, 자원을 그래픽 파이프 라인에 묶고, GPU가 수행할 렌더링 명령들을 지시하는 데 쓰인다.

다음은 장치와 장치 문맥을 생성하는 함수이다.

HRESULT D3D11CreateDevice(
    IDXGIAdapter            *pAdapter,
    D3D_DRIVER_TYPE         DriverType,
    HMODULE                 Software,
    UINT                    Flags,
    const D3D_FEATURE_LEVEL *pFeatureLevels,
    UINT                    FeatureLevels,
    UINT                    SDKVersion,
    ID3D11Device            **ppDevice,
    D3D_FEATURE_LEVEL       *pFeatureLevel,
    ID3D11DeviceContext     **ppImmediateContext
);

 

Parameter

1. Adapter

이 함수로 생성할 장치를 나타내는 디스플레이 어댑터를 지정한다. NULL 또는 0을 지정하면 기본 디스플레이 어댑터가 사용된다. 이후 포스팅의 예제 프로그램들은 항상 기본 어댑터를 사용한다.

 

2. DriverType

일반적으로는 렌더링에 3차원 그래픽 가속이 적용되게 하기 위해 이 매개변수에 D3D_DRIVER_TYPE_HARDWARE를 지정한다. 상황에 따라서는 다른 값을 지정하기도 한다.

 

3. Software

소프트웨어 구동기를 지정한다. 이 포스팅에서는 하드웨어를 사용해서 렌더링 하므로 항상 NULL 값을 지정할것이다. 이외의 값으로 지정하기 위해선, 실제로 사용 가능한 소프트웨어 구동기가 있어야 한다.

 

4. Flags

추가적인 장치 생성 플래그들(OR로 결합가능)을 지정한다. 흔히 쓰이는 플래그 2개를 들자면 아래와 같다.

 

(a) D3D11_CREATE_DEVICE_DEBUG

디버그 모드 빌드에서 디버그 계층을 활성화 하려면 반드시 설정해야하는 플래그이다.

 

(b) DRD11_CREATE_DEVICE_SINGLETHREADED

Direct3D가 여러 개의 스레드에서 호출되지 않는다는 보장이 있을 때, 이 플래그를 지정하면 성능이 향상된다. 이 플래그를 지정한 경우 ID3D11Device::CreateDeferredContext의 호출은 실패한다.

 

5. pFeatureLevels

D3D_FEATURE_LEVEL 형식 원소들의 배열로, 원소들의 순서가 곧 기능 수준들을 점검하는 순서이다. 이 매개변수에 NULL 값을 지정하면 지원되는 최고 기능 수준이 선택된다. 이 포스팅은 Direct3D 11을 대상으로 하므로, D3D_FEATURE_LEVEL_11_0이 선택되게 한다.

 

6. FeatureLevels

배열 pFeatureLvels의 D3D_FEATURE_LEVEL의 원소 갯수이다. NULL값을 지정했다면 이 매개변수는 0으로 지정한다.

 

7. SDKVersion

이후 포스팅에선 Direct3D 11대상 이므로 항상 D3D11_SDK_VERSION을 지정한다.

 

8. ppDevice

함수가 생성한 장치를 돌려준다.

 

9. pFeatureLevel

5번 매개변수의 pFeatureLeves 배열에서 처음으로 지원되는 기능을 돌려준다.

 

10. ppImmediateContext

생성된 장치 문맥을 돌려준다.

 

다음은 이 함수의 호출 예이다.

UINT createDeviceFlags = 0;

#if defined(DEBUG) || defined(_DEBUG)
    createDeviceFlags |= D3D11_CREATE_DEBUG;
#endif

D3D_FEATURE_LEVEL featureLevel;
ID3D11Device* md3dDevice;
ID3D11DeviceContext* md3dImmediateContext;
HRESULT hr = D3D11CreateDevice(
        0, D3D_DRIVER_TYPE_HARDWARE, 0,
        createDeviceFlags, 0, 0,
        D3D11_SDK_VERSION, &md3dDevice, &featureLevel,
        &md3dImmediateContext
    );
    
if( FAILED(hr) ){
    MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0);
    return false;
}

if( featureLevel != D3D_FEATURE_LEVEL_11_0 ){
    MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0);
    return false;
}

 


즉시 문맥(Immediate Context)와 지연 문맥(Deferred Context)

앞선 과정에서 생성된 문맥은 즉시문맥(Immediate Context)이다. 하지만 이 이외에 지연문맥(Deferred Context, ID3D11Device::CreateDeferred Context) 이라는것도 있다. 지연 문맥은 Direct3D 11 다중 스레드 지원 구조의 일부이다. 다중 스레드 사용은 고급개념이므로 별도의 포스팅으로 따로 정리하겠다. 기본 개념만 정리하면 아래와 같다.

 

1. 주 렌더링 스레드에는 즉시문맥을 사용한다.

2. 개별 일꾼(worker) 스레드들에서는 임의의 개수의 추가적인 지연문맥들을 사용한다.

   (a) 각 일꾼 스레드는 그리기 명령들을 명령 목록(ID3D11CommandList)에 기록한다.

   (b) 주 렌더링 스레드는 즉시 문맥을 이용해서 각 일꾼 스레드의 명령 목록에 있는 명령들을 실행한다.

명령 목록을 생성하는 데 시간이 걸린다면, 다중 코어 시스템에서 이처럼 명령 목록들을 병렬로 생성함으로써 성능 향상을 꾀할 수 있다.

 

 

Comments