2016-08-02 27 views
1

我使用計算着色器將單像素點渲染到uint32紋理中。紋理是3d紋理,x和y是視口座標,z具有座標0和1上的附加屬性的深度信息,因此如果您願意,可以使用兩個手動構建的rendertargets。代碼看起來像這樣:手動深度渲染:儘管使用原子操作的隨機結果

layout (r32ui, binding = 0) coherent volatile uniform uimage3D renderBuffer; 
layout (rgba32f, binding = 1) restrict readonly uniform imageBuffer pointBuffer; 

for(int j = 0; j < numPoints/gl_WorkGroupSize.x + 1; j++) 
{ 
    vec4 point = imageLoad(pointBuffer, ...) 
    // ... transform point ... 
    uint originalDepth = imageAtomicMin(renderBuffer, ivec3(imageCoords, 0), point.depth); 
    if (originalDepth >= point.depth) 
    { 
     // write happened, store the attributes 
     imageStore(renderBuffer, ivec3(imageCoords, 1), point.attributes); 
    } 
} 

雖然深度值是正確的,我有幾個像素在兩個值之間閃爍的屬性。

pointBuffer中點的順序是隨機的(但我已經驗證了所有點的集合總是相同的),所以我的第一個想法是兩個相等的深度值可能會更改輸出,具體取決於哪一個來自第一。所以我做了它,if originalDepth == point.depth它使用imageAtomicMax始終具有相同的兩個替代屬性書面,但沒有改變。

我散落在各地barrier()memoryBarrier(),但這並沒有改變。我也爲此刪除了所有分歧的控制流,沒有任何改變。

將本地工作大小減少到32個可消除90%的閃爍,但仍有一部分依然存在。

任何想法將不勝感激。

編輯:之前你問我爲什麼手動做這個東西,而不是使用正常的光柵化和片段着色器,原因是性能。光柵化器沒有幫助,因爲我渲染單像素點,共享內存大大加快了速度,並且我多次渲染每個點,這就要求我使用速度較慢的幾何着色器。

回答

1

問題是這樣的:您在寫入renderBuffer時遇到競爭狀況。如果兩個不同的CS調用映射到相同的像素,並且他們都決定寫入該值,則您的imageStore調用中會有一場競賽。一個可能會覆蓋另一個,可能是部分覆蓋,或者完全是其他的東西。但無論如何,它不能保證工作。

這可以通過執行光柵化器來最好地解決:將流程分成兩個獨立的階段。第一階段執行... transform point ...部分,將數據寫入緩衝區。第二階段然後通過點並將它們寫入最終圖像。

在階段2中,每個CS調用執行鍼對特定輸出像素的處理的全部。這樣,沒有競爭條件。當然,這要求階段1以可以按照像素排序的方式產生數據。

關於後者有幾種方法。您可以使用鏈接列表,每個像素列表。或者你可以使用每個工作組的列表,其中工作組代表像素空間的某個X/Y區域。在這種情況下,您可以使用本地共享內存作爲本地深度緩衝區,所有CS調用都從該區域讀取/寫入。在他們完成處理像素後,將它寫出到實際內存中。基本上,你會手動實現基於瓦片的渲染。事實上,如果你有一個批次這些點,一個基於磁貼的解決方案將允許你合併流水線,所以你不必等到第一階段完成之後再開始一些階段2.您可以將階段1分解爲塊。你開始幾個階段1塊,然後是從第一階段1讀取的階段2塊,然後是另一階段1,等等。

Vulkan與其事件系統相比,OpenGL有更好的工具來構建這樣一個高效的依賴鏈。

+0

我自己寫了一封評論,直接在imageStore上面聲明「這裏有潛在的競爭條件」,但由於某種原因決定不承擔責任。可能太專注了......反正謝謝:)我正在渲染一個64x64 shadowmaps的地圖集,並且每個SM都有一個工作組,但這太大了,無法在共享內存中使用深度緩衝區。兩個問題:每個工作組列表不只是將問題從全局移動到共享內存,我還需要解決那裏的競爭條件?其次,流水線會需要幾個調度調用嗎? – karyon

+0

「*每個工作組列表不只是將問題從全局移動到共享內存,我還需要解決那裏的競爭條件?*」是的,但有些事情可以在那裏解決,這些都相對便宜。 –

+0

一個指針從哪裏開始將是很好的,因爲我在這裏結束了我的知識,這東西很難谷歌...... – karyon