2017-09-10 61 views
0

在我的Vulkan應用程序中,我使用了一個命令緩衝區,並且我預先記錄了其中的所有內容,現在我有一個錯誤和其中一個我懷疑它的地方,我將數據區域從暫存緩衝區複製到GPU(設備本地)緩衝區,然後在該緩衝區上執行操作。單個命令緩衝區中的同步

問題是,即使在使用單個命令緩衝區時,是否應該進行同步?

我的問題並不是只針對複製緩衝區,這是一個普遍的問題,是否有任何情況下,即使在一個命令緩衝區的應用程序,你應該做同步?

回答

1

在Vulkan中,您必須幾乎同步所有內容。

這不是因爲您只使用一個命令緩衝區,所以命令不能異步運行。我們假設你正在複製一個緩衝區,並且想在讀取這個緩衝區之後作爲一個頂點緩衝區。

您必須發出從TRANSFER_STAGEVERTEX_INPUT_STAGE以及srcAccess TRANSFER_WRITE和dstAccess VERTEX_ATTRIBUTE_READ的內存屏障。

通過這種方式,屏障確保傳輸完成,並且內存既可用又可見。

它可能是這樣的紅色: 當第二個命令到達VERTEX_INPUT_STAGE時,請等待先前的命令完成TRANSFER_STAGE(它是執行障礙)。並且爲TRANSFER_STAGE刷新TRANSFER_WRITE緩存並使VERTEX_INPUT_STAGEVERTEX_ATTRIBUTE_READ緩存無效(這是內存屏障)。我在這裏使用了flush/invalidate這個詞,因爲某些階段TOPBOTTOM沒有訪問內存,所以嘗試對它們執行內存屏障是沒有用的。

但是,我讀到您正在使用暫存緩衝區,當您寫入暫存緩衝區時,來自HOST的memoryBarrier由提交命令緩衝區組成。但是,如果您不使用COHERENT內存,則必須使用vkFlushMappedMemoryRanges

一個好主意,可以使用障礙之前,你會使用DATAS:

TRANSFER 
WORK that do not use the value transferred 
BARRIER 
USE DATAS 

你可以有更多的信息here甚至當我使用

+0

我想,我對命令緩衝區內命令的執行順序有一個完全錯誤的想法(我不知道爲什麼它首先出現在我的頭上)。這次仔細閱讀規範後,我現在對我頭腦中的每一個同步想法都很悲觀,並且我看到很多矛盾在我讀到的例子中,直到現在和我現在的想法,現在我的問題是命令是同步的?有沒有? –

+0

那些具有內存影響(或受內存影響)的命令只需要同步?通過記憶我的意思是(緩衝區和圖像) –

+0

在我給答案的結尾,我解釋了很多關於記憶障礙的內容。但是,哪些命令是同步的,我會說同一個子通道內的vkCmdDraw是「已經」同步的。 同步不僅適用於內存。您也可以使用純粹的執行屏障:來自資源的使用值,B寫入新值。您必須等待A完成,但不需要對它們執行內存屏障。 –

0

應該怎麼做同步一個命令緩衝區?

我很想做出一個單詞答案:「是」。

即使使用單個緩衝區(或通常是一個隊列),也需要同步,因爲命令緩衝區中的命令允許在執行過程中重疊。您需要將其訪問同步到資源VkImage s,VkBuffer s及其內存)。你通常用管道障礙這樣做,它在隊列中的命令的某些子操作之間添加執行依賴關係存儲器依賴關係

您可能正在使用應用程序中的交換鏈。沒有「呈現管道」與管道屏障同步,因此必須使用信號量進行同步。

最後你還是需要與主機(CPU)同步。您不允許銷燬仍在使用中的手柄(並且最終您需要銷燬/清理)。您必須通過使用圍欄或類似圍欄vkDeviceWaitIdle()的同步來確保它們未被使用。

而且我們不要忘記(一如既往)您需要同步CPU線程。要在Vulkan中具體說明,您仍需要將傳遞給命令的參數進行同步/互斥。

只有少數例外,你不必做某種明確的同步。例如,只要在調用vkQueueSubmit之前發生,就不需要同步連貫(或刷新)的主機(CPU)寫入。