2016-03-27 2 views
2

С выпущенным Vulkan я решил написать (как хобби) графический интерфейс на основе Vulkan. Тем не менее, я сейчас застрял на самом первом этапе - загружая функции Vulkan. Я использую Nvidia C++ Vulkan wrapper, которая требует, насколько я вижу, функций Vulkan для загрузки по всему миру.Загрузка функций Vulkan глобально

я могу загрузить локальные функции успешно, однако ::vkCreateInstance не удается:

void loadInstanceFunctions() { 
    PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance"); //works 

    ::vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance"); //does not work 
} 

Попытка присвоить новый указатель на функцию в глобальном масштабе дает мне 2 ошибки времени компиляции (скомпилированы с использованием VS2015):

  • выражение должно быть модифицируемым значением l.
  • '=': функция как левый операнд.

Есть прототипы функций, объявленных в vulkan.h заголовка, например:

VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*     pCreateInfo, 
    const VkAllocationCallbacks*    pAllocator, 
    VkInstance*         pInstance); 

Это то, что могло бы помешать мне погрузочных функций в глобальном масштабе. Если бы я определил VK_NO_PROTOTYPES, то эти прототипы были бы пропущены, и я считаю, что могу просто повторно объявить их как PFN_vkCreateInstance vkCreateInstance = nullptr; и так далее. Но верно ли это?

Итак, мой вопрос - каков правильный способ загрузки функций Vulkan по всему миру?

+0

Что вы имеете в виду под «не делает Работа". Есть ли ошибка времени компиляции, и если да, можете ли вы скопировать/вставить весь вывод компилятора из этой ошибки? Или вы имеете в виду поведение во время работы? – Yakk

+0

Есть ли причина, по которой вы не можете просто использовать Vulkan SDK для загрузки указателей на функции? Я имею в виду, если вы используете оболочку на C++ для NVIDIA, то вы явно не против стороннего программного обеспечения. И действительно, работа с Vulkan с валидационным слоем похожа на работу с нитроглицерином без оборудования для обеспечения безопасности. –

+0

Скопируйте ошибки дословно: не перефразируйте и не копируйте/не вставляете его часть. Каждое сообщение об ошибке и информации и предупреждения, генерируемое компиляцией, кодами ошибок и номерами строк, именами файлов и т. Д. Если вы посмотрите на свой код, у вас есть локальная переменная с именем 'vkCreateInstance', то вы используете разрешение области видимости для доступа к тому, что кажется глобальной переменной под названием' vkCreateInstance' (или, по крайней мере, глобальное имя с именем 'vkCreateInstance' - кто знает!) , Я понятия не имею, что вы пытаетесь сделать. Отправьте сообщение [MCVE], которое генерирует вашу ошибку. – Yakk

ответ

5
::vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance"); //does not work 

Вы пытаетесь присвоить указатель на функцию символа vkCreateInstance, который, по умолчанию, определяется в качестве прототипа в vulkan.h.

Определение VK_NO_PROTOTYPES будет предварительно обработать все прототипы:

#ifndef VK_NO_PROTOTYPES 
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*     pCreateInfo, 
    const VkAllocationCallbacks*    pAllocator, 
    VkInstance*         pInstance); 
... 
#endif 

После того, как прототипы исчезли, вы можете загрузить vkCreateInstance глобально согласно documentation:

#define VK_NO_PROTOTYPES 
#include <vulkan/vulkan.h> 

#ifdef __cplusplus 
extern "C" { 
#endif 
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName); 
#ifdef __cplusplus 
} 
#endif 

PFN_vkCreateInstance vkCreateInstance; 

int main() 
{ 
     vkCreateInstance = (PFN_vkCreateInstance) vkGetInstanceProcAddr(NULL, "vkCreateInstance"); 

     return 0; 
} 
+0

Yup, это работает. Просто требуется 'extern 'C" {} 'для' vkGetInstanceProcAddr' декларации. – FrogTheFrog

+0

Приносим извинения, спасибо, что заметили это! – alteous

Смежные вопросы