UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
RHIValidationContext.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 RHIValidationContext.h: Public RHI Validation Context definitions.
5=============================================================================*/
6
7#pragma once
8
10#include "RHIValidationUtils.h"
11#include "RHIValidation.h"
12
13#if ENABLE_RHI_VALIDATION
14
15#include "RHI.h"
16
17class FValidationRHI;
18
19void ValidateShaderParameters(FRHIShader* RHIShader, RHIValidation::FTracker* Tracker, RHIValidation::FStaticUniformBuffers& StaticUniformBuffers, RHIValidation::FStageBoundUniformBuffers& BoundUniformBuffers, TConstArrayView<FRHIShaderParameterResource> InParameters, ERHIAccess InRequiredAccess, RHIValidation::EUAVMode InRequiredUAVMode);
20
22{
23public:
24 enum EType
25 {
26 Default,
28 } const Type;
29
30 FValidationComputeContext(EType Type);
31
32 void ValidateDispatch();
33
35 {
36 }
37
39 {
41 return *RHIContext;
42 }
43
44 virtual void SetExecutingCommandList(FRHICommandListBase* InCmdList) override final
45 {
47 RHIContext->SetExecutingCommandList(InCmdList);
48 }
49
50 virtual void RHISetComputePipelineState(FRHIComputePipelineState* ComputePipelineState) override final
51 {
52 State.BoundShader = ComputePipelineState->GetComputeShader();
53
54 // Reset the compute UAV tracker since the renderer must re-bind all resources after changing a shader.
55 Tracker->ResetUAVState(RHIValidation::EUAVMode::Compute);
56
57 State.StaticUniformBuffers.bInSetPipelineStateCall = true;
58 RHIContext->RHISetComputePipelineState(ComputePipelineState);
59 State.StaticUniformBuffers.bInSetPipelineStateCall = false;
60 }
61
62 virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) override final
63 {
65 FValidationRHI::ValidateThreadGroupCount(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
66 RHIContext->RHIDispatchComputeShader(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
67 Tracker->Dispatch();
68 }
69
70 virtual void RHIDispatchIndirectComputeShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
71 {
73 FValidationRHI::ValidateDispatchIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset);
74 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
75 RHIContext->RHIDispatchIndirectComputeShader(ArgumentBuffer, ArgumentOffset);
76 Tracker->Dispatch();
77 }
78
79 virtual void RHISetAsyncComputeBudget(EAsyncComputeBudget Budget) override final
80 {
81 RHIContext->RHISetAsyncComputeBudget(Budget);
82 }
83
84 virtual void RHIBeginTransitions(TArrayView<const FRHITransition*> Transitions) override final
85 {
86 for (const FRHITransition* Transition : Transitions)
87 {
88 Tracker->AddOps(Transition->PendingAliases);
89 }
90
91 for (const FRHITransition* Transition : Transitions)
92 {
93 Tracker->AddOps(Transition->PendingOperationsBegin);
94 }
95
96 for (const FRHITransition* Transition : Transitions)
97 {
98 Tracker->AddOps(Transition->PendingSignals[GetPipeline()]);
99 }
100
101 RHIContext->RHIBeginTransitions(Transitions);
102 }
103
104 virtual void RHIEndTransitions(TArrayView<const FRHITransition*> Transitions) override final
105 {
106 for (const FRHITransition* Transition : Transitions)
107 {
108 Tracker->AddOps(Transition->PendingWaits[GetPipeline()]);
109 }
110
111 for (const FRHITransition* Transition : Transitions)
112 {
113 Tracker->AddOps(Transition->PendingOperationsEnd);
114 }
115
116 for (const FRHITransition* Transition : Transitions)
117 {
118 Tracker->AddOps(Transition->PendingAliasingOverlaps);
119 }
120
121 RHIContext->RHIEndTransitions(Transitions);
122 }
123
124 virtual void SetTrackedAccess(const FRHITrackedAccessInfo& Info) override final
125 {
126 check(Info.Resource != nullptr);
127 check(Info.Access != ERHIAccess::Unknown);
128 check(Info.Pipelines != ERHIPipeline::None);
129
130 Tracker->SetTrackedAccess(Info.Resource->GetValidationTrackerResource(), Info.Access, Info.Pipelines);
131
132 RHIContext->SetTrackedAccess(Info);
133 }
134
135 virtual void RHIClearUAVFloat(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FVector4f& Values) override final
136 {
137 Tracker->Assert(UnorderedAccessViewRHI->GetViewIdentity(), ERHIAccess::UAVCompute);
138 RHIContext->RHIClearUAVFloat(UnorderedAccessViewRHI, Values);
139 }
140
141 virtual void RHIClearUAVUint(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FUintVector4& Values) override final
142 {
143 // @todo should we assert here? If the base RHI uses a compute shader via
144 // FRHICommandList_RecursiveHazardous then we might double-assert which breaks the tracking
145 RHIContext->RHIClearUAVUint(UnorderedAccessViewRHI, Values);
146 }
147
148 virtual void RHISetShaderRootConstants(const FUint32Vector4& Constants) final override
149 {
150 RHIContext->RHISetShaderRootConstants(Constants);
151 }
152
155 uint32 Width, uint32 Height) override final
156 {
157 SBT->ValidateStateForDispatch(Tracker);
158 RHIContext->RHIRayTraceDispatch(RayTracingPipelineState, RayGenShader, SBT, GlobalResourceBindings, Width, Height);
159 }
160
163 FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
164 {
165 FValidationRHI::ValidateDispatchIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset);
166 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
167 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
168
169 SBT->ValidateStateForDispatch(Tracker);
170 RHIContext->RHIRayTraceDispatchIndirect(RayTracingPipelineState, RayGenShader, SBT, GlobalResourceBindings, ArgumentBuffer, ArgumentOffset);
171 }
172
178 bool bEmulated) final override
179 {
181 {
182 RHI_VALIDATION_CHECK(SharedBindlessParameters.Num() == 0, TEXT("SharedBindlessParameters should not be set on this platform and configuration"));
183 }
184
185 RHI_VALIDATION_CHECK(Dispatches.Num() > 0, TEXT("A shader bundle must be dispatched with at least one record."));
186 for (const FRHIShaderBundleComputeDispatch& Dispatch : Dispatches)
187 {
188 if (!Dispatch.IsValid())
189 {
190 continue;
191 }
192
193 State.BoundShader = Dispatch.Shader;
194
195 // Reset the compute UAV tracker since the renderer must re-bind all resources after changing a shader.
196 Tracker->ResetUAVState(RHIValidation::EUAVMode::Compute);
197
198 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, State.BoundUniformBuffers, Dispatch.Parameters->ResourceParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
199 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, State.BoundUniformBuffers, Dispatch.Parameters->BindlessParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
200
201 if (bEmulated)
202 {
203 const uint32 ArgumentOffset = (Dispatch.RecordIndex * ShaderBundleRHI->ArgStride) + ShaderBundleRHI->ArgOffset;
204 FValidationRHI::ValidateDispatchIndirectArgsBuffer(RecordArgBuffer, ArgumentOffset);
205 }
206 }
207
208 Tracker->Assert(RecordArgBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
209
211 }
212
219 bool bEmulated) final override
220 {
222 {
223 RHI_VALIDATION_CHECK(SharedBindlessParameters.Num() == 0, TEXT("SharedBindlessParameters should not be set on this platform and configuration"));
224 }
225
226 // TODO:
227#if 0
228 RHI_VALIDATION_CHECK(Dispatches.Num() > 0, TEXT("A shader bundle must be dispatched with at least one record."));
229 for (const FRHIShaderBundleGraphicsDispatch& Dispatch : Dispatches)
230 {
231 if (!Dispatch.IsValid())
232 {
233 continue;
234 }
235
236 // Reset the graphics UAV tracker since the renderer must re-bind all resources after changing a shader.
237 Tracker->ResetUAVState(RHIValidation::EUAVMode::Graphics);
238
239 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, Dispatch.Parameters.ResourceParameters, ERHIAccess::SRVGraphics, RHIValidation::EUAVMode::Graphics);
240 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, Dispatch.Parameters.BindlessParameters, ERHIAccess::SRVGraphics, RHIValidation::EUAVMode::Graphics);
241
242 if (bEmulated)
243 {
244 const uint32 ArgumentOffset = (Dispatch.RecordIndex * ShaderBundleRHI->ArgStride) + ShaderBundleRHI->ArgOffset;
245 //ValidateIndirectArgsBuffer
246 //FValidationRHI::ValidateDispatchIndirectArgsBuffer(RecordArgBuffer, ArgumentOffset);
247 }
248 }
249
250 Tracker->Assert(RecordArgBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
251#endif
253 }
254
255 virtual void RHIBeginUAVOverlap() final override
256 {
257 Tracker->AllUAVsOverlap(true);
258 RHIContext->RHIBeginUAVOverlap();
259 }
260
261 virtual void RHIEndUAVOverlap() final override
262 {
263 Tracker->AllUAVsOverlap(false);
264 RHIContext->RHIEndUAVOverlap();
265 }
266
267 virtual void RHIBeginUAVOverlap(TConstArrayView<FRHIUnorderedAccessView*> UAVs) final override
268 {
269 for (FRHIUnorderedAccessView* UAV : UAVs)
270 {
271 Tracker->SpecificUAVOverlap(UAV->GetViewIdentity(), true);
272 }
273 RHIContext->RHIBeginUAVOverlap(UAVs);
274 }
275
276 virtual void RHIEndUAVOverlap(TConstArrayView<FRHIUnorderedAccessView*> UAVs) final override
277 {
278 for (FRHIUnorderedAccessView* UAV : UAVs)
279 {
280 Tracker->SpecificUAVOverlap(UAV->GetViewIdentity(), false);
281 }
282 RHIContext->RHIEndUAVOverlap(UAVs);
283 }
284
286 {
287 if (State.BoundShader == nullptr)
288 {
289 RHI_VALIDATION_CHECK(false, TEXT("A compute PSO has to be set to set resources into a shader!"));
290 return;
291 }
292
293 if (Shader != State.BoundShader)
294 {
295 RHI_VALIDATION_CHECK(false, *FString::Printf(TEXT("Invalid attempt to set parameters for compute shader '%s' while the currently bound shader is '%s'"), Shader->GetShaderName(), State.BoundShader->GetShaderName()));
296 return;
297 }
298
299 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, State.BoundUniformBuffers, InResourceParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
300 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, State.BoundUniformBuffers, InBindlessParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
301
303 }
304
306 {
307 if (State.BoundShader == nullptr)
308 {
309 RHI_VALIDATION_CHECK(false, TEXT("A compute PSO has to be set to set resources into a shader!"));
310 return;
311 }
312
313 RHIContext->RHISetShaderUnbinds(Shader, InUnbinds);
314 }
315
317 {
318 InUniformBuffers.Bind(State.StaticUniformBuffers.Bindings);
319 RHIContext->RHISetStaticUniformBuffers(InUniformBuffers);
320 }
321
323 {
324 RHIContext->RHISetStaticUniformBuffer(Slot, UniformBuffer);
325 }
326
327#if WITH_RHI_BREADCRUMBS
328 virtual void RHIBeginBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) final override
329 {
330 Tracker->BeginBreadcrumbGPU(Breadcrumb);
331 RHIContext->RHIBeginBreadcrumbGPU(Breadcrumb);
332 }
333 virtual void RHIEndBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) final override
334 {
335 Tracker->EndBreadcrumbGPU(Breadcrumb);
336 RHIContext->RHIEndBreadcrumbGPU(Breadcrumb);
337 }
338#endif // WITH_RHI_BREADCRUMBS
339
340 virtual void RHIWriteGPUFence(FRHIGPUFence* FenceRHI) override final
341 {
342 RHIContext->RHIWriteGPUFence(FenceRHI);
343 }
344
345 virtual void RHISetGPUMask(FRHIGPUMask GPUMask) override final
346 {
347 RHIContext->RHISetGPUMask(GPUMask);
348 }
349
350 virtual FRHIGPUMask RHIGetGPUMask() const override final
351 {
352 return RHIContext->RHIGetGPUMask();
353 }
354
356
357#if WITH_MGPU
359 {
360 RHIContext->RHITransferResources(Params);
361 }
362
364 {
365 RHIContext->RHITransferResourceSignal(FenceDatas, SrcGPUMask);
366 }
367
369 {
370 RHIContext->RHITransferResourceWait(FenceDatas);
371 }
372
374 {
375 RHIContext->RHICrossGPUTransfer(Params, PreTransfer, PostTransfer);
376 }
377
379 {
380 RHIContext->RHICrossGPUTransferSignal(Params, PreTransfer);
381 }
382
384 {
385 RHIContext->RHICrossGPUTransferWait(SyncPoints);
386 }
387#endif // WITH_MGPU
388
389 virtual void RHIExecuteMultiIndirectClusterOperation(const FRayTracingClusterOperationParams& Params) override final
390 {
391 RHIContext->RHIExecuteMultiIndirectClusterOperation(Params);
392 }
393
395 {
396 // #hwrt_todo: explicit transitions and state validation for BLAS
398 {
399 const FRayTracingGeometryInitializer& Initializer = P.Geometry->GetInitializer();
400
401 if (Initializer.IndexBuffer)
402 {
403 Tracker->Assert(Initializer.IndexBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
404 }
405
407 {
408 const FBufferRHIRef& RHIVertexBuffer = Segment.VertexBuffer;
409 Tracker->Assert(Segment.VertexBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
410 }
411 }
412
413 RHIContext->RHIBuildAccelerationStructures(Params, ScratchBufferRange);
414 }
415
417 {
418 // #hwrt_todo: validate all referenced BLAS states
419 for (const FRayTracingSceneBuildParams& P : Params)
420 {
421 if (P.Scene)
422 {
423 Tracker->Assert(P.Scene->GetWholeResourceIdentity(), ERHIAccess::BVHWrite);
424 }
425
426 if (P.InstanceBuffer)
427 {
428 Tracker->Assert(P.InstanceBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
429 }
430
431 if (P.ScratchBuffer)
432 {
433 Tracker->Assert(P.ScratchBuffer->GetWholeResourceIdentity(), ERHIAccess::UAVCompute);
434 }
435 }
436
437 RHIContext->RHIBuildAccelerationStructures(Params);
438 }
439
440 virtual void RHIBindAccelerationStructureMemory(FRHIRayTracingScene* Scene, FRHIBuffer* Buffer, uint32 BufferOffset) override final
441 {
442 RHIContext->RHIBindAccelerationStructureMemory(Scene, Buffer, BufferOffset);
443 }
444
446 {
448 PlatformContext->WrappingContext = this;
449 PlatformContext->Tracker = &State.TrackerInstance;
450 }
451
453
454protected:
455 struct FState
456 {
457 RHIValidation::FTracker TrackerInstance{ ERHIPipeline::AsyncCompute };
458 RHIValidation::FStaticUniformBuffers StaticUniformBuffers;
459 RHIValidation::FStageBoundUniformBuffers BoundUniformBuffers;
460
461 FString ComputePassName;
463
464 void Reset();
465 } State;
466
467 friend class FValidationRHI;
468};
469
470class FValidationContext final : public IRHICommandContext
471{
472public:
473 enum EType
474 {
475 Default,
477 } const Type;
478
480
482 {
484 return *RHIContext;
485 }
486
487 virtual void SetExecutingCommandList(FRHICommandListBase* InCmdList) override final
488 {
490 RHIContext->SetExecutingCommandList(InCmdList);
491 }
492
493 virtual void RHISetComputePipelineState(FRHIComputePipelineState* ComputePipelineState) override final
494 {
495 State.bGfxPSOSet = false;
496
497 FMemory::Memset(State.BoundShaders, 0);
498 State.BoundShaders[SF_Compute] = ComputePipelineState->GetComputeShader();
499
500 // Reset the compute UAV tracker since the renderer must re-bind all resources after changing a shader.
501 Tracker->ResetUAVState(RHIValidation::EUAVMode::Compute);
502
503 State.StaticUniformBuffers.bInSetPipelineStateCall = true;
504 RHIContext->RHISetComputePipelineState(ComputePipelineState);
505 State.StaticUniformBuffers.bInSetPipelineStateCall = false;
506 }
507
508 virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) override final
509 {
511 FValidationRHI::ValidateThreadGroupCount(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
512 RHIContext->RHIDispatchComputeShader(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
513 Tracker->Dispatch();
514 }
515
516 virtual void RHIDispatchIndirectComputeShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
517 {
519 FValidationRHI::ValidateDispatchIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset);
520 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
521 RHIContext->RHIDispatchIndirectComputeShader(ArgumentBuffer, ArgumentOffset);
522 Tracker->Dispatch();
523 }
524
525 virtual void RHISetAsyncComputeBudget(EAsyncComputeBudget Budget) override final
526 {
527 RHIContext->RHISetAsyncComputeBudget(Budget);
528 }
529
530 // Useful when used with geometry shader (emit polygons to different viewports), otherwise SetViewPort() is simpler
531 // @param Count >0
532 // @param Data must not be 0
533 virtual void RHISetMultipleViewports(uint32 Count, const FViewportBounds* Data) override final
534 {
535 RHIContext->RHISetMultipleViewports(Count, Data);
536 }
537
538 virtual void RHIClearUAVFloat(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FVector4f& Values) final override
539 {
540 // @todo should we assert here? If the base RHI uses a compute shader via
541 // FRHICommandList_RecursiveHazardous then we might double-assert which breaks the tracking
542 RHIContext->RHIClearUAVFloat(UnorderedAccessViewRHI, Values);
543 }
544
545 virtual void RHIClearUAVUint(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FUintVector4& Values) final override
546 {
547 // @todo should we assert here? If the base RHI uses a compute shader via
548 // FRHICommandList_RecursiveHazardous then we might double-assert which breaks the tracking
549 RHIContext->RHIClearUAVUint(UnorderedAccessViewRHI, Values);
550 }
551
552 virtual void RHISetShaderRootConstants(const FUint32Vector4& Constants) final override
553 {
554 RHIContext->RHISetShaderRootConstants(Constants);
555 }
556
562 bool bEmulated) final override
563 {
565 {
566 RHI_VALIDATION_CHECK(SharedBindlessParameters.Num() == 0, TEXT("SharedBindlessParameters should not be set on this platform and configuration"));
567 }
568
569 RHI_VALIDATION_CHECK(Dispatches.Num() > 0, TEXT("A shader bundle must be dispatched with at least one record."));
570 RHIValidation::FStageBoundUniformBuffers& BoundUniformBuffers = State.BoundUniformBuffers.Get(SF_Compute);
571
572 for (const FRHIShaderBundleComputeDispatch& Dispatch : Dispatches)
573 {
574 if (!Dispatch.IsValid())
575 {
576 continue;
577 }
578
579 State.BoundShaders[SF_Compute] = Dispatch.Shader;
580
581 // Reset the compute UAV tracker since the renderer must re-bind all resources after changing a shader.
582 Tracker->ResetUAVState(RHIValidation::EUAVMode::Compute);
583
584 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, Dispatch.Parameters->ResourceParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
585 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, Dispatch.Parameters->BindlessParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
586
587 if (bEmulated)
588 {
589 const uint32 ArgumentOffset = (Dispatch.RecordIndex * ShaderBundleRHI->ArgStride) + ShaderBundleRHI->ArgOffset;
590 FValidationRHI::ValidateDispatchIndirectArgsBuffer(RecordArgBuffer, ArgumentOffset);
591 }
592 }
593
594 Tracker->Assert(RecordArgBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
595
597 }
598
605 bool bEmulated) final override
606 {
608 {
609 RHI_VALIDATION_CHECK(SharedBindlessParameters.Num() == 0, TEXT("SharedBindlessParameters should not be set on this platform and configuration"));
610 }
611
612 // TODO
613#if 0
614 RHI_VALIDATION_CHECK(Dispatches.Num() > 0, TEXT("A shader bundle must be dispatched with at least one record."));
615 for (const FRHIShaderBundleGraphicsDispatch& Dispatch : Dispatches)
616 {
617 if (!Dispatch.IsValid())
618 {
619 continue;
620 }
621
622 //State.bComputePSOSet = true;
623
624 // Reset the compute UAV tracker since the renderer must re-bind all resources after changing a shader.
625 Tracker->ResetUAVState(RHIValidation::EUAVMode::Graphics);
626
627 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, Dispatch.Parameters.ResourceParameters, ERHIAccess::SRVGraphics, RHIValidation::EUAVMode::Graphics);
628 ValidateShaderParameters(Dispatch.Shader, Tracker, State.StaticUniformBuffers, Dispatch.Parameters.BindlessParameters, ERHIAccess::SRVGraphics, RHIValidation::EUAVMode::Graphics);
629
630 if (bEmulated)
631 {
632 const uint32 ArgumentOffset = (Dispatch.RecordIndex * ShaderBundleRHI->ArgStride) + ShaderBundleRHI->ArgOffset;
633 //FValidationRHI::ValidateDispatchIndirectArgsBuffer(RecordArgBuffer, ArgumentOffset);
634 }
635 }
636
637 Tracker->Assert(RecordArgBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
638#endif
640 }
641
642 virtual void RHIBeginUAVOverlap() final override
643 {
644 Tracker->AllUAVsOverlap(true);
645 RHIContext->RHIBeginUAVOverlap();
646 }
647
648 virtual void RHIEndUAVOverlap() final override
649 {
650 Tracker->AllUAVsOverlap(false);
651 RHIContext->RHIEndUAVOverlap();
652 }
653
654 virtual void RHIBeginUAVOverlap(TConstArrayView<FRHIUnorderedAccessView*> UAVs) final override
655 {
656 for (FRHIUnorderedAccessView* UAV : UAVs)
657 {
658 Tracker->SpecificUAVOverlap(UAV->GetViewIdentity(), true);
659 }
660 RHIContext->RHIBeginUAVOverlap(UAVs);
661 }
662
663 virtual void RHIEndUAVOverlap(TConstArrayView<FRHIUnorderedAccessView*> UAVs) final override
664 {
665 for (FRHIUnorderedAccessView* UAV : UAVs)
666 {
667 Tracker->SpecificUAVOverlap(UAV->GetViewIdentity(), false);
668 }
669 RHIContext->RHIEndUAVOverlap(UAVs);
670 }
671
672 virtual void RHIResummarizeHTile(FRHITexture* DepthTexture) override final
673 {
674 Tracker->Assert(DepthTexture->GetWholeResourceIdentity(), ERHIAccess::DSVWrite);
675 RHIContext->RHIResummarizeHTile(DepthTexture);
676 }
677
678 virtual void* RHIGetNativeCommandBuffer() override final
679 {
680 return RHIContext->RHIGetNativeCommandBuffer();
681 }
682
683 virtual void RHIBeginTransitions(TArrayView<const FRHITransition*> Transitions) override final
684 {
685 for (const FRHITransition* Transition : Transitions)
686 {
687 if (Transition->AllowInRenderingPass() == false)
688 {
689 ensureMsgf(!State.bInsideBeginRenderPass, TEXT("Ending a transition within a renderpass is not supported!"));
690 }
691
692 Tracker->AddOps(Transition->PendingAliases);
693 }
694
695 for (const FRHITransition* Transition : Transitions)
696 {
697 Tracker->AddOps(Transition->PendingOperationsBegin);
698 }
699
700 for (const FRHITransition* Transition : Transitions)
701 {
702 Tracker->AddOps(Transition->PendingSignals[GetPipeline()]);
703 }
704
705 RHIContext->RHIBeginTransitions(Transitions);
706 }
707
708 virtual void RHIEndTransitions(TArrayView<const FRHITransition*> Transitions) override final
709 {
710 for (const FRHITransition* Transition : Transitions)
711 {
712 if (Transition->AllowInRenderingPass() == false)
713 {
714 ensureMsgf(!State.bInsideBeginRenderPass, TEXT("Ending a transition within a renderpass is not supported!"));
715 }
716
717 Tracker->AddOps(Transition->PendingWaits[GetPipeline()]);
718 }
719
720 for (const FRHITransition* Transition : Transitions)
721 {
722 Tracker->AddOps(Transition->PendingOperationsEnd);
723 }
724
725 for (const FRHITransition* Transition : Transitions)
726 {
727 Tracker->AddOps(Transition->PendingAliasingOverlaps);
728 }
729
730 RHIContext->RHIEndTransitions(Transitions);
731 }
732
733 virtual void SetTrackedAccess(const FRHITrackedAccessInfo& Info) override final
734 {
735 check(Info.Resource != nullptr);
736 check(Info.Access != ERHIAccess::Unknown);
737
738 Tracker->SetTrackedAccess(Info.Resource->GetValidationTrackerResource(), Info.Access, Info.Pipelines);
739
740 RHIContext->SetTrackedAccess(Info);
741 }
742
743 virtual void RHIBeginRenderQuery(FRHIRenderQuery* RenderQuery) override final
744 {
745 RHIContext->RHIBeginRenderQuery(RenderQuery);
746 }
747
748 virtual void RHIEndRenderQuery(FRHIRenderQuery* RenderQuery) override final
749 {
750 RHIContext->RHIEndRenderQuery(RenderQuery);
751 }
752
753#if (RHI_NEW_GPU_PROFILER == 0)
754 virtual void RHICalibrateTimers(FRHITimestampCalibrationQuery* CalibrationQuery) override final
755 {
756 RHIContext->RHICalibrateTimers(CalibrationQuery);
757 }
758#endif
759
760 // This method is queued with an RHIThread, otherwise it will flush after it is queued; without an RHI thread there is no benefit to queuing this frame advance commands
761 virtual void RHIEndDrawingViewport(FRHIViewport* Viewport, bool bPresent, bool bLockToVsync) override final
762 {
763 RHIContext->RHIEndDrawingViewport(Viewport, bPresent, bLockToVsync);
764 }
765
766 virtual void RHISetStreamSource(uint32 StreamIndex, FRHIBuffer* VertexBuffer, uint32 Offset) override final
767 {
768 //#todo-rco: Decide if this is needed or not...
769 //checkf(State.bGfxPSOSet, TEXT("A Graphics PSO has to be set to set-up the vertex streams!"));
770
771 // @todo: do we really need to allow setting nullptr stream sources anymore?
772 if (VertexBuffer)
773 {
774 checkf(State.bInsideBeginRenderPass, TEXT("A RenderPass has to be set to set-up the vertex streams!"));
775 Tracker->Assert(VertexBuffer->GetWholeResourceIdentity(), ERHIAccess::VertexOrIndexBuffer);
776 }
777
778 RHIContext->RHISetStreamSource(StreamIndex, VertexBuffer, Offset);
779 }
780
781 // @param MinX including like Win32 RECT
782 // @param MinY including like Win32 RECT
783 // @param MaxX excluding like Win32 RECT
784 // @param MaxY excluding like Win32 RECT
785 virtual void RHISetViewport(float MinX, float MinY, float MinZ, float MaxX, float MaxY, float MaxZ) override final
786 {
787 RHIContext->RHISetViewport(MinX, MinY, MinZ, MaxX, MaxY, MaxZ);
788 }
789
790 virtual void RHISetStereoViewport(float LeftMinX, float RightMinX, float LeftMinY, float RightMinY, float MinZ, float LeftMaxX, float RightMaxX, float LeftMaxY, float RightMaxY, float MaxZ) override final
791 {
792 RHIContext->RHISetStereoViewport(LeftMinX, RightMinX, LeftMinY, RightMinY, MinZ, LeftMaxX, RightMaxX, LeftMaxY, RightMaxY, MaxZ);
793 }
794
795 // @param MinX including like Win32 RECT
796 // @param MinY including like Win32 RECT
797 // @param MaxX excluding like Win32 RECT
798 // @param MaxY excluding like Win32 RECT
799 virtual void RHISetScissorRect(bool bEnable, uint32 MinX, uint32 MinY, uint32 MaxX, uint32 MaxY) override final
800 {
801 RHIContext->RHISetScissorRect(bEnable, MinX, MinY, MaxX, MaxY);
802 }
803
805 {
806 checkf(State.bInsideBeginRenderPass, TEXT("Graphics PSOs can only be set inside a RenderPass!"));
807 State.bGfxPSOSet = true;
808
810 {
812 State.BoundShaders[FrequencyIndex] = IsValidGraphicsFrequency(Frequency) ? GraphicsState->GetShader(Frequency) : nullptr;
813 }
814
816
817 // Setting a new PSO unbinds all previous bound resources
818 Tracker->ResetUAVState(RHIValidation::EUAVMode::Graphics);
819
820 State.StaticUniformBuffers.bInSetPipelineStateCall = true;
821 RHIContext->RHISetGraphicsPipelineState(GraphicsState, StencilRef, bApplyAdditionalState);
822 State.StaticUniformBuffers.bInSetPipelineStateCall = false;
823 }
824
825#if PLATFORM_USE_FALLBACK_PSO
827 {
828 checkf(State.bInsideBeginRenderPass, TEXT("Graphics PSOs can only be set inside a RenderPass!"));
829 State.bGfxPSOSet = true;
830
831 FMemory::Memset(State.BoundShaders, 0);
832 State.BoundShaders[SF_Vertex] = PsoInit.BoundShaderState.GetVertexShader();
833 State.BoundShaders[SF_Pixel] = PsoInit.BoundShaderState.GetPixelShader();
834 State.BoundShaders[SF_Geometry] = PsoInit.BoundShaderState.GetGeometryShader();
835 State.BoundShaders[SF_Amplification] = PsoInit.BoundShaderState.GetAmplificationShader();
836 State.BoundShaders[SF_Mesh] = PsoInit.BoundShaderState.GetMeshShader();
837
838 ValidateDepthStencilForSetGraphicsPipelineState(PsoInit.DepthStencilState->ActualDSMode);
839
840 // Setting a new PSO unbinds all previous bound resources
841 Tracker->ResetUAVState(RHIValidation::EUAVMode::Graphics);
842
843 State.StaticUniformBuffers.bInSetPipelineStateCall = true;
844 RHIContext->RHISetGraphicsPipelineState(PsoInit, StencilRef, bApplyAdditionalState);
845 State.StaticUniformBuffers.bInSetPipelineStateCall = false;
846 }
847#endif
848
850 {
851 if (!State.bGfxPSOSet)
852 {
853 RHI_VALIDATION_CHECK(false, TEXT("A graphics PSO has to be set to set resources into a shader!"));
854 return;
855 }
856
857 RHIValidation::FStageBoundUniformBuffers& BoundUniformBuffers = State.BoundUniformBuffers.Get(Shader->GetFrequency());
858
860
861 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, InResourceParameters, RequiredAccess, RHIValidation::EUAVMode::Graphics);
862 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, InBindlessParameters, RequiredAccess, RHIValidation::EUAVMode::Graphics);
863
865 }
866
868 {
869 if (State.BoundShaders[SF_Compute] == nullptr)
870 {
871 RHI_VALIDATION_CHECK(false, TEXT("A compute PSO has to be set to set resources into a shader!"));
872 return;
873 }
874
875 if (Shader != State.BoundShaders[SF_Compute])
876 {
877 RHI_VALIDATION_CHECK(false, *FString::Printf(TEXT("Invalid attempt to set parameters for compute shader '%s' while the currently bound shader is '%s'"), Shader->GetShaderName(), State.BoundShaders[SF_Compute]->GetShaderName()));
878 return;
879 }
880
881 RHIValidation::FStageBoundUniformBuffers& BoundUniformBuffers = State.BoundUniformBuffers.Get(SF_Compute);
882
883 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, InResourceParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
884 ValidateShaderParameters(Shader, Tracker, State.StaticUniformBuffers, BoundUniformBuffers, InBindlessParameters, ERHIAccess::SRVCompute, RHIValidation::EUAVMode::Compute);
885
887 }
888
890 {
891 if (!State.bGfxPSOSet)
892 {
893 RHI_VALIDATION_CHECK(false, TEXT("A graphics PSO has to be set to set resources into a shader!"));
894 return;
895 }
896
897 RHIContext->RHISetShaderUnbinds(Shader, InUnbinds);
898 }
899
901 {
902 if (State.BoundShaders[SF_Compute] == nullptr)
903 {
904 RHI_VALIDATION_CHECK(false, TEXT("A compute PSO has to be set to set resources into a shader!"));
905 return;
906 }
907
908 RHIContext->RHISetShaderUnbinds(Shader, InUnbinds);
909 }
910
912 {
913 InUniformBuffers.Bind(State.StaticUniformBuffers.Bindings);
914 RHIContext->RHISetStaticUniformBuffers(InUniformBuffers);
915 }
916
918 {
919 RHIContext->RHISetStaticUniformBuffer(Slot, UniformBuffer);
920 }
921
923 {
924 RHIContext->RHISetUniformBufferDynamicOffset(Slot, Offset);
925 }
926
927 virtual void RHISetStencilRef(uint32 StencilRef) override final
928 {
929 //checkf(State.bGfxPSOSet, TEXT("A Graphics PSO has to be set to change stencil ref!"));
930 RHIContext->RHISetStencilRef(StencilRef);
931 }
932
933 virtual void RHISetBlendFactor(const FLinearColor& BlendFactor) override final
934 {
935 //checkf(State.bGfxPSOSet, TEXT("A Graphics PSO has to be set to change blend factor!"));
936 RHIContext->RHISetBlendFactor(BlendFactor);
937 }
938
939 virtual void RHIDrawPrimitive(uint32 BaseVertexIndex, uint32 NumPrimitives, uint32 NumInstances) override final
940 {
942 RHIContext->RHIDrawPrimitive(BaseVertexIndex, NumPrimitives, NumInstances);
943 Tracker->Draw();
944 }
945
946 virtual void RHIDrawPrimitiveIndirect(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
947 {
949 FValidationRHI::ValidateIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset, sizeof(FRHIDrawIndirectParameters), 0);
950 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
951 RHIContext->RHIDrawPrimitiveIndirect(ArgumentBuffer, ArgumentOffset);
952 Tracker->Draw();
953 }
954
955 virtual void RHIDrawIndexedIndirect(FRHIBuffer* IndexBufferRHI, FRHIBuffer* ArgumentsBufferRHI, int32 DrawArgumentsIndex, uint32 NumInstances) override final
956 {
958 FValidationRHI::ValidateIndirectArgsBuffer(ArgumentsBufferRHI, DrawArgumentsIndex * ArgumentsBufferRHI->GetStride(), sizeof(FRHIDrawIndexedIndirectParameters), 0);
959 Tracker->Assert(ArgumentsBufferRHI->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
960 Tracker->Assert(IndexBufferRHI->GetWholeResourceIdentity(), ERHIAccess::VertexOrIndexBuffer);
961 RHIContext->RHIDrawIndexedIndirect(IndexBufferRHI, ArgumentsBufferRHI, DrawArgumentsIndex, NumInstances);
962 Tracker->Draw();
963 }
964
965 // @param NumPrimitives need to be >0
966 virtual void RHIDrawIndexedPrimitive(FRHIBuffer* IndexBuffer, int32 BaseVertexIndex, uint32 FirstInstance, uint32 NumVertices, uint32 StartIndex, uint32 NumPrimitives, uint32 NumInstances) override final
967 {
969 checkf(EnumHasAnyFlags(IndexBuffer->GetUsage(), EBufferUsageFlags::IndexBuffer), TEXT("The buffer '%s' is used as an index buffer, but was not created with the IndexBuffer flag."), *IndexBuffer->GetName().ToString());
970 Tracker->Assert(IndexBuffer->GetWholeResourceIdentity(), ERHIAccess::VertexOrIndexBuffer);
971 RHIContext->RHIDrawIndexedPrimitive(IndexBuffer, BaseVertexIndex, FirstInstance, NumVertices, StartIndex, NumPrimitives, NumInstances);
972 Tracker->Draw();
973 }
974
975 virtual void RHIDrawIndexedPrimitiveIndirect(FRHIBuffer* IndexBuffer, FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
976 {
978 checkf(EnumHasAnyFlags(IndexBuffer->GetUsage(), EBufferUsageFlags::IndexBuffer), TEXT("The buffer '%s' is used as an index buffer, but was not created with the IndexBuffer flag."), *IndexBuffer->GetName().ToString());
979 FValidationRHI::ValidateIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset, sizeof(FRHIDrawIndexedIndirectParameters), 0);
980 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
981 Tracker->Assert(IndexBuffer->GetWholeResourceIdentity(), ERHIAccess::VertexOrIndexBuffer);
982 RHIContext->RHIDrawIndexedPrimitiveIndirect(IndexBuffer, ArgumentBuffer, ArgumentOffset);
983 Tracker->Draw();
984 }
985
987 {
989 checkf(EnumHasAnyFlags(IndexBuffer->GetUsage(), EBufferUsageFlags::IndexBuffer), TEXT("The buffer '%s' is used as an index buffer, but was not created with the IndexBuffer flag."), *IndexBuffer->GetName().ToString());
990 FValidationRHI::ValidateIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset, sizeof(FRHIDrawIndexedIndirectParameters), 0);
991 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
992 if (CountBuffer)
993 {
994 Tracker->Assert(CountBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
995 }
996 Tracker->Assert(IndexBuffer->GetWholeResourceIdentity(), ERHIAccess::VertexOrIndexBuffer);
997 RHIContext->RHIMultiDrawIndexedPrimitiveIndirect(IndexBuffer, ArgumentBuffer, ArgumentOffset, CountBuffer, CountBufferOffset, MaxDrawArguments);
998 Tracker->Draw();
999 }
1000
1001 virtual void RHIDispatchMeshShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) final override
1002 {
1004 FValidationRHI::ValidateThreadGroupCount(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
1005 RHIContext->RHIDispatchMeshShader(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
1006 Tracker->Draw();
1007 }
1008
1009 virtual void RHIDispatchIndirectMeshShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override
1010 {
1012 FValidationRHI::ValidateDispatchIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset);
1013 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
1014 RHIContext->RHIDispatchIndirectMeshShader(ArgumentBuffer, ArgumentOffset);
1015 Tracker->Draw();
1016 }
1017
1024 virtual void RHISetDepthBounds(float MinDepth, float MaxDepth) override final
1025 {
1026 checkf(MinDepth >= 0.f && MinDepth <= 1.f, TEXT("Depth bounds min of %f is outside allowed range of [0, 1]"), MinDepth);
1027 checkf(MaxDepth >= 0.f && MaxDepth <= 1.f, TEXT("Depth bounds max of %f is outside allowed range of [0, 1]"), MaxDepth);
1028 RHIContext->RHISetDepthBounds(MinDepth, MaxDepth);
1029 }
1030
1031 virtual void RHISetShadingRate(EVRSShadingRate ShadingRate, EVRSRateCombiner Combiner) override final
1032 {
1033 RHIContext->RHISetShadingRate(ShadingRate, Combiner);
1034 }
1035
1036#if WITH_RHI_BREADCRUMBS
1037 virtual void RHIBeginBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) override final
1038 {
1039 Tracker->BeginBreadcrumbGPU(Breadcrumb);
1040 RHIContext->RHIBeginBreadcrumbGPU(Breadcrumb);
1041 }
1042 virtual void RHIEndBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) override final
1043 {
1044 Tracker->EndBreadcrumbGPU(Breadcrumb);
1045 RHIContext->RHIEndBreadcrumbGPU(Breadcrumb);
1046 }
1047#endif // WITH_RHI_BREADCRUMBS
1048
1049 virtual void RHIBeginRenderPass(const FRHIRenderPassInfo& InInfo, const TCHAR* InName) override final
1050 {
1051 checkf(!State.bInsideBeginRenderPass, TEXT("Trying to begin RenderPass '%s', but already inside '%s'!"), *State.RenderPassName, InName);
1052 checkf(InName!=nullptr, TEXT("RenderPass should have a name!"));
1053 State.bInsideBeginRenderPass = true;
1054 State.RenderPassInfo = InInfo;
1055 State.RenderPassName = InName;
1056
1058
1059 // assert that render targets are writable
1061 {
1062 FRHIRenderPassInfo::FColorEntry& RTV = State.RenderPassInfo.ColorRenderTargets[RTVIndex];
1063 if (RTV.RenderTarget == nullptr)
1064 {
1065 checkf(RTV.ResolveTarget == nullptr, TEXT("Render target is null, but resolve target is not."));
1066 continue;
1067 }
1068
1069 // Check all bound textures have the same dimensions
1070 FIntVector MipDimensions = RTV.RenderTarget->GetMipDimensions(RTV.MipIndex);
1071 checkf(ViewDimensions.IsZero() || ViewDimensions == MipDimensions, TEXT("Render target size mismatch (RT%d: %dx%d vs. Expected: %dx%d). All render and depth target views must have the same effective dimensions."), RTVIndex, MipDimensions.X, MipDimensions.Y, ViewDimensions.X, ViewDimensions.Y);
1073
1074 uint32 ArraySlice = RTV.ArraySlice;
1075 uint32 NumArraySlices = 1;
1076 if (RTV.ArraySlice < 0)
1077 {
1078 ArraySlice = 0;
1079 NumArraySlices = 0;
1080 }
1081
1082 Tracker->Assert(RTV.RenderTarget->GetViewIdentity(RTV.MipIndex, 1, ArraySlice, NumArraySlices, 0, 0), ERHIAccess::RTV);
1083
1084 if (RTV.ResolveTarget)
1085 {
1086 const FRHITextureDesc& RenderTargetDesc = RTV.RenderTarget->GetDesc();
1087 const FRHITextureDesc& ResolveTargetDesc = RTV.ResolveTarget->GetDesc();
1088
1089 checkf(RenderTargetDesc.Extent == ResolveTargetDesc.Extent, TEXT("Render target extent must match resolve target extent."));
1090 checkf(RenderTargetDesc.Format == ResolveTargetDesc.Format, TEXT("Render target format must match resolve target format."));
1091
1092 Tracker->Assert(RTV.ResolveTarget->GetViewIdentity(RTV.MipIndex, 1, ArraySlice, NumArraySlices, 0, 0), ERHIAccess::ResolveDst);
1093 }
1094 }
1095
1096 FRHIRenderPassInfo::FDepthStencilEntry& DSV = State.RenderPassInfo.DepthStencilRenderTarget;
1097
1098 if (DSV.DepthStencilTarget)
1099 {
1100 // Check all bound textures have the same dimensions
1101 FIntVector MipDimensions = DSV.DepthStencilTarget->GetMipDimensions(0);
1102 checkf(ViewDimensions.IsZero() || ViewDimensions == MipDimensions, TEXT("Depth target size mismatch (Depth: %dx%d vs. Expected: %dx%d). All render and depth target views must have the same effective dimensions."), MipDimensions.X, MipDimensions.Y, ViewDimensions.X, ViewDimensions.Y);
1104
1105 if (DSV.ResolveTarget)
1106 {
1107 const FRHITextureDesc& DepthStencilTargetDesc = DSV.DepthStencilTarget->GetDesc();
1108 const FRHITextureDesc& ResolveTargetDesc = DSV.ResolveTarget->GetDesc();
1109
1110 checkf(DepthStencilTargetDesc.Extent == ResolveTargetDesc.Extent, TEXT("Depth stencil target extent must match resolve target extent."));
1111 checkf(DepthStencilTargetDesc.IsTexture2D() && ResolveTargetDesc.IsTexture2D(), TEXT("Only 2D depth stencil resolves are supported."));
1112 }
1113 }
1114
1115 // @todo: additional checks for matching array slice counts on RTVs/DSVs
1116
1117 // assert depth is in the correct mode
1118 if (DSV.ExclusiveDepthStencil.IsUsingDepth())
1119 {
1120 ERHIAccess DepthAccess = DSV.ExclusiveDepthStencil.IsDepthWrite()
1123
1124 checkf(DSV.DepthStencilTarget, TEXT("Depth read/write is enabled but no depth stencil texture is bound."));
1125 Tracker->Assert(DSV.DepthStencilTarget->GetViewIdentity(0, 0, 0, 0, uint32(RHIValidation::EResourcePlane::Common), 1), DepthAccess);
1126
1127 if (DSV.ResolveTarget)
1128 {
1129 Tracker->Assert(DSV.ResolveTarget->GetViewIdentity(0, 0, 0, 0, uint32(RHIValidation::EResourcePlane::Common), 1), ERHIAccess::ResolveDst);
1130 }
1131 }
1132
1133 // assert stencil is in the correct mode
1134 if (DSV.ExclusiveDepthStencil.IsUsingStencil())
1135 {
1136 ERHIAccess StencilAccess = DSV.ExclusiveDepthStencil.IsStencilWrite()
1139
1140 checkf(DSV.DepthStencilTarget, TEXT("Stencil read/write is enabled but no depth stencil texture is bound."));
1141
1142 bool bIsStencilFormat = IsStencilFormat(DSV.DepthStencilTarget->GetFormat());
1143 checkf(bIsStencilFormat, TEXT("Stencil read/write is enabled but depth stencil texture doesn't have a stencil plane."));
1144 if (bIsStencilFormat)
1145 {
1146 Tracker->Assert(DSV.DepthStencilTarget->GetViewIdentity(0, 0, 0, 0, uint32(RHIValidation::EResourcePlane::Stencil), 1), StencilAccess);
1147
1148 if (DSV.ResolveTarget)
1149 {
1150 Tracker->Assert(DSV.ResolveTarget->GetViewIdentity(0, 0, 0, 0, uint32(RHIValidation::EResourcePlane::Stencil), 1), ERHIAccess::ResolveDst);
1151 }
1152 }
1153 }
1154
1155 // assert shading-rate attachment is in the correct mode and format.
1156 if (State.RenderPassInfo.ShadingRateTexture.IsValid())
1157 {
1158 FTextureRHIRef ShadingRateTexture = State.RenderPassInfo.ShadingRateTexture;
1159 checkf(ShadingRateTexture->GetFormat() == GRHIVariableRateShadingImageFormat, TEXT("Shading rate texture is bound, but is not the correct format for this RHI."));
1160 Tracker->Assert(ShadingRateTexture->GetViewIdentity(0, 0, 0, 0, 0, 0), ERHIAccess::ShadingRateSource);
1161 }
1162
1163 RHIContext->RHIBeginRenderPass(InInfo, InName);
1164 }
1165
1166 virtual void RHIEndRenderPass() override final
1167 {
1168 checkf(State.bInsideBeginRenderPass, TEXT("Trying to end a RenderPass but not inside one!"));
1169 RHIContext->RHIEndRenderPass();
1170 State.bInsideBeginRenderPass = false;
1171 State.PreviousRenderPassName = State.RenderPassName;
1172 }
1173
1174 virtual void RHINextSubpass() override final
1175 {
1176 RHIContext->RHINextSubpass();
1177 }
1178
1179 virtual void RHIBeginParallelRenderPass(TSharedPtr<FRHIParallelRenderPassInfo> InInfo, const TCHAR* InName) override final
1180 {
1181 RHIContext->RHIBeginParallelRenderPass(InInfo, InName);
1182 }
1183
1184 virtual void RHIEndParallelRenderPass() override final
1185 {
1186 RHIContext->RHIEndParallelRenderPass();
1187 }
1188
1189 virtual void RHIWriteGPUFence(FRHIGPUFence* FenceRHI) override final
1190 {
1191 RHIContext->RHIWriteGPUFence(FenceRHI);
1192 }
1193
1194 virtual void RHISetGPUMask(FRHIGPUMask GPUMask) override final
1195 {
1196 RHIContext->RHISetGPUMask(GPUMask);
1197 }
1198
1199 virtual FRHIGPUMask RHIGetGPUMask() const override final
1200 {
1201 return RHIContext->RHIGetGPUMask();
1202 }
1203
1205
1206 virtual void RHICopyTexture(FRHITexture* SourceTexture, FRHITexture* DestTexture, const FRHICopyTextureInfo& CopyInfo) override final
1207 {
1208 ensureMsgf(!State.bInsideBeginRenderPass, TEXT("Copying inside a RenderPass is not efficient!"));
1209
1210 // @todo: do we need to pick subresource, not just whole resource identity here.
1211 // also, is CopySrc / CopyDest correct?
1212 Tracker->Assert(SourceTexture->GetWholeResourceIdentity(), ERHIAccess::CopySrc);
1213 Tracker->Assert(DestTexture->GetWholeResourceIdentity(), ERHIAccess::CopyDest);
1214
1215 FValidationRHIUtils::ValidateCopyTexture(SourceTexture, DestTexture, CopyInfo);
1216 RHIContext->RHICopyTexture(SourceTexture, DestTexture, CopyInfo);
1217 }
1218
1219 virtual void RHICopyBufferRegion(FRHIBuffer* DestBuffer, uint64 DstOffset, FRHIBuffer* SourceBuffer, uint64 SrcOffset, uint64 NumBytes)
1220 {
1221 Tracker->Assert(SourceBuffer->GetWholeResourceIdentity(), ERHIAccess::CopySrc);
1222 Tracker->Assert(DestBuffer->GetWholeResourceIdentity(), ERHIAccess::CopyDest);
1223 RHIContext->RHICopyBufferRegion(DestBuffer, DstOffset, SourceBuffer, SrcOffset, NumBytes);
1224 }
1225
1227 {
1228 SBT->Clear();
1229 RHIContext->RHIClearShaderBindingTable(SBT);
1230 }
1231
1233 {
1234 SBT->Commit();
1236 {
1237 Tracker->Assert(InlineBindingDataBuffer->GetWholeResourceIdentity(), ERHIAccess::CopyDest);
1238 }
1239 RHIContext->RHICommitShaderBindingTable(SBT, InlineBindingDataBuffer);
1240 }
1241
1242 virtual void RHIExecuteMultiIndirectClusterOperation(const FRayTracingClusterOperationParams& Params) override final
1243 {
1244 RHIContext->RHIExecuteMultiIndirectClusterOperation(Params);
1245 }
1246
1248 {
1249 for (const FRayTracingGeometryBuildParams& P : Params)
1250 {
1251 const FRayTracingGeometryInitializer& Initializer = P.Geometry->GetInitializer();
1252
1253 if (Initializer.IndexBuffer)
1254 {
1255 Tracker->Assert(Initializer.IndexBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
1256 }
1257
1259 {
1260 Tracker->Assert(Segment.VertexBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
1261 }
1262 }
1263
1264 RHIContext->RHIBuildAccelerationStructures(Params, ScratchBufferRange);
1265 }
1266
1268 {
1269 for (const FRayTracingSceneBuildParams& P : Params)
1270 {
1271 if (P.Scene)
1272 {
1273 Tracker->Assert(P.Scene->GetWholeResourceIdentity(), ERHIAccess::BVHWrite);
1274 }
1275
1276 if (P.InstanceBuffer)
1277 {
1278 Tracker->Assert(P.InstanceBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
1279 }
1280
1281 if (P.ScratchBuffer)
1282 {
1283 Tracker->Assert(P.ScratchBuffer->GetWholeResourceIdentity(), ERHIAccess::UAVCompute);
1284 }
1285 }
1286
1287 RHIContext->RHIBuildAccelerationStructures(Params);
1288 }
1289
1290 virtual void RHIBindAccelerationStructureMemory(FRHIRayTracingScene* Scene, FRHIBuffer* Buffer, uint32 BufferOffset) override final
1291 {
1292 RHIContext->RHIBindAccelerationStructureMemory(Scene, Buffer, BufferOffset);
1293 }
1294
1297 uint32 Width, uint32 Height) override final
1298 {
1299 SBT->ValidateStateForDispatch(Tracker);
1300 RHIContext->RHIRayTraceDispatch(RayTracingPipelineState, RayGenShader, SBT, GlobalResourceBindings, Width, Height);
1301 }
1302
1305 FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) override final
1306 {
1307 FValidationRHI::ValidateDispatchIndirectArgsBuffer(ArgumentBuffer, ArgumentOffset);
1308 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::IndirectArgs);
1309 Tracker->Assert(ArgumentBuffer->GetWholeResourceIdentity(), ERHIAccess::SRVCompute);
1310
1311 SBT->ValidateStateForDispatch(Tracker);
1312 RHIContext->RHIRayTraceDispatchIndirect(RayTracingPipelineState, RayGenShader, SBT, GlobalResourceBindings, ArgumentBuffer, ArgumentOffset);
1313 }
1314
1316 {
1317 SBT->SetBindingsOnShaderBindingTable(Pipeline, NumBindings, Bindings, BindingType);
1318 RHIContext->RHISetBindingsOnShaderBindingTable(SBT, Pipeline, NumBindings, Bindings, BindingType);
1319 }
1320
1321 void ValidateDispatch();
1322 void ValidateDrawing();
1323
1324 IRHICommandContext* RHIContext = nullptr;
1325
1327 {
1329 PlatformContext->WrappingContext = this;
1330 PlatformContext->Tracker = &State.TrackerInstance;
1331 }
1332
1333protected:
1334 struct FState
1335 {
1336 RHIValidation::FTracker TrackerInstance{ ERHIPipeline::Graphics };
1337 RHIValidation::FStaticUniformBuffers StaticUniformBuffers;
1338 RHIValidation::FBoundUniformBuffers BoundUniformBuffers;
1339
1340 FRHIRenderPassInfo RenderPassInfo;
1341 FString RenderPassName;
1342 FString PreviousRenderPassName;
1343 FString ComputePassName;
1344
1346
1347 bool bGfxPSOSet{};
1349
1350 void Reset();
1351 } State;
1352
1353 friend class FValidationRHI;
1354
1355private:
1357 {
1358 FRHIRenderPassInfo::FDepthStencilEntry& DSV = State.RenderPassInfo.DepthStencilRenderTarget;
1359
1360 // assert depth is in the correct mode
1361 if (DSMode.IsUsingDepth())
1362 {
1363 checkf(DSV.ExclusiveDepthStencil.IsUsingDepth(), TEXT("Graphics PSO is using depth but it's not enabled on the RenderPass."));
1364 checkf(DSMode.IsDepthRead() || DSV.ExclusiveDepthStencil.IsDepthWrite(), TEXT("Graphics PSO is writing to depth but RenderPass depth is ReadOnly."));
1365 }
1366
1367 // assert stencil is in the correct mode
1368 if (DSMode.IsUsingStencil())
1369 {
1370 checkf(DSV.ExclusiveDepthStencil.IsUsingStencil(), TEXT("Graphics PSO is using stencil but it's not enabled on the RenderPass."));
1371 checkf(DSMode.IsStencilRead() || DSV.ExclusiveDepthStencil.IsStencilWrite(), TEXT("Graphics PSO is writing to stencil but RenderPass stencil is ReadOnly."));
1372 }
1373 }
1374};
1375
1376#endif // ENABLE_RHI_VALIDATION
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
constexpr bool EnumHasAnyFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:35
FInt32Vector3 FIntVector
Definition MathFwd.h:115
bool IsStencilFormat(EPixelFormat Format)
Definition PixelFormat.h:409
ERHIAccess
Definition RHIAccess.h:11
@ SRVGraphicsNonPixel
@ VertexOrIndexBuffer
ERayTracingBindingType
Definition RHICommandList.h:281
EShaderFrequency
Definition RHIDefinitions.h:202
@ SF_Compute
Definition RHIDefinitions.h:208
@ SF_NumFrequencies
Definition RHIDefinitions.h:216
@ SF_Amplification
Definition RHIDefinitions.h:205
@ SF_Vertex
Definition RHIDefinitions.h:203
@ SF_Mesh
Definition RHIDefinitions.h:204
@ SF_Geometry
Definition RHIDefinitions.h:207
@ SF_Pixel
Definition RHIDefinitions.h:206
@ MaxSimultaneousRenderTargets
Definition RHIDefinitions.h:287
uint8 FUniformBufferStaticSlot
Definition RHIDefinitions.h:722
EVRSRateCombiner
Definition RHIDefinitions.h:873
bool IsValidGraphicsFrequency(EShaderFrequency InShaderFrequency)
Definition RHIDefinitions.h:228
EAsyncComputeBudget
Definition RHIDefinitions.h:1317
EVRSShadingRate
Definition RHIDefinitions.h:860
FRHIGlobals GRHIGlobals
Definition RHIGlobals.cpp:6
#define GRHIVariableRateShadingImageFormat
Definition RHIGlobals.h:892
void ValidateShaderParameters(const TShaderRef< FShader > &Shader, const FShaderParametersMetadata *ParametersMetadata, const void *ParametersData)
Definition ShaderParameterStruct.h:125
uint32 Offset
Definition VulkanMemory.cpp:4033
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition RHIResources.h:409
Definition RHIResources.h:4572
Definition RHIResources.h:1581
Definition RHICommandList.h:455
Definition RHIResources.h:1078
Definition RHIResources.h:1018
Definition RHIResources.h:2387
Definition RHIResources.h:1058
Definition RHIResources.h:947
Definition RHIResources.h:1115
Definition RHIResources.h:3755
Definition RHIResources.h:984
Definition RHIResources.h:2444
Definition RHIResources.h:3863
Definition RHIResources.h:3919
Definition RHIResources.h:854
Definition RHIResources.h:3981
Definition RHIResources.h:2153
EPixelFormat GetFormat() const
Definition RHIResources.h:2341
Definition RHIResources.h:1232
Definition RHIResources.h:3294
Definition RHIResources.h:2515
Definition RHIContext.h:49
Definition RHIContext.h:693
virtual void RHIDrawIndexedIndirect(FRHIBuffer *IndexBufferRHI, FRHIBuffer *ArgumentsBufferRHI, int32 DrawArgumentsIndex, uint32 NumInstances)=0
virtual void RHINextSubpass()
Definition RHIContext.h:858
virtual void RHISetStereoViewport(float LeftMinX, float RightMinX, float LeftMinY, float RightMinY, float MinZ, float LeftMaxX, float RightMaxX, float LeftMaxY, float RightMaxY, float MaxZ)
Definition RHIContext.h:744
virtual void RHISetStreamSource(uint32 StreamIndex, FRHIBuffer *VertexBuffer, uint32 Offset)=0
virtual void RHIDrawIndexedPrimitive(FRHIBuffer *IndexBuffer, int32 BaseVertexIndex, uint32 FirstInstance, uint32 NumVertices, uint32 StartIndex, uint32 NumPrimitives, uint32 NumInstances)=0
virtual void RHIDrawPrimitiveIndirect(FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)=0
virtual void RHICommitShaderBindingTable(FRHIShaderBindingTable *SBT, FRHIBuffer *InlineBindingDataBuffer)
Definition RHIContext.h:876
virtual void RHICopyBufferRegion(FRHIBuffer *DestBuffer, uint64 DstOffset, FRHIBuffer *SourceBuffer, uint64 SrcOffset, uint64 NumBytes)=0
virtual void RHISetBlendFactor(const FLinearColor &BlendFactor)
Definition RHIContext.h:788
virtual void RHIBeginRenderQuery(FRHIRenderQuery *RenderQuery)=0
virtual void RHISetShaderUnbinds(FRHIGraphicsShader *Shader, TConstArrayView< FRHIShaderParameterUnbind > InUnbinds)
Definition RHIContext.h:781
virtual void RHIResummarizeHTile(FRHITexture *DepthTexture)
Definition RHIContext.h:717
virtual void RHIDispatchIndirectMeshShader(FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)
Definition RHIContext.h:821
virtual void RHIDispatchIndirectComputeShader(FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)=0
virtual void RHIEndRenderQuery(FRHIRenderQuery *RenderQuery)=0
virtual void RHISetBindingsOnShaderBindingTable(FRHIShaderBindingTable *SBT, FRHIRayTracingPipelineState *Pipeline, uint32 NumBindings, const FRayTracingLocalShaderBindings *Bindings, ERayTracingBindingType BindingType)
Definition RHIContext.h:871
virtual void RHIBeginParallelRenderPass(TSharedPtr< FRHIParallelRenderPassInfo > InInfo, const TCHAR *InName)
Definition RHIContext.h:844
virtual void RHIEndDrawingViewport(FRHIViewport *Viewport, bool bPresent, bool bLockToVsync)=0
virtual void RHIDrawIndexedPrimitiveIndirect(FRHIBuffer *IndexBuffer, FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)=0
virtual void RHISetDepthBounds(float MinDepth, float MaxDepth)=0
virtual void RHISetShadingRate(EVRSShadingRate ShadingRate, EVRSRateCombiner Combiner)
Definition RHIContext.h:839
virtual void RHIEndRenderPass()=0
virtual void RHIDispatchMeshShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ)
Definition RHIContext.h:816
virtual void RHIEndParallelRenderPass()
Definition RHIContext.h:849
virtual void RHIClearShaderBindingTable(FRHIShaderBindingTable *SBT)
Definition RHIContext.h:866
virtual void RHIBeginRenderPass(const FRHIRenderPassInfo &InInfo, const TCHAR *InName)=0
virtual void RHISetGraphicsPipelineState(FRHIGraphicsPipelineState *GraphicsState, uint32 StencilRef, bool bApplyAdditionalState)=0
virtual void RHIDrawPrimitive(uint32 BaseVertexIndex, uint32 NumPrimitives, uint32 NumInstances)=0
virtual void RHISetViewport(float MinX, float MinY, float MinZ, float MaxX, float MaxY, float MaxZ)=0
virtual void RHIMultiDrawIndexedPrimitiveIndirect(FRHIBuffer *IndexBuffer, FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset, FRHIBuffer *CountBuffer, uint32 CountBuffeOffset, uint32 MaxDrawArguments)
Definition RHIContext.h:811
virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ)=0
virtual void RHISetScissorRect(bool bEnable, uint32 MinX, uint32 MinY, uint32 MaxX, uint32 MaxY)=0
virtual void RHISetMultipleViewports(uint32 Count, const FViewportBounds *Data)=0
virtual void RHICopyTexture(FRHITexture *SourceTexture, FRHITexture *DestTexture, const FRHICopyTextureInfo &CopyInfo)=0
virtual void RHISetStencilRef(uint32 StencilRef)
Definition RHIContext.h:786
virtual void RHISetShaderParameters(FRHIGraphicsShader *Shader, TConstArrayView< uint8 > InParametersData, TConstArrayView< FRHIShaderParameter > InParameters, TConstArrayView< FRHIShaderParameterResource > InResourceParameters, TConstArrayView< FRHIShaderParameterResource > InBindlessParameters)=0
Definition RHIContext.h:257
virtual void RHISetStaticUniformBuffer(FUniformBufferStaticSlot Slot, FRHIUniformBuffer *UniformBuffer)=0
virtual void RHIDispatchComputeShaderBundle(FRHIShaderBundle *ShaderBundle, FRHIBuffer *RecordArgBuffer, TConstArrayView< FRHIShaderParameterResource > SharedBindlessParameters, TConstArrayView< FRHIShaderBundleComputeDispatch > Dispatches, bool bEmulated)
Definition RHIContext.h:322
virtual void RHIBeginUAVOverlap()
Definition RHIContext.h:337
virtual void RHISetStaticUniformBuffers(const FUniformBufferStaticBindings &InUniformBuffers)=0
IRHIComputeContext & GetLowestLevelContext()
Definition RHIContext.h:506
virtual void RHISetShaderUnbinds(FRHIComputeShader *ComputeShader, TConstArrayView< FRHIShaderParameterUnbind > InUnbinds)
Definition RHIContext.h:357
virtual void RHIClearUAVFloat(FRHIUnorderedAccessView *UnorderedAccessViewRHI, const FVector4f &Values)=0
virtual void RHIEndUAVOverlap()
Definition RHIContext.h:338
virtual void RHIBuildAccelerationStructures(TConstArrayView< FRayTracingGeometryBuildParams > Params, const FRHIBufferRange &ScratchBufferRange)
Definition RHIContext.h:476
void SetTrackedAccess(const FRHITrackedAccessInfo &Info)
Definition RHIContext.h:516
virtual void RHIEndTransitions(TArrayView< const FRHITransition * > Transitions)=0
virtual void RHISetUniformBufferDynamicOffset(FUniformBufferStaticSlot Slot, uint32 Offset)
Definition RHIContext.h:366
virtual FRHIGPUMask RHIGetGPUMask() const
Definition RHIContext.h:402
virtual void RHIBeginTransitions(TArrayView< const FRHITransition * > Transitions)=0
virtual void RHISetGPUMask(FRHIGPUMask GPUMask)
Definition RHIContext.h:397
virtual void RHISetShaderParameters(FRHIComputeShader *ComputeShader, TConstArrayView< uint8 > InParametersData, TConstArrayView< FRHIShaderParameter > InParameters, TConstArrayView< FRHIShaderParameterResource > InResourceParameters, TConstArrayView< FRHIShaderParameterResource > InBindlessParameters)=0
virtual void RHIBindAccelerationStructureMemory(FRHIRayTracingScene *Scene, FRHIBuffer *Buffer, uint32 BufferOffset)
Definition RHIContext.h:486
virtual void RHIDispatchGraphicsShaderBundle(FRHIShaderBundle *ShaderBundle, FRHIBuffer *RecordArgBuffer, const FRHIShaderBundleGraphicsState &BundleState, TConstArrayView< FRHIShaderParameterResource > SharedBindlessParameters, TConstArrayView< FRHIShaderBundleGraphicsDispatch > Dispatches, bool bEmulated)
Definition RHIContext.h:329
virtual void RHICopyToStagingBuffer(FRHIBuffer *SourceBufferRHI, FRHIStagingBuffer *DestinationStagingBufferRHI, uint32 InOffset, uint32 InNumBytes)
Definition RHIContext.h:383
virtual void RHIExecuteMultiIndirectClusterOperation(const FRayTracingClusterOperationParams &Params)
Definition RHIContext.h:471
virtual void RHIRayTraceDispatchIndirect(FRHIRayTracingPipelineState *RayTracingPipelineState, FRHIRayTracingShader *RayGenShader, FRHIShaderBindingTable *SBT, const FRayTracingShaderBindings &GlobalResourceBindings, FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)
Definition RHIContext.h:279
virtual void RHISetAsyncComputeBudget(EAsyncComputeBudget Budget)
Definition RHIContext.h:288
virtual void SetExecutingCommandList(FRHICommandListBase *InCmdList)
Definition RHIContext.h:550
virtual void RHISetComputePipelineState(FRHIComputePipelineState *ComputePipelineState)=0
virtual void RHIWriteGPUFence(FRHIGPUFence *FenceRHI)
Definition RHIContext.h:392
virtual void RHIDispatchIndirectComputeShader(FRHIBuffer *ArgumentBuffer, uint32 ArgumentOffset)=0
virtual void RHIClearUAVUint(FRHIUnorderedAccessView *UnorderedAccessViewRHI, const FUintVector4 &Values)=0
virtual void RHIRayTraceDispatch(FRHIRayTracingPipelineState *RayTracingPipelineState, FRHIRayTracingShader *RayGenShader, FRHIShaderBindingTable *SBT, const FRayTracingShaderBindings &GlobalResourceBindings, uint32 Width, uint32 Height)
Definition RHIContext.h:272
virtual void RHISetShaderRootConstants(const FUint32Vector4 &Constants)
Definition RHIContext.h:317
virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ)=0
virtual void * RHIGetNativeCommandBuffer()
Definition RHIContext.h:534
Definition ArrayView.h:139
Definition SharedPointer.h:692
Type
Definition PawnAction_Move.h:11
void Dispatch(FRHIComputeCommandList &RHICmdList, const TShaderRef< TShaderClass > &ComputeShader, const FShaderParametersMetadata *ParametersMetadata, const typename TShaderClass::FParameters &Parameters, FIntVector GroupCount)
Definition RenderGraphUtils.h:491
int32 P[512]
Definition FieldSystemNoiseAlgo.cpp:11
FUniformParams Params
Definition MeshPaintVirtualTexture.cpp:162
EType
Definition AccessDetection.h:11
State
Definition PacketHandler.h:88
Definition Color.h:48
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119
Definition RHICommandList.h:212
Definition RHICommandList.h:183
Definition RHI.h:572
Definition MultiGPU.h:33
bool RequiresSharedBindlessParameters
Definition RHIGlobals.h:630
struct FRHIGlobals::FShaderBundles ShaderBundles
Definition RHIResources.h:5250
Definition RHIResources.h:5260
Definition RHIResources.h:5248
Definition RHIShaderParameters.h:398
Definition RHIShaderParameters.h:428
Definition RHIShaderParameters.h:414
Definition RHIResources.h:1689
Definition RHITransition.h:450
Definition RHITransition.h:475
Definition RHIContext.h:643
Definition RHIContext.h:590
Definition RHIResources.h:3496
Definition RHIResources.h:3463
Definition RHICommandList.h:267
Definition RHIContext.h:600
Definition RHICommandList.h:248
Definition RHI.h:507