vk: Add support for extended device fault information

This commit is contained in:
kd-11 2022-12-24 17:13:11 +03:00 committed by kd-11
parent 623f5822b3
commit 6000e3a47d
4 changed files with 157 additions and 32 deletions

View file

@ -21,39 +21,65 @@
#include <util/types.hpp>
#ifndef VK_EXT_attachment_feedback_loop_layout
// Requires SDK ver 230 which is not supported by CI currently
#ifndef VK_EXT_device_fault
#define VK_EXT_attachment_feedback_loop_layout 1
#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout"
#define VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT static_cast<VkImageLayout>(1000339000)
#define VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT 0x00080000
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT static_cast<VkStructureType>(1000339000)
#define VK_EXT_device_fault 1
#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault"
#define VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT static_cast<VkStructureType>(1000341002)
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT static_cast<VkStructureType>(1000341000)
typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT {
typedef enum VkDeviceFaultAddressTypeEXT {
VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = 0,
VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = 1,
VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = 2,
VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = 3,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = 4,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = 5,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6,
} VkDeviceFaultAddressTypeEXT;
typedef struct VkPhysicalDeviceFaultFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 attachmentFeedbackLoopLayout;
} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT;
#endif
#ifndef VK_KHR_fragment_shader_barycentric
#define VK_KHR_fragment_shader_barycentric 1
#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric"
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR static_cast<VkStructureType>(1000203000)
typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 fragmentShaderBarycentric;
} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR;
typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR {
VkStructureType sType;
void* pNext;
VkBool32 triStripVertexOrderIndependentOfProvokingVertex;
} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR;
VkBool32 deviceFault;
VkBool32 deviceFaultVendorBinary;
} VkPhysicalDeviceFaultFeaturesEXT;
typedef struct VkDeviceFaultCountsEXT {
VkStructureType sType;
void* pNext;
uint32_t addressInfoCount;
uint32_t vendorInfoCount;
VkDeviceSize vendorBinarySize;
} VkDeviceFaultCountsEXT;
typedef struct VkDeviceFaultAddressInfoEXT {
VkDeviceFaultAddressTypeEXT addressType;
VkDeviceAddress reportedAddress;
VkDeviceSize addressPrecision;
} VkDeviceFaultAddressInfoEXT;
typedef struct VkDeviceFaultVendorInfoEXT {
char description[VK_MAX_DESCRIPTION_SIZE];
uint64_t vendorFaultCode;
uint64_t vendorFaultData;
} VkDeviceFaultVendorInfoEXT;
typedef struct VkDeviceFaultInfoEXT {
VkStructureType sType;
void* pNext;
char description[VK_MAX_DESCRIPTION_SIZE];
VkDeviceFaultAddressInfoEXT* pAddressInfos;
VkDeviceFaultVendorInfoEXT* pVendorInfos;
void* pVendorBinaryData;
} VkDeviceFaultInfoEXT;
VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultInfoEXT(
VkDevice device,
VkDeviceFaultCountsEXT* pFaultCounts,
VkDeviceFaultInfoEXT* pFaultInfo);
typedef VkResult (VKAPI_PTR* PFN_vkGetDeviceFaultInfoEXT)(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo);
#endif

View file

@ -35,6 +35,7 @@ namespace vk
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR shader_barycentric_info{};
VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border_color_info{};
VkPhysicalDeviceBorderColorSwizzleFeaturesEXT border_color_swizzle_info{};
VkPhysicalDeviceFaultFeaturesEXT device_fault_info{};
if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
{
@ -78,6 +79,13 @@ namespace vk
features2.pNext = &border_color_swizzle_info;
}
if (device_extensions.is_supported(VK_EXT_DEVICE_FAULT_EXTENSION_NAME))
{
device_fault_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
device_fault_info.pNext = features2.pNext;
features2.pNext = &device_fault_info;
}
auto _vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(parent, "vkGetPhysicalDeviceFeatures2KHR"));
ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!"
_vkGetPhysicalDeviceFeatures2KHR(dev, &features2);
@ -92,6 +100,7 @@ namespace vk
optional_features_support.barycentric_coords = !!shader_barycentric_info.fragmentShaderBarycentric;
optional_features_support.framebuffer_loops = !!fbo_loops_info.attachmentFeedbackLoopLayout;
optional_features_support.extended_device_fault = !!device_fault_info.deviceFault;
features = features2.features;
@ -754,6 +763,11 @@ namespace vk
_vkCmdPipelineBarrier2KHR = reinterpret_cast<PFN_vkCmdPipelineBarrier2KHR>(vkGetDeviceProcAddr(dev, "vkCmdPipelineBarrier2KHR"));
}
if (pgpu->optional_features_support.extended_device_fault)
{
_vkGetDeviceFaultInfoEXT = reinterpret_cast<PFN_vkGetDeviceFaultInfoEXT>(vkGetDeviceProcAddr(dev, "vkGetDeviceFaultInfoEXT"));
}
memory_map = vk::get_memory_mapping(pdev);
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
m_pipeline_binding_table = vk::get_pipeline_binding_table(pdev);

View file

@ -91,6 +91,7 @@ namespace vk
bool surface_capabilities_2 = false;
bool synchronization_2 = false;
bool unrestricted_depth_range = false;
bool extended_device_fault = false;
} optional_features_support;
friend class render_device;
@ -153,6 +154,7 @@ namespace vk
PFN_vkCmdSetEvent2KHR _vkCmdSetEvent2KHR = nullptr;
PFN_vkCmdWaitEvents2KHR _vkCmdWaitEvents2KHR = nullptr;
PFN_vkCmdPipelineBarrier2KHR _vkCmdPipelineBarrier2KHR = nullptr;
PFN_vkGetDeviceFaultInfoEXT _vkGetDeviceFaultInfoEXT = nullptr;
public:
render_device() = default;
@ -187,6 +189,7 @@ namespace vk
bool get_framebuffer_loops_support() const { return pgpu->optional_features_support.framebuffer_loops; }
bool get_barycoords_support() const { return pgpu->optional_features_support.barycentric_coords; }
bool get_synchronization2_support() const { return pgpu->optional_features_support.synchronization_2; }
bool get_extended_device_fault_support() const { return pgpu->optional_features_support.extended_device_fault; }
u64 get_descriptor_update_after_bind_support() const { return pgpu->descriptor_indexing_support.update_after_bind_mask; }
u32 get_descriptor_max_draw_calls() const { return pgpu->descriptor_max_draw_calls; }

View file

@ -1,3 +1,4 @@
#include "device.h"
#include "shared.h"
#include "util/logs.hpp"
@ -9,9 +10,84 @@ namespace vk
{
extern void print_debug_markers();
void die_with_error(VkResult error_code, std::string message, std::source_location src_loc)
std::string retrieve_device_fault_info()
{
std::string error_message;
if (!g_render_device || !g_render_device->get_extended_device_fault_support())
{
return {};
}
ensure(g_render_device->_vkGetDeviceFaultInfoEXT);
std::string fault_message = "Device Fault Information:";
VkDeviceFaultCountsEXT fault_counts{};
g_render_device->_vkGetDeviceFaultInfoEXT(*g_render_device, &fault_counts, NULL);
std::vector<VkDeviceFaultAddressInfoEXT> address_info(fault_counts.addressInfoCount, VkDeviceFaultAddressInfoEXT{});
std::vector<VkDeviceFaultVendorInfoEXT> vendor_info(fault_counts.vendorInfoCount, VkDeviceFaultVendorInfoEXT{});
VkDeviceFaultInfoEXT fault_info
{
.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT,
.pAddressInfos = address_info.data(),
.pVendorInfos = vendor_info.data()
};
fault_counts.vendorInfoCount = 0;
g_render_device->_vkGetDeviceFaultInfoEXT(*g_render_device, &fault_counts, &fault_info);
fault_message += fmt::format("Fault Summary:\n %s\n\n", fault_info.description);
if (!address_info.empty())
{
fault_message += fmt::format(" Address Fault Information:\n", fault_info.description);
for (const auto& fault : address_info)
{
std::string access_type = "unknown";
switch (fault.addressType)
{
case VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT:
access_type = "none"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT:
access_type = "read"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT:
access_type = "write"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT:
access_type = "execute"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT:
access_type = "instruction_pointer_unknown"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT:
access_type = "instruction_pointer_invalid"; break;
case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT:
access_type = "instruction_pointer_fault"; break;
default:
break;
}
fault_message += fmt::format(" - Fault at address 0x%llx caused by %s\n", fault.reportedAddress, access_type);
}
}
if (!vendor_info.empty())
{
fault_message += fmt::format(" Vendor Fault Information:\n", fault_info.description);
for (const auto& fault : vendor_info)
{
fault_message += fmt::format(" - [0x%llx, 0x%llx] %s\n", fault.vendorFaultCode, fault.vendorFaultData, fault.description);
}
}
return fault_message;
}
void die_with_error(VkResult error_code, std::string message,
const char* file,
const char* func,
u32 line,
u32 col)
{
std::string error_message, extra_info;
int severity = 0; // 0 - die, 1 - warn, 2 - nothing
switch (error_code)
@ -42,6 +118,7 @@ namespace vk
break;
case VK_ERROR_DEVICE_LOST:
error_message = "Device lost (Driver crashed with unspecified error or stopped responding and recovered) (VK_ERROR_DEVICE_LOST)";
extra_info = retrieve_device_fault_info();
break;
case VK_ERROR_MEMORY_MAP_FAILED:
error_message = "Memory map failed (VK_ERROR_MEMORY_MAP_FAILED)";
@ -100,6 +177,11 @@ namespace vk
break;
}
if (!extra_info.empty())
{
error_message = fmt::format("%s\n---------------- EXTRA INFORMATION --------------------\n%s", error_message, extra_info);
}
switch (severity)
{
default: