1 // VirtualDub - Video processing and capture application
2 // System library component
3 // Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
5 // Beginning with 1.6.0, the VirtualDub system library is licensed
6 // differently than the remainder of VirtualDub. This particular file is
7 // thus licensed as follows (the "zlib" license):
9 // This software is provided 'as-is', without any express or implied
10 // warranty. In no event will the authors be held liable for any
11 // damages arising from the use of this software.
13 // Permission is granted to anyone to use this software for any purpose,
14 // including commercial applications, and to alter it and redistribute it
15 // freely, subject to the following restrictions:
17 // 1. The origin of this software must not be misrepresented; you must
18 // not claim that you wrote the original software. If you use this
19 // software in a product, an acknowledgment in the product
20 // documentation would be appreciated but is not required.
21 // 2. Altered source versions must be plainly marked as such, and must
22 // not be misrepresented as being the original software.
23 // 3. This notice may not be removed or altered from any source
29 #include <vd2/system/win32/intrin.h>
30 #include <vd2/system/cpuaccel.h>
32 static long g_lCPUExtensionsEnabled
;
33 static long g_lCPUExtensionsAvailable
;
36 bool FPU_enabled
, MMX_enabled
, SSE_enabled
, ISSE_enabled
, SSE2_enabled
;
39 #if (!defined(VD_CPU_X86) && !defined(VD_CPU_AMD64)) || defined(__MINGW32__)
40 long CPUCheckForExtensions() {
47 bool VDIsAVXSupportedByOS() {
48 uint32 xfeature_enabled_mask
;
55 mov dword ptr xfeature_enabled_mask
, eax
58 return (xfeature_enabled_mask
& 0x06) == 0x06;
61 extern "C" bool VDIsAVXSupportedByOS();
65 // This code used to use IsProcessorFeaturePresent(), but this function is somewhat
66 // suboptimal in Win64 -- for one thing, it doesn't return true for MMX, at least
68 long CPUCheckForExtensions() {
69 // check for CPUID (x86 only)
74 or dword ptr
[esp
], 00200000h
;set the ID bit
80 if (!(id
& 0x00200000)) {
81 // if we don't have CPUID, we probably won't want to try FPU optimizations
87 // check for features register
88 long flags
= CPUF_SUPPORTS_FPU
| CPUF_SUPPORTS_CPUID
;
97 if (cpuInfo
[3] & (1 << 23))
98 flags
|= CPUF_SUPPORTS_MMX
;
100 if (cpuInfo
[3] & (1 << 25)) {
101 // Check if SSE is actually supported.
102 bool sseSupported
= true;
106 __asm andps xmm0
,xmm0
107 } __except(EXCEPTION_EXECUTE_HANDLER
) {
108 if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION
)
109 sseSupported
= false;
114 flags
|= CPUF_SUPPORTS_SSE
| CPUF_SUPPORTS_INTEGER_SSE
;
116 if (cpuInfo
[3] & (1 << 26))
117 flags
|= CPUF_SUPPORTS_SSE2
;
119 if (cpuInfo
[2] & 0x00000001)
120 flags
|= CPUF_SUPPORTS_SSE3
;
122 if (cpuInfo
[2] & 0x00000200)
123 flags
|= CPUF_SUPPORTS_SSSE3
;
125 if (cpuInfo
[2] & 0x00080000)
126 flags
|= CPUF_SUPPORTS_SSE41
;
128 // check OSXSAVE and AVX bits
129 if ((cpuInfo
[2] & ((1 << 27) | (1 << 28))) == ((1 << 27) | (1 << 28))) {
130 if (VDIsAVXSupportedByOS())
131 flags
|= CPUF_SUPPORTS_AVX
;
136 // check for 3DNow!, 3DNow! extensions
137 __cpuid(cpuInfo
, 0x80000000);
138 if ((unsigned)cpuInfo
[0] >= 0x80000001U
) {
139 __cpuid(cpuInfo
, 0x80000001);
141 if (cpuInfo
[3] & (1 << 31))
142 flags
|= CPUF_SUPPORTS_3DNOW
;
144 if (cpuInfo
[3] & (1 << 30))
145 flags
|= CPUF_SUPPORTS_3DNOW_EXT
;
147 if (cpuInfo
[3] & (1 << 22))
148 flags
|= CPUF_SUPPORTS_INTEGER_SSE
;
155 long CPUEnableExtensions(long lEnableFlags
) {
156 g_lCPUExtensionsEnabled
= lEnableFlags
;
158 MMX_enabled
= !!(g_lCPUExtensionsEnabled
& CPUF_SUPPORTS_MMX
);
159 FPU_enabled
= !!(g_lCPUExtensionsEnabled
& CPUF_SUPPORTS_FPU
);
160 SSE_enabled
= !!(g_lCPUExtensionsEnabled
& CPUF_SUPPORTS_SSE
);
161 ISSE_enabled
= !!(g_lCPUExtensionsEnabled
& CPUF_SUPPORTS_INTEGER_SSE
);
162 SSE2_enabled
= !!(g_lCPUExtensionsEnabled
& CPUF_SUPPORTS_SSE2
);
164 return g_lCPUExtensionsEnabled
;
167 long CPUGetAvailableExtensions() {
168 return g_lCPUExtensionsAvailable
;
171 long CPUGetEnabledExtensions() {
172 return g_lCPUExtensionsEnabled
;
175 void VDCPUCleanupExtensions() {
176 #if defined(VD_CPU_X86)
182 #elif defined(VD_CPU_AMD64)