Я прочитал пример кода о копировании изображений между процессором и графическим процессором с использованием VK_PIPELINE_STAGE_HOST_BIT. (Для простоты ниже я буду использовать код phsuedo) Для gpu->cpu это похоже на: 1.vkCmdCopyImage(..., src_img, ... dst_img, ...); 2.vkCmdPipelineBarrier(...,VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,...);
Для cpu->gpu это похоже на:
Я могу понять часть cpu->gpu, так как нам нужно использовать барьер, чтобы сделать src_img видимым для gpu, поэтому сначала мы делаем барьер, а затем копируем src_img в dst_img. Но для gpu->cpu сначала выполняется копирование, а затем барьер. Интересно, без использования барьера, чтобы сначала сделать src_img видимым для хоста, как может быть успешна копия изображения? К вашему сведению, пример кода взят отсюда, https://cpp.hotexamples.com/site/file?hash=0xf064d23ec4332e7951809e5112a592758b3c2c71a4560a9e77da0176b1a9193a Обратитесь к функции CopyToImage и функции CopyFromImage
Интересно, без использования барьера, чтобы сначала сделать src_img видимым для хоста, как может быть успешна копия изображения?
Поскольку хост не читает исходное изображение; он читает целевое изображение, на которое копируется. Команда копирования читает исходное изображение, поскольку именно команда копирования копирует изображение.
целевой образ находится в памяти хоста
Нет, он находится в памяти устройства. Вы знаете это, потому что память инкапсулирована с помощью объекта VkDeviceMemory
, была выделена с помощью команд выделения памяти устройства и будет освобождена командой освобождения памяти устройства.
Это конкретное распределение памяти используется совместно с хостом, но принадлежит устройству.
Операция копирования является операцией устройства. Барьер предоставляет хосту результаты этой операции.
Во многих случаях память устройства не может быть видна на хосте, поэтому в первую очередь вам нужна операция переноса. Кажется, вы предполагаете, что передача осуществляется хостом (ЦП), но нет причин, по которым это должно быть правдой (может быть механизм DMA и т. д.).
спасибо @solidpixel, если перенос уже произошел, то зачем после этого еще нужен барьер для формирования домена устройства -> работа домена хоста? (т.е. vkCmdPipelineBarrier(...,VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,...);)
... потому что без барьера у вас нет гарантии, что копия действительно завершена. Поток команд определяет, когда начинаются операции, но фактическая обработка является асинхронной.
Спасибо @solidpixel. Я понимаю, что вы имеете в виду, вы говорите об операциях доступности и видимости, упомянутых в Registry.khronos.org/vulkan/specs/1.3-extensions/html/… Но в этой ссылке также содержится другой тип операции, называемый " операция с доменом памяти», в нем говорится: «Если маска доступа к месту назначения включает VK_ACCESS_HOST_READ_BIT или VK_ACCESS_HOST_WRITE_BIT, то зависимость включает операцию домена памяти от домена устройства к домену хоста». вы знакомы с этим понятием?
@NicolBolas Ах, «целевое изображение находится в памяти устройства», теперь это будет иметь смысл! Но как же?! Я думал, что host_visible означает, что блок памяти находится в памяти хоста, а device_local означает, что блок находится в памяти устройства? Если нет, то для host_visible означает ли это, что один и тот же контент имеет две копии в памяти: одна в памяти хоста, а другая в памяти устройства?
@AnningWuwang: Через окно вы видите чей-то дом. Это не делает его вашим домом. То же самое касается памяти; тот факт, что хост может его видеть, не делает его памятью хоста. Это память устройства, но иногда хост может играть с ней.
@NicolBolas относительно того, где находится видимая память хоста, можете ли вы взглянуть на страницу 10 по адресу khronos.org/assets/uploads/developers/library/… и дать разъяснение, пожалуйста? Как видно, host_visible находится в памяти хоста, а не в памяти устройства?
@NicolBolas На странице 13 также говорится, что host_visible находится в системной памяти.
@AnningWuwang: Vulkan - это абстракция, как и концепции «памяти устройства» и «видимости хоста». «Память устройства» означает память, к которой устройство имеет прямой доступ. Такая память инкапсулируется VkDeviceMemory
объектами. «Видимая для хоста» память — это память устройства, доступная хосту, если он того пожелает. «Системная память» — это не концепция Вулкана; это концепция для конкретного оборудования. Память устройства встроенного графического процессора всегда является «системной памятью» и всегда «видима хостом». Но это не мешает ему быть «памятью устройства» и даже DEVICE_LOCAL.
@NicolBolas Полностью понял! Большое спасибо за ваше фантастическое объяснение! Можно ли дать вам еще несколько очков репутации за эту ветку? :) Я как бы помню, что раньше мог давать свои баллы, но теперь я не вижу никакой кнопки.
Итак, если в целевом образе не установлен когерентный бит, нужно ли мне вызывать vkinvalidatemamppedmemoryranges..., чтобы сделать целевое изображение видимым для хоста, поскольку барьер уже должен был сделать целевое изображение видимым для хоста?
Барьер не делает его видимым, он гарантирует его доступность. Если выделение памяти кэшируется на хосте, вам все равно понадобится vkInvalidateMappedMemoryRanges()
— когерентность кэша процессора не зависит от передачи команды.
Спасибо @solidpixel, если вы посмотрите на Registry.khronos.org/vulkan/specs/1.3-extensions/html/… вы увидите, что зависимость от памяти (барьер) будет генерировать как операцию доступности для исходной области и операция видимости для области назначения
@AnningWuwang: Хорошо, пожалуйста, перестаньте относиться к Stack Overflow как к форуму, где вы можете продолжать туннелировать все глубже и глубже во все более и более конкретную эзотерику. Если у вас есть вопрос о том, что вам нужно сделать, чтобы получить доступ к памяти с хоста, задайте его. Или просто продолжайте читать ту самую ссылку, которую вы разместили, потому что она находится прямо там, на 4 абзаца ниже.
Спасибо, Николь, за случай gpu->cpu исходный образ находится в памяти устройства, а целевой образ находится в памяти хоста, без использования барьера, чтобы сначала сделать память устройства видимой для хоста, не будет копия команда не удалась? (поскольку src img в памяти устройства на данный момент еще не стал видимым/доступным для памяти хоста?)