1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | |
22 | /* WIKI CATEGORY: CPUInfo */ |
23 | |
24 | /** |
25 | * # CategoryCPUInfo |
26 | * |
27 | * CPU feature detection for SDL. |
28 | * |
29 | * These functions are largely concerned with reporting if the system has |
30 | * access to various SIMD instruction sets, but also has other important info |
31 | * to share, such as system RAM size and number of logical CPU cores. |
32 | * |
33 | * CPU instruction set checks, like SDL_HasSSE() and SDL_HasNEON(), are |
34 | * available on all platforms, even if they don't make sense (an ARM processor |
35 | * will never have SSE and an x86 processor will never have NEON, for example, |
36 | * but these functions still exist and will simply return false in these |
37 | * cases). |
38 | */ |
39 | |
40 | #ifndef SDL_cpuinfo_h_ |
41 | #define SDL_cpuinfo_h_ |
42 | |
43 | #include <SDL3/SDL_stdinc.h> |
44 | |
45 | #include <SDL3/SDL_begin_code.h> |
46 | /* Set up for C function definitions, even when using C++ */ |
47 | #ifdef __cplusplus |
48 | extern "C" { |
49 | #endif |
50 | |
51 | /** |
52 | * A guess for the cacheline size used for padding. |
53 | * |
54 | * Most x86 processors have a 64 byte cache line. The 64-bit PowerPC |
55 | * processors have a 128 byte cache line. We use the larger value to be |
56 | * generally safe. |
57 | * |
58 | * \since This macro is available since SDL 3.2.0. |
59 | */ |
60 | #define SDL_CACHELINE_SIZE 128 |
61 | |
62 | /** |
63 | * Get the number of logical CPU cores available. |
64 | * |
65 | * \returns the total number of logical CPU cores. On CPUs that include |
66 | * technologies such as hyperthreading, the number of logical cores |
67 | * may be more than the number of physical cores. |
68 | * |
69 | * \threadsafety It is safe to call this function from any thread. |
70 | * |
71 | * \since This function is available since SDL 3.2.0. |
72 | */ |
73 | extern SDL_DECLSPEC int SDLCALL SDL_GetNumLogicalCPUCores(void); |
74 | |
75 | /** |
76 | * Determine the L1 cache line size of the CPU. |
77 | * |
78 | * This is useful for determining multi-threaded structure padding or SIMD |
79 | * prefetch sizes. |
80 | * |
81 | * \returns the L1 cache line size of the CPU, in bytes. |
82 | * |
83 | * \threadsafety It is safe to call this function from any thread. |
84 | * |
85 | * \since This function is available since SDL 3.2.0. |
86 | */ |
87 | extern SDL_DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); |
88 | |
89 | /** |
90 | * Determine whether the CPU has AltiVec features. |
91 | * |
92 | * This always returns false on CPUs that aren't using PowerPC instruction |
93 | * sets. |
94 | * |
95 | * \returns true if the CPU has AltiVec features or false if not. |
96 | * |
97 | * \threadsafety It is safe to call this function from any thread. |
98 | * |
99 | * \since This function is available since SDL 3.2.0. |
100 | */ |
101 | extern SDL_DECLSPEC bool SDLCALL SDL_HasAltiVec(void); |
102 | |
103 | /** |
104 | * Determine whether the CPU has MMX features. |
105 | * |
106 | * This always returns false on CPUs that aren't using Intel instruction sets. |
107 | * |
108 | * \returns true if the CPU has MMX features or false if not. |
109 | * |
110 | * \threadsafety It is safe to call this function from any thread. |
111 | * |
112 | * \since This function is available since SDL 3.2.0. |
113 | */ |
114 | extern SDL_DECLSPEC bool SDLCALL SDL_HasMMX(void); |
115 | |
116 | /** |
117 | * Determine whether the CPU has SSE features. |
118 | * |
119 | * This always returns false on CPUs that aren't using Intel instruction sets. |
120 | * |
121 | * \returns true if the CPU has SSE features or false if not. |
122 | * |
123 | * \threadsafety It is safe to call this function from any thread. |
124 | * |
125 | * \since This function is available since SDL 3.2.0. |
126 | * |
127 | * \sa SDL_HasSSE2 |
128 | * \sa SDL_HasSSE3 |
129 | * \sa SDL_HasSSE41 |
130 | * \sa SDL_HasSSE42 |
131 | */ |
132 | extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE(void); |
133 | |
134 | /** |
135 | * Determine whether the CPU has SSE2 features. |
136 | * |
137 | * This always returns false on CPUs that aren't using Intel instruction sets. |
138 | * |
139 | * \returns true if the CPU has SSE2 features or false if not. |
140 | * |
141 | * \threadsafety It is safe to call this function from any thread. |
142 | * |
143 | * \since This function is available since SDL 3.2.0. |
144 | * |
145 | * \sa SDL_HasSSE |
146 | * \sa SDL_HasSSE3 |
147 | * \sa SDL_HasSSE41 |
148 | * \sa SDL_HasSSE42 |
149 | */ |
150 | extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE2(void); |
151 | |
152 | /** |
153 | * Determine whether the CPU has SSE3 features. |
154 | * |
155 | * This always returns false on CPUs that aren't using Intel instruction sets. |
156 | * |
157 | * \returns true if the CPU has SSE3 features or false if not. |
158 | * |
159 | * \threadsafety It is safe to call this function from any thread. |
160 | * |
161 | * \since This function is available since SDL 3.2.0. |
162 | * |
163 | * \sa SDL_HasSSE |
164 | * \sa SDL_HasSSE2 |
165 | * \sa SDL_HasSSE41 |
166 | * \sa SDL_HasSSE42 |
167 | */ |
168 | extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE3(void); |
169 | |
170 | /** |
171 | * Determine whether the CPU has SSE4.1 features. |
172 | * |
173 | * This always returns false on CPUs that aren't using Intel instruction sets. |
174 | * |
175 | * \returns true if the CPU has SSE4.1 features or false if not. |
176 | * |
177 | * \threadsafety It is safe to call this function from any thread. |
178 | * |
179 | * \since This function is available since SDL 3.2.0. |
180 | * |
181 | * \sa SDL_HasSSE |
182 | * \sa SDL_HasSSE2 |
183 | * \sa SDL_HasSSE3 |
184 | * \sa SDL_HasSSE42 |
185 | */ |
186 | extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE41(void); |
187 | |
188 | /** |
189 | * Determine whether the CPU has SSE4.2 features. |
190 | * |
191 | * This always returns false on CPUs that aren't using Intel instruction sets. |
192 | * |
193 | * \returns true if the CPU has SSE4.2 features or false if not. |
194 | * |
195 | * \threadsafety It is safe to call this function from any thread. |
196 | * |
197 | * \since This function is available since SDL 3.2.0. |
198 | * |
199 | * \sa SDL_HasSSE |
200 | * \sa SDL_HasSSE2 |
201 | * \sa SDL_HasSSE3 |
202 | * \sa SDL_HasSSE41 |
203 | */ |
204 | extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE42(void); |
205 | |
206 | /** |
207 | * Determine whether the CPU has AVX features. |
208 | * |
209 | * This always returns false on CPUs that aren't using Intel instruction sets. |
210 | * |
211 | * \returns true if the CPU has AVX features or false if not. |
212 | * |
213 | * \threadsafety It is safe to call this function from any thread. |
214 | * |
215 | * \since This function is available since SDL 3.2.0. |
216 | * |
217 | * \sa SDL_HasAVX2 |
218 | * \sa SDL_HasAVX512F |
219 | */ |
220 | extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX(void); |
221 | |
222 | /** |
223 | * Determine whether the CPU has AVX2 features. |
224 | * |
225 | * This always returns false on CPUs that aren't using Intel instruction sets. |
226 | * |
227 | * \returns true if the CPU has AVX2 features or false if not. |
228 | * |
229 | * \threadsafety It is safe to call this function from any thread. |
230 | * |
231 | * \since This function is available since SDL 3.2.0. |
232 | * |
233 | * \sa SDL_HasAVX |
234 | * \sa SDL_HasAVX512F |
235 | */ |
236 | extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX2(void); |
237 | |
238 | /** |
239 | * Determine whether the CPU has AVX-512F (foundation) features. |
240 | * |
241 | * This always returns false on CPUs that aren't using Intel instruction sets. |
242 | * |
243 | * \returns true if the CPU has AVX-512F features or false if not. |
244 | * |
245 | * \threadsafety It is safe to call this function from any thread. |
246 | * |
247 | * \since This function is available since SDL 3.2.0. |
248 | * |
249 | * \sa SDL_HasAVX |
250 | * \sa SDL_HasAVX2 |
251 | */ |
252 | extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX512F(void); |
253 | |
254 | /** |
255 | * Determine whether the CPU has ARM SIMD (ARMv6) features. |
256 | * |
257 | * This is different from ARM NEON, which is a different instruction set. |
258 | * |
259 | * This always returns false on CPUs that aren't using ARM instruction sets. |
260 | * |
261 | * \returns true if the CPU has ARM SIMD features or false if not. |
262 | * |
263 | * \threadsafety It is safe to call this function from any thread. |
264 | * |
265 | * \since This function is available since SDL 3.2.0. |
266 | * |
267 | * \sa SDL_HasNEON |
268 | */ |
269 | extern SDL_DECLSPEC bool SDLCALL SDL_HasARMSIMD(void); |
270 | |
271 | /** |
272 | * Determine whether the CPU has NEON (ARM SIMD) features. |
273 | * |
274 | * This always returns false on CPUs that aren't using ARM instruction sets. |
275 | * |
276 | * \returns true if the CPU has ARM NEON features or false if not. |
277 | * |
278 | * \threadsafety It is safe to call this function from any thread. |
279 | * |
280 | * \since This function is available since SDL 3.2.0. |
281 | */ |
282 | extern SDL_DECLSPEC bool SDLCALL SDL_HasNEON(void); |
283 | |
284 | /** |
285 | * Determine whether the CPU has LSX (LOONGARCH SIMD) features. |
286 | * |
287 | * This always returns false on CPUs that aren't using LOONGARCH instruction |
288 | * sets. |
289 | * |
290 | * \returns true if the CPU has LOONGARCH LSX features or false if not. |
291 | * |
292 | * \threadsafety It is safe to call this function from any thread. |
293 | * |
294 | * \since This function is available since SDL 3.2.0. |
295 | */ |
296 | extern SDL_DECLSPEC bool SDLCALL SDL_HasLSX(void); |
297 | |
298 | /** |
299 | * Determine whether the CPU has LASX (LOONGARCH SIMD) features. |
300 | * |
301 | * This always returns false on CPUs that aren't using LOONGARCH instruction |
302 | * sets. |
303 | * |
304 | * \returns true if the CPU has LOONGARCH LASX features or false if not. |
305 | * |
306 | * \threadsafety It is safe to call this function from any thread. |
307 | * |
308 | * \since This function is available since SDL 3.2.0. |
309 | */ |
310 | extern SDL_DECLSPEC bool SDLCALL SDL_HasLASX(void); |
311 | |
312 | /** |
313 | * Get the amount of RAM configured in the system. |
314 | * |
315 | * \returns the amount of RAM configured in the system in MiB. |
316 | * |
317 | * \threadsafety It is safe to call this function from any thread. |
318 | * |
319 | * \since This function is available since SDL 3.2.0. |
320 | */ |
321 | extern SDL_DECLSPEC int SDLCALL SDL_GetSystemRAM(void); |
322 | |
323 | /** |
324 | * Report the alignment this system needs for SIMD allocations. |
325 | * |
326 | * This will return the minimum number of bytes to which a pointer must be |
327 | * aligned to be compatible with SIMD instructions on the current machine. For |
328 | * example, if the machine supports SSE only, it will return 16, but if it |
329 | * supports AVX-512F, it'll return 64 (etc). This only reports values for |
330 | * instruction sets SDL knows about, so if your SDL build doesn't have |
331 | * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and |
332 | * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. |
333 | * Plan accordingly. |
334 | * |
335 | * \returns the alignment in bytes needed for available, known SIMD |
336 | * instructions. |
337 | * |
338 | * \threadsafety It is safe to call this function from any thread. |
339 | * |
340 | * \since This function is available since SDL 3.2.0. |
341 | * |
342 | * \sa SDL_aligned_alloc |
343 | * \sa SDL_aligned_free |
344 | */ |
345 | extern SDL_DECLSPEC size_t SDLCALL SDL_GetSIMDAlignment(void); |
346 | |
347 | /* Ends C function definitions when using C++ */ |
348 | #ifdef __cplusplus |
349 | } |
350 | #endif |
351 | #include <SDL3/SDL_close_code.h> |
352 | |
353 | #endif /* SDL_cpuinfo_h_ */ |
354 | |