Guest User

Untitled

a guest
Jul 19th, 2023
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 7.75 KB | None | 0 0
  1. module vulkan;
  2.  
  3. import std.exception : enforce;
  4.  
  5. import erupted;
  6. import bindbc.sdl : SDL_Window, SDL_Vulkan_GetInstanceExtensions, SDL_Vulkan_CreateSurface;
  7.  
  8. import memory;
  9. import util: CStringList;
  10.  
  11. version (validateVulkan)
  12. {
  13.     string [] validationLayers = ["VK_LAYER_KHRONOS_validation"];
  14.     const(char)[] debugExtension = "VK_EXT_debug_utils";
  15. } else {
  16.     string [] validationLayers = [];
  17. }  
  18.  
  19.  
  20.  
  21. CStringList getInstanceExtensions (SDL_Window * window)
  22. {
  23.     uint n;
  24.     SDL_Vulkan_GetInstanceExtensions(window,&n,null);
  25.     version (validateVulkan)
  26.     {
  27.         auto extensions = CStringList(n+1);
  28.         SDL_Vulkan_GetInstanceExtensions(window,&n,extensions.ptr);
  29.         extensions[n] = cast(const(char)*) debugExtension.ptr;
  30.     } else {
  31.         auto extensions = CStringList(n);
  32.         SDL_Vulkan_GetInstanceExtensions(window,&n,extensions.ptr);
  33.     }
  34.  
  35.     return extensions;
  36. }
  37.  
  38. void createInstance (CStringList extensions)
  39. {
  40.     auto vlayers = CStringList(validationLayers);
  41.     VkApplicationInfo appInfo =
  42.     {
  43.         pApplicationName: "Vulkan Test",
  44.         apiVersion: VK_MAKE_API_VERSION(0,1,3,0),
  45.     };
  46.     VkInstanceCreateInfo createInfo =
  47.     {
  48.         pApplicationInfo: &appInfo,
  49.         enabledLayerCount: cast(uint) vlayers.length,
  50.         ppEnabledLayerNames: vlayers.ptr,
  51.         enabledExtensionCount: cast(uint) extensions.length,
  52.         ppEnabledExtensionNames: extensions.ptr,
  53.     };
  54.     auto r = vkCreateInstance(&createInfo, null, &instance);
  55.     enforce(r == VK_SUCCESS,"failed to create instance");
  56.     loadInstanceLevelFunctions(instance);
  57. }
  58.  
  59.  
  60. void getPhysicalDevices ()
  61. {
  62.     uint n;
  63.     vkEnumeratePhysicalDevices(instance, &n, null);
  64.     physicalDevices = allocator.makeArray!VkPhysicalDevice(n);
  65.     vkEnumeratePhysicalDevices(instance,&n,physicalDevices.ptr);
  66.     enforce(physicalDevices.length > 0,"no physical devices found");
  67. }
  68.  
  69. void pickPhysicalDevice ()
  70. {
  71.     if (physicalDevices.length == 1)
  72.     {
  73.         primaryPhysicalDevice = physicalDevices[0];
  74.     } else {
  75.         ulong maxScore,index=-1;
  76.         foreach(i,device; physicalDevices)
  77.         {
  78.             uint score = 0;
  79.             VkPhysicalDeviceProperties properties;
  80.             device.vkGetPhysicalDeviceProperties(&properties);
  81.             VkPhysicalDeviceFeatures features;
  82.             device.vkGetPhysicalDeviceFeatures(&features);
  83.             switch(properties.deviceType)
  84.             {
  85.                 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: score = 1000; break;
  86.                 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: score = 500; break;
  87.                 case VK_PHYSICAL_DEVICE_TYPE_CPU: score = 100; break;
  88.                 default: score = 0;
  89.             }
  90.             if (score > maxScore)
  91.             {
  92.                 maxScore = score;
  93.                 index = i;
  94.             }
  95.            
  96.         }
  97.         primaryPhysicalDevice = physicalDevices[index];
  98.     }
  99.     enforce(primaryPhysicalDevice,"failed to find acceptable physical device");
  100. }
  101.  
  102. int [2] findQueueFamilies (VkPhysicalDevice dev)
  103. {
  104.     int [2] r = [-1,-1];
  105.     uint n;
  106.     vkGetPhysicalDeviceQueueFamilyProperties(dev,&n,null);
  107.     auto families = memory.allocator.makeArray!VkQueueFamilyProperties(n);
  108.     vkGetPhysicalDeviceQueueFamilyProperties(dev,&n,families.ptr);
  109.     foreach (i,family; families)
  110.     {
  111.         if (family.queueCount > 0 && family.queueFlags & VK_QUEUE_GRAPHICS_BIT) r[0] = cast(uint) i;  
  112.         VkBool32 presentSupport = false;
  113.         vkGetPhysicalDeviceSurfaceSupportKHR(dev,cast(uint)i, surface, &presentSupport);
  114.         if (family.queueCount > 0 && presentSupport) r[1] = cast(uint) i;
  115.     }
  116.     enforce (r[0] >= 0,"failed to find grahpics family");
  117.     enforce (r[1] >= 0,"failed to find present family");
  118.     return r;
  119. }
  120.  
  121. void createLogicalDevice (int[2] q)
  122. {
  123.     const(float[]) priority = [1.0f];
  124.     VkDeviceQueueCreateInfo queueCreateInfo =
  125.     {
  126.         sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
  127.         queueFamilyIndex: cast(uint) q[0],
  128.         queueCount: 1,
  129.         pQueuePriorities: priority.ptr,
  130.     };
  131.     VkPhysicalDeviceFeatures deviceFeatures;
  132.     VkDeviceCreateInfo createInfo =
  133.     {
  134.         sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
  135.         pQueueCreateInfos: &queueCreateInfo,
  136.         queueCreateInfoCount: 1,
  137.         pEnabledFeatures: &deviceFeatures,
  138.     };
  139.     auto r = vkCreateDevice(primaryPhysicalDevice,&createInfo,null,&device);
  140.     enforce(r == VK_SUCCESS,"failed to create logical device");
  141.  
  142. }
  143.  
  144. void getGraphicsQueue (uint i)
  145. {
  146.     vkGetDeviceQueue(device, 0, 0, &graphicsQueue);
  147.     enforce(graphicsQueue,"failed to get graphics queue");
  148. }
  149.  
  150. void init (SDL_Window * window)
  151. {
  152.     createInstance(getInstanceExtensions(window));
  153.  
  154.     version(validateVulkan) setupDebugMessenger();
  155.    
  156.     getPhysicalDevices();
  157.     pickPhysicalDevice();
  158.     SDL_Vulkan_CreateSurface(window,instance,&surface);
  159.     enforce(surface,"failed to create surface");
  160.     auto indicies = findQueueFamilies(primaryPhysicalDevice);
  161.     createLogicalDevice(indicies);
  162.     getGraphicsQueue(cast(uint)indicies[0]);  
  163. }
  164.  
  165. void shutdown()
  166. {
  167.    
  168.     vkDestroySurfaceKHR(instance,surface,null);
  169.     memory.allocator.dispose(physicalDevices);
  170.     version(validateVulkan) destroyDebugUtilsMessengerEXT(instance, debugMessenger, null);
  171.     vkDestroyInstance(instance,null);
  172. }
  173.  
  174.  
  175.  
  176.  
  177. VkDebugUtilsMessengerEXT debugMessenger;
  178. VkSurfaceKHR surface = VK_NULL_HANDLE;
  179. VkInstance instance = null;
  180. VkPhysicalDevice [] physicalDevices;
  181. VkPhysicalDevice primaryPhysicalDevice;
  182. VkDevice device;
  183. VkQueue graphicsQueue, presentQueue;
  184.  
  185.  
  186. // Debug functions
  187. extern (C) uint debugCallback ( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, uint messageType,
  188.                                 const(VkDebugUtilsMessengerCallbackDataEXT)* pCallbackData, void * pUserData) nothrow @nogc
  189. {
  190.     import std.stdio;
  191.     printf("message type: %i\n",messageType);
  192.     printf("%s\n", pCallbackData.pMessage);
  193.    return VK_FALSE;  
  194. }
  195.  
  196. VkResult createDebugUtilsMessengerEXT(  VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
  197.                                         const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger)
  198. {
  199.     auto func = cast(PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
  200.     if (func != null) {
  201.         return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
  202.     } else {
  203.         return VK_ERROR_EXTENSION_NOT_PRESENT;
  204.     }
  205. }
  206.  
  207. void destroyDebugUtilsMessengerEXT( VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger,
  208.                                     const VkAllocationCallbacks* pAllocator)
  209. {
  210.     auto func = cast(PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
  211.     if (func != null) {
  212.         func(instance, debugMessenger, pAllocator);
  213.     }
  214. }
  215.  
  216. void setupDebugMessenger ()
  217. {
  218.     if (validationLayers.length == 0) return;
  219.  
  220.     VkDebugUtilsMessengerCreateInfoEXT createInfo =
  221.     {
  222.         sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
  223.         messageSeverity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
  224.                          VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
  225.                          VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
  226.         messageType: VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
  227.                      VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
  228.                      VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
  229.         pfnUserCallback: &debugCallback,
  230.     };
  231.     enforce( createDebugUtilsMessengerEXT(instance, &createInfo, null, &debugMessenger) == VK_SUCCESS,"failed to create debug messenger");
  232. }
Advertisement
Add Comment
Please, Sign In to add comment