2016-02-26 114 views
0

我有一個使用6 GL計算着色器序列的Marching Cubes的GPU實現,每個讀取緩衝區之前寫入的緩衝區都有相應的內存屏障。早期階段中使用的緩衝區保存臨時標記變量,並且在不再需要時將其大小調整爲0,但不會刪除,因爲我將在稍後的運行中再次使用它們。從GL計算着色器讀取緩衝區後釋放緩衝區

在某些階段,我需要從着色器中的緩衝區中讀取數據,然後在着色器完成之後立即釋放它,然後爲下一個着色器階段分配緩衝區。我的問題是如何安全地做到這一點。內存屏障文檔講述瞭如何在允許其他着色器讀取之前確保完成所有寫入操作,但在第一個着色器中沒有提到讀取操作。

如果我做的:

glUseProgram(firstShader); 
glDispatchCompute(size,1,1); 
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 
glNamedBufferData(firstBuffer,0,NULL,GL_DYNAMIC_DRAW); 
glNamedBufferData(secondBuffer,1000000,&data,GL_DYNAMIC_DRAW); 
glUseProgram(secondShader); 
glDispatchCompute(size,1,1); 

firstBuffer不能保證被調整,直至firstShader完成從中讀取?如果不是,我該如何做到這一點?

+0

請注意,在您的主要性能循環中分配/釋放內存不會在性能方面爲您帶來任何收益。事實上,如果重構計算着色器以使用共享變量而不是多次通過並讀取/寫入GPU內存,則可能會從算法中獲得更多。 –

+0

感謝您的評論Nicol。我正在建模非常大的網格,所以問題是內存使用而不是性能。我使用第一對通道來收集樣本,並找到生成幾何圖形的立方體,以便從那時起可以減少大量的調用次數。有幾點我必須將整個樣本空間保留在內存中,這可能需要幾百MB,所以我希望在完成後立即擺脫它。不知道如何去使用共享變量,因爲它們非常小並且僅限於單個工作組? – russ

回答

0

並且在不再需要時應將其調整爲0,但不會刪除,因爲我會再次希望它們用於以後的運行。

調整緩衝區大小等效於刪除緩衝區,並在同一個ID上分配新的緩衝區。

在某些階段,我需要從着色器中的緩衝區中讀取數據,然後在着色器完成之後立即釋放它,然後爲下一個着色階段分配緩衝區。我的問題是如何安全地做到這一點。

只要刪除它即可。在第一階段刪除緩衝區只會刪除該ID。該id只是對實際緩衝區對象的另一個引用。當調整大小或刪除緩衝區時,只有id和實際緩衝區之間的關聯被切斷。調整大小實際上會創建一個新的緩衝區,並將其重新與其關聯。實際上調用glBufferData將做同樣的事情(與glBufferSubData相反)。這被稱爲「孤兒」。

實際的緩衝區被釋放,一旦它的最後一個引用,無論是通過使用或從一個ID,下降。

+0

謝謝,這就是我需要知道的一切:) – russ