UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ShaderPreprocessTypes.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Containers/Array.h"
9#include "ShaderCore.h"
10#include "ShaderSource.h"
11
15
18
19/*
20* Helper class used to remap compiler diagnostic messages from stripped preprocessed source (i.e. source with all whitespace normalized
21* and comments and line directives removed) back to line numbers/locations from the original source.
22*/
24{
25private:
26 void Remap(FShaderCompilerError& Diagnostic) const;
27
29 void AddSourceBlock(int32 OriginalLineNum, int32 StrippedLineNum)
30 {
31 AddSourceBlock(OriginalLineNum, StrippedLineNum, FString());
32 }
33 void AddSourceBlock(int32 OriginalLineNum, int32 StrippedLineNum, FString&& OriginalPath);
34 void AddStrippedLine(int32 StrippedLineNum, int32 Offset);
35 void Shrink();
36
37 struct FRemapData
38 {
39 const FString& Filename;
40 int32 LineNumber = INDEX_NONE;
41
42 bool IsValid() { return LineNumber != INDEX_NONE; }
43 };
44 FRemapData GetRemapData(int32 StrippedLineNum) const;
45
46 struct FSourceBlock
47 {
48 // Line number of the first line of code in the stripped preprocessed source for this block
49 int32 StrippedLineNum;
50
51 // Associated line number of where the first line of code in the block occurred in the unstripped source
52 int32 OriginalLineNum;
53
54 // Full path associated with this block in the original unstripped source (as given by line directive)
55 FString OriginalPath;
56 };
58 TArray<int32> StrippedLineOffsets;
59};
60
62
64{
65public:
69
71 {
72 return PreprocessedSource.GetView();
73 }
74
76 {
77 return PreprocessedSource.GetView();
78 }
79
81 {
82 if (WideSource.IsEmpty())
83 {
84 WideSource = FString(PreprocessedSource.GetView());
85 }
86 return FStringView(WideSource);
87 }
88
90 {
91 // if the unstripped source is requested, check if the "original source" field has been populated
92 // if not then stripping hasn't occurred so there's only one preprocessed source; return it
93
94 // convert and store wide versions of requested source if view is requested.
95 // this is only used in debug paths (debug output and viewing source in-editor)
96 // and the job should be freed shortly after, so the memory overhead is not a concern
97 if (OriginalPreprocessedSource.IsEmpty())
98 {
99 if (WideSource.IsEmpty())
100 {
101 WideSource = FString(PreprocessedSource.GetView());
102 }
103 return FStringView(WideSource);
104 }
105 else
106 {
107 if (WideSourceUnstripped.IsEmpty())
108 {
109 WideSourceUnstripped = FString(OriginalPreprocessedSource.GetView());
110 }
111 return FStringView(WideSourceUnstripped);
112 }
113 }
114
116 {
117 return PreprocessedSource;
118 }
119
120 inline void ForEachLine(TFunction<void(FAnsiStringView Line, int32 LineIndex)> Callback) const
121 {
123 int32 EndIndex = 0, LineIndex = 0, StartIndex = 0;
124 while (StartIndex < Source.Len())
125 {
126 EndIndex = Source.Find(ANSITEXTVIEW("\n"), StartIndex);
127 if (EndIndex == INDEX_NONE)
128 {
129 EndIndex = Source.Len();
130 }
131 FAnsiStringView Line(Source.GetData() + StartIndex, EndIndex - StartIndex);
132 StartIndex = EndIndex + 1;
133 Callback(Line, LineIndex++);
134 }
135 }
136
137 inline bool HasDirective(const FString& Directive) const
138 {
139 const int32 NumberOfDirectives = PragmaDirectives.Num();
140 for (int32 i = 0; i < NumberOfDirectives; i++)
141 {
142 const FString& CurrentDirective = PragmaDirectives[i];
143 if (CurrentDirective.Equals(Directive))
144 {
145 return true;
146 }
147 }
148 return false;
149 }
150
151 inline void VisitDirectives(TFunction<void(const FString*)> Action) const
152 {
153 const int32 NumberOfDirectives = PragmaDirectives.Num();
154 for (int32 i = 0; i < NumberOfDirectives; i++)
155 {
156 const FString& CurrentDirective = PragmaDirectives[i];
157 Action(&CurrentDirective);
158 }
159 }
160
161 inline void VisitDirectivesWithPrefix(const TCHAR* Prefix, TFunction<void(const FString*)> Action) const
162 {
163 const int32 NumberOfDirectives = PragmaDirectives.Num();
164 for (int32 i = 0; i < NumberOfDirectives; i++)
165 {
166 const FString& CurrentDirective = PragmaDirectives[i];
167 if (CurrentDirective.StartsWith(Prefix))
168 {
169 Action(&CurrentDirective);
170 }
171 }
172 }
173
174 inline void AddDirective(FString&& Directive)
175 {
176 PragmaDirectives.Add(Directive);
177 }
178
179 // Temporary helper for preprocessor wrapper function. Can be deprecated when
180 // all backends move to independent preprocessing.
182 {
183 for (FString& Directive : PragmaDirectives)
184 {
186 }
187 }
188
189 inline bool IsSecondary() const
190 {
191 return bIsSecondary;
192 }
193
194 inline bool GetSucceeded() const
195 {
196 return bSucceeded;
197 }
198
199 inline void LogError(FString&& Message)
200 {
203 }
204
205 inline void LogError(FString&& FilePath, FString&& Message, FString&& LineNumberStr)
206 {
209 CompilerError.ErrorLineString = LineNumberStr;
210 CompilerError.StrippedErrorMessage = Message;
211 }
212
213 inline void LogError(FString&& FilePath, FString&& Message, int32 LineNumber)
214 {
215 FString LineNumberStr = LexToString(LineNumber);
216 LogError(MoveTemp(FilePath), MoveTemp(Message), MoveTemp(LineNumberStr));
217 }
218
220 {
221 return Errors;
222 }
223
225 {
226 return MakeArrayView(Errors);
227 }
228
229 double GetPreprocessTime() const
230 {
231 return PreprocessTime;
232 }
233
235 {
236 return ShaderDiagnosticDatas;
237 }
238
240 {
241 return ShaderDiagnosticDatas;
242 }
243
244 friend FArchive& operator<<(FArchive& Ar, FShaderPreprocessOutput& PreprocessOutput);
245
246private:
247
249 friend class FShaderCompileJob;
250
251 // Strips comments/whitespace/line directives from the preprocessed source, replacing the contents of PreprocessedSource
252 // and saving the original source in the OriginalPreprocessedSource member
253 void StripCode(bool bCopyOriginalPreprocessdSource);
254
255 void CompressCode()
256 {
257 PreprocessedSource.Compress();
258 OriginalPreprocessedSource.Compress();
259 }
260
261 void DecompressCode()
262 {
263 PreprocessedSource.Decompress();
264 OriginalPreprocessedSource.Decompress();
265 }
266
267 void RemapErrors(FShaderCompilerOutput& Output) const;
268
269 // Output of preprocessing; should be set by IShaderFormat::PreprocessShader
270 FShaderSource PreprocessedSource;
271
272 // Set by Finalize; original preprocessed source as set by IShaderFormat::PreprocessShader
273 FShaderSource OriginalPreprocessedSource;
274
275 // Set when GetSourceViewWide or GetUnstrippedSourceView accessors are called
276 // Mutable so we can maintain const correctness in the API otherwise.
277 mutable FString WideSource;
278 mutable FString WideSourceUnstripped;
279
280 // Array of errors encountered in preprocessing; should be populated by IShaderFormat::PreprocessShader
282
283 // Array of "UESHADERMETADATA" pragmas encountered by preprocessing; set automatically by core preprocessing
284 // and expected to be queried by IShaderFormat
285 TArray<FString> PragmaDirectives;
287
288 double PreprocessTime = 0.0;
289 bool bSucceeded = false;
290 bool bIsSecondary = false;
291
292 TArray<FShaderDiagnosticData> ShaderDiagnosticDatas;
293};
constexpr auto MakeArrayView(OtherRangeType &&Other)
Definition ArrayView.h:873
@ INDEX_NONE
Definition CoreMiscDefines.h:150
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
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const TCHAR * LexToString(EAnalyticsRecordEventMode Mode)
Definition IAnalyticsProvider.cpp:5
UE_FORCEINLINE_HINT bool IsValid(const UObject *Test)
Definition Object.h:1875
RENDERCORE_API FStringView GetShaderSourceDebugHashPrefixWide()
Definition ShaderPreprocessTypes.cpp:75
RENDERCORE_API FShaderSource::FViewType GetShaderSourceDebugHashPrefix()
Definition ShaderPreprocessTypes.cpp:70
TStringView< TCHAR > FStringView
Definition StringFwd.h:45
#define ANSITEXTVIEW(str)
Definition StringView.h:555
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Offset
Definition VulkanMemory.cpp:4033
Definition Archive.h:1208
Definition ShaderCore.cpp:1801
Definition ShaderCompilerJobTypes.h:331
Definition ShaderPreprocessTypes.h:64
FStringView GetUnstrippedSourceView() const
Definition ShaderPreprocessTypes.h:89
bool IsSecondary() const
Definition ShaderPreprocessTypes.h:189
FAnsiStringView GetSourceViewAnsi() const
Definition ShaderPreprocessTypes.h:75
TArray< FShaderCompilerError > & EditErrors()
Definition ShaderPreprocessTypes.h:219
void VisitDirectives(TFunction< void(const FString *)> Action) const
Definition ShaderPreprocessTypes.h:151
void LogError(FString &&FilePath, FString &&Message, FString &&LineNumberStr)
Definition ShaderPreprocessTypes.h:205
TConstArrayView< FShaderCompilerError > GetErrors() const
Definition ShaderPreprocessTypes.h:224
FShaderPreprocessOutput()
Definition ShaderPreprocessTypes.h:66
friend FArchive & operator<<(FArchive &Ar, FShaderPreprocessOutput &PreprocessOutput)
Definition ShaderPreprocessTypes.cpp:394
TArray< FShaderDiagnosticData > & EditDiagnosticDatas()
Definition ShaderPreprocessTypes.h:234
FShaderSource & EditSource()
Definition ShaderPreprocessTypes.h:115
FShaderSource::FViewType GetSourceView() const
Definition ShaderPreprocessTypes.h:70
bool HasDirective(const FString &Directive) const
Definition ShaderPreprocessTypes.h:137
void VisitDirectivesWithPrefix(const TCHAR *Prefix, TFunction< void(const FString *)> Action) const
Definition ShaderPreprocessTypes.h:161
void LogError(FString &&Message)
Definition ShaderPreprocessTypes.h:199
void AddDirective(FString &&Directive)
Definition ShaderPreprocessTypes.h:174
double GetPreprocessTime() const
Definition ShaderPreprocessTypes.h:229
FStringView GetSourceViewWide() const
Definition ShaderPreprocessTypes.h:80
void ForEachLine(TFunction< void(FAnsiStringView Line, int32 LineIndex)> Callback) const
Definition ShaderPreprocessTypes.h:120
void LogError(FString &&FilePath, FString &&Message, int32 LineNumber)
Definition ShaderPreprocessTypes.h:213
bool GetSucceeded() const
Definition ShaderPreprocessTypes.h:194
void MoveDirectives(TArray< FString > &OutDirectives)
Definition ShaderPreprocessTypes.h:181
const TArray< FShaderDiagnosticData > & GetDiagnosticDatas() const
Definition ShaderPreprocessTypes.h:239
Definition ShaderSource.h:19
RENDERCORE_API void Decompress()
Definition ShaderSource.cpp:76
RENDERCORE_API void Compress()
Definition ShaderSource.cpp:48
bool IsEmpty() const
Definition ShaderSource.h:109
FViewType GetView() const
Definition ShaderSource.h:91
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
ElementType & AddDefaulted_GetRef() UE_LIFETIMEBOUND
Definition Array.h:2815
Definition AndroidPlatformMisc.h:14
Definition ShaderCore.h:544
Definition ShaderCompilerCore.h:411
FString StrippedErrorMessage
Definition ShaderCompilerCore.h:446
FString ErrorVirtualFilePath
Definition ShaderCompilerCore.h:444
Definition ShaderCompilerCore.h:210
Definition ShaderCompilerCore.h:491
Definition ShaderPreprocessTypes.h:24