void VideoBackend::Shutdown() { // TODO: should be in Video_Cleanup // Immediately stop app from submitting work to GPU, and wait for all submitted work to complete. // D3D12TODO: Check this. D3D::command_list_mgr->ExecuteQueuedWork(true); // internal interfaces D3D::ShutdownUtils(); ShaderCache::Shutdown(); ShaderConstantsManager::Shutdown(); StaticShaderCache::Shutdown(); BBox::Shutdown(); g_xfb_encoder.reset(); g_perf_query.reset(); g_vertex_manager.reset(); g_texture_cache.reset(); g_renderer.reset(); D3D::Close(); ShutdownShared(); }
void VideoBackend::Shutdown() { g_command_buffer_mgr->WaitForGPUIdle(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); }
void VideoBackend::Shutdown() { g_shader_cache->Shutdown(); g_renderer->Shutdown(); g_texture_cache.reset(); g_perf_query.reset(); g_vertex_manager.reset(); g_framebuffer_manager.reset(); g_renderer.reset(); ShutdownShared(); }
void VideoBackend::Shutdown() { g_shader_cache->Shutdown(); g_renderer->Shutdown(); BoundingBox::Shutdown(); g_sampler_cache.reset(); g_texture_cache.reset(); g_perf_query.reset(); g_vertex_manager.reset(); g_framebuffer_manager.reset(); g_shader_cache.reset(); ProgramShaderCache::Shutdown(); g_renderer.reset(); ShutdownShared(); }
void VideoBackend::Shutdown() { // TODO: should be in Video_Cleanup D3D::ShutdownUtils(); PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); GeometryShaderCache::Shutdown(); BBox::Shutdown(); g_perf_query.reset(); g_vertex_manager.reset(); g_texture_cache.reset(); g_renderer.reset(); ShutdownShared(); }
void VideoSoftware::Shutdown() { if (g_shader_cache) g_shader_cache->Shutdown(); if (g_renderer) g_renderer->Shutdown(); DebugUtil::Shutdown(); g_texture_cache.reset(); g_perf_query.reset(); g_framebuffer_manager.reset(); g_shader_cache.reset(); g_vertex_manager.reset(); g_renderer.reset(); ShutdownShared(); }
void VideoBackend::Shutdown() { g_renderer->Shutdown(); D3D::ShutdownUtils(); PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); GeometryShaderCache::Shutdown(); BBox::Shutdown(); g_perf_query.reset(); g_vertex_manager.reset(); g_texture_cache.reset(); g_renderer.reset(); ShutdownShared(); D3D::Close(); }
void VideoBackend::Shutdown() { if (g_renderer) g_renderer->Shutdown(); if (g_command_buffer_mgr) g_command_buffer_mgr->WaitForGPUIdle(); g_perf_query.reset(); g_texture_cache.reset(); g_vertex_manager.reset(); g_renderer.reset(); g_framebuffer_manager.reset(); StateTracker::DestroyInstance(); if (g_shader_cache) g_shader_cache->Shutdown(); g_shader_cache.reset(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); ShutdownShared(); UnloadVulkanLibrary(); }
void VideoBackend::Shutdown() { GLInterface->Shutdown(); GLInterface.reset(); ShutdownShared(); }
void VideoSoftware::Shutdown() { SWOGLWindow::Shutdown(); ShutdownShared(); }
bool VideoBackend::Initialize(void* window_handle) { if (!LoadVulkanLibrary()) { PanicAlert("Failed to load Vulkan library."); return false; } // HACK: Use InitBackendInfo to initially populate backend features. // This is because things like stereo get disabled when the config is validated, // which happens before our device is created (settings control instance behavior), // and we don't want that to happen if the device actually supports it. InitBackendInfo(); InitializeShared(); // Check for presence of the debug layer before trying to enable it bool enable_validation_layer = g_Config.bEnableValidationLayer; if (enable_validation_layer && !VulkanContext::CheckValidationLayerAvailablility()) { WARN_LOG(VIDEO, "Validation layer requested but not available, disabling."); enable_validation_layer = false; } // Create Vulkan instance, needed before we can create a surface. bool enable_surface = (window_handle != nullptr); VkInstance instance = VulkanContext::CreateVulkanInstance(enable_surface, enable_validation_layer); if (instance == VK_NULL_HANDLE) { PanicAlert("Failed to create Vulkan instance."); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Load instance function pointers if (!LoadVulkanInstanceFunctions(instance)) { PanicAlert("Failed to load Vulkan instance functions."); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create Vulkan surface VkSurfaceKHR surface = VK_NULL_HANDLE; if (enable_surface) { surface = SwapChain::CreateVulkanSurface(instance, window_handle); if (surface == VK_NULL_HANDLE) { PanicAlert("Failed to create Vulkan surface."); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } } // Fill the adapter list, and check if the user has selected an invalid device // For some reason nvidia's driver crashes randomly if you call vkEnumeratePhysicalDevices // after creating a device.. VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(instance); size_t selected_adapter_index = static_cast<size_t>(g_Config.iAdapter); if (gpu_list.empty()) { PanicAlert("No Vulkan physical devices available."); if (surface != VK_NULL_HANDLE) vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); UnloadVulkanLibrary(); ShutdownShared(); return false; } else if (selected_adapter_index >= gpu_list.size()) { WARN_LOG(VIDEO, "Vulkan adapter index out of range, selecting first adapter."); selected_adapter_index = 0; } // Pass ownership over to VulkanContext, and let it take care of everything. g_vulkan_context = VulkanContext::Create(instance, gpu_list[selected_adapter_index], surface, &g_Config, enable_validation_layer); if (!g_vulkan_context) { PanicAlert("Failed to create Vulkan device"); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create swap chain. This has to be done early so that the target size is correct for auto-scale. std::unique_ptr<SwapChain> swap_chain; if (surface != VK_NULL_HANDLE) { swap_chain = SwapChain::Create(window_handle, surface, g_Config.IsVSync()); if (!swap_chain) { PanicAlert("Failed to create Vulkan swap chain."); return false; } } // Create command buffers. We do this separately because the other classes depend on it. g_command_buffer_mgr = std::make_unique<CommandBufferManager>(g_Config.bBackendMultithreading); if (!g_command_buffer_mgr->Initialize()) { PanicAlert("Failed to create Vulkan command buffers"); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create main wrapper instances. g_object_cache = std::make_unique<ObjectCache>(); g_framebuffer_manager = std::make_unique<FramebufferManager>(); g_renderer = std::make_unique<Renderer>(std::move(swap_chain)); // Invoke init methods on main wrapper classes. // These have to be done before the others because the destructors // for the remaining classes may call methods on these. if (!g_object_cache->Initialize() || !FramebufferManager::GetInstance()->Initialize() || !StateTracker::CreateInstance() || !Renderer::GetInstance()->Initialize()) { PanicAlert("Failed to initialize Vulkan classes."); g_renderer.reset(); StateTracker::DestroyInstance(); g_framebuffer_manager.reset(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } // Create remaining wrapper instances. g_vertex_manager = std::make_unique<VertexManager>(); g_texture_cache = std::make_unique<TextureCache>(); g_perf_query = std::make_unique<PerfQuery>(); if (!VertexManager::GetInstance()->Initialize() || !TextureCache::GetInstance()->Initialize() || !PerfQuery::GetInstance()->Initialize()) { PanicAlert("Failed to initialize Vulkan classes."); g_perf_query.reset(); g_texture_cache.reset(); g_vertex_manager.reset(); g_renderer.reset(); StateTracker::DestroyInstance(); g_framebuffer_manager.reset(); g_object_cache.reset(); g_command_buffer_mgr.reset(); g_vulkan_context.reset(); UnloadVulkanLibrary(); ShutdownShared(); return false; } return true; }