作者Ninja5566 (苦味)
看板C_and_CPP
標題[問題] OpenGL Compute Shader同步不同group
時間Fri Dec 23 04:34:15 2016
開發平台(Platform): (Ex: Win10, Linux, ...)
Win10
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
VS2015
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
OpenGL 4.3
問題(Question):
我想利用compute shader做一個global index array
假設我每個在 compute shader 中的 work group 有一個 shared variable, 叫做local index array,
array長度固定, 但是裡面內含的有效index 數量並非固定, 例如說:
shared int array[1024]; // 每一個work group 自己具有的array
group 1: length = 3, array = 3, 4, 2, -1, -1, -1, -1.... (-1代表無效值)
group 2: length = 5, array = 1, 5, 3, 4, 6, -1, -1, -1,..
group 3: length = 1, array = 2, -1, -1, -1, -1....
因為我想要節省記憶體, 所以我想把這些group的local index array merge到
global index array, 也就是一個Shader Storage Buffer Object
, 並且讓他長成以下這個樣子:
global index array = 3, 4, 2, 1, 5, 3, 4, 6, 2, -1, -1, .....
此array 為group 依序將自己的 index array 接到前一個group的 array後方
我現在的問題是, 是否有辦法做到這件事情? 困難點在於, group 2必須要等到
group 1貼完array(或至少要更新一個offset讓group 2 知道他要從哪邊開始貼)
,group 3 也要等到group 2 更新玩global index array的offset才知道要從哪裡開始
但是 OpenGL 的barrier 只有同步同一個group的thread功能, 並無法同步不同
group, 所以我想請問有甚麼方法可以達到我的要求?
我原本的想法是用一塊Shader Storage Buffer Object 來記錄說最後一個更新
list offset group的編號是多少, 還沒有輪到你的group就在一個while loop
裡面等, 但是我在想這個方法是不是沒甚麼效率, 會不會有比較好的解法?
請各位前輩幫忙回答一下, 感謝!
程式碼(Code):(請善用置底文網頁, 記得排版)
補充說明(Supplement):
其實我想實作Forward Plus Rendering, 但是一直不知道linked list
該怎麼做..
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 65.186.78.215
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1482438858.A.089.html
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 04:34:43
1F:推 Sidney0503: 為何不使用vao vbo? 12/23 08:03
2F:→ Ninja5566: compute shader完全不相容rendering pipeline 12/23 08:16
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 09:48:19
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 11:49:56
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 11:51:28
3F:→ johnjohnlin: 基本上要 2-pass,用 parallel prefix sum 作 12/23 15:30
因為我不是很熟compute shader, 所以這邊我是用猜的, 有錯請指正
如果用兩個pass, local index array勢必無法宣告成shared, 因為一旦第一
個pass (算local index array)執行完, shared variable會被回收, 所以
local index array 就必須要存在 SSBO. 但是這樣一來做所謂的prefix sum就
沒有意義了, 因為
1. 我直接要存取的話就讀local index array的SSBO就好, 何必讀global index array?
2. 既然local index array都存在SSBO了, 省下記憶體的目標基本上也失敗了
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 21:58:40
4F:→ johnjohnlin: 第一個 pass 只產生 element 數量,prefix sum 之後 12/23 23:06
5F:→ johnjohnlin: 就是 offset 了,gpu 幾乎不會有 global sync thread 12/23 23:07
6F:推 johnjohnlin: 如果不 care order 的話,用 atomic add 應該還行 12/23 23:10
只產生數量會造成計算浪費, 因為要得到數量前必須要先算local index array
有哪些, 所以第二階段雖然有了正確的offset, 但是還要再算一次local index有哪些
才能update global index array
其實我這邊沒講清楚是我的疏忽, 每個rendering cycle中, 每個work group所
產生的 index array 有效長度都會變動, 所以不能假設它們數量是固定的
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 23:38:29
※ 編輯: Ninja5566 (65.186.78.215), 12/23/2016 23:41:02