Synchronizacja między buforami poleceń w Vulkan
Jest kilka sposobów na synchronizację w Vulkanie. Tak to rozumiem:
- ogrodzenia są synchronizacją GPU Z CPU.
- semafory są synchronizowane przez GPU do GPU, są używane do synchronizacji kolejki zgłoszenia (w tych samych lub różnych kolejkach).
- zdarzenia są bardziej ogólne, resetowane i sprawdzane zarówno na CPU, jak i GPU.
- bariery są używane do synchronizacji wewnątrz bufora poleceń.
W moim przypadku mam dwa bufory poleceń. I chcę drugi bufor poleceń do wykonania po pierwszym.
submitInfo.pCommandBuffers = &firstCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
// wait for first command buffer to finish
submitInfo.pCommandBuffers = &secondCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
Jaki rodzaj synchronizacji jest do tego najlepszy?
Jeśli używam vkQueueWaitIdle(queue)),
czy to to samo, co używanie ogrodzenia, czy powinienem użyć do tego zdarzenia lub semaforów?
Jeśli w tym samym czasie wyślę do kolejki wiele poleceń:
std::vector<VkCommandBuffer> submitCmdBuffers = {
firstCommandBuffer,
secondCommandBuffer
};
submitInfo.commandBufferCount = submitCmdBuffers.size();
submitInfo.pCommandBuffers = submitCmdBuffers.data();
Czy jest jeszcze sposób na synchronizację między pierwszym i drugim? 2 answers
Pierwszym buforem polecenia jest obiekt renderujący z włączonym testem głębokości. Drugi bufor poleceń to renderowanie konturów siatek z wyłączonym testem głębokości. Ponieważ musi być na innych obiektach.
W tym przypadku to, czego potrzebujesz, zależy raczej od tego, czym są te bufory poleceń.
Jeśli są to dodatkowe bufory poleceń wykonywane w ramach tej samej instancji render pass, to nie trzeba synchronizacji. Nie, chyba że jesteś ręczny odczyt z tekstury głębi w dodatkowym buforze poleceń. Dlaczego?
Ponieważ sekcja 2.2.1 API Ordering chroni Cię. Testowanie głębi i pisanie głębi w instancji render-pass będzie zawsze przebiegać w kolejności API. Tak więc późniejsze polecenia, czy to w tym samym CB, czy w innym, będą zamawiane w odniesieniu do testowania/pisania głębi.
Jednakże, jeśli chcesz odczytać bufor głębi z shadera lub Twoje bufory poleceń są w innym renderowaniu przekazać instancje, a następnie potrzebujesz jawnej synchronizacji za pośrednictwem zdarzenia.
W tym przypadku maska stage dla polecenia vkCmdSetEvent
powinna być stage, który zapisuje wartość głębi. Może to być EARLY_FRAGMENT_TESTS_BIT
lub LATE_FRAGMENT_TESTS_BIT
. Aby być bezpiecznym, użyj obu. Ponieważ jednak prawdopodobnie aktualizujesz ten sam bufor kolorów, potrzebujesz również etapu COLOR_ATTACHMENT_OUTPUT_BIT
. Wstaw to polecenie na końcu pierwszego bufora poleceń (lub po zakończeniu zapisu głębi).
Na vkCmdWaitEvent
, chcesz poczekać na etapy rurociągu, które potrzebuję tego. W Twoim przypadku jest to ponownie test fragmentu i załącznik koloru. Ale jeśli etap shadera ma odczytać głębię, potrzebny jest również ten etap w Komendzie wait.
Ponieważ pamięć jest zaangażowana, Twój vkCmdWaitEvent
będzie również musiał użyć zależności pamięci od buforów głębi i koloru.
Naprawdę, cała ta złożoność jest powodem, dla którego powinieneś spróbować umieścić te bufory poleceń w tej samej instancji render pass, jeśli to w ogóle możliwe. Jedynym powodem, dla którego nie możesz tego zrobić, jest jeśli chcesz czytać z bufora głębi w shaderze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-06 06:59:40
Do scenariusza należy użyć zdarzeń. Powinny to być najlżejsze obiekty synchronizacji, aby zsynchronizować wykonanie dwóch buforów poleceń w danej kolejności, nawet jeśli przesyłasz je jednocześnie. Pamiętaj jednak, że zdarzenia nie działają w różnych kolejkach. Jeśli używasz tylko jednego, użyj zdarzeń i staraj się, aby maski etapu rurociągów src i dst były jak najbardziej wąskie.
Semafory są kolejnym sposobem synchronizacji wykonywania bufora poleceń, ale działają one tylko przy składaniu kolejki, więc są cięższe niż wydarzenia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-27 13:42:14