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

View File

@ -25,4 +25,7 @@ bool nullGpu();
bool dumpShaders();
bool dumpPM4();
bool vkValidationEnabled();
bool vkValidationSyncEnabled();
}; // 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)
: window{window_}, instance{window, Config::getGpuId()}, scheduler{instance},
swapchain{instance, window}, texture_cache{instance, scheduler} {
: window{window_}, instance{window, Config::getGpuId(), Config::vkValidationEnabled()},
scheduler{instance}, swapchain{instance, window}, texture_cache{instance, scheduler} {
rasterizer = std::make_unique<Rasterizer>(instance, scheduler, texture_cache, liverpool);
const u32 num_images = swapchain.GetImageCount();
const vk::Device device = instance.GetDevice();

View File

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

View File

@ -18,7 +18,8 @@ namespace Vulkan {
class Instance {
public:
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();
/// Returns a formatted string for the driver version
@ -200,7 +201,7 @@ private:
vk::PhysicalDeviceProperties properties;
vk::PhysicalDeviceFeatures features;
vk::DriverIdKHR driver_id;
vk::UniqueDebugUtilsMessengerEXT debug_callback;
vk::UniqueDebugUtilsMessengerEXT debug_callback{};
std::string vendor_name;
VmaAllocator allocator{};
vk::Queue present_queue;

View File

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

View File

@ -15,12 +15,16 @@
#include <vector>
#include "common/assert.h"
#include "common/config.h"
#include "common/logging/log.h"
#include "sdl_window.h"
#include "video_core/renderer_vulkan/vk_platform.h"
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(
VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type,
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)));
}
const auto extensions = GetInstanceExtensions(window_type, enable_validation);
const auto extensions = GetInstanceExtensions(window_type, true);
const vk::ApplicationInfo application_info = {
.pApplicationName = "shadPS4",
@ -193,21 +197,37 @@ vk::UniqueInstance CreateInstance(vk::DynamicLoader& dl, Frontend::WindowSystemT
std::array<const char*, 2> layers;
if (enable_validation) {
layers[num_layers++] = "VK_LAYER_KHRONOS_validation";
layers[num_layers++] = VALIDATION_LAYER_NAME;
}
if (dump_command_buffers) {
layers[num_layers++] = "VK_LAYER_LUNARG_api_dump";
layers[num_layers++] = API_DUMP_LAYER_NAME;
}
vk::InstanceCreateInfo instance_ci = {
.pApplicationInfo = &application_info,
.enabledLayerCount = num_layers,
.ppEnabledLayerNames = layers.data(),
.enabledExtensionCount = static_cast<u32>(extensions.size()),
.ppEnabledExtensionNames = extensions.data(),
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,
};
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);

View File

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