mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-18 22:42:23 +00:00
graphics: add --gpu-assisted-validation and report fatal VkResults (#268)
Build and Release KytyPS5 / Prepare build metadata (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (Windows) (push) Blocked by required conditions
Build and Release KytyPS5 / Build KytyPS5 (macOS) (push) Blocked by required conditions
Build and Release KytyPS5 / Build KytyPS5 (Linux) (push) Blocked by required conditions
Build and Release KytyPS5 / Release KytyPS5 (push) Blocked by required conditions
Build and Release KytyPS5 / Prepare build metadata (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (Windows) (push) Blocked by required conditions
Build and Release KytyPS5 / Build KytyPS5 (macOS) (push) Blocked by required conditions
Build and Release KytyPS5 / Build KytyPS5 (Linux) (push) Blocked by required conditions
Build and Release KytyPS5 / Release KytyPS5 (push) Blocked by required conditions
* graphics: report the VkResult when a submit or fence wait fails * graphics: add a --gpu-assisted-validation flag * graphics: imply Vulkan validation for GPU-assisted validation --------- Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -93,6 +93,10 @@ bool SpirvDebugPrintfEnabled() {
|
||||
return g_config->spirv_debug_printf_enabled;
|
||||
}
|
||||
|
||||
bool GpuAssistedValidationEnabled() {
|
||||
return g_config->gpu_assisted_validation_enabled && g_config->vulkan_validation_enabled;
|
||||
}
|
||||
|
||||
bool RenderDocEnabled() {
|
||||
return g_config->renderdoc_enabled;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ struct ConfigOptions {
|
||||
std::filesystem::path printf_output_file = "_kyty.txt";
|
||||
ProfilerDirection profiler_direction = ProfilerDirection::None;
|
||||
bool spirv_debug_printf_enabled = false;
|
||||
bool gpu_assisted_validation_enabled = false;
|
||||
bool renderdoc_enabled = false;
|
||||
bool readback_linear_images = false;
|
||||
bool playgo_hack_enabled = false;
|
||||
@@ -84,6 +85,8 @@ ProfilerDirection GetProfilerDirection();
|
||||
|
||||
bool SpirvDebugPrintfEnabled();
|
||||
|
||||
bool GpuAssistedValidationEnabled();
|
||||
|
||||
bool RenderDocEnabled();
|
||||
bool ReadbackLinearImagesEnabled();
|
||||
bool PlayGoHackEnabled();
|
||||
|
||||
@@ -17,10 +17,29 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
namespace Libs::Graphics {
|
||||
|
||||
namespace {
|
||||
|
||||
void ReportVulkanFatal(const char* what, vk::Result result, uint32_t slot, uint64_t submit_seq,
|
||||
uint32_t debug_op, uint64_t debug_submit, uint32_t arg0, uint32_t arg1,
|
||||
uint32_t arg2, uint32_t arg3, uint64_t arg4) {
|
||||
LOGF("%s failed: %s (%d), slot=%u submit_seq=%" PRIu64 " debug_op=%u debug_submit=%" PRIu64
|
||||
" args=%u,%u,%u,%u,0x%016" PRIx64 "\n",
|
||||
what, VulkanToString(result).c_str(), static_cast<int>(result), slot, submit_seq, debug_op,
|
||||
debug_submit, arg0, arg1, arg2, arg3, arg4);
|
||||
std::printf("%s failed: %s (%d), slot=%u submit_seq=%" PRIu64 " debug_op=%u debug_submit=%" PRIu64
|
||||
" args=%u,%u,%u,%u,0x%016" PRIx64 "\n",
|
||||
what, VulkanToString(result).c_str(), static_cast<int>(result), slot, submit_seq,
|
||||
debug_op, debug_submit, arg0, arg1, arg2, arg3, arg4);
|
||||
std::fflush(stdout);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FenceResourceRetainer::~FenceResourceRetainer() {
|
||||
if (!m_resources.empty()) {
|
||||
EXIT("fence resource retainer destroyed before release\n");
|
||||
@@ -169,8 +188,9 @@ void CommandBuffer::Execute(const SubmitInfo& submit) {
|
||||
|
||||
auto result = graphics.device.resetFences(1, &fence);
|
||||
if (result != vk::Result::eSuccess) {
|
||||
LOGF("vkResetFences failed before submit: %s (%d)\n", VulkanToString(result).c_str(),
|
||||
static_cast<int>(result));
|
||||
ReportVulkanFatal("vkResetFences (before submit)", result, m_slot->id, m_submit_seq,
|
||||
m_debug_op, m_debug_submit_id, m_debug_arg0, m_debug_arg1, m_debug_arg2,
|
||||
m_debug_arg3, m_debug_arg4);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(result != vk::Result::eSuccess);
|
||||
|
||||
@@ -192,11 +212,9 @@ void CommandBuffer::Execute(const SubmitInfo& submit) {
|
||||
m_fence_waited = false;
|
||||
|
||||
if (result != vk::Result::eSuccess) {
|
||||
LOGF("vkQueueSubmit failed: %s (%d), slot=%u submit_seq=%" PRIu64
|
||||
" debug_op=%u debug_submit=%" PRIu64 " args=%u,%u,%u,%u,0x%016" PRIx64 "\n",
|
||||
VulkanToString(result).c_str(), static_cast<int>(result), m_slot->id, m_submit_seq,
|
||||
m_debug_op, m_debug_submit_id, m_debug_arg0, m_debug_arg1, m_debug_arg2, m_debug_arg3,
|
||||
m_debug_arg4);
|
||||
ReportVulkanFatal("vkQueueSubmit", result, m_slot->id, m_submit_seq, m_debug_op,
|
||||
m_debug_submit_id, m_debug_arg0, m_debug_arg1, m_debug_arg2, m_debug_arg3,
|
||||
m_debug_arg4);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(result != vk::Result::eSuccess);
|
||||
}
|
||||
@@ -213,11 +231,9 @@ void CommandBuffer::WaitForFenceOnly() {
|
||||
auto device = m_graphics.device;
|
||||
auto result = device.waitForFences(1, &m_slot->fence, VK_TRUE, UINT64_MAX);
|
||||
if (result != vk::Result::eSuccess) {
|
||||
LOGF("vkWaitForFences failed: %s (%d), slot=%u submit_seq=%" PRIu64
|
||||
" debug_op=%u debug_submit=%" PRIu64 " args=%u,%u,%u,%u,0x%016" PRIx64 "\n",
|
||||
VulkanToString(result).c_str(), static_cast<int>(result), m_slot->id, m_submit_seq,
|
||||
m_debug_op, m_debug_submit_id, m_debug_arg0, m_debug_arg1, m_debug_arg2, m_debug_arg3,
|
||||
m_debug_arg4);
|
||||
ReportVulkanFatal("vkWaitForFences", result, m_slot->id, m_submit_seq, m_debug_op,
|
||||
m_debug_submit_id, m_debug_arg0, m_debug_arg1, m_debug_arg2, m_debug_arg3,
|
||||
m_debug_arg4);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(result != vk::Result::eSuccess);
|
||||
m_fence_waited = true;
|
||||
|
||||
@@ -554,6 +554,14 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
|
||||
EXIT_NOT_IMPLEMENTED(supported_features2.features.depthBiasClamp != VK_TRUE);
|
||||
features12.timelineSemaphore = VK_TRUE;
|
||||
|
||||
if (Config::GpuAssistedValidationEnabled()) {
|
||||
if (supported_features12.bufferDeviceAddress != VK_TRUE) {
|
||||
EXIT("--gpu-assisted-validation requires bufferDeviceAddress, unsupported by this "
|
||||
"device\n");
|
||||
}
|
||||
features12.bufferDeviceAddress = VK_TRUE;
|
||||
}
|
||||
|
||||
vk::PhysicalDeviceFeatures device_features {};
|
||||
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
device_features.samplerAnisotropy = VK_TRUE;
|
||||
@@ -571,6 +579,9 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
|
||||
graphics.sample_rate_shading_enabled = true;
|
||||
device_features.vertexPipelineStoresAndAtomics =
|
||||
supported_features2.features.vertexPipelineStoresAndAtomics;
|
||||
if (Config::GpuAssistedValidationEnabled()) {
|
||||
device_features.shaderInt64 = supported_features2.features.shaderInt64;
|
||||
}
|
||||
|
||||
if (graphics.subgroup_size_control_enabled &&
|
||||
supported_features13.subgroupSizeControl == VK_TRUE) {
|
||||
@@ -833,23 +844,26 @@ void WindowContext::CreateVulkan() {
|
||||
app_info.engineVersion = 1;
|
||||
app_info.apiVersion = VULKAN_TARGET_API_VERSION; // NOLINT
|
||||
|
||||
vk::ValidationFeatureEnableEXT enabled_features[] = {
|
||||
if (Config::SpirvDebugPrintfEnabled() && Config::GpuAssistedValidationEnabled()) {
|
||||
EXIT("--spirv-debug-printf and --gpu-assisted-validation are mutually exclusive\n");
|
||||
}
|
||||
|
||||
vk::ValidationFeatureEnableEXT enabled_features[3] = {};
|
||||
uint32_t enabled_features_count = 0;
|
||||
#ifdef KYTY_ENABLE_BEST_PRACTICES
|
||||
vk::ValidationFeatureEnableEXT::eBestPractices,
|
||||
enabled_features[enabled_features_count++] = vk::ValidationFeatureEnableEXT::eBestPractices;
|
||||
#endif
|
||||
#ifdef KYTY_ENABLE_DEBUG_PRINTF
|
||||
vk::ValidationFeatureEnableEXT::eDebugPrintf,
|
||||
#endif
|
||||
};
|
||||
|
||||
uint32_t enabled_features_count =
|
||||
sizeof(enabled_features) / sizeof(vk::ValidationFeatureEnableEXT);
|
||||
|
||||
#ifdef KYTY_ENABLE_DEBUG_PRINTF
|
||||
if (!Config::SpirvDebugPrintfEnabled()) {
|
||||
enabled_features_count--;
|
||||
if (Config::SpirvDebugPrintfEnabled()) {
|
||||
enabled_features[enabled_features_count++] = vk::ValidationFeatureEnableEXT::eDebugPrintf;
|
||||
}
|
||||
#endif
|
||||
if (Config::GpuAssistedValidationEnabled()) {
|
||||
enabled_features[enabled_features_count++] = vk::ValidationFeatureEnableEXT::eGpuAssisted;
|
||||
LOGF("Vulkan GPU-assisted validation is enabled; expect a large slowdown\n");
|
||||
std::printf("Vulkan GPU-assisted validation is enabled; expect a large slowdown\n");
|
||||
std::fflush(stdout);
|
||||
}
|
||||
|
||||
vk::ValidationFeaturesEXT validation_features {};
|
||||
validation_features.sType = vk::StructureType::eValidationFeaturesEXT;
|
||||
|
||||
@@ -51,6 +51,8 @@ static void PrintUsage() {
|
||||
::printf(" --vblank-frequency <num> Virtual vblank frequency. Default: 60.\n");
|
||||
::printf(" --console-language <0-29> Console language. Default: 1 (English US).\n");
|
||||
::printf(" --vulkan-validation <true|false> Enable Vulkan validation.\n");
|
||||
::printf(" --gpu-assisted-validation <t|f> Bounds-check shader accesses on the GPU.\n"
|
||||
" Implies --vulkan-validation; very slow.\n");
|
||||
::printf(" --shader-validation <true|false> Enable shader validation.\n");
|
||||
::printf(" --shader-optimization-type <value> None, Size, or Performance.\n");
|
||||
::printf(" --shader-log-direction <value> Silent, Console, or File.\n");
|
||||
@@ -213,6 +215,11 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
|
||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
||||
return false;
|
||||
}
|
||||
} else if (arg == "--gpu-assisted-validation") {
|
||||
if (!ParseBool(value, options.config.gpu_assisted_validation_enabled)) {
|
||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
||||
return false;
|
||||
}
|
||||
} else if (arg == "--shader-validation") {
|
||||
if (!ParseBool(value, options.config.shader_validation_enabled)) {
|
||||
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
|
||||
@@ -277,6 +284,10 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
|
||||
}
|
||||
}
|
||||
|
||||
if (options.config.gpu_assisted_validation_enabled) {
|
||||
options.config.vulkan_validation_enabled = true;
|
||||
}
|
||||
|
||||
return show_help || (!options.app0_dir.empty() && !options.elf.empty());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user