Karma Engine
Loading...
Searching...
No Matches
GenericPlatformMemory.h
1#pragma once
2
3#include "krpch.h"
4
5namespace Karma
6{
7 typedef size_t SIZE_T;
8
9 //---------------------------------------------------------------------
10 // Utility for automatically setting up the pointer-sized integer type
11 //---------------------------------------------------------------------
12
13 template<typename T32BITS, typename T64BITS, int PointerSize>
15 {
16 // nothing here are is it an error if the partial specializations fail
17 };
18
19 template<typename T32BITS, typename T64BITS>
20 struct SelectIntPointerType<T32BITS, T64BITS, 8>
21 {
22 // Select the 64 bit type.
23 typedef T64BITS TIntPointer;
24 };
25
26 template<typename T32BITS, typename T64BITS>
27 struct SelectIntPointerType<T32BITS, T64BITS, 4>
28 {
29 // Select the 32 bit type.
30 typedef T32BITS TIntPointer;
31 };
32
33 // Unsigned int. The same size as a pointer.
34 typedef SelectIntPointerType<uint32_t, uint64_t, sizeof(void*)>::TIntPointer UPTRINT;
35
36 enum class EMemcpyCachePolicy : uint8_t
37 {
38 // Writes to destination memory are cache-visible (default).
39 // This should be used if copy results are immediately accessed by CPU.
40 StoreCached,
41
42 // Writes to destination memory bypass cache (avoiding pollution).
43 // Optimizes for large copies that aren't read from soon after.
44 StoreUncached,
45 };
46
47 struct KARMA_API FGenericPlatformMemory
48 {
55 static FORCEINLINE void* Memmove(void* Dest, const void* Src, SIZE_T Count)
56 {
57 return memmove(Dest, Src, Count);
58 }
59
60 static FORCEINLINE int32_t Memcmp(const void* Buf1, const void* Buf2, SIZE_T Count)
61 {
62 return memcmp(Buf1, Buf2, Count);
63 }
64
65 static FORCEINLINE void* Memset(void* Dest, uint8_t Char, SIZE_T Count)
66 {
67 return memset(Dest, Char, Count);
68 }
69
70 static FORCEINLINE void* Memzero(void* Dest, SIZE_T Count)
71 {
72 return memset(Dest, 0, Count);
73 }
74
75 static FORCEINLINE void* Memcpy(void* Dest, const void* Src, SIZE_T Count)
76 {
77 return memcpy(Dest, Src, Count);
78 }
79
81 static FORCEINLINE void* BigBlockMemcpy(void* Dest, const void* Src, SIZE_T Count)
82 {
83 return memcpy(Dest, Src, Count);
84 }
85
87 static FORCEINLINE void* StreamingMemcpy(void* Dest, const void* Src, SIZE_T Count)
88 {
89 return memcpy(Dest, Src, Count);
90 }
91
93 static FORCEINLINE void* ParallelMemcpy(void* Dest, const void* Src, SIZE_T Count, EMemcpyCachePolicy Policy = EMemcpyCachePolicy::StoreCached)
94 {
95 (void)Policy;
96 return memcpy(Dest, Src, Count);
97 }
98
99 private:
100 template <typename T>
101 static FORCEINLINE void Valswap(T& A, T& B)
102 {
103 // Usually such an implementation would use move semantics, but
104 // we're only ever going to call it on fundamental types and MoveTemp
105 // is not necessarily in scope here anyway, so we don't want to
106 // #include it if we don't need to.
107 T Tmp = A;
108 A = B;
109 B = Tmp;
110 }
111
112 static void MemswapGreaterThan8(void* Ptr1, void* Ptr2, SIZE_T Size);
113
114 public:
115 // NOT FUNCTIONAL YET
116 static inline void Memswap(void* Ptr1, void* Ptr2, SIZE_T Size)
117 {
118 switch (Size)
119 {
120 case 0:
121 break;
122
123 case 1:
124 Valswap(*(uint8_t*)Ptr1, *(uint8_t*)Ptr2);
125 break;
126
127 case 2:
128 Valswap(*(uint16_t*)Ptr1, *(uint16_t*)Ptr2);
129 break;
130
131 case 3:
132 Valswap(*((uint16_t*&)Ptr1)++, *((uint16_t*&)Ptr2)++);
133 Valswap(*(uint8_t*)Ptr1, *(uint8_t*)Ptr2);
134 break;
135
136 case 4:
137 Valswap(*(uint32_t*)Ptr1, *(uint32_t*)Ptr2);
138 break;
139
140 case 5:
141 Valswap(*((uint32_t*&)Ptr1)++, *((uint32_t*&)Ptr2)++);
142 Valswap(*(uint8_t*)Ptr1, *(uint8_t*)Ptr2);
143 break;
144
145 case 6:
146 Valswap(*((uint32_t*&)Ptr1)++, *((uint32_t*&)Ptr2)++);
147 Valswap(*(uint16_t*)Ptr1, *(uint16_t*)Ptr2);
148 break;
149
150 case 7:
151 Valswap(*((uint32_t*&)Ptr1)++, *((uint32_t*&)Ptr2)++);
152 Valswap(*((uint16_t*&)Ptr1)++, *((uint16_t*&)Ptr2)++);
153 Valswap(*(uint8_t*)Ptr1, *(uint8_t*)Ptr2);
154 break;
155
156 case 8:
157 Valswap(*(uint64_t*)Ptr1, *(uint64_t*)Ptr2);
158 break;
159
160 case 16:
161 Valswap(((uint64_t*)Ptr1)[0], ((uint64_t*)Ptr2)[0]);
162 Valswap(((uint64_t*)Ptr1)[1], ((uint64_t*)Ptr2)[1]);
163 break;
164
165 default:
166 MemswapGreaterThan8(Ptr1, Ptr2, Size);
167 break;
168 }
169 }
170 };
171}
Definition GenericPlatformMemory.h:48
static FORCEINLINE void * ParallelMemcpy(void *Dest, const void *Src, SIZE_T Count, EMemcpyCachePolicy Policy=EMemcpyCachePolicy::StoreCached)
Definition GenericPlatformMemory.h:93
static FORCEINLINE void * BigBlockMemcpy(void *Dest, const void *Src, SIZE_T Count)
Definition GenericPlatformMemory.h:81
static FORCEINLINE void * Memmove(void *Dest, const void *Src, SIZE_T Count)
Definition GenericPlatformMemory.h:55
static FORCEINLINE void * StreamingMemcpy(void *Dest, const void *Src, SIZE_T Count)
Definition GenericPlatformMemory.h:87
Definition GenericPlatformMemory.h:15