Skip to content

Instantly share code, notes, and snippets.

@tycho
Last active March 23, 2018 04:41
Show Gist options
  • Save tycho/0053795c2732655ca0d23dbdba4932a3 to your computer and use it in GitHub Desktop.
Save tycho/0053795c2732655ca0d23dbdba4932a3 to your computer and use it in GitHub Desktop.
Windows 10 ARM64 - ANGLE build
This is my patch for building ANGLE on Windows 10 ARM64. It's not ready for upstream because it breaks
the x86/x86_64 builds -- this isn't out of necessity but rather expedience. I just wanted to get ANGLE
built for the platform quickly.
I did have to copy a bunch of blobs out of C:\Windows\WinSXS to fill some Windows SDK directories (which
aren't present in the actual Windows SDK for some reason):
C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\arm64
C:\Program Files (x86)\Windows Kits\10\Redist\D3D\arm64
>gclient revinfo
.: https://chromium.googlesource.com/angle/angle.git
build: https://chromium.googlesource.com/chromium/src/build.git@2f3b6e8ce9e783b2a09496d70eef2974506a41c8
buildtools: https://chromium.googlesource.com/chromium/buildtools.git@461b345a815c1c745ac0534a6a4bd52d123abe68
buildtools\clang_format\script: https://chromium.googlesource.com/chromium/llvm-project/cfe/tools/clang-format.git@0653eee0c81ea04715c635dd0885e8096ff6ba6d
buildtools\third_party\libc++\trunk: https://chromium.googlesource.com/chromium/llvm-project/libcxx.git@f56f1bba1ade4a408d403ff050d50e837bae47df
buildtools\third_party\libc++abi\trunk: https://chromium.googlesource.com/chromium/llvm-project/libcxxabi.git@05ba3281482304ae8de31123a594972a495da06d
buildtools\third_party\libunwind\trunk: https://chromium.googlesource.com/external/llvm.org/libunwind.git@fc0a910c25d5415dd72ba9451b7cba380e3cc1e7
testing: https://chromium.googlesource.com/chromium/src/testing@6dfa36ab2e5143fa2f7353e3af5d2935af2e61f7
third_party/cherry: https://android.googlesource.com/platform/external/cherry@4f8fb08d33ca5ff05a1c638f04c85bbb8d8b52cc
third_party/deqp/src: https://android.googlesource.com/platform/external/deqp@5bc346ba2d5465a2e6094e254f12b1586fd0097f
third_party/glslang/src: https://android.googlesource.com/platform/external/shaderc/glslang@2edde6665d9a56ead5ea0e55b4e64d9a803e6164
third_party/googletest/src: https://chromium.googlesource.com/external/github.com/google/googletest.git@d175c8bf823e709d570772b038757fadf63bc632
third_party/libpng/src: https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c
third_party/spirv-headers/src: https://android.googlesource.com/platform/external/shaderc/spirv-headers@98b01515724c428d0f0a5d01deffcce0f5f5e61c
third_party/spirv-tools/src: https://android.googlesource.com/platform/external/shaderc/spirv-tools@9996173f363729b3a97309685dbd4d78547a63a7
third_party/vulkan-validation-layers/src: https://android.googlesource.com/platform/external/vulkan-validation-layers@354ad3ba8b88136b82b712acab9b8fcb981beaff
third_party/zlib: https://chromium.googlesource.com/chromium/src/third_party/zlib@24ab14872e8e068ba08cc31cc3d43bcc6d5cb832
tools/clang: https://chromium.googlesource.com/chromium/src/tools/clang.git@e70074db10b27867e6c873adc3ac7e5f9ee0ff6e
tools/gyp: https://chromium.googlesource.com/external/gyp@5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f
diff --git a/BUILD.gn b/BUILD.gn
index 345f27d95..323414d22 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -24,8 +24,8 @@ if (!build_with_chromium) {
deps = [
":angle_shader_translator",
":translator_fuzzer",
- "//samples:all",
- "//src/tests:all",
+ #"//samples:all",
+ #"//src/tests:all",
]
}
}
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 73b31b740..9ac117c87 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -150,7 +150,7 @@ inline bool supportsSSE2()
return supports;
}
-#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
{
int info[4];
__cpuid(info, 0);
@@ -889,7 +889,8 @@ inline uint32_t BitfieldReverse(uint32_t value)
}
// Count the 1 bits.
-#if defined(ANGLE_PLATFORM_WINDOWS)
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM64)
+#define BITCOUNT_FOUND
inline int BitCount(uint32_t bits)
{
return static_cast<int>(__popcnt(bits));
@@ -903,6 +904,7 @@ inline int BitCount(uint64_t bits)
#endif // defined(ANGLE_PLATFORM_WINDOWS)
#if defined(ANGLE_PLATFORM_POSIX)
+#define BITCOUNT_FOUND
inline int BitCount(uint32_t bits)
{
return __builtin_popcount(bits);
@@ -916,6 +918,28 @@ inline int BitCount(uint64_t bits)
#endif // defined(ANGLE_IS_64_BIT_CPU)
#endif // defined(ANGLE_PLATFORM_POSIX)
+#if !defined(BITCOUNT_FOUND)
+inline int BitCount(uint32_t bits)
+{
+ int c = 0;
+ while (bits) {
+ bits &= (bits - 1);
+ c++;
+ }
+ return c;
+}
+
+inline int BitCount(uint64_t bits)
+{
+ int c = 0;
+ while (bits) {
+ bits &= (bits - 1);
+ c++;
+ }
+ return c;
+}
+#endif
+
#if defined(ANGLE_PLATFORM_WINDOWS)
// Return the index of the least significant bit set. Indexing is such that bit 0 is the least
// significant bit. Implemented for different bit widths on different platforms.
diff --git a/src/common/platform.h b/src/common/platform.h
index 57a2b9238..b96bc11b5 100644
--- a/src/common/platform.h
+++ b/src/common/platform.h
@@ -84,7 +84,7 @@
# undef far
#endif
-#if defined(_MSC_VER) && !defined(_M_ARM)
+#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64)
#include <intrin.h>
#define ANGLE_USE_SSE
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
diff --git a/build/build_config.h b/build/build_config.h
index 6b30422e0..ce772cd37 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -138,7 +138,7 @@
#define ARCH_CPU_ARMEL 1
#define ARCH_CPU_32_BITS 1
#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || defined(_M_ARM64)
#define ARCH_CPU_ARM_FAMILY 1
#define ARCH_CPU_ARM64 1
#define ARCH_CPU_64_BITS 1
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 80bfa75f2..5038cdf22 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -238,6 +238,12 @@ config("sdk_link") {
"$visual_studio_path\VC\lib\amd64",
"$visual_studio_path\VC\atlmfc\lib\amd64",
]
+ } else if (current_cpu == "arm64") {
+ ldflags = [ "/MACHINE:ARM64" ]
+ lib_dirs = [
+ "$windows_sdk_path\Lib\winv6.3\um\arm64",
+ "$visual_studio_path\VC\lib\arm64",
+ ]
} else {
ldflags = [
"/MACHINE:X86",
@@ -357,6 +363,9 @@ if (current_cpu == "x64") {
# The number after the comma is the minimum required OS version.
# 5.02 = Windows Server 2003.
subsystem_version_suffix = ",5.02"
+} else if (current_cpu == "arm64") {
+ # 6.02 = Windows 10
+ subsystem_version_suffix = ",6.02"
} else {
# 5.01 = Windows XP.
subsystem_version_suffix = ",5.01"
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
index 22054716f..6f24ea351 100644
--- a/build/toolchain/win/BUILD.gn
+++ b/build/toolchain/win/BUILD.gn
@@ -391,6 +391,27 @@ if (target_cpu == "x86") {
}
}
+if (target_cpu == "arm64") {
+ x86_toolchain_data = exec_script("setup_toolchain.py",
+ [
+ visual_studio_path,
+ windows_sdk_path,
+ visual_studio_runtime_dirs,
+ "arm64",
+ goma_disabled,
+ ],
+ "scope")
+
+ msvc_toolchain("arm64") {
+ environment = "environment.arm64"
+ cl = "${goma_prefix}\"${x86_toolchain_data.vc_bin_dir}/cl.exe\""
+ toolchain_args = {
+ current_cpu = "arm64"
+ is_clang = false
+ }
+ }
+}
+
# 64-bit toolchains.
x64_toolchain_data = exec_script("setup_toolchain.py",
[
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index a1d2ea4b2..626364516 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -89,7 +89,7 @@ def _LoadToolchainEnv(cpu, sdk_dir):
# Check if we are running in the SDK command line environment and use
# the setup script from the SDK if so. |cpu| should be either
# 'x86' or 'x64'.
- assert cpu in ('x86', 'x64')
+ assert cpu in ('x86', 'x64', 'arm64')
if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir:
# Load environment from json file.
env = os.path.normpath(os.path.join(sdk_dir, 'bin/SetEnv.%s.json' % cpu))
@@ -142,8 +142,10 @@ def _LoadToolchainEnv(cpu, sdk_dir):
# Chromium requires the 10.0.15063.468 SDK - previous versions don't have
# all of the required declarations and 10.0.16299.0 has some
# incompatibilities (crbug.com/773476).
- args = [script_path, 'amd64_x86' if cpu == 'x86' else 'amd64',
- '10.0.15063.0']
+ envname = cpu
+ if cpu == 'arm64':
+ envname = 'x86_arm64'
+ args = [script_path, envname, '10.0.16299.0']
variables = _LoadEnvFromBat(args)
return _ExtractImportantEnvironment(variables)
@@ -171,7 +173,7 @@ def main():
target_cpu = sys.argv[4]
goma_disabled = sys.argv[5]
- cpus = ('x86', 'x64')
+ cpus = ('x86', 'x64', 'arm64')
assert target_cpu in cpus
vc_bin_dir = ''
include = ''
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 114eefc10..780c8d9e0 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -92,9 +92,10 @@ def SetEnvironmentAndGetRuntimeDllDirs():
# directory ensures that they are available when needed.
bitness = platform.architecture()[0]
# When running 64-bit python the x64 DLLs will be in System32
+ arm64_path = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.13.26020\onecore\arm64\Microsoft.VC141.CRT'
x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
x64_path = os.path.join(r'C:\Windows', x64_path)
- vs_runtime_dll_dirs = [x64_path, r'C:\Windows\SysWOW64']
+ vs_runtime_dll_dirs = [arm64_path, r'C:\Windows\SysWOW64']
return vs_runtime_dll_dirs
@@ -204,14 +205,14 @@ def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, dll_pattern, suffix):
'C:\\Program Files (x86)\\Windows Kits\\10'))
ucrt_dll_dirs = os.path.join(win_sdk_dir, 'Redist', 'ucrt', 'DLLs',
target_cpu)
- ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
+ ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll')) + glob.glob(os.path.join(ucrt_dll_dirs, 'ucrtbase.dll'))
assert len(ucrt_files) > 0
for ucrt_src_file in ucrt_files:
file_part = os.path.basename(ucrt_src_file)
ucrt_dst_file = os.path.join(target_dir, file_part)
_CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
- _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
- os.path.join(source_dir, 'ucrtbase' + suffix))
+ #_CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
+ # os.path.join(source_dir, 'ucrtbase' + suffix))
def FindVCToolsRoot():
@@ -249,6 +250,7 @@ def _CopyPGORuntime(target_dir, target_cpu):
# There's no version of pgosweep.exe in HostX64/x86, so we use the copy
# from HostX86/x86.
pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86')
+ pgo_arm64_runtime_dir = os.path.join(pgo_runtime_root, 'arm64')
pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64')
else:
raise Exception('Unexpected toolchain version: %s.' % env_version)
@@ -262,6 +264,8 @@ def _CopyPGORuntime(target_dir, target_cpu):
source = os.path.join(pgo_x86_runtime_dir, runtime)
elif target_cpu == 'x64':
source = os.path.join(pgo_x64_runtime_dir, runtime)
+ elif target_cpu == 'arm64':
+ source = os.path.join(pgo_arm64_runtime_dir, runtime)
else:
raise NotImplementedError("Unexpected target_cpu value: " + target_cpu)
if not os.path.exists(source):
@@ -292,7 +296,7 @@ def CopyDlls(target_dir, configuration, target_cpu):
return
x64_runtime, x86_runtime = vs_runtime_dll_dirs
- runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
+ runtime_dir = x64_runtime if (target_cpu == 'x64' or target_cpu == 'arm64') else x86_runtime
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
if configuration == 'Debug':
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment