예전에는 내용 정리와 일지랑 섞어서 쓰긴 했는데 좀 분리를 해볼까 합니다.

어차피 내용 정리는 나중에 옮겨야 겠지만.

 

현재 4-3까지 읽었고, 5챕터를 읽은 상태입니다.

이제 여기서 선택지가 있어 조금 고민입니다.

 

하나는 4-4를 읽으면서 구조를 직접 짜보고 나중에 수정하는 것.

다른 하나는 5챕터 예시 코드를 보면서 우선 코드를 작성해놓고, 남은 4챕터와 6챕터를 읽고 코드 정리를 하는 것입니다.

 

아마 직접 해보는 전자가 더 정확히 익힐 수도 있겠지만,
잘 모르는건 예시를 우선 보는 것이 더 잘 이해하기에 후자로 진행하고자 합니다.

 

그래서 당장 다음 공부 날짜인 내일은 6챕터 코드를 제가 원하는 형태로 바꿔가면서 작성을 하려고 합니다.

아마 하루에 끝날 것 같지는 않은데, 이게 끝나면 4챕터 남은 것, 6챕터를 읽으면서 주석을 상세히 작성하고자 합니다.

'내용정리 > DirectX12' 카테고리의 다른 글

20.07.28 개발일지  (0) 2020.07.28
20.07.25 개발일지  (0) 2020.07.25
08. Direct3D의 초기화 - CPU와 GPU의 상호작용  (0) 2020.07.24
08. Direct3D의 초기화 - 기본지식 2  (0) 2020.07.24
09. 렌더링 파이프라인 2  (1) 2020.07.14
  • Graphic Programming에서는 GPU와 CPU. 두 Processor가 작동한다는 점을 이해할 필요가 있다.

  • 이 둘은 병렬로 작동하지만, 종종 동기화가 필요하다.

  • 최적의 성능을 위해서는 둘 모두 최대한 바쁘게 돌아가게 만들어야 하며, 동기화를 최소화 해야 한다.

    • 동기화는 한 Processor의 작업이 마칠 때까지 다른 Processor는 놀아야 한다는 것을 의미한다.

  • 한마디로, 동기화는 병렬성을 망친다.

명렬 대기열(Command Queue)과 명령 목록(Command List)

  • CPU는  Command List를 Direct3D API를 통해 GPU의 Command Queue에 제출한다.

    • 하지만 "Queue"에서 알 수 있듯이,
      Command Queue에 넘어갔다고 GPU가 그 즉시 실행하는 것은 아니다.

    • Command들은 GPU가 처리할 준비가 되어야 비로서 실행되기 시작한다.

    • 즉, GPU가 이전에 제출된 Command를 처리하는 동안에는 Queue에 남아 있다는 것이다.

  • Command Queue가 비면 GPU는 놀게 되고, 꽉 차면 Queue에 자리가 생길 때까지 CPU가 놀게 된다.

    • 게임 같은 High-Quality Application에서는 가용 Hardware Resource를 최대한 쓰는 것이 목표다.

    • 즉, CPU도 GPU도 항상 쉬지 않고 일하게 만들어야 한다.

  • Direct3D 12에서 Command Queue를 담당하는 Interface는 ID3D12CommandQueue이다.

    • 이를 생성하기 위해서는 D3D12_COMMAND_QUEUE_DESC 구조체를 채운 후 ID3D12Device::CreateCommandQueue를 호출해야 한다.

  • 다음은 Command Queue를 채우는 방식을 보여주는 예시 코드이다.

Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Flags = D3D12_COMNAND_QUEUE_FLAG_NONE;
ThrowIfFailed(md3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)));
  • 위 예시 코드에서 사용된 보조 메크로 IID_PPV_ARGS는 다음과 같이 정의되어 있다.

#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
  • 여기서 __uuidof(**(ppType))은 (**(ppType))의 COM Interface ID로 평가 된다.

    • 위 예에서의 ID는 ID3D12CommandQueue이다.

  • 보조함수 IID_PPV_ARGS_Helper는 ppType을 void**로 Cast한다.

  • Direct3D 12 API에는 생성하고자 하는 Interface의 COM ID와 void**를 받는 함수들이 많기 때문에

    책에서 이 매크로를 선언하고, 책 내의 예시코드 전반적으로 사용되고 있다.

ExcuteCommandLists

  • ExcuteCommandLists는 Command List에 있는 Command들을 Queue에 추가하는 메서드이다.

void ID3D12CommandQueue::ExecuteCommandLists(
  UINT              NumCommandLists,
  ID3D12CommandList * const *ppCommandLists
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12commandqueue-executecommandlists

 

ID3D12CommandQueue::ExecuteCommandLists (d3d12.h) - Win32 apps

Submits an array of command lists for execution.

docs.microsoft.com

  • 선언으로 보면 ID3D12CommandList가 Command List를 담당하는 것 같지만,

    실제 그래픽 작업을 위한 Command List는 이를 상속하는 ID3D12GraphicsCommandList라는 Interface가 담당한다.

HRESULT Close();

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-close

 

ID3D12GraphicsCommandList::Close (d3d12.h) - Win32 apps

Indicates that recording to the command list has finished.

docs.microsoft.com

  • ExcuteCommandLists로 Command List를 제출하기 전에

    반드시 이 메서드를 이용해 Command List를 닫아야 함을 기억하자.

CreateCommandAllocator

  • Command List에는 ID3D12CommandAllocator가 하나 연관된다.

    • Command List에 추가된 Command들은 이 Allocator의 메모리에 저장된다.

  • ExcuteCommandLists로 Command List를 제출하면 Command Queue는 Allocator에 담긴 Command들을 참조한다.

  • Command Memory Allocator는 다음 메서드를 이용해 생성한다.

HRESULT CreateCommandAllocator(
  D3D12_COMMAND_LIST_TYPE type,
  REFIID                  riid,
  void                    **ppCommandAllocator
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createcommandallocator

 

ID3D12Device::CreateCommandAllocator (d3d12.h) - Win32 apps

Creates a command allocator object.

docs.microsoft.com

  • type은 이 Allocator와 연관시킬 수 있는 Command List 종류이다.

  • 책에서 주로 쓰이는 Type은 다음과 같다.

D3D12_COMMAND_LIST_TYPE_DIRECT

  • GPU가 직접 실행 시킬 수 있는 Command List

  • 지금까지 설명한 Command List들이 이에 포함됨.

D3D12_COMMAND_LIST_TYPE_BUNDLE

  • Bundle을 나타내는 Command List

  • Command List를 만드는 데에 CPU의 부담이 어느정도 따른다.

    • 때문에 Direct3D 12는 일련의 Command들을 Bundle 단위로 기록할 수 있는 최적화 수단을 제공한다.

  • Bundle을 추가하면 Driver는 Rendering 도중에 실행이 최적화 되도록 Bundle의 Command들을 PreCompile한다.

  • Application이 특정 Command List들을 구축하는데 시간이 오래 걸린다면, 이를 고려할 필요가 있다.

    • 단, Direct3D 12 API는 이미 아주 효율적이라 이런 경우가 자주 생기지 않는다.

    • 때문에 Bundle 사용이 성능상 이득을 가져오는 명백한 경우에만 사용한다.

  • 즉, Bundle을 무조건 사용하지는 말아야 한다.

riid

  • 생성하고자 하는 ID3D12CommandAllocator의 COM ID

ppCommandAllocator

  • 생성된 Command Allocator를 가리키는 포인터

  • 출력되는 매개변수

typedef enum D3D12_COMMAND_LIST_TYPE {
  D3D12_COMMAND_LIST_TYPE_DIRECT,
  D3D12_COMMAND_LIST_TYPE_BUNDLE,
  D3D12_COMMAND_LIST_TYPE_COMPUTE,
  D3D12_COMMAND_LIST_TYPE_COPY,
  D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE,
  D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS,
  D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE
} ;

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createcommandallocator

 

ID3D12Device::CreateCommandAllocator (d3d12.h) - Win32 apps

Creates a command allocator object.

docs.microsoft.com

CreateCommandList

HRESULT ID3D12Device::CreateCommandList(
  UINT                    nodeMask,
  D3D12_COMMAND_LIST_TYPE type,
  ID3D12CommandAllocator  *pCommandAllocator,
  ID3D12PipelineState     *pInitialState,
  REFIID                  riid,
  void                    **ppCommandList
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createcommandlist

 

ID3D12Device::CreateCommandList - Win32 apps

Creates a command list.

docs.microsoft.com

nodeMask

  • GPU가 여러개일 때에는 이 Command List와 연관시킬

    물리적 GPU Adpater Node들을 지정하는 비트마스크 값을 설정한다.

  • GPU가 하나인 겨우에는 0으로 설정하면 된다.

  • System의 GPU Adapter node 개수는 다음 메서드로 알아낼 수 있다.

UINT ID3D12DeviceGetNodeCount();

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getnodecount

 

ID3D12Device::GetNodeCount (d3d12.h) - Win32 apps

Reports the number of physical adapters (nodes) that are associated with this device.

docs.microsoft.com

type

  • Command List의 종류

  • pCommandAllocator

    • 생성된 Command List와 연관시킬 Allocator

    • Command Allocator의 type은 Command List의 type와 일치해야 한다.

pInitialState

  • Command List의 초기 Pipeline 상태를 지정한다.

  • Bundle이거나 초기화 목적으로 쓰이고 실제 그리기 명령이 없는 Command List의 경우 null을 지정한다.

  • 자세한 내용은 나중에 추가로 정리 할 예정이다.

riid

  • 생성하고자 하는 Command List에 해당하는 ID3D12CommandList Interface의 COM ID

ppCommandList

  • 생성된 Command List를 가르키는 포인터

  • 출력 매개변수

  • 한 Allocator를 여러 Command List에 연관시켜도 되지만,
    Command를 여러 Command List에 동시에 기록할 수는 없다.

    • 바꿔 말하면, 현재 Command를 추가하는 Command List를 제외한 모든 Command List들은 닫혀 있어야 한다.

    • 그래야 Command List의 모든 Command가 Allocator 안에 인접해서 저장된다.

  • Command List를 Create 하거나 Reset하면 Command List가 열린 상태가 된다.

    • 때문에 같은 Allocator로 두 Command List를 연달아 Create하면 오류가 발생한다.

Reset

HRESULT ID3D12GraphicsCommandList::Reset(
  ID3D12CommandAllocator *pAllocator,
  ID3D12PipelineState    *pInitialState
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-reset

 

ID3D12GraphicsCommandList::Reset (d3d12.h) - Win32 apps

Resets a command list back to its initial state as if a new command list was just created.

docs.microsoft.com

  • Reset 함수는 Command List뿐만 아니라 Command Allocator에서도 제공한다.

    • 예를 들어, 하나의 Frame을 완성하는데 필요한 Rendering 명령들을 모두 GPU에 제출 한 후에는

      Command Allocator의 Memory를 다음 Frame을 위해 재사용해야 할 것이다.

    • ID3D12CommandAllocator::Reset 메서드는 이 때 사용된다.

HRESULT ID3D12CommandAllocator::Reset();

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12commandallocator-reset

 

ID3D12CommandAllocator::Reset (d3d12.h) - Win32 apps

Indicates to re-use the memory that is associated with the command allocator.

docs.microsoft.com

  • 하지만 Command Queue가 Allocator 안의 자료를 참조하고 있을수도 있다.

    • 때문에 GPU가 Command Allocator에 담긴 모든 Command를 실행했음이 확실해지기 전까지
      Command Allocator를 재설정하지 말아야 한다.

CPU/GPU 동기화

  • 한 System에서 두 개의 Processor가 병렬로 실행되다 보니 여러 동기화문제가 발생한다.

    • 이에 대한 해결법 중 하나는 GPU가 Command Queue의 Command들 중

      특정 지점까지의 모든 Command를 다 처리할 때까지 CPU를 기다리게 하는 것이다.

  • Queue의 모든 Command를 처리하는 것을 Flush라고 한다.

  • 이 때 필요한 것은 Fence라는 객체이다.

    • Fence는 ID3D12Fence Interface로 구현하며 GPU와 CPU의 동기화를 위한 수단으로 쓰인다.

    • Fence를 생성하는 메서드는 다음과 같다.

HRESULT ID3D12Device::CreateFence(
  UINT64            InitialValue,
  D3D12_FENCE_FLAGS Flags,
  REFIID            riid,
  void              **ppFence
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createfence

 

ID3D12Device::CreateFence (d3d12.h) - Win32 apps

Creates a fence object.

docs.microsoft.com

  • Fence 객체는 UINT64 값 하나를 관리한다.

    • 이는 그냥 시간상의 특정 Fence 지점을 식별하는 정수이다.

  • 예를 들어, Fence가 하나도 없을 때에는 이 값을 0으로 둔다.

    • 새 Fence를 만들 때에는 이 값이 1씩 증가한다.

  • 이를 아래 예시 코드를 보며 더 자세히 설명을 해보겠다.

UINT64 mCurrentFence = 0;
void D3DApp::FlushCommandQueue()
{
	// 현재 Fence 지점까지의 명령들을 표시하도록 Fence 값을 전진시킨다.
    mCurrentFence++;
    
    // 새 Fence 지점을 설정하는 Signal을 Command Queue에 추가한다.
    // 지금 우리는 GPU timeline상에 있으므로 새 Fence 지점은 
    // GPU가 이 Signal() Command까지의 모든 명령을 처리하기 전까지는 설정되지 않는다.
    ThrowIfFailed(mCommandQueue->Signal(mFence.Get(), mCurrentFence));
    
    // GPU가 이 Fence 지점까지의 Command들을 완료할 때까지 기다린다.
    if(mFence->GetCompletedValue() < mCurrentFence)
    {
    	HANDLE eventHandle = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
        
        // GPU가 현재 Fence 지점에 도달했으면 이벤트를 발동한다.
        ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, eventHandle));
        
        // GPU가 현재 Fence 지점에 도달했음을 뜻하는 이벤트를 기다린다.
        WaitForSingleObject(eventHandle, INFINITE);
        CloseHandle(eventHandle);
    }
}
  • 하지만 이것은 이상적인 해결책은 아니다.

    • GPU의 작업이 끝날 때까지 CPU가 기다려야하기 때문이다.

  • 하지만 충분히 간단한 해결책이므로 당분간은 이 방법을 이용한다.

  • Command Queue를 비우는 시점에는 제약이 거의 없다.

    • 특히 한 Frame에서 1번만 비워야 하는 것도 아니다.

  • 예를 들어 초기화를 위한 GPU Command들이 있다고 하자.

    • 먼저 그 Command가 실행되었음이 확실해진 후 Command Allocator를 재설정 하려면

      Command Queue를 비운 후 Command Allocator를 Reset하면 된다.

  • Resource hazard를 막기 위해 Direct3D는 Resource들에게 State를 부여한다.

    • 새로 생성된 Resource는 Default State로 시작한다.

  • 임의의 State Transition를 Direct3D에게 보고하는 것은 전적으로 Application의 몫이다.

    • 덕분에 GPU는 State를 전이하고 Resourece Hazard를 방지하는데 필요한 일들을 자유롭게 진행할 수 있다.

  • 예를 들어, Texture Resource에 자료를 기록해야 할 때에는 그 Texture의 State를 Render Object State로 설정한다.

    • 이후 Texture의 자료를 읽어야 할 때가 되면 State를 Shader Resource State로 Transition 한다.

  • Application이 State Transition을 Direct3D에게 보고 함으로써,
    GPU는 Resource Hazard를 피하는데 필요한 조치를 할 수 있다.

    • 쓰기 연산이 완료되길 기다린 후 읽기를 시도 하는 등

  • Resource Transition을 보고하는 부담을 Application이 담당하는 것은 성능 때문이다.

    • GPU 입장에서는 Transition이 언제 발생하는지 몰라 항상 자동으로 추적하게 해야 한다.

    • Programmer는 이러한 Transition이 언제 일어아는지 미리 알고 있기에 필요할 때 추적할 수 있다.

전이 자원 장벽(Transition Resource Barrier)

  • Resource State Transition은 Transition Resource Barrier들의 Array를 설정해서 지정한다.

    • Array를한번의 API 호출로 여러 개의 Resource를 Transition 할 수 있다.

  • 코드 상에서는 Resource Barrier는 D3D12_RESOURCE_DESC 구조체로 서술된다.

typedef struct D3D12_RESOURCE_BARRIER {
  D3D12_RESOURCE_BARRIER_TYPE  Type;
  D3D12_RESOURCE_BARRIER_FLAGS Flags;
  union {
    D3D12_RESOURCE_TRANSITION_BARRIER Transition;
    D3D12_RESOURCE_ALIASING_BARRIER   Aliasing;
    D3D12_RESOURCE_UAV_BARRIER        UAV;
  };
} D3D12_RESOURCE_BARRIER;

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_resource_barrier

 

D3D12_RESOURCE_BARRIER (d3d12.h) - Win32 apps

Describes a resource barrier (transition in resource use).

docs.microsoft.com

  • 이 책에서는 Direct3D 12의 구조체들에 여러 편의용 메서드들을 추가한 확장 버전을 사용한다.

    • 대부분의 구조체들은 이런 편의용 확장 버전들이 존재하며,
      이 책에서 사용하는 것들은 Microsoft 사이트에서 내려받을 수 있다.

https://docs.microsoft.com/en-us/windows/win32/direct3d12/helper-structures-for-d3d12

 

Helper Structures for D3D12 - Win32 apps

These helper structures help initialize many of the Direct3D 12 structures, and are declared in d3dx12.h.

docs.microsoft.com

https://github.com/microsoft/DirectX-Graphics-Samples

 

microsoft/DirectX-Graphics-Samples

This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows. - microsoft/DirectX-Graphics-Samples

github.com

  • Transition Resource Barrier는 GPU에게 Resource의 State가 Transition됨을 알려주는
    하나의 Command라고 생각할 수 있다.

    • Comand를 통해 Resource State Transition를 알려주는 덕분에,
      GPU는 이후 Command들을 실행 할 때 Resource Hazard를 피하는데 필요한 단계를 밟을 수 있다.

Command List를 이용한 Multi Thread 활용

  • Direct3D 12는 Multi Thread를 효율적으로 활용할 수 있도록 설계되었다.

    • Command List의 서러계는 Direct3D가 Multi Thread 적용의 장점을 취하는 대표적인 한 방법이다.

  • 물체가 많은 큰 장면을 다룰 때,
    장면 전체를 하나의 Command List로 그리려 하면 구축하는데 CPU 시간이 오래 걸린다.

    • 이에 대한 자명한 해결책은 여러 개의 Command List를 병렬로 구축하는 것이다.

  • Command List 구축에 Multi Thread를 적용 할 때 주의해야 할 점이 쳐가지 있다.

    1. Command List와 Command Allocator는 Free-Threaded 하지 않는다.

      보통의 경우 여러 Thread가 같은 Command List나 Allocator를 공유하지도 않고,
      그 메서드들을 동시에 호출하지도 않는다.

      따라서, 일반적으로 각 Thread는 각자 자신만의 Command List와 Allocator를 가지게 된다.

    2. Command Queue는 Free-Threaded하다.

      즉, 여러 Thread가 같은 Command Queue에 접근해서 그 메서드들을 동시에 호출할 수 있다.

      특히, Thread들이 각자 생성한 Command List를 동시에 Command Queue에 제출할 수 있다.

    3. 성능상의 이유로,
      Application은 동시에 기록할 수 있는
      Command List의 최대 개수를 반드시 초기화 시점에서 설정해야 한다.

  • 단순함을 위해, 이 책에서는 Multi Thread를 사용하지 않는다.

    • 하지만 System Resource 사용을 극대화 하려면 Application이

      반드시 Multi Thread를 이용해 Multi Core의 장점을 최대한 활용할 필요가 있다.

'내용정리 > DirectX12' 카테고리의 다른 글

20.07.25 개발일지  (0) 2020.07.25
20.07.24 일지  (0) 2020.07.24
08. Direct3D의 초기화 - 기본지식 2  (0) 2020.07.24
09. 렌더링 파이프라인 2  (1) 2020.07.14
09. 렌더링 파이프라인 1  (0) 2020.07.14

이전 내용은 DirectX11 기반 내용을 현재 DirectX12에 맞게 검색한 뒤 작성한 내용입니다.

이후 DirectX12 책을 구매하였고, 몇가지 내용이 추가되어 그 내용을 우선 작성합니다.

 

---------------------------------------------------------------------------------------------------

 

DXGI(DirectX Graphics Infrastructure)

  • DirectX3D와 함께 쓰이는 API로 여러 그래픽 API들에 공통인 그래픽 관련 작업들이 존재한다.

    • 예를 들어 SwapChain을 위한 대표적인 Interface인 IDXGISwapShain은 사실 DXGI API일부이다.

    • 그 밖에 Graphic System Data의 Enumeration. 그리고 지원되는 표현 형식들도 DXGI가 제공한다.

IDXGIFactory

  • 주로 IDXGISwapChain Interface 생성과 Display Adapter Enumeration에 쓰인다.

IDXGIAdapter

  • Display Adapter를 대표하는 Interface

Display Adapter

  • 그래픽 기능성을 구현하며, 일반적으로 하드웨어 장치(ex. Graphic Card)이다.

    • 하지만 하드웨어 그래픽 기능성을 흉내내는 소프트웨어 디스플레이 기능성도 존재한다.

  • 하나의 시스템은 여러개의 Adpater를 가질 수 있다.

IDXGIOutput

  • Display Output을 담당하는 Interface.

  • DXGI_MODE_DESC 구조체에는 하나의 Display Mode를 서술하는 여러 멤버들이 있다.

typedef struct DXGI_MODE_DESC {
  UINT                     Width;
  UINT                     Height;
  DXGI_RATIONAL            RefreshRate;
  DXGI_FORMAT              Format;
  DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
  DXGI_MODE_SCALING        Scaling;
} DXGI_MODE_DESC;

typedef struct DXGI_RATIONAL {
  UINT Numerator;
  UINT Denominator;
} DXGI_RATIONAL;

typedef enum DXGI_MODE_SCANLINE_ORDER { 
  DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED        = 0,
  DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE        = 1,
  DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST  = 2,
  DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST  = 3
} DXGI_MODE_SCANLINE_ORDER;

typedef enum DXGI_MODE_SCALING { 
  DXGI_MODE_SCALING_UNSPECIFIED  = 0,
  DXGI_MODE_SCALING_CENTERED     = 1,
  DXGI_MODE_SCALING_STRETCHED    = 2
} DXGI_MODE_SCALING;

https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb173064(v=vs.85)

 

DXGI_MODE_DESC structure (Windows)

DXGI_MODE_DESC structure 05/18/2018 2 minutes to read In this article --> Describes a display mode. Syntax typedef struct DXGI_MODE_DESC { UINT                     Width; UINT                     Height; DXGI_RATIONA

docs.microsoft.com

  • 이러한 Display Mode Enumeration은 전체 화면 모드로 갈 때 특히 중요하다.

    • 성능을 극대화 하려면 지정된 Display Mode가 반드시 모니터가 지원하는 Display Mode와 일치해야 한다.

    • 모니터가 지원하는 Display Mode들을 열거해 그 중 하나를 지정하면 이러한 일치성이 보장된다.

Display Output

  • 모니터와 같이 화면을 출력하는 장치.

기능 지원 점검

  • ID3D12Device::CheckFeatureSupport 메서드는 Graphic Driver의 MultiSampling 지원 여부를

    점검할 수 있다고 소개했다.

    • 하지만 이는 CheckFeatureSupport가 확인할 수 있는 수 많은 기능들 중 하나일 뿐이다.

  • CheckFeatureSupport의 서명은 다음과 같다.

HRESULT CheckFeatureSupport(
  D3D12_FEATURE Feature,
  void          *pFeatureSupportData,
  UINT          FeatureSupportDataSize
);
  • Feature는 이 메서드로 지원 여부를 점검할 기능들의 종류를 나타낸다.

  • pFeatureSupportData는 기능 지원 정보가 설정될 구조체를 가르키는 포인터이다.

    • 이는 Feature 값에 따라 구체적인 형식이 다르다.

  • FeatureSupportDataSize는 pFeatureSupportData에 전달한 구조체의 크기를 나타낸다.

D3D12_FEATURE_D3D12_OPTIONS

  • Direct3D 12의 여러 기능들을 점검한다.

  • pFeatureSupportData에는 D3D12_FEATURE_DATA_D3D12_OPTIONS 인스턴스를 가르키는 포인터를 넣어야 한다.

DED12_FEATURE_ARCHITECTURE

  • Hardware Architecture 기능들을 점검한다.

  • pFeatureSupportData에 D3D12_FEATURE_DATA_ARCHITECTURE 인스턴스를 가르키는 포인터를 넣어야 한다.

D3D12_FEATURE_FEATURE_LEVELS

  • 기능 수준들을 점검한다.

  • D3D12_FEATURE_DATA_FEATURE_LEVELS 인스턴스를 가리키는 포인터를 넣어야 한다.

D3D12_FEATURE_FORMAT_SUPPORT

  • 주어진 Texture 형식에 대한 기능들을 점검한다.

  • D3D12_FEATURE_DATA_FORMAT_SUPPORT 인스턴스를 가르키는 포인터를 넣어야 한다.

D3D12_FEATURE_MULTICAMPLE_QUALITY_LEVELS

  • MultiSampling 기능들을 점검한다.

  • D3D12_FEATURE_DATA_MULTISAMPLING_QUALITY_LEVELS 인스턴스를 가르키는 포인터를 넣어야 한다.

상주성(Residency)

  • 게임에 사용되는 모든 자원이 GPU를 필요로 하는 것은 아니다.

  • 때문에 Direct3D 12의 Application은 Resource를 GPU 메모리로부터 내리거나 올려서
    Residency를 관리한다.

    • 이러한 작업의 핵심은 GPU Memory 점유율을 최소화 하는 것이다.

  • 성능적 측면에서 한가지 주의해야 할 점이 있다.

    • Application은 같은 자원을 짧은 시간에 GPU Memory에 넣었다 뺐다 하는 상황을 피해야 한다.

    • 이러한 활동에는 비용이 따르기 때문이다.

  • 이상적으로, 한동안 사용하지 않는 Resource들만 GPU Memory에서 내려야 한다.

  • Residency을 변경하는 대표적인 예로는 Level이나 Area가 바뀌는 시점을 들 수 있다.

  • 보통은 Resource를 생성하면 GPU Memory에 올라가고, 파괴되면 Memory에서 내려간다.

    • 하지만 다음 메서드들을 이용해 Application이 직접 Residency를 제어할 수 있다.

HRESULT ID3D12Device::MakeResident(
  UINT           NumObjects,
  ID3D12Pageable * const *ppObjects
);

HRESULT ID3D12Device::Evict(
  UINT           NumObjects,
  ID3D12Pageable * const *ppObjects
);

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-makeresident

 

ID3D12Device::MakeResident (d3d12.h) - Win32 apps

Makes objects resident for the device.

docs.microsoft.com

https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-evict

 

ID3D12Device::Evict (d3d12.h) - Win32 apps

Enables the page-out of data, which precludes GPU access of that data.

docs.microsoft.com

 

+ Recent posts