Как синхронизировать `vkMapMemory`?

vkMapMemory указывает:

vkMapMemory не проверяет, используется ли в данный момент память устройства, перед возвратом указателя доступа к хосту. Приложение должно гарантировать, что любая ранее отправленная команда, которая записывает в этот диапазон, была завершена до того, как хост прочитает или запишет в этот диапазон, и что любая ранее отправленная команда, которая читает из этого диапазона, будет завершена до того, как хост запишет в эту область.

Он ссылается на этот сайт которого, к сожалению, пока не существует. Мне интересно, как я буду синхронизировать это?

В основном мне нужно беспокоиться о двух вещах

  • Только 1 поток обращается к одному и тому же диапазону одновременно
  • Графический процессор в настоящее время не пытается прочитать диапазон

Единственный реальный способ, который я вижу, чтобы синхронизировать это, - это безопасный список потоков. Каждый раз, когда вы хотите писать/читать в/из этого буфера, вы должны добавить диапазон памяти, который вы в данный момент пытаетесь прочитать или записать, в этот безопасный список потоков.

Это означает, что когда вы хотите получить доступ к этому буферу, вам нужно заблокировать этот список и найти диапазон, к которому вы пытаетесь получить доступ.

Так вы бы синхронизировали vkMapMemory или есть другие способы сделать это?


person Maik Klein    schedule 09.08.2016    source источник


Ответы (1)


Единственный раз, когда gpu попытается получить доступ к отображенной памяти, это когда буфер команд, обращающийся к этой памяти, был отправлен. Эта память будет использоваться до тех пор, пока не будет передан соответствующий vkFence.

Полностью общим решением было бы отслеживать каждый доступ к памяти со стороны графического процессора и окружать каждый доступ к памяти, отображаемый ЦП, парой начала/конца, которая будет ждать на соответствующих заборах и вызывать сброс/аннулирование по мере необходимости. Это много отслеживания состояния и множество потенциально блокирующих вызовов.

Однако для постоянных данных сетки/текстуры вам нужно будет только записать в память промежуточный буфер, а затем скопировать в локальный буфер устройства, невидимый для хоста. Вам не нужно это часто, поэтому достаточно одного забора, чтобы отслеживать, находится ли его копия в полете. Или для данных, которые должны сохраняться только в течение одного кадра (для каждого преобразования объекта), вы можете использовать кольцевой буфер. Считывание результатов теста окклюзии графического процессора или результатов вычислений можно использовать кольцевой буфер.

Я надеюсь, что вы видите, как появляется закономерность. Используйте всего несколько сопоставленных кольцевых буферов и очень внимательно относитесь к тому, когда они используются графическим процессором, а затем вам просто нужно сохранить небольшой массив vkFence+offset+size для каждого кольцевого буфера, чтобы гарантировать отсутствие опасности для данных.

person ratchet freak    schedule 09.08.2016