MALI Tile-based rendering簡單原理介紹

寫在最前

關於mali的架構的一點深入瞭解,將現有的GPU的基本流程和mali的做對比,提出其中的優點與缺點。原文地址:https://developer.arm.com/graphics/developer-guides/tile-based-rendering

傳統GPU

傳統GPU的架構一般被稱爲Immediate mode GPU.主要的流程就是vertex shader 和 fragment shader順序執行,僞代碼如下:

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

數據流是這樣的:

傳統GPU

優點

主要優點就是vertex的輸出能夠留在片上,可以被下一階段直接快速讀取。

缺點

如果有很大的圖形(主要是三角形)需要被渲染,那framebuffer就會很大,比如對於整個屏幕的顏色渲染或者深度渲染就會消耗很多存儲資源,但是片上是沒有這麼多資源的,因此就要頻繁讀取DDR。很多和當前frame有關的操作( 比如blending, depth testing 或者 stencil testing)都需要讀取這個working set,因此需要的帶寬是很大的,並且這樣能耗也很高,對於移動設備來說,這種方式很不利於設備運行。

Tile-based GPU

因此mali的GPU提出了Tile-based概念,就是將圖像分成16*16的小塊。分小塊進行渲染,最後寫入到DDR,就能夠減少讀寫DDR的頻率,進而解決上述問題。不過分塊需要知道整個圖像的幾何學信息,所以操作分成了兩步:

  1. 第一步執行幾何學相關的操作,併產生tile list.
  2. 第二步對每一個tile執行fragment操作,完成之後寫入內存

僞代碼如下:

# Pass one
for draw in renderPass:
    for primitive in draw:
        for vertex in primitive:
            execute_vertex_shader(vertex)
        append_tile_list(primitive)

# Pass two
for tile in renderPass:
    for primitive in tile:
        for fragment in primitive:
            execute_fragment_shader(fragment)

數據流如下:

maliGPU

優點

顯而易見,解決了傳統模型的帶寬問題,因爲fragment shader每次都是讀取一個小塊放在片上,不需要頻繁讀取內存,直到最後操作完成,再寫入內存。甚至還能夠通過壓縮tile的方法進一步減少對於內存的讀寫。另外在圖像有一些區域固定不動的時候,通過調用函數判斷tile是否相同,減少重複的渲染。

缺點

這個操作需要在vertex階段之後,將輸出的幾何數據寫入到DDR,然後才被fragment shader讀取。這之間也就是tile寫入DDR的開銷和fragment shader渲染讀取DDR開銷的平衡。另外還有一些操作(比如tessellation)也不適用於Tile-based GPU。

總結

現在屏顯的分辨率越來越大從1080p到1440p再到4K,可以遇見的,mali這種架構將在未來大規模使用。

不過也有一些陷阱,開發者需要避開。首先是要合理設置render pass以充分利用這種架構的特點;其次要了解這種幾何學分割所能得到的好處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章