void Renderer::initDebug() { fvkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT"); fvkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT"); if (fvkCreateDebugReportCallbackEXT == nullptr || fvkDestroyDebugReportCallbackEXT == nullptr) { assert(0 && "Error querying debug report functions"); std::exit(-1); } errorCheck(fvkCreateDebugReportCallbackEXT(mInstance, &mDebugCallbackCreateInfo, nullptr, &mDebugReport)); }
void Renderer::_InitDebug() { fvkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(_instance, "vkCreateDebugReportCallbackEXT"); fvkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(_instance, "vkDestroyDebugReportCallbackEXT"); if (fvkCreateDebugReportCallbackEXT == nullptr || fvkDestroyDebugReportCallbackEXT == nullptr) { assert(0 && "Vulkan ERROR: Unable to fetch debug function pointers."); std::exit(-1); } fvkCreateDebugReportCallbackEXT(_instance, &_debug_callback_create_info, nullptr, &_debug_report); }
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { VkResult err; VkWin32SurfaceCreateInfoKHR sci; PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR"); if (!vkCreateWin32SurfaceKHR) { _glfwInputError(GLFW_API_UNAVAILABLE, "Win32: Vulkan instance missing VK_KHR_win32_surface extension"); return VK_ERROR_EXTENSION_NOT_PRESENT; } memset(&sci, 0, sizeof(sci)); sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; sci.hinstance = GetModuleHandle(NULL); sci.hwnd = window->win32.handle; err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface); if (err) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create Vulkan surface: %s", _glfwGetVulkanResultString(err)); } return err; }
// Platform dependant call VkSurfaceKHR VulkanWindowContext::createVkSurface(VkInstance instance, void* platformData) { static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr; if (!createWin32SurfaceKHR) { createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR"); } if (!platformData) { return VK_NULL_HANDLE; } ContextPlatformData_win* winPlatformData = reinterpret_cast<ContextPlatformData_win*>(platformData); VkSurfaceKHR surface; VkWin32SurfaceCreateInfoKHR surfaceCreateInfo; memset(&surfaceCreateInfo, 0, sizeof(VkWin32SurfaceCreateInfoKHR)); surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; surfaceCreateInfo.pNext = nullptr; surfaceCreateInfo.flags = 0; surfaceCreateInfo.hinstance = winPlatformData->fHInstance; surfaceCreateInfo.hwnd = winPlatformData->fHWnd; VkResult res = createWin32SurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); if (VK_SUCCESS != res) { return VK_NULL_HANDLE; } return surface; }
WindowContext* NewVulkanForAndroid(ANativeWindow* window, const DisplayParams& params) { auto createVkSurface = [window] (VkInstance instance) -> VkSurfaceKHR { static PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR = nullptr; if (!createAndroidSurfaceKHR) { createAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr( instance, "vkCreateAndroidSurfaceKHR"); } if (!window) { return VK_NULL_HANDLE; } VkSurfaceKHR surface; VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; surfaceCreateInfo.pNext = nullptr; surfaceCreateInfo.flags = 0; surfaceCreateInfo.window = window; VkResult res = createAndroidSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); return (VK_SUCCESS == res) ? surface : VK_NULL_HANDLE; }; auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; }; WindowContext* ctx = new VulkanWindowContext(params, createVkSurface, canPresent); if (!ctx->isValid()) { delete ctx; return nullptr; } return ctx; }
ne_status vkgfx_init_surface(void) { VkResult err = 0; VkWin32SurfaceCreateInfoKHR ci; PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = NULL; memset(&ci, 0x0, sizeof(ci)); vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) vkGetInstanceProcAddr(vkgfx_instance, "vkCreateWin32SurfaceKHR"); if (!vkCreateWin32SurfaceKHR) { log_entry(VK_WIN32_GFX_MODULE, LOG_CRITICAL, "Vulkan instance missing VK_KHR_win32_surface extension"); return NE_FAIL; } ci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; ci.hwnd = GetActiveWindow(); ci.hinstance = GetModuleHandle(NULL); err = vkCreateWin32SurfaceKHR(vkgfx_instance, &ci, vkgfx_allocator, &vkgfx_surface); if (err) { log_entry(VK_WIN32_GFX_MODULE, LOG_CRITICAL, "Failed to create Vulkan surface: %d", err); return NE_FAIL; } return NE_OK; }
static void cleanup_vulkan() { vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) { vkDestroyFence(g_Device, g_Fence[i], g_Allocator); vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]); vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator); vkDestroySemaphore(g_Device, g_PresentCompleteSemaphore[i], g_Allocator); vkDestroySemaphore(g_Device, g_RenderCompleteSemaphore[i], g_Allocator); } for (uint32_t i = 0; i < g_BackBufferCount; i++) { vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); } vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator); vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT // get the proc address of the function pointer, required for used extensions auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator); }
void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) { auto func = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); if (func != nullptr) { func(instance, callback, pAllocator); } }
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) { auto func = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); if (func != nullptr) { return func(instance, pCreateInfo, pAllocator, pCallback); } else { return VK_ERROR_EXTENSION_NOT_PRESENT; } }
void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack) { CreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); DestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); dbgBreakCallback = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"); VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {}; dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback; dbgCreateInfo.flags = flags; VkResult err = CreateDebugReportCallback( instance, &dbgCreateInfo, nullptr, (callBack != VK_NULL_HANDLE) ? &callBack : &msgCallback); assert(!err); }
/** * Initialize instance and device related functions */ void WSI::init(){ // g_gdpa = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(instance, "vkGetDeviceProcAddr"); pfnGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceSupportKHR"); GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceSupportKHR); GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceCapabilitiesKHR); GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfaceFormatsKHR); GET_INSTANCE_PROC_ADDR(instance, GetPhysicalDeviceSurfacePresentModesKHR); GET_INSTANCE_PROC_ADDR(instance, GetSwapchainImagesKHR); GET_DEVICE_PROC_ADDR(device, CreateSwapchainKHR); GET_DEVICE_PROC_ADDR(device, DestroySwapchainKHR); GET_DEVICE_PROC_ADDR(device, GetSwapchainImagesKHR); GET_DEVICE_PROC_ADDR(device, AcquireNextImageKHR); GET_DEVICE_PROC_ADDR(device, QueuePresentKHR); }
gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance, const gchar * name) { g_return_val_if_fail (GST_IS_VULKAN_INSTANCE (instance), NULL); g_return_val_if_fail (instance->instance != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); GST_TRACE_OBJECT (instance, "%s", name); return vkGetInstanceProcAddr (instance->instance, name); }
// Platform dependant call bool VulkanWindowContext::canPresent(VkInstance instance, VkPhysicalDevice physDev, uint32_t queueFamilyIndex) { static PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR getPhysicalDeviceWin32PresentationSupportKHR = nullptr; if (!getPhysicalDeviceWin32PresentationSupportKHR) { getPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); } VkBool32 check = getPhysicalDeviceWin32PresentationSupportKHR(physDev, queueFamilyIndex); return (VK_FALSE != check); }
void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack) { CreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); DestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); dbgBreakCallback = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"); VkDebugReportCallbackCreateInfoEXT dbgCreateInfo; dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; dbgCreateInfo.pNext = NULL; dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback; dbgCreateInfo.pUserData = NULL; dbgCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; VkDebugReportCallbackEXT debugReportCallback; VkResult err = CreateDebugReportCallback( instance, &dbgCreateInfo, NULL, &debugReportCallback); assert(!err); }
bool VkContext::SetupValidation() { // Set debug validation callback vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr( instance, "vkCreateDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr( instance, "vkDestroyDebugReportCallbackEXT"); vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr( instance, "vkDebugReportMessageEXT"); VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {}; dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)MessageCallback; dbgCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; CheckVkResult(vkCreateDebugReportCallbackEXT(instance, &dbgCreateInfo, nullptr, &msgCallback)); return true; }
void setupDebugCallback() { if (!enableValidationLayers) return; VkDebugReportCallbackCreateInfoEXT createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; createInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT) debugCallback; auto CreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); if (!CreateDebugReportCallback || CreateDebugReportCallback(instance, &createInfo, nullptr, &callback) != VK_SUCCESS) { throw std::runtime_error("failed to set up debug callback!"); } }
VkResult gvkInitUtils::registerDefaultDebugCallback(VkInstance inst, VkDebugReportCallbackEXT * callback) { using dbgext = PFN_vkCreateDebugReportCallbackEXT; dbgext CreateDebugReportCallback = VK_NULL_HANDLE; CreateDebugReportCallback = (dbgext) vkGetInstanceProcAddr(inst, "vkCreateDebugReportCallbackEXT"); VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = {}; callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; callbackCreateInfo.pfnCallback = &defaultDebugReportCallback; return CreateDebugReportCallback(inst, &callbackCreateInfo, nullptr, callback); }
static void CleanupVulkan() { ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT // Remove the debug report callback auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator); }
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname) { GLFWvkproc proc; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); if (!_glfwInitVulkan()) return NULL; proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); if (!proc) proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname); return proc; }
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily) { PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); if (!vkGetPhysicalDeviceWin32PresentationSupportKHR) { _glfwInputError(GLFW_API_UNAVAILABLE, "Win32: Vulkan instance missing VK_KHR_win32_surface extension"); return GLFW_FALSE; } return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily); }
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, unsigned int queuefamily) { PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR"); if (!vkGetPhysicalDeviceMirPresentationSupportKHR) { _glfwInputError(GLFW_API_UNAVAILABLE, "Mir: Vulkan instance missing VK_KHR_mir_surface extension"); return GLFW_FALSE; } return vkGetPhysicalDeviceMirPresentationSupportKHR(device, queuefamily, _glfw.mir.connection); }
Context::~Context() { vkDestroyCommandPool(kDevice, kCmdPool, NULL); vkDestroyDevice(kDevice, NULL); if (enableValidationLayers) { auto func = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(kInstance, "vkDestroyDebugReportCallbackEXT"); if (func == nullptr) { throw std::runtime_error("Could not load vkDestroyDebugReportCallbackEXT"); } func(kInstance, kDebugReportCallback, NULL); } kShaders.clear(); vkDestroyInstance(kInstance, NULL); return; }
bool LoadVulkanInstanceFunctions(VkInstance instance) { bool required_functions_missing = false; auto LoadFunction = [&](PFN_vkVoidFunction* func_ptr, const char* name, bool is_required) { *func_ptr = vkGetInstanceProcAddr(instance, name); if (!(*func_ptr) && is_required) { ERROR_LOG(VIDEO, "Vulkan: Failed to load required instance function %s", name); required_functions_missing = true; } }; #define VULKAN_INSTANCE_ENTRY_POINT(name, required) \ LoadFunction(reinterpret_cast<PFN_vkVoidFunction*>(&name), #name, required); #include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #undef VULKAN_INSTANCE_ENTRY_POINT return !required_functions_missing; }
static void setup_vulkan(GLFWwindow* window) { VkResult err; // Create Vulkan Instance { uint32_t extensions_count; const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&extensions_count); VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.enabledExtensionCount = extensions_count; create_info.ppEnabledExtensionNames = glfw_extensions; #ifdef IMGUI_VULKAN_DEBUG_REPORT // enabling multiple validation layers grouped as lunarg standard validation const char* layers[] = {"VK_LAYER_LUNARG_standard_validation"}; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; // need additional storage for char pointer to debug report extension const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); for (size_t i = 0; i < extensions_count; i++) extensions[i] = glfw_extensions[i]; extensions[ extensions_count ] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count+1; create_info.ppEnabledExtensionNames = extensions; #endif // IMGUI_VULKAN_DEBUG_REPORT err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); #ifdef IMGUI_VULKAN_DEBUG_REPORT free(extensions); // create the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci ={}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = NULL; // get the proc address of the function pointer, required for used extensions PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); err = vkCreateDebugReportCallbackEXT( g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report ); check_vk_result(err); #endif // IMGUI_VULKAN_DEBUG_REPORT } // Create Window Surface { err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &g_Surface); check_vk_result(err); } // Get GPU { uint32_t gpu_count; err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); check_vk_result(err); VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); check_vk_result(err); // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. g_Gpu = gpus[0]; free(gpus); } // Get queue { uint32_t count; vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, NULL); VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, queues); for (uint32_t i = 0; i < count; i++) { if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { g_QueueFamily = i; break; } } free(queues); } // Check for WSI support { VkBool32 res; vkGetPhysicalDeviceSurfaceSupportKHR(g_Gpu, g_QueueFamily, g_Surface, &res); if (res != VK_TRUE) { fprintf(stderr, "Error no WSI support on physical device 0\n"); exit(-1); } } // Get Surface Format { // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format // additionally several new color spaces were introduced with Vulkan Spec v1.0.40 // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used uint32_t count; vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL); VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats); // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available if (count == 1) { if( formats[0].format == VK_FORMAT_UNDEFINED ) { g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; } else { // no point in searching another format g_SurfaceFormat = formats[0]; } } else { // request several formats, the first found will be used VkFormat requestSurfaceImageFormat[] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM}; VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; bool requestedFound = false; for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) { if( requestedFound ) { break; } for (uint32_t j = 0; j < count; j++) { if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) { g_SurfaceFormat = formats[j]; requestedFound = true; } } } // if none of the requested image formats could be found, use the first available if (!requestedFound) g_SurfaceFormat = formats[0]; } free(formats); } // Get Present Mode { // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory #ifdef IMGUI_UNLIMITED_FRAME_RATE g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; #endif uint32_t count = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, nullptr); VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes); bool presentModeAvailable = false; for (size_t i = 0; i < count; i++) { if (presentModes[i] == g_PresentMode) { presentModeAvailable = true; break; } } if( !presentModeAvailable ) g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // always available } // Create Logical Device { int device_extension_count = 1; const char* device_extensions[] = {"VK_KHR_swapchain"}; const uint32_t queue_index = 0; const uint32_t queue_count = 1; const float queue_priority[] = {1.0f}; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = g_QueueFamily; queue_info[0].queueCount = queue_count; queue_info[0].pQueuePriorities = queue_priority; VkDeviceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; create_info.queueCreateInfoCount = sizeof(queue_info)/sizeof(queue_info[0]); create_info.pQueueCreateInfos = queue_info; create_info.enabledExtensionCount = device_extension_count; create_info.ppEnabledExtensionNames = device_extensions; err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device); check_vk_result(err); vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue); } // Create Framebuffers { int w, h; glfwGetFramebufferSize(window, &w, &h); resize_vulkan(window, w, h); glfwSetFramebufferSizeCallback(window, resize_vulkan); } // Create Command Buffers for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) { { VkCommandPoolCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; info.queueFamilyIndex = g_QueueFamily; err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]); check_vk_result(err); } { VkCommandBufferAllocateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; info.commandPool = g_CommandPool[i]; info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; info.commandBufferCount = 1; err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]); check_vk_result(err); } { VkFenceCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; info.flags = VK_FENCE_CREATE_SIGNALED_BIT; err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]); check_vk_result(err); } { VkSemaphoreCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_PresentCompleteSemaphore[i]); check_vk_result(err); err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_RenderCompleteSemaphore[i]); check_vk_result(err); } } // Create Descriptor Pool { VkDescriptorPoolSize pool_size[11] = { { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } }; VkDescriptorPoolCreateInfo pool_info = {}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; pool_info.maxSets = 1000 * 11; pool_info.poolSizeCount = 11; pool_info.pPoolSizes = pool_size; err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); check_vk_result(err); } }
GLFWbool _glfwInitVulkan(void) { VkResult err; VkExtensionProperties* ep; uint32_t i, count; #if !defined(_GLFW_VULKAN_STATIC) #if defined(_GLFW_WIN32) const char* name = "vulkan-1.dll"; #else const char* name = "libvulkan.so.1"; #endif if (_glfw.vk.available) return GLFW_TRUE; _glfw.vk.handle = _glfw_dlopen(name); if (!_glfw.vk.handle) { _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); return GLFW_FALSE; } _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); if (!_glfw.vk.GetInstanceProcAddr) { _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader does not export vkGetInstanceProcAddr"); _glfwTerminateVulkan(); return GLFW_FALSE; } _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); if (!_glfw.vk.EnumerateInstanceExtensionProperties) { _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); _glfwTerminateVulkan(); return GLFW_FALSE; } #endif // _GLFW_VULKAN_STATIC err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); if (err) { _glfwInputError(GLFW_PLATFORM_ERROR, "Vulkan: Failed to query instance extension count: %s", _glfwGetVulkanResultString(err)); _glfwTerminateVulkan(); return GLFW_FALSE; } ep = calloc(count, sizeof(VkExtensionProperties)); err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep); if (err) { _glfwInputError(GLFW_PLATFORM_ERROR, "Vulkan: Failed to query instance extensions: %s", _glfwGetVulkanResultString(err)); free(ep); _glfwTerminateVulkan(); return GLFW_FALSE; } for (i = 0; i < count; i++) { if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) _glfw.vk.KHR_surface = GLFW_TRUE; if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) _glfw.vk.KHR_win32_surface = GLFW_TRUE; if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) _glfw.vk.KHR_xlib_surface = GLFW_TRUE; if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) _glfw.vk.KHR_xcb_surface = GLFW_TRUE; if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) _glfw.vk.KHR_wayland_surface = GLFW_TRUE; if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0) _glfw.vk.KHR_mir_surface = GLFW_TRUE; } free(ep); _glfw.vk.available = GLFW_TRUE; if (_glfw.vk.KHR_surface) { _glfw.vk.extensions = _glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount); } return GLFW_TRUE; }
C9::C9() : mGpuCount(0), mPhysicalDevices(nullptr), mReferenceCount(0), mInstance(VK_NULL_HANDLE), mLayerProperties(nullptr), mLayerPropertyCount(0), mValidationPresent(false), mResult(VK_SUCCESS), mOptionDescriptions("Allowed options") { //Setup configuration & logging. mOptionDescriptions.add_options() ("LogFile", boost::program_options::value<std::string>(), "The location of the log file."); boost::program_options::store(boost::program_options::parse_config_file<char>("SchaeferGL.conf", mOptionDescriptions), mOptions); boost::program_options::notify(mOptions); if (mOptions.count("LogFile")) { boost::log::add_file_log(mOptions["LogFile"].as<std::string>()); } else { boost::log::add_file_log("SchaeferGL.log"); } //Continue instance setup. mResult = vkEnumerateInstanceLayerProperties(&mLayerPropertyCount, nullptr); if (mResult != VK_SUCCESS) { BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumerateInstanceLayerProperties failed with return code of " << mResult; return; } else { BOOST_LOG_TRIVIAL(info) << "C9::C9 vkEnumerateInstanceLayerProperties found " << mLayerPropertyCount << " layers."; } mLayerProperties = new VkLayerProperties[mLayerPropertyCount]; mResult = vkEnumerateInstanceLayerProperties(&mLayerPropertyCount, mLayerProperties); if (mResult == VK_SUCCESS) { for (size_t i = 0; i < mLayerPropertyCount; i++) { if (strcmp(mLayerProperties[i].layerName,"VK_LAYER_LUNARG_standard_validation")==0) { mValidationPresent = true; } BOOST_LOG_TRIVIAL(info) << "C9::C9 vkEnumerateInstanceLayerProperties - layerName: " << mLayerProperties[i].layerName; } } mExtensionNames.push_back("VK_KHR_surface"); mExtensionNames.push_back("VK_KHR_win32_surface"); #ifdef _DEBUG mExtensionNames.push_back("VK_EXT_debug_report"); mLayerExtensionNames.push_back("VK_LAYER_LUNARG_standard_validation"); #endif // _DEBUG // initialize the VkApplicationInfo structure VkApplicationInfo app_info = {}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pNext = nullptr; app_info.pApplicationName = APP_SHORT_NAME; app_info.applicationVersion = 1; app_info.pEngineName = APP_SHORT_NAME; app_info.engineVersion = 1; app_info.apiVersion = 0; // VK_API_VERSION; // initialize the VkInstanceCreateInfo structure VkInstanceCreateInfo inst_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; NULL, // const void* pNext; 0, // VkInstanceCreateFlags flags; &app_info, // const VkApplicationInfo* pApplicationInfo; mLayerExtensionNames.size(), // uint32_t enabledLayerNameCount; mLayerExtensionNames.size()>0 ? mLayerExtensionNames.data() : nullptr,// const char* const* ppEnabledLayerNames; mExtensionNames.size(), // uint32_t enabledExtensionNameCount; mExtensionNames.size()>0 ? mExtensionNames.data() : nullptr, // const char* const* ppEnabledExtensionNames; }; //Get an instance handle. if (VK_SUCCESS == vkCreateInstance(&inst_info, NULL, &mInstance)) { #ifdef _DEBUG /* Load VK_EXT_debug_report entry points in debug builds */ vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(mInstance, "vkCreateDebugReportCallbackEXT")); vkDebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(vkGetInstanceProcAddr(mInstance, "vkDebugReportMessageEXT")); vkDestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(mInstance, "vkDestroyDebugReportCallbackEXT")); VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = {}; callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; callbackCreateInfo.pNext = nullptr; callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; callbackCreateInfo.pfnCallback = &DebugReportCallback; callbackCreateInfo.pUserData = nullptr; /* Register the callback */ mResult = vkCreateDebugReportCallbackEXT(mInstance, &callbackCreateInfo, nullptr, &mCallback); if (mResult != VK_SUCCESS) { BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkCreateDebugReportCallbackEXT failed with return code of " << mResult; return; } else { BOOST_LOG_TRIVIAL(info) << "C9::C9 vkCreateDebugReportCallbackEXT succeeded."; } #endif //Fetch an array of available physical devices. mResult = vkEnumeratePhysicalDevices(mInstance, &mGpuCount, NULL); if (mResult != VK_SUCCESS) { BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumeratePhysicalDevices failed with return code of " << mResult; return; } else { BOOST_LOG_TRIVIAL(info) << "There were " << mGpuCount << " physical devices found."; } if (mGpuCount > 0) { mPhysicalDevices = new VkPhysicalDevice[mGpuCount](); mResult = vkEnumeratePhysicalDevices(mInstance, &mGpuCount, mPhysicalDevices); if (mResult != VK_SUCCESS) { BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkEnumeratePhysicalDevices failed with return code of " << mResult; return; } } else { BOOST_LOG_TRIVIAL(fatal) << "No phyuscial devices were found."; } } else { BOOST_LOG_TRIVIAL(fatal) << "C9::C9 vkCreateInstance failed."; return; } }
static void SetupVulkan(const char** extensions, uint32_t extensions_count) { VkResult err; // Create Vulkan Instance { VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.enabledExtensionCount = extensions_count; create_info.ppEnabledExtensionNames = extensions; #ifdef IMGUI_VULKAN_DEBUG_REPORT // Enabling multiple validation layers grouped as LunarG standard validation const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); extensions_ext[extensions_count] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count + 1; create_info.ppEnabledExtensionNames = extensions_ext; // Create Vulkan Instance err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); free(extensions_ext); // Get the function pointer (required for any extensions) auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); // Setup the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = NULL; err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #else // Create Vulkan Instance without any debug feature err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); #endif } // Select GPU { uint32_t gpu_count; err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); check_vk_result(err); VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); check_vk_result(err); // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. g_PhysicalDevice = gpus[0]; free(gpus); } // Select graphics queue family { uint32_t count; vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); for (uint32_t i = 0; i < count; i++) if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { g_QueueFamily = i; break; } free(queues); IM_ASSERT(g_QueueFamily != -1); } // Create Logical Device (with 1 queue) { int device_extension_count = 1; const char* device_extensions[] = { "VK_KHR_swapchain" }; const float queue_priority[] = { 1.0f }; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = g_QueueFamily; queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = queue_priority; VkDeviceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); create_info.pQueueCreateInfos = queue_info; create_info.enabledExtensionCount = device_extension_count; create_info.ppEnabledExtensionNames = device_extensions; err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); check_vk_result(err); vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); } // Create Descriptor Pool { VkDescriptorPoolSize pool_sizes[] = { { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } }; VkDescriptorPoolCreateInfo pool_info = {}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); pool_info.pPoolSizes = pool_sizes; err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); check_vk_result(err); } }
int sample_main() { struct sample_info info = {}; init_global_layer_properties(info); /* VULKAN_KEY_START */ /* Common validation layers * Loader will chain them together in the order given, * though order doesn't really matter for these validation * layers. */ info.instance_layer_names.push_back("VK_LAYER_GOOGLE_threading"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_device_limits"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_image"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_mem_tracker"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_param_checker"); info.instance_layer_names.push_back("VK_LAYER_LUNARG_swapchain"); info.instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects"); if (!demo_check_layers(info.instance_layer_properties, info.instance_layer_names)) { exit(1); } /* Enable debug callback extension */ info.instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); VkApplicationInfo app_info = {}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pNext = NULL; app_info.pApplicationName = "vulkansamples_enable_validation_with_callback"; app_info.applicationVersion = 1; app_info.pEngineName = "Vulkan Samples"; app_info.engineVersion = 1; app_info.apiVersion = VK_API_VERSION; VkInstanceCreateInfo inst_info = {}; inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; inst_info.pNext = NULL; inst_info.flags = 0; inst_info.pApplicationInfo = &app_info; inst_info.enabledLayerCount = info.instance_layer_names.size(); inst_info.ppEnabledLayerNames = info.instance_layer_names.size() ? info.instance_layer_names.data() : NULL; inst_info.enabledExtensionCount = info.instance_extension_names.size(); inst_info.ppEnabledExtensionNames = info.instance_extension_names.data(); VkResult res = vkCreateInstance(&inst_info, NULL, &info.inst); assert(res == VK_SUCCESS); init_enumerate_device(info); init_device_layer_properties(info); /* * Common validation layers * Loader will chain them together in the order given, * though order doesn't really matter for these validation * layers. * Instance layers and Device layers are independent so * must enable validation layers for both to see everything. */ info.device_layer_names.push_back("VK_LAYER_GOOGLE_threading"); info.device_layer_names.push_back("VK_LAYER_LUNARG_device_limits"); info.device_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); info.device_layer_names.push_back("VK_LAYER_LUNARG_image"); info.device_layer_names.push_back("VK_LAYER_LUNARG_mem_tracker"); info.device_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); info.device_layer_names.push_back("VK_LAYER_LUNARG_param_checker"); info.device_layer_names.push_back("VK_LAYER_LUNARG_swapchain"); info.device_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects"); if (!demo_check_layers(info.device_layer_properties, info.device_layer_names)) { exit(1); } float queue_priorities[1] = {0.0}; VkDeviceQueueCreateInfo queue_info = {}; vkGetPhysicalDeviceQueueFamilyProperties(info.gpus[0], &info.queue_count, NULL); assert(info.queue_count >= 1); info.queue_props.resize(info.queue_count); vkGetPhysicalDeviceQueueFamilyProperties(info.gpus[0], &info.queue_count, info.queue_props.data()); assert(info.queue_count >= 1); bool found = false; for (unsigned int i = 0; i < info.queue_count; i++) { if (info.queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { queue_info.queueFamilyIndex = i; found = true; break; } } assert(found); assert(info.queue_count >= 1); queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info.pNext = NULL; queue_info.queueCount = 1; queue_info.pQueuePriorities = queue_priorities; VkDeviceCreateInfo device_info = {}; device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; device_info.pNext = NULL; device_info.queueCreateInfoCount = 1; device_info.pQueueCreateInfos = &queue_info; device_info.enabledLayerCount = info.device_layer_names.size(); device_info.ppEnabledLayerNames = device_info.enabledLayerCount ? info.device_layer_names.data() : NULL; device_info.enabledExtensionCount = info.device_extension_names.size(); device_info.ppEnabledExtensionNames = device_info.enabledExtensionCount ? info.device_extension_names.data() : NULL; device_info.pEnabledFeatures = NULL; res = vkCreateDevice(info.gpus[0], &device_info, NULL, &info.device); assert(res == VK_SUCCESS); VkDebugReportCallbackEXT debug_report_callback; info.dbgCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr( info.inst, "vkCreateDebugReportCallbackEXT"); if (!info.dbgCreateDebugReportCallback) { std::cout << "GetInstanceProcAddr: Unable to find " "vkCreateDebugReportCallbackEXT function." << std::endl; exit(1); } info.dbgDestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr( info.inst, "vkDestroyDebugReportCallbackEXT"); if (!info.dbgDestroyDebugReportCallback) { std::cout << "GetInstanceProcAddr: Unable to find " "vkDestroyDebugReportCallbackEXT function." << std::endl; exit(1); } VkDebugReportCallbackCreateInfoEXT create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; create_info.pNext = NULL; create_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; create_info.pfnCallback = dbgFunc; create_info.pUserData = NULL; res = info.dbgCreateDebugReportCallback(info.inst, &create_info, NULL, &debug_report_callback); switch (res) { case VK_SUCCESS: break; case VK_ERROR_OUT_OF_HOST_MEMORY: std::cout << "dbgCreateDebugReportCallback: out of host memory\n" << std::endl; exit(1); break; default: std::cout << "dbgCreateDebugReportCallback: unknown failure\n" << std::endl; exit(1); break; } /* Create a command pool */ VkCommandPoolCreateInfo cmd_pool_info = {}; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext = NULL; cmd_pool_info.queueFamilyIndex = info.graphics_queue_family_index; cmd_pool_info.flags = 0; res = vkCreateCommandPool(info.device, &cmd_pool_info, NULL, &info.cmd_pool); assert(res == VK_SUCCESS); /* * Destroying the device before destroying the command pool above * will trigger a validation error. */ std::cout << "calling vkDestroyDevice before destroying command pool\n"; std::cout << "this should result in an error\n"; vkDestroyDevice(info.device, NULL); /* Clean up callback */ info.dbgDestroyDebugReportCallback(info.inst, debug_report_callback, NULL); /* VULKAN_KEY_END */ vkDestroyInstance(info.inst, NULL); return 0; }
int main() { //Настроем вывод. setlocale(LC_ALL, "Russian"); //Подготовим данные приложения VkApplicationInfo app_info; memset(&app_info, 0, sizeof(app_info)); app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pApplicationName = app_name; #ifdef VK_API_VERSION_1_0 app_info.apiVersion = VK_API_VERSION_1_0; #else app_info.apiVersion = VK_API_VERSION; #endif app_info.applicationVersion = VK_MAKE_VERSION(0, 1, 25); VkResult res; //заранее подготовим переменную для результата, она нам понадобится несколько раз. //Данные экземпляра VkInstanceCreateInfo instance_info; memset(&instance_info, 0, sizeof(instance_info)); instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_info.pApplicationInfo = &app_info; uint32_t available_instance_layer_count = 0; //узнаём кол-во установленных слоёв. res = vkEnumerateInstanceLayerProperties(&available_instance_layer_count, nullptr); if (res != VK_SUCCESS) { std::wcout << "Не удалось получить кол-во слоёв.\n"; return -1; } //настраиваем массив std::vector<VkLayerProperties> available_instance_layers(available_instance_layer_count); //Получаем слои res = vkEnumerateInstanceLayerProperties(&available_instance_layer_count, available_instance_layers.data()); if (available_instance_layer_count) { //А теперь выводим на экран. std::wcout << L"\n\nСлои экземпляра:\n"; for (uint32_t i = 0; i < available_instance_layer_count; i++) { VkLayerProperties &properties = available_instance_layers[i]; std::cout << properties.layerName << (strlen(properties.layerName) < 24 ? "\t" : "") << (strlen(properties.layerName) < 32 ? "\t" : "") << "\t|" << properties.description << "\n"; } } std::cout << "\n\n"; std::vector<const char *> instance_layers; instance_layers.push_back("VK_LAYER_LUNARG_standard_validation"); //И затем отправим их в стурктуру с информацией. instance_info.enabledLayerCount = instance_layers.size(); instance_info.ppEnabledLayerNames = instance_layers.data(); //Кол-во расширений. uint32_t available_instance_extension_count = 0; //Забираем кол-во расширений. res = vkEnumerateInstanceExtensionProperties(NULL, &available_instance_extension_count, nullptr); if (res != VK_SUCCESS) //Проверка { std::wcout << "Не удалось получить кол-во расширений.\n"; return -1; } //настраиваем массив std::vector<VkExtensionProperties> available_instance_extensions(available_instance_extension_count); //Получаем расширения res = vkEnumerateInstanceExtensionProperties(NULL, &available_instance_extension_count, available_instance_extensions.data()); if (available_instance_extension_count) { //Вывод на экран. std::wcout << L"\n\nРасширения экземпляра:\n"; for (uint32_t i = 0; i < available_instance_extensions.size(); i++) { VkExtensionProperties &properties = available_instance_extensions[i]; std::cout << properties.extensionName << "\n"; } std::cout << "\n\n"; } //Настройка расширений std::vector<const char *> instance_extensions; instance_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); instance_info.enabledExtensionCount = instance_extensions.size(); instance_info.ppEnabledExtensionNames = instance_extensions.data(); VkInstance instance = VK_NULL_HANDLE; res = vkCreateInstance(&instance_info, NULL, &instance); if (res != VK_SUCCESS) //С проверками особо заморачиваться не будем. { std::wcerr << L"Что-то не так...\n"; return -1; } else std::wcout << L"Экземпляр Vulkan создан.\n"; //Создадим указатели на функции таким образом. PFN_vkCreateDebugReportCallbackEXT fvkCreateDebugReportCallbackEXT = NULL; PFN_vkDestroyDebugReportCallbackEXT fvkDestroyDebugReportCallbackEXT = NULL; //И получим их. fvkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); fvkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); /* Отлично, мы получили эти функции! Теперь, нам нужно подготовить информацию для callback'ов, а также * оставить хэндл, который мы конечно же потом уничтожим. */ //Структура, которую мы должны заполнить VkDebugReportCallbackCreateInfoEXT debug_report_callback_info; memset(&debug_report_callback_info, 0, sizeof(debug_report_callback_info)); debug_report_callback_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; debug_report_callback_info.flags = VK_DEBUG_REPORT_DEBUG_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT; // Настало время прикрепить наш прототип здесь: debug_report_callback_info.pfnCallback = DebugReportCallback; VkDebugReportCallbackEXT debug_report_callback = VK_NULL_HANDLE; //И наконец-таки привзяываем наш Callback: res = fvkCreateDebugReportCallbackEXT(instance, &debug_report_callback_info, NULL, &debug_report_callback); if (res != VK_SUCCESS) { std::wcerr << L"Не удалось создать debug-report callback.\n"; return -1; } std::vector<VkPhysicalDevice> gpu_list; //здесь будем хранить физические устройства. uint32_t gpu_count; //кол-во девайсов //получаем колв-о девайсов и сразу проверяем на удачу. if (vkEnumeratePhysicalDevices(instance, &gpu_count, VK_NULL_HANDLE) != VK_SUCCESS) { std::wcerr << L"Посчитать физические устройства не удалось :(\n"; return -1; } gpu_list.resize(gpu_count); //заранее изменим размер под самый оптимальный. //Забираем физические девайсы if (vkEnumeratePhysicalDevices(instance, &gpu_count, gpu_list.data()) != VK_SUCCESS) { std::wcerr << L"Заполучить твои физические устройства не удалось, но я приду за ними в следующий раз!\n"; return -1; } //Выбираем видеокарту VkPhysicalDevice gpu = gpu_list[0]; //Теперь, семейства. uint32_t family_count = 0; //кол-во семейтсв vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, nullptr); std::vector<VkQueueFamilyProperties> family_properties_list(family_count); vkGetPhysicalDeviceQueueFamilyProperties(gpu, &family_count, family_properties_list.data()); //Листаем семейтсва и получаем нужное. uint32_t valid_family_index = (uint32_t) -1; //значение -1 будем использовать как "не найдено, 404". for (uint32_t i = 0; i < family_count; i++) //листаем все семейства. { VkQueueFamilyProperties &properties = family_properties_list[i]; if (properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) { if (valid_family_index == (uint32_t) -1) valid_family_index = i; } } //И если наш индекс всё ещё не перезаписан, то.. if (valid_family_index == (uint32_t) -1) return -1; //Описываем очереди. VkDeviceQueueCreateInfo device_queue_info; memset(&device_queue_info, 0, sizeof(device_queue_info)); device_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; float device_queue_priority[] = {1.0f}; device_queue_info.queueCount = 1; device_queue_info.queueFamilyIndex = valid_family_index; device_queue_info.pQueuePriorities = device_queue_priority; VkDeviceCreateInfo device_info; memset(&device_info, 0, sizeof(device_info)); device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; device_info.queueCreateInfoCount = 1; device_info.pQueueCreateInfos = &device_queue_info; uint32_t available_device_layer_count = 0; res = vkEnumerateDeviceLayerProperties(gpu, &available_device_layer_count, VK_NULL_HANDLE); if (res != VK_SUCCESS) { std::wcout << "Не удалось получить кол-во слоёв.\n"; return -1; } //настраиваем массив std::vector<VkLayerProperties> available_device_layers(available_device_layer_count); res = vkEnumerateDeviceLayerProperties(gpu, &available_device_layer_count, available_device_layers.data()); if (res != VK_SUCCESS) { std::wcout << "Не удалось получить слои.\n"; return -1; } if (available_device_layer_count) { //А теперь выводим на экран. std::wcout << L"\n\nСлои устройства:\n"; for (uint32_t i = 0; i < available_device_layer_count; i++) { //Сделаем красивый вывод для имени и описания слоя. VkLayerProperties &properties = available_device_layers[i]; std::cout << properties.layerName << (strlen(properties.layerName) < 24 ? "\t" : "") << (strlen(properties.layerName) < 32 ? "\t" : "") << "\t|" << properties.description << "\n"; } } std::cout << "\n\n"; //Кол-во расширений. uint32_t available_device_extension_count = 0; //Забираем кол-во расширений. res = vkEnumerateDeviceExtensionProperties(gpu, NULL, &available_device_extension_count, VK_NULL_HANDLE); if (res != VK_SUCCESS) //Проверка { std::wcout << "Не удалось получить кол-во расширений.\n"; return -1; } //настраиваем массив std::vector<VkExtensionProperties> available_device_extensions(available_device_extension_count); //Получаем расширения res = vkEnumerateDeviceExtensionProperties(gpu, NULL, &available_device_extension_count, available_device_extensions.data()); if (available_device_extension_count) { //Вывод на экран. std::wcout << L"\n\nРасширения устройства:\n"; for (uint32_t i = 0; i < available_device_extensions.size(); i++) { VkExtensionProperties &properties = available_device_extensions[i]; std::cout << properties.extensionName << "\n"; } std::cout << "\n\n"; } std::vector<const char *> device_layers = instance_layers; //Расширения и слои device_info.enabledLayerCount = device_layers.size(); device_info.ppEnabledLayerNames = device_layers.data(); //А расширения устройства оставим и на сей раз пустым. std::vector<const char *> device_extensions; device_info.enabledExtensionCount = device_extensions.size(); device_info.ppEnabledExtensionNames = device_extensions.data(); VkDevice device = VK_NULL_HANDLE; if (vkCreateDevice(gpu, &device_info, NULL, &device) != VK_SUCCESS) return -1; vkDestroyDevice(device, NULL); fvkDestroyDebugReportCallbackEXT(instance, debug_report_callback, NULL); vkDestroyInstance(instance, NULL); std::wcout << L"Пожарено!\n"; return 0; }
void OgldevVulkanCore::CreateInstance() { VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = m_appName.c_str(); appInfo.engineVersion = 1; appInfo.apiVersion = VK_API_VERSION_1_0; const char* pInstExt[] = { #ifdef ENABLE_DEBUG_LAYERS VK_EXT_DEBUG_REPORT_EXTENSION_NAME, #endif VK_KHR_SURFACE_EXTENSION_NAME, #ifdef _WIN32 VK_KHR_WIN32_SURFACE_EXTENSION_NAME, #else VK_KHR_XCB_SURFACE_EXTENSION_NAME #endif }; #ifdef ENABLE_DEBUG_LAYERS const char* pInstLayers[] = { "VK_LAYER_LUNARG_standard_validation" }; #endif VkInstanceCreateInfo instInfo = {}; instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instInfo.pApplicationInfo = &appInfo; #ifdef ENABLE_DEBUG_LAYERS instInfo.enabledLayerCount = ARRAY_SIZE_IN_ELEMENTS(pInstLayers); instInfo.ppEnabledLayerNames = pInstLayers; #endif instInfo.enabledExtensionCount = ARRAY_SIZE_IN_ELEMENTS(pInstExt); instInfo.ppEnabledExtensionNames = pInstExt; VkResult res = vkCreateInstance(&instInfo, NULL, &m_inst); CHECK_VULKAN_ERROR("vkCreateInstance %d\n", res); #ifdef ENABLE_DEBUG_LAYERS // Get the address to the vkCreateDebugReportCallbackEXT function my_vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(m_inst, "vkCreateDebugReportCallbackEXT")); // Register the debug callback VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; callbackCreateInfo.pNext = NULL; callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; callbackCreateInfo.pfnCallback = &MyDebugReportCallback; callbackCreateInfo.pUserData = NULL; VkDebugReportCallbackEXT callback; res = my_vkCreateDebugReportCallbackEXT(m_inst, &callbackCreateInfo, NULL, &callback); CHECK_VULKAN_ERROR("my_vkCreateDebugReportCallbackEXT error %d\n", res); #endif }