OpenGL紅皮書版本8(GL 4.3)示例11.19將imageLoad()
放置在while循環中,保持輪詢,直到前一個基元的至少一個片段已更新此值。這本書說GLSL memoryBarrier()
例11.19顯示了一個非常簡單的內存障礙用例。它允許 片段之間的某種程度的排序得到保證。在
functionUsingBarriers()
的頂部,使用一個簡單的循環等待內存位置的內容 到達我們當前的原始ID。 因爲我們知道 沒有來自同一個基元的兩個片段可以落在相同的 像素上,所以我們知道當我們在 函數的主體中執行代碼時,來自前一個基元的至少一個片段是 處理。然後我們使用非原子操作來修改我們的 片段位置處的內存內容。我們發信號給其他着色器 調用,我們通過寫入最初在函數頂部輪詢的共享內存位置 來完成調用。爲了確保我們的修改的圖像內容寫回之前其他着色器調用內存 開始進入函數體中,我們使用 彩色圖像的更新和 原始計數器強制排序之間內存屏障通話。
然而,GL規範4.3表示由另一個調用書面
有一個調用民調內存假定其他調用已經啓動,可以完成其寫入
那麼我們怎麼能確保先前原語的片段調用已啓動並完成其寫入?
郵政SRC代碼
#version 420 core
layout (rgba32f} uniform coherent image2D my_image;
// Declaration of function
void functionUsingBarriers(coherent uimageBuffer i)
{
uint val;
// This loop essentially waits until at least one fragment from
// an earlier primitive (that is, one with gl_PrimitiveID - 1)
// has reached the end of this function point. Note that this is
// not a robust loop as not every primitive will generate
// fragments.
do
{
val = imageLoad(i, 0).x;
} while (val != gl_PrimitiveID);
// At this point, we can load data from another global image
vec4 frag = imageLoad(my_image, gl_FragCoord.xy);
// Operate on it...
frag *= 0.1234;
frag = pow(frag, 2.2);
// Write it back to memory
imageStore(my_image, gl_FragCoord.xy, frag);
// Now, we’re about to signal that we’re done with processing
// the pixel. We need to ensure that all stores thus far have
// been posted to memory. So, we insert a memory barrier.
memoryBarrier();
// Now we write back into the original "primitive count" memory
// to signal that we have reached this point. The stores
// resulting from processing "my_image" will have reached memory
// before this store is committed due to the barrier.
imageStore(i, 0, gl_PrimitiveID + 1);
// Now issue another barrier to ensure that the results of the
// image store are committed to memory before this shader
// invocation ends.
memoryBarrier();
}
並非我們所有人都有這本書。你能否真正向我們提供這個例子中正在發生的事情的具體細節?特別是,「以前的原始」是什麼意思? –
嗨尼科爾,我已經更新了這個問題。請重新閱讀。 –