Improved CPU detection code.
This commit is contained in:
parent
42a2bf73ec
commit
9db58c543f
BIN
asm/cpu-detect.obj
Normal file
BIN
asm/cpu-detect.obj
Normal file
Binary file not shown.
@ -412,6 +412,14 @@ bool x264_is_prerelease(void)
|
||||
return (VER_X264_PRE_RELEASE);
|
||||
}
|
||||
|
||||
/*
|
||||
* CPUID prototype (actual function is in ASM code)
|
||||
*/
|
||||
extern "C"
|
||||
{
|
||||
void x264_cpu_cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect CPU features
|
||||
*/
|
||||
@ -425,7 +433,7 @@ x264_cpu_t x264_detect_cpu_features(int argc, char **argv)
|
||||
|
||||
x264_cpu_t features;
|
||||
SYSTEM_INFO systemInfo;
|
||||
int CPUInfo[4] = {-1};
|
||||
unsigned int CPUInfo[4];
|
||||
char CPUIdentificationString[0x40];
|
||||
char CPUBrandString[0x40];
|
||||
|
||||
@ -434,42 +442,49 @@ x264_cpu_t x264_detect_cpu_features(int argc, char **argv)
|
||||
memset(CPUIdentificationString, 0, sizeof(CPUIdentificationString));
|
||||
memset(CPUBrandString, 0, sizeof(CPUBrandString));
|
||||
|
||||
__cpuid(CPUInfo, 0);
|
||||
memcpy(CPUIdentificationString, &CPUInfo[1], sizeof(int));
|
||||
memcpy(CPUIdentificationString + 4, &CPUInfo[3], sizeof(int));
|
||||
memcpy(CPUIdentificationString + 8, &CPUInfo[2], sizeof(int));
|
||||
x264_cpu_cpuid(0, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||
memcpy(CPUIdentificationString, &CPUInfo[1], 4);
|
||||
memcpy(CPUIdentificationString + 4, &CPUInfo[3], 4);
|
||||
memcpy(CPUIdentificationString + 8, &CPUInfo[2], 4);
|
||||
features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0);
|
||||
strncpy_s(features.vendor, 0x40, CPUIdentificationString, _TRUNCATE);
|
||||
|
||||
if(CPUInfo[0] >= 1)
|
||||
{
|
||||
__cpuid(CPUInfo, 1);
|
||||
features.mmx = (CPUInfo[3] & 0x800000) || false;
|
||||
features.sse = (CPUInfo[3] & 0x2000000) || false;
|
||||
features.sse2 = (CPUInfo[3] & 0x4000000) || false;
|
||||
features.ssse3 = (CPUInfo[2] & 0x200) || false;
|
||||
features.sse3 = (CPUInfo[2] & 0x1) || false;
|
||||
features.ssse3 = (CPUInfo[2] & 0x200) || false;
|
||||
x264_cpu_cpuid(1, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||
features.mmx = (CPUInfo[3] & 0x800000U) || false;
|
||||
features.sse = (CPUInfo[3] & 0x2000000U) || false;
|
||||
features.sse2 = (CPUInfo[3] & 0x4000000U) || false;
|
||||
features.ssse3 = (CPUInfo[2] & 0x200U) || false;
|
||||
features.sse3 = (CPUInfo[2] & 0x1U) || false;
|
||||
features.ssse3 = (CPUInfo[2] & 0x200U) || false;
|
||||
features.stepping = CPUInfo[0] & 0xf;
|
||||
features.model = ((CPUInfo[0] >> 4) & 0xf) + (((CPUInfo[0] >> 16) & 0xf) << 4);
|
||||
features.family = ((CPUInfo[0] >> 8) & 0xf) + ((CPUInfo[0] >> 20) & 0xff);
|
||||
if(features.sse) features.mmx2 = true; //MMXEXT is a subset of SSE!
|
||||
}
|
||||
|
||||
__cpuid(CPUInfo, 0x80000000);
|
||||
int nExIds = qMax<int>(qMin<int>(CPUInfo[0], 0x80000004), 0x80000000);
|
||||
x264_cpu_cpuid(0x80000000U, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||
unsigned int nExIds = qBound(0x80000000U, CPUInfo[0], 0x80000004U);
|
||||
|
||||
for(int i = 0x80000002; i <= nExIds; ++i)
|
||||
if((_stricmp(CPUIdentificationString, "AuthenticAMD") == 0) && (nExIds >= 0x80000001U))
|
||||
{
|
||||
__cpuid(CPUInfo, i);
|
||||
x264_cpu_cpuid(0x80000001U, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||
features.mmx2 = features.mmx2 || (CPUInfo[3] & 0x00400000U);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0x80000002U; i <= nExIds; ++i)
|
||||
{
|
||||
x264_cpu_cpuid(i, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||
switch(i)
|
||||
{
|
||||
case 0x80000002:
|
||||
case 0x80000002U:
|
||||
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
|
||||
break;
|
||||
case 0x80000003:
|
||||
case 0x80000003U:
|
||||
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
|
||||
break;
|
||||
case 0x80000004:
|
||||
case 0x80000004U:
|
||||
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
|
||||
break;
|
||||
}
|
||||
@ -517,11 +532,13 @@ x264_cpu_t x264_detect_cpu_features(int argc, char **argv)
|
||||
{
|
||||
if(!_stricmp("--force-cpu-no-64bit", argv[i])) { flag = true; features.x64 = false; }
|
||||
if(!_stricmp("--force-cpu-no-mmx", argv[i])) { flag = true; features.mmx = false; }
|
||||
if(!_stricmp("--force-cpu-no-mmx2", argv[i])) { flag = true; features.mmx2 = false; }
|
||||
if(!_stricmp("--force-cpu-no-sse", argv[i])) { flag = true; features.sse = features.sse2 = features.sse3 = features.ssse3 = false; }
|
||||
if(!_stricmp("--force-cpu-no-intel", argv[i])) { flag = true; features.intel = false; }
|
||||
|
||||
if(!_stricmp("--force-cpu-have-64bit", argv[i])) { flag = true; features.x64 = true; }
|
||||
if(!_stricmp("--force-cpu-have-mmx", argv[i])) { flag = true; features.mmx = true; }
|
||||
if(!_stricmp("--force-cpu-have-mmx2", argv[i])) { flag = true; features.mmx2 = true; }
|
||||
if(!_stricmp("--force-cpu-have-sse", argv[i])) { flag = true; features.sse = features.sse2 = features.sse3 = features.ssse3 = true; }
|
||||
if(!_stricmp("--force-cpu-have-intel", argv[i])) { flag = true; features.intel = true; }
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ typedef struct
|
||||
int count;
|
||||
bool x64;
|
||||
bool mmx;
|
||||
bool mmx2;
|
||||
bool sse;
|
||||
bool sse2;
|
||||
bool sse3;
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -59,13 +59,22 @@ static int x264_main(int argc, char* argv[])
|
||||
qDebug(" CPU vendor id : %s (Intel: %s)", cpuFeatures.vendor, X264_BOOL(cpuFeatures.intel));
|
||||
qDebug("CPU brand string : %s", cpuFeatures.brand);
|
||||
qDebug(" CPU signature : Family: %d, Model: %d, Stepping: %d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping);
|
||||
qDebug("CPU capabilities : MMX: %s, SSE: %s, SSE2: %s, SSE3: %s, SSSE3: %s, x64: %s", X264_BOOL(cpuFeatures.mmx), X264_BOOL(cpuFeatures.sse), X264_BOOL(cpuFeatures.sse2), X264_BOOL(cpuFeatures.sse3), X264_BOOL(cpuFeatures.ssse3), X264_BOOL(cpuFeatures.x64));
|
||||
qDebug("CPU capabilities : MMX=%s, MMXEXT=%s, SSE=%s, SSE2=%s, SSE3=%s, SSSE3=%s, X64=%s", X264_BOOL(cpuFeatures.mmx), X264_BOOL(cpuFeatures.mmx2), X264_BOOL(cpuFeatures.sse), X264_BOOL(cpuFeatures.sse2), X264_BOOL(cpuFeatures.sse3), X264_BOOL(cpuFeatures.ssse3), X264_BOOL(cpuFeatures.x64));
|
||||
qDebug(" Number of CPU's : %d\n", cpuFeatures.count);
|
||||
|
||||
//Make sure this CPU can run x264
|
||||
if(!(cpuFeatures.mmx && cpuFeatures.sse))
|
||||
//Make sure this CPU can run x264 (requires MMX + MMXEXT/iSSE to run x264 with ASM enabled, additionally requires SSE1 for most x264 builds)
|
||||
if(!(cpuFeatures.mmx && cpuFeatures.mmx2))
|
||||
{
|
||||
qFatal("Sorry, but this machine is not physically capable of running x264. Please get a CPU that supports at least the MMX and ISSE instruction sets!");
|
||||
qFatal("Sorry, but this machine is not physically capable of running x264. Please get a CPU that supports at least the MMX and MMXEXT instruction sets!");
|
||||
}
|
||||
else if(!(cpuFeatures.mmx && cpuFeatures.sse))
|
||||
{
|
||||
qWarning("WARNING: System does not support SSE1, most x264 builds will not work !!!\n");
|
||||
for(;;)
|
||||
{
|
||||
int ret = MessageBoxW(NULL, L"BIG FAT WARNING: This machine apparently does NOT support the SSE1 instruction set and thus probably will NOT be able to run x264!", L"Simple x264 Launcher", MB_ABORTRETRYIGNORE|MB_TOPMOST|MB_ICONEXCLAMATION);
|
||||
if(ret == IDIGNORE) break; else if(ret == IDRETRY) continue; else return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Initialize Qt
|
||||
|
@ -260,6 +260,9 @@ copy "$(SolutionDir)res\toolset\*.exe" "$(SolutionDir)bin\$(Configuration)\tools
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="x264_launcher.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="asm\cpu-detect.obj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -19,6 +19,9 @@
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{961e9f99-8107-45a2-984d-188819a67e8e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Assembly">
|
||||
<UniqueIdentifier>{2c9c8836-2259-4412-894e-7cc32bef99de}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ReadMe.txt" />
|
||||
@ -142,4 +145,9 @@
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="asm\cpu-detect.obj">
|
||||
<Filter>Assembly</Filter>
|
||||
</Object>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user