void Device::Destroy() { if (VK_NULL_HANDLE == m_Device) return; for (auto pll : m_CachedPipelineLayout) { pll.second->~PipelineLayout(); } m_CachedPipelineLayout.clear(); for (auto dsl : m_CachedDescriptorSetLayout) { dsl.second->~DescriptorSetLayout(); } for (auto alloc : m_CachedDescriptorPool) { alloc.second->~DescriptorAllocator(); } m_CachedDescriptorSetLayout.clear(); m_PendingPass.~vector(); m_ResourceManager->~ResourceManager(); m_ContextPool->~CommandContextPool(); vkDestroyDevice(m_Device, nullptr); VKLOG(Info, "Device-Destroyed"); m_Device = VK_NULL_HANDLE; }
int sample_main() { struct sample_info info = {}; init_instance(info, "vulkansamples_device"); init_enumerate_device(info); /* VULKAN_KEY_START */ 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); float queue_priorities[1] = {0.0}; 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.enabledExtensionCount = 0; device_info.ppEnabledExtensionNames = NULL; device_info.enabledLayerCount = 0; device_info.ppEnabledLayerNames = NULL; device_info.pEnabledFeatures = NULL; VkDevice device; VkResult U_ASSERT_ONLY res = vkCreateDevice(info.gpus[0], &device_info, NULL, &device); assert(res == VK_SUCCESS); vkDestroyDevice(device, NULL); /* VULKAN_KEY_END */ destroy_instance(info); return 0; }
VulkanCommon::~VulkanCommon() { if( Vulkan.Device != VK_NULL_HANDLE ) { vkDeviceWaitIdle( Vulkan.Device ); for( size_t i = 0; i < Vulkan.SwapChain.Images.size(); ++i ) { if( Vulkan.SwapChain.Images[i].ImageView != VK_NULL_HANDLE ) { vkDestroyImageView( GetDevice(), Vulkan.SwapChain.Images[i].ImageView, nullptr ); } } if( Vulkan.SwapChain.Handle != VK_NULL_HANDLE ) { vkDestroySwapchainKHR( Vulkan.Device, Vulkan.SwapChain.Handle, nullptr ); } vkDestroyDevice( Vulkan.Device, nullptr ); } if( Vulkan.PresentationSurface != VK_NULL_HANDLE ) { vkDestroySurfaceKHR( Vulkan.Instance, Vulkan.PresentationSurface, nullptr ); } if( Vulkan.Instance != VK_NULL_HANDLE ) { vkDestroyInstance( Vulkan.Instance, nullptr ); } if( VulkanLibrary ) { #if defined(VK_USE_PLATFORM_WIN32_KHR) FreeLibrary( VulkanLibrary ); #elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) dlclose( VulkanLibrary ); #endif } }
GrVkBackendContext::~GrVkBackendContext() { vkDeviceWaitIdle(fDevice); vkDestroyDevice(fDevice, nullptr); fDevice = VK_NULL_HANDLE; vkDestroyInstance(fInstance, nullptr); fInstance = VK_NULL_HANDLE; }
void destroy_vulkan_renderer_backend(ReaperRoot& root, VulkanBackend& backend) { REAPER_PROFILE_SCOPE("Vulkan", MP_RED1); log_info(root, "vulkan: destroying backend"); destroy_vulkan_wm_swapchain(root, backend, backend.presentInfo); log_debug(root, "vulkan: waiting for current work to finish"); Assert(vkDeviceWaitIdle(backend.device) == VK_SUCCESS); log_debug(root, "vulkan: destroying logical device"); vkDestroyDevice(backend.device, nullptr); log_debug(root, "vulkan: destroying presentation surface"); vkDestroySurfaceKHR(backend.instance, backend.presentInfo.surface, nullptr); delete root.renderer->window; root.renderer->window = nullptr; #if defined(REAPER_DEBUG) log_debug(root, "vulkan: detaching debug callback"); vulkan_destroy_debug_callback(backend); #endif vkDestroyInstance(backend.instance, nullptr); log_debug(root, "vulkan: unloading {}", REAPER_VK_LIB_NAME); Assert(backend.vulkanLib != nullptr); dynlib::close(backend.vulkanLib); backend.vulkanLib = nullptr; }
//Destroyer VulkanBase::~VulkanBase() { // Wait until all operations are complete to destroy stuff CHECK_RESULT(vkQueueWaitIdle(queue)); swapchain.clean(); //vkFreeCommandBuffers(device, commandPool, commandBuffersVector.size(), commandBuffersVector.data()); vkDestroyCommandPool(device, commandPool, nullptr); // Destroy synchronization elements vkDestroySemaphore(device, imageAcquiredSemaphore, nullptr); vkDestroySemaphore(device, renderingCompletedSemaphore, nullptr); vkDestroyFence(device, presentFence, nullptr); // Destroy logical device vkDestroyDevice(device, nullptr); #ifdef _DEBUG if (enableValidation) { vkDebug::freeDebugCallback(instance); } #endif // _DEBUG vkDestroyInstance(instance,nullptr); }
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 Win32CleanShutdown(HWND window) { g_Running = false; vkDestroySurfaceKHR(VKInstance, surface, NULL); vkDestroyInstance(VKInstance, NULL); vkDestroyDevice(device_handle, NULL); ReleaseDC(window, g_WindowDC); PostQuitMessage(0); }
VulkanExampleBase::~VulkanExampleBase() { // Clean up Vulkan resources swapChain.cleanup(); if (descriptorPool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(device, descriptorPool, nullptr); } if (setupCmdBuffer != VK_NULL_HANDLE) { vkFreeCommandBuffers(device, cmdPool, 1, &setupCmdBuffer); } destroyCommandBuffers(); vkDestroyRenderPass(device, renderPass, nullptr); for (uint32_t i = 0; i < frameBuffers.size(); i++) { vkDestroyFramebuffer(device, frameBuffers[i], nullptr); } for (auto& shaderModule : shaderModules) { vkDestroyShaderModule(device, shaderModule, nullptr); } vkDestroyImageView(device, depthStencil.view, nullptr); vkDestroyImage(device, depthStencil.image, nullptr); vkFreeMemory(device, depthStencil.mem, nullptr); vkDestroyPipelineCache(device, pipelineCache, nullptr); if (textureLoader) { delete textureLoader; } vkDestroyCommandPool(device, cmdPool, nullptr); vkDestroySemaphore(device, semaphores.presentComplete, nullptr); vkDestroySemaphore(device, semaphores.renderComplete, nullptr); vkDestroyDevice(device, nullptr); if (enableValidation) { vkDebug::freeDebugCallback(instance); } vkDestroyInstance(instance, nullptr); #if defined(__linux) #if defined(__ANDROID__) // todo : android cleanup (if required) #else xcb_destroy_window(connection, window); xcb_disconnect(connection); #endif #endif }
TEST(WrapObjects, Insert) { VkInstance instance = VK_NULL_HANDLE; VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance); ASSERT_EQ(result, VK_SUCCESS); uint32_t physicalCount = 0; result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr); ASSERT_EQ(result, VK_SUCCESS); ASSERT_GT(physicalCount, 0u); std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]); result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get()); ASSERT_EQ(result, VK_SUCCESS); ASSERT_GT(physicalCount, 0u); for(uint32_t p = 0; p < physicalCount; ++p) { uint32_t familyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr); ASSERT_EQ(result, VK_SUCCESS); ASSERT_GT(familyCount, 0u); std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]); vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get()); ASSERT_EQ(result, VK_SUCCESS); ASSERT_GT(familyCount, 0u); for(uint32_t q = 0; q < familyCount; ++q) { if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) { continue; } float const priorities[] = {0.0f}; // Temporary required due to MSVC bug. VkDeviceQueueCreateInfo const queueInfo[1] { VK::DeviceQueueCreateInfo(). queueFamilyIndex(q). queueCount(1). pQueuePriorities(priorities) }; auto const deviceInfo = VK::DeviceCreateInfo(). queueCreateInfoCount(1). pQueueCreateInfos(queueInfo); VkDevice device; result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device); ASSERT_EQ(result, VK_SUCCESS); vkDestroyDevice(device, nullptr); } } vkDestroyInstance(instance, nullptr); }
VulkanContext::~VulkanContext() { if (m_device != VK_NULL_HANDLE) vkDestroyDevice(m_device, nullptr); if (m_debug_report_callback != VK_NULL_HANDLE) DisableDebugReports(); vkDestroyInstance(m_instance, nullptr); }
/** * Default destructor * * @note Frees the logical device */ ~VulkanDevice() { if (commandPool) { vkDestroyCommandPool(logicalDevice, commandPool, nullptr); } if (logicalDevice) { vkDestroyDevice(logicalDevice, nullptr); } }
void VulkanContext::DestroyDevice() { ILOG("VulkanContext::DestroyDevice (performing deletes)"); // If there happen to be any pending deletes, now is a good time. for (int i = 0; i < ARRAY_SIZE(frame_); i++) { frame_[i].deleteList.PerformDeletes(device_); } Delete().PerformDeletes(device_); vkDestroyDevice(device_, nullptr); device_ = nullptr; }
Device::~Device() { if (!initialized()) return; for (int i = 0; i < QUEUE_COUNT; i++) { for (std::vector<Queue *>::iterator it = queues_[i].begin(); it != queues_[i].end(); it++) delete *it; queues_[i].clear(); } vkDestroyDevice(handle(), NULL); }
void VkContext::Destroy() { vkDeviceWaitIdle(dev); // Free command buffers if (drawCmdBuffers.size() > 0) { vkFreeCommandBuffers(dev, cmdPool, (u32)drawCmdBuffers.size(), &drawCmdBuffers[0]); } // Destroy command pools vkDestroyCommandPool(dev, cmdPool, nullptr); // Destroy semaphores vkDestroySemaphore(dev, acquireCompleteSemaphore, nullptr); vkDestroySemaphore(dev, renderCompleteSemaphore, nullptr); // Destroy swapchain image views for (u32 i = 0; i < swapchainImageViews.size(); i++) { vkDestroyImageView(dev, swapchainImageViews[i], nullptr); } // Destroy swapchain if (swapchain) { vkDestroySwapchainKHR(dev, swapchain, nullptr); } // Destroy surface if (surf) { vkDestroySurfaceKHR(instance, surf, nullptr); } // Destroy device if (dev) { vkDestroyDevice(dev, nullptr); } #ifdef VOXL_DEBUG // Destroy debug report callback if (msgCallback != VK_NULL_HANDLE) { vkDestroyDebugReportCallbackEXT(instance, msgCallback, nullptr); } #endif // Destroy instance if (instance) { vkDestroyInstance(instance, nullptr); } // Terminate GLFW glfwTerminate(); }
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); }
Tutorial01::~Tutorial01() { if( Vulkan.Device != VK_NULL_HANDLE ) { vkDeviceWaitIdle( Vulkan.Device ); vkDestroyDevice( Vulkan.Device, nullptr ); } if( Vulkan.Instance != VK_NULL_HANDLE ) { vkDestroyInstance( Vulkan.Instance, nullptr ); } if( VulkanLibrary ) { #if defined(VK_USE_PLATFORM_WIN32_KHR) FreeLibrary( VulkanLibrary ); #elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) dlclose( VulkanLibrary ); #endif } }
void cleanup() { vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyRenderPass(device, renderPass, nullptr); for (auto imageView : swapChainImageViews) { vkDestroyImageView(device, imageView, nullptr); } vkDestroySwapchainKHR(device, swapChain, nullptr); vkDestroyDevice(device, nullptr); DestroyDebugReportCallbackEXT(instance, callback, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); glfwDestroyWindow(window); glfwTerminate(); }
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; }
void shutdown() { on_window_resize_listener = static_cast<size_t >(-1); if (vk_globals::device != nullptr) { vkDeviceWaitIdle(vk_globals::device); shutdown_swap_chain(); vkDestroyDevice(vk_globals::device, nullptr); vk_globals::device = nullptr; } if (vk_globals::surface != nullptr) { vkDestroySurfaceKHR(vk_globals::instance, vk_globals::surface, nullptr); } if (vk_globals::instance != nullptr) { vkDestroyInstance(vk_globals::instance, nullptr); } }
//int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) int main(int argc, char *argv[]) { VkInstance vk_instance = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE; SwapChain swap_chain; DrawCommandBuffer command_buffer; VkCommandPool swap_chain_command_pool = VK_NULL_HANDLE; VkCommandPool draw_command_pool = VK_NULL_HANDLE; if (VkResult err = init_Vulkan(vk_instance, &device, &command_buffer, &swap_chain)) { print_vk_error_code("Unable to initialize Vulkan: ", err); return 1; } // Swap chain command pool create_command_pool(device, swap_chain.queue_family_idx, &swap_chain_command_pool); if (swap_chain.queue_family_idx == command_buffer.queue_family_idx) { draw_command_pool = swap_chain_command_pool; } else { create_command_pool(device, command_buffer.queue_family_idx, &draw_command_pool); } uint32_t w = 800; uint32_t h = 600; setup(device, swap_chain_command_pool, swap_chain, &w, &h); //while (true) { // clear screen // swap chain } vkDestroyDevice(device, nullptr); vkDestroyInstance(vk_instance, nullptr); return 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Main // int main() { if( createWindow() ) { if( initVkInstance( "vulkan_test", "lamp_engine" ) ) { getDevicesList(); if( findSupportedQueue() && createDevice() ) { if( initCommandBuffers() ) { if( initSwapChains() ) { ShowWindow( ghWnd, true ); // Start loop MSG msg; while( !gClose && GetMessage( &msg, NULL, 0, 0 ) > 0 ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } vkFreeCommandBuffers( gDevice, gCmdPool, 1, &gCmd ); vkDestroyCommandPool( gDevice, gCmdPool, nullptr ); } vkDestroyDevice( gDevice, nullptr ); } vkDestroyInstance( gInstance, nullptr ); } } system("PAUSE"); return 0; }
VulkanBase::~VulkanBase() { swapChain.cleanup(); vkDestroyDescriptorPool(device, descriptorPool, nullptr); if (setupCmdBuffer != VK_NULL_HANDLE) vkFreeCommandBuffers(device, cmdPool, 1, &setupCmdBuffer); destroyCommandBuffers(); vkDestroyRenderPass(device, renderPass, nullptr); for (uint32_t i = 0; i < frameBuffers.size(); i++) vkDestroyFramebuffer(device, frameBuffers[i], nullptr); for (auto& shaderModule : shaderModules) vkDestroyShaderModule(device, shaderModule, nullptr); vkDestroyImageView(device, depthStencil.view, nullptr); vkDestroyImage(device, depthStencil.image, nullptr); vkFreeMemory(device, depthStencil.mem, nullptr); vkDestroyPipelineCache(device, pipelineCache, nullptr); if (textureLoader) delete textureLoader; vkDestroyCommandPool(device, cmdPool, nullptr); vkDestroySemaphore(device, semaphores.presentComplete, nullptr); vkDestroySemaphore(device, semaphores.renderComplete, nullptr); vkDestroyDevice(device, nullptr); if (enableValidation) vkDebug::freeDebugCallback(instance); vkDestroyInstance(instance, nullptr); }
static void gst_vulkan_device_finalize (GObject * object) { GstVulkanDevice *device = GST_VULKAN_DEVICE (object); g_free (device->queue_family_props); device->queue_family_props = NULL; if (device->cmd_pool) vkDestroyCommandPool (device->device, device->cmd_pool, NULL); device->cmd_pool = VK_NULL_HANDLE; if (device->device) { vkDeviceWaitIdle (device->device); vkDestroyDevice (device->device, NULL); } device->device = VK_NULL_HANDLE; if (device->instance) gst_object_unref (device->instance); device->instance = VK_NULL_HANDLE; G_OBJECT_CLASS (parent_class)->finalize (object); }
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 VulkanDevice::Unload(VulkanInstance * vulkanInstance) { vkDestroyDevice(device, VK_NULL_HANDLE); vkDestroySurfaceKHR(vulkanInstance->GetInstance(), surface, VK_NULL_HANDLE); }
VKDevice::~VKDevice () { if (_dev_id) vkDestroyDevice (_dev_id, _allocator.ptr ()); }
TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
int main(){ printf("This code initializes a Vulkan device"); /** Steps required 1. Create Vulkan Instance 2. Enumerate the GPUs 3. Query Queues on the GPU (Queues represent on what 'channels' will the data process, query the queue for COMPUTE type queue or GRAPHICS type queue 4. Create a queue priority 5. Create a device with information from 2, 3 and 4 **/ /** 1. Create Vulkan Instance **/ VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pNext = NULL; appInfo.pApplicationName = APP_SHORT_NAME; appInfo.applicationVersion = 1; appInfo.pEngineName = APP_SHORT_NAME; appInfo.engineVersion = 1; appInfo.apiVersion = VK_API_VERSION; VkInstanceCreateInfo icInfo = {}; icInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; icInfo.pNext = NULL; icInfo.flags = 0; icInfo.pApplicationInfo = & appInfo; icInfo.enabledExtensionCount = 0; icInfo.ppEnabledExtensionNames = NULL; icInfo.enabledLayerCount = 0; icInfo.enabledLayerCount = NULL; VkInstance instance; VkResult res; res = vkCreateInstance(&icInfo, NULL, &instance); if(res == VK_ERROR_INCOMPATIBLE_DRIVER){ printf("Cannot find a Vulkan Compatible ICD\n"); exit(-1); } else if(res){ printf("Some error occured\n"); exit(-1); } printf("Yay! Vulkan is initialized\n"); /** 2. Enumerate the GPUs **/ uint32_t gpuCount = 0; res = vkEnumeratePhysicalDevices(instance, &gpuCount, NULL); printf("found %d gpus\n", gpuCount); VkPhysicalDevice* gpus = new VkPhysicalDevice[gpuCount]; printf("Listing gpus...\n", gpuCount); res = vkEnumeratePhysicalDevices(instance, &gpuCount, gpus); while(++idx < gpuCount){ VkPhysicalDeviceProperties props= {}; vkGetPhysicalDeviceProperties(gpus[idx], &props); printf("%d-%d-%d-%d-%s\n", props.apiVersion, props.driverVersion, props.vendorID, props.deviceID, props.deviceName); } /** 3. Query for the supported queues **/ /** From renderdocs vulkan Command buffers are submitted to a VkQueue. The notion of queues are how work becomes serialised to be passed to the GPU. A VkPhysicalDevice (remember way back? The GPU handle) can report a number of queue families with different capabilities. e.g. a graphics queue family and a compute-only queue family. When you create your device you ask for a certain number of queues from each family, and then you can enumerate them from the device after creation with vkGetDeviceQueue(). **/ uint32_t queue_count = 0; vkGetPhysicalDeviceQueueFamilyProperties(gpus[0], &queue_count, NULL); if(queue_count <= 0){ printf("No Queues found.. aborting\n"); exit(-1); } VkQueueFamilyProperties* queue_props = new VkQueueFamilyProperties[queue_count]; vkGetPhysicalDeviceQueueFamilyProperties(gpus[0], &queue_count, queue_props); float queue_priorities[1] = {0.0}; /** 4. Create a queue priority **/ VkDeviceQueueCreateInfo qi = {}; qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; qi.pNext = NULL; qi.queueCount = 1; qi.pQueuePriorities = queue_priorities; idx = -1; while(++idx < queue_count){ if(queue_props[idx].queueFlags & VK_QUEUE_GRAPHICS_BIT){ //Look for a queue that has Graphics capabilities qi.queueFamilyIndex = idx; break; } } /** 5. Create a device with information from 2, 3 and 4 **/ VkDeviceCreateInfo dci = {}; dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; dci.pNext = NULL; dci.queueCreateInfoCount = 1; dci.pQueueCreateInfos = &qi; dci.enabledExtensionCount = 0; dci.ppEnabledExtensionNames = NULL; dci.enabledLayerCount = 0; dci.ppEnabledLayerNames = NULL; dci.pEnabledFeatures = NULL; VkDevice device; res = vkCreateDevice(gpus[0], &dci, NULL, &device); if(res){ printf("There was a problem creating the device"); exit(-1); } /** All's great, first thing lets create a command buffer **/ VkCommandPoolCreateInfo cpci = {}; cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cpci.pNext = NULL; cpci.queueFamilyIndex = qi.queueFamilyIndex; cpci.flags = 0; VkCommandPool cp; res = vkCreateCommandPool(device, &cpci, NULL, &cp); if(res){ printf("There was a problem creating a command pool"); exit(-1); } /** Create a command buffer from the command pool **/ VkCommandBufferAllocateInfo cbai = {}; cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; cbai.pNext = NULL; cbai.commandPool = cp; cbai.commandBufferCount = 1; cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; VkCommandBuffer* commandBuffer = new VkCommandBuffer[1]; //single command res = vkAllocateCommandBuffers(device, &cbai, commandBuffer); if(res){ printf("There was a problem creating a command buffer"); exit(-1); } /** no, we never leave the crap behind **/ vkFreeCommandBuffers(device, cp, 1, commandBuffer); vkDestroyCommandPool(device, cp, NULL); vkDestroyDevice(device, NULL); printf("Device created"); vkDestroyInstance(instance, NULL); delete[] gpus; return 0; }
void Renderer::_DeInitDevice() { vkDestroyDevice(_device, nullptr); _device = nullptr; }