Disable ubershaders on problematic Adreno compiler versions.
This commit is contained in:
@@ -615,6 +615,8 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
||||
}
|
||||
}
|
||||
|
||||
_register_requested_device_extension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
|
||||
|
||||
uint32_t device_extension_count = 0;
|
||||
VkResult err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, nullptr);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan device extension count (VkResult error %d).", err));
|
||||
@@ -684,6 +686,81 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
void RenderingDeviceDriverVulkan::_check_driver_workarounds(const VkPhysicalDeviceProperties &p_device_properties, const VkPhysicalDeviceDriverPropertiesKHR *p_driver_properties) {
|
||||
// Workaround a driver bug on Adreno 5XX GPUs that causes a crash when
|
||||
// there are empty descriptor set layouts placed between non-empty ones.
|
||||
adreno_5xx_empty_descriptor_set_layout_workaround =
|
||||
p_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM &&
|
||||
p_device_properties.deviceID >= 0x5000000 &&
|
||||
p_device_properties.deviceID < 0x6000000;
|
||||
|
||||
// Workaround for the Adreno 6XX family of devices.
|
||||
//
|
||||
// There's a known issue with the Vulkan driver in this family of devices where it'll crash if a dynamic state for drawing is
|
||||
// used in a command buffer before a dispatch call is issued. As both dynamic scissor and viewport are basic requirements for
|
||||
// the engine to not bake this state into the PSO, the only known way to fix this issue is to reset the command buffer entirely.
|
||||
//
|
||||
// As the render graph has no built in limitations of whether it'll issue compute work before anything needs to draw on the
|
||||
// frame, and there's no guarantee that compute work will never be dependent on rasterization in the future, this workaround
|
||||
// will end recording on the current command buffer any time a compute list is encountered after a draw list was executed.
|
||||
// A new command buffer will be created afterwards and the appropriate synchronization primitives will be inserted.
|
||||
//
|
||||
// Executing this workaround has the added cost of synchronization between all the command buffers that are created as well as
|
||||
// all the individual submissions. This performance hit is accepted for the sake of being able to support these devices without
|
||||
// limiting the design of the renderer.
|
||||
//
|
||||
// This bug was fixed in driver version 512.503.0, so we only enabled it on devices older than this.
|
||||
//
|
||||
driver_workarounds.avoid_compute_after_draw =
|
||||
p_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM &&
|
||||
p_device_properties.deviceID >= 0x6000000 && // Adreno 6xx
|
||||
p_device_properties.driverVersion < VK_MAKE_VERSION(512, 503, 0) &&
|
||||
strstr(p_device_properties.deviceName, "Turnip") == nullptr;
|
||||
|
||||
// Workaround a driver bug on Adreno 730 GPUs that keeps leaking memory on each call to vkResetDescriptorPool.
|
||||
// Which eventually run out of memory. In such case we should not be using linear allocated pools
|
||||
// Bug introduced in driver 512.597.0 and fixed in 512.671.0.
|
||||
// Confirmed by Qualcomm.
|
||||
if (linear_descriptor_pools_enabled) {
|
||||
const uint32_t reset_descriptor_pool_broken_driver_begin = VK_MAKE_VERSION(512u, 597u, 0u);
|
||||
const uint32_t reset_descriptor_pool_fixed_driver_begin = VK_MAKE_VERSION(512u, 671u, 0u);
|
||||
|
||||
linear_descriptor_pools_enabled =
|
||||
p_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM &&
|
||||
(p_device_properties.driverVersion < reset_descriptor_pool_broken_driver_begin || p_device_properties.driverVersion > reset_descriptor_pool_fixed_driver_begin);
|
||||
}
|
||||
|
||||
if (p_driver_properties != nullptr) {
|
||||
// Workaround for Adreno drivers where ubershaders with a lot of constant literals crash the compiler.
|
||||
driver_workarounds.disable_ubershaders =
|
||||
p_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM &&
|
||||
strstr(p_driver_properties->driverInfo, "Compiler Version: EV031.32.02.") != nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceDriverVulkan::_get_device_properties() {
|
||||
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
|
||||
|
||||
if (functions.GetPhysicalDeviceProperties2 != nullptr && enabled_device_extension_names.has(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
|
||||
VkPhysicalDeviceProperties2KHR device_props = {};
|
||||
device_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
|
||||
|
||||
VkPhysicalDeviceDriverPropertiesKHR driver_props = {};
|
||||
driver_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
|
||||
device_props.pNext = &driver_props;
|
||||
|
||||
functions.GetPhysicalDeviceProperties2(physical_device, &device_props);
|
||||
physical_device_properties = device_props.properties;
|
||||
|
||||
_check_driver_workarounds(physical_device_properties, &driver_props);
|
||||
|
||||
} else {
|
||||
vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
|
||||
|
||||
_check_driver_workarounds(physical_device_properties, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
Error RenderingDeviceDriverVulkan::_check_device_features() {
|
||||
vkGetPhysicalDeviceFeatures(physical_device, &physical_device_features);
|
||||
|
||||
@@ -1742,25 +1819,6 @@ void RenderingDeviceDriverVulkan::_set_object_name(VkObjectType p_object_type, u
|
||||
Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t p_frame_count) {
|
||||
context_device = context_driver->device_get(p_device_index);
|
||||
physical_device = context_driver->physical_device_get(p_device_index);
|
||||
vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
|
||||
|
||||
// Workaround a driver bug on Adreno 730 GPUs that keeps leaking memory on each call to vkResetDescriptorPool.
|
||||
// Which eventually run out of memory. In such case we should not be using linear allocated pools
|
||||
// Bug introduced in driver 512.597.0 and fixed in 512.671.0.
|
||||
// Confirmed by Qualcomm.
|
||||
if (linear_descriptor_pools_enabled) {
|
||||
const uint32_t reset_descriptor_pool_broken_driver_begin = VK_MAKE_VERSION(512u, 597u, 0u);
|
||||
const uint32_t reset_descriptor_pool_fixed_driver_begin = VK_MAKE_VERSION(512u, 671u, 0u);
|
||||
linear_descriptor_pools_enabled = physical_device_properties.driverVersion < reset_descriptor_pool_broken_driver_begin || physical_device_properties.driverVersion > reset_descriptor_pool_fixed_driver_begin;
|
||||
}
|
||||
|
||||
// Workaround a driver bug on Adreno 5XX GPUs that causes a crash when
|
||||
// there are empty descriptor set layouts placed between non-empty ones.
|
||||
adreno_5xx_empty_descriptor_set_layout_workaround =
|
||||
physical_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM &&
|
||||
physical_device_properties.deviceID >= 0x5000000 &&
|
||||
physical_device_properties.deviceID < 0x6000000;
|
||||
|
||||
frame_count = p_frame_count;
|
||||
|
||||
// Copy the queue family properties the context already retrieved.
|
||||
@@ -1773,6 +1831,8 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t
|
||||
Error err = _initialize_device_extensions();
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device extensions. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
_get_device_properties();
|
||||
|
||||
err = _check_device_features();
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device features. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
@@ -7388,6 +7448,10 @@ bool RenderingDeviceDriverVulkan::is_composite_alpha_supported(CommandQueueID p_
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderingDeviceDriver::DriverWorkarounds RenderingDeviceDriverVulkan::get_driver_workarounds() const {
|
||||
return driver_workarounds;
|
||||
}
|
||||
|
||||
/******************/
|
||||
|
||||
RenderingDeviceDriverVulkan::RenderingDeviceDriverVulkan(RenderingContextDriverVulkan *p_context_driver) {
|
||||
|
||||
Reference in New Issue
Block a user