mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-08 03:33:14 +00:00
Video Core: debug tools (#412)
* video_core: better use of rdoc markers * renderer_vulkan: added gpu assisted validation * renderer_vulkan: make nv_checkpoints operational * video_core: unified Vulkan objects names
This commit is contained in:
parent
3e2d4d6b79
commit
ace39957ef
11 changed files with 161 additions and 29 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "sdl_window.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
@ -213,6 +214,13 @@ bool Instance::CreateDevice() {
|
|||
add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
|
||||
add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
||||
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
|
||||
const bool has_sync2 = add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
|
||||
|
||||
if (has_sync2) {
|
||||
has_nv_checkpoints = Config::isMarkersEnabled()
|
||||
? add_extension(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME)
|
||||
: false;
|
||||
}
|
||||
|
||||
const auto family_properties = physical_device.getQueueFamilyProperties();
|
||||
if (family_properties.empty()) {
|
||||
|
@ -308,6 +316,9 @@ bool Instance::CreateDevice() {
|
|||
vk::PhysicalDeviceRobustness2FeaturesEXT{
|
||||
.nullDescriptor = true,
|
||||
},
|
||||
vk::PhysicalDeviceSynchronization2Features{
|
||||
.synchronization2 = has_sync2,
|
||||
},
|
||||
};
|
||||
|
||||
if (!color_write_en) {
|
||||
|
|
|
@ -88,6 +88,10 @@ public:
|
|||
return profiler_context;
|
||||
}
|
||||
|
||||
bool HasNvCheckpoints() const {
|
||||
return has_nv_checkpoints;
|
||||
}
|
||||
|
||||
/// Returns true when a known debugging tool is attached.
|
||||
bool HasDebuggingToolAttached() const {
|
||||
return has_renderdoc || has_nsight_graphics;
|
||||
|
@ -259,6 +263,7 @@ private:
|
|||
bool debug_utils_supported{};
|
||||
bool has_nsight_graphics{};
|
||||
bool has_renderdoc{};
|
||||
bool has_nv_checkpoints{};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -221,12 +221,61 @@ vk::UniqueInstance CreateInstance(vk::DynamicLoader& dl, Frontend::WindowSystemT
|
|||
|
||||
vk::Bool32 enable_sync =
|
||||
enable_validation && Config::vkValidationSyncEnabled() ? vk::True : vk::False;
|
||||
vk::LayerSettingEXT layer_set = {
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "validate_sync",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_sync,
|
||||
vk::Bool32 enable_gpuav =
|
||||
enable_validation && Config::vkValidationSyncEnabled() ? vk::True : vk::False;
|
||||
const char* gpuav_mode = enable_validation && Config::vkValidationGpuEnabled()
|
||||
? "GPU_BASED_GPU_ASSISTED"
|
||||
: "GPU_BASED_NONE";
|
||||
const std::array layer_setings = {
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "validate_sync",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_sync,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "sync_queue_submit",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_sync,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "validate_gpu_based",
|
||||
.type = vk::LayerSettingTypeEXT::eString,
|
||||
.valueCount = 1,
|
||||
.pValues = &gpuav_mode,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "gpuav_reserve_binding_slot",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_gpuav,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "gpuav_descriptor_checks",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_gpuav,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "gpuav_validate_indirect_buffer",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_gpuav,
|
||||
},
|
||||
vk::LayerSettingEXT{
|
||||
.pLayerName = VALIDATION_LAYER_NAME,
|
||||
.pSettingName = "gpuav_buffer_copies",
|
||||
.type = vk::LayerSettingTypeEXT::eBool32,
|
||||
.valueCount = 1,
|
||||
.pValues = &enable_gpuav,
|
||||
},
|
||||
};
|
||||
|
||||
vk::StructureChain<vk::InstanceCreateInfo, vk::LayerSettingsCreateInfoEXT> instance_ci_chain = {
|
||||
|
@ -238,8 +287,8 @@ vk::UniqueInstance CreateInstance(vk::DynamicLoader& dl, Frontend::WindowSystemT
|
|||
.ppEnabledExtensionNames = extensions.data(),
|
||||
},
|
||||
vk::LayerSettingsCreateInfoEXT{
|
||||
.settingCount = 1,
|
||||
.pSettings = &layer_set,
|
||||
.settingCount = layer_setings.size(),
|
||||
.pSettings = layer_setings.data(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -230,16 +230,42 @@ void Rasterizer::UpdateDepthStencilState() {
|
|||
cmdbuf.setDepthBoundsTestEnable(depth.depth_bounds_enable);
|
||||
}
|
||||
|
||||
void Rasterizer::ScopeMarkerBegin(const std::string& str) {
|
||||
void Rasterizer::ScopeMarkerBegin(const std::string_view& str) {
|
||||
if (!Config::isMarkersEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
|
||||
.pLabelName = str.c_str(),
|
||||
.pLabelName = str.data(),
|
||||
});
|
||||
}
|
||||
|
||||
void Rasterizer::ScopeMarkerEnd() {
|
||||
if (!Config::isMarkersEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.endDebugUtilsLabelEXT();
|
||||
}
|
||||
|
||||
void Rasterizer::ScopedMarkerInsert(const std::string_view& str) {
|
||||
if (!Config::isMarkersEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
|
||||
.pLabelName = str.data(),
|
||||
});
|
||||
}
|
||||
|
||||
void Rasterizer::Breadcrumb(u64 id) {
|
||||
if (!instance.HasNvCheckpoints()) {
|
||||
return;
|
||||
}
|
||||
scheduler.CommandBuffer().setCheckpointNV(id);
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -35,8 +35,10 @@ public:
|
|||
|
||||
void DispatchDirect();
|
||||
|
||||
void ScopeMarkerBegin(const std::string& str);
|
||||
void ScopeMarkerBegin(const std::string_view& str);
|
||||
void ScopeMarkerEnd();
|
||||
void ScopedMarkerInsert(const std::string_view& str);
|
||||
void Breadcrumb(u64 id);
|
||||
|
||||
void InvalidateMemory(VAddr addr, u64 size);
|
||||
void MapMemory(VAddr addr, u64 size);
|
||||
|
|
|
@ -158,6 +158,13 @@ void Scheduler::SubmitExecution(SubmitInfo& info) {
|
|||
try {
|
||||
instance.GetGraphicsQueue().submit(submit_info, info.fence);
|
||||
} catch (vk::DeviceLostError& err) {
|
||||
if (instance.HasNvCheckpoints()) {
|
||||
const auto checkpoint_data = instance.GetGraphicsQueue().getCheckpointData2NV();
|
||||
for (const auto& cp : checkpoint_data) {
|
||||
LOG_CRITICAL(Render_Vulkan, "{}: {:#x}", vk::to_string(cp.stage),
|
||||
reinterpret_cast<u64>(cp.pCheckpointMarker));
|
||||
}
|
||||
}
|
||||
UNREACHABLE_MSG("Device lost during submit: {}", err.what());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue