The first thing to do is to have cmake:
brew install cmake
After that you can install molten-vk:
brew install molten-vk
cmake_minimum_required(VERSION 3.10)
project(SDL2Vulkan LANGUAGES CXX)
# Find the libraries
find_package(SDL2 REQUIRED)
# Find the MoltenVK libraries
find_path(MOLTENVK_INCLUDE_DIR vulkan/vulkan.h HINTS "/usr/local/include" "/usr/local/opt/molten-vk/include")
find_library(MOLTENVK_LIB NAMES MoltenVK PATHS "/usr/local/lib" "/usr/local/opt/molten-vk/lib")
if(NOT MOLTENVK_INCLUDE_DIR OR NOT MOLTENVK_LIB)
message(FATAL_ERROR "Could not find MoltenVK. Please make sure it is installed.")
endif()
# Set up Vulkan include directories and link libraries
include_directories(${SDL2_INCLUDE_DIRS} ${MOLTENVK_INCLUDE_DIR})
# Create an executable target
add_executable(${PROJECT_NAME} main.cpp)
# Link the libraries to the target
target_link_libraries(${PROJECT_NAME}
"-framework QuartzCore"
"-framework Metal"
"-framework Foundation"
"-framework IOSurface"
"-framework CoreGraphics"
"-framework IOKit"
"-framework AppKit"
SDL2::SDL2
SDL2::SDL2main
${MOLTENVK_LIB}
)
The main.cpp simply test if vulkan is setting things up correcty, you should Have nothing diplayed on the screen but no errors in the terminal
#include <iostream>
#include <vector>
#include <vulkan/vulkan.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#ifndef UINT32_MAX
#define UINT32_MAX 0xffffffff
#endif
void check_vk_result(VkResult result, const char* operation) {
if (result != VK_SUCCESS) {
std::cerr << "Vulkan error (" << operation << "): " << result << std::endl;
exit(1);
}
}
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
if (SDL_Vulkan_LoadLibrary(nullptr) != 0) {
std::cerr << "SDL_Vulkan_LoadLibrary Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Window* window = SDL_CreateWindow("SDL2Vulkan", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 360, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
if (window == nullptr) {
std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
uint32_t extensionCount;
const char** extensionNames = 0;
if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr)) {
std::cerr << "SDL_Vulkan_GetInstanceExtensions Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
extensionNames = new const char *[extensionCount];
if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensionNames)) {
std::cerr << "SDL_Vulkan_GetInstanceExtensions Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
const VkInstanceCreateInfo instInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
nullptr, // pApplicationInfo
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
extensionCount, // enabledExtensionCount
extensionNames, // ppEnabledExtensionNames
};
VkInstance vkInst;
VkResult result = vkCreateInstance(&instInfo, nullptr, &vkInst);
check_vk_result(result, "vkCreateInstance");
uint32_t physicalDeviceCount;
result = vkEnumeratePhysicalDevices(vkInst, &physicalDeviceCount, nullptr);
check_vk_result(result, "vkEnumeratePhysicalDevices");
if (physicalDeviceCount == 0) {
std::cerr << "Failed to find GPUs with Vulkan support!" << std::endl;
vkDestroyInstance(vkInst, nullptr);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
vkEnumeratePhysicalDevices(vkInst, &physicalDeviceCount, physicalDevices.data());
VkPhysicalDevice physicalDevice = physicalDevices[0];
uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
VkSurfaceKHR surface;
if (!SDL_Vulkan_CreateSurface(window, vkInst, &surface)) {
std::cerr << "SDL_Vulkan_CreateSurface Error: " << SDL_GetError() << std::endl;
vkDestroyInstance(vkInst, nullptr);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
uint32_t graphicsQueueIndex = UINT32_MAX;
uint32_t presentQueueIndex = UINT32_MAX;
VkBool32 support;
uint32_t i = 0;
for (VkQueueFamilyProperties queueFamily : queueFamilies) {
if (graphicsQueueIndex == UINT32_MAX && queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
graphicsQueueIndex = i;
if (presentQueueIndex == UINT32_MAX) {
result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &support);
check_vk_result(result, "vkGetPhysicalDeviceSurfaceSupportKHR");
if(support)
presentQueueIndex = i;
}
++i;
}
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo queueInfo = {
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
graphicsQueueIndex, // graphicsQueueIndex
1, // queueCount
&queuePriority, // pQueuePriorities
};
VkPhysicalDeviceFeatures deviceFeatures = {};
const char* deviceExtensionNames[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
VkDeviceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
1, // queueCreateInfoCount
&queueInfo, // pQueueCreateInfos
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
1, // enabledExtensionCount
deviceExtensionNames, // ppEnabledExtensionNames
&deviceFeatures, // pEnabledFeatures
};
VkDevice device;
result = vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);
check_vk_result(result, "vkCreateDevice");
VkQueue graphicsQueue;
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
VkQueue presentQueue;
vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue);
SDL_Log("Initialized successfully");
bool running = true;
while(running) {
SDL_Event windowEvent;
while(SDL_PollEvent(&windowEvent))
if(windowEvent.type == SDL_QUIT) {
running = false;
break;
}
}
vkDestroyDevice(device, nullptr);
vkDestroyInstance(vkInst, nullptr);
SDL_DestroyWindow(window);
SDL_Vulkan_UnloadLibrary();
SDL_Quit();
return 0;
}