[GPU] Tile-based Rendering (Mobile GPU)

ARM Mail GPU는 Tile-based Rendering 기술을 지원한다. Tile-based Rendering이란 Framebuffer를 작은 단위로 나누어서 Rendering 작업을 수행하는 것이다. Mail GPU의 경우 16 x 16 Pixel단위로 나누어서 Rendering 연산을 수행한다. 출처 1은 Tile-based Rendering의 장점, 단점을 정리한 글이다. 출처1의 글을 읽고 짧게 정리해보았다.

Immediate Mode GPUs

기존 PC GPU는 Immediate Mode Rendering을 지원한다. Immediate Mode Rendering 이란 Command Stream을 준수하여서 Primitive마다 Vertex Shader 연산과 Fragment Shader 연산을 순서대로 수행하는 것을 의미한다. 아래 Pseudo Code는 Immediate Mode Rendering 연산의 순서를 보여준다 (해당 부분은 Parallel Processing 및 Pipeline에 대한 부분은 제외되어 있다).

for draw in renderPass:
    for primitive in draw:
        for vertex in primitive:
            execute_vertex_shader(vertex)
        for fragment in primitive:
            execute_fragment_shader(fragment)

아래 그림 1은 위 Pseudo Code를 도식화한 것이다.

그림 1: Immediate Mode Rendering 순서 (출처 1)

Advantage: Immediate Mode Rendering

가장 큰 장점은 Vertex Shader 연산의 결괏값이 GPU의 On-chip 메모리에 저장되어 있어서 Fragment Shader 연산을 수행할 때 이득이 있다. On-chip 메모리에 Vertex Shader의 연산 결괏값이 저장되어 있기 때문에 중간 결괏값 (Intermediate Geometry State) 로딩에 따른 Bandwidth 사용량이 적다.

Disadvantage: Immediate Mode Rendering

가장 큰 단점은 Triangle이 기존 결괏값을 덮는 경우에 발생한다고 한다 (정확한 의미를 제대로 파악하지 못하였는데 아마로 Depth Test로 인해서 기존의 삼각형을 덮는 새로운 삼각형을 그리는 것을 의미하는 것 같다). 이런 경우 Framebuffer의 중간 결괏값 (Framebuffer Working Set)을 계속 읽고 써야 하는 문제가 발생한다. Framebuffer의 중간값으로는 Color Buffer, Depth Buffer, Stencil Buffer등이 있다. 1440p를 지원하는 안드로이드 단말의 경우 Framebuffer의 중간 결괏값의 크기가 대략 30MB 정도로 추측할 수 있다.

  • 1440p Screen: 2560 x 1440 Pixel = 3,686,400 Pixel
  • Color + Depth/Stencil: 64bits = 8Bytes
  • Total Size: 3,686,400 x 8Bytes = 28,800KB = 28.125MB (대략 30MB)

30MB에 해당하는 데이터는 On-chip 메모리에 저장하기 힘들기 때문에 Off-chip DRAM에 저장한다. Blending, Depth Testing, Stencil Testing과 같은 연산작업은 중간 결괏값 (Working set)을 사용하게 된다. 그리고 Fragment Shader 연산에서 거의 모든 Fragment (Pixel)에 해당하는 중간값을 Read하고 연산 결괏값은 다시 Write (Read-Modifed-Write)하는 작업을 반복적으로 수행해야 한다. 결과적으로 Off-chip 메모리 (DRAM을 의미하는 듯)에 반복적인 Access로 인한 Bandwidth 사용량이 많다. 정리하면 메모리 Access로 인한 파워 사용량이 증가하게 되고, 모바일과 같은 디바이스에서는 Critical 한 문제가 될 수도 있다.

Tile-based GPUs

Mail GPU는 Tile-based Architecture을 사용한다고 한다. Tile-based Rendering의 경우 External Memory Access를 최소화한다. 앞에서 설명한 바와 같이 Tile-based Rendering은 작은 단위로 나누어서 Rendering 작업을 수행하는 것이다. Mail GPU의 경우 16 x 16 Pixel (16 x 16 Tiles)로 타일링한다. 각 Tile에 대한 Fragment Shader 연산이 완료되면 메모리로 Write 한다고 한다. Tile-based Rendering의 경우 Tile에 포함된 삼각형 Geometry 정보를 알기 위해서, 아래와 같이 2가지 Step으로 나누어서 연산을 수행한다.

(정확한 이해한 게 맞는지 몰라서 영어도 첨부하였다)

  • Step 1: 모든 Geometry 연산을 수행하여 타일을 생성한다. 각 타일은 어떤 primitive를 포함하고 있는지 알고 있다 (The first pass executes all of the geometry related processing, and generates the tile lists which indicate which primitives contribute to each screen tile).
  • Step 2: 타일 단위로 Fragment 연산을 수행한다. 각 타일의 Fragment 연산이 끝나면 해당 결괏값을 메모리에 저장한다 (The second pass executes all of the fragment processing, tile by tile, writing tiles back to memory as they have been completed).

아래 Pseudo Code는 위 2개의 Step을 의미한다.

for draw in renderPass:
    for primitive in draw:
        for vertex in primitive:
            execute_vertex_shader(vertex)
        append_tile_list(primitive)
for tile in renderPass:
    for primitive in tile:
        for fragment in primitive:
            execute_fragment_shader(fragment)

아래 그림 2는 위 Pseudo Code를 도식화한 그림이다.

그림 2: Tile-based Rendering 순서 (출처 1)

Advantage: Tile-based Rendering (Bandwidth)

가장 큰 장점은 메모리(Off-chip Memory를 의미하는 것 같음) Bandwidth를 적게 사용한다는 것이다. Fragment Shader 연산을 하면서 Read-Modified-Write형태의 연산을 자주 수행하게 되는데 Tile-based Rendering의 경우 작은 Tile에 대한 데이터 결괏값만 필요로 하므로 대부분 데이터가 On-chip 메모리에 로딩되어 있다. 그렇기 때문에 Off-Chip 메모리에 대한 Access가 줄게 되고 그로 인해 Bandwidth 사용량이 줄어든다. 특히 Fragment-Heavy Content의 경우 Memory Bandwidth로 인한 부하가 큰 편이기 때문에 더 큰 이득을 볼 수 있다고 한다.

추가로 Framebuffer Bandwidth Saving Optimization이 가능하다고 한다. 간단히 설명하면 현재 타일에서 연산한 결과와 이전 Framebuffer에 저장(이전 연산된 결과)되어 있는 데이터의 차이가 발생하지 않으면 Main Memory에 결과를 Update하지 않아도 된다. 이러한 부분을 제거하기 위해서 CRC Check (Transaction Elimination, 네트워크 등에서 Error Correction등에 사용되는 기술임)을 사용하여 같은 결과를 2번 업데이트하지 않는다고 한다. 예를 들어 게임  UI부분은 크게 변화가 없다. 이러한 부분은 결과를 메인 메모리에 매번 저장할 필요가 없다. 결과적으로 Bandwidth 사용량은 감소한다. 하지만, 성능에는 이득이 없다고 한다. 결괏값이 같은지 여부를 판단하기 위해서는 현재 Tile도 모든 Fragment 연산을 수행해야 하기 때문이다.

다음으로 Compression을 통한 Bandwidth 사용량을 줄이는 방법에 대한 설명이 있다 (개인적으로 이 부분은 Tile-based Rendering을 사용하여 Bandwidth 사용량이 줄어든다기보다는
단지 Bandwidth를 줄이기 위해서 ARM에서 만든 기술인 것 같다). ARM에서 만든 Compression 기술은 ARM FrameBuffer Compression (AFBC)이라고 한다. 해당 Compression은 Render-to-Texture Output에서 사용 가능하다. Render-to-Texture은 이전에 계산된 Fragment 데이터값을 다음 Render Pass에서 Input으로 사용하는 경우를 의미한다 (현재 이 부분에 대해서 공부를 하고 있는데 보통 하나의 Scene을 화면에 출력하기 위해서 여러 개의 Render Pass를 걸쳐서 계산하게 된다. 하나의 Render Pass에서 Texture을 생성하게 된다. 이렇게 생성된 결과를 불러서 다음 Render Pass에서 Texture로 사용한다. 보통 전체 화면에 대한 Texture 연산을 수행한다거나, 빛(Light)과 같은 연산을 할 때 자주 사용되는 것 같다).

  • 추가: 문서 중간정도에 Stencil Buffer 또는 Depth Buffer을 1번만 사용되는 경우 glDiscardFramebufferEXT (glInvalidateFramebuffer )와 같은 연산을 추가하여서 Main Memory에 Stencil 또는 Depth 결괏값을 저장하지 않을 수 있다는 내용이 있다. 솔직히 무슨 말인지 잘 모르겠다.

Advantage: Tile-based Rendering (Algorithm)

Tile-Based Rendering을 사용하면 다양한 Rendering Algorithm을 추가 할 수 있다고 한다. 아래 2가지 Algorithm 예제를 정리해보았다.

  • Multi-Sample Anti-Aliasing (MSAA): Tile-based Rendering을 사용하지 않는 경우 MSAA 연산을 위해서 추가 Render Pass가 필요하다. 하지만, Tile-based Rendering의 경우 MSAA 연산을 위한 메모리 값을 On-chip에 저장해 놓을 수 있다고 한다.
  • Deferred Lighting (Deferred Shading와 같은 개념인 듯함):  Deferred Shading이란 Light 연산을 줄이기 위한 방법이다 (출처 3 참조). 보통 MSAA와 같이 Render Pass를 나누어 연산해야 하는데, Tile-based Rendering의 경우 역시나 Tile 단위로 연산을 수행함으로 필요한 데이터 값을 On-chip 메모리에 저장해놓을 수 있다.

아직 위 알고리즘을 정확하게 이해하지 못해서 생기는 문제인지 아니면 내가 제대로 이해를 했기 때문에 보이는 문제인지는 잘 모르겠다. 하지만, 위 알고리즘 모두 앞에서 언급했던 Framebuffer를 여러 번 Access 하는 문제를 해결하는 것과 큰 차이가 없어 보인다. 새로운 Render Pass를 만들게 되면 결과적으로 Framebuffer에 대한 Access가 증가하게 되고, 그럼 Bandwidth가 늘어나는 문제가 발생할 수밖에 없는 것 같다. 결과적으로 Tile-based Rendering을 사용하면 Bandwidth 사용량이 줄어드는 이점 1개 뿐이 없는 것 같다.

Disadvantage: Tile-based Rendering

가장 큰 단점은 Immediate Rendering 기법과 달리 중간 결괏값 (Vertex Shading 연산 결과: (예) Varing Data, Intermediate State)을 Off-chip 메모리에 저장해야 한다. 결과적으로 Tile-based Rendering이 Immediate Rendering 대비 Bandwidth를 더 많이 사용하는 경우도 발생 할 수 있다는 의미이다. 이와 더불어 Tessellation과 같이 Immediate Rendering에서 강점을 보이는 기능들은 Tile-based rendering에서는 사용하면 Bandwidth 사용량이 더 증가 할 수도 있다.

또 개인적인 생각입니다. 아마도 Tile-base Rendering이란 기능은 우리가 쓰는 모바일 기기에서 최적화 할 수 있는 기술인 것 같다. 컴퓨터와 같이 배터리 Resource의 제한이 없다거나, 연산이 많이 지원하는 경우 큰 이득이 없어 보이는 것 같다.

출처

  1. https://developer.arm.com/graphics/developer-guides/tile-based-rendering
  2. https://developer.qualcomm.com/download/adrenosdk/vulkan-developer-guide.pdf
  3. https://learnopengl.com/Advanced-Lighting/Deferred-Shading

Leave a Comment