ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1. DirectX 기초
    Software/DirectX 2024. 5. 24. 08:54
    728x90

     

    Table of Contents

    1. Com 객체
    2. 전면버퍼(front buffer)와 후면버퍼(back buffer)
    3. 깊이 버퍼(Depth buffer)
    4. 자원과 서술자(View)  
              * 뷰의 종류  
              * 자원과 서술자(View)
    5. 샘플링(Sampling)
    6. 기능 수준(feature level)
    7. DXGI (DirectX Graphics Infrastructure)
    8. 상주성(Residency)


     

    1. Com 객체

    COM 클래스는 DirectX SDK에서 제공되는 파이프라인 구조들을 담는 인스턴스들을 일컬으며 다음과 같은 특성이 있다.

    • COM 클래스는 생성자에 할당자가 포함되어 있어 new 키워드로 생성하지 않아도 된다.
    • 또한 해제할때 delete가 아니라 해당 메서드내부의 release를 호출해주면 된다.
    • COM 클래스를 효율적으로 관리하기 위한 COMPTR 스마트 포인터라는 매서드를 SDK에서 제공한다.
    • COMPTR은 범위를 벗어나면 자동으로 Release를 호출하기 때문에 사용자가 따로 해제코드를 실행시켜주지 않아도 된다.
    • 해당 클래스들은 WRL라이브러리에 포함되어 있다. #include <wrl.h>
    • COM인터페이스들은 모두 I로 시작한다.
    • Tip 객체 생성함수인자로 넘겨줄때 .GetAddressOf() 매서드를 사용해 해당 인스턴스를 쉽게 넘겨줄 수 있다.
      ex) CreateAllocator(list_type,mAlloc.GetaddressOf());

     

     

     

    2. 전면버퍼(front buffer)와 후면버퍼(back buffer)

     어떤 오브젝트가 게임 상에서 애니메이션을 실행한다고 가정해보자. 이 때 하나의 화면에서 해당 움직임을 프레임 단위로 그렸다 지웠다를 반복한다면 사용자에게는 화면이 지워지는 깜빡임 현상이 발생할 것이다.

     이러한 깜빡임 현상 없이 자연스러운 애니메이션을 표현하기 위해 DirectX에서는 화면을 두개(전면과 후면)으로 나누고 한 화면이 표시되고 있을 때 표시되고 있지 않은 화면에 그림을 그린 후, 그림이 완성되면 교체하는 방법을 사용해 깜빡임 현상을 없애는 기법을 사용하고 있다.

    이 때 사용자가 보고 있는 화면을 전면버퍼(front buffer), 컴퓨터가 그림을 그리는 화면을 후면버퍼(back buffer) 라고 한다. 전면버퍼와 후면버퍼를 바꾸는 과정을 제시(Presenting)혹은 SwapChain이라고 한다.

    • 스왑체인 과정은 COM객체 중 IDXGISWAPCHAIN이 담당한다.
    • 전면버퍼와 후면버퍼를 바꾸는 과정은 해당 서로의 포인터만 맞바꾸면 되므로 효율적이다.
    • 이렇게 전면과 후면 버퍼 두 개의 화면을 번갈아 사용하는 방법을 이중 버퍼링 이라고 한다.
    • 삼중 버퍼링도 가능하지만 이중버퍼링으로도 표현에 부족함이 없다.

     

     

     

    3. 깊이 버퍼(Depth buffer)

     깊이 버퍼는 해당 오브젝트의 깊이정보(일반적으로 내 화면에서 양의 z방향 값)를 담고 있는 버퍼이다. 텍스쳐와 같은 형태로, 텍스쳐와 1:1 매칭된다. Depth buffer는 0(카메라와 가장 가까운 지점)부터 1(카메라와 가장 먼 지점)으로 나뉘며 각각의 물체의 깊이를 판단해서 화면에 출력될 픽셀의 색을 갱신해나간다.

     첫 초기화때 해당 픽셀은 사용자가 지정한 바탕색으로 초기화되며 깊이버퍼는 1.0(가장먼곳)이 된다. 렌더링 전에 하나씩 물체 정보를 갱신하면서 1.0보다 가까운 깊이를 가진 물체가 있으면 해당 픽셀 위에 존재하면 그 물체의 픽셀로 해당 지점을 갱신한다.
    이러한 판정을 거쳐 해당 픽셀에 가장 가까운 물체에 해당하는 픽셀이 최종 승자가 되어 후면버퍼에 렌더링되게 된다.

    보통 원소 형식으로 depth와 stencil을 함께 사용하는 뎁스 스탠실 버퍼를 사용하며 스탠실은 좀더 고급주제이므로 후 장에서 다루도록 한다.

     

     

     

    4. 자원과 서술자(View)

     서술자(View)는 GPU가 자원을 어떤 단계의 파이프라인에 묶을것(BInd)할 것인지에 대해 서술하는 간접 층이다.
    이러한 간접층을 두는 이유는 리소스 자체에는 해당 리소스를 어떤 단계에 써야하는지, 어느만큼 적용시켜야하는지에 대한 명시를 같이 포함하고 있지 않기 때문이다. 또한 무형식으로 생성된 리소스를 서술자가 구체적으로 형식을 명시해 사용할 수 있게 만들어 주는 역할도 한다.

     

    뷰의 종류
    • ConstBuffer View (상수 버퍼를 관리하는 서술자)
    • Shader Resource View (쉐이더를 관리하는 서술자)
    • Unordered acceess view (순서 없는 접근 관리 서술자)
    • Sampler State View ( 표본추출기(sampler)를 관리하는 서술자)
    • Render Target View( 렌더 대상을 관리하는 서술자)
    • Depth Stencil View (깊이와 스탠실을 관리하는 서술자)

     

    뷰의 특성
    • 이러한 뷰들은 서술자힙(descriptor heap)에 저장된다.
    • 서술자 종류마다 개별적인 서술자 힙이 필요하다.
    • 하나의 자원에 여러종류의 서술자가 참조할 수있다.
    • 예를 들어 텍스쳐렌더에 쓰인 텍스쳐가 쉐이더 단계로 넘어가서 색을 표시하는데 사용될 수도 있다.
    • 서술자들은 응용 프로그램 초기화 시점에서 생성하는 것이 실행 시점에서 생성하는것보다 낫다.
    • 무형식 자원은 정말 필요할 때에만 사용하는것이 최적화를 위한 지름길이다

     

     

     

    5. 샘플링(Sampling)

     샘플링(Sampling)은 계단현상(aliasing)을 제거하는 기법을 일컬으며 안티 엘리어싱(anti aliasing)이라고도 한다.

    샘플링엔 다음과 같은 기법이 있다.

     

    SuperSampling

    • 이 기법은 후면버퍼 크기를 전면의 4배로 잡고 물체를 그린다음 전면으로 이동시키는 방법이다. 이는 전면버퍼에 비해 4배 많은 픽셀값을 계산해야 하므로 메모리 소비량이 매우 높아진다는 단점이 있다. 대신 부분 픽셀값이 서로 다른 색을 가지므로 정확도가 높다

     

    MultiSampling (다중표본화)

    • 슈퍼 샘플링의 메모리 소모 문제를 해결하기 위해 절충적으로 나온 안티엘리어싱 기법이 다중표본화(MultiSampling)이다.
      다중표본화는 픽셀 하나를 4부분으로 쪼개지만 픽셀당 한번만 색을 계산하는 기법이다. 계산횟수가 상대적으로 낮다.

     

    파이프 라인 단계에서 가장 높은 비용(계산량)을 필요로 하는 단계가 색을 계산하는 단계이다. 따라서 다중표본화는 픽셀당 한번계산이고 슈퍼샘플링은 픽셀당 부분픽셀 4번 계산하므로 비용이 상당히 낮다. 하지만 정확도는 슈퍼샘플링이 훨씬 높다.

    D3D에서 다중표본화를 사용하기 위해서는 DXGI_SAMPLE_DESC라는 구조체를 적절히 채워서 스왑체인과 깊이버퍼에 적절히 설정해줘야한다. 후면버퍼와 깊이버퍼를 생성할때 동일한 샘플러를 적용해야한다.

     

     

     

    6. 기능 수준(feature level)

     현재 하드웨어의 그래픽카드가 어느정도 Direct 버전까지 지원하는지를 확인하는 열거형 구조체이다. 대략 Dx9버전부터 11까지의 버전들이 들어있다. 실제 응용프로그램에서는 구형 하드웨어를 사용하는 이용자가 있으므로, 해당 구조체로 하드웨어 정보를 파악한 후 그것에 맞는 환경을 제공하는 것을 고려해야 한다.

     

     

     

    7. DXGI (DirectX Graphics Infrastructure)

     DXGI는 D3D와 함께 사용되는 API다. 그래픽 자료들은 포맷은 서로 다르지만 공통된 작업을 필요로 하는 경우가 있다.이렇듯 서로 다른 포맷을 가진 자료들의 공통된 그래픽 처리를 담당하는 것이 DXGI 인터페이스이다. 예를 들어 SWAP CHain은 3d뿐만 아니라 2d 애니메이션에도 매끄러운 움직임을 위해 필수적인 작업이다. 따라서 Swap chain은 d3d가 아닌 DXGI에 소속된 인터페이스 이다.

     그 밖에도 디스플레이 어뎁터나 모니터, 지원되는 디스플레이 모드등 공통적인 그래픽 기능을 열거하는 기능을 DXGI가 제공하고 있다.

     

    DXGI의 핵심 인터페이스 종류
    • IDXGIFactory : 스왑체인과 디스플레이 어뎁터등을 생성하는 데 사용되는 인터페이스
    • IDXGIAdapter : 여기서 디스플레이 어뎁터는 주로 그래픽카드를 의미한다. 하지만 소프트웨어 디스플레이 어댑터도 존재한다. 컴퓨터에는 여러개의 어댑터가 있을 수 있고(내장그래픽과 외장그래픽) 이를 어느 시점에서 사용할 지 결정시킬 수 있다.
      이 때 Microsoft Basic Render Driver는 윈도우 8이상에 포함된 소프트웨어 디스플레이 어댑터이다.
    • IDXGIOutput : 디스플레이 출력
    • DXGI_MODE_DESC : 디스플레이 모드 멤버 구조체
    • ID3D12Device::CheckFeatureSupport : 하드웨어 기능 지원 여부를 점검할 수 있는 많은 정보들을 담고 있는 함수

     

     

     

    8. 상주성(Residency)

     상주성이란 자원이 GPU메모리에 들어있는 지에 대한 여부를 의미한다. 예를 들어 게임의 레벨이나 지역이 바뀌는 시점에 필요한 자원만 메모리로 올리고 나머지는 메모리에서 내리는 것을 상주성 관리라고 한다. 상주성 관리가 중요한 이유는 GPU를 다른 응용프로그램에서도 사용할 수 있으므로 GPU점유를 프로그램이 최소화 해야한다는 점이다.

     하지만 제일 중요한 것은 GPU에 같은 자원을 빠른 시간내에 올렸다 내렸다 하는것을 최대한 피해야 한다는 것이다. GPU에 자원을 올리는 작업이 비용이 크기 때문이다. 이는 최적화와 밀접한 관련이 있다. 따라서 이상적으로는 한동안 GPU에서 사용하지 않을 자원들만 GPU 메모리에서 내려야한다. 기본적으로 자원을 생성하면 GPU메모리에 입주하며, 파괴되면 메모리에서 나간다. 게임의 볼륨이 커질수록 상주성 관리가 중요하고 직접 관리해 줘야한다.

     

     

     

    728x90

    'Software > DirectX' 카테고리의 다른 글

    6. 입력조립기 ( Input Assembler )  (0) 2024.05.24
    5. 파이프라인과 3차원 표현  (0) 2024.05.24
    4. 타이머  (0) 2024.05.24
    3. DirectX 초기화  (0) 2024.05.24
    2. CPU와 GPU의 상호작용  (0) 2024.05.24