Вызов API Vulkan для драйверов графического процессора

Предыстория:
Я присматривался к написанию приложения, для которого нужна очень простая, но быстрая графика (просто рисование линий и квадратов), и я, вероятно, собираюсь использовать такую ​​библиотеку, как GLFW или Вулкано, если я собираюсь использовать Rust.

Я хочу понять конкретную и, как мне кажется, довольно практичную деталь API Vulkan. Я понимаю, что графические процессоры могут быть довольно сложной темой, но я хочу подчеркнуть, что у меня нет опыта работы с низкоуровневой графикой или Vulkan, поэтому я понимаю, что на мой вопрос нельзя ответить, или если мой вопрос даже не вызывает смысл. Я постараюсь использовать правильную терминологию. Должен признать, я не лучший специалист в том, чтобы бегло просматривать и просматривать большие объемы исходного кода, я не совсем понимаю и до сих пор понимаю общую концепцию, поэтому я надеюсь, что смогу найти здесь свой ответ. Я пробовал посмотреть исходный код драйверов Vulkan и Mesa, но это не принесло никаких результатов.

ОРИГИНАЛЬНЫЙ вопрос:
Я хочу понять, как вызов API распространяется на драйвер графического процессора.

Я искал, но не смог найти то, что ищу. Ближайшие сообщения, которые я нашел, - это два:
https://softwareengineering.stackexchange.com/questions/279069/how-does-a-program-talk-to-a-graphics-card
https://superuser.com/questions/461022/how-does-the-cpu-and-gpu-interact-in-displaying-computer-graphics

Оба они упоминают нечто похожее на: Чтобы заставить графический процессор что-то делать, вы должны выполнить вызов через поддерживаемый API. Я знаю это, но ни один из двоих не вдавался в подробности того, как выполняется этот вызов API. Надеюсь, приведенная ниже диаграмма иллюстрирует мой вопрос.

MyVulkanProgram.c with "#include <vulkan/vulkan.h>"
|
| (Makes call via Vulkan API)
v
This is the part I don't understand!
|
v
Driver (Mesa, for example) takes the request sent via the Vulkan API.
|
| (Driver asks GPU to perform task)
v
GPU does task

Меня не волнует, что и как GPU что-то делает. Как он вызывается через вызов API через Vulkan и как он распространяется по системе. В идеале я ищу фрагмент кода или ссылку на то, где в исходном коде Vulkan фактический запрос отправляется драйверу.

Или я все неправильно понял? Является ли Вулкан большей частью водителя, чем я думаю? Может быть, драйвер включает тот же заголовок Vulkan, что и мой MyVulkanProgram.c, и драйвер связан вместе с файлами библиотеки, такими как libvulkan.so и др.? Это больше похоже на схему ниже?

MyVulkanProgram.c with "#include <vulkan/vulkan.h>"
|
| (Makes call via Vulkan API)
v
Driver (Mesa, for example, which includes the vulkan headers and is linked with the Vulkan shared object-files) takes the request sent via the Vulkan API.
|
| (Driver asks GPU to perform task)
v
GPU does task

Может быть, это базовый вопрос, а может и нет, но я все равно в замешательстве. Очень благодарен за любые ответы!

ОБНОВЛЕННЫЙ вопрос:
Прочитав ответ от @krOoze (ответ от krOoze ), и учитывая обзорный рисунок загрузчика Vulkan в упомянутом документе, я могу более точно выразить свой вопрос.

Как приложение, выполняющее вызов через API Vulkan, достигает ICD через загрузчик Vulkan?


person Mah    schedule 26.05.2021    source источник
comment
Я хочу понять, как вызов API распространяется на драйвер графического процессора. Ну, это полностью зависит от графического стека для рассматриваемой ОС.   -  person Nicol Bolas    schedule 26.05.2021
comment
@NicolBolas Да, я искал несколько агностический ответ, но я обновлю свой вопрос. Прочитав ответ krOoz, я думаю, что смогу лучше формализовать свой вопрос.   -  person Mah    schedule 28.05.2021


Ответы (1)


Вы ищете Vulkan-Loader / LoaderAndLayerInterface.md документация.

Приложение взаимодействует с загрузчиком (иногда называемым Vulkan RT или Vulkan Runtime). Это vulkan-1.dll (или so).

Загрузчик также имеет vulkan-1.lib, который является классической оболочкой dll. Здесь происходит загрузка основной версии и команд WSI, но вы можете пропустить lib и сделать все это вручную прямо из dll с помощью vkGetInstanceProcAddr.

Тогда у вас есть ICD (устанавливаемые клиентские драйверы). Это что-то вроде nvoglv64.dll, и на вашем ПК их может быть больше (например, Intel iGPU + NV). Имя произвольное и зависит от производителя. Загрузчик находит их через файлы конфигурации.

Теперь, когда вы вызываете что-то в команде, полученной с помощью vkGetInstanceProcAddress (что является всем, если вы используете только *.lib), вы попадаете на трамплин загрузчика, который вызывает цепочку слоев, после чего вызывается соответствующий ICD (или все они) . Затем стек вызовов разматывается, поэтому он идет в другом направлении, пока не вернется в приложение. Загрузчик делает мьютексы и объединяет входные и выходные данные в ICD.

Команды, полученные с помощью vkGetDeviceProcAddress, немного более упрощены, поскольку они не требуют мьютекса или слияния и предназначены для передачи в ICD без особого вмешательства со стороны загрузчика.

Код также находится в том же репозитории: trampoline.c и loader.c. Это довольно просто; каждый слой просто вызывает слой под ним. Начинается у батута и заканчивается уровнем терминатора, который, в свою очередь, вызывает уровень ICD.

person krOoze    schedule 26.05.2021
comment
Да! Раздел документа Vulkan Installable Client Driver Interface With Loader ответил на большинство моих вопросов (спасибо). Просто чтобы убедиться, что я правильно понимаю: у меня нет системы Windows, чтобы проверить, на что на самом деле указывает реестр HKEY_LOCAL_MACHINE \ ... \ VulkanDriverName (через файл-манифест ICD), но я предполагаю, что это nvoglv64.dll . Может ли эта .dll считаться частью (проприетарного) драйвера для Nvidia? Я понимаю, что эта .dll знает, как остальная часть стека работает внутри, поэтому я счастлив оставить все как есть. - person Mah; 28.05.2021
comment
Примечание: для всех, кто читает. Документация (ссылка) отвечает на вопрос большинства платформы (такие как Windows, Linux и macOS), а не только Windows. - person Mah; 28.05.2021
comment
@Mah Реестр указывает на nv-vk64.json (соответственно nv-vk32.json), который, в свою очередь, указывает на nvoglv64.dll (соответственно nvoglv32.dll). Он является частью устанавливаемого клиентского драйвера (проприетарного драйвера для Nvidia). - person krOoze; 28.05.2021