r.Vulkan.EnableValidation
r.Vulkan.EnableValidation
#Overview
name: r.Vulkan.EnableValidation
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
0 to disable validation layers\n1 to enable errors\n2 to enable errors & warnings\n3 to enable errors, warnings & performance warnings\n4 to enable errors, warnings, performance & information messages\n5 to enable all messages
It is referenced in 11
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.Vulkan.EnableValidation is to control the level of Vulkan validation layers enabled during runtime. It is primarily used for debugging and performance optimization in the Vulkan rendering system.
This setting variable is primarily used by the Vulkan RHI (Runtime Hardware Interface) subsystem of Unreal Engine. It’s particularly important for the debugging and validation components of the Vulkan implementation.
The value of this variable is set through a console variable (CVar) named GValidationCvar. It can be set programmatically, through the console, or via command-line arguments.
The variable interacts closely with several other debugging and validation-related variables, particularly GGPUValidationCvar for GPU validation.
Developers should be aware that:
- Higher validation levels can significantly impact performance and should generally be used only during development.
- The variable uses different integer values to enable different levels of validation, from 0 (disabled) to 5 (all messages).
- It affects the creation and behavior of the Vulkan debug messenger.
Best practices for using this variable include:
- Use it in development builds, but disable or minimize its use in release builds.
- Start with lower levels (1 or 2) and increase as needed for more detailed debugging.
- Be prepared to handle the performance impact when enabling higher levels of validation.
Regarding the associated variable GValidationCvar: The purpose of GValidationCvar is to provide a programmatic interface to control the r.Vulkan.EnableValidation setting. It’s used throughout the Vulkan RHI implementation to check the current validation level and adjust behavior accordingly.
GValidationCvar is used in various parts of the Vulkan RHI, including debug layer setup, instance creation, and error handling. It’s particularly important in the setup of the debug messenger and in determining which validation features to enable.
The value of GValidationCvar is typically set based on the r.Vulkan.EnableValidation CVar, but it can also be influenced by command-line arguments.
Developers should be aware that changes to GValidationCvar can have wide-ranging effects on the Vulkan RHI’s behavior, particularly in terms of error reporting and performance.
Best practices for GValidationCvar include using it consistently throughout the codebase when checking validation levels, and ensuring it’s properly synchronized across different threads when necessary.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanLayers.cpp:20
Scope: file
Source code excerpt:
#if VULKAN_HAS_DEBUGGING_ENABLED
TAutoConsoleVariable<int32> GValidationCvar(
TEXT("r.Vulkan.EnableValidation"),
VULKAN_VALIDATION_DEFAULT_VALUE,
TEXT("0 to disable validation layers\n")
TEXT("1 to enable errors\n")
TEXT("2 to enable errors & warnings\n")
TEXT("3 to enable errors, warnings & performance warnings\n")
TEXT("4 to enable errors, warnings, performance & information messages\n")
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Public/VulkanConfiguration.h:27
Scope: file
Source code excerpt:
#endif
// default value of r.Vulkan.EnableValidation
// 0 - disable validation layers
// 1 - enable errors
// 2 - enable errors & warnings
// 3 - enable errors, warnings & performance warnings
// 4 - enable errors, warnings, performance & information messages
// 5 - enable all messages
#Associated Variable and Callsites
This variable is associated with another variable named GValidationCvar
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanDebug.cpp:31
Scope: file
Source code excerpt:
#endif // PLATFORM_ANDROID
extern TAutoConsoleVariable<int32> GValidationCvar;
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT MsgSeverity,
VkDebugUtilsMessageTypeFlagsEXT MsgType, const VkDebugUtilsMessengerCallbackDataEXT* CallbackData, void* UserData)
{
const bool bError = (MsgSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0;
const bool bWarning = (MsgSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0;
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanDebug.cpp:186
Scope (from outer to inner):
file
function void FVulkanDynamicRHI::SetupDebugLayerCallback
Source code excerpt:
ZeroVulkanStruct(CreateInfo, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT);
const int32 CVar = GValidationCvar.GetValueOnRenderThread();
CreateInfo.messageSeverity = (CVar >= 1 ? VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT : 0) |
(CVar >= 2 ? VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT : 0) | (CVar >= 3 ? VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT : 0);
CreateInfo.messageType = (CVar >= 1 ? (VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) : 0) |
(CVar >= 3 ? VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT : 0);
CreateInfo.pfnUserCallback = DebugUtilsCallback;
VkResult Result = (*CreateDebugUtilsMessengerEXT)(Instance, &CreateInfo, nullptr, &Messenger);
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanExtensions.cpp:1472
Scope (from outer to inner):
file
class class FVulkanEXTValidationFeaturesExtension : public FVulkanInstanceExtension
function virtual void PreCreateInstance
Source code excerpt:
{
#if VULKAN_HAS_DEBUGGING_ENABLED
check(GValidationCvar.GetValueOnAnyThread() > 0);
auto GetValidationFeaturesEnabled = []()
{
TArray<VkValidationFeatureEnableEXT> Features;
const int32 GPUValidationValue = GGPUValidationCvar.GetValueOnAnyThread();
if (GPUValidationValue > 0)
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanLayers.cpp:19
Scope: file
Source code excerpt:
#if VULKAN_HAS_DEBUGGING_ENABLED
TAutoConsoleVariable<int32> GValidationCvar(
TEXT("r.Vulkan.EnableValidation"),
VULKAN_VALIDATION_DEFAULT_VALUE,
TEXT("0 to disable validation layers\n")
TEXT("1 to enable errors\n")
TEXT("2 to enable errors & warnings\n")
TEXT("3 to enable errors, warnings & performance warnings\n")
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanLayers.cpp:309
Scope (from outer to inner):
file
function void FVulkanDynamicRHI::SetupValidationRequests
Source code excerpt:
{
#if VULKAN_HAS_DEBUGGING_ENABLED
int32 VulkanValidationOption = GValidationCvar.GetValueOnAnyThread();
// Command line overrides Cvar
if (FParse::Param(FCommandLine::Get(), TEXT("vulkandebug")))
{
// Match D3D and GL
GValidationCvar->Set(2, ECVF_SetByCommandline);
}
else if (FParse::Value(FCommandLine::Get(), TEXT("vulkanvalidation="), VulkanValidationOption))
{
GValidationCvar->Set(VulkanValidationOption, ECVF_SetByCommandline);
}
if (FParse::Param(FCommandLine::Get(), TEXT("gpuvalidation")))
{
if (GValidationCvar->GetInt() < 2)
{
GValidationCvar->Set(2, ECVF_SetByCommandline);
}
GGPUValidationCvar->Set(2, ECVF_SetByCommandline);
}
GRHIGlobals.IsDebugLayerEnabled = (GValidationCvar.GetValueOnAnyThread() > 0);
#endif
}
// Get a list of debugging layers to activate
void FVulkanIntanceSetupHelper::AddDebugLayers(const TArray<FLayerWithExtensions>& LayerProperties, FVulkanInstanceExtensionArray& UEExtensions, TArray<const ANSICHAR*>& OutLayers)
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp:1067
Scope (from outer to inner):
file
function void FVulkanDynamicRHI::InitInstance
Source code excerpt:
#if VULKAN_SUPPORTS_VALIDATION_CACHE
#if VULKAN_HAS_DEBUGGING_ENABLED
if (GValidationCvar.GetValueOnAnyThread() > 0)
{
SaveValidationCacheCmd = IConsoleManager::Get().RegisterConsoleCommand(
TEXT("r.Vulkan.SaveValidationCache"),
TEXT("Save validation cache."),
FConsoleCommandDelegate::CreateStatic(SaveValidationCache),
ECVF_Default
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHIPrivate.h:600
Scope: file
Source code excerpt:
#if VULKAN_HAS_DEBUGGING_ENABLED
extern TAutoConsoleVariable<int32> GValidationCvar;
#endif
static inline VkAttachmentLoadOp RenderTargetLoadActionToVulkan(ERenderTargetLoadAction InLoadAction)
{
VkAttachmentLoadOp OutLoadAction = VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.cpp:713
Scope (from outer to inner):
file
function int32 FVulkanSwapChain::AcquireImageIndex
Source code excerpt:
if (Result == VK_ERROR_VALIDATION_FAILED_EXT)
{
extern TAutoConsoleVariable<int32> GValidationCvar;
if (GValidationCvar.GetValueOnRenderThread() == 0)
{
UE_LOG(LogVulkanRHI, Fatal, TEXT("vkAcquireNextImageKHR failed with Validation error. Try running with r.Vulkan.EnableValidation=1 to get information from the driver"));
}
}
else
#endif
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanUtil.cpp:1078
Scope (from outer to inner):
file
namespace VulkanRHI
function void VerifyVulkanResult
Source code excerpt:
if (Result == VK_ERROR_VALIDATION_FAILED_EXT)
{
if (GValidationCvar.GetValueOnRenderThread() == 0)
{
UE_LOG(LogVulkanRHI, Fatal, TEXT("Failed with Validation error. Try running with r.Vulkan.EnableValidation=1 or -vulkandebug to get information from the validation layers."));
}
}
#endif