mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 13:28:01 +03:00
vk: Add support for extended device fault information
This commit is contained in:
parent
623f5822b3
commit
6000e3a47d
4 changed files with 157 additions and 32 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue