-
Notifications
You must be signed in to change notification settings - Fork 89
/
palUtil.h
708 lines (566 loc) · 31.9 KB
/
palUtil.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
/*
***********************************************************************************************************************
*
* Copyright (c) 2014-2024 Advanced Micro Devices, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************************************************************/
/**
***********************************************************************************************************************
* @file palUtil.h
* @brief Common include for the PAL utility collection. Defines common types, macros, enums, etc.
***********************************************************************************************************************
*/
#pragma once
/// Utility macro for turning another macro into a string literal.
#define _PAL_STRINGIFY(_x) #_x
#define PAL_STRINGIFY(_x) _PAL_STRINGIFY(_x)
/// C++11 standard version.
#define PAL_CPLUSPLUS_11 201103L
/// C++14 standard version.
#define PAL_CPLUSPLUS_14 201402L
/// C++17 standard version.
#define PAL_CPLUSPLUS_17 201703L
/// C++ feature version from September 2017 contains a few C++20 features.
#define PAL_CPLUSPLUS_1709 201709L
/// C++20 standard version.
#define PAL_CPLUSPLUS_20 202002L
/// C++ standard version used to compile PAL.
# define PAL_CPLUSPLUS __cplusplus
/// Checks if PAL is compiled with C++ of at least version @p v.
#define PAL_CPLUSPLUS_AT_LEAST(v) (PAL_CPLUSPLUS >= (v))
static_assert(
PAL_CPLUSPLUS_AT_LEAST(PAL_CPLUSPLUS_1709),
"C++ standard version " PAL_STRINGIFY(PAL_CPLUSPLUS_1709) " is required to build PAL. "
"Found " PAL_STRINGIFY(PAL_CPLUSPLUS) ".");
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 878
/// We already declare NOMINMAX publicly, but that won't stop clients from defining their own min/max macros.
/// These macros confuse the compiler when using functions named min/max, leading to build errors.
#if defined(min) || defined(max)
static_assert(false, "Clients may not define macros named \"min\" or \"max\".");
#endif
#endif
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 873
#include <chrono>
#endif
#include <cstddef>
/// stdint is included instead of cstdint to allow Visual Studio Intellisense to work for Linux builds. This can be
/// removed if the error caused by including cstdint is figured out.
#include "stdint.h"
/// Include in the class declaration in order to disallow use of the copy constructor and assignment operator for that
/// class.
#define PAL_DISALLOW_COPY_AND_ASSIGN(_typename) \
_typename(const _typename&) = delete; \
_typename& operator=(const _typename&) = delete;
/// Include in the declaration in order to disallow use of the default constructor for a class.
#define PAL_DISALLOW_DEFAULT_CTOR(_typename) \
_typename() = delete;
#if !defined(__GNUC__)
// Equates to the [__stdcall](https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/stdcall.md) convention on Windows.
#define PAL_STDCALL __stdcall
// Equates to the [__cdecl](https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/cdecl.md) convention on Windows.
#define PAL_CDECL __cdecl
// Equates to [__declspec(align(__x))](https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/align-cpp.md) on Windows.
#define PAL_ALIGN(__x) __declspec(align(__x))
#define PAL_FORCE_INLINE __forceinline
#else
/// Undefined on GCC platforms.
#define PAL_STDCALL
/// Undefined on GCC platforms.
#define PAL_CDECL
/// Undefined on GCC platforms.
#define PAL_ALIGN(__x)
#define PAL_FORCE_INLINE __attribute__((always_inline)) inline
#endif
/// Platform cache line size in bytes.
#define PAL_CACHE_LINE_BYTES 64
/// Platform system memory page size in bytes.
#define PAL_PAGE_BYTES 4096
/// Force cache line alignment.
#define PAL_ALIGN_CACHE_LINE PAL_ALIGN(PAL_CACHE_LINE_BYTES)
#if defined(__unix__)
/// Value representing an invalid file descriptor on Linux systems.
constexpr int32_t InvalidFd = -1;
#endif
#ifdef __has_builtin
/// A macro that checks for the presence of builtin functions. Will default to false if the compiler does not have
/// support for doing this check.
#define PAL_HAS_BUILTIN(builtin) __has_builtin(builtin)
#else
#define PAL_HAS_BUILTIN(builtin) 0
#endif
#if defined(__has_cpp_attribute)
#define PAL_HAS_CPP_ATTR(attr) __has_cpp_attribute(attr)
#else
#define PAL_HAS_CPP_ATTR(attr) 0
#endif
/// Library-wide namespace encapsulating all PAL utility collection entities.
namespace Util
{
typedef int8_t int8; ///< 8-bit integer.
typedef int16_t int16; ///< 16-bit integer.
typedef int32_t int32; ///< 32-bit integer.
typedef int64_t int64; ///< 64-bit integer.
typedef uint8_t uint8; ///< Unsigned 8-bit integer.
typedef uint16_t uint16; ///< Unsigned 16-bit integer.
typedef uint32_t uint32; ///< Unsigned 32-bit integer.
typedef uint64_t uint64; ///< Unsigned 64-bit integer.
typedef uint64_t gpusize; ///< Used to specify GPU addresses and sizes of GPU allocations. This differs from
/// size_t since the GPU still uses 64-bit addresses on a 32-bit OS.
/// Error and return codes indicating outcome of a requested operation. Success result codes are greater than or equal
/// to 0, and error results codes are less than 0.
enum class Result : int32
{
/// @internal The operation completed successfully.
_Success = 0x00000000,
// Unfortunately for Linux clients, X.h includes a "#define Success 0" macro. Clients have their choice of either
// undefing Success before including this header or using _Success when dealing with PAL.
#ifndef Success
/// The operation completed successfully.
Success = _Success,
#endif
/// The operation is not supported.
Unsupported = 0x00000001,
/// The operation completed successfully but the result is not ready. This result code normally applies to
/// situations where results of queued GPU operations such as queries and fences have not been written to memory
/// yet.
NotReady = 0x00000002,
/// The wait operation completed due to a client-specified timeout condition.
Timeout = 0x00000003,
/// The event is in the "set" state. @see IGpuEvent::GetStatus.
EventSet = 0x00000004,
/// The event is in the "reset" state. @see IGpuEvent::GetStatus.
EventReset = 0x00000005,
/// The operation was successful, but the client has reached the maximum allowable number of flippable GPU memory
/// objects. Future requests to create presentable Images or flippable GPU memory objects may fail due to
/// limitations within the underlying OS.
/// @see IDevice::CreateGpuMemory.
/// @see IDevice::CreatePresentableImage.
TooManyFlippableAllocations = 0x00000006,
/// The present was successful, but some portion of the window is currently occluded by another window.
PresentOccluded = 0x00000007,
/// The directory/file/etc. being created already exists.
AlreadyExists = 0x00000008,
/// A warning indicates an operation is successful (supported by H/W) but out of a certain spec (e.g. VESA).
OutOfSpec = 0x00000009,
/// The value being searched for was not found.
NotFound = 0x0000000A,
/// End of file reached successfully.
Eof = 0x0000000B,
/// If ReserveEntryOnMiss was specified, the entry was not found, and the entry was successfully reserved.
Reserved = 0x0000000C,
/// If an operation is purposefully terminated early, rather than from an error.
Aborted = 0x0000000D,
/// The operation encountered an unknown error.
ErrorUnknown = -(0x00000001),
/// The requested operation is unavailable at this time.
ErrorUnavailable = -(0x00000002),
/// The initialization operation failed for unknown reasons.
ErrorInitializationFailed = -(0x00000003),
/// The operation could not complete due to insufficient system memory.
ErrorOutOfMemory = -(0x00000004),
/// The operation could not complete due to insufficient GPU memory.
ErrorOutOfGpuMemory = -(0x00000005),
/// The device was lost due to its removal or a possible hang and recovery condition. The client should destroy all
/// devices (and objects attached to them) and re-enumerate the available devices be calling EnumerateDevices().
ErrorDeviceLost = -(0x00000007),
/// A required input pointer passed to the call was invalid (probably null).
ErrorInvalidPointer = -(0x00000008),
/// An invalid value was passed to the call.
ErrorInvalidValue = -(0x00000009),
/// An invalid ordinal was passed to the call.
ErrorInvalidOrdinal = -(0x0000000A),
/// An invalid memory size was passed to the call.
ErrorInvalidMemorySize = -(0x0000000B),
/// Invalid flags were passed to the call.
ErrorInvalidFlags = -(0x0000000C),
/// An invalid alignment parameter was specified
ErrorInvalidAlignment = -(0x0000000D),
/// An invalid resource format was specified.
ErrorInvalidFormat = -(0x0000000E),
/// The requested operation cannot be performed on the provided @ref Pal::IImage object.
ErrorInvalidImage = -(0x0000000F),
/// The descriptor set data is invalid or does not match the related pipeline.
ErrorInvalidDescriptorSetData = -(0x00000010),
/// An invalid queue type was specified.
ErrorInvalidQueueType = -(0x00000011),
/// An invalid object type was specified.
ErrorInvalidObjectType = -(0x00000012),
/// The specified shader uses an unsupported version of AMD IL.
ErrorUnsupportedShaderIlVersion = -(0x00000013),
/// The specified shader code is invalid or corrupt.
ErrorBadShaderCode = -(0x00000014),
/// The specified serialized pipeline data is invalid or corrupt.
ErrorBadPipelineData = -(0x00000015),
/// The queue operation specified more GPU memory references than are supported.
/// @see Pal::IQueue::Submit
/// @see Pal::IDevice::AddGpuMemoryReferences
/// @see Pal::DeviceProperties::maxGpuMemoryRefsResident
ErrorTooManyMemoryReferences = -(0x00000016),
/// The memory object cannot be mapped because it does not reside in a CPU visible heap.
ErrorNotMappable = -(0x00000017),
/// The map operation failed due to an unknown or system reason.
ErrorGpuMemoryMapFailed = -(0x00000018),
/// The unmap operation failed due to an unknown or system reason.
ErrorGpuMemoryUnmapFailed = -(0x00000019),
/// The serialized pipeline load operation failed due to an incompatible device.
ErrorIncompatibleDevice = -(0x0000001A),
/// The serialized pipeline load operation failed due to an incompatible PAL library.
ErrorIncompatibleLibrary = -(0x0000001B),
/// The requested operation (such as command buffer submission) can't be completed because command buffer
/// construction is not complete.
ErrorIncompleteCommandBuffer = -(0x0000001C),
/// The specified command buffer failed to build correctly. This error can be delayed from the original source of
/// the error since the command buffer building methods do not return error codes.
ErrorBuildingCommandBuffer = -(0x0000001D),
/// The operation cannot complete since not all objects have valid GPU memory bound to them.
ErrorGpuMemoryNotBound = -(0x0000001E),
/// The requested operation is not supported on the specified queue type.
ErrorIncompatibleQueue = -(0x0000001F),
/// The object cannot be created or opened for sharing between multiple GPU devices.
ErrorNotShareable = -(0x00000020),
/// The operation failed because the specified fullscreen mode was unavailable. This could be a failure while
/// attempting to take fullscreen ownership, or when attempting to perform a fullscreen present and the user has
/// left fullscreen mode.
ErrorFullscreenUnavailable = -(0x00000021),
/// The targeted screen of the operation has been removed from the system.
ErrorScreenRemoved = -(0x00000022),
/// Present failed because the screen mode is no longer compatible with the source image.
ErrorIncompatibleScreenMode = -(0x00000023),
/// The cross-GPU present failed, possibly due to a lack of system bus bandwidth to accommodate the transfer.
ErrorMultiDevicePresentFailed = -(0x00000024),
/// The slave GPU(s) in an MGPU system cannot create BLTable present images.
ErrorWindowedPresentUnavailable = -(0x00000025),
/// The attempt to enter fullscreen exclusive mode failed because the specified image doesn't properly match the
/// screen's current dimensions.
ErrorInvalidResolution = -(0x00000026),
/// The shader specifies a thread group size that is bigger than what is supported by this device.
ErrorThreadGroupTooBig = -(0x00000027),
/// Invalid image create info: Specified both color target and depth usage
ErrorInvalidImageTargetUsage = -(0x00000028),
/// Invalid image create info: Specified a 1D type for a color target
ErrorInvalidColorTargetType = -(0x00000029),
/// Invalid image create info: Specified a non-2D type for a depth/stencil target
ErrorInvalidDepthTargetType = -(0x0000002A),
/// Invalid image create info: The image format supports depth/stencil but depth/stencil usage was not specified
ErrorMissingDepthStencilUsage = -(0x0000002B),
/// Invalid image create info: Specified MSAA and multiple mip levels
ErrorInvalidMsaaMipLevels = -(0x0000002C),
/// Invalid image create info: The image format is incompatible with MSAA
ErrorInvalidMsaaFormat = -(0x0000002D),
/// Invalid image create info: The image type is incompatible with MSAA
ErrorInvalidMsaaType = -(0x0000002E),
/// The sample count is invalid
ErrorInvalidSampleCount = -(0x0000002F),
/// Invalid image create info: Invalid block compressed image type
ErrorInvalidCompressedImageType = -(0x00000030),
/// Invalid image create info: Format is incompatible with the specified image usage
ErrorInvalidUsageForFormat = -(0x00000032),
/// Invalid image create info: Array size is invalid
ErrorInvalidImageArraySize = -(0x00000033),
/// Invalid image create info: Array size is invalid for a 3D image
ErrorInvalid3dImageArraySize = -(0x00000034),
/// Invalid image create info: Image width is invalid
ErrorInvalidImageWidth = -(0x00000035),
/// Invalid image create info: Image height is invalid
ErrorInvalidImageHeight = -(0x00000036),
/// Invalid image create info: Image depth is invalid
ErrorInvalidImageDepth = -(0x00000037),
/// Invalid image create info: Mip count is invalid
ErrorInvalidMipCount = -(0x00000038),
/// Invalid image create info: Image format is incompatible with the image usage specified.
ErrorFormatIncompatibleWithImageUsage = -(0x00000039),
/// Operation requested an image plane that is not available on the image.
ErrorImagePlaneUnavailable = -(0x0000003A),
/// Another format is incompatible with an image's format.
ErrorFormatIncompatibleWithImageFormat = -(0x0000003B),
/// Another format is incompatible with an image plane's format.
ErrorFormatIncompatibleWithImagePlane = -(0x0000003C),
/// Operation requires a shader readable or writable image usage but the image does not support it.
ErrorImageNotShaderAccessible = -(0x0000003D),
/// Format is paired with a channel mapping that contains invalid components.
ErrorInvalidFormatSwizzle = -(0x0000003E),
/// A base mip level that is out of bounds or otherwise invalid was specified.
ErrorInvalidBaseMipLevel = -(0x0000003F),
/// A view array size that was zero or otherwise invalid was specified.
ErrorInvalidViewArraySize = -(0x00000040),
/// A view base array slice that was out of bounds or otherwise invalid was specified.
ErrorInvalidViewBaseSlice = -(0x00000041),
/// A view image type was specified that is incompatible with the image's type.
ErrorViewTypeIncompatibleWithImageType = -(0x00000042),
/// A view specifies an array slice range that is larger than what is supported by the image.
ErrorInsufficientImageArraySize = -(0x00000043),
/// It is illegal to create a cubemap view into an MSAA image.
ErrorCubemapIncompatibleWithMsaa = -(0x00000044),
/// A cubemap view was created to an image that does not have square width and height.
ErrorCubemapNonSquareFaceSize = -(0x00000045),
/// An fmask view was created to an image that does not support an fmask.
ErrorImageFmaskUnavailable = -(0x00000046),
/// A private screen was removed.
ErrorPrivateScreenRemoved = -(0x00000047),
/// A private screen was already in exclusive use.
ErrorPrivateScreenUsed = -(0x00000048),
/// The image count created or opened on this private display exceed maximum.
ErrorTooManyPrivateDisplayImages = -(0x00000049),
/// The private screen is not enabled.
ErrorPrivateScreenNotEnabled = -(0x0000004A),
/// The private screen count exceeds the maximum (including emulated and physical ones).
ErrorTooManyPrivateScreens = -(0x0000004B),
/// Invalid image create info: Image rowPitch does not equal the image's actual row pitch.
ErrorMismatchedImageRowPitch = -(0x0000004C),
/// Invalid image create info: Image depthPitch does not equal the image's actual depth pitch.
ErrorMismatchedImageDepthPitch = -(0x0000004D),
/// The given swap chain cannot be associated with any more presentable images.
ErrorTooManyPresentableImages = -(0x0000004E),
/// A fence was used in GetStatus() or WaitForFences() without being used in any submission.
ErrorFenceNeverSubmitted = -(0x0000004F),
/// The image used on the specified private screen has an invalid format.
ErrorPrivateScreenInvalidFormat = -(0x00000050),
/// The timing data set on the specified private screen was invalid.
ErrorPrivateScreenInvalidTiming = -(0x00000051),
/// The resolution set on the specified private screen was invalid.
ErrorPrivateScreenInvalidResolution = -(0x00000052),
/// The scaling parameter set on the specified private screen was invalid.
ErrorPrivateScreenInvalidScaling = -(0x00000053),
/// Invalid image create info: Invalid YUV image type
ErrorInvalidYuvImageType = -(0x00000054),
/// The external shader cache found a matching hash but the with different key data.
ErrorShaderCacheHashCollision = -(0x00000055),
/// The external shader cache is full
ErrorShaderCacheFull = -(0x00000056),
/// The operation caused a pagefault.
ErrorGpuPageFaultDetected = -(0x00000057),
/// The provided pipeline ELF uses an unsupported ABI version.
ErrorUnsupportedPipelineElfAbiVersion = -(0x00000058),
/// The provided pipeline ELF is invalid.
ErrorInvalidPipelineElf = -(0x00000059),
/// The returned results were incomplete.
ErrorIncompleteResults = -(0x00000060),
/// The display mode is imcompatible with framebuffer or CRTC.
ErrorIncompatibleDisplayMode = -(0x00000061),
/// Implicit fullscreen exclusive mode is not safe because the specified window size doesn't match the
/// screen's current dimensions.
ErrorIncompatibleWindowSize = -(0x00000062),
/// A semaphore was used in WaitForSemaphores() without being signaled.
ErrorSemaphoreNeverSignaled = -(0x00000063),
/// Invalid image create info: specified metadataMode is invalid for the Image.
ErrorInvalidImageMetadataMode = -(0x00000064),
/// Invalid external handle detected for the Image.
ErrorInvalidExternalHandle = -(0x00000065),
/// The permission of operation is denied.
ErrorPermissionDenied = -(0x00000066),
/// The operation failed because the disk is full.
ErrorDiskFull = -(0x00000067),
/// The static VMID acquire/release operation failed.
ErrorStaticVmidOpFailed = -(0x00000068),
};
///Specifies a ratio of two unsigned integers.
struct Rational
{
uint32 numerator; ///< Numerator
uint32 denominator; ///< Denominator
};
/// Implements operator== for PAL's Rational struct where similar ratios like 2/3 and 4/6 are treated as equal.
///
/// @param left Rational to be compared
/// @param right Rational to be compared
///
/// @return true if the ratios are logically equal.
constexpr bool operator==(
const Rational& lhs,
const Rational& rhs)
{
// Any ratio with a zero denominator is illegal/undefined, for example: "3/0 == 5/0" or "5/3 == 0/0". We must pick
// either "true" or "false" for these illegal cases. "true" seems like the most wrong option so we use "false".
if ((lhs.denominator == 0) || (rhs.denominator == 0))
{
return false;
}
// Otherwise, our equality check is: lhs_n / lhs_d == rhs_n / rhs_d
// Multiply both sides by lhs_d: lhs_n == rhs_n * lhs_d / rhs_d
// Multiply both sides by rhs_d: lhs_n * rhs_d == rhs_n * lhs_d
// This trick avoids dealing with common factors or remainders and uses no slow division instructions.
return (static_cast<uint64>(lhs.numerator) * static_cast<uint64>(rhs.denominator) ==
static_cast<uint64>(rhs.numerator) * static_cast<uint64>(lhs.denominator));
}
// Flags to be passed to store operations.
struct StoreFlags
{
union
{
struct
{
uint32 enableFileCache : 1; ///< If we should skip the file cache layer when we get to it.
uint32 enableCompression : 1; ///< If we should skip the compression layer when we get to it.
uint32 reserved : 30;
};
uint32 all;
};
};
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 873
/// Seconds stored as a float instead of an integer.
using fseconds = std::chrono::duration<float>;
/// Milliseconds stored as a float instead of an integer.
using fmilliseconds = std::chrono::duration<float, std::milli>;
/// Microseconds stored as a float instead of an integer.
using fmicroseconds = std::chrono::duration<float, std::micro>;
/// Nanoseconds stored as a float instead of an integer.
using fnanoseconds = std::chrono::duration<float, std::nano>;
/// A time_point who's epoch is January 1st 1970 and uses seconds for the duration.
/// C++20 guarantees us that system_clock's epoch is always January 1st 1970 on all platforms.
/// system_clock's internal duration is still implementation defined.
/// On Windows it's hundreds of nanoseconds and on Linux it's seconds.
/// However time_point has it's own duration type.
/// As long as we go through the time_point to interpret the duration then everything should be in terms of seconds.
using SecondsSinceEpoch = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;
/// Like std::chrono::duration_cast, but it preserves the special 'infinite' value used in timeouts.
template <class ToDuration, class Rep, class Period>
constexpr ToDuration TimeoutCast(
const std::chrono::duration<Rep, Period>& d)
{
if (d == (std::chrono::duration<Rep,Period>::max)())
{
return (ToDuration::max)();
}
else
{
return std::chrono::duration_cast<ToDuration, Rep, Period>(d);
}
}
#endif
/// Inline function to determine if a Result enum is considered an error.
constexpr bool IsErrorResult(Result result) { return (static_cast<int32>(result) < 0); }
/// Inline function to collapse two Result enums into the most useful Result code. It considers errors to be more
/// interesting than success codes and considers "Success" to be the least interesting success code. If both Results
/// are errors, the first Result is returned.
constexpr Result CollapseResults(Result lhs, Result rhs)
{ return (IsErrorResult(lhs) || (static_cast<uint32>(lhs) > static_cast<uint32>(rhs))) ? lhs : rhs; }
/**
***********************************************************************************************************************
* @page UtilOverview Utility Collection
*
* In addition to its GPU-specific core functionality, PAL provides a lot of generic, OS-abstracted software utilities
* in the @ref Util namespace. The PAL core relies on these utilities, but they are also available for use by its
* clients. In fact, it is possible to build and use PAL only for its utility collection by building PAL with the
* PAL_BUILD_CORE build option set to 0.
*
* All available PAL utilities are defined in the @ref Util namespace, and are briefly summarized below. See the
* Reference topics for more detailed information on specific classes, enums, etc.
*
* ### System Memory Management
* palSysMemory.h defines a handful of macros that can be used for allocating and freeing system heap memory. These
* macros will use the client-specified allocation callbacks specified by the client at CreatePlatform() if specified.
* These macros are:
*
* - PAL_MALLOC: Equivalent to malloc().
* - PAL_CALLOC: Equivalent to calloc().
* - PAL_FREE: Equivalent to free().
* - PAL_SAFE_FREE: Equivalent to free(), then nulls out the specified pointer.
* - PAL_NEW: Equivalent to C++ new.
* - PAL_NEW_ARRAY: Equivalent to C++ new[].
* - PAL_PLACEMENT_NEW: Equivalent to C++ placement new.
* - PAL_DELETE: Equivalent to C++ delete.
* - PAL_DELETE_THIS: Special version of PAL_DELETE that effectively does "delete this;" This is necessary for
* classes that have non-public destructors.
* - PAL_DELETE_ARRAY: Equivalent to C++ delete[].
* - PAL_SAFE_DELETE_ARRAY: Equivalent to C++ delete, then nulls out the specified pointer.
* - PAL_SAFE_DELETE: Equivalent to C++ delete[], then nulls out the specified pointer.
*
* ### Allocators
* All of the memory management macros take in a templated allocator, which is required to have the following two
* functions defined:
*
* void* Alloc(const Util::AllocInfo)
* void Free(const Util::FreeInfo)
*
* It is expected that clients that specify their own allocators will handle cases that require specific alignments
* and/or zeroing the returned memory.
*
* Some allocators can be created for use by clients:
* - VirtualLinearAllocator: A linear allocator that allocates virtual memory and backs it with physical memory
* when needed.
*
* ### Debug Prints and Asserts
* palDbgPrint.h and palAssert.h provide a number of macros used widely by the PAL core and also available for use
* by clients.
*
* The PAL_DPF, PAL_DPINFO, PAL_DPERROR, and PAL_DPWARN can be used to issue debug prints. These macros will be nulled
* out if PAL_ENABLE_PRINTS_ASSERTS is not defined to be 1. SetDbgPrintMode() can be called to configure how the
* different categories of debug prints will be handled (e.g., print to the debugger, print to file, etc.).
*
* The PAL_ASSERT and PAL_ALERT macros can be used to verify expected states of the program at runtime. PAL_ASSERT
* should be used for verifying expected invariants and assumptions, while PAL_ALERT should be used to alert the
* developer of a condition that is allowed, but not typically expected (i.e., failure of a system memory allocation).
* Note that the polarity of the condition check is different between assert and alert. Asserts "assert" that the
* specified condition is true (and complain if it's not), while alerts "alert" a developer if an unexpected condition
* is true. These macros will be nulled out if PAL_ENABLE_PRINTS_ASSERTS is not defined to be 1. EnableAssertMode()
* can be called to enable/disable asserts or alerts at runtime.
*
* ### Generic Containers
* Util includes a number of generic container data structure implementations. Note that most of these are broken up
* into two header files - for example, list.h and listImpl.h. The intention is that list.h will be included from
* other header files that need a full list definition, while listImpl.h will be included by .cpp files that actually
* interact with the list. This should keep build times down versus putting all implementations directly in list.h.
* - AutoBuffer: Allows dynamic arrays to be placed on the stack without a heap allocation in situations where a
* maximum reasonable expected size is known.
* - Deque: Double ended queue.
* - HashMap: Fast map implementation. Note that this implementation has some non-standard restrictions on the key
* (can't be 0) and value size (must fit in a cache line).
* - HashSet: Fast set implementation. Note the similar restrictions to HashMap.
* - IntervalTree: [Interval tree] implementation.
* - RingBuffer: A ringed buffer of variable length and size.
*
* ### Multithreading and Synchronization
* Util includes a number of OS-abstracted multithreading and CPU synchronization constructs:
*
* - Thread
* - Mutex
* - Semaphore
* - ConditionVariable
* - Event
*
* ### Files
* The File class provides an OS-abstracted interface for opening files and reading/writing data in those files.
* Further, the ElfReadContext and ElfWriteContext classes provide functionality for reading and writing buffers in the
* [Executable and Linkable Format (ELF)]
* The ELF utilities can be used in conjunction with File in order to read/write ELF files on disk.
*
* ### Inline Functions
* palInlineFuncs.h defines a bunch of simple inline functions that are used throughout PAL and might be useful to
* clients. Some examples include VoidPtrInc(), Pow2Pad(), Min(), Max(), Strncpy(), etc.
*
* palMath.h defines a Math namespace with various constants and functions related to floating point conversions and
* basic math rouintes like Sqrt().
*
* Additionally, palHashLiteralString.h defines a template metaprogramming string hash implementation that can produce
* a FNV1A hash for a string specified in the source code without the string showing up in a compiled release build.
*
* ### System Utilities
* palSysUtil.h defines a few functions providing abstracted system-specific functionality:
* - Access to the high resolution CPU performance counters with GetPerfFrequency() and GetPerfCpuTime().
* - Support for asynchronously querying if a particular keyboard key is currently pressed with IsKeyPressed().
*
* ### Cryptographic Algorithm Implementations
* Util provides the crypto algorithm Md5
*
* Next: @ref GpuUtilOverview
***********************************************************************************************************************
*/
} // Util