mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12: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>
|
#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_device_fault 1
|
||||||
#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout"
|
#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault"
|
||||||
#define VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT static_cast<VkImageLayout>(1000339000)
|
#define VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT static_cast<VkStructureType>(1000341002)
|
||||||
#define VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT 0x00080000
|
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT static_cast<VkStructureType>(1000341000)
|
||||||
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT static_cast<VkStructureType>(1000339000)
|
|
||||||
|
|
||||||
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;
|
VkStructureType sType;
|
||||||
void* pNext;
|
void* pNext;
|
||||||
VkBool32 attachmentFeedbackLoopLayout;
|
VkBool32 deviceFault;
|
||||||
} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT;
|
VkBool32 deviceFaultVendorBinary;
|
||||||
|
} VkPhysicalDeviceFaultFeaturesEXT;
|
||||||
#endif
|
|
||||||
|
typedef struct VkDeviceFaultCountsEXT {
|
||||||
#ifndef VK_KHR_fragment_shader_barycentric
|
VkStructureType sType;
|
||||||
|
void* pNext;
|
||||||
#define VK_KHR_fragment_shader_barycentric 1
|
uint32_t addressInfoCount;
|
||||||
#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
|
uint32_t vendorInfoCount;
|
||||||
#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric"
|
VkDeviceSize vendorBinarySize;
|
||||||
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR static_cast<VkStructureType>(1000203000)
|
} VkDeviceFaultCountsEXT;
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR {
|
typedef struct VkDeviceFaultAddressInfoEXT {
|
||||||
VkStructureType sType;
|
VkDeviceFaultAddressTypeEXT addressType;
|
||||||
void* pNext;
|
VkDeviceAddress reportedAddress;
|
||||||
VkBool32 fragmentShaderBarycentric;
|
VkDeviceSize addressPrecision;
|
||||||
} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR;
|
} VkDeviceFaultAddressInfoEXT;
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR {
|
typedef struct VkDeviceFaultVendorInfoEXT {
|
||||||
VkStructureType sType;
|
char description[VK_MAX_DESCRIPTION_SIZE];
|
||||||
void* pNext;
|
uint64_t vendorFaultCode;
|
||||||
VkBool32 triStripVertexOrderIndependentOfProvokingVertex;
|
uint64_t vendorFaultData;
|
||||||
} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR;
|
} 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
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace vk
|
||||||
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR shader_barycentric_info{};
|
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR shader_barycentric_info{};
|
||||||
VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border_color_info{};
|
VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border_color_info{};
|
||||||
VkPhysicalDeviceBorderColorSwizzleFeaturesEXT border_color_swizzle_info{};
|
VkPhysicalDeviceBorderColorSwizzleFeaturesEXT border_color_swizzle_info{};
|
||||||
|
VkPhysicalDeviceFaultFeaturesEXT device_fault_info{};
|
||||||
|
|
||||||
if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
|
if (device_extensions.is_supported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
|
||||||
{
|
{
|
||||||
|
@ -78,6 +79,13 @@ namespace vk
|
||||||
features2.pNext = &border_color_swizzle_info;
|
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"));
|
auto _vkGetPhysicalDeviceFeatures2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(vkGetInstanceProcAddr(parent, "vkGetPhysicalDeviceFeatures2KHR"));
|
||||||
ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!"
|
ensure(_vkGetPhysicalDeviceFeatures2KHR); // "vkGetInstanceProcAddress failed to find entry point!"
|
||||||
_vkGetPhysicalDeviceFeatures2KHR(dev, &features2);
|
_vkGetPhysicalDeviceFeatures2KHR(dev, &features2);
|
||||||
|
@ -92,6 +100,7 @@ namespace vk
|
||||||
|
|
||||||
optional_features_support.barycentric_coords = !!shader_barycentric_info.fragmentShaderBarycentric;
|
optional_features_support.barycentric_coords = !!shader_barycentric_info.fragmentShaderBarycentric;
|
||||||
optional_features_support.framebuffer_loops = !!fbo_loops_info.attachmentFeedbackLoopLayout;
|
optional_features_support.framebuffer_loops = !!fbo_loops_info.attachmentFeedbackLoopLayout;
|
||||||
|
optional_features_support.extended_device_fault = !!device_fault_info.deviceFault;
|
||||||
|
|
||||||
features = features2.features;
|
features = features2.features;
|
||||||
|
|
||||||
|
@ -754,6 +763,11 @@ namespace vk
|
||||||
_vkCmdPipelineBarrier2KHR = reinterpret_cast<PFN_vkCmdPipelineBarrier2KHR>(vkGetDeviceProcAddr(dev, "vkCmdPipelineBarrier2KHR"));
|
_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);
|
memory_map = vk::get_memory_mapping(pdev);
|
||||||
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
|
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
|
||||||
m_pipeline_binding_table = vk::get_pipeline_binding_table(pdev);
|
m_pipeline_binding_table = vk::get_pipeline_binding_table(pdev);
|
||||||
|
|
|
@ -91,6 +91,7 @@ namespace vk
|
||||||
bool surface_capabilities_2 = false;
|
bool surface_capabilities_2 = false;
|
||||||
bool synchronization_2 = false;
|
bool synchronization_2 = false;
|
||||||
bool unrestricted_depth_range = false;
|
bool unrestricted_depth_range = false;
|
||||||
|
bool extended_device_fault = false;
|
||||||
} optional_features_support;
|
} optional_features_support;
|
||||||
|
|
||||||
friend class render_device;
|
friend class render_device;
|
||||||
|
@ -153,6 +154,7 @@ namespace vk
|
||||||
PFN_vkCmdSetEvent2KHR _vkCmdSetEvent2KHR = nullptr;
|
PFN_vkCmdSetEvent2KHR _vkCmdSetEvent2KHR = nullptr;
|
||||||
PFN_vkCmdWaitEvents2KHR _vkCmdWaitEvents2KHR = nullptr;
|
PFN_vkCmdWaitEvents2KHR _vkCmdWaitEvents2KHR = nullptr;
|
||||||
PFN_vkCmdPipelineBarrier2KHR _vkCmdPipelineBarrier2KHR = nullptr;
|
PFN_vkCmdPipelineBarrier2KHR _vkCmdPipelineBarrier2KHR = nullptr;
|
||||||
|
PFN_vkGetDeviceFaultInfoEXT _vkGetDeviceFaultInfoEXT = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
render_device() = default;
|
render_device() = default;
|
||||||
|
@ -187,6 +189,7 @@ namespace vk
|
||||||
bool get_framebuffer_loops_support() const { return pgpu->optional_features_support.framebuffer_loops; }
|
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_barycoords_support() const { return pgpu->optional_features_support.barycentric_coords; }
|
||||||
bool get_synchronization2_support() const { return pgpu->optional_features_support.synchronization_2; }
|
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; }
|
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; }
|
u32 get_descriptor_max_draw_calls() const { return pgpu->descriptor_max_draw_calls; }
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "device.h"
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "util/logs.hpp"
|
#include "util/logs.hpp"
|
||||||
|
|
||||||
|
@ -9,9 +10,84 @@ namespace vk
|
||||||
{
|
{
|
||||||
extern void print_debug_markers();
|
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
|
int severity = 0; // 0 - die, 1 - warn, 2 - nothing
|
||||||
|
|
||||||
switch (error_code)
|
switch (error_code)
|
||||||
|
@ -42,6 +118,7 @@ namespace vk
|
||||||
break;
|
break;
|
||||||
case VK_ERROR_DEVICE_LOST:
|
case VK_ERROR_DEVICE_LOST:
|
||||||
error_message = "Device lost (Driver crashed with unspecified error or stopped responding and recovered) (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;
|
break;
|
||||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||||
error_message = "Memory map failed (VK_ERROR_MEMORY_MAP_FAILED)";
|
error_message = "Memory map failed (VK_ERROR_MEMORY_MAP_FAILED)";
|
||||||
|
@ -100,6 +177,11 @@ namespace vk
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!extra_info.empty())
|
||||||
|
{
|
||||||
|
error_message = fmt::format("%s\n---------------- EXTRA INFORMATION --------------------\n%s", error_message, extra_info);
|
||||||
|
}
|
||||||
|
|
||||||
switch (severity)
|
switch (severity)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue