일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Dijkstra
- 다익스트라
- 그래프
- Brute Force
- Hash
- 스토어드 프로시저
- 이진탐색
- union find
- SQL
- Trie
- Two Points
- String
- MYSQL
- binary search
- DP
- Stored Procedure
- two pointer
- Today
- Total
codingfarm
Direct3D의 초기화 - 깊이, 스텐실 버퍼와 뷰 생성 본문
이제 깊이, 스텐실 버퍼를 생성해야 한다. 이전에 설명했듯이, 깊이 버퍼는 그냥 깊이정보를 담는 (그리고 스텐실을 사용하는 경우 스텐실 정보도 담는) 2차원 텍스처이다. 2차원 텍스처를 생성할 때에는 생성할 텍스처를 서술하는 D3D11_TEXTURE2D_DESC 구조체를 채우고 ID3D11Device::CreateTexture2D 메서드를 호출해야 한다. D3D11_TEXTURE2D_DESC 구조체의 정의는 아래와 같다.
typedef struct D3D11_TEXTURE2D_DESC {
UINT Width;
UINT Height;
UINT MipLevels;
UINT ArraySize;
DXGI_FORMAT Format;
DXGI_SAMPLE_DESC SampleDesc;
D3D11_USAGE Usage;
UINT BindFlags;
UINT CPUAccessFlags;
UINT MiscFlags;
} D3D11_TEXTURE2D_DESC;
1. Width : 텍스처의 너비(텍셀 단위)
2. Height : 텍스처의 높이(xprtpf eksdnl)
3. MipLevels : 밉맵 수준의 갯수. 깊이$\cdot$스텐실 버퍼를 위한 텍스처에서는 밉맵 수준이 하나만 잇으면 된다.
4. ArraySize : 텍스처 배열의 텍스처 갯수. 깊이$\cdot$스텐실 버퍼의 경우에는 텍스처 하나만 필요하다.
5. Format : 텍셀의 형식을 뜻하는 필드로, DXGI_FORMAT 열거형의 값들 중 하나를 지정한다. 깊이$\cdot$스텐실 버퍼의 경우에 나온 형식들 중 하나를 사용해야 한다.
6. SampleDesc : 다중 표본 갯수의 품질 수준을 서술하는 구조체. 4X MSAA는 화면 해상도의 4배 크기인 후면 버퍼 하나와 깊이 버퍼 하나를 사용해서 부분 픽셀당 색상과 깊이$\cdot$스텐실 정보를 담는다. 따라서 깊이$\cdot$스텐실 버퍼를 위한 다중표본화 설정은 렌더 대상에 쓰인 설정과 일치해야 한다.
7. Usage : 텍스처의 용도를 뜻하는 필드로, D3D11_USAGE 열거형의 값들 중 하나를 지정한다.
가능한 값은 아래의 4가지이다.
value | feature |
D3D11_USAGE_DEFAULT | $\bullet$ 자원을 GPU가 읽고 써야 한다면 이 용도를 설정한다. $\bullet$ 이 용도를 설정하면 CPU는 자원을 읽거나 쓸 수 없다. $\bullet$ 깊이$\cdot$스텐실 버퍼에 대한 모든 읽기$\cdot$쓰기는 GPU가 수행하므로 깊이\$cdot$스텐실 버퍼를 위한 텍스처를 생성할때에는 바로 이 D3D11_USAGE_DEFAULT 를 사용한다. |
D3D11_USAGE_IMMUTABLE | $\bullet$ 자원을 일단 생성한 후에는 그 내용을 바꾸지 않는 경우에 이 용도를 지정한다. $\bullet$ 이용도를 지정하면 자원이 GPU 읽기전용이 되어서 몇가지 최적화가 가능해진다. $\bullet$ CPU와 GPU는 이러한 불변 자원에 자료를 기록할 수 없다. $\bullet$ CPU는 불변 자원의 자료를 읽을 수 없다. |
D3D11_USAGE_DYNAMIC | $\bullet$ 응용 프로그램(CPU)이 자원의 내용을 빈번하게 갱신해야 한다면(가령 매 프레임마다) 이 용도를 지정한다. $\bullet$ 이 용도로 성된 자원은 GPU가 읽을 수 있고 CPU가 기록할 수 있다. $\bullet$ GPU의 자원을 CPU에서 동적으로 갱신하면 성능상의 피해가 생긴다. 새 자료를 CPU 메모리(즉 시스템 RAM)에서 GPU 메모리(즉 비디오 RAM)로 전송해야하기 때문이다. $\bullet$ 따라서 이 동적 용도 자원은 꼭 필요한 경우가 아니라면 피해야 한다. |
D3D11_USAGE_STAGING | $\bullet$ 응용 프로그램(CPU)이 자원의 복사본을 읽어야 한다면(즉, 자원이 자료를 비디오 메모리에서 시스템 메모리로 전송할 수 있어야 한다면) 이 용도를 지정해야 한다. $\bullet$ GPU에서 CPU 메모리로의 자료 복사는 느린 연산이므로 꼭 필요한 경우가 아니라면 피해야 한다. |
8. BindFlags : 자원을 파이프라인에 어떤 식으로 묶을 것인지를 지정하는 하나이상의 플래그들을 OR로 결합해서 지정한다. 깊이$\cdot$스텐실 버퍼의 경우 D3D11_BIND_DEPTH_STENCIL 플래그를 지정해야 한다. 그 외에 텍스처에 대해 가능한 결속 플래그(bind flag)를 들자면
(a) D3D11_BIND_RENDER_TARGET : 텍스처를 렌더 대상으로서 파이프라인에 묶는다.
(b) D3D11_BIND_SHADER_RESOURCE : 텍스처를 셰이더 자원으로서 파이프라인에 묶는다.
9. CPUAccessFlags : CPU가 자원에 접근하는 방식을 결정하는 플래그들을 지정한다.
value | 기능 |
D3D11_CPU_ACCESS_WRITE | CPU가 자원에 자료를 기록해야 할경우 |
D3D11_USAGE_DYNAMIC D3D11_USAGE_STAGING |
CPU의 쓰기 접근이 가능해야 할 경우 |
D3D11_CPU_ACCESS_READ | CPU가 자원을 읽어야 할 경우 |
0 | 깊이$\cdot$스텐실 버퍼의 경우 GPU만 깊이$\cdot$스텐실 버퍼를 읽고 쓸 뿐 CPU는 전혀 접근하지 않을 경우 |
10. MiscFalgs : 기타 플래그들로, 깊이$\cdot$스텐실 버퍼에는 적용되지 않으므로 그냥 0을 지정하면 된다.
참고
앞에서 용도 플래그 D3D11_USAGE_DYNAMIC과 D3D11_USAGE_STAGING은 성능상의 피해가 있으므로 피해야 한다고 말했다. 이 둘의 공통 요인은 CPU가 관여한다는것으로, CPU 메모리와 GPU 메모리 사이에서 자료가 오가면 성능에 악영향이 미친다. 최대 속도를 위한 최선의 방법은 모든 자원을 생성해서 GPU에 올린 후 GPU 메모리에 유지하고 GPU만이 그것을 읽고 쓰는 식으로 그래픽 하드웨어가 작동하게 만드는 것이다. 응용 프로그램에 따라서는 CPU가 반드시 관여해야 하므로 이 플래그들을 피할 수 없는 경우도 있지만, 어쨋든 이 플래그들은 최소한으로만 사용하는 것이 바람직하다.
다양한 옵션들의 활용은 나중에 살펴보고, 지금은 깊이$\cdot$스텐실 버퍼의 생성에 필요한 옵션들에 집중한다.
후면버퍼와 마찬가지로, 깊이$\cdot$스텐실 버퍼를 사용하려면 그에 대한 깊이$\cdot$스텐실 뷰를 생성해서 파이프라인에 붙여야 한다. 그 과정은 렌더 대상 뷰의 것과 비슷하다. 다음은 깊이$\cdot$스텐실 텍스처와 해당 깊이$\cdot$스텐실 뷰를 생성하는 방법을 보여주는 코드이다.
D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = mClientWidth;
depthStencilDesc.Height = mClientHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//4X MSAA를 사용하는가? 반드시 교환 사슬의 MSAA 설정과 일치해야 함.
if( mEnable4xMsaa ){
depthStencilDesc.SampleDesc.Count = 4;
depthStencilDesc.SampleDesc.Quality = m4xMsaaQuality-1;
}
//MSAA를 사용하지 않음
else{
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
}
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
ID3D11Texture2D* mDepthStencilBuffer;
ID3D11DepthStencilView* mDepthStencilView;
HR(md3dDevice->CreateTexture2D(
&depthStencilDesc, // 생성할 텍스처를 서술하는 구조체
0,
&mDepthStencilBuffer)); // 깊이, 스텐실 버퍼를 가리키는 포인터를 돌려준다.
HR(md3dDevice->CreateDepthStencilView(
mDepthStencilBuffer, // 뷰를 생성하고자 하는 자원.
0,
mDepthStencilView)); // 깊이, 스텐실 뷰를 돌려준다.
CreateTexture2D의 두번째 매개변수는 텍스처에 채울 초기 자료를 가리키는 포인터이다. 그런데 지금 이 텍스처는 깊이, 스텐실 버퍼로 사용할 것이므로 따로 자료를 채울 필요가 없다. 깊이 버퍼링과 스텐실 연산을 수행할 때 Direct3D가 직접 깊이, 스텐실 버퍼를 기록한다. 따라서 이 둘째 매개변수에는 널 값을 설정한다.
CreateDepthStencilView 메서드의 둘째 매개변수는 D3D11_DEPTH_STENCIL_VIEW_DESC 구조체를 가리키는 포인터이다. 이 구조체는 특히 자원의 원소의 자료형식을 서술한다. 형식을 완전히 지정해서 자원을 생성햇다면(즉 무형식 자원이 아니라면) 이 매개변수에 NULL 값을 지정해도 된다. 그러면 메서드는 주어진 자원을 생성했을 때 지정한 형식을 적용해서 자원의 첫 번째 밉맵 수준에 대한 뷰를 생성한다. 지금 예의 경우 깊이, 스텐실 버퍼는 형식을 지정해서 생성한 자원이므로 널 값을 지정했다.
'computer graphics > DirectX11' 카테고리의 다른 글
Direct3D의 초기화 - 뷰포트 설정 (0) | 2020.11.29 |
---|---|
Direct3D의 초기화 - 뷰들을 출력 병합기 단계에 묶기 (0) | 2020.11.29 |
Direct3D의 초기화 - 렌더 대상 뷰의 생성 (0) | 2020.11.28 |
Direct3D의 초기화 - 교환 사슬의 설정 및 생성 (0) | 2020.11.28 |
Direct3D의 초기화 - 4X MSAA 품질 수준 지원 점검 (0) | 2020.11.28 |