Creator: Add CPU check on startup
This adds an sse42 cpu check on startup for both linux and windows, mac has been excluded, since there are no intel based macs that do not support SSE42. The way this works is, we count on the OS to initialize the shared libraries in the order they are linked (which currently holds true) before calling the initialization code in the main executable. This allows us to check the CPU before running any of the code in the main executable that might not be supported by the current isa. Changing those build flags is for a future PR, but for now and for future reference: blender_cpu_check must be build without optimized CPU flags so it'll be able to run on older CPUs. some code has been duplicated from blenlib, there's really no way around that since we cannot link blenlib as it may be build with optimized cpu flags. Windows currently gives a popup to inform the user, while linux reports to the console, there may be better ways to communicate with linux users with perhaps some generic GUI popup, but I'm unaware of these and will leave this for the linux platform maintainer to polish. Part of #116592 Pull Request: https://projects.blender.org/blender/blender/pulls/118054
This commit is contained in:
parent
c473a165b8
commit
0326b29899
|
@ -387,6 +387,18 @@ else()
|
|||
set(WITH_SYSTEM_EIGEN3 OFF)
|
||||
endif()
|
||||
|
||||
if((NOT WITH_PYTHON_MODULE) AND (
|
||||
(WIN32 AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")) OR
|
||||
((UNIX AND NOT APPLE) AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"))))
|
||||
option(WITH_CPU_CHECK "\
|
||||
Report when a CPU is not compatible on startup \
|
||||
instead of failing to start with an inscrutable error."
|
||||
ON
|
||||
)
|
||||
mark_as_advanced(WITH_CPU_CHECK)
|
||||
else()
|
||||
set(WITH_CPU_CHECK OFF)
|
||||
endif()
|
||||
|
||||
# Modifiers
|
||||
option(WITH_MOD_FLUID "Enable Mantaflow Fluid Simulation Framework" ON)
|
||||
|
|
|
@ -327,6 +327,31 @@ if(WITH_PYTHON_MODULE)
|
|||
|
||||
else()
|
||||
add_executable(blender ${EXETYPE} ${SRC})
|
||||
if(WITH_CPU_CHECK)
|
||||
target_compile_definitions(blender PRIVATE WITH_CPU_CHECK)
|
||||
# we cannot directly link against any blender libraries for the cpu_check module
|
||||
# as they may have been build for an ISA that is unsupported by the CPU
|
||||
# running this code.
|
||||
add_library(blender_cpu_check SHARED
|
||||
creator_cpu_check.cc
|
||||
)
|
||||
target_link_libraries(blender_cpu_check
|
||||
PRIVATE ${PLATFORM_LINKLIBS}
|
||||
)
|
||||
# blender_cpu_check *NEEDS* to be linked first, there can be no exceptions
|
||||
# to this, this is to ensure this will be the first code to run once the
|
||||
# blender binary has been loaded by the OS.
|
||||
target_link_libraries(blender PRIVATE blender_cpu_check)
|
||||
if(NOT WIN32)
|
||||
set(_LIB_SUB_FOLDER "lib/")
|
||||
endif()
|
||||
set_target_properties(blender_cpu_check
|
||||
PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}"
|
||||
)
|
||||
unset(_LIB_SUB_FOLDER)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_executable(blender-launcher WIN32
|
||||
blender_launcher_win32.c
|
||||
|
@ -690,6 +715,13 @@ if(UNIX AND NOT APPLE)
|
|||
DESTINATION "."
|
||||
)
|
||||
|
||||
if(WITH_CPU_CHECK)
|
||||
install(
|
||||
TARGETS blender_cpu_check
|
||||
DESTINATION "./lib"
|
||||
)
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
|
||||
|
@ -745,7 +777,6 @@ file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0.0.0)\n
|
|||
TARGETS blender
|
||||
DESTINATION "./bin"
|
||||
)
|
||||
|
||||
# Misc files.
|
||||
install(
|
||||
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
|
||||
|
@ -1850,6 +1881,13 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE)
|
|||
COMPONENT Blender
|
||||
DESTINATION "."
|
||||
)
|
||||
if(WITH_CPU_CHECK)
|
||||
install(
|
||||
TARGETS blender_cpu_check
|
||||
COMPONENT Blender
|
||||
DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
set_target_properties(
|
||||
blender
|
||||
PROPERTIES
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#ifdef WIN32
|
||||
# include "utfconv.hh"
|
||||
# include <windows.h>
|
||||
# ifdef WITH_CPU_CHECK
|
||||
# pragma comment(linker, "/include:cpu_check_win32")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WITH_TBB_MALLOC) && defined(_MSC_VER) && defined(NDEBUG)
|
||||
|
@ -277,7 +280,6 @@ int main(int argc,
|
|||
)
|
||||
{
|
||||
bContext *C;
|
||||
|
||||
#ifndef WITH_PYTHON_MODULE
|
||||
bArgs *ba;
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup creator
|
||||
*/
|
||||
#include <string>
|
||||
|
||||
#if defined(WIN32)
|
||||
# include <Windows.h>
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* The code below is duplicated from system.c from bf_blenlib. This is on purpose, since bf_blenlib
|
||||
* may be build with CPU flags that are not available on the current cpu so we can't link it. */
|
||||
|
||||
#if !defined(_WIN32)
|
||||
static void __cpuid(
|
||||
/* Cannot be const, because it is modified below.
|
||||
* NOLINTNEXTLINE: readability-non-const-parameter. */
|
||||
int data[4],
|
||||
int selector)
|
||||
{
|
||||
# if defined(__x86_64__)
|
||||
asm("cpuid" : "=a"(data[0]), "=b"(data[1]), "=c"(data[2]), "=d"(data[3]) : "a"(selector));
|
||||
# else
|
||||
(void)selector;
|
||||
data[0] = data[1] = data[2] = data[3] = 0;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cpu_supports_sse42(void)
|
||||
{
|
||||
int result[4], num;
|
||||
__cpuid(result, 0);
|
||||
num = result[0];
|
||||
|
||||
if (num >= 1) {
|
||||
__cpuid(result, 0x00000001);
|
||||
return (result[2] & ((int)1 << 20)) != 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *cpu_brand_string(void)
|
||||
{
|
||||
static char buf[49] = {0};
|
||||
int result[4] = {0};
|
||||
__cpuid(result, 0x80000000);
|
||||
if (result[0] >= (int)0x80000004) {
|
||||
__cpuid((int *)(buf + 0), 0x80000002);
|
||||
__cpuid((int *)(buf + 16), 0x80000003);
|
||||
__cpuid((int *)(buf + 32), 0x80000004);
|
||||
const char *buf_ptr = buf;
|
||||
// Trim any leading spaces.
|
||||
while (*buf_ptr == ' ') {
|
||||
buf_ptr++;
|
||||
}
|
||||
return buf_ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
extern "C" __declspec(dllexport) void cpu_check_win32()
|
||||
{
|
||||
# ifdef _M_X64
|
||||
if (!cpu_supports_sse42()) {
|
||||
std::string error_title = "Unsupported CPU - " + std::string(cpu_brand_string());
|
||||
MessageBoxA(NULL,
|
||||
"Blender requires a CPU with SSE42 support.",
|
||||
error_title.c_str(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
exit(-1);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hinstDLL */, DWORD fdwReason, LPVOID /* lpvReserved */)
|
||||
{
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
cpu_check_win32();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
|
||||
static __attribute__((constructor)) void cpu_check(void)
|
||||
{
|
||||
# ifdef __x86_64
|
||||
if (!cpu_supports_sse42()) {
|
||||
std::string error = "Unsupported CPU - " + std::string(cpu_brand_string()) +
|
||||
"\nBlender requires a CPU with SSE42 support.";
|
||||
printf("%s\n", error.c_str());
|
||||
exit(-1);
|
||||
}
|
||||
return;
|
||||
# endif
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue