Hello I am new to Vulkan and c++.
I am following a tutorial on Vulkan for Visual-Studio and stuck at creating a Vulkan Instance. Through a lot of googling I found out that the error -9 (VK_ERROR_INCOMPATIBLE_DRIVER) is based on the Vulkan Version 1.3, me using MacOS and how it implements the MoltenVk or must be included or something else like that. There it got too complicated for me.
I have tried to search through the documentations and now I don't really even understand what MoltenVk is or how I even tried to include Vulkan with cmake in my project.
I may found a solution on [here] and on stackoverflow (Why does vkCreateInstance return "VK_ERROR_INCOMPATIBLE_DRIVER" on MacOS despite vulkan supported GPU and up to date driver?) but I am not able to implement/understand it. Maybe somebody can explain it or tell me how to implement it?. The Site said I should put something like that in
std::vector<const char*>
extNames.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
extNames.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
VkInstanceCreateInfo inst_info = {};
ins_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
inst_info.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
inst_info.ppEnabledExtensionNames = extNames.data();
I have tried it that way and with some deviations in the vk_device.cpp file without any success.
My Project basically looks like this:
Project
--.vscode
--bin
->Project.exe
--build
--CMakeFiles
--libs
--SDL
--src
--Vk_base
->vk_base.h
->vk_device.cpp
->main.cpp
->CMakeList.txt
vk_base.h:
#include <vulkan/vulkan.h>
struct VulkanContext {
VkInstance instance;
};
VulkanContext* initVulkan();
vk_device.cpp:
#include "vk_base.h"
#include <iostream>
bool initVulkanInstance(VulkanContext* context) {
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan App";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_VERSION_1_0;
VkInstanceCreateInfo createInfo = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
createInfo.pApplicationInfo = &appInfo;
createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; // MAC OS SPECIFIC
//createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size()); // MAC OS SPECIFIC
//createInfo.ppEnabledExtensionNames = extNames.data(); // MAC OS SPECIFIC
VkResult creation_result = vkCreateInstance(&createInfo, 0, &context->instance);
std::cout << creation_result << std::endl;
return true;
}
VulkanContext* initVulkan() {
VulkanContext* context = new VulkanContext();
if (initVulkanInstance(context) != VK_SUCCESS) {
throw std::runtime_error("failed to create instance!");
}
return context;
}
main.cpp
#include <iostream>
#include <SDL.h>
#include "vk_base/vk_base.h"
bool handleMessage() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
return false;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
return false;
}
break;
}
}
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *_window;
_window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 500, SDL_WINDOW_RESIZABLE);
SDL_Event e;
bool quit = false;
while (!quit) {
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
}
}
}
VulkanContext* context = initVulkan();
SDL_DestroyWindow(_window);
SDL_Quit();
return 0;
}
and my Cmakefile to create the Project in the build folder with the command : cmake ../ -GXcode ( I have tried it with -GXcode and without)
CMakeLists.txt:
#project name
project(Project)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(SOURCE_FILES src/main.cpp src/vk_base/vk_device.cpp)
#find SDL2
add_subdirectory(libs/SDL)
#find Vulkan
find_package(Vulkan REQUIRED)
#vulkan executebl
add_executable(Project ${SOURCE_FILES})
target_include_directories(Project PUBLIC libs/SDL/include)
target_link_libraries(Project PUBLIC SDL2-static)
target_link_libraries(Project PUBLIC Vulkan::Vulkan)
target_link_libraries(Project PUBLIC ${Vulkan_LIBRARIES})
Thank you for reading and sry for my bad english:) if there are misspellings in it, it is probably not the cause of the problem and just a typo from me on this thread :p
if you are not comfortable with C++, steer away from Vulkan. One will teach you exactly the wrong lessons about the other. Vulkan is low-level API, and shows you how you should not be programming C++ in 98 % of the time.
Apple does not support Vulkan. They have their own API Metal. MoltenVK is a library that attempts to translate Vulkan function calls to Metal calls.
This API translation does not match 1:1, so the MoltenVK wrapper is not a conformant Vulkan implementation. You need to waive that it is not conformant, and that you know of and will avoid triggering the limitations:
You waive the Vulkan conformance by adding VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
bit to the Instance creation:
#ifdef __APPLE__
createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif //__APPLE__
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
is part of a Vulkan extension, so that extension needs to be enabled before using the bit, per standard Vulkan rules:
#ifdef __APPLE__
extNames.push_back( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME );
#endif //__APPLE__
createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
createInfo.ppEnabledExtensionNames = extNames.data();