yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "vulkan-api.h" 2 3#include "slang.h" 4 5#include <assert.h> 6#include <stdio.h> 7#include <stdlib.h> 8#include <string.h> 9#include <vector> 10 11#if SLANG_WINDOWS_FAMILY 12#include <windows.h> 13#else 14#include <dlfcn.h> 15#endif 16 17#if _DEBUG 18#define ENABLE_VALIDATION_LAYER 1 19#endif 20 21VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback ( 22VkDebugReportFlagsEXT /*flags*/ , 23VkDebugReportObjectTypeEXT /*objType*/ , 24uint64_t /*srcObject*/ , 25size_t /*location*/ , 26int32_t /*msgCode*/ , 27const char * pLayerPrefix , 28const char * pMsg , 29void * /*pUserData*/ 30) 31{ 32printf ("[%s]: %s\n" ,pLayerPrefix ,pMsg ); 33return 1 ; 34} 35 36int initializeVulkanDevice (VulkanAPI & api ) 37{ 38// Load vulkan library. 39const char * dynamicLibraryName = "Unknown" ; 40 41#if SLANG_WINDOWS_FAMILY 42dynamicLibraryName = "vulkan-1.dll" ; 43HMODULE module = ::LoadLibraryA (dynamicLibraryName ); 44api .vulkanLibraryHandle = (void * )module ; 45#define VK_API_GET_GLOBAL_PROC (x ) api.x = (PFN_##x)GetProcAddress(module, #x); 46#elif SLANG_APPLE_FAMILY 47dynamicLibraryName = "libvulkan.dylib" ; 48api .vulkanLibraryHandle = dlopen (dynamicLibraryName ,RTLD_NOW ); 49#define VK_API_GET_GLOBAL_PROC (x ) api.x = (PFN_##x)dlsym(api.vulkanLibraryHandle, #x); 50#else 51dynamicLibraryName = "libvulkan.so.1" ; 52api .vulkanLibraryHandle = dlopen (dynamicLibraryName ,RTLD_NOW ); 53#define VK_API_GET_GLOBAL_PROC (x ) api.x = (PFN_##x)dlsym(api.vulkanLibraryHandle, #x); 54#endif 55 56// Initialize all the global functions. 57VK_API_ALL_GLOBAL_PROCS (VK_API_GET_GLOBAL_PROC ) 58if (!api .vkCreateInstance ) 59return -1 ; 60 61// Enable validation layer if available. 62 std::vector < const char *> layers ; 63#ifdef ENABLE_VALIDATION_LAYER 64uint32_t propertyCount ; 65if (api .vkEnumerateInstanceLayerProperties (& propertyCount ,nullptr )!= 0 ) 66return -1 ; 67 std::vector < VkLayerProperties > properties (propertyCount ); 68if (api .vkEnumerateInstanceLayerProperties (& propertyCount ,properties .data ())!= 0 ) 69return -1 ; 70for (const auto & p :properties ) 71 { 72if (strcmp (p .layerName ,"VK_LAYER_KHRONOS_validation" )== 0 ) 73 { 74layers .push_back ("VK_LAYER_KHRONOS_validation" ); 75 } 76 } 77#endif 78 79// Create Vulkan Instance. 80VkApplicationInfo applicationInfo = {VK_STRUCTURE_TYPE_APPLICATION_INFO }; 81applicationInfo .pApplicationName = "slang-hello-world" ; 82applicationInfo .pEngineName = "slang-hello-world" ; 83applicationInfo .apiVersion = VK_API_VERSION_1_2 ; 84applicationInfo .engineVersion = 1 ; 85applicationInfo .applicationVersion = 1 ; 86const char * instanceExtensions []= { 87#if SLANG_APPLE_FAMILY 88VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME , 89#endif 90VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME , 91VK_EXT_DEBUG_REPORT_EXTENSION_NAME , 92 }; 93VkInstanceCreateInfo instanceCreateInfo = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; 94#if SLANG_APPLE_FAMILY 95instanceCreateInfo .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR ; 96#endif 97instanceCreateInfo .pApplicationInfo = & applicationInfo ; 98instanceCreateInfo .enabledExtensionCount = SLANG_COUNT_OF (instanceExtensions ); 99instanceCreateInfo .ppEnabledExtensionNames = & instanceExtensions [0 ]; 100if (layers .size ()) 101 { 102instanceCreateInfo .ppEnabledLayerNames = & layers [0 ]; 103instanceCreateInfo .enabledLayerCount = (uint32_t )layers .size (); 104 } 105if (api .vkCreateInstance (& instanceCreateInfo ,nullptr ,& api .instance )!= 0 ) 106return -1 ; 107 108// Load instance functions. 109api .initInstanceProcs (); 110 111// Create debug report callback. 112if (api .vkCreateDebugReportCallbackEXT ) 113 { 114VkDebugReportFlagsEXT debugFlags = 115VK_DEBUG_REPORT_ERROR_BIT_EXT |VK_DEBUG_REPORT_WARNING_BIT_EXT ; 116 117VkDebugReportCallbackCreateInfoEXT debugCreateInfo = { 118VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT }; 119debugCreateInfo .pfnCallback = & debugMessageCallback ; 120debugCreateInfo .pUserData = nullptr ; 121debugCreateInfo .flags = debugFlags ; 122 123RETURN_ON_FAIL (api .vkCreateDebugReportCallbackEXT ( 124api .instance , 125& debugCreateInfo , 126nullptr , 127& api .debugReportCallback )); 128 } 129 130// Enumerate physical devices. 131uint32_t numPhysicalDevices = 0 ; 132RETURN_ON_FAIL (api .vkEnumeratePhysicalDevices (api .instance ,& numPhysicalDevices ,nullptr )); 133 std::vector < VkPhysicalDevice > physicalDevices ; 134physicalDevices .resize (numPhysicalDevices ); 135RETURN_ON_FAIL ( 136api .vkEnumeratePhysicalDevices (api .instance ,& numPhysicalDevices ,& physicalDevices [0 ])); 137 138// We will use device 0. 139api .initPhysicalDevice (physicalDevices [0 ]); 140 141VkDeviceCreateInfo deviceCreateInfo = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; 142deviceCreateInfo .queueCreateInfoCount = 1 ; 143deviceCreateInfo .pEnabledFeatures = & api .deviceFeatures ; 144 145// Find proper queue family index. 146uint32_t numQueueFamilies = 0 ; 147api .vkGetPhysicalDeviceQueueFamilyProperties (api .physicalDevice ,& numQueueFamilies ,nullptr ); 148 149 std::vector < VkQueueFamilyProperties > queueFamilies ; 150queueFamilies .resize (numQueueFamilies ); 151api .vkGetPhysicalDeviceQueueFamilyProperties ( 152api .physicalDevice , 153& numQueueFamilies , 154& queueFamilies [0 ]); 155 156// Find a queue that can service our needs. 157auto requiredQueueFlags = VK_QUEUE_COMPUTE_BIT ; 158for (int i = 0 ;i < int (numQueueFamilies );++ i ) 159 { 160if ((queueFamilies [i ].queueFlags & requiredQueueFlags )== requiredQueueFlags ) 161 { 162api .queueFamilyIndex = i ; 163break ; 164 } 165 } 166if (api .queueFamilyIndex == -1 ) 167return -1 ; 168 169#if SLANG_APPLE_FAMILY 170const char * deviceExtensions []= { 171"VK_KHR_portability_subset" , 172 }; 173#endif 174 175VkDeviceQueueCreateInfo queueCreateInfo = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; 176float queuePriority = 0.0f ; 177queueCreateInfo .queueFamilyIndex = api .queueFamilyIndex ; 178queueCreateInfo .queueCount = 1 ; 179queueCreateInfo .pQueuePriorities = & queuePriority ; 180deviceCreateInfo .pQueueCreateInfos = & queueCreateInfo ; 181#if SLANG_APPLE_FAMILY 182deviceCreateInfo .enabledExtensionCount = SLANG_COUNT_OF (deviceExtensions ); 183deviceCreateInfo .ppEnabledExtensionNames = & deviceExtensions [0 ]; 184#endif 185RETURN_ON_FAIL (api .vkCreateDevice (api .physicalDevice ,& deviceCreateInfo ,nullptr ,& api .device )); 186 187// Load device functions. 188api .initDeviceProcs (); 189 190return 0 ; 191} 192 193int VulkanAPI ::initInstanceProcs () 194{ 195assert (instance && vkGetInstanceProcAddr != nullptr ); 196 197#define VK_API_GET_INSTANCE_PROC (x ) x = (PFN_##x)vkGetInstanceProcAddr(instance, #x); 198 199VK_API_ALL_INSTANCE_PROCS (VK_API_GET_INSTANCE_PROC ) 200// Get optional 201VK_API_INSTANCE_PROCS_OPT (VK_API_GET_INSTANCE_PROC ) 202 203#undef VK_API_GET_INSTANCE_PROC 204 205return 0 ; 206} 207 208int VulkanAPI ::initPhysicalDevice (VkPhysicalDevice inPhysicalDevice ) 209{ 210assert (physicalDevice == VK_NULL_HANDLE ); 211physicalDevice = inPhysicalDevice ; 212 213vkGetPhysicalDeviceProperties (physicalDevice ,& deviceProperties ); 214vkGetPhysicalDeviceFeatures (physicalDevice ,& deviceFeatures ); 215vkGetPhysicalDeviceMemoryProperties (physicalDevice ,& deviceMemoryProperties ); 216 217return 0 ; 218} 219 220int VulkanAPI ::initDeviceProcs () 221{ 222assert (instance && device && vkGetDeviceProcAddr != nullptr ); 223 224#define VK_API_GET_DEVICE_PROC (x ) x = (PFN_##x)vkGetDeviceProcAddr(device, #x); 225VK_API_DEVICE_PROCS (VK_API_GET_DEVICE_PROC ) 226#undef VK_API_GET_DEVICE_PROC 227 228return 0 ; 229} 230 231int VulkanAPI ::findMemoryTypeIndex (uint32_t typeBits ,VkMemoryPropertyFlags properties ) 232{ 233assert (typeBits ); 234 235const int numMemoryTypes = int (deviceMemoryProperties .memoryTypeCount ); 236 237// bit holds current test bit against typeBits. Ie bit == 1 << typeBits 238 239uint32_t bit = 1 ; 240for (int i = 0 ;i < numMemoryTypes ;++ i ,bit += bit ) 241 { 242auto const & memoryType = deviceMemoryProperties .memoryTypes [i ]; 243if ((typeBits & bit )&& (memoryType .propertyFlags & properties )== properties ) 244 { 245return i ; 246 } 247 } 248 249// assert(!"failed to find a usable memory type"); 250return -1 ; 251} 252 253VulkanAPI ::~VulkanAPI () 254{ 255if (vkDestroyDevice ) 256 { 257vkDestroyDevice (device ,nullptr ); 258 } 259if (vkDestroyDebugReportCallbackEXT ) 260 { 261vkDestroyDebugReportCallbackEXT (instance ,debugReportCallback ,nullptr ); 262 } 263if (vkDestroyInstance ) 264 { 265vkDestroyInstance (instance ,nullptr ); 266 } 267}