Windows: Add ARM64 support

* Only works on machines with a Qualcomm Snapdragon 8cx Gen3 or above.
  Older generation devices are not and will not be supported due to
  some driver issues
* Requires VS2022 for building.
* Uses new MSVC preprocessor for sse2neon compatibility.
* SIMD is not enabled, waiting on conversion of blenlib to C++.

Ref #119126

Pull Request: https://projects.blender.org/blender/blender/pulls/117036
This commit is contained in:
Anthony Roberts 2024-03-06 15:46:43 +01:00 committed by Brecht Van Lommel
parent 3d5fa7698f
commit 445fd42c61
32 changed files with 233 additions and 53 deletions

@ -640,7 +640,7 @@ mark_as_advanced(WITH_CYCLES_PRECOMPUTE)
mark_as_advanced(CYCLES_TEST_DEVICES) mark_as_advanced(CYCLES_TEST_DEVICES)
# NVIDIA CUDA & OptiX # NVIDIA CUDA & OptiX
if(NOT APPLE) if(NOT APPLE AND NOT (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES ARM64))
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON) option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON) option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA) mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
@ -675,7 +675,7 @@ When set, this path will be used at runtime to compile OptiX kernels."
endif() endif()
# AMD HIP # AMD HIP
if(NOT APPLE) if(NOT APPLE AND NOT (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES ARM64))
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON) option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF) option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
# Radeon VII (gfx906) not currently working with HIP SDK, so left out of the list. # Radeon VII (gfx906) not currently working with HIP SDK, so left out of the list.
@ -702,7 +702,7 @@ if(APPLE)
endif() endif()
# oneAPI # oneAPI
if(NOT APPLE) if(NOT APPLE AND NOT (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES ARM64))
option(WITH_CYCLES_DEVICE_ONEAPI "Enable Cycles oneAPI compute support" OFF) option(WITH_CYCLES_DEVICE_ONEAPI "Enable Cycles oneAPI compute support" OFF)
option(WITH_CYCLES_ONEAPI_BINARIES "\ option(WITH_CYCLES_ONEAPI_BINARIES "\
Enable Ahead-Of-Time compilation for Cycles oneAPI device" Enable Ahead-Of-Time compilation for Cycles oneAPI device"
@ -2140,8 +2140,14 @@ set(CMAKE_CXX_EXTENSIONS OFF)
# Make MSVC properly report the value of the __cplusplus preprocessor macro # Make MSVC properly report the value of the __cplusplus preprocessor macro
# Available MSVC 15.7 (1914) and up, without this it reports 199711L regardless # Available MSVC 15.7 (1914) and up, without this it reports 199711L regardless
# of the C++ standard chosen above. # of the C++ standard chosen above.
# In addition, for ARM64 devices, we need to tell MSVC to use the new preprocessor
# This is because sse2neon requires it.
if(MSVC) if(MSVC)
string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus") string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus")
if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
string(APPEND CMAKE_CXX_FLAGS " /Zc:preprocessor")
string(APPEND CMAKE_C_FLAGS " /Zc:preprocessor")
endif()
endif() endif()
# Visual Studio has all standards it supports available by default # Visual Studio has all standards it supports available by default

@ -87,12 +87,17 @@ endif()
if(NOT APPLE) if(NOT APPLE)
set(WITH_XR_OPENXR ON CACHE BOOL "" FORCE) set(WITH_XR_OPENXR ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE) # Can't use CMAKE_SYSTEM_PROCESSOR here as it's not set yet,
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE) # so fall back to checking the env for vcvarsall's VSCMD_ARG_TGT_ARCH
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE) if(NOT (WIN32 AND "$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "arm64"))
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE) set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE) set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
endif()
endif() endif()
if(WIN32)
set(WITH_CYCLES_DEVICE_HIPRT ON CACHE BOOL "" FORCE) if(WIN32 AND NOT (WIN32 AND "$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "arm64"))
set(WITH_CYCLES_DEVICE_HIPRT ON CACHE BOOL "" FORCE)
endif() endif()

@ -257,7 +257,11 @@ set(PLATFORM_LINKFLAGS_RELEASE "${PLATFORM_LINKFLAGS} ${PDB_INFO_OVERRIDE_LINKER
string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221") string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221")
if(CMAKE_CL_64) if(CMAKE_CL_64)
string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:X64 ") if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:ARM64 ")
else()
string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:X64 ")
endif()
else() else()
string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ") string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ")
endif() endif()
@ -266,7 +270,11 @@ if(NOT DEFINED LIBDIR)
# Setup 64bit and 64bit windows systems # Setup 64bit and 64bit windows systems
if(CMAKE_CL_64) if(CMAKE_CL_64)
message(STATUS "64 bit compiler detected.") message(STATUS "64 bit compiler detected.")
set(LIBDIR_BASE "windows_x64") if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
set(LIBDIR_BASE "windows_arm64")
else()
set(LIBDIR_BASE "windows_x64")
endif()
else() else()
message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder") message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder")
endif() endif()
@ -604,9 +612,15 @@ if(NOT WITH_WINDOWS_FIND_MODULES)
if(NOT BOOST_VERSION) if(NOT BOOST_VERSION)
message(FATAL_ERROR "Unable to determine Boost version") message(FATAL_ERROR "Unable to determine Boost version")
endif() endif()
set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}") if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
set(BOOST_DEBUG_POSTFIX "vc142-mt-gyd-x64-${BOOST_VERSION}") set(BOOST_POSTFIX "vc143-mt-a64-${BOOST_VERSION}")
set(BOOST_PREFIX "") set(BOOST_DEBUG_POSTFIX "vc143-mt-gyd-a64-${BOOST_VERSION}")
set(BOOST_PREFIX "")
else()
set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}")
set(BOOST_DEBUG_POSTFIX "vc142-mt-gyd-x64-${BOOST_VERSION}")
set(BOOST_PREFIX "")
endif()
endif() endif()
if(WITH_BOOST) if(WITH_BOOST)
@ -625,8 +639,9 @@ if(WITH_BOOST)
if(NOT Boost_FOUND) if(NOT Boost_FOUND)
warn_hardcoded_paths(BOOST) warn_hardcoded_paths(BOOST)
# This is file new in 3.4 if it does not exist, assume we are building against 3.3 libs # This is file new in 3.4 if it does not exist, assume we are building against 3.3 libs
# Note, as ARM64 was introduced in 4.x, this check is not needed
set(BOOST_34_TRIGGER_FILE ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_python${_PYTHON_VERSION_NO_DOTS}-${BOOST_DEBUG_POSTFIX}.lib) set(BOOST_34_TRIGGER_FILE ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_python${_PYTHON_VERSION_NO_DOTS}-${BOOST_DEBUG_POSTFIX}.lib)
if(NOT EXISTS ${BOOST_34_TRIGGER_FILE}) if (NOT EXISTS ${BOOST_34_TRIGGER_FILE})
set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}") set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}")
set(BOOST_PREFIX "lib") set(BOOST_PREFIX "lib")
endif() endif()
@ -893,6 +908,15 @@ if(WITH_CODEC_SNDFILE)
endif() endif()
endif() endif()
if(WITH_CPU_SIMD AND SUPPORT_NEON_BUILD)
windows_find_package(sse2neon)
if(NOT SSE2NEON_FOUND)
set(SSE2NEON_ROOT_DIR ${LIBDIR}/sse2neon)
set(SSE2NEON_INCLUDE_DIRS ${LIBDIR}/sse2neon)
set(SSE2NEON_FOUND True)
endif()
endif()
if(WITH_CYCLES AND WITH_CYCLES_OSL) if(WITH_CYCLES AND WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
set(OSL_SHADER_DIR ${CYCLES_OSL}/shaders) set(OSL_SHADER_DIR ${CYCLES_OSL}/shaders)

@ -1,4 +1,8 @@
set BUILD_VS_LIBDIR=lib/windows_x64 if "%BUILD_ARCH%" == "arm64" (
set BUILD_VS_LIBDIR=lib/windows_arm64
) else (
set BUILD_VS_LIBDIR=lib/windows_x64
)
if NOT "%verbose%" == "" ( if NOT "%verbose%" == "" (
echo Library Directory = "%BUILD_VS_LIBDIR%" echo Library Directory = "%BUILD_VS_LIBDIR%"

@ -19,6 +19,11 @@ if "%WITH_PYDEBUG%"=="1" (
set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On
) )
if "%BUILD_ARCH%"=="arm64" (
set MSBUILD_PLATFORM=arm64
set BUILD_PLATFORM_SELECT=-A ARM64
)
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS% set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS%
if NOT EXIST %BUILD_DIR%\nul ( if NOT EXIST %BUILD_DIR%\nul (

@ -5,12 +5,18 @@ if "%BUILD_ARCH%"=="" (
) else if "%PROCESSOR_ARCHITEW6432%" == "AMD64" ( ) else if "%PROCESSOR_ARCHITEW6432%" == "AMD64" (
set WINDOWS_ARCH= Win64 set WINDOWS_ARCH= Win64
set BUILD_ARCH=x64 set BUILD_ARCH=x64
) else if "%PROCESSOR_ARCHITECTURE%" == "ARM64" (
set WINDOWS_ARCH= arm64
set BUILD_ARCH=arm64
) else ( ) else (
echo Error: 32 bit builds of blender are no longer supported. echo Error: 32 bit builds of blender are no longer supported.
goto ERR goto ERR
) )
) else if "%BUILD_ARCH%"=="x64" ( ) else if "%BUILD_ARCH%"=="x64" (
set WINDOWS_ARCH= Win64 set WINDOWS_ARCH= Win64
) else if "%BUILD_ARCH%"=="arm64" (
set WINDOWS_ARCH= arm64
set BUILD_ARCH=arm64
) )
:EOF :EOF
exit /b 0 exit /b 0

@ -23,6 +23,24 @@ if EXIST %PYTHON% (
goto detect_python_done goto detect_python_done
) )
rem Additionally check for the ARM64 version
set PYTHON=%BLENDER_DIR%\lib\windows_arm64\python\310\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\lib\windows_arm64\python\311\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\lib\windows_arm64\python\312\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
set PYTHON=%BLENDER_DIR%\lib\windows_arm64\python\39\bin\python.exe
if EXIST %PYTHON% (
goto detect_python_done
)
if NOT EXIST %PYTHON% ( if NOT EXIST %PYTHON% (
if EXIST %BLENDER_DIR%\lib\windows_x64\.git ( if EXIST %BLENDER_DIR%\lib\windows_x64\.git (
echo Warning: Python not found, there is likely an issue with the library folder echo Warning: Python not found, there is likely an issue with the library folder

@ -3,6 +3,11 @@ if EXIST %BLENDER_DIR%\lib\windows_x64\llvm\bin\clang-format.exe (
goto detect_done goto detect_done
) )
if EXIST %BLENDER_DIR%\lib\windows_arm64\llvm\bin\clang-format.exe (
set CF_PATH=lib\windows_arm64\llvm\bin
goto detect_done
)
echo clang-format not found echo clang-format not found
exit /b 1 exit /b 1

@ -50,6 +50,8 @@ if NOT "%1" == "" (
goto ERR goto ERR
) else if "%1" == "x64" ( ) else if "%1" == "x64" (
set BUILD_ARCH=x64 set BUILD_ARCH=x64
) else if "%1" == "arm64" (
set BUILD_ARCH=arm64
) else if "%1" == "2019" ( ) else if "%1" == "2019" (
set BUILD_VS_YEAR=2019 set BUILD_VS_YEAR=2019
) else if "%1" == "2019pre" ( ) else if "%1" == "2019pre" (

@ -9,7 +9,11 @@ cd "%BLENDER_DIR%/scripts/addons"
for /f "delims=" %%i in ('"%GIT%" rev-parse --abbrev-ref HEAD') do echo Addons_Branch_name=%%i for /f "delims=" %%i in ('"%GIT%" rev-parse --abbrev-ref HEAD') do echo Addons_Branch_name=%%i
for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Addons_Branch_hash=%%i for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Addons_Branch_hash=%%i
cd "%BLENDER_DIR%/lib/windows_x64" if "%BUILD_ARCH%" == "arm64" (
cd "%BLENDER_DIR%/lib/windows_arm64"
) else (
cd "%BLENDER_DIR%/lib/windows_x64"
)
for /f "delims=" %%i in ('"%GIT%" rev-parse --abbrev-ref HEAD') do echo Libs_Branch_name=%%i for /f "delims=" %%i in ('"%GIT%" rev-parse --abbrev-ref HEAD') do echo Libs_Branch_name=%%i
for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Libs_Branch_hash=%%i for /f "delims=" %%i in ('"%GIT%" rev-parse HEAD') do echo Libs_Branch_hash=%%i

@ -127,7 +127,7 @@ typedef uint32_t cuuint32_t;
typedef uint64_t cuuint64_t; typedef uint64_t cuuint64_t;
#endif #endif
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__) || defined(__ppc64__) || defined(__PPC64__) #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__) || defined(_M_ARM64) || defined(__ppc64__) || defined(__PPC64__)
typedef unsigned long long CUdeviceptr; typedef unsigned long long CUdeviceptr;
#else #else
typedef unsigned int CUdeviceptr; typedef unsigned int CUdeviceptr;

@ -86,7 +86,7 @@ typedef uint32_t hipuint32_t;
typedef uint64_t hipuint64_t; typedef uint64_t hipuint64_t;
#endif #endif
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__) || defined(__ppc64__) || defined(__PPC64__) #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__) || defined(_M_ARM64) || defined(__ppc64__) || defined(__PPC64__)
typedef unsigned long long hipDeviceptr_t; typedef unsigned long long hipDeviceptr_t;
#else #else
typedef unsigned int hipDeviceptr_t; typedef unsigned int hipDeviceptr_t;

@ -2,4 +2,4 @@ Project: miniLZO - mini subset of the LZO real-time data compression librar
URL: http://www.oberhumer.com/opensource/lzo/ URL: http://www.oberhumer.com/opensource/lzo/
License: GPLv2+ License: GPLv2+
Upstream version: 2.08 Upstream version: 2.08
Local modifications: None Local modifications: Add #ifdef for Windows ARM64 (MSVC) platforms

@ -770,7 +770,7 @@
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) #elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1 # define LZO_ARCH_I086 1
# define LZO_INFO_ARCH "i086" # define LZO_INFO_ARCH "i086"
#elif defined(__aarch64__) #elif defined(__aarch64__) || defined(_M_ARM64)
# define LZO_ARCH_ARM64 1 # define LZO_ARCH_ARM64 1
# define LZO_INFO_ARCH "arm64" # define LZO_INFO_ARCH "arm64"
#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) #elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)

@ -790,7 +790,7 @@
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) #elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1 # define LZO_ARCH_I086 1
# define LZO_INFO_ARCH "i086" # define LZO_INFO_ARCH "i086"
#elif defined(__aarch64__) #elif defined(__aarch64__) || defined(_M_ARM64)
# define LZO_ARCH_ARM64 1 # define LZO_ARCH_ARM64 1
# define LZO_INFO_ARCH "arm64" # define LZO_INFO_ARCH "arm64"
#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) #elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)

@ -22,6 +22,10 @@
# include "GHOST_ContextVK.hh" # include "GHOST_ContextVK.hh"
#endif #endif
#ifdef WIN32
# include "BLI_path_util.h"
#endif
#include <Dwmapi.h> #include <Dwmapi.h>
#include <assert.h> #include <assert.h>
@ -127,15 +131,27 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
if (!setDrawingContextType(type)) { if (!setDrawingContextType(type)) {
const char *title = "Blender - Unsupported Graphics Card Configuration"; const char *title = "Blender - Unsupported Graphics Card Configuration";
const char *text = const char *text = "";
"A graphics card and driver with support for OpenGL 4.3 or higher is " #if defined(WIN32)
"required.\n\nInstalling the latest driver for your graphics card might resolve the " if (strncmp(BLI_getenv("PROCESSOR_IDENTIFIER"), "ARM", 3) == 0) {
"issue."; text =
if (GetSystemMetrics(SM_CMONITORS) > 1) { "A driver with support for OpenGL 4.3 or higher is required.\n\n"
"If you are on a Qualcomm 8cx Gen3 device or newer, you need to download the"
"\"OpenCL™, OpenGL®, and Vulkan® Compatibility Pack\" from the MS Store.";
}
else
#endif
{
text = text =
"A graphics card and driver with support for OpenGL 4.3 or higher is " "A graphics card and driver with support for OpenGL 4.3 or higher is "
"required.\n\nPlugging all monitors into your primary graphics card might resolve " "required.\n\nInstalling the latest driver for your graphics card might resolve the "
"this issue. Installing the latest driver for your graphics card could also help."; "issue.";
if (GetSystemMetrics(SM_CMONITORS) > 1) {
text =
"A graphics card and driver with support for OpenGL 4.3 or higher is "
"required.\n\nPlugging all monitors into your primary graphics card might resolve "
"this issue. Installing the latest driver for your graphics card could also help.";
}
} }
MessageBox(m_hWnd, text, title, MB_OK | MB_ICONERROR); MessageBox(m_hWnd, text, title, MB_OK | MB_ICONERROR);
::ReleaseDC(m_hWnd, m_hDC); ::ReleaseDC(m_hWnd, m_hDC);

@ -28,13 +28,23 @@
#define PACKETMODE 0 #define PACKETMODE 0
#include <pktdef.h> #include <pktdef.h>
#define WINTAB_PRINTF(x, ...) \ #if !defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL
{ \ # define WINTAB_PRINTF(x, ...) \
if (GHOST_Wintab::getDebug()) { \ { \
printf(x, __VA_ARGS__); \ if (GHOST_Wintab::getDebug()) { \
printf(x, __VA_ARGS__); \
} \
} \ } \
} \ (void)0
(void)0 #else
# define WINTAB_PRINTF(x, ...) \
{ \
if (GHOST_Wintab::getDebug()) { \
printf(x, ##__VA_ARGS__); \
} \
} \
(void)0
#endif
/* Typedefs for Wintab functions to allow dynamic loading. */ /* Typedefs for Wintab functions to allow dynamic loading. */
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);

@ -86,7 +86,7 @@
/* Alignment directive */ /* Alignment directive */
#ifdef _WIN64 #ifdef _WIN64
# define ALIGN_STRUCT __declspec(align(64)) # define BLI_ALIGN_STRUCT __declspec(align(64))
#else #else
# define ALIGN_STRUCT # define BLI_ALIGN_STRUCT
#endif #endif

@ -10,7 +10,9 @@
* SIMD instruction support. * SIMD instruction support.
*/ */
#if defined(__ARM_NEON) && defined(WITH_SSE2NEON) // TODO: Re-enable this once blenlib is converted to C++
#if (defined(__ARM_NEON) /* || (defined(_M_ARM64) && defined(_MSC_VER))*/) && \
defined(WITH_SSE2NEON)
/* SSE/SSE2 emulation on ARM Neon. Match SSE precision. */ /* SSE/SSE2 emulation on ARM Neon. Match SSE precision. */
# if !defined(SSE2NEON_PRECISE_MINMAX) # if !defined(SSE2NEON_PRECISE_MINMAX)
# define SSE2NEON_PRECISE_MINMAX 1 # define SSE2NEON_PRECISE_MINMAX 1

@ -127,6 +127,7 @@ static void __cpuid(
char *BLI_cpu_brand_string(void) char *BLI_cpu_brand_string(void)
{ {
#if !defined(_M_ARM64)
char buf[49] = {0}; char buf[49] = {0};
int result[4] = {0}; int result[4] = {0};
__cpuid(result, 0x80000000); __cpuid(result, 0x80000000);
@ -138,11 +139,27 @@ char *BLI_cpu_brand_string(void)
/* TODO(sergey): Make it a bit more presentable by removing trademark. */ /* TODO(sergey): Make it a bit more presentable by removing trademark. */
return brand; return brand;
} }
#else
// No CPUID on ARM64, so we pull from the registry (on Windows) instead
DWORD vendorIdentifierLength = 255;
char vendorIdentifier[255];
if (RegGetValueA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
"VendorIdentifier",
RRF_RT_REG_SZ,
NULL,
&vendorIdentifier,
&vendorIdentifierLength) == ERROR_SUCCESS)
{
return BLI_strdup(vendorIdentifier);
}
#endif
return NULL; return NULL;
} }
int BLI_cpu_support_sse42(void) int BLI_cpu_support_sse42(void)
{ {
#if !defined(_M_ARM64)
int result[4], num; int result[4], num;
__cpuid(result, 0); __cpuid(result, 0);
num = result[0]; num = result[0];
@ -151,6 +168,7 @@ int BLI_cpu_support_sse42(void)
__cpuid(result, 0x00000001); __cpuid(result, 0x00000001);
return (result[2] & ((int)1 << 20)) != 0; return (result[2] & ((int)1 << 20)) != 0;
} }
#endif
return 0; return 0;
} }

@ -144,15 +144,27 @@ static bool BLI_windows_system_backtrace_run_trace(FILE *fp, HANDLE hThread, PCO
symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO); symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
STACKFRAME frame = {0}; STACKFRAME frame = {0};
DWORD machineType = 0;
#if defined(_M_AMD64)
frame.AddrPC.Offset = context->Rip; frame.AddrPC.Offset = context->Rip;
frame.AddrPC.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Rsp; frame.AddrFrame.Offset = context->Rsp;
frame.AddrFrame.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Rsp; frame.AddrStack.Offset = context->Rsp;
frame.AddrStack.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat;
machineType = IMAGE_FILE_MACHINE_AMD64;
#elif defined(_M_ARM64)
frame.AddrPC.Offset = context->Pc;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Fp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Sp;
frame.AddrStack.Mode = AddrModeFlat;
machineType = IMAGE_FILE_MACHINE_ARM64;
#endif
while (true) { while (true) {
if (StackWalk64(IMAGE_FILE_MACHINE_AMD64, if (StackWalk64(machineType,
GetCurrentProcess(), GetCurrentProcess(),
hThread, hThread,
&frame, &frame,

@ -410,7 +410,13 @@ void BLI_spin_lock(SpinLock *spin)
#elif defined(__APPLE__) #elif defined(__APPLE__)
BLI_mutex_lock(spin); BLI_mutex_lock(spin);
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# if defined(_M_ARM64)
// InterlockedExchangeAcquire takes a long arg on MSVC ARM64
static_assert(sizeof(long) == sizeof(SpinLock));
while (InterlockedExchangeAcquire((volatile long *)spin, 1)) {
# else
while (InterlockedExchangeAcquire(spin, 1)) { while (InterlockedExchangeAcquire(spin, 1)) {
# endif
while (*spin) { while (*spin) {
/* Spin-lock hint for processors with hyper-threading. */ /* Spin-lock hint for processors with hyper-threading. */
YieldProcessor(); YieldProcessor();

@ -28,6 +28,13 @@
errtot++; \ errtot++; \
} \ } \
(void)0 (void)0
# elif defined(_MSVC_TRADITIONAL) && !_MSVC_TRADITIONAL
# define ERRMSG(format, ...) \
{ \
fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##__VA_ARGS__); \
errtot++; \
} \
(void)0
# else # else
# define ERRMSG(format, ...) \ # define ERRMSG(format, ...) \
{ \ { \

@ -47,7 +47,9 @@ void Manager::begin_sync()
acquired_textures.clear(); acquired_textures.clear();
layer_attributes.clear(); layer_attributes.clear();
#ifndef NDEBUG // For some reason, if this uninitialised data pattern was enabled (ie release asserts enabled),
// The viewport just gives up rendering objects on ARM64 devices. Possibly Mesa GLOn12-related.
#if !defined(NDEBUG) && !defined(_M_ARM64)
/* Detect uninitialized data. */ /* Detect uninitialized data. */
memset(matrix_buf.current().data(), memset(matrix_buf.current().data(),
0xF0, 0xF0,

@ -431,11 +431,15 @@ static void detect_workarounds()
} }
} }
/* Right now draw shader parameters are broken on Qualcomm devices /* Draw shader parameters are broken on Qualcomm Windows ARM64 devices
* regardless of driver version */ * on Mesa version < 24.0.0 */
if (GPU_type_matches(GPU_DEVICE_QUALCOMM, GPU_OS_WIN, GPU_DRIVER_ANY)) { if (GPU_type_matches(GPU_DEVICE_QUALCOMM, GPU_OS_WIN, GPU_DRIVER_ANY)) {
GCaps.shader_draw_parameters_support = false; if (strstr(version, "Mesa 20.") || strstr(version, "Mesa 21.") ||
GLContext::shader_draw_parameters_support = false; strstr(version, "Mesa 22.") || strstr(version, "Mesa 23."))
{
GCaps.shader_draw_parameters_support = false;
GLContext::shader_draw_parameters_support = false;
}
} }
/* Some Intel drivers have issues with using mips as frame-buffer targets if /* Some Intel drivers have issues with using mips as frame-buffer targets if

@ -102,8 +102,8 @@ else()
endif() endif()
# Keep until APPLE/ARM libraries are updated. # Keep until APPLE/ARM libraries are updated.
if(APPLE) if(APPLE OR WIN32)
if(CMAKE_OSX_ARCHITECTURES MATCHES arm64) if(CMAKE_OSX_ARCHITECTURES MATCHES arm64 OR CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
list(APPEND INC_SYS list(APPEND INC_SYS
${IMATH_INCLUDE_DIRS} ${IMATH_INCLUDE_DIRS}
) )

@ -45,8 +45,8 @@ if(WITH_IMAGE_OPENEXR)
endif() endif()
# Keep until APPLE/ARM libraries are updated. # Keep until APPLE/ARM libraries are updated.
if(APPLE) if(APPLE OR WIN32)
if(CMAKE_OSX_ARCHITECTURES MATCHES arm64) if(CMAKE_OSX_ARCHITECTURES MATCHES arm64 OR CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
list(APPEND INC_SYS list(APPEND INC_SYS
${IMATH_INCLUDE_DIRS} ${IMATH_INCLUDE_DIRS}
) )

@ -52,6 +52,11 @@ if(WIN32)
# warning alert. # warning alert.
# Silence them by restore warn C4100 back to w4 # Silence them by restore warn C4100 back to w4
remove_cc_flag("/w34100") remove_cc_flag("/w34100")
if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
# USD currently does not support the new preprocessor,
# and does not use sse2neon, so we can remove it here
remove_cc_flag("/Zc:preprocessor")
endif()
endif() endif()
set(INC set(INC

@ -791,6 +791,9 @@ StructRNA *ID_code_to_RNA_type(short idcode);
/* macro which inserts the function name */ /* macro which inserts the function name */
#if defined __GNUC__ #if defined __GNUC__
# define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args) # define RNA_warning(format, args...) _RNA_warning("%s: " format "\n", __func__, ##args)
#elif defined(_MSVC_TRADITIONAL) && \
!_MSVC_TRADITIONAL // The "new preprocessor" is enabled via /Zc:preprocessor
# define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, ##__VA_ARGS__)
#else #else
# define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__) # define RNA_warning(format, ...) _RNA_warning("%s: " format "\n", __FUNCTION__, __VA_ARGS__)
#endif #endif

@ -31,7 +31,7 @@
#define BEND_EPS 0.000001f #define BEND_EPS 0.000001f
ALIGN_STRUCT struct DeformUserData { BLI_ALIGN_STRUCT struct DeformUserData {
bool invert_vgroup; bool invert_vgroup;
char mode; char mode;
char deform_axis; char deform_axis;

@ -33,6 +33,11 @@ if(WIN32)
# warning alert. # warning alert.
# Silence them by restore warn C4100 back to w4 # Silence them by restore warn C4100 back to w4
remove_cc_flag("/w34100") remove_cc_flag("/w34100")
if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
# USD currently does not support the new preprocessor,
# and does not use sse2neon, so we can remove it here
remove_cc_flag("/Zc:preprocessor")
endif()
endif() endif()
set(INC set(INC

@ -619,6 +619,11 @@ if(WIN32)
${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise.dll ${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise.dll
${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_core.dll ${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_core.dll
${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_device_cpu.dll ${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_device_cpu.dll
)
endif()
if(EXISTS ${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_device_sycl.dll) # Platforms that have SyCL support
windows_install_shared_manifest(
FILES
${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_device_sycl.dll ${LIBDIR}/OpenImageDenoise/bin/OpenImageDenoise_device_sycl.dll
) )
endif() endif()
@ -1345,14 +1350,20 @@ elseif(WIN32)
endif() endif()
# this will exist for 4.1 lib folders # this will exist for 4.1 lib folders
if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.cp${_PYTHON_VERSION_NO_DOTS}-win_amd64.pyd) if(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
set(_openvdb_arch arm64)
else()
set(_openvdb_arch amd64)
endif()
if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.cp${_PYTHON_VERSION_NO_DOTS}-win_${_openvdb_arch}.pyd)
install( install(
FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.cp${_PYTHON_VERSION_NO_DOTS}-win_amd64.pyd FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.cp${_PYTHON_VERSION_NO_DOTS}-win_${_openvdb_arch}.pyd
DESTINATION ${TARGETDIR_VER}/python/lib/site-packages DESTINATION ${TARGETDIR_VER}/python/lib/site-packages
CONFIGURATIONS Debug CONFIGURATIONS Debug
) )
install( install(
FILES ${LIBDIR}/openvdb/python/pyopenvdb.cp${_PYTHON_VERSION_NO_DOTS}-win_amd64.pyd FILES ${LIBDIR}/openvdb/python/pyopenvdb.cp${_PYTHON_VERSION_NO_DOTS}-win_${_openvdb_arch}.pyd
DESTINATION ${TARGETDIR_VER}/python/lib/site-packages DESTINATION ${TARGETDIR_VER}/python/lib/site-packages
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
) )