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