openlang

Кто владеет буфером Vulkan после отправки?

C++ RAII-обёртка над буфером Vulkan записывает работу с этим буфером, отправляет её и выходит из области видимости. Деструктор тут же вызывает vkDestroyBuffer. Отправленные команды, которые ссылаются на буфер, ещё выполняются.

Такой вызов недопустим. Vulkan требует, чтобы все отправленные команды, ссылающиеся на буфер, завершили выполнение до его уничтожения. Выход из области видимости показывает лишь, что хост закончил с обёрткой. О GPU он не говорит ничего.

Первая мысль такая. При отправке переместить обёртку в список ресурсов кадра на освобождение и уничтожать её только тогда, когда завершение этой отправки известно. Не могу решить, где должно происходить перемещение. Внутри вызова отправки? В том, кто владеет кадром? И название «список кадра» не отвечает, когда запись действительно можно отпускать.

Разговор продолжается 3

Следуя доводам
  1. Ссылка на ответ

    Ответственный за освобождение должен быть один и назван явно. Кто-то удаляет запись, когда завершение известно, и кто-то сохраняет её, если операция хоста завершилась раньше. Это может быть один и тот же компонент, но в дизайне должно быть сказано, какой. Обнуление локального указателя обёртки меняет только эту переменную. Оно ничего не освобождает и ничего не говорит о том, завершились ли отправленные команды.

  2. Ссылка на ответ

    Сначала проверьте, где живёт сам список на освобождение. Если его записи лежат во временной памяти, которую чистят в конце кадра, а их буферы ещё ждут GPU, записи исчезнут раньше, чем сделают своё дело. В Odin это значит смотреть, какой аллокатор запомнил динамический массив, а не какой лежит в контексте в момент отправки.

  3. Ссылка на ответ

    Если передача это перемещение в список отложенного удаления, конструктор перемещения обёртки должен оставить источник ничем не владеющим, чтобы его деструктор ничего не делал. Обычно для этого в перемещённый объект записывают VK_NULL_HANDLE и проверяют его в деструкторе. Пропустите это, и локальная переменная всё равно уничтожит буфер при выходе из области видимости, а в списке при этом сидит второй владелец.

    Перемещённые объекты тоже уничтожаются. Формула стандарта «допустимое, но неуказанное состояние» относится только к библиотечным типам. Для собственной обёртки перемещённое состояние это то, что записал ваш конструктор перемещения, и ничего больше.

Другие стороны того же вопроса

  1. Сигналы срабатывают сразу, а не в конце кадра

    Меня это укусило в Godot, и, похоже, рано или поздно кусает всех. emit_signal() и signal.emit() вызывают подключённые функции…

    Ответы 2gdscript