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);
|
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
|
* Detect CPU features
|
||||||
*/
|
*/
|
||||||
@ -425,7 +433,7 @@ x264_cpu_t x264_detect_cpu_features(int argc, char **argv)
|
|||||||
|
|
||||||
x264_cpu_t features;
|
x264_cpu_t features;
|
||||||
SYSTEM_INFO systemInfo;
|
SYSTEM_INFO systemInfo;
|
||||||
int CPUInfo[4] = {-1};
|
unsigned int CPUInfo[4];
|
||||||
char CPUIdentificationString[0x40];
|
char CPUIdentificationString[0x40];
|
||||||
char CPUBrandString[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(CPUIdentificationString, 0, sizeof(CPUIdentificationString));
|
||||||
memset(CPUBrandString, 0, sizeof(CPUBrandString));
|
memset(CPUBrandString, 0, sizeof(CPUBrandString));
|
||||||
|
|
||||||
__cpuid(CPUInfo, 0);
|
x264_cpu_cpuid(0, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||||
memcpy(CPUIdentificationString, &CPUInfo[1], sizeof(int));
|
memcpy(CPUIdentificationString, &CPUInfo[1], 4);
|
||||||
memcpy(CPUIdentificationString + 4, &CPUInfo[3], sizeof(int));
|
memcpy(CPUIdentificationString + 4, &CPUInfo[3], 4);
|
||||||
memcpy(CPUIdentificationString + 8, &CPUInfo[2], sizeof(int));
|
memcpy(CPUIdentificationString + 8, &CPUInfo[2], 4);
|
||||||
features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0);
|
features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0);
|
||||||
strncpy_s(features.vendor, 0x40, CPUIdentificationString, _TRUNCATE);
|
strncpy_s(features.vendor, 0x40, CPUIdentificationString, _TRUNCATE);
|
||||||
|
|
||||||
if(CPUInfo[0] >= 1)
|
if(CPUInfo[0] >= 1)
|
||||||
{
|
{
|
||||||
__cpuid(CPUInfo, 1);
|
x264_cpu_cpuid(1, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||||
features.mmx = (CPUInfo[3] & 0x800000) || false;
|
features.mmx = (CPUInfo[3] & 0x800000U) || false;
|
||||||
features.sse = (CPUInfo[3] & 0x2000000) || false;
|
features.sse = (CPUInfo[3] & 0x2000000U) || false;
|
||||||
features.sse2 = (CPUInfo[3] & 0x4000000) || false;
|
features.sse2 = (CPUInfo[3] & 0x4000000U) || false;
|
||||||
features.ssse3 = (CPUInfo[2] & 0x200) || false;
|
features.ssse3 = (CPUInfo[2] & 0x200U) || false;
|
||||||
features.sse3 = (CPUInfo[2] & 0x1) || false;
|
features.sse3 = (CPUInfo[2] & 0x1U) || false;
|
||||||
features.ssse3 = (CPUInfo[2] & 0x200) || false;
|
features.ssse3 = (CPUInfo[2] & 0x200U) || false;
|
||||||
features.stepping = CPUInfo[0] & 0xf;
|
features.stepping = CPUInfo[0] & 0xf;
|
||||||
features.model = ((CPUInfo[0] >> 4) & 0xf) + (((CPUInfo[0] >> 16) & 0xf) << 4);
|
features.model = ((CPUInfo[0] >> 4) & 0xf) + (((CPUInfo[0] >> 16) & 0xf) << 4);
|
||||||
features.family = ((CPUInfo[0] >> 8) & 0xf) + ((CPUInfo[0] >> 20) & 0xff);
|
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);
|
x264_cpu_cpuid(0x80000000U, &CPUInfo[0], &CPUInfo[1], &CPUInfo[2], &CPUInfo[3]);
|
||||||
int nExIds = qMax<int>(qMin<int>(CPUInfo[0], 0x80000004), 0x80000000);
|
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)
|
switch(i)
|
||||||
{
|
{
|
||||||
case 0x80000002:
|
case 0x80000002U:
|
||||||
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
|
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
|
||||||
break;
|
break;
|
||||||
case 0x80000003:
|
case 0x80000003U:
|
||||||
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
|
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
|
||||||
break;
|
break;
|
||||||
case 0x80000004:
|
case 0x80000004U:
|
||||||
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
|
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
|
||||||
break;
|
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-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-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-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-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-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-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-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; }
|
if(!_stricmp("--force-cpu-have-intel", argv[i])) { flag = true; features.intel = true; }
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ typedef struct
|
|||||||
int count;
|
int count;
|
||||||
bool x64;
|
bool x64;
|
||||||
bool mmx;
|
bool mmx;
|
||||||
|
bool mmx2;
|
||||||
bool sse;
|
bool sse;
|
||||||
bool sse2;
|
bool sse2;
|
||||||
bool sse3;
|
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 vendor id : %s (Intel: %s)", cpuFeatures.vendor, X264_BOOL(cpuFeatures.intel));
|
||||||
qDebug("CPU brand string : %s", cpuFeatures.brand);
|
qDebug("CPU brand string : %s", cpuFeatures.brand);
|
||||||
qDebug(" CPU signature : Family: %d, Model: %d, Stepping: %d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping);
|
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);
|
qDebug(" Number of CPU's : %d\n", cpuFeatures.count);
|
||||||
|
|
||||||
//Make sure this CPU can run x264
|
//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.sse))
|
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
|
//Initialize Qt
|
||||||
|
@ -260,6 +260,9 @@ copy "$(SolutionDir)res\toolset\*.exe" "$(SolutionDir)bin\$(Configuration)\tools
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="x264_launcher.rc" />
|
<ResourceCompile Include="x264_launcher.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Object Include="asm\cpu-detect.obj" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
<Filter Include="Generated Files">
|
<Filter Include="Generated Files">
|
||||||
<UniqueIdentifier>{961e9f99-8107-45a2-984d-188819a67e8e}</UniqueIdentifier>
|
<UniqueIdentifier>{961e9f99-8107-45a2-984d-188819a67e8e}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Assembly">
|
||||||
|
<UniqueIdentifier>{2c9c8836-2259-4412-894e-7cc32bef99de}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="ReadMe.txt" />
|
<None Include="ReadMe.txt" />
|
||||||
@ -142,4 +145,9 @@
|
|||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Object Include="asm\cpu-detect.obj">
|
||||||
|
<Filter>Assembly</Filter>
|
||||||
|
</Object>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user