Application 을 구동하기 위해서 연산을 담당하는 CPU 외에 구동에 필요한 리소스를 저장하는 메모리인 RAM이 필요하다. 마찬가지로 GPU 또한 그래픽 연산을 위한 RAM을 가지고 있으며 이는 무한하지 않다.
게임 등에서 렌더링 퀄리티를 올리는 데 많은 요소가 있지만 그 중 눈에 확연히 띄는 것은 아마 texture일 것이다. 고해상도의 texture 를 사용할 수록 결과물의 선명도에서 큰 차이를 보일 것이다. 다만 언급했다싶이 RAM의 제한때문에 무한정 큰 texture 를 사용할 수 없고 render scene에서 샘플링되는 고해상도의 texture가 많다면 cache hit, memory bandwidth 등에서 성능 하락을 야기하며 심할 경우 RAM 부족으로 프로그램을 돌릴 수 없는 상황까지 이르게 될 것이다.
더불어, 모바일 디바이스의 경우 단순히 RAM 점유율 문제 뿐만 아니라 memory 병목은 배터리 효율 또한 일으킬 수 있다.
따라서 texture data를 압축하여 보관/사용 하는 것은 꽤나 중요한 일이다. 압축에는 크게 손실/비손실(lossy/lossless) 그룹으로 나눌 수 있을 것이며, 대표적인 손실 압축포멧은 JPEG, 비손실 압축포멧은 PNG를 들 수 있을 것이다. 다만 이런 압축 포멧은 GPU상에서 사용될 수 없는데, PNG의 경우 압축을 해제하는 시간이 컨텐츠에 따라 가변적이며 JPEG는 압축 해제에 걸리는 시간이 크다. 또한 정해지지 않은 압축비율로 인하여 GPU에서는 해당 포멧을 바로 사용하지 못하고 결국 bitmap data로 upload 후 사용 가능하다.
Texture compression을 GPU에서 활용하기 위해서는 다음과 같은 제약사항이 있다.
- 압축 알고리즘이 간단하고 해제 시 걸리는 시간이 짧아야 하며
- 압축비가 일정해야 한다
이러한 요건을 만족하는 포멧은 BC (Block Compression), ETC/EAC (Ericsson Texture Compression), ASTC (Adaptable Scalable Texture Compression) 등이 있다.
이러한 포멧들은 모두 lossy compression이며, 이미지 품질저하에도 불구하고 큰 압축률 (BC1의 경우 RGBA 이미지를 작은 4x4 pixel block로 만들며, 하나의 block을 8byte로 압축한다. 즉 8:1 압축비를 가지며 RGBA 1024x1024 이미지의 경우 4MB -> 0.5MB로 압축 가능하다)에 대한 이점이 있어 널리 쓰이고 있다.
다양한 압축 포멧이 있는 이유 중 하나는 특허 문제로, BC1~5 의 압축포멧을 사용하기 위해서는 특허료를 내야했다. 이를 피하기 위해 모바일 GPU vendor에서 ETC1, ETC2 등을 개발하였고 Android 단말에서는 거의 표준으로 사용되고 있다. 또한 컨텐츠에 따라 각 압축 포멧 별로 좋은 품질을 유지하는 것이 달라 다양하게 쓰이고있다. ASTC는 그 중 가장 최신에 나온 포멧이며 사용료가 없어 많이 사용되기 시작하며, Vulkan Core API에서 지원되며, OpenGL ES 3.1에서도 지원되기 시작한다.
특히 ASTC의 경우 block scale을 다르게 설정할 수 있어, 컨텐츠별로 block size를 변화시킬 수 있으며, ASTC 4x4의 경우 ETC 보다 품질이 좋아 normal map 등에도 사용할 수 있다.
그 외에 GPU vendor사에서 사용하는 압축 알고리즘이 존재한다. 대표적인 예로 ARM의 AFBC (ARM Frame Buffer Compression)와 Qualcomm의 UBWC (Universial Bandwidth Compression)을 들 수 있다.
AFBC의 경우 Framebuffer 를 압축하는 것으로 lossless compression으로 품질에 영향을 주지 않으며, framebuffer에 있는 attachment가 AFBC 지원되는 포멧일 때 압축하여 load/store 에서 memory bandwidth 이점을 얻을 수 있다.
위 그림과 같이 AFBC를 사용하였을 경우 tile 에 올라가 있던 attachment 정보를 store 하는 것을 알려주는 external write bandwidth 가 약 33% 줄어든 것을 알 수 있으며, 이는 memory bottleneck 상황에서 크게 성능을 향상함과 동시에 배터리 소모 또한 줄이는데 도움이 될 것이다.
UBWC 의 경우는 기존의 texture compression이나 AFBC와는 다르게, 이미지 버퍼에 한정되지 않고 지원되는 포멧이라면 모두 압축을하여 다른 IP에 전달하는 역할을 한다. 즉 texture 외에도 vertex/index buffer 등이 지원이 되는 포멧이라면 이를 모두 압축하여 전달하는 것이다.
위와 같이 texture compression 을 사용할 경우 package size 뿐만 아니라 bandwidth 측면에서 큰 이득을 볼 수 있고 이는 성능 향상 또는 배터리 소모량을 줄여주게 된다. 또한 특정 GPU vendor에서 지원되는 compression 이 있는지 확인 하고 어떤 포멧이 지원되는지 확인하는 것이 좋다 (예로 attahcment의 포멧을 RGB8과 RGBA8 로 설정하고 비교하였을 때 RGB8을 위한 총 buffer size가 RGBA8 보다는 적을 것이지만, vendor compression에서 RGBA8만 지원된다면 실제 성능은 RGBA8가 더 좋게 나온다).
ref:
godotengine.org/article/betsy-gpu-texture-compressor
developer.nvidia.com/astc-texture-compression-for-game-assets
sv-journal.org/2014-1/06/en/index.php?lang=en
www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/
developer.qualcomm.com/qfile/34706/80-nb295-7_a-adreno_vulkan_developer_guide.pdf
'잡다' 카테고리의 다른 글
Bitonic sort (0) | 2020.12.22 |
---|---|
OIT : Weighted, Blended OIT (0) | 2020.12.09 |
Order Independent Transparency (0) | 2020.12.03 |
Android Vulkan layer 적용 (0) | 2020.11.18 |
Vulkan Layer (0) | 2020.11.14 |