renderer_vulkan, config: option to toggle VK validation layer

This commit is contained in:
psucien 2024-06-07 09:12:43 +02:00
parent dd5a25fda2
commit fe3b546d93
8 changed files with 67 additions and 29 deletions

View File

@ -21,6 +21,8 @@ static bool isShowSplash = false;
static bool isNullGpu = false; static bool isNullGpu = false;
static bool shouldDumpShaders = false; static bool shouldDumpShaders = false;
static bool shouldDumpPM4 = false; static bool shouldDumpPM4 = false;
static bool vkValidation = false;
static bool vkValidationSync = false;
bool isLleLibc() { bool isLleLibc() {
return isLibc; return isLibc;
@ -69,6 +71,14 @@ bool dumpPM4() {
return shouldDumpPM4; return shouldDumpPM4;
} }
bool vkValidationEnabled() {
return vkValidation;
}
bool vkValidationSyncEnabled() {
return vkValidationSync;
}
void load(const std::filesystem::path& path) { void load(const std::filesystem::path& path) {
// If the configuration file does not exist, create it and return // If the configuration file does not exist, create it and return
std::error_code error; std::error_code error;
@ -110,6 +120,15 @@ void load(const std::filesystem::path& path) {
shouldDumpPM4 = toml::find_or<toml::boolean>(gpu, "dumpPM4", false); shouldDumpPM4 = toml::find_or<toml::boolean>(gpu, "dumpPM4", false);
} }
} }
if (data.contains("Vulkan")) {
const auto vkResult = toml::expect<toml::value>(data.at("Vulkan"));
if (vkResult.is_ok()) {
auto vk = vkResult.unwrap();
vkValidation = toml::find_or<toml::boolean>(vk, "validation", true);
vkValidationSync = toml::find_or<toml::boolean>(vk, "validation_sync", true);
}
}
if (data.contains("Debug")) { if (data.contains("Debug")) {
auto debugResult = toml::expect<toml::value>(data.at("Debug")); auto debugResult = toml::expect<toml::value>(data.at("Debug"));
if (debugResult.is_ok()) { if (debugResult.is_ok()) {
@ -156,6 +175,8 @@ void save(const std::filesystem::path& path) {
data["GPU"]["nullGpu"] = isNullGpu; data["GPU"]["nullGpu"] = isNullGpu;
data["GPU"]["dumpShaders"] = shouldDumpShaders; data["GPU"]["dumpShaders"] = shouldDumpShaders;
data["GPU"]["dumpPM4"] = shouldDumpPM4; data["GPU"]["dumpPM4"] = shouldDumpPM4;
data["Vulkan"]["validation"] = vkValidation;
data["Vulkan"]["validation_sync"] = vkValidationSync;
data["Debug"]["DebugDump"] = isDebugDump; data["Debug"]["DebugDump"] = isDebugDump;
data["LLE"]["libc"] = isLibc; data["LLE"]["libc"] = isLibc;

View File

@ -25,4 +25,7 @@ bool nullGpu();
bool dumpShaders(); bool dumpShaders();
bool dumpPM4(); bool dumpPM4();
bool vkValidationEnabled();
bool vkValidationSyncEnabled();
}; // namespace Config }; // namespace Config

View File

@ -62,8 +62,8 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice physical_device, vk::Format for
} }
RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool) RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool)
: window{window_}, instance{window, Config::getGpuId()}, scheduler{instance}, : window{window_}, instance{window, Config::getGpuId(), Config::vkValidationEnabled()},
swapchain{instance, window}, texture_cache{instance, scheduler} { scheduler{instance}, swapchain{instance, window}, texture_cache{instance, scheduler} {
rasterizer = std::make_unique<Rasterizer>(instance, scheduler, texture_cache, liverpool); rasterizer = std::make_unique<Rasterizer>(instance, scheduler, texture_cache, liverpool);
const u32 num_images = swapchain.GetImageCount(); const u32 num_images = swapchain.GetImageCount();
const vk::Device device = instance.GetDevice(); const vk::Device device = instance.GetDevice();

View File

@ -40,10 +40,13 @@ Instance::Instance(bool enable_validation, bool dump_command_buffers)
dump_command_buffers)}, dump_command_buffers)},
physical_devices{instance->enumeratePhysicalDevices()} {} physical_devices{instance->enumeratePhysicalDevices()} {}
Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index) Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index,
: instance{CreateInstance(dl, window.getWindowInfo().type, true, false)}, bool enable_validation /*= false*/)
debug_callback{CreateDebugCallback(*instance)}, : instance{CreateInstance(dl, window.getWindowInfo().type, enable_validation, false)},
physical_devices{instance->enumeratePhysicalDevices()} { physical_devices{instance->enumeratePhysicalDevices()} {
if (enable_validation) {
debug_callback = CreateDebugCallback(*instance);
}
const std::size_t num_physical_devices = static_cast<u16>(physical_devices.size()); const std::size_t num_physical_devices = static_cast<u16>(physical_devices.size());
ASSERT_MSG(num_physical_devices > 0, "No physical devices found"); ASSERT_MSG(num_physical_devices > 0, "No physical devices found");

View File

@ -18,7 +18,8 @@ namespace Vulkan {
class Instance { class Instance {
public: public:
explicit Instance(bool validation = false, bool dump_command_buffers = false); explicit Instance(bool validation = false, bool dump_command_buffers = false);
explicit Instance(Frontend::WindowSDL& window, s32 physical_device_index); explicit Instance(Frontend::WindowSDL& window, s32 physical_device_index,
bool enable_validation = false);
~Instance(); ~Instance();
/// Returns a formatted string for the driver version /// Returns a formatted string for the driver version
@ -200,7 +201,7 @@ private:
vk::PhysicalDeviceProperties properties; vk::PhysicalDeviceProperties properties;
vk::PhysicalDeviceFeatures features; vk::PhysicalDeviceFeatures features;
vk::DriverIdKHR driver_id; vk::DriverIdKHR driver_id;
vk::UniqueDebugUtilsMessengerEXT debug_callback; vk::UniqueDebugUtilsMessengerEXT debug_callback{};
std::string vendor_name; std::string vendor_name;
VmaAllocator allocator{}; VmaAllocator allocator{};
vk::Queue present_queue; vk::Queue present_queue;

View File

@ -170,12 +170,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
// Set module name to hash in renderdoc // Set module name to hash in renderdoc
const auto name = fmt::format("{}_{:#x}", stage, hash); const auto name = fmt::format("{}_{:#x}", stage, hash);
const vk::DebugUtilsObjectNameInfoEXT name_info = { Vulkan::SetObjectName(instance.GetDevice(), stages[i], name);
.objectType = vk::ObjectType::eShaderModule,
.objectHandle = std::bit_cast<u64>(stages[i]),
.pObjectName = name.c_str(),
};
instance.GetDevice().setDebugUtilsObjectNameEXT(name_info);
if (Config::dumpShaders()) { if (Config::dumpShaders()) {
DumpShader(spv_code, hash, stage, "spv"); DumpShader(spv_code, hash, stage, "spv");

View File

@ -15,12 +15,16 @@
#include <vector> #include <vector>
#include "common/assert.h" #include "common/assert.h"
#include "common/config.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "sdl_window.h" #include "sdl_window.h"
#include "video_core/renderer_vulkan/vk_platform.h" #include "video_core/renderer_vulkan/vk_platform.h"
namespace Vulkan { namespace Vulkan {
static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
static const char* const API_DUMP_LAYER_NAME = "VK_LAYER_LUNARG_api_dump";
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type, VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) { const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
@ -179,7 +183,7 @@ vk::UniqueInstance CreateInstance(vk::DynamicLoader& dl, Frontend::WindowSystemT
VK_VERSION_MAJOR(available_version), VK_VERSION_MINOR(available_version))); VK_VERSION_MAJOR(available_version), VK_VERSION_MINOR(available_version)));
} }
const auto extensions = GetInstanceExtensions(window_type, enable_validation); const auto extensions = GetInstanceExtensions(window_type, true);
const vk::ApplicationInfo application_info = { const vk::ApplicationInfo application_info = {
.pApplicationName = "shadPS4", .pApplicationName = "shadPS4",
@ -193,21 +197,37 @@ vk::UniqueInstance CreateInstance(vk::DynamicLoader& dl, Frontend::WindowSystemT
std::array<const char*, 2> layers; std::array<const char*, 2> layers;
if (enable_validation) { if (enable_validation) {
layers[num_layers++] = "VK_LAYER_KHRONOS_validation"; layers[num_layers++] = VALIDATION_LAYER_NAME;
} }
if (dump_command_buffers) { if (dump_command_buffers) {
layers[num_layers++] = "VK_LAYER_LUNARG_api_dump"; layers[num_layers++] = API_DUMP_LAYER_NAME;
} }
vk::InstanceCreateInfo instance_ci = { vk::Bool32 enable_sync =
.pApplicationInfo = &application_info, enable_validation && Config::vkValidationSyncEnabled() ? vk::True : vk::False;
.enabledLayerCount = num_layers, vk::LayerSettingEXT layer_set = {
.ppEnabledLayerNames = layers.data(), .pLayerName = VALIDATION_LAYER_NAME,
.enabledExtensionCount = static_cast<u32>(extensions.size()), .pSettingName = "validate_sync",
.ppEnabledExtensionNames = extensions.data(), .type = vk::LayerSettingTypeEXT::eBool32,
.valueCount = 1,
.pValues = &enable_sync,
}; };
auto instance = vk::createInstanceUnique(instance_ci); vk::StructureChain<vk::InstanceCreateInfo, vk::LayerSettingsCreateInfoEXT> instance_ci_chain = {
vk::InstanceCreateInfo{
.pApplicationInfo = &application_info,
.enabledLayerCount = num_layers,
.ppEnabledLayerNames = layers.data(),
.enabledExtensionCount = static_cast<u32>(extensions.size()),
.ppEnabledExtensionNames = extensions.data(),
},
vk::LayerSettingsCreateInfoEXT{
.settingCount = 1,
.pSettings = &layer_set,
},
};
auto instance = vk::createInstanceUnique(instance_ci_chain.get());
VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance); VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance);

View File

@ -222,12 +222,7 @@ TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& sc
// Set module debug name // Set module debug name
auto module_name = magic_enum::enum_name(static_cast<DetilerType>(pl_id)); auto module_name = magic_enum::enum_name(static_cast<DetilerType>(pl_id));
const vk::DebugUtilsObjectNameInfoEXT name_info = { Vulkan::SetObjectName(instance.GetDevice(), module, module_name);
.objectType = vk::ObjectType::eShaderModule,
.objectHandle = std::bit_cast<u64>(module),
.pObjectName = module_name.data(),
};
instance.GetDevice().setDebugUtilsObjectNameEXT(name_info);
const vk::PipelineShaderStageCreateInfo shader_ci = { const vk::PipelineShaderStageCreateInfo shader_ci = {
.stage = vk::ShaderStageFlagBits::eCompute, .stage = vk::ShaderStageFlagBits::eCompute,