r.Vulkan.DynamicGlobalUBs
r.Vulkan.DynamicGlobalUBs
#Overview
name: r.Vulkan.DynamicGlobalUBs
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
2 to treat ALL uniform buffers as dynamic [default]\n1 to treat global/packed uniform buffers as dynamic\n0 to treat them as regular
It is referenced in 7
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.Vulkan.DynamicGlobalUBs is to control how uniform buffers are treated in the Vulkan rendering pipeline of Unreal Engine 5. It specifically determines whether uniform buffers should be handled as dynamic or regular buffers.
This setting variable is primarily used in the Vulkan RHI (Rendering Hardware Interface) subsystem of Unreal Engine 5. It affects how the engine manages uniform buffers when using the Vulkan graphics API.
The value of this variable is set through a console variable (CVar) system. It’s defined with default value 2, but can be changed at runtime or through configuration files.
The variable interacts closely with its associated variable GDynamicGlobalUBs, which is used throughout the code to actually implement the behavior defined by r.Vulkan.DynamicGlobalUBs.
Developers must be aware that this variable has three possible values:
- 2: Treat ALL uniform buffers as dynamic (default)
- 1: Treat only global/packed uniform buffers as dynamic
- 0: Treat all uniform buffers as regular
The best practices when using this variable include:
- Understanding the performance implications of dynamic vs. regular uniform buffers in your specific use case.
- Being aware that changing this setting might affect the behavior of Vulkan bindless rendering.
- Considering the hardware limits (maxDescriptorSetUniformBuffersDynamic) when using dynamic uniform buffers.
Regarding the associated variable GDynamicGlobalUBs:
The purpose of GDynamicGlobalUBs is to implement the behavior defined by r.Vulkan.DynamicGlobalUBs within the engine’s C++ code.
It’s used in various parts of the Vulkan RHI implementation, including descriptor set management, pipeline state handling, and shader compilation.
The value of GDynamicGlobalUBs is set based on the r.Vulkan.DynamicGlobalUBs console variable.
This variable directly interacts with various Vulkan-specific classes and functions to determine how uniform buffers should be handled.
Developers should be aware that:
- Changes to r.Vulkan.DynamicGlobalUBs will be reflected in GDynamicGlobalUBs.
- The variable is used in performance-critical paths, so changing it can have significant performance implications.
Best practices include:
- Using GDynamicGlobalUBs consistently throughout the Vulkan RHI code when dealing with uniform buffer handling.
- Being cautious about changing its value at runtime, as it can affect ongoing rendering operations.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanShaders.cpp:14
Scope: file
Source code excerpt:
TAutoConsoleVariable<int32> GDynamicGlobalUBs(
TEXT("r.Vulkan.DynamicGlobalUBs"),
2,
TEXT("2 to treat ALL uniform buffers as dynamic [default]\n")\
TEXT("1 to treat global/packed uniform buffers as dynamic\n")\
TEXT("0 to treat them as regular"),
ECVF_ReadOnly | ECVF_RenderThreadSafe
);
#Associated Variable and Callsites
This variable is associated with another variable named GDynamicGlobalUBs
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanDescriptorSets.cpp:259
Scope (from outer to inner):
file
function bool FVulkanBindlessDescriptorManager::VerifySupport
Source code excerpt:
if (bMeetsPropertiesRequirements)
{
extern TAutoConsoleVariable<int32> GDynamicGlobalUBs;
if (GDynamicGlobalUBs->GetInt() != 0)
{
UE_LOG(LogRHI, Warning, TEXT("Dynamic Uniform Buffers are enabled, but they will not be used with Vulkan bindless."));
}
extern int32 GVulkanEnableDefrag;
if (GVulkanEnableDefrag != 0) // :todo-jn: to be turned back on with new defragger
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanPipelineState.h:15
Scope: file
Source code excerpt:
class FVulkanComputePipeline;
extern TAutoConsoleVariable<int32> GDynamicGlobalUBs;
// Common Pipeline state
class FVulkanCommonPipelineDescriptorState : public VulkanRHI::FDeviceChild
{
public:
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanPipelineState.h:191
Scope (from outer to inner):
file
class class FVulkanComputePipelineDescriptorState : public FVulkanCommonPipelineDescriptorState
function bool UpdateDescriptorSets
Source code excerpt:
check(!bUseBindless);
const bool bUseDynamicGlobalUBs = (GDynamicGlobalUBs->GetInt() > 0);
if (bUseDynamicGlobalUBs)
{
return InternalUpdateDescriptorSets<true>(CmdListContext, CmdBuffer);
}
else
{
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanPipelineState.h:254
Scope (from outer to inner):
file
class class FVulkanGraphicsPipelineDescriptorState : public FVulkanCommonPipelineDescriptorState
function bool UpdateDescriptorSets
Source code excerpt:
check(!bUseBindless);
const bool bUseDynamicGlobalUBs = (GDynamicGlobalUBs->GetInt() > 0);
if (bUseDynamicGlobalUBs)
{
return InternalUpdateDescriptorSets<true>(CmdListContext, CmdBuffer);
}
else
{
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanShaders.cpp:13
Scope: file
Source code excerpt:
#include "RHICoreShader.h"
TAutoConsoleVariable<int32> GDynamicGlobalUBs(
TEXT("r.Vulkan.DynamicGlobalUBs"),
2,
TEXT("2 to treat ALL uniform buffers as dynamic [default]\n")\
TEXT("1 to treat global/packed uniform buffers as dynamic\n")\
TEXT("0 to treat them as regular"),
ECVF_ReadOnly | ECVF_RenderThreadSafe
#Loc: <Workspace>/Engine/Source/Runtime/VulkanRHI/Private/VulkanShaders.cpp:847
Scope (from outer to inner):
file
function void FVulkanDescriptorSetsLayoutInfo::FinalizeBindings
Source code excerpt:
Binding.descriptorCount = 1;
const bool bConvertAllUBsToDynamic = !Device.SupportsBindless() && (GDynamicGlobalUBs.GetValueOnAnyThread() > 1);
const bool bConvertPackedUBsToDynamic = !Device.SupportsBindless() && (bConvertAllUBsToDynamic || (GDynamicGlobalUBs.GetValueOnAnyThread() == 1));
const bool bConsolidateAllIntoOneSet = GDescriptorSetLayoutMode.GetValueOnAnyThread() == 2;
const uint32 MaxDescriptorSetUniformBuffersDynamic = Device.GetLimits().maxDescriptorSetUniformBuffersDynamic;
uint8 DescriptorStageToSetMapping[ShaderStage::NumStages];
FMemory::Memset(DescriptorStageToSetMapping, UINT8_MAX);