2014-05-17 83 views
2

我有一個片段着色器,使用圖像加載/存儲操作在imageBuffer上執行處理。 我專門關注以下情形:單階段(片段着色器),單通場景GLSL一致imageBuffer訪問

  • 我有一個片段着色器(無多級(例如頂點然後片段着色器)的考慮,也沒有多路渲染。)
  • ImageBuffer的變量聲明爲一致。獨家對連貫的圖像緩衝區感興趣。

爲了使事情非常清楚,我的情況是這樣的:

// Source code of my sole and unique fragment shader: 
coherent layout(1x32) uniform uimageBuffer data; 

void main() 
{ 
    ... 
    various calls to imageLoad(data, ..., ...); 
    ... 
    various calls to imageStore(data, ..., ...); 
    ... 
} 

我基本上都看了規範

ARB_shader_image_load_store

特別是這個非常段落:

「使用聲明的聲明作爲「一致」保證 商店的結果將立即可見,以着色器調用使用 類似聲明的變量;調用內存屏障需要 確保專賣店是可見的其他業務「

注:我的‘連貫統一ImageBuffer的數據;’聲明恰恰是一個‘類似聲明的’變量我的情況是單通。 ,單級(片段着色器)

現在,我已經看過各種網站和跌跌撞撞(大多數人一樣,我認爲)在此線程stackoverflow.com:

How exactly is GLSL's "coherent" memory qualifier interpreted by GPU drivers for multi-pass rendering?

多SP ecifically,這一段:

「着色器甚至不能作一個假設,一個店之後發出負載 將得到剛存儲在這個 很着色器中的內存(是真的。你必須在把內存屏障拉 一個關)「

我的問題是這樣的:。

隨着規定的一致預選賽中,在我的單着色器,單通處理的情況下,我可以肯定或不確定imageStore()對我的片段着色器的所有調用(例如當前的調用以及其他併發調用)是否立即可見?

通過閱讀ARB_shader_image_load_store規範對我來說:

  • 在這個問題的答案是肯定的,
  • 我不需要任何類型的內存屏障()的,
  • 在計算器上面引用線程引用的句子可能確實是誤導和錯誤的。

感謝您的見解。

+0

你是在一些重大的頭痛,如果你不要在此着色器使用一個內存屏障,既*** ***負荷,稍後存儲。如果你的抽牌只能得到一個單獨的片段,你可能會安全地把它關閉。但對於任何更大的場景,您需要同步片段着色器調用之間的同步,否則其他片段可能會在另一個存儲器之前加載。片段着色器可以按照驅動程序認爲會產生理智結果的任何順序進行安排,imageLoad/Store在考慮因素時被有效忽略,因爲它假定您知道自己在做什麼。 –

+0

@ AndonM.Coleman你沒有回答我的問題。這個問題是:**我可以肯定或不確定imageStore()對於我的片段着色器的所有調用(例如當前的調用以及其他併發調用)都將立即可見嗎?**換句話說,是在單一着色器階段加載/存儲連貫且類似聲明的變量**保證**將按順序執行?規範似乎說是的,一些論壇成員說不。您只是提及併發編程的一般問題。我知道我無法控制着色器調用的調度。 – fred54

+0

這是你的問題,然後沒有。 –

回答

0

使用內存屏障。

一方面GPU可以優化和取memeory的整個塊來讀取,並有單獨的存儲器寫入。

換句話說,如果你的着色器隨時修改單個位置只有一次,然後其確定,但如果將其轉發鄰居值之後,應用一些計算,那麼你需要的內存屏障。

0

有了規定,在我的單着色器,單通處理場景的連貫預選賽,可我是或否確保imageStore()的將立即到我的片段着色器的所有調用可見的(例如, 。當前的調用以及其他併發調用)?

如果每個片段着色器寫入圖像在不同的地點,每個片段着色器只讀取它寫的位置,那麼你甚至不需要coherent。但是,如果片段着色器實例想要讀取其他片段着色器實例寫入的數據,那麼您就是SOL。有沒有你可以爲那個做。

如果它是一個計算着色器,你可以發出barrier呼叫到工作組內的同步操作。這將確保您想要閱讀的寫作發生(您仍然需要撥打memoryBarrier以使其可見)。但是,這隻能確保在此工作組內的實例發生了寫入。來自其他實例的寫入仍未定義。

,更具體地說,本款:

順便說一句,那款是錯誤的。非常非常錯誤。太糟糕了,是誰寫的那款將永遠不會被識別的人;)