Direct3D 9에서 Direct3D 11로의 중요 변경 사항

요약

이 토픽에서는 DirectX 9와 DirectX 11 간의 대략적인 차이점에 대해 설명합니다.

Direct3D 11은 그래픽 하드웨어에 대한 낮은 수준의 가상화된 인터페이스인 Direct3D 9와 기본적으로 동일한 유형의 API입니다. 이 기능으로 다양한 하드웨어 구현에서 그래픽 그리기 작업을 수행할 수 있습니다. Direct3D 9 이후 그래픽 API의 레이아웃이 변경되었습니다. 디바이스 컨텍스트의 개념이 확장되었으며, 특히 그래픽 인프라용으로 API가 추가되었습니다. Direct3D 디바이스에 저장된 리소스에는 리소스 뷰라고 하는 데이터 다형성을 위한 새로운 메커니즘이 있습니다.

핵심 API 함수

Direct3D 9에서는 사용하기 전에 Direct3D API에 대한 인터페이스를 생성해야 했습니다. Direct3D 11 UWP(유니버설 Windows 플랫폼) 게임에서 D3D11CreateDevice라는 정적 함수를 호출하여 디바이스 및 디바이스 컨텍스트를 생성합니다.

디바이스 및 디바이스 컨텍스트

Direct3D 11 디바이스는 가상화된 그래픽 어댑터를 나타냅니다. 예를 들어, GPU에 텍스처 업로드, 텍스처 리소스, 스왑 체인에 대한 뷰 생성, 텍스처 샘플러 생성 등 비디오 메모리에 리소스를 생성하는 데 사용됩니다. Direct3D 11 디바이스 인터페이스가 사용되는 전체 목록은 ID3D11DeviceID3D11Device1을 참조하세요.

A Direct3D 11. 디바이스 컨텍스트는 파이프라인 상태를 설정하고 렌더링 명령을 생성하는 데 사용됩니다. 예를 들어, Direct3D 11 렌더링 체인은 디바이스 컨텍스트를 사용하여 렌더링 체인을 설정하고 장면을 그립니다(아래 참조). 디바이스 컨텍스트는 Direct3D 디바이스 리소스에서 사용하는 비디오 메모리에 액세스(매핑)하는 데 사용됩니다. 또한 상수 버퍼 데이터와 같은 하위 리소스 데이터를 업데이트하는 데도 사용됩니다. Direct3D 11 디바이스 컨텍스트가 사용되는 전체 목록은 ID3D11DeviceContextID3D11DeviceContext1을 참조하세요. 대부분의 샘플은 즉각적인 컨텍스트를 사용하여 디바이스에 직접 렌더링하지만 Direct3D 11은 주로 다중 스레딩에 사용되는 지연된 디바이스 컨텍스트도 지원합니다.

Direct3D 11에서는 D3D11CreateDevice를 호출하여 디바이스 핸들과 디바이스 컨텍스트 핸들을 모두 가져옵니다. 이 메서드는 특정 하드웨어 기능 집합을 요청하고 그래픽 어댑터에서 지원하는 Direct3D 기능 수준에 대한 정보를 검색하는 위치이기도 합니다. 디바이스, 디바이스 컨텍스트, 스레딩 고려 사항에 대한 자세한 내용은 Direct3D 11의 디바이스 소개를 참조하세요.

디바이스 인프라, 프레임 버퍼, 렌더링 대상 뷰

Direct3D 11에서 디바이스 어댑터 및 하드웨어 구성은 IDXGIAdapterIDXGIDevice1 COM 인터페이스를 사용하여 DXGI(DirectX Graphics Infrastructure) API로 설정됩니다. 버퍼 및 기타 창 리소스(표시 또는 오프스크린)는 특정 DXGI 인터페이스에 의해 생성되고 구성됩니다. IDXGIFactory2 팩터리 패턴 구현은 프레임 버퍼와 같은 DXGI 리소스를 획득합니다. DXGI는 스왑 체인을 소유하므로 DXGI 인터페이스를 사용하여 화면에 프레임을 표시합니다. IDXGISwapChain1을 참조하세요.

IDXGIFactory2를 사용하여 게임과 호환되는 스왑 체인을 생성합니다. HWND에 대한 스왑 체인을 만드는 대신 코어 창 또는 컴퍼지션(XAML interop)에 대한 스왑 체인을 생성해야 합니다.

디바이스 리소스 및 리소스 뷰

Direct3D 11은 보기라고 하는 비디오 메모리 리소스에 대한 추가 수준의 다형성을 지원합니다. 기본적으로 텍스처에 대한 단일 Direct3D 9 개체가 있는 경우, 이제 데이터를 보유하는 텍스처 리소스와 뷰가 렌더링에 사용되는 방법을 나타내는 리소스 뷰라는 두 개의 개체가 있습니다. 리소스를 기반으로 하는 뷰를 사용하면 해당 리소스를 특정 용도로 사용할 수 있습니다. 예를 들어, 2D 텍스처 리소스는 ID3D11Texture2D로 생성한 다음 셰이더 리소스 뷰(ID3D11ShaderResourceView)를 생성해 셰이더에서 텍스처로 사용할 수 있습니다. 동일한 2D 텍스처 리소스에 렌더링 대상 뷰(ID3D11RenderTargetView)를 생성해 그리기 화면으로 사용할 수도 있습니다. 또 다른 예에서는 동일한 픽셀 데이터가 단일 텍스처 리소스에서 2개의 개별 보기를 사용하여 2개의 서로 다른 픽셀 형식으로 표시됩니다.

기본 리소스는 해당 리소스에서 생성할 뷰 형식과 호환 가능한 속성으로 생성해야 합니다. 예를 들어 표면에 ID3D11RenderTargetView가 적용될 경우 이 표면은 D3D11\_BIND\_RENDER\_TARGET 플래그를 사용하여 만들어집니다. 표면은 또한 렌더링과 호환되는 DXGI 표면 형식을 사용해야 합니다(DXGI\_FORMAT 참조).

렌더링에 사용하는 대부분의 리소스는 ID3D11DeviceChild에서 상속되는 ID3D11Resource 인터페이스에서 상속됩니다. 꼭짓점 버퍼, 인덱스 버퍼, 상수 버퍼, 셰이더는 모두 Direct3D 11 리소스입니다. 입력 레이아웃 및 샘플러 상태는 ID3D11DeviceChild에서 직접 상속됩니다.

리소스 뷰는 DXGI\_FORMAT 열거형 값을 사용하여 픽셀 형식을 나타냅니다. 일부 D3DFMT는 DXGI\_FORMAT으로 지원되지 않습니다. 예를 들어 DXGI에는 D3DFMT\_R8G8B8에 해당하는 24bpp RGB 형식이 없습니다. 또한 일부 RGB 형식에 해당하는 BGR이 없습니다. 예를 들어 DXGI\_FORMAT\_R10G10B10A2\_UNORM은 D3DFMT\_A2B10G10R10과 동일하지만, D3DFMT\_A2R10G10B10에 직접 해당하는 형식은 없습니다. 이러한 레거시 형식의 콘텐츠를 빌드 시 지원되는 형식으로 변환할 계획입니다. 전체 DXGI 형식 목록을 보려면 DXGI\_FORMAT 열거형을 참조하세요.

Direct3D 디바이스 리소스(및 리소스 뷰)는 장면이 렌더링되기 전에 생성됩니다. 디바이스 컨텍스트는 아래에 설명된 대로 렌더링 체인을 설정하는 데 사용됩니다.

디바이스 컨텍스트 및 렌더링 체인

Direct3D 9 및 Direct3D 10.x에는 리소스 생성, 상태, 그리기를 관리한 단일 Direct3D 디바이스 개체가 있었습니다. Direct3D 11에서 Direct3D 디바이스 인터페이스는 여전히 리소스 생성을 관리하지만 모든 상태 및 그리기 작업은 Direct3D 디바이스 컨텍스트를 사용하여 처리됩니다. 다음은 디바이스 컨텍스트(ID3D11DeviceContext1 인터페이스)를 사용하여 렌더링 체인을 설정하는 방법의 예제입니다.

  • 렌더링 대상 뷰 설정 및 지우기(및 깊이 스텐실 뷰)
  • 입력 어셈블러 단계(IA 단계)에 대한 꼭짓점 버퍼, 인덱스 버퍼, 입력 레이아웃 설정
  • 파이프라인에 꼭짓점 및 픽셀 셰이더 바인딩
  • 셰이더에 상수 버퍼 바인딩
  • 픽셀 셰이더에 텍스처 뷰 및 샘플러 바인딩
  • 장면 그리기

ID3D11DeviceContext::Draw 메서드 중 하나가 호출되면 렌더링 대상 보기에 장면이 그려집니다. 완료되면 모든 그리기가 DXGI 어댑터를 사용하여 IDXGISwapChain1::Present1을 호출하여 완성된 프레임을 표시합니다.

상태 관리

SetRenderState, SetSamplerState, SetTextureStageState 메서드로 설정된 개별 토글의 큰 집합이 있는 Direct3D 9 관리형 상태 설정입니다. Direct3D 11은 레거시 고정 함수 파이프라인을 지원하지 않으므로 SetTextureStageState는 PS(픽셀 셰이더)를 작성하는 것으로 대체됩니다. Direct3D 9 상태 블록과 동등하지 않습니다. 대신 Direct3D 11은 렌더링 상태를 그룹화하기 위해 보다 간소화된 방법을 제공하는 4가지 종류의 상태 개체를 사용하여 상태를 관리합니다.

예를 들어 D3DRS\_ZENABLE의 SetRenderState를 사용하는 대신 이 상태 설정과 다른 관련 상태 설정에 대해 DepthStencilState 개체를 만든 다음 렌더링하는 동안 이 개체를 사용하여 상태를 변경합니다.

Direct3D 9 애플리케이션을 상태 개체로 포팅하는 경우 다양한 상태 조합이 변경할 수 없는 상태 개체로 표시된다는 점을 알아야 합니다. 한 번 생성되고 유효하다면 재사용해야 합니다.

Direct3D 기능 수준

Direct3D에는 기능 수준이라는 하드웨어 지원을 결정하는 새로운 메커니즘이 있습니다. 기능 수준은 잘 정의된 GPU 기능 집합을 요청할 수 있도록 하여 그래픽 어댑터의 수행 가능 작업을 간소화합니다. 예를 들어 9_1 기능 수준은 셰이더 모델 2.x를 포함하여 Direct3D 9 그래픽 어댑터가 제공하는 기능을 구현합니다. 9_1은 가장 낮은 기능 수준이므로 모든 디바이스에서 꼭짓점 셰이더와 픽셀 셰이더를 지원하는 것(Direct3D 9 프로그램 가능 셰이더 모델에서 지원하는 것과 동일한 단계)을 기대할 수 있습니다.

게임에서 D3D11CreateDevice를 사용하여 Direct3D 디바이스 및 디바이스 컨텍스트를 생성합니다. 이 함수를 호출할 때 게임에서 지원할 수 있는 기능 수준 목록을 제공합니다. 해당 목록에서 지원되는 가장 높은 기능 수준을 반환합니다. 예를 들어 게임에서 BC4/BC5 텍스처(DirectX 10 하드웨어의 기능)를 사용할 수 있는 경우 지원되는 기능 수준 목록에 최소한 9_1과 10_0을 포함합니다. 게임이 DirectX 9 하드웨어에서 실행되어 BC4/BC5 텍스처를 사용할 수 없으면 D3D11CreateDevice는 9_1을 반환합니다. 그러면 게임이 다른 텍스처 형식(및 보다 작은 텍스처)으로 대체됩니다.

Direct3D 9 게임을 확장하여 더 높은 Direct3D 기능 수준을 지원하기로 결정한 경우, 기존 Direct3D 9 그래픽 코드 포팅을 먼저 완료하는 것이 좋습니다. Direct3D 11에서 게임을 작업한 후에는 향상된 그래픽으로 렌더링 경로를 보다 쉽게 추가할 수 있습니다.

기능 수준 지원에 대한 자세한 설명은 Direct3D 기능 수준을 참조하세요. Direct3D 11 기능의 전체 목록은 Direct3D 11 기능Direct3D 11.1 기능을 참조하세요.

기능 수준 및 프로그래밍 가능 파이프라인

Direct3D 9 이후에도 하드웨어는 계속 발전해 왔으며 프로그래밍 가능한 그래픽 파이프라인에 몇 가지 새로운 선택적 단계가 추가되었습니다. 그래픽 파이프라인에 대한 선택적 집합은 Direct3D 기능 수준에 따라 다릅니다. 기능 수준 10.0에는 GPU에서 멀티패스 렌더링을 위한 선택적 스트림 아웃이 있는 지오메트리 셰이더 단계가 포함됩니다. 기능 수준 11_0에는 하드웨어 공간 분할에 사용할 수 있는 헐 셰이더 및 도메인 셰이더가 포함되어 있습니다. 기능 수준 11_0에서는 또한 DirectCompute 셰이더를 완전히 지원합니다. 반면 기능 수준 10.x에서는 제한된 형태의 DirectCompute만 지원합니다.

모든 셰이더는 Direct3D 기능 수준에 해당하는 셰이더 프로필을 사용하여 HLSL로 작성됩니다. 셰이더 프로필은 상위 버전과 호환되므로 vs_4_0_level_9_1 또는 ps_4_0_level_9_1을 사용하여 컴파일되는 HLSL 셰이더는 모든 디바이스에서 작동합니다. 셰이더 프로필은 하위 버전과는 호환되지 않으므로 vs_4_1을 사용하여 컴파일된 셰이더는 기능 수준 10_1, 11_0 또는 11_1 디바이스에서만 작동합니다.

SetVertexShaderConstant 및 SetPixelShaderConstant와 공유 배열을 사용하여 셰이더에 대한 Direct3D 9 관리형 상수. Direct3D 11은 꼭짓점 버퍼 또는 인덱스 버퍼와 같은 리소스인 상수 버퍼를 사용합니다. 상수 버퍼는 효율적으로 업데이트되도록 설계되었습니다. 셰이더 상수 전부로 단일 전역 배열을 구성하지 않고 상수로 논리적 그룹을 구성하고 하나 이상의 상수 버퍼를 통해 그룹을 관리합니다. Direct3D 9 게임을 Direct3D 11로 포팅하는 경우 상수 버퍼를 적절하게 업데이트할 수 있도록 구성하도록 계획합니다. 예를 들어, 모든 프레임이 업데이트되지 않는 셰이더 상수는 별도의 상수 버퍼로 그룹화하므로 동적 셰이더 상수와 함께 해당 데이터를 그래픽 어댑터에 지속적으로 업로드할 필요가 없습니다.

참고 대부분의 Direct3D 9 애플리케이션은 셰이더를 광범위하게 사용했지만 레거시 고정 함수 동작을 사용하여 혼합되는 경우도 있습니다. Direct3D 11은 프로그래밍 가능 음영 모델만 사용합니다. Direct3D 9의 레거시 고정 함수 기능은 사용되지 않습니다.