DirectX 11

220921

슬뷔 2022. 9. 26. 03:32

스왚체인은 두 버퍼중에 현재 프론트 버퍼를 윈도우에 복사를 시킨다.

그러려면 스왚체인은 만들어질때 출력될 윈도우가 누군지 알아야 된다. -> 목적지를 알아야한다.

 

스왚이펙트 = DISCARD -> 이전 버퍼의 그림을 없앤다 (스왚체인을 하면 백버퍼 프론트버퍼 바뀌기 때문에)

 

uuidof -> 클래스마다 고유한 id값

Adaptor

Factory

DXGIDevice 는 Dx디바이스에서 쿼리인터페이스에서 uuidof를 이용해서 값을 얻어온다.

쿼리인터페이스는 범용적인 함수이다. 앞에 자료형이 뭐냐에 따라서 그 주소를 줘야하기 때문에

두번째인자에 void 이중포인터로 받게 된다.

계층관계로 되어있어서 DXGIDevice에  getparent 하면 어댑터를 얻어낼 수 있다. 

어댑터의 윗층 부모가 팩토리여서 어댑터에 getparent 하면 팩토리를 얻어낼 수 있다.

 

스왚체인 만드는 곳이 팩토리에 있어서 팩토리까지 가야한다.

위 세개는 rc(레퍼런스 카운트)를 꼭 줄여줘야한다 (release를 해야함)

 

스왚체인 만들 때 이미 내부적으로 사용하는 버퍼옵션에 따라서 렌더타겟텍스쳐를 만들었다.

스왚체인->getbuffer (getbuffer 를 하면 참조를 하기 때문에 rc가 하나 증가한다)

 

랜더타겟뷰는 device가 갖고있기 때문에 

m_device->createrendertargetview 를 ㅏㅎ면 된다. 

createrendertargetview  -> 랜더타겟 용도로 제작된 텍스쳐를 전달하는 역할

 

뎁스스텐실텍스쳐(깊이를 저장하는 것이 목적인데 스텐실 값도 저장을 함)는 스왚체인이 들고있지 않는다.

스왚체인은 그림 그릴 목적지인 렌더타겟만 들고 있는다.

뎁스스텐실텍스쳐는 직접 제작해야한다.

D3D11_TEXTURE2D_DESC texdesc = {};

bindflags -> 텍스쳐의 용도인데 usage랑 좀 다르다.

만들어진 텍스쳐를 gpu 메모리에 가만히 두면 쓸 데가 없다.

랜더타겟텍스쳐도 결국 랜더링용으로 출력목적지로 지정하는 것이다.

 

gpu에는 메모리랑 연산하는 연산코어가 있는데, 

텍스쳐를 올리면 메모리에 접근해서 연산해서 그려내는 것이다.

메모리에 들어있는 리소스는 gpu 장치에 전달을 할 때, 텍스쳐의 용도에 맞게 바인딩을 하는 것이다.

만약 출력이 목적이라고 하면, 바인딩플래그는 랜더타겟이다. 

텍스쳐는 제작할 때부터 용도가 이미 설정이 되어있기 때문에 중간에 용도를 바꿀 수 없다.

그것에 맞지 않는 용도로 사용하려고 하면 문제가 생긴다.

 

다이나믹 -> 동적이다 라는 의미

 

cpu가 연산해서 gpu 메모리에 접근 

택스쳐가 c++ 코드를 이용해서 동일한 사이즈로 접근해서 (maping) 일치를 시킨다. 

사본?을 떠온건데(복사) 값을 채우고 보내서 덮어씌운다.

맵핑영역을 설정할 때 gpu에 있는 데이터를 우리쪽으로 가져오게 하려면 cpuaccessflag를 read 옵션을 줘야한다.

그럼 Usage는 STAGING로 가야한다.

맵핑영역을 설정할 때 일단 가져와서 gpu메모리가 어떻게 되어있는지 확인할 수 있고, 수정해서 다시 보낼 수 있다.

다이렉트로 직접 조작할 수는 없다.(완전히 다른 영역이기 때문에)

확인하고 수정해서 다시 덮어씌워 보내려면 read가 아닌 write 를 주어야한다.

그리고 Usage(사용용도)를 다이나믹으로 해야한다.

나중에 cpu 쪽에 데이터를 보내서 덮어 씌울 수 있다는 의미이다.

 

따라서,

Usage = D3D11_USAGE::D3D11_USAGE_STAGING;

CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_READ;

가 한 쌍이고,

 

Usage = D3D11_USAGE::D3D11_USAGE_DYNAMIC;

CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;

가 한 쌍이다.

 

두 개 다 되게 하려면 비트연산자를 조합해야한다.

 

Usage = D3D11_USAGE::D3D11_USAGE_DEFAULT;

CPUAccessFlags = 0;

 

CPU 쪽에서 접근해서 수정할 수 없고, 값을 렘영역으로 가져와서 볼 수도 없다.

 

뎁스 스텐실 텍스쳐는 우리가 접근할 이유가 없다.. -> gpu가 랜더링하는 과정에서 gpu에서 출력을 할거기 때문이다.

랜더타겟도 gpu가 연산하면서 그림을 그리는데 cpu로 가져올 필요가 없다.

스왚체인이 이미 하고있기 때문이다. -> 랜더타겟으로 그린 그림을 윈도우로 출력하는 기능을 한다.

그래서 맵핑해서 가져올 이유가 없고 오로지 그림그리고 화면에 출력만하면 되기 때문에 옵션을 주지 않아도 된다.

 

3byte는 깊이, 1byte는 스텐실을 저장해서 총 4byte.

 

해상도는 랜더타겟과 완전히 동일해야한다.

그려진거 그대로 깊이정보가 저장이 되어야하기 때문이다.

 

MipLevel -> 텍스쳐 한 장을 만들어 낼 때, 같은 해상도를 저퀄리티?로 여러개 만드는 것

이미지 로딩을 할 때 의미가 있음. 그래서 여기엔 0. 제작 안함

추가플레그도 필요없음.

 

이미지로딩 순서?

ssd -> 시스템메모리 ram에 로딩 -> gpu에 동일한 크기의 서브리소스 데이터 가져와서 로딩

 

그래픽스 파이프라인을 통해 그림을 그림..

아웃풋머지(om) 단계에서 최종적으로 그림을 출력할 때,

그림은 랜더타켓텍스쳐에 깊이는 뎁스스텐실텍스쳐에 출력이 될 것이다. 

OMㅇㅔ 출력 바인딩 단계를 셋팅해놔야하는데

RTT(RanderTargetTexture) 그림을 그리는 장치이다. DST(DepthStensilTexture) 깊이를 그리는 장치이다.

라고 바인딩을 거는 것이다.

OM 은 랜더링 관련 기능이니까 디바이스콘텍스트에 구현이 되어있다.

랜더타겟뷰로 전달하고, 뎁스스텐실뷰로 전달을 해서 바인딩을 한다.

 

Present 함수 -> 매 프레임마다 백버퍼를 색으로 채우고 프론트버퍼로 교체 (현재 그리고 있는 백버퍼와 윈도우에 나가고 있는 프론트버퍼를 교체)  

 

그림그리는건 gpu의 텍스쳐이고, 화면에 보이는건 윈도우 비트맵에 색을 채운것이다.

gpu의 텍스쳐를 색을 채워서 프론트버퍼로 지정해놓으면 present 함수 이용해서 버퍼 체인지해서 

완성된 그림을 윈도우쪽에서 받아볼 수 있다.

 

gpu는 코어가 수천개가 달라붙어서 병렬처리가 빠르기 때문에 속도가 쳐지지 않고 빠르게 연산할 수 있다.

 

 

'DirectX 11' 카테고리의 다른 글

220929  (0) 2022.09.29
220922  (0) 2022.09.26
220920  (0) 2022.09.22
220919  (1) 2022.09.19
220915  (0) 2022.09.15