초기화

Oak_Cassia·2022년 5월 10일
0

DirectX 12

목록 보기
1/1

Direct3D

  • GPU 제어 및 프로그래밍 목적의 저수준 그래픽 API
  • 하드웨어 드라이버가 GPU의 고유한 기계어 명령어로 번역

Com

  • Component Object Model
    • 프로그래밍 언어 독립성과 하위 호환성을 위한 기술
  • COM 객체, COM 인터페이스 라고 불림
  • 다쓰고 Relese 호출
    • ComPtr 사용하면 호출할 필요 없음(자동)
  • Get: 바탕 COM 인터페이스를 가리킨느 포인터 반환
    • COM 인터페이스 포인터 형식의 인수를 받는 함수를 호출할 때 씀
  • GetAddressOf: 바탕 COM 인터페이스를 가리킨느 포인터 반환
    • 함수 매개변수를 통해 COM 인터페이스 포인터를 반환할 때 씀
  • Reset: ComPtr 인스턴스를 nullptr로 설정, 바탕COM 인터페이스의 참조 횟수 1감소

텍스처 형식

  • 2차원 텍스처는 자료 원소들의 행렬
    • 2차원 이미지 자료 저장
    • 텍스처의 각 원소에 픽셀 하나의 색상 저장
    • 3차원 벡터를 저장하기도 한다
  • 1차원 텍스처는 1차원 배열, 3차원 텍스처는 3차원 배열
  • 밉맵(?) 수준이 존재할 수 있다
  • 텍스처에 담는 원소로 DXGI_FORMAT 형식들 사용
  • RGBA를 담지만 3차원 벡터를 담기도 가능
  • 무형식 텍스처는 메모리 확보 후 자료의 해석 방식은 나중에 텍스처를 파이프라인에 묶을 때 지정하는 용도
  • 정점 자료 형식과 색인 자료 형식을 서술하 때 쓰인다

Swap chain

  • 이중 버퍼링
    • 한 프레임을 화면 바깥의 텍스처에 그린다. (후면 버퍼)
    • 후면 버퍼를 하나의 프레임으로 화면에 표시
    • 두 개의 텍스처 버퍼가 필요
      • front buffer(전면 버퍼)
      • back buffer(후면 버퍼)
    • 화면에 전면 버퍼에 담긴 정보 표시
    • 다음 프레임 후면 버퍼에 저장
    • 전면 버퍼와 후면 버퍼 역할 교체(presenting)
  • 전면 버퍼와 후면 버퍼 swap chain 형성

깊이 버퍼링

  • 깊이 버퍼는 이미지 자료를 담지 않는 텍스처
    • 각 픽셀의 깊이 정보 저장 (0.0~1.0)
  • 물체를 그리는 순서와 무관하게 깊이 정보로 순서를 표시
  • 각 물체들은 프레임의 한 픽셀을 두고 경쟁하는데 값이 더 작다면 후면 버퍼와 깊이 버퍼에 기록
    • 관찰자에 가장 가까운 픽셀이 렌더링

스텐실 버퍼: 픽셀이 후면 버퍼에 기록되지 않게 하는 버퍼

자원과 서술자(Descriptor)

  • 렌더링 중 GPU는 자원에 자료를 쓰거나 읽어들임
  • 그리기 명령 제출 전 참조할 자원을 렌더링 파이프라인에 바인딩
  • 그리기 호출마다 달라지는 자원이 있어 필요시 바인딩 갱신
  • GPU 자원들이 파이프라인에 묶이지 않음
    • 자원을 참조하는 서술자가 실제로 파이프라인에 묶임
      • 서술자는 GPU에 자원을 서술해주는 경량의 일종의 자료구조
  • GPU는 자원 서술자를 통해 자원의 실제 자료에 접근
  • 서술자를 통해 자료를 사용하는 데 필요한 정보 획득
  • GPU 자원은 범용적인 메모리 조각
    • 따라서 같은 자원을 렌더링 파이프라인의 서로 다른 단계에서 사용 가능
    • 자원 자체로는 형식을 알 수가 없어 서술자 사용
  • 서술자: 자원 자료를 지정, 자원을 GPU에 서술
    • 자원을 파이프 라인의 어느 단계에 묶어야 하는지 설명
    • 파이프라인에 묶을 자원의 부분 영역을 서술자로 지정할 수도 있음
    • 무형식 자원에 대해 구체적인 형식 명시 가능
    • View 라고도 한다.
    • 서술자 형식
      • CBV/SRV/UAV: (Const Buffer, Shader Resource, Unordered Access) View
      • RTV: Render Target View
      • DSV: Depth/Stencil View
      • sampler(?)
  • 서술자 힙: 서술자들의 배열, 서술자가 저장되는 곳
    • 종류마다 개별적인 힙 필요
    • 한 종류의 서술자는 같은 서술자에 저장
    • 하지만 한 종류의 서술자에 여러 개의 힙을 둘 수도 있음
    • 응용 프로그램 초기화 시점에 생성

다중표본화의 이론

  • 계단 현상이라 불리는 앨리어싱 효과가 있다.
    • 선을 픽셀들의 배열로 근사하면 발생
    • 해상도를 키우면 되나 키우는 게 불가능하거나 충분하지 않은 경우
      앨리어싱 제거 기법을 사용한다.

초과표본화(supersampling)

  • 후면 버퍼와 깊이 버퍼를 화면 해상도 보다 4배 크기로 한다.(가로 세로 2배)
  • 3차원 장면을 4배 크기의 해상도에서 후면 버퍼에 렌더링
  • 이미지를 화면에 제시할 때 후면 버퍼를 원래 크기의 버퍼로 환원(resolving)
  • 하향 표본화 라고도 불린다.
  • 4픽셀 블록의 네 색상의 평균을 블록에 해당하는 픽셀의 최종 색상으로 사용
  • 화면해상도를 소프트웨어에서 증가

다중 표본화(multisampling)

  • Direct3D 에서 사용
  • 일부 계산 결과를 부분 픽셀들 사이에서 공유해 초과 표본화보다 비용이 낮음
  • 4X 다중표본화: 초과 표본화처럼 크기가 화면 해상도의 4배인 후면 버퍼, 깊이 버퍼 사용
  • 이미지 색상을 각 부분픽셀이 아닌 픽셀당 한 번만 계산
  • 그 색상과 부분픽셀들의 가시성과 포괄도를 이용해 최종 색상 결정
    • 서브 픽셀의 중심이 다각형의 내부에 존재하는지를 파악

Direct3D에서 다중표본화를 하기 위해 DXGI_SAMPLE_DESC 구조체를 채워야 한다. 아래는 멤버

  • UINT Count: 픽셀당 추출할 표본의 개수
  • UINT Quality: 원하는 품질 수준
  • 위 구조체는 SwapChain 버프들과 깊이 버퍼 모두에 필요. 후면 버퍼, 깊이 버퍼를 생성할 때 동일한 다중표본화 설정을 적용

기능 수준

  • Direct3D 11에서 도입
  • D3D_FEATURE_LEVER 열거형
  • GPU가 지원하는 기능들의 집합을 정의

DXGI

  • DirctX Graphics Infrastructure
  • Direct3D와 함께 쓰이는 API
  • 공통되는 기능 처리(swpachain, 전체화면 등)

기능 지원 점검

  • ID3D12Device::CheckFeatureSupport로 여러가지 기능을 점검할 수 있다.
  • 12의 여러 기능, 하드웨어 아키텍처 기능, 기능 수준, 텍스처 형식에 대한 기능, 다중표본화 등

상주성

  • 텍스처, 3차원 메시 등 수많은 자원이 항상 GPU에 필요하진 않다.
  • 퇴거: 자원을 GPU 메모리에서 내림
  • 입주: 필요시 GPU 메모리에 올림

기본지식 끝~


CPU와 GPU

  • 그래픽 프로그래밍은 두 처리장치가 병렬로 작동
  • 동기화가 필요하지만 성능을 망치지 않게 조절해야 한다

Command Queue, Command List

  • cpu는 command list에 그리기 명령을 담고
    Direct3D API를 통해 대기열(command queue)에 제출한다.
  • 명령들을 대기열에 제출해도 GPU가 즉시 실행하는 것은 아니다.(GPU가 준비가 되면 실행)
  • 대기열이 비면 GPU가 놀고 꽉 차면 CPU가 논다.(os buffer?)
  • ID3D12CommandQueue
    • D3D12_COMMAND)QUEUE_DESC 구조체 채운 후 ID3D12Device::CreateCommandQueue 호출
  • 커맨드 리스트는 배열의 첫 원소부터 차례로 실행

동기화

  • 기존의 명령이 다 실행되지 않고 다음 명령이 덮어쓰여지면 문제 발생
  • GPU가 커맨드 큐의 명령들 중 특정 지점까지의 모든 명령을 다 처리할 때 까지 CPU를 기다리게 하는 방법 사용
    • 이 때 fence 객체가 필요

자원 상태 전이

  • Resource hazard: GPU가 자원에 자료를 다 기록하지 않거나 시작하지 않았을 때 자원을 읽으려 할 때 생기는 상황
    • Direct3D가 자원에 상태를 부여
  • transition resource barrier: GPU에 자원의 상태가 전이됨을 알려주는 하나의 명령

명령 목록을 이용한 다중 스레드 활용

  • 물체가 많을 때 장면 전체를 하나의 목록으로 그리려 하면 명령 목록을 구축하는 데 시간이 오래걸림
    • 병렬로 여러 명령 목록을 구축

초기화

  1. D3D12CreateDevice 함수를 이용해 ID3D12Device 생성
  2. ID3D12Fence 객체 생성 후 서술자들의 크기를 얻음
  3. 4X MSAA 품질 수준 지원 여부 점검
  4. 명령 대기열과 명령 목록 할당자, 주 명령 목록 생성
  5. Swapchain 서술하고 생성
  6. 응용 프로그램에 필요한 서술자 힙들을 생성
  7. 후면 버퍼의 크기를 설정, 후면버퍼에 대한 렌더 대상 뷰 생성
  8. 깊이 스텐실 버퍼를 생성, 그와 연관된 깊이 스텐실 뷰 생성
  9. 뷰포트와 가위 판정용 사각형들을 설정

장치 생성

  • Direct3D 초기화의 시작
  • Device는 디스플레이 어댑터를 나타내는 객체(물리 장치 혹은 소프트웨어)
  • 기능 지원 점검
  • 자원이나 뷰, 명령 목록 등 모든 Direct3D 인터페이스 객체들의 생성에 쓰임

fence 생성, 서술자 크기 얻기

  • CPU GPU 동기화 위한 fence
  • 필요한 서술자들의 크기 미리 조회해서 설정(GPU마다 크기가 다를 수 있음)

4X MSAA 품질 수준 지원 점검

  • 비용이 크지 않으면서도 화질 개선, 11급 장치가 모든 렌더 대상 형식에서 지원

명령 대기열과 명령 목록 생성

  • ID3D12ComandQueue
  • ID3D12CommandAllocator
  • Id3D12GraphicsCommandList

스왑 체인의 서술과 생성

  • DXGI_SWAP_CHAIN_DESC 구조체 인스턴스의 멤버들을 생성하려는 스왑체인에 맞게 설정

서술자 힙 생성

  • 서술자/뷰 들을 담음
  • ID3D12Device::CreateDescriptorHeap

렌더 타겟 뷰 생성 (RTV)

  • 후면 버퍼를 파이프라인의 output merger 단계에 묶으려면 후면 버퍼에 대한 RTV 생성이 필요하다.
  • 스왑체인에 저장된 버퍼 자원을 얻어야 함

깊이 스텐실 버퍼와 뷰 생성

  • 깊이 스텐실 버퍼 생성 전 뷰를 생성해서 파이프라인에 묶어야 함

뷰포트 설정

  • 3차워 장면을 후면버퍼의 일부를 차지하는 직사각혀 영역에 그리기
  • 2인용 모드를 위한 화면 분할

가위 직사각형 설정

  • 특정 픽셀 선별하는 용도
  • 가위 직사각형 바깥에 있는 픽셀은 후면 버퍼에 래스터화 되지 않는다.

시간 측정과 애니메이션

  • 애니메이션을 수행하려면 프레임 간 경과시간을 정확히 알아야 한다.
  • 프레임률이 높으면 더 정밀한 타이머 필요

성능 타이머

  • Windows가 제공하는 performance timer
  • 측정 단위는 지나간 클럭 틱의 개수
  • QueryPerformanceCounter((LARGE_INTEGER*)&currTime));
    • 반환이 아닌 매개변수에 현재 값 돌려줌
    • 역수는 틱당 초

이번 프레임 시간과 이전 프레임 시간의 차이를 구해 프레임 사이에 시간이 얼마나 흘렀는지 알 수 있다.

전체시간: 응용프로그램 시작 후 흐른 시간

profile
rust로 뭐할까

0개의 댓글