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
This commit is contained in:
Jeroen Bakker
2024-12-02 14:50:32 +01:00
parent cd57a17698
commit 108a0f2ec0
5 changed files with 95 additions and 46 deletions

View File

@@ -5,6 +5,7 @@
set(INC
PUBLIC .
../../source/blender/imbuf
../../source/blender/gpu
../guardedalloc
)

View File

@@ -21,6 +21,8 @@
# endif
#endif
#include "vulkan/vk_ghost_api.hh"
#include <vector>
#include <cassert>
@@ -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;

View File

@@ -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

View File

@@ -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<StringRefNull> missing_capabilities_get(VkPhysicalDevice vk_physical_device)
{
Vector<StringRefNull> missing_capabilities;
@@ -98,49 +146,6 @@ static Vector<StringRefNull> 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<StringRefNull> 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<StringRefNull> missing_capabilities = missing_capabilities_get(vk_physical_device);
/* Report result. */
if (missing_capabilities.is_empty()) {
/* This device meets minimum requirements. */

View File

@@ -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