UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
RHICommandList.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 RHICommandList.inl: RHI Command List inline definitions.
5=============================================================================*/
6
7#pragma once
8
12class FRHIResource;
14struct FRHICommandBase;
15
17{
19}
20
22{
23 checkf(IsImmediate(), TEXT("This operation expects the immediate command list."));
24 return static_cast<FRHICommandListImmediate&>(*this);
25}
26
27inline bool FRHICommandListBase::Bypass() const
28{
29#if CAN_TOGGLE_COMMAND_LIST_BYPASS
31#else
32 return false;
33#endif
34}
35
37 : Immed(nullptr)
38{
40 {
42 if (InImmed.StallRHIThread())
43 {
44 Immed = &InImmed;
45 }
46 }
47}
48
50{
51 if (Immed)
52 {
53 Immed->UnStallRHIThread();
54 }
55}
56
57namespace PipelineStateCache
58{
59 /* Evicts unused state entries based on r.pso.evictiontime time. Called in RHICommandList::BeginFrame */
60 extern RHI_API void FlushResources();
61}
62
64{
65 if (IsImmediate())
66 {
67 static_cast<FRHICommandListImmediate&>(*this).SubmitCommandsHint();
68 }
69}
70
71// Helper class for traversing a FRHICommandList
73{
74public:
76 {
77 CmdPtr = CmdList.Root;
78#if DO_CHECK
79 NumCommands = 0;
81#endif
82 }
84 {
85#if DO_CHECK
86 checkf(CmdListNumCommands == NumCommands, TEXT("Missed %d Commands!"), CmdListNumCommands - NumCommands);
87#endif
88 }
89
90 inline bool HasCommandsLeft() const
91 {
92 return !!CmdPtr;
93 }
94
96 {
97 FRHICommandBase* RHICmd = CmdPtr;
98 CmdPtr = RHICmd->Next;
99#if DO_CHECK
100 NumCommands++;
101#endif
102 return RHICmd;
103 }
104
105private:
106 FRHICommandBase* CmdPtr;
107
108#if DO_CHECK
109 uint32 NumCommands;
111#endif
112};
113
115 : RHICmdList(RHICmdList)
116 , Previous(RHICmdList.PersistentState.CurrentFenceScope)
117{
118 RHICmdList.PersistentState.CurrentFenceScope = this;
119}
120
122{
123 if (bFenceRequested)
124 {
125 RHICmdList.PersistentState.CurrentFenceScope = nullptr;
126 RHICmdList.RHIThreadFence(true);
127 }
128
129 RHICmdList.PersistentState.CurrentFenceScope = Previous;
130}
131
133 : RHICmdList(RHICmdList)
134{
135 if (RHICmdList.GetPipeline() == ERHIPipeline::None)
136 {
138 bPipelineSet = true;
139 }
140}
141
143{
144 if (bPipelineSet)
145 {
147 }
148}
149
155
160
165
166#if WITH_RHI_BREADCRUMBS
167
168 namespace UE::RHI::Breadcrumbs::Private
169 {
170 inline FRHIComputeCommandList& GetRHICmdList(FRHIComputeCommandList& RHICmdList) { return RHICmdList; }
171 inline FRHIComputeCommandList& GetRHICmdList(IRHIComputeContext & RHIContext) { return static_cast<FRHIComputeCommandList&>(RHIContext.GetExecutingCommandList()); }
172
174 {
176 FRHIBreadcrumbNode* Node = RHICmdList.GetCurrentBreadcrumbRef();
177 return Node ? Node->GetFullPath() : TEXT("NoBreadcrumb");
178 }
179 }
180
181 template <typename TDesc, typename... TValues>
182 inline FRHIBreadcrumbNode* FRHIBreadcrumbAllocator::AllocBreadcrumb(TRHIBreadcrumbInitializer<TDesc, TValues...> const& Args)
183 {
184 TDesc const* Desc = std::get<0>(Args);
185 if (!Desc)
186 {
187 return nullptr;
188 }
189
190 return std::apply([&](auto&&... Values)
191 {
192 return Alloc<UE::RHI::Breadcrumbs::Private::TRHIBreadcrumb<TDesc>>(*this, *Desc, std::forward<decltype(Values)>(Values)...);
193 }, std::get<1>(Args));
194 }
195
196 template <typename TDesc, typename... TValues>
197 inline FRHIBreadcrumbScope::FRHIBreadcrumbScope(FRHIComputeCommandList& RHICmdList, TRHIBreadcrumbInitializer<TDesc, TValues...>&& Args)
198 : FRHIBreadcrumbScope(RHICmdList, RHICmdList.GetBreadcrumbAllocator().AllocBreadcrumb(Args))
199 {}
200
201 inline FRHIBreadcrumbScope::FRHIBreadcrumbScope(FRHIComputeCommandList& RHICmdList, FRHIBreadcrumbNode* Node)
202 : RHICmdList(RHICmdList)
203 , Node(Node)
204 {
205 if (Node)
206 {
207 Node->SetParent(RHICmdList.PersistentState.LocalBreadcrumb);
208 RHICmdList.BeginBreadcrumbCPU(Node, true);
209
210 for (ERHIPipeline Pipeline : MakeFlagsRange(RHICmdList.GetPipelines()))
211 {
212 RHICmdList.BeginBreadcrumbGPU(Node, Pipeline);
213 }
214 }
215 }
216
217 inline FRHIBreadcrumbScope::~FRHIBreadcrumbScope()
218 {
219 if (Node)
220 {
221 for (ERHIPipeline Pipeline : MakeFlagsRange(RHICmdList.GetPipelines()))
222 {
223 RHICmdList.EndBreadcrumbGPU(Node, Pipeline);
224 }
225
226 RHICmdList.EndBreadcrumbCPU(Node, true);
227 }
228 }
229
230 template <typename TDesc, typename... TValues>
231 inline FRHIBreadcrumbEventManual::FRHIBreadcrumbEventManual(FRHIComputeCommandList& RHICmdList, TRHIBreadcrumbInitializer<TDesc, TValues...>&& Args)
232 : Node(RHICmdList.GetBreadcrumbAllocator().AllocBreadcrumb(Args))
233 #if DO_CHECK
234 , Pipeline(RHICmdList.GetPipeline())
235 , ThreadId(FPlatformTLS::GetCurrentThreadId())
236 #endif
237 {
238 #if DO_CHECK
240 #endif
241
242 Node->SetParent(RHICmdList.PersistentState.LocalBreadcrumb);
243 RHICmdList.BeginBreadcrumbCPU(Node.Get(), true);
244 RHICmdList.BeginBreadcrumbGPU(Node.Get(), RHICmdList.GetPipeline());
245 }
246
247 inline void FRHIBreadcrumbEventManual::End(FRHIComputeCommandList& RHICmdList)
248 {
249 checkf(Node, TEXT("Manual breadcrumb was already ended."));
250 #if DO_CHECK
251 checkf(Pipeline == RHICmdList.GetPipeline(), TEXT("Manual breadcrumb was started and ended on different pipelines. Start: %s, End: %s")
253 , *GetRHIPipelineName(RHICmdList.GetPipeline())
254 );
255
256 checkf(ThreadId == FPlatformTLS::GetCurrentThreadId(), TEXT("Manual breadcrumbs must be started and ended on the same thread."));
257 #endif
258
259 RHICmdList.EndBreadcrumbGPU(Node.Get(), RHICmdList.GetPipeline());
260 RHICmdList.EndBreadcrumbCPU(Node.Get(), true);
261 Node = {};
262 }
263
264 inline FRHIBreadcrumbEventManual::~FRHIBreadcrumbEventManual()
265 {
266 checkf(!Node, TEXT("Manual breadcrumb was destructed before it was ended."));
267 }
268
269#endif // WITH_RHI_BREADCRUMBS
270
271template <typename RHICmdListType, typename LAMBDA>
273{
275
276 FRHIContextArray Contexts { InPlace, nullptr };
277 for (ERHIPipeline Pipeline : MakeFlagsRange(Pipelines))
278 {
279 Contexts[Pipeline] = CmdList.Contexts[Pipeline];
280 check(Contexts[Pipeline]);
281 }
282
283 // Static cast to enforce const type in lambda args
284 Lambda(static_cast<FRHIContextArray const&>(Contexts));
285 Lambda.~LAMBDA();
286}
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ InPlace
Definition CoreMiscDefines.h:162
#define TEXT(x)
Definition Platform.h:1272
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE_TEXT_ON_CHANNEL(Name, Channel)
Definition CpuProfilerTrace.h:534
UE::EnumFlags::Private::TRange< EnumType > MakeFlagsRange(EnumType Flags)
Definition EnumRange.h:285
RHI_API FRHICommandListExecutor GRHICommandList
Definition RHICommandList.cpp:119
bool IsRunningRHIInSeparateThread()
Definition RHICommandList.h:159
ERHIPipeline
Definition RHIPipeline.h:13
FString GetRHIPipelineName(ERHIPipeline Pipeline)
Definition RHIStrings.cpp:512
CORE_API bool IsInRenderingThread()
Definition ThreadingBase.cpp:273
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
if(Failed) console_printf("Failed.\n")
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition RHICommandList.h:455
bool SetAllowExtraTransitions(bool NewState)
Definition RHICommandList.h:1229
struct FRHICommandListBase::FPersistentState PersistentState
ERHIPipeline GetPipeline() const
Definition RHICommandList.h:675
uint32 NumCommands
Definition RHICommandList.h:1353
RHI_API FGraphEventRef RHIThreadFence(bool bSetLockFence=false)
Definition RHICommandList.cpp:1610
FRHICommandListImmediate & GetAsImmediate()
Definition RHICommandList.inl:21
FRHIContextArray Contexts
Definition RHICommandList.h:1351
bool Bypass() const
Definition RHICommandList.inl:27
FRHICommandBase * Root
Definition RHICommandList.h:1337
void ReplaceResources(TArray< FRHIResourceReplaceInfo > &&ReplaceInfos)
Definition RHICommandList.h:1165
bool IsImmediate() const
Definition RHICommandList.inl:16
RHI_API ERHIPipeline SwitchPipeline(ERHIPipeline Pipeline)
Definition RHICommandList.cpp:510
Definition RHICommandList.h:5284
bool Bypass() const
Definition RHICommandList.h:5309
Definition RHICommandList.h:4626
void SubmitCommandsHint()
Definition RHICommandList.h:5017
RHI_API void UnStallRHIThread()
Definition RHICommandList.cpp:1897
Definition RHICommandList.inl:73
FRHICommandListIterator(FRHICommandListBase &CmdList)
Definition RHICommandList.inl:75
~FRHICommandListIterator()
Definition RHICommandList.inl:83
FRHICommandBase * NextCommand()
Definition RHICommandList.inl:95
bool HasCommandsLeft() const
Definition RHICommandList.inl:90
FRHICommandListScopedAllowExtraTransitions(FRHICommandListBase &RHICmdList, bool bAllowExtraTransitions)
Definition RHICommandList.inl:150
~FRHICommandListScopedAllowExtraTransitions()
Definition RHICommandList.inl:156
FRHICommandListScopedFence(FRHICommandListBase &RHICmdList)
Definition RHICommandList.inl:114
~FRHICommandListScopedFence()
Definition RHICommandList.inl:121
~FRHICommandListScopedPipelineGuard()
Definition RHICommandList.inl:142
FRHICommandListScopedPipelineGuard(FRHICommandListBase &RHICmdList)
Definition RHICommandList.inl:132
Definition RHICommandList.h:2735
void SubmitCommandsHint()
Definition RHICommandList.inl:63
Definition RHIResources.h:5541
~FRHIResourceReplaceBatcher()
Definition RHICommandList.inl:161
Definition RHIResources.h:54
Definition RHICommandList.h:4582
FScopedRHIThreadStaller()=delete
~FScopedRHIThreadStaller()
Definition RHICommandList.inl:49
Definition RHIContext.h:257
Definition PipelineStateCache.cpp:26
RHI_API void FlushResources()
Definition PipelineStateCache.cpp:3534
MINIMAL_WINDOWS_API DWORD WINAPI GetCurrentThreadId()
Definition AndroidPlatformTLS.h:16
static uint32 GetCurrentThreadId(void)
Definition AndroidPlatformTLS.h:20
Definition RHICommandList.h:349
FRHICommandBase * Next
Definition RHICommandList.h:350
FRHICommandListScopedFence * CurrentFenceScope
Definition RHICommandList.h:1481
uint8 bImmediate
Definition RHICommandList.h:1472
void ExecuteAndDestruct(FRHICommandListBase &CmdList) override final
Definition RHICommandList.inl:272