DX12엔진에서 64KB Align문제 해결 – Texture

몇일전 포스팅 했다시피 DX12에선 모든 D3DResource가 64KB Align을 요구하고, 그래서 1Byte짜리 버퍼만 할당해도 64KB짜리가 할당된다.
Voxel Horizon은 상당히 많은 개수의 Voxel-Object를 만들어내므로 DX12버전에선 GPU메모리를 미친듯이 먹고 있었다.

앞선 포스팅에서 언급했다시피 Vertex Buffer와 Index Buffer에 대해서는 직접 만든 heap에 64KB Align된 D3DResource를 결합해서 해결했다.

그리고 Texture가 남았다. 이게 처음에 좀 난감했다.  왜냐하면 1차원 버퍼가 아니고 2차원 이상의 버퍼이기 때문이다. 2차원 버퍼에 대한 heap을 만들려다가 포기하고 쉬운 방법을 선택했다.

현재 Voxel-Object의  Light Texture에 대해서는 가로 길이를 64픽셀로 고정하고 있다. 복셀의 개수가 많아져서 patch개수가 늘어나면 텍스처의 세로 길이가 길어진다.
OK. 그러면 텍스쳐의 세로 길이를 heap에서 리턴하는 어드레스와 일치시키면 되겠네.

Light Texture는 16bits(2bytes)포맷에 가로길이는 64픽셀이므로 64KB에 맞추려면 세로 사이즈는 512픽셀이 된다.

즉 512bytes로 align된 어드레스를 리턴하는 heap이 있으면 된다. 여기에 D3DTexture의 세로 사이즈 (2 – 512 사이)를 요청해서 얻은 어드레스를 512로 나눈  나머지가 텍스처(64 x 512 pixels) 안에서 Start-Y좌표가 된다. 어드레스가 512이상인 경우는 어드레스를 512로 나눈 값이 D3DTexture 배열에서의 인덱스가 된다.

가로 사이즈는 64로 고정이므로 결국 VertexBuffer, IndexBuffer를 heap에 맵핑한 방법과 똑같은 것이다.

이 방법을 사용해서 Vertex Buffer , Index Buffer , Texture까지 전부 64KB Aligned D3DResoruce로 할당했다.

그리고 테스트.

현재 GPU 메모리 808MB로 표시되고 있고 게임 실행전에 500MB정도 소모하고 있던 상태이므로 게임이 소모하는 GPU메모리는 300MB정도.
작업 들어가기전 몇일전 측정했을때 DX12에서 총 3.2GB정도, 게임에서 먹는데 2.8GB정도 먹고 있었다.

시스템 메모리는 Command Queue pool을 만들면서 실수로 CommandAllocator->Reset()을 호출하지 않아서 Command Allocator가 계속 커졌던것. 이 버그는 어제 잡았다.

결국 DX12로 실제 플레이할 수 있는 제품을 만들어내려면 이런식의 리소스 관리가 필요하다.

After – 64KB Aligned D3DResource + Custom Heap 적용
voxel_horizon_dx12_2017_0628

Before – D3D API로 D3DResource 할당 후 바로 사용

voxel_horizon_2017_0624_dx12


답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

w

%s에 연결하는 중