반응형

Debugging D3D 응용 프로그램은 상당히 고통스럽겠지만 만약 당신이 D3D 응용 프로그램에서 무슨 일이 일어나고 있는지 알기를 원한다면 이 설정은 필수적인 것이다(에러 코드는 Debug Output 없이 많은 정보를 제공하지 않는다).


그러나, 상황이 Windows(8.1), Visual Studio(2013), DirectX(11.2)의 최신 버전에서 최근에 상당히 많이 변경되었다.


변경점에 대한 내용 링크 >> https://blogs.msdn.microsoft.com/chuckw/2013/02/26/directx-11-1-and-windows-7-update/


다음 동영상은 D3D Debugging, DirectX Control Panel, 모든 새로운 기반 구조 작업에 대한 방법과 관련된 변경 사항 중 일부를 설명한다.


(PPT 슬라이드 형식으로도 볼 수 있다. >> https://view.officeapps.live.com/op/view.aspx?src=http%3a%2f%2fvideo.ch9.ms%2fsessions%2fbuild%2f2013%2f3-141.pptx)

동영상이자 원문 링크 >> http://graphicdna.blogspot.kr/2013/10/directx-control-panel-and-d3d-debug.html


DirectX의 기능 중 일부는 더 이상 DirectX SDK와 함께 배포되지 않는다는 것을 명심해야한다. 하지만 그것들은 Windows SDK와 함께 배포된다. 그래서 우리는 D3D에서 디버그 출력을 활성화하려고 할 때 직면할 수 있는 모든 가능한 경우를 커버하려고 한다.

  1. DirectX SDK(June 2010)과 Windows7에서 작업하는 경우
  2. Windows7 or Windows8에 있는 Windows SDK를 사용하는 경우
  3. Windows8.1과 거기에 속한 Windows SDK를 사용하는 겨우

새로운 DirectX Control Panel

DirectX Control Panel을 이용하면 D3D Debug를 활성화하고 다른 것들을 관리할 수 있는데 우선은 DirectX SDK(June 2010) Version의 Control Panel과 Windows SDK Version의 Control Panel을 구별하는 법을 배워야 한다.


이것은 아주 쉬운데 : 새로운 버전의 DirectX Control Panel은 단 하나의 탭만을 포함하고 있다(Direct3D 10.x/11.x):

DirectX SDK(June 2010) Version

Control Panel

Windows SDK Version

Control Panel

imageimage
Location:Location:

C:\Program Files (x86)\

Microsoft DirectX SDK (June 2010)\

Utilities\bin\x64 (or x86)

C:\Windows\System32

D3D 10.x 나 11.x로 개발을 할 때는 이전의 버전의 Control Panel으로는 아무런 효과가 없을 것이기 때문에 새 버전의 Control Panel을 사용해야 한다.

여전히 D3D9과 DX SDK 2010으로 개발하려고 한다면 이전 버전의 Control Panel을 사용하면 된다.


Note

"Feature Level 제한"과 같은 패널의 새로운 기능을 배우려면 위의 동영상을 참조하라.


Windows7

D3D 9.x

만약 여전히 D3D9으로 개발을 하려고 한다면, 솔직히 말해서 새로운 버전을 사용하는 것을 심각하게 고려해보기를 바란다. 하지만 그렇게 할 수 없는 경우라면, 응용 프로그램에서 Debug를 활성화 해야한다. 위에서 설명했던 DX SDK 2010 버전의 Control Panel을 사용하고, Direct3D 9 탭에서 "Use Debug Version of Direct3D 9"을 찾아서 선택하고, Debug Output Level을 "More" 쪽으로 움직여야 한다.


다음의 이미지처럼 :

image

 

DirectX 라이브러리의 Debug 버전을 사용하도록 DirectX 응용 프로그램을 강제해야 한다. 그래서 바로 Visual Studio에서 Debug Output을 보기 시작해야 한다.

Managed D3D9 applications (SlimDX, SharpDX 및 유사한 wrappers)

만약 C#을 이용해서 개발하는 경우에는, Visual Studio에서 기본 프로젝트 속성의 Debug 탭에서 "Enable native code debugging" 플래그를 활성화해야 한다는 것을 명심해야 한다. 그렇지 않으면 기본 디버그 출력을 출력 창을 통해서 얻을 수 없게 된다.

image

 

D3D 10.x / 11.x

Important Note

D3D 10.x와 11.x의 Debugging용 필수 구성 요소는 더 이상 이전의 DirectX SDK(June 2010)과 함께 설치되지 않는다. D3D 10.x와 11.x의 Debugging용 필수 구성 요소를 설치하기 위해 (Win7이 있는 경우에도) Windows 8 SDK를 설치해야 한다. 필수 구성 요소를 얻지 못한 경우에는 "debug" 플래그 장치의 생성에 실패한다(자세한 정보는 아래를 참조). 구성 요소를 가지고 있는지 확인하는 쉬운 방법은 C:\Windows\System32에 새로운 DX Control Panel이 있는지 확인하는 것이다. 해당 경로에 "DXCpl.exe" 파일이 있는지 확인하면 된다.


D3D 10.x/11.x에서의 Debug Output을 활성화사는 법은 조금 다르다. 설정은 응용 프로그램 별로 해야한다(Control Panel의 목록에 exe를 추가하고, 거기에 대한 특정 구성을 설정해야한다). 다음을 따라하면 된다.

  1. 새로운 DirectX Control Panel을 열고 Direct3D 10.x / 11.x 탭으로 이동한다.
  2. DX panel으로 컨트롤하고자 하는 응용 프로그램의 목록에 exe파일을 추가하기 위해 "Edit List"를 클릭한다.
  3. 하나의 창이 팝업된다(아래의). "..."을 클릭하고 추가하고자하는 exe파일이 있는 경로로 이동하고, exe 파일을 선택하고 "Ok" 버튼을 누른다.
    image
  4. 메인 탭으로 돌아가서 원하는 구성과(아마 강제 debug 출력을 하기 위한 "Force On"을 설정하기를 원할 것이다) 보고 싶지 않은 모든 메시지 유형을 끄는 "mute all ther message"(만약 그렇게 하기를 원한다면)을 선택한다.

exe 파일을 Control panel의 관리 응용 프로그램 목록에 등록했다면, 다음 단계는 D3D device의 DirectX Debug Layer에 연결하는 것이다.

아래의 링크에서 더 많은 정보를 찾을 수 있다. 하지만 기본적으로 해야할 것은 D3D11_CREATE_DEVICE_DEBUG 플래그를 포함한 생성 플래그를 이용하여 device를 만드는 것이다.

https://msdn.microsoft.com/en-us/library/windows/desktop/jj200584(v=vs.85).aspx

 

Managed D3D 10.x / 11.x 응용 프로그램(SlimDX, SharpDX and 유사한 wrappers)

C#으로 개발할 때는 D3D 9과 같이, Visual Studio의 메인 프로젝트 속성의 Debug 탭에서 "Enable native code debugging" 플래그를 활성화 시키는 것을 기억해야 한다. 그렇지 않다면 기본 디버그 출력은 Output window를 통해서 얻을 수 없다(자세한 내용은 이 게시물의 위 내용을 참고).

 


Windows 8.x + Windows SDK

이번 파트는 Windows 8.1와 새로운 Windows SDK 버전을 사용하여 작업하는 경우를 커버한다.

D3D 9.x

Windows 8에서의 Debugging D3D 9 응용 프로그램은 Windows 7에서와 마찬가지로 정확하게 같은 동작을 한다. 당연하게도 새로운 Windows SDK는 D3D9을 구성하는 도구를 포함하고 있지 않기 때문에, 이전 버전의 Control panel에 액세스하려면 DX SDK(June 2010)을 설치해야만 한다.(나의 모든 컴퓨터가 Windows 8.1로 업데이트되어 이런 작업이 모두 작동하는지 확인하지 못했다. 여기에 대해서 어떠한 피드백이든 환영한다.)

확실하게 말할 수 있는 것은, 불행하게도, D3D9 debugging은 Windows8.1에서 작동하지 않을 것으로 보인다는 것이다. 만약 이전 버전의 DX control panel을 열면 D3D9 탭의 모든 debug 부분이 회색으로 표시되는 것을 볼 수 있을 것이다.(나는 어떻게 해서는 이것을 되도록 노력했지만 운이 없는지 실패했다. 그래서 만약에 이것을 가능하게 한다면 나에게 알려주기 바란다.)

 

D3D 10.x / 11.x

D3D 10.x와 11.x의 Debug output 활성화는 Windows 7과 거의 동일하다.  이때를 제외하면 DXSDK 폴더 대신에 C:\Windows\System32에 위치한 새로운 버전의 DX Control Panel을 사용해야 한다.(Enabling debug output for D3D 10.x and 11.x is pretty much the same as in the case of Windows 7, unless this time you will need to use the NEW version of the DX Control Panel, located in C:\Windows\System32 instead of the usual DXSDK folders.)

또한, D3D11_CREATE_DEVICE_DEBUG 생성 플래그를 지정하여 Device를 생성해야하고(위의 설명을 참조), C#으로 개발하는 경우라면, 메인 프로젝트에서 "Enable native code debugging" 옵션을 활성화 해야한다.

 

문제 해결

  • 응용 프로그램은 작동하지만 debug output을 얻지 못하는 경우 : D3D9으로 개발하는 경우 이전 버전의 Control Panel의 debug 라이브러리를 활성화해야 한다. 또한 C#으로 작업하는 경우에는, "Enable native code debugging" 옵션을 확실하게 활성화해야 한다. D3D 10/11으로 작업하는 경우에는, D3D11_CREATE_DEVICE_DEBUG 플래그를 이용하여 장치를 생성하고, 작업하는 응용 프로그램을 DX Control Panel의 프로그램 관리 목록에 등록해야 한다. 모든 경우에 항상 적절한 DX Control Panel을 사용해야 한다(자세한 것은 위의 내용을 참조).
  • D3D 10.x / 11.x 에서 debug 생성 플래그를 이용한 device 생성을 시도하는 동안 응용 프로그램이 실패하는 경우 : 이것은 일반적으로 올바른 SDK가 설치되어 있지 않은 경우에 발생한다. 만약에 Windows 7 이나 Windows 8을 사용한다면 Windows8 SDK를 설치해야 한다. 만약에 최신 Windows 8.1을 사용하고 있다면 Windows 8.1 SDK를 설치해야 한다. Windows 8.1은 Windows 8.0 SDK 버전과 호환되지 않는다. D3D 10.x/11.x 구성요소가 있는지 확인하는 간단한 방법은 C:\Windows\System32 의 경로에 새로운 버전의 DX Control Panel이 있는지 확인하는 것이다.

 

원문 링크 >> http://graphicdna.blogspot.kr/2013/10/directx-control-panel-and-d3d-debug.html

반응형
반응형

Direct3D는 어떻게 보면 두 개의 레이어가 따로 있다. C++ 쪽에서 Debug를 돌려도 렌더링 쪽에서는 느려질 수 있는 것은 그렇게 많지 않다.


Direct3D에서는 실제 GPU로 들어가는 부분에 Direct3D Runtime이 있다. 여기에도 Debug 빌드와 Release 빌드가 있는데 이것은 C++ 코드와 전혀 상관없이 DirectX Control Panel에 들어가서 수정할 수 있는 것이다. 그것을 Release로 만들면 최적화가 적용되어서 빨라지고 Debug로 만들면 최적화 기능이 꺼지고 Debug 기능들로 인해서 느려진다.


일반적으로 대부분의 프로그래머는 빠르고 에러도 덜 뱉는다는 이유로 Direct3D를 Release로 켜놓고 사용하는데 어느 순간엔가는 이것을 Debug 빌드로 돌려서 Debug를 해야하는 순간이 온다. Memory leak 문제가 발생할 수도 있고, 참조 카운터 문제가 있을 수도 있다. 그래서 이것을 Debug로 바꾸는 순간 엄청난 Warning과 Error를 발생시키는 경우가 있다. 매 프레임마다 같은 혹은 비슷한 장면은 계속해서 그려야하는 렌더링의 특징 상 break를 걸기도 어렵고 Debugging도 어려워진다.


그렇기 때문에 그래픽 프로그래머는 반드시 Direct3D Runtime을 Debug 빌드로 두고 작업을 해야한다. Release 빌드에선 에러나 경고를 뱉지 않던 코드가 Debug 빌드에서 쏟아져 나올 수 있다. 그런 것을 무시하고 Release 빌드로만 작업하고 그런 에러와 경고가 쌓인 상태로 나중에 다른 프로그래머가 Debug를 하려고 하면 수많은 경고와 에러로 인해서 도저히 Debug 작업을 할 수 없게 된다. 결국 작업을 하기 위해서는 이 수많은 에러와 경고들을 처리할 수 밖에 없는데 이렇게 수 개월치 쌓인 문제를 한꺼번에 처리하는 것보다는 에러 하나, 경고 하나가 발생했을때 바로 처리하는 것이 훨씬 깔끔하고 빠른 문제 처리 방법이다.


렌더링 쪽에서는 크게 Debug 빌드가 느린 것 같지는 않은데 게임 쪽에서는 프레임 속도가 제대로 안나오면 문제가 있을 수도 있다.


참고 :: https://www.youtube.com/watch?v=eOF6IZU4nxQ


반응형
반응형

Direct3D 9 때부터 있던 DXTrace 함수가 있다.

 

Direct3D의 대부분의 함수는 HRESULT 타입으로 값을 반환하는데

 

DirectX의 대부분의 함수는 HRESULT형으로 값을 반환하는데 DXTrace 함수는 이때 발생한 에러에 대한 내용을 출력하는 사용되는 함수이다.

 

원래의 사용법은

 

#if defined(DEBUG) | defined(_DEBUG)
    #ifndef HR
    #define HR(x)                                              \
    {                                                          \
        HRESULT hr = (x);                                      \
        if(FAILED(hr))                                         \
        {                                                      \
            DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true); \
        }                                                      \
    }
    #endif
#else
    #ifndef HR
    #define HR(x) (x)
    #endif
#endif


이다.

 

함수의 각 파라메터는

DXTrace(

__FILE__ :: 에러가 발생한 파일,

__LINE__ :: 에러가 발생한 라인,

hr :: 에러가 발생한 원인이 들어 있는 HRESULT 값,

L#x :: 문자열 타입으로 에러가 발생했을때 메시지창에 띄울 내용,

flag :: 메시지 창을 띄울 것인가?)

를 의미한다.

 

다만 이 함수는 dxerr.lib, dxerr.h에 포함되어 있는데 이 라이브러리와 헤더는 DX SDK가 Windows10 SDK에 포함되면서 사라졌다.

그렇기 때문에 에러 메시지를 출력할 다른 방법을 이용해야 한다. 그 방법의 하나로


#if defined(DEBUG) || defined(_DEBUG)
    #ifndef HR
    #define HR(x)                                            \
    {                                                        \
        HRESULT hr = (x);                                    \
        if(FAILED(hr))                                       \
        {                                                    \
            LPWSTR output;                                   \
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |       \
                FORMAT_MESSAGE_IGNORE_INSERTS      |         \
                FORMAT_MESSAGE_ALLOCATE_BUFFER,              \
                NULL,                                        \
                hr,                                          \
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   \
                (LPTSTR) &output,                            \
                0,                                           \
                NULL);                                       \
            MessageBox(NULL, output, L"Error", MB_OK);       \
        }                                                    \
    }
    #endif
#else
    #ifndef HR
    #define HR(x) (x)
    #endif
#endif



DXTrace 함수 대신에 FormatMessage 함수와 MessageBox를 이용하는 것이다.

반응형
반응형

Severity    Code    Description    Project    File    Line    Suppression State

Error    LNK2019    unresolved external symbol _D3D11CreateDevice@40 referenced in function "protected: bool __thiscall D3DApp::InitDirect3D(void)" (?InitDirect3D@D3DApp@@IAE_NXZ)

 

Direct3D 11 프로그래밍과 관련해서 LNK2019 Error 응답하지 않는 외부 심볼 D3D11CreateDevice 에 대한 해결책.

 

d3d11 정적 라이브러리 파일을 연결해 주어야 한다.

d3d11과 관련된 함수를 사용하는 최상위 헤더에

 

#pragma comment(lib, "d3d11.lib")

를 추가해줄 것.


반응형
반응형

이전 버전의 Visual Studio에서는 Direct3D 11 세팅하기가 더럽게 불편했다.

 

마이크로소프트 다운로드 센터에서 DX SDK를 다운 받고 설치하고

 

프로젝트 속성에 들어가서 include, library 디렉토리를 연결하고 Linker에서 .lib 파일 넣어주는등 많은 작업이 필요 했는데

 

Visual Studio 2015로 넘어오고 Windows10 SDK를 받게 되면서부터 저런 작업을 할 필요가 없어졌다.

 

아마 듣기로는 Windows10 SDK에 Direct3D SDK가 포함되었다고 들었다.

 

그럼으로서 이제는 그냥 윈도우즈 API 프로그래밍 할때 #include <Windows.h>를 통해서 윈도우즈 관련 API를 포함했듯이

 

#include <d3d11.h>

 

Direct3D 관련 헤더들을 바로 불러올 수 있다.

 

다만 이전 버전에서 쓰이던 dxerr.h, xnamath.h 같은 몇몇 헤더는 사라졌으니 대체할 헤더를 잘 찾아볼것.


그리고 Direct 프로그래밍 하면서 쓰일 최상위 헤더에


#pragma comment(lib,"d3d11.lib")


를 추가해서 direct3d 라이브러리를 연결해주면 된다.



반응형
반응형

Direct3D에는 surface라는 용어가 나온다. MSDN에서는 그 뒤에 (Direct3D 9)이라고 표기 되어 있는 것으로 봐서는 DX9때부터 쭉 사용되어 오던 개념인것 같다.

Surface는 디스플레이 메모리의 선형 공간으로 보여주고 보통 디스플레이 카드의 디스플레이 메모리에 상주한다. 하지만 surface는 시스템 메모리에도 존재할 수 있다.

Surface는 IDirect3DSurface9 인터페이스에 의해서 관리된다.

  • Front buffer. 그래픽 어댑터에 의해 해석되고 모니터에 표시된 메모리 상의 직사각형 영역. Direct3D 응용 프로그램에서는 front buffer에 직접적으로 쓰기 작업을 하지 않아야 한다.
  • Back buffer. 응용 프로그램에서 직접적으로 쓰기 작업을 하는 메모리 상의 직사각형 영역. 이 back buffer는 모니터 상에 직접적으로 표시되지 않아야 한다.
  • Surface 뒤집기(교환). Back buffer에서 front buffer로 이동하는 절차.
  • Swap chain. Front buffer에 연속적으로 보여질 수 있는 하나 이상의 back buffer의  집단.

 

Surface 얻어오기

아래의 메서드 중 하나를 호출하여 surface 생성한다.

  • CreateDepthStencilSurface
  • CreateOffscreenPlainSurface
  • CreateRenderTarget

Surface format은 surface memory 내의 각 필셀의 데이터를 어떻게 해석할지를 결정한다. Direct3D는 surface format를 설명하는 D3DSURFACE_DESC 구조체의 D3DFORMAT을 사용한다. GetDesc() 메서드를 호출하는 것으로 현재 사용되는 surface의 format을 찾아올 수 있다.

Surface가 생성되었을 때 , 아래의 메서드 중 하나를 호출하여 포인터를 얻어올 수 있다.

  • GetCubeMapSurface
  • GetBackBuffer
  • GetDepthStencilBuffer
  • GetFrontBuffer
  • GetRenderTarget
  • GetBackBuffer
  • GetSurfaceLevel

IDirect3DSurface9 인터페이스는 UpdateSurface() 메서드를 통해서 간접적으로 메모리에 접근할 수 있다. 이 메서드는 한 IDirect3DSurface9 인터페이스로 부터 다른 IDirect3DSurface9 인터페이스에 픽셀의 사각형 영역을 복사할 수 있도록 허용한다. 이 surface 인터페이스도 직접적으로 디스플레이 메모리에 접근할 수 있는 메서드를 가지고 있다. 예를 들어 LockRect 메서드를 이용하여 디스플레이 메모리의 사각형 영역을 잠글 수 있다. surface의 잠긴 사각형 영역에 대한 작업이 완료된 이우에는 UnlockRect를 호출해주는 것이 중요하다.

 

위의 내용은 DX9 버전에서 정의되어 있는 Surface에 대한 내용이고 포프님의 간단하고 명료하신 설명에 따르면

"그냥 텍스처인데 텍스처에는 밉맵이 있어서 여러장의 크기가 다른 이미지들이 한 텍스처에 포함되므로 각각의 크기가 다른 이미지들을 서피스(표면) 이라 합니다."

"즉 서피스 = 이미지 한장. 이미지들 여러개가 모인것(밉맵, 큐브맵, 3디 이미지) = 텍스처"

유영천 님께서는

"Surface 개념 자체는 모든 DX버전에 다 해당됩니다. 그냥 이미지를 담을 수 있는 버퍼는 몽땅 다 Surface입니다. DDraw시절에도 Surface가 있었고 DX12에 와서도 Surface가 있습니다. 포프님 설명이 가장 정확합니다."

라고 설명해주셨다.


반응형

'Direct3D > Direct3D 용어' 카테고리의 다른 글

[Direct3D 용어] Direct3D Surface  (0) 2016.11.01
반응형

IDXGISwapChain1::Present1를 호출한 이후에 디스플레이 서페이스 내부의 픽셀 관리에 대한 옵션.


typedef enum DXGI_SWAP_EFFECT

{

  DXGI_SWAP_EFFECT_DISCARD          = 0,
  DXGI_SWAP_EFFECT_SEQUENTIAL       = 1,
  DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL  = 3,
  DXGI_SWAP_EFFECT_FLIP_DISCARD     = 4
} DXGI_SWAP_EFFECT;



각 상수의 내용

DXGI_SWAP_EFFECT_DISCARD
이 플래그는 IDXGISwapChain1::Present1을 호출한 이후에 bit-block transfer(bitblt) 모델을 지정하고 DXGI가 back buffer의 내용을 지우도록 지정한다. 이 플래그는 하나 이상의 back buffer를 가진 swap chain에 대해 유효하지만 응용 프로그램은 0번 buffer(첫번째 버퍼)에 대한 읽기/쓰기 접근이 가능하다.


Note

전용 전체 화면과 UWP 전체 화면 사이에는 차이가 있다. Windows PC UWP에 Direct3D 11 응용 프로그램을 이식하는 경우, swap chain을 생성할때 UWP와 Win32에서의 동작이 다르기 때문에 DXGI_SWAP_EFFECT_DISCARD를 사용하는 것을 주의하지 않으면 GPU 성능에 좋지 않을 수 있다. 이것은 이전의 bitblt 모델에 의해서 원래 수행된 메모리 복사를 통해 연산 시간이 감소하기 때문에 UWP 응용 프로그램이 FLIP swap 모드를 강제되는 것이 원인이다.(다른 swap 모드로 설정되어 있는 경우에도). UWP 내의 Flip 모델을 사용하여 수동적으로 DX11 Discard swap chain을 변환하는 것과 가능하다면 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 대신에 DXGI_SWAP_EFFECT_FLIP_DISCARD를 사용할 것을 권장한다. 아래의 예시를 참조하라.


DXGI_SWAP_EFFECT_SEQUENTIAL
이 플래그는 IDXGISwapChain1::Present1을 호출한 이후에 bitblt 모델을 지정하고 DXGI가 back buffer의 내용을 지속하도록 지정한다. 첫번째 버퍼(0번 버퍼)부터 마지막 버퍼까지 순서대로 swap chain의 내용을 제시하려면 이 옵션을 사용한다. 이 플래그는 multisampling과 함께 사용할 수 없다.

DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
이 플래그는 IDXGISwapChain1::Present1을 호출한 이후에 flip presentation 모델을 지정하고 DXGI가 back buffer의 내용을 지속하도록 지정한다. 이 플래그는 multisampling과 함께 사용할 수 없다.


Direct3D 11

이 enumeration 값은 Winsows8부터 지원되기 시작했다.


DXGI_SWAP_EFFECT_FLIP_DISCARD
이 플래그는 IDXGISwapChain1::Present1을 호출한 이후에 flip presentation 모델을 지정하고 DXGI가 back buffer의 내용을 지우도록 지정한다. 이 플래그는 multisampling과 partial presentation(부분 프레젠테이션)과 함께 사용할 수 없다. DXGI 1.4 Improvements(DXGI 1.4 개선점)를 보라.


Direct3D 11

이 enumeration 값은 Winsows10부터 지원되기 시작했다


Note

Windows Store 응용 프로그램들은 DXGI_SWAP_EFFECT_SEQUENTIAL이나 DXGI_SWAP_EFFECT_FLIP_DISCARD를 사용해야만 한다.


DXGI 1.4 Improvements >> https://msdn.microsoft.com/ko-kr/library/windows/desktop/mt427784(v=vs.85).aspx


Remarks

이 enumeration은 DXGI_SWAP_CHAIN_DESC과 DXGI_SWAP_CHAIN_DESC1 구조체에 의해서 사용된다.

Multisampling을 DXGI_SWAP_EFFECT_SEQUENTIAL이나 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL과 함께 사용하기 위해서는, 별도의 render target에서 multisampling을 수행해야 한다.
예를 들어, 채워진 D3D11_TEXTURE2D_DESC 구조체와 ID3D11Device::CreateTexture2D 호출에 의해 multisampling된 텍스처를 생성한다(BindFlags 멤버를 D3D11_BIND_RENDER_TARGET로 설정하고 SampleDesc의 멤버를 multisampling 매개변수로 설정해야 한다).
다음은 텍스처를 위한 render-target view를 생성하고, 텍스처에 scene을 렌더링 하기 위해 ID3D11Device::CreateRenderTargetView를 호출한다.
마지막으로는 multisampling된 텍스처를 multisampling되지 않은 swap chain에 resolve하기 위해 ID3D11DeviceContext::ResolveSubresource를 호출한다.

Presentation 모델들의 중요한 차이점은 back buffer의 내용을 어떻게 Desktop Window Manager(DWM)의 composition으로 가지고 오는가 이다.
bitblt 모델에서는 DXGI_SWAP_EFFECT_DISCARD와 DXGI_SWAP_EFFECT_SEQUENTIAL 값을 사용하고, IDXGISwapChain1::Present1의 매 호출마다 back buffer의 내용을 redirection surface에 복사한다.
Flip 모델에서는 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 값을 사용하고, 모든 back buffer를 DWM과 공유한다. 따라서 DWM은 추가적인 복사 작업없이 back buffer에서 바로 작성할 수 있다. 일반적으로는 flip 모델이 bitblt 모델보다 더 효율적이며, 강화된 현재 상태에 대한 통계 등 더 많은 기능을 제공한다.

SyncInterval 파라미터에 0이 지정된 flip 모델 swap chain에 IDXGISwapChain1::Present1를 호출할 때, IDXGISwapChain1::Present1의 동작은 Direct3D 9Ex의 D3DSWAPEFFECT_FLIPEX와 D3DPRESENT_FORCEIMMEDIATE로 설정된 IDirect3DDevice9Ex:PresentEx와 같은 동작을 한다. 즉, 런타임은 큐에 저장된 모든 이전 프레임 대신에 다름 프레임을 present할 뿐만 아니라 큐에 저장된 이전 프레임들에게 남아있는 모든 잔여 시간을 종료한다.

Flip 모델이 더 효율적인지에 상관없이, Bitblt 모델은 GDI와 DirectX Presentation을 혼합할 수 있는 유일한 방법이기 때문에 응용프로그램은 여전히 bitblt 모델을 선택할 수 있다.
Flip 모델에서는, 응용 프로그램은 DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE으로 swap chain을 생성해야 하며, back buffer에서 명시적으로 GetDC를 사용해야만 한다. Flip-모델 swap chain의
IDXGISwapChain1::Present1이 성공적인 첫번째 호출이 된 이후에, GDI는 swap chain을 파괴하고 swap chain과 연결된 HWND와 함께 더이상 작업을 수행하지 않는다. 이러한 제한 사항은 심지어 ScrollWindowEx 같은 메서드에도 확장된다.

Flip 모델 swap chain과 최적화 presentation에 대한 자세한 정보는 다음의 링크를 참조하라.
https://msdn.microsoft.com/ko-kr/library/windows/desktop/hh706345(v=vs.85).aspx

 

예제

UWP에서 swap chain을 생성하는 법, DX11 템플릿에 대한 새 인스턴스를 만들 필요가 있고, D3D12  샘플의 DeviceResources::CreateWindowSizeDependentResources를 구현해 볼 필요가 있다.


DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
 
       swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width);    // 윈도우 사이즈에 일치시킨다.
       swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height);
       swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;            // 이것은 일반적인 swap chain 포맷이다.
       swapChainDesc.Stereo = false;
       swapChainDesc.SampleDesc.Count = 1;                           // Multi-sampling을 사용하지 않는다.
       swapChainDesc.SampleDesc.Quality = 0;
       swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
       swapChainDesc.BufferCount = 2;                                // 대기 시간을 최소화하기 위해 더블 버퍼링을 사용한다.
       swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;     // 모든 Windows Store 응용 프로그램은 flip effect를 사용해야 한다.
       swapChainDesc.Flags = 2048;
       swapChainDesc.Scaling = scaling;
       swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
 
       // This sequence obtains the DXGI factory that was used to create the Direct3D device above.
       ComPtr<IDXGIDevice3> dxgiDevice;
       DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
 
       ComPtr<IDXGIAdapter> dxgiAdapter;
       DX::ThrowIfFailed(dxgiDevice->GetAdapter(&dxgiAdapter));
 
       ComPtr<IDXGIFactory4> dxgiFactory;
       DX::ThrowIfFailed(dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)));
 
       ComPtr<IDXGISwapChain1> swapChain;
       DX::ThrowIfFailed(
              dxgiFactory->CreateSwapChainForCoreWindow(
                     m_d3dDevice.Get(),
                     reinterpret_cast<IUnknown*>(m_window.Get()),
                     &swapChainDesc,
                     nullptr,
                     &swapChain
                     )
              );



이 글은 MSDN의 DXGI_SWAP_EFFECT enumeration 항목을 번역한 것입니다.

반응형

'Direct3D > Direct3D MSDN 번역' 카테고리의 다른 글

[Direct3D 11] DXGI_SWAP_EFFECT enumeration  (0) 2016.11.01
[Direct3D 11] DXGI_SWAP_CHAIN_DESC  (0) 2016.11.01
반응형

Swap chain의 특성을 담고 있는 구조체.

 

typedef struct DXGI_SWAP_CHAIN_DESC
{
    DXGI_MODE_DESC BufferDesc;      // 생성하고자 하는 back buffer의 속성들을 서술하는 구조체
    DXGI_SAMPLE_DESC SampleDesc;    // Multisampling을 위해 추출할 표본 개수와 품질 수준을 서술하는 구조체
    DXGI_USAGE BufferUsage;         // 버퍼의 용도를 서술하는 구조체
    UINT BufferCount;               // Swap chain에서 사용할 back buffer의 개수.(이중버퍼링 : 1개, 삼중버퍼링 : 2개)
    HWND OutputWindow;              // 렌더링 결과를 표시할 윈도우 창의 핸들
    BOOL Windowed;                  // 창 모드를 원하면 true, 전체화면 모드를 원하면 false
    DXGI_SWAP_EFFECT SwapEffect;    // Swap 효과를 서술하는 구조체
    UINT Flags;                     // 추가적인 플래그
} DXGI_SWAP_CHAIN_DESC;
 
typedef struct DXGI_MODE_DESC
{
    UINT Width;                                 // 원하는 back buffer 너비
    UINT Height;                                // 원하는 back buffer 높이
    DXGI_RATIONAL RefreshRate                   // 디스플레이 모드 갱신율
    DXGI_FORMAT Format;                         // back buffer 픽셀 형식
    DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;  // 디스플레이 스캔라인 모드
    DXGI_MODE_SCALING Scaling;                  // 디스플레이 비례 모드
} DXGI_MODE_DESC;
 
DXGI_SWAP_CHAIN_DESC::DXGI_USAGE    // 버퍼의 용도
{
    DXGI_USAGE_SHADER_INPUT         // 셰이더 입력
    DXGI_USAGE_RENDER_TARGET_OUTPUT // 렌더 타겟 출력으로 surface 또는 자원을 사용
    DXGI_USAGE_BACK_BUFFER          // surface 또는 자원을 back buffer로 사용.
                                    //swap chain을 생성할 때 DXGI_USAGE_BACK_BUFFER을 전달할 필요는 없다.
    DXGI_USAGE_SHARED               // surface 또는 자원을 공유
    DXGI_USAGE_READ_ONLY            // surface 또는 자원을 읽기 전용으로 사용
    DXGI_USAGE_DISCARD_ON_PRESENT   // DXGI 모듈에서 내부적으로 사용
    DXGI_USAGE_UNORDERED_ACCESS     // surface 또는 자원에 무순서 접근을 위해 사용
}

 

DXGI_SWAP_EFFECT

DXGI_SWAP_CHAIN_FLAG

DXGI_MODE_SCANLINE_ORDER

DXGI_MODE_SCALING

 

위에 네 가지 열거형에 대해서는 딱히 알기 쉽게 번역되어 있는 내용이 없다.

나중에 시간이 날때 번역해서 올리자.

반응형

'Direct3D > Direct3D MSDN 번역' 카테고리의 다른 글

[Direct3D 11] DXGI_SWAP_EFFECT enumeration  (0) 2016.11.01
[Direct3D 11] DXGI_SWAP_CHAIN_DESC  (0) 2016.11.01

+ Recent posts