UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MeshDrawShaderBindings.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 MeshDrawShaderBindings.h:
5=============================================================================*/
6
7#pragma once
8
9#include "Shader.h"
10
11// Whether to assert when mesh command shader bindings were not set by the pass processor.
12// Enabled by default in debug
13#define VALIDATE_MESH_COMMAND_BINDINGS DO_GUARD_SLOW
14
17{
18protected:
20
21public:
22
28
29#if DO_GUARD_SLOW
31 {
32 return ParameterMapInfo;
33 }
34#endif
35
37 {
38 // Since 4.25, FShader (the owner of this memory) is no longer shared across the shadermaps and gets deleted at the same time as the owning shadermap.
39 // To prevent crashes when a singe mesh draw command is shared across multiple MICs with compatible shaders, consider shader bindings belonging to different FShaders different.
40 return &ParameterMapInfo == &Rhs.ParameterMapInfo;
41 }
42
44 {
45 uint32 DataSize = 0;
46 for (const FShaderLooseParameterBufferInfo& Info : ParameterMapInfo.LooseParameterBuffers)
47 {
48 DataSize += Info.Size;
49 }
50 return DataSize;
51 }
52
53 inline uint32 GetDataSizeBytes() const
54 {
55 uint32 DataSize = sizeof(void*) *
56 (ParameterMapInfo.UniformBuffers.Num()
57 + ParameterMapInfo.TextureSamplers.Num()
58 + ParameterMapInfo.SRVs.Num());
59
60 // Allocate a bit for each SRV tracking whether it is a FRHITexture* or FRHIShaderResourceView*
62
64
65 // Align to pointer size so subsequent packed shader bindings will have their pointers aligned
66 return Align(DataSize, sizeof(void*));
67 }
68
69protected:
70
71 // Note: pointers first in layout, so they stay aligned
73 {
74 return 0;
75 }
76
77 inline uint32 GetSamplerOffset() const
78 {
79 return ParameterMapInfo.UniformBuffers.Num() * sizeof(FRHIUniformBuffer*);
80 }
81
82 inline uint32 GetSRVOffset() const
83 {
84 return GetSamplerOffset()
85 + ParameterMapInfo.TextureSamplers.Num() * sizeof(FRHISamplerState*);
86 }
87
88 inline uint32 GetSRVTypeOffset() const
89 {
90 return GetSRVOffset()
91 + ParameterMapInfo.SRVs.Num() * sizeof(FRHIShaderResourceView*);
92 }
93
95 {
96 return GetSRVTypeOffset()
98 }
99
101};
102
104{
106public:
112
113 template<typename UniformBufferStructType>
115 {
116 checkfSlow(Parameter.IsInitialized(), TEXT("Parameter was not serialized"));
117
118 if (Parameter.IsBound())
119 {
120 checkf(Value.GetReference(), TEXT("Attempted to set null uniform buffer for type %s"), UniformBufferStructType::FTypeInfo::GetStructMetadata()->GetStructTypeName());
121 WriteBindingUniformBuffer(Value.GetReference(), Parameter.GetBaseIndex());
122 }
123 }
124
125 template<typename UniformBufferStructType>
127 {
128 checkfSlow(Parameter.IsInitialized(), TEXT("Parameter was not serialized"));
129
130 if (Parameter.IsBound())
131 {
132 checkf(Value.GetUniformBufferRHI(), TEXT("Attempted to set null uniform buffer for type %s"), UniformBufferStructType::FTypeInfo::GetStructMetadata()->GetStructTypeName());
133 WriteBindingUniformBuffer(Value.GetUniformBufferRHI(), Parameter.GetBaseIndex());
134 }
135 }
136
138 {
139 checkfSlow(Parameter.IsInitialized(), TEXT("Parameter was not serialized"));
140
141 if (Parameter.IsBound())
142 {
143 checkf(Value, TEXT("Attempted to set null uniform buffer"));
144 WriteBindingUniformBuffer(Value, Parameter.GetBaseIndex());
145 }
146 }
147
149 {
150 checkfSlow(Parameter.IsInitialized(), TEXT("Parameter was not serialized"));
151
152 if (Parameter.IsBound())
153 {
154 checkf(Value, TEXT("Attempted to set null SRV on slot %u"), Parameter.GetBaseIndex());
155 WriteBindingSRV(Value, Parameter.GetBaseIndex());
156 }
157 }
158
160 {
161 checkfSlow(SamplerParameter.IsInitialized(), TEXT("Parameter was not serialized"));
162
163 if (SamplerParameter.IsBound())
164 {
165 checkf(SamplerStateRHI, TEXT("Attempted to set null Sampler on slot %u"), SamplerParameter.GetBaseIndex());
166 WriteBindingSampler(SamplerStateRHI, SamplerParameter.GetBaseIndex());
167 }
168 }
169
170 void Add(FShaderResourceParameter TextureParameter, FRHITexture* TextureRHI)
171 {
172 checkfSlow(TextureParameter.IsInitialized(), TEXT("Parameter was not serialized"));
173
174 if (TextureParameter.IsBound())
175 {
176 checkf(TextureRHI, TEXT("Attempted to set null Texture on slot %u"), TextureParameter.GetBaseIndex());
177 WriteBindingTexture(TextureRHI, TextureParameter.GetBaseIndex());
178 }
179 }
180
182 FShaderResourceParameter TextureParameter,
184 FRHISamplerState* SamplerStateRHI,
185 FRHITexture* TextureRHI)
186 {
187 Add(TextureParameter, TextureRHI);
188 Add(SamplerParameter, SamplerStateRHI);
189 }
190
191 template<class ParameterType>
192 void Add(FShaderParameter Parameter, const ParameterType& Value)
193 {
194 static_assert(!TIsUECoreVariant<ParameterType, double>::Value, "FMeshDrawSingleShaderBindings cannot Add double core variants! Switch to float variant.");
195 static_assert(!TIsUECoreVariant<typename std::remove_pointer<typename TDecay<ParameterType>::Type>::type, double>::Value, "FMeshDrawSingleShaderBindings cannot Add double core variants! Switch to float variant.");
196 static_assert(!TIsPointer<ParameterType>::Value, "Passing by pointer is not valid.");
197 checkfSlow(Parameter.IsInitialized(), TEXT("Parameter was not serialized"));
198
199 if (Parameter.IsBound())
200 {
201 bool bFoundParameter = false;
202 uint8* LooseDataOffset = GetLooseDataStart();
203
206 {
208
209 if (LooseParameterBuffer.BaseIndex == Parameter.GetBufferIndex())
210 {
213 {
215
216 if (Parameter.GetBaseIndex() == LooseParameter.BaseIndex)
217 {
218 checkSlow(Parameter.GetNumBytes() == LooseParameter.Size);
219 ensureMsgf(sizeof(ParameterType) == Parameter.GetNumBytes(), TEXT("Attempted to set fewer bytes than the shader required. Setting %" SIZE_T_FMT " bytes on loose parameter at BaseIndex %u, Size %u. This can cause GPU hangs, depending on usage."), sizeof(ParameterType), Parameter.GetBaseIndex(), Parameter.GetNumBytes());
220 const int32 NumBytesToSet = FMath::Min<int32>(sizeof(ParameterType), Parameter.GetNumBytes());
222 const int32 NumBytesToClear = FMath::Min<int32>(0, Parameter.GetNumBytes() - NumBytesToSet);
224 bFoundParameter = true;
225 break;
226 }
227
229 }
230 break;
231 }
232
234 }
235
236 checkfSlow(bFoundParameter, TEXT("Attempted to set loose parameter at BaseIndex %u, Size %u which was never in the shader's parameter map."), Parameter.GetBaseIndex(), Parameter.GetNumBytes());
237 }
238 }
239
240private:
241 uint8* Data;
242
243 inline const FRHIUniformBuffer** GetUniformBufferStart() const
244 {
245 return (const FRHIUniformBuffer**)(Data + GetUniformBufferOffset());
246 }
247
248 inline FRHISamplerState** GetSamplerStart() const
249 {
252 }
253
254 inline FRHIResource** GetSRVStart() const
255 {
257 checkfSlow(Align(*SRVDataStart, sizeof(void*)) == *SRVDataStart, TEXT("FMeshDrawSingleShaderBindings should have been laid out so that stored pointers are aligned"));
258 return (FRHIResource**)SRVDataStart;
259 }
260
261 inline uint8* GetSRVTypeStart() const
262 {
264 return SRVTypeDataStart;
265 }
266
267 inline uint8* GetLooseDataStart() const
268 {
270 return LooseDataStart;
271 }
272
273 template<typename ElementType>
274 inline int FindSortedArrayBaseIndex(const TConstArrayView<ElementType>& Array, uint32 BaseIndex)
275 {
276 int Index = 0;
277 int Size = Array.Num();
278
279 //start with binary search for larger lists
280 while (Size > 8)
281 {
282 const int LeftoverSize = Size % 2;
283 Size = Size / 2;
284
285 const int CheckIndex = Index + Size;
286 const int IndexIfLess = CheckIndex + LeftoverSize;
287
288 Index = Array[CheckIndex].BaseIndex < BaseIndex ? IndexIfLess : Index;
289 }
290
291 //small size array optimization
292 const int ArrayEnd = FMath::Min(Index + Size + 1, Array.Num());
293 while (Index < ArrayEnd)
294 {
295 if (Array[Index].BaseIndex == BaseIndex)
296 {
297 return Index;
298 }
299 Index++;
300 }
301
302 return -1;
303 }
304
305 inline void WriteBindingUniformBuffer(const FRHIUniformBuffer* Value, uint32 BaseIndex)
306 {
307 int32 FoundIndex = FindSortedArrayBaseIndex(MakeArrayView(ParameterMapInfo.UniformBuffers), BaseIndex);
308 if (FoundIndex >= 0)
309 {
310 GetUniformBufferStart()[FoundIndex] = Value;
311 }
312
313 checkfSlow(FoundIndex >= 0, TEXT("Attempted to set a uniform buffer at BaseIndex %u which was never in the shader's parameter map."), BaseIndex);
314 }
315
316 inline void WriteBindingSampler(FRHISamplerState* Value, uint32 BaseIndex)
317 {
318 int32 FoundIndex = FindSortedArrayBaseIndex(MakeArrayView(ParameterMapInfo.TextureSamplers), BaseIndex);
319 if (FoundIndex >= 0)
320 {
321 GetSamplerStart()[FoundIndex] = Value;
322 }
323
324 checkfSlow(FoundIndex >= 0, TEXT("Attempted to set a texture sampler at BaseIndex %u which was never in the shader's parameter map."), BaseIndex);
325 }
326
327 inline void WriteBindingSRV(FRHIShaderResourceView* Value, uint32 BaseIndex)
328 {
329 int32 FoundIndex = FindSortedArrayBaseIndex(MakeArrayView(ParameterMapInfo.SRVs), BaseIndex);
330 if (FoundIndex >= 0)
331 {
332 uint32 TypeByteIndex = FoundIndex / 8;
333 uint32 TypeBitIndex = FoundIndex % 8;
334 GetSRVTypeStart()[TypeByteIndex] |= 1 << TypeBitIndex;
335 GetSRVStart()[FoundIndex] = Value;
336 }
337
338 checkfSlow(FoundIndex >= 0, TEXT("Attempted to set SRV at BaseIndex %u which was never in the shader's parameter map."), BaseIndex);
339 }
340
341 inline void WriteBindingTexture(FRHITexture* Value, uint32 BaseIndex)
342 {
343 int32 FoundIndex = FindSortedArrayBaseIndex(MakeArrayView(ParameterMapInfo.SRVs), BaseIndex);
344 if (FoundIndex >= 0)
345 {
346 GetSRVStart()[FoundIndex] = Value;
347 }
348
349 checkfSlow(FoundIndex >= 0, TEXT("Attempted to set Texture at BaseIndex %u which was never in the shader's parameter map."), BaseIndex);
350 }
351};
constexpr T Align(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:18
#define SIZE_T_FMT
Definition AndroidPlatformString.h:30
constexpr auto MakeArrayView(OtherRangeType &&Other)
Definition ArrayView.h:873
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkfSlow(expr, format,...)
Definition AssertionMacros.h:333
#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::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MeshDrawShaderBindings.h:17
uint32 GetSRVOffset() const
Definition MeshDrawShaderBindings.h:82
uint32 GetLooseDataOffset() const
Definition MeshDrawShaderBindings.h:94
uint32 GetDataSizeBytes() const
Definition MeshDrawShaderBindings.h:53
FMeshDrawShaderBindingsLayout(const TShaderRef< FShader > &Shader)
Definition MeshDrawShaderBindings.h:23
uint32 GetSRVTypeOffset() const
Definition MeshDrawShaderBindings.h:88
uint32 GetUniformBufferOffset() const
Definition MeshDrawShaderBindings.h:72
uint32 GetLooseDataSizeBytes() const
Definition MeshDrawShaderBindings.h:43
uint32 GetSamplerOffset() const
Definition MeshDrawShaderBindings.h:77
const FShaderParameterMapInfo & ParameterMapInfo
Definition MeshDrawShaderBindings.h:19
bool operator==(const FMeshDrawShaderBindingsLayout &Rhs) const
Definition MeshDrawShaderBindings.h:36
Definition MeshPassProcessor.h:908
Definition MeshDrawShaderBindings.h:104
void Add(FShaderResourceParameter TextureParameter, FRHITexture *TextureRHI)
Definition MeshDrawShaderBindings.h:170
void AddTexture(FShaderResourceParameter TextureParameter, FShaderResourceParameter SamplerParameter, FRHISamplerState *SamplerStateRHI, FRHITexture *TextureRHI)
Definition MeshDrawShaderBindings.h:181
void Add(FShaderParameter Parameter, const ParameterType &Value)
Definition MeshDrawShaderBindings.h:192
FMeshDrawSingleShaderBindings(const FMeshDrawShaderBindingsLayout &InLayout, uint8 *InData)
Definition MeshDrawShaderBindings.h:107
void Add(const TShaderUniformBufferParameter< UniformBufferStructType > &Parameter, const TUniformBuffer< UniformBufferStructType > &Value)
Definition MeshDrawShaderBindings.h:126
void Add(const FShaderUniformBufferParameter &Parameter, const FRHIUniformBuffer *Value)
Definition MeshDrawShaderBindings.h:137
void Add(FShaderResourceParameter Parameter, FRHIShaderResourceView *Value)
Definition MeshDrawShaderBindings.h:148
void Add(const TShaderUniformBufferParameter< UniformBufferStructType > &Parameter, const TUniformBufferRef< UniformBufferStructType > &Value)
Definition MeshDrawShaderBindings.h:114
void Add(FShaderResourceParameter SamplerParameter, FRHISamplerState *SamplerStateRHI)
Definition MeshDrawShaderBindings.h:159
Definition RHIResources.h:54
Definition RHIResources.h:671
Definition RHIResources.h:3304
Definition RHIResources.h:2153
Definition RHIResources.h:1232
Definition MeshPassProcessor.h:1119
Definition Shader.h:251
Definition Shader.h:216
Definition Shader.h:290
Definition ShaderParameters.h:56
Definition ShaderParameters.h:87
bool IsBound() const
Definition ShaderParameters.h:95
bool IsInitialized() const
Definition ShaderParameters.h:96
uint32 GetBaseIndex() const
Definition ShaderParameters.h:98
Definition ShaderParameters.h:109
Definition ArrayView.h:139
UE_FORCEINLINE_HINT constexpr SizeType Num() const
Definition ArrayView.h:380
Definition Shader.h:1021
Definition ShaderParameters.h:148
Definition ShaderParameterMacros.h:136
Definition UniformBuffer.h:29
GeometryCollection::Facades::FMuscleActivationData Data
Definition MuscleActivationConstraints.h:15
U16 Index
Definition radfft.cpp:71
static constexpr UE_FORCEINLINE_HINT T DivideAndRoundUp(T Dividend, T Divisor)
Definition UnrealMathUtility.h:694
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119
Definition IsPointer.h:12
Definition IsUECoreType.h:19