From 108a0f2ec0aaca695bb61521a72af26c0410de13 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 2 Dec 2024 14:50:32 +0100 Subject: [PATCH] Vulkan: Share driver check between GPU and GHOST GPU and GHOST require to have identical checks to remove faulty drivers. When not done GHOST can still select a device that isn't supported and lead to freezing interfaces. Pull Request: https://projects.blender.org/blender/blender/pulls/131241 --- intern/ghost/CMakeLists.txt | 1 + intern/ghost/intern/GHOST_ContextVK.cc | 5 ++ source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/vulkan/vk_backend.cc | 104 ++++++++++++---------- source/blender/gpu/vulkan/vk_ghost_api.hh | 30 +++++++ 5 files changed, 95 insertions(+), 46 deletions(-) create mode 100644 source/blender/gpu/vulkan/vk_ghost_api.hh diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 7fba434b099..6fa6ee6a090 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -5,6 +5,7 @@ set(INC PUBLIC . ../../source/blender/imbuf + ../../source/blender/gpu ../guardedalloc ) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 737f2a8a03e..a7a15ab88e5 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -21,6 +21,8 @@ # endif #endif +#include "vulkan/vk_ghost_api.hh" + #include #include @@ -357,6 +359,9 @@ static GHOST_TSuccess ensure_vulkan_device(VkInstance vk_instance, if (!device_vk.has_extensions(required_extensions)) { continue; } + if (!blender::gpu::GPU_vulkan_is_supported_driver(physical_device)) { + continue; + } if (vk_surface != VK_NULL_HANDLE) { uint32_t format_count; diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 335db665910..720c10417ee 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -279,6 +279,7 @@ set(VULKAN_SRC vulkan/vk_drawlist.hh vulkan/vk_fence.hh vulkan/vk_framebuffer.hh + vulkan/vk_ghost_api.hh vulkan/vk_image_view.hh vulkan/vk_immediate.hh vulkan/vk_index_buffer.hh diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 6bc028f7501..61dd23bb6b0 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -22,6 +22,7 @@ #include "vk_drawlist.hh" #include "vk_fence.hh" #include "vk_framebuffer.hh" +#include "vk_ghost_api.hh" #include "vk_index_buffer.hh" #include "vk_pixel_buffer.hh" #include "vk_query.hh" @@ -37,13 +38,60 @@ static CLG_LogRef LOG = {"gpu.vulkan"}; namespace blender::gpu { -static const char *KNOWN_CRASHING_DRIVER = "unstable driver"; static const char *vk_extension_get(int index) { return VKBackend::get().device.extension_name_get(index); } +bool GPU_vulkan_is_supported_driver(VkPhysicalDevice vk_physical_device) +{ + /* Check for known faulty drivers. */ + VkPhysicalDeviceProperties2 vk_physical_device_properties = {}; + VkPhysicalDeviceDriverProperties vk_physical_device_driver_properties = {}; + vk_physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + vk_physical_device_driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + vk_physical_device_properties.pNext = &vk_physical_device_driver_properties; + vkGetPhysicalDeviceProperties2(vk_physical_device, &vk_physical_device_properties); + uint32_t conformance_version = VK_MAKE_API_VERSION( + vk_physical_device_driver_properties.conformanceVersion.major, + vk_physical_device_driver_properties.conformanceVersion.minor, + vk_physical_device_driver_properties.conformanceVersion.subminor, + vk_physical_device_driver_properties.conformanceVersion.patch); + + /* Intel IRIS on 10th gen CPU (and older) crashes due to multiple driver issues. + * + * 1) Workbench is working, but EEVEE pipelines are failing. Calling vkCreateGraphicsPipelines + * for certain EEVEE shaders (Shadow, Deferred rendering) would return with VK_SUCCESS, but + * without a created VkPipeline handle. + * + * 2) When vkCmdBeginRendering is called some requirements need to be met, that can only be met + * when actually calling a vkCmdDraw* command. According to the Vulkan specs the requirements + * should only be met when calling a vkCmdDraw* command. + */ + if (vk_physical_device_driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && + vk_physical_device_properties.properties.deviceType == + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && + conformance_version < VK_MAKE_API_VERSION(1, 3, 2, 0)) + { + return false; + } + + /* NVIDIA drivers below 550 don't work. When sending command to the GPU there is no reply back + * when they are finished. Driver 550 should support GTX 700 and above GPUs. + * + * NOTE: We should retest later after fixing other issues. Allowing more drivers is always + * better as reporting to the user is quite limited. + */ + if (vk_physical_device_driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY && + conformance_version < VK_MAKE_API_VERSION(1, 3, 7, 2)) + { + return false; + } + + return true; +} + static Vector missing_capabilities_get(VkPhysicalDevice vk_physical_device) { Vector missing_capabilities; @@ -98,49 +146,6 @@ static Vector missing_capabilities_get(VkPhysicalDevice vk_physic missing_capabilities.append(VK_KHR_SWAPCHAIN_EXTENSION_NAME); } - /* Check for known faulty drivers. */ - VkPhysicalDeviceProperties2 vk_physical_device_properties = {}; - VkPhysicalDeviceDriverProperties vk_physical_device_driver_properties = {}; - vk_physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; - vk_physical_device_driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; - vk_physical_device_properties.pNext = &vk_physical_device_driver_properties; - vkGetPhysicalDeviceProperties2(vk_physical_device, &vk_physical_device_properties); - uint32_t conformance_version = VK_MAKE_API_VERSION( - vk_physical_device_driver_properties.conformanceVersion.major, - vk_physical_device_driver_properties.conformanceVersion.minor, - vk_physical_device_driver_properties.conformanceVersion.subminor, - vk_physical_device_driver_properties.conformanceVersion.patch); - - /* Intel IRIS on 10th gen CPU (and older) crashes due to multiple driver issues. - * - * 1) Workbench is working, but EEVEE pipelines are failing. Calling vkCreateGraphicsPipelines - * for certain EEVEE shaders (Shadow, Deferred rendering) would return with VK_SUCCESS, but - * without a created VkPipeline handle. - * - * 2) When vkCmdBeginRendering is called some requirements need to be met, that can only be met - * when actually calling a vkCmdDraw* command. According to the Vulkan specs the requirements - * should only be met when calling a vkCmdDraw* command. - */ - if (vk_physical_device_driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && - vk_physical_device_properties.properties.deviceType == - VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && - conformance_version < VK_MAKE_API_VERSION(1, 3, 2, 0)) - { - missing_capabilities.append(KNOWN_CRASHING_DRIVER); - } - - /* NVIDIA drivers below 550 don't work. When sending command to the GPU there is no reply back - * when they are finished. Driver 550 should support GTX 700 and above GPUs. - * - * NOTE: We should retest later after fixing other issues. Allowing more drivers is always - * better as reporting to the user is quite limited. - */ - if (vk_physical_device_driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY && - conformance_version < VK_MAKE_API_VERSION(1, 3, 7, 2)) - { - missing_capabilities.append(KNOWN_CRASHING_DRIVER); - } - return missing_capabilities; } @@ -173,11 +178,18 @@ bool VKBackend::is_supported() vkEnumeratePhysicalDevices(vk_instance, &physical_devices_count, vk_physical_devices.data()); for (VkPhysicalDevice vk_physical_device : vk_physical_devices) { - Vector missing_capabilities = missing_capabilities_get(vk_physical_device); - VkPhysicalDeviceProperties vk_properties = {}; vkGetPhysicalDeviceProperties(vk_physical_device, &vk_properties); + if (!GPU_vulkan_is_supported_driver(vk_physical_device)) { + CLOG_WARN(&LOG, + "Installed driver for device [%s] has known issues and will not be used. Updating " + "driver might improve compatibility.", + vk_properties.deviceName); + continue; + } + Vector missing_capabilities = missing_capabilities_get(vk_physical_device); + /* Report result. */ if (missing_capabilities.is_empty()) { /* This device meets minimum requirements. */ diff --git a/source/blender/gpu/vulkan/vk_ghost_api.hh b/source/blender/gpu/vulkan/vk_ghost_api.hh new file mode 100644 index 00000000000..5c71f3cb86d --- /dev/null +++ b/source/blender/gpu/vulkan/vk_ghost_api.hh @@ -0,0 +1,30 @@ +/* SPDX-FileCopyrightText: 2022 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +/** This file contains API that the GHOST_ContextVK can invoke directly. */ + +namespace blender::gpu { + +/** + * Is the driver of the given physical device supported? + * + * There are some drivers that have known issues and should not be used. This check needs to be + * identical between GPU module and GHOST, otherwise GHOST can still select a device which isn't + * supported. + * + * For example on a Linux machine where llvmpipe is installed and an not supported NVIDIA driver + * Blender would detect a supported configuration using llvmpipe, but GHOST could still select the + * unsupported NVIDIA driver. + * + * Returns true when supported, false when not supported. + */ +bool GPU_vulkan_is_supported_driver(VkPhysicalDevice vk_physical_device); + +} // namespace blender::gpu