UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GenericPlatformDriver.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
7#include "Containers/Array.h"
10#include "Misc/DateTime.h"
11#include "Misc/Optional.h"
12#include "Misc/Parse.h"
13#include "Misc/ConfigCacheIni.h"
15
16// Represents a full driver version with multiple version numbers,
17// e.g. 30.0.13023.4001.
19{
20public:
21 FDriverVersion() = default;
22
27
28 void Parse(const FString& DriverVersionString)
29 {
30 Values.Empty();
33
36 {
38 }
40 }
41
42 bool operator>(const FDriverVersion& Other) const
43 {
44 for (int32 Idx = 0; Idx < Values.Num(); ++Idx)
45 {
46 if (Values[Idx] > Other.Values[Idx])
47 {
48 return true;
49 }
50 if (Values[Idx] < Other.Values[Idx])
51 {
52 return false;
53 }
54 }
55
56 return false;
57 }
58
59 bool operator==(const FDriverVersion& Other) const
60 {
61 return !(*this > Other) && !(Other > *this);
62 }
63 bool operator<(const FDriverVersion& Other) const
64 {
65 return Other > *this;
66 }
67 bool operator!=(const FDriverVersion& Other) const
68 {
69 return !(*this == Other);
70 }
71 bool operator>=(const FDriverVersion& Other) const
72 {
73 return (*this == Other) || (*this > Other);
74 }
75 bool operator<=(const FDriverVersion& Other) const
76 {
77 return (*this == Other) || (*this < Other);
78 }
79
80 // Index from the left (major version first).
82 {
83 return Values[Index];
84 }
85
87 {
88 return Values;
89 }
90
91private:
92 TArray<uint32> Values;
93};
94
99
100// Find the comparison operator in the input string, and advances the In pointer to point to the first character
101// after the comparison operator.
102// Defaults to Equal if no comparison operator is present.
104{
105 if (In[0] == '=' && In[1] == '=')
106 {
107 In += 2;
108 return ECO_Equal;
109 }
110 if (In[0] == '!' && In[1] == '=')
111 {
112 In += 2;
113 return ECO_NotEqual;
114 }
115 if (*In == '>')
116 {
117 ++In;
118 if (*In == '=')
119 {
120 ++In;
121 return ECO_GreaterOrEqual;
122 }
123 return ECO_Greater;
124 }
125 if (*In == '<')
126 {
127 ++In;
128 if (*In == '=')
129 {
130 ++In;
131 return ECO_LessOrEqual;
132 }
133 return ECO_Less;
134 }
135 return ECO_Equal;
136}
137
138// Compare two objects given the comparison operator.
139template <class T>
140bool CompareWithOp(const T& A, EComparisonOp Op, const T& B)
141{
142 switch (Op)
143 {
144 case ECO_Equal: return A == B;
145 case ECO_NotEqual: return A != B;
146 case ECO_Greater: return A > B;
147 case ECO_GreaterOrEqual: return A >= B;
148 case ECO_Less: return A < B;
149 case ECO_LessOrEqual: return A <= B;
150 }
151 check(0);
152 return false;
153}
154
156{
157 // Hardware vendor ID, e.g. 0x10DE for NVIDIA.
159
160 // Name of the graphics device, e.g. "NVIDIA GeForce GTX 680" or "AMD Radeon R9 200 / HD 7900 Series".
162
163 // Name of the hardware vendor, e.g. "NVIDIA" or "Advanced Micro Devices, Inc."
165
166 // Internal driver version, which may differ from the version shown to the user. Set to "Unknown" if the driver detection failed.
168
169 // User-facing driver version.
171
172 // Driver date as reported by the driver. Format is MM-DD-YYYY.
173 FString DriverDate;
174
175 // Current RHI.
176 FString RHIName;
177
178 bool IsValid() const
179 {
180 return !DeviceDescription.IsEmpty()
181 && VendorId
182 && (InternalDriverVersion != TEXT("Unknown")) // If driver detection code fails.
183 && (InternalDriverVersion != TEXT("")); // If running on a non-Windows platform we don't fill in the driver version.
184 }
185
186 void SetAMD() { VendorId = 0x1002; }
187 void SetIntel() { VendorId = 0x8086; }
188 void SetNVIDIA() { VendorId = 0x10DE; }
189 void SetQualcomm() { VendorId = 0x4D4F4351; }
190
191 bool IsAMD() const { return VendorId == 0x1002; }
192 bool IsIntel() const { return VendorId == 0x8086; }
193 bool IsNVIDIA() const { return VendorId == 0x10DE; }
194 bool IsQualcomm() const
195 {
196 // On Windows, the DXGI vendor ID is reported as 0x4D4F4351.
197 // On other platforms, it's 0x5143.
198 return VendorId == 0x5143 || VendorId == 0x4D4F4351;
199 }
200
202 {
203 if (IsIntel())
204 {
206
207 // https://www.intel.com/content/www/us/en/support/articles/000005654/graphics.html
208 // Version format changed in April 2018 starting with xx.xx.100.xxxx.
209 // In the unified driver version, that's the first value.
210 return (ThisVersion.GetVersionValue(0) >= 100) == (UnifiedDriverVersion.GetVersionValue(0) >= 100);
211 }
212
213 return true;
214 }
215
216 static FString GetNVIDIAUnifiedVersion(const FString& InternalVersion)
217 {
218 // Ignore the Windows/DirectX version by taking the last digits of the internal version
219 // and moving the version dot. Coincidentally, that's the user-facing string. For example:
220 // 9.18.13.4788 -> 3.4788 -> 347.88
221 if (InternalVersion.Len() < 6)
222 {
223 return InternalVersion;
224 }
225
226 FString RightPart = InternalVersion.Right(6);
227 RightPart = RightPart.Replace(TEXT("."), TEXT(""));
228 RightPart.InsertAt(3, TEXT("."));
229 return RightPart;
230 }
231
232 static FString GetIntelUnifiedVersion(const FString& InternalVersion)
233 {
234 // https://www.intel.com/content/www/us/en/support/articles/000005654/graphics.html
235 // Drop off the OS and DirectX version. For example:
236 // 27.20.100.8935 -> 100.8935
238 if (DotIndex != INDEX_NONE)
239 {
241 if (DotIndex != INDEX_NONE)
242 {
243 return InternalVersion.RightChop(DotIndex + 1);
244 }
245 }
246 return InternalVersion;
247 }
248
250 {
251 // We use the internal version as the base to avoid instability or changes to the user-facing driver versioning scheme,
252 // and we remove the parts of the version that identify unimportant factors like Windows or DirectX version.
253 const FString& FullVersion = InternalDriverVersion;
254
256 {
258 }
259 else if (IsIntel())
260 {
262 }
263 return FullVersion;
264 }
265};
266
267static FDateTime ParseMonthDayYearDate(const FString& DateString)
268{
269 FString Month, DayYear, Day, Year;
270 DateString.Split(TEXT("-"), &Month, &DayYear);
271 DayYear.Split(TEXT("-"), &Day, &Year);
273}
274
275// Represents an optional set of constraints that a driver configuration entry can include:
276// * The RHI being used (e.g. "D3D12" will result in the entry to be considered only when running in D3D12).
277// * The adapter name, using a regular expression (e.g. ".*RTX.*" will result in the entry to be considered only for cards that contain the string "RTX").
281
283
285 {
286 FString RHINameString;
287 FParse::Value(Entry, TEXT("RHI="), RHINameString);
288 if (!RHINameString.IsEmpty())
289 {
291 }
292
294 FParse::Value(Entry, TEXT("AdapterNameRegex="), AdapterNameRegexString);
295 if (!AdapterNameRegexString.IsEmpty())
296 {
298 }
299 }
300
302 {
304
306 {
307 if (*RHINameConstraint != Info.RHIName)
308 {
309 return false;
310 }
312 }
313
315 {
317 if (!Matcher.FindNext())
318 {
319 return false;
320 }
322 }
323
324 return true;
325 }
326
331};
332
333// This corresponds to one DriverDenyList entry in the Hardware.ini configuration file. One entry includes:
334// * The drivers being denylisted, specified through one of the following:
335// * A driver version, along with any comparison operator (e.g. "<473.47" would denylist any driver which version is less than 473.47). This uses the "unified" driver version (see FGPUDriverInfo::GetUnifiedDriverVersion).
336// * A driver date, along with any comparison operator (e.g. "<=10-31-2023" would denylist any driver which release date is on or before Oct. 31, 2023).
337// * A set of optional constraints that the denylist entry will consider when the driver is being tested (see FDriverConfigEntryConstraints).
338// * The reason for the driver(s) being denylisted, e.g.visual glitches, stability, or performance issues.
343
344 // Expected format is MM-DD-YYYY.
346 {
349 Entry.ComparisonOp = ParseComparisonOp(Chars);
350 Entry.Date = ParseMonthDayYearDate(FString(Chars));
351 return Entry;
352 }
353 };
354
368
370
373 {
374 FString DriverVersionString;
375 FParse::Value(Entry, TEXT("DriverVersion="), DriverVersionString);
376 if (!DriverVersionString.IsEmpty())
377 {
379 }
380
381 FString DriverDateString;
382 FParse::Value(Entry, TEXT("DriverDate="), DriverDateString);
383 if (!DriverDateString.IsEmpty())
384 {
386 }
387
388 ensureMsgf(IsValid(), TEXT("Exactly one of driver date or driver version must be specified in a driver denylist entry"));
389
390 FParse::Value(Entry, TEXT("Reason="), DenylistReason);
391 ensure(!DenylistReason.IsEmpty());
392 }
393
394 // Checks whether the given driver is denylisted by this entry, and also returns the number
395 // of constraints that have been satisfied in OutNumSatisfiedConstraints.
397 {
399
400 if (!IsValid())
401 {
402 return false;
403 }
404
405 // Check constraints first. Only apply the driver version/date check
406 // if all constraints are satisfied.
408 {
409 return false;
410 }
411
412 if (DriverVersion && Info.IsSameDriverVersionGeneration(DriverVersion->Version))
413 {
414 FDriverVersion CurrentDriverVersion(Info.GetUnifiedDriverVersion());
415 return CompareWithOp(CurrentDriverVersion, DriverVersion->ComparisonOp, DriverVersion->Version);
416 }
417
418 if (DriverDate)
419 {
420 FDateTime CurrentDriverDate = ParseMonthDayYearDate(Info.DriverDate);
421 return CompareWithOp(CurrentDriverDate, DriverDate->ComparisonOp, DriverDate->Date);
422 }
423
424 return false;
425 }
426
427 // Returns true whether this denylist entry will always apply to the latest drivers available,
428 // i.e. the comparison function is > or >=.
430 {
431 if (DriverVersion)
432 {
433 return DriverVersion->ComparisonOp == ECO_Greater || DriverVersion->ComparisonOp == ECO_GreaterOrEqual;
434 }
435 if (DriverDate)
436 {
437 return DriverDate->ComparisonOp == ECO_Greater || DriverDate->ComparisonOp == ECO_GreaterOrEqual;
438 }
439 return false;
440 }
441
442 bool IsValid() const
443 {
444 return DriverVersion.IsSet() != DriverDate.IsSet();
445 }
446
449
451};
452
453// This corresponds to one SuggestedDriverVersion entry in the Hardware.ini configuration file. One entry includes:
454// * The suggested driver version.
455// * A set of optional constraints (see FDriverConfigEntryConstraints).
457
461 {
462 // For backwards compatibility, accept either "DriverVersion=..." or
463 // just the version string without the structured format.
464 FParse::Value(Entry, TEXT("DriverVersion="), SuggestedDriverVersion);
465 if (SuggestedDriverVersion.IsEmpty() && !HasConstraints() && !FString(Entry).Contains(TEXT("=")))
466 {
468 }
469 }
470
471 // Checks whether this entry applies to the given driver info, and also returns the number
472 // of constraints that have been satisfied in OutNumSatisfiedConstraints.
477
478 bool IsValid()
479 {
480 return !SuggestedDriverVersion.IsEmpty();
481 }
482
484};
485
487{
488public:
490 : DriverInfo(InDriverInfo)
491 {
492 }
493
494 // Returns the best suggested driver version that matches the current configuration, if it exists.
499
500 // Finds the best driver denylist entry that matches the current driver and configuration, if it exists.
505
506private:
507 template <typename TEntryType>
508 TOptional<TEntryType> GetBestConfigEntry(const TCHAR* ConfigEntryName) const
509 {
510 const FString Section = GetVendorSectionName();
511
512 if (Section.IsEmpty())
513 {
514 return {};
515 }
516
517 // Multiple entries can match, but some entries may match on more
518 // constraints (e.g. both RHI and adapter name). Choose the entry
519 // that satisfies the most constraints.
521
524 for (const FString& EntryString : EntryStrings)
525 {
526 ensure(!EntryString.IsEmpty());
527 TEntryType Entry(*EntryString);
528
530 if (Entry.AppliesToDriver(DriverInfo, NumSatisfiedConstraints))
531 {
533 {
535 }
536 }
537 }
538
539 if (MostRelevantEntry.Key.IsValid())
540 {
541 return MostRelevantEntry.Key;
542 }
543 return {};
544 }
545
546 // Get the corresponding vendor's section name in the Hardware.ini file.
547 // Returns an empty string if not found.
548 FString GetVendorSectionName() const
549 {
550 const TCHAR* Section = nullptr;
551
552 if (DriverInfo.IsNVIDIA())
553 {
554 Section = TEXT("GPU_NVIDIA");
555 }
556 if (DriverInfo.IsAMD())
557 {
558 Section = TEXT("GPU_AMD");
559 }
560 else if (DriverInfo.IsIntel())
561 {
562 Section = TEXT("GPU_Intel");
563 }
564 else if (DriverInfo.IsQualcomm())
565 {
566 Section = TEXT("GPU_Qualcomm");
567 }
568 if (!Section)
569 {
570 return TEXT("");
571 }
572
573 return FString::Printf(TEXT("%s %s"), Section, ANSI_TO_TCHAR(FPlatformProperties::IniPlatformName()));
574 }
575
576 FGPUDriverInfo DriverInfo;
577};
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define ensure( InExpression)
Definition AssertionMacros.h:464
FConfigCacheIni * GConfig
Definition CoreGlobals.cpp:54
FString GHardwareIni
Definition CoreGlobals.cpp:251
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#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
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
EComparisonOp
Definition GenericPlatformDriver.h:96
@ ECO_NotEqual
Definition GenericPlatformDriver.h:97
@ ECO_Less
Definition GenericPlatformDriver.h:97
@ ECO_GreaterOrEqual
Definition GenericPlatformDriver.h:97
@ ECO_Greater
Definition GenericPlatformDriver.h:97
@ ECO_LessOrEqual
Definition GenericPlatformDriver.h:97
@ ECO_Equal
Definition GenericPlatformDriver.h:97
@ ECO_Unknown
Definition GenericPlatformDriver.h:97
EComparisonOp ParseComparisonOp(const TCHAR *&In)
Definition GenericPlatformDriver.h:103
bool CompareWithOp(const T &A, EComparisonOp Op, const T &B)
Definition GenericPlatformDriver.h:140
#define ANSI_TO_TCHAR(str)
Definition StringConv.h:1020
uint32_t uint32
Definition binka_ue_file_header.h:6
CORE_API int32 GetArray(const TCHAR *Section, const TCHAR *Key, TArray< FString > &out_Arr, const FString &Filename)
Definition ConfigCacheIni.cpp:5170
Definition GenericPlatformDriver.h:19
bool operator!=(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:67
FDriverVersion()=default
uint32 GetVersionValue(uint32 Index) const
Definition GenericPlatformDriver.h:81
bool operator<(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:63
const TArray< uint32 > & GetVersionValues() const
Definition GenericPlatformDriver.h:86
bool operator>=(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:71
bool operator==(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:59
void Parse(const FString &DriverVersionString)
Definition GenericPlatformDriver.h:28
bool operator<=(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:75
bool operator>(const FDriverVersion &Other) const
Definition GenericPlatformDriver.h:42
FDriverVersion(const FString &DriverVersionString)
Definition GenericPlatformDriver.h:23
Definition GenericPlatformDriver.h:487
FGPUDriverHelper(const FGPUDriverInfo &InDriverInfo)
Definition GenericPlatformDriver.h:489
TOptional< FDriverDenyListEntry > FindDriverDenyListEntry() const
Definition GenericPlatformDriver.h:501
TOptional< FSuggestedDriverEntry > FindSuggestedDriverVersion() const
Definition GenericPlatformDriver.h:495
Definition Regex.h:44
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
void Empty(SizeType Slack=0)
Definition Array.h:2273
@ CaseSensitive
Definition CString.h:23
@ FromStart
Definition CString.h:36
U16 Index
Definition radfft.cpp:71
Definition DateTime.h:76
Definition GenericPlatformDriver.h:278
TOptional< FRegexPattern > AdapterNameRegexConstraint
Definition GenericPlatformDriver.h:280
bool HasConstraints()
Definition GenericPlatformDriver.h:327
TOptional< FString > RHINameConstraint
Definition GenericPlatformDriver.h:279
bool AreConstraintsSatisfied(const FGPUDriverInfo &Info, uint32 &OutNumSatisfiedConstraints) const
Definition GenericPlatformDriver.h:301
FDriverConfigEntryConstraints(const TCHAR *Entry)
Definition GenericPlatformDriver.h:284
Definition GenericPlatformDriver.h:340
static FDriverDateDenyListEntry FromString(const FString &DriverDateStringWithComparisonOp)
Definition GenericPlatformDriver.h:345
FDateTime Date
Definition GenericPlatformDriver.h:342
EComparisonOp ComparisonOp
Definition GenericPlatformDriver.h:341
Definition GenericPlatformDriver.h:355
EComparisonOp ComparisonOp
Definition GenericPlatformDriver.h:356
FDriverVersion Version
Definition GenericPlatformDriver.h:357
static FDriverVersionDenyListEntry FromString(const FString &DriverVersionStringWithComparisonOp)
Definition GenericPlatformDriver.h:359
Definition GenericPlatformDriver.h:339
FDriverDenyListEntry()=default
FString DenylistReason
Definition GenericPlatformDriver.h:450
bool AppliesToLatestDrivers()
Definition GenericPlatformDriver.h:429
bool AppliesToDriver(const FGPUDriverInfo &Info, uint32 &OutNumSatisfiedConstraints) const
Definition GenericPlatformDriver.h:396
FDriverDenyListEntry(const TCHAR *Entry)
Definition GenericPlatformDriver.h:371
bool IsValid() const
Definition GenericPlatformDriver.h:442
TOptional< FDriverVersionDenyListEntry > DriverVersion
Definition GenericPlatformDriver.h:447
TOptional< FDriverDateDenyListEntry > DriverDate
Definition GenericPlatformDriver.h:448
Definition GenericPlatformDriver.h:156
static FString GetNVIDIAUnifiedVersion(const FString &InternalVersion)
Definition GenericPlatformDriver.h:216
bool IsNVIDIA() const
Definition GenericPlatformDriver.h:193
void SetNVIDIA()
Definition GenericPlatformDriver.h:188
FString GetUnifiedDriverVersion() const
Definition GenericPlatformDriver.h:249
bool IsAMD() const
Definition GenericPlatformDriver.h:191
FString ProviderName
Definition GenericPlatformDriver.h:164
FString DeviceDescription
Definition GenericPlatformDriver.h:161
FString InternalDriverVersion
Definition GenericPlatformDriver.h:167
bool IsValid() const
Definition GenericPlatformDriver.h:178
uint32 VendorId
Definition GenericPlatformDriver.h:158
FString DriverDate
Definition GenericPlatformDriver.h:173
void SetQualcomm()
Definition GenericPlatformDriver.h:189
FString RHIName
Definition GenericPlatformDriver.h:176
static FString GetIntelUnifiedVersion(const FString &InternalVersion)
Definition GenericPlatformDriver.h:232
bool IsSameDriverVersionGeneration(const FDriverVersion &UnifiedDriverVersion) const
Definition GenericPlatformDriver.h:201
void SetIntel()
Definition GenericPlatformDriver.h:187
bool IsIntel() const
Definition GenericPlatformDriver.h:192
FString UserDriverVersion
Definition GenericPlatformDriver.h:170
bool IsQualcomm() const
Definition GenericPlatformDriver.h:194
void SetAMD()
Definition GenericPlatformDriver.h:186
static CORE_API bool Value(const TCHAR *Stream, const TCHAR *Match, FName &Name)
Definition Parse.cpp:584
Definition GenericPlatformDriver.h:456
FSuggestedDriverEntry(const TCHAR *Entry)
Definition GenericPlatformDriver.h:459
FSuggestedDriverEntry()=default
bool AppliesToDriver(const FGPUDriverInfo &Info, uint32 &OutNumSatisfiedConstraints)
Definition GenericPlatformDriver.h:473
FString SuggestedDriverVersion
Definition GenericPlatformDriver.h:483
bool IsValid()
Definition GenericPlatformDriver.h:478
static UE_FORCEINLINE_HINT int32 Atoi(const CharType *String)
Definition CString.h:1173
Definition Optional.h:131
OptionalType & Emplace(ArgsType &&... Args)
Definition Optional.h:323
Definition Tuple.h:652