Sunday, November 29, 2020

LÖVE on Windows 10 ARM64 Part 3: We're Going ARM64

LÖVE 12.0-development branch running in Windows 10 ARM64 under QEMU.

This is the moment of truth, and this is will be the last part of my LÖVE on Windows 10 ARM64 blog post series (part 1 here, part 2 here). In short, it's possible.

The long answer however, require various patches. Most of the patches went into external libraries that LÖVE needed. The timeline of these is simply by these recent commits, but an explanation each of them are as follows:

The first thing to do is to update SDL to 2.0.12, apply Megasource-specific patches, then apply this patch so it compiles under VS2019 because screw MSVC generating calls to memset and memcpy even when you specify /NODEFAULTLIB! Next is to update OpenAL-soft up to the recent commit for MSVC ARM64 support (see my previous blog post, I mentioned about OpenAL-soft there) then re-apply Megasource-specific patches.

The next library is bit tough and this is where most of my time spent. Ogg and Vorbis is the most annoying one that I start to suspect this is CMake bug (I use 3.19.1, the latest as of writing). I updated Ogg and Vorbis to 1.3.4 and 1.3.7 respectively, and for some reason I got error that reads "cannot open input file 'ogg.obj'" for "liblove" and "megatest" targets. Looking at the project configuration using Visual Studio shows that"ogg" is referenced twice in those both targets. I unfortunately went to last resort by using Megasource-provided CMake for both projects and the problem went away. To be honest, I have no idea why that happends, and I'm kind of sure that using Megasource-provided CMake may gives inferior performance because it uses generic, non-architecture-dependent code. Anyway it's solved so let's move on.

The last change is to Megasource CMakeLists.txt itself. There are various changes there that needs to be explained (I'll be using green-highlighted line number).

  • Line 20: Add variable for detecting ARM64 compilation. Currently, it only works for MSVC + Visual Studio targets but this is sufficient for my needs at the moment.
  • Line 155 and line 171: Unfortunately, as of CMake 3.19.1, their InstallRequiredSystemLibraries module doesn't support MSVC ARM64 and it will pick x64/AMD64 DLLs instead, so those lines will supress copying the MSVC redistributable libs when compiling for MSVC ARM64.
  • Line 242: SDL will try to load OpenGL32 in Windows first then trying other backends. This gives me bit puzzle when prototyping my patches because even setting LOVE_GRAPHICS_USE_OPENGLES=1, SDL_RENDER_DRIVER=opengles, and
    SDL_OPENGL_ES_DRIVER=1 environment variable has no effect, so I went into last resort and tell SDL not to compile the OpenGL backend instead. This is fine, LOVE will run using OpenGLES codepath using ANGLE.

    SDL fails to find OpenGL32.dll in Windows 10 ARM
  • Line 270 and line 332: LuaJIT doesn't support Windows 10 ARM64 yet, so Lua 5.1.5 bundled with the Megasource must be used. This is actually a performance impact but if even the LuaJIT interpreter can't compile (let alone the JIT compiler) then it's impossible to use LuaJIT there unless Mike adds support for it. This also increases fragmentaton because people who uses LÖVE are used to bitwise library provided by LuaJIT, but a possible fix for this is to bundle LuaJIT's LuaBitOp within Lua 5.1.5 or LOVE (when LuaJIT is not used).

After applying patches to Megasource, now patches in LÖVE are as follows, and mostly related to its buildsystem and dependencies instead:

First, tell LÖVE not to link to OpenGL. While Windows 10 SDK for ARM64 provides OpenGL headers, it doesn't include OpenGL library which cause link errors in later step. This is fine and there are no noticeable problems whatsover (even in Windows x64 builds) because LÖVE will use SDL to load OpenGL(ES) functions anyway.

The next is PhysFS, which is easy fix, and I have plan to report that later on. The last problem is dr_mp3 used in LOVE 12.0. dr_mp3 and dr_flac doesn't expect this compiler and platform combination so I have to report this problem to upstream for a proper fix (which for dr_flac, doesn't compile error so that one can wait). This is why this blog post is slightly delayed.

Afterwards, LÖVE will compile and you can install and push it to your Windows 10 ARM64 machine (or QEMU) and see LÖVE runs there. Currently I can't provide binaries at the moment because the automated GitHub Actions that's supposed to compile LÖVE binaries via artifacts is failing for some reason and quick search shows that it's OpenAL-soft to blame. So an update to prebuilt binaries will probably come in another blog post or edits in this blog post instead.

Speaking of ARM64, someone also managed to compile LÖVE for Apple Silicon


 ... which is related to this blog post title.

Thursday, November 19, 2020

LÖVE on Windows 10 ARM64 Part 2: One Step at A Time

 

OpenAL-soft test program I wrote running in Windows 10 ARM64 under QEMU

So I have few news that I want to share. First, OpenAL-soft now complies for Windows 10 ARM64. LÖVE depends on OpenAL for high performance audio backend (even the -soft version of OpenAL developed by kcat is fast enough), so getting this compiles for Windows 10 ARM64 means one step forward to bring LÖVE on Windows 10 ARM64. And the last is Microsoft released OpenGL driver built on-top of Direct3D 12 for Windows 10 ARM. This probably sounds that my effort of making weekly binaries of ANGLE using GitHub Actions is useless but actually no. Compiling ANGLE is bit data-intensive so people will just prefer getting binaries.

Since I've successfully able to run Windows 10 ARM64 under QEMU, this blog post will wrote about it.

The first thing that comes to my mind when installing this is picking good tutorials. I found this tutorial (click here) is good as it provides all the necessary drivers, firmware, and EFIvars needed, although I have to source the .iso myself, but I already did that beforehand.

As the tutorial said, it's slow as dirt at i7-4770K, so it's safe to assume that it's even slower than dirt at my laptop, i5-7200U (okay it has dGPU but it's irrelevant for this). I had to do the setup multiple times with multiple strategies just to make it get past OOBE and I think I killed around 120GB worth of SSD writes because this.

My first method is basically naive method. Automatic graphic installer, then proceed as Microsoft intended. This doesn't go well because I can't get past OOBE and then it just automatically restart then stuck in restart loop (which forces me to redo the install again). I retried this multiple times with different CPU (from 2 to 4 CPU) and RAM (from 2 to 4GB) configuration with no avail, so my conclusion is I need to look for other methods.

Because my problem is related to OOBE, it makes me wonder if I can somehow skipped it. I don't quite remember the whole progress of this, but what I remember is I installed Windows 10 kinda "manually". I searched on YouTube about Windows 10 hacks by Enderman and found an interesting video of installing Windows 10. Basically instead of installing via GUI, just install it from command prompt.

First time I tried the method, it result in unbootable OS (blue screen with INACCESSIBLE_BOOT_DEVICE). That's because the "manual" install method assume no additional drivers needed to detect the disk. Unfortunately in my case, I need to add RedHat VirtIO driver prior installing so it can detect the disk (see tutorial link above at step 9). Well even when I installed the drivers manually via DISM, it still result in endless boot loading icon, so I erased the whole install again.

Finally, the method I found to be working is this. First, install the Windows 10 as usual (from the ISO). After the first-phase install finished, I boot back to the setup ISO then open command prompt there (Shift+F10). At this command prompt, I installed the RedHat VirtIO with "pnputil" command, then mount the partition back with diskpart. Afterwards, I just follow along the YouTube video above starting at 0:56 (no need to type the bcdboot command!). For the last part, when the video says wait for 5 minutes, I actually waited for hours. First attempt of this failed so had to redo again, but then I found it works when I simply "reset" the emulator just when it shows the login screen.

Afterwards, jsut tick the privacy thingy then you're ready to use it. You need to alter the registry again to kill OneDrive setup tho because running x86-emulated binaries there is too slow to the point that installing VS2019 redistributable is impossible because no window pops up (let alone OneDrive setup). For additional performance, this tips (click here) really helps alot on making sure the CPU stays idle and not spin at 100% continously.

That's how I got Windows 10 ARM64 running under QEMU in my laptop. And of course I'll continue this blog post when I have progress.

... and if you want to read the previous blog post, please click here.

Monday, November 16, 2020

LÖVE on Windows 10 ARM64 Part 1: Compiling Dependencies

ARM64 laptops probably start getting its hand on like 2021 or 2022 (wild guess). As one of LÖVE development team, this makes me wonder if I can run LÖVE under Windows 10 ARM64, natively, because using x86 emulation is cheating and doesn't work anyway due to LÖVE dependency to OpenGL.

First thing I have to think is:

  1. Get Windows 10 ARM64 toolchain. This is easy. Visual Studio Installer provide this.
  2. Get QEMU.
  3. Get Windows 10 ARM64 image.

Fact: I have to go to my friend house and ask to use his WiFi to download those because I'm poor.

Quick testing the ARM64 toolchain by compiling my infamous HonokaMiku with CMake shows the ARM64 cross compiler works. Now before compiling LÖVE, these things comes to mind prior trying to compile it:

  1. LuaJIT doesn't support Windows/ARM64 combination.
  2. OpenGL is not supported. 

Point 1 is kinda bummer because even LuaJIT interpreter is waaaayyy faster than Lua 5.1.5, but I have no choice other than adding -DLOVE_JIT=0 CMake flags later on. Point 2 can be solved by using ANGLE. I have to "brute-force" GitHub Actions to get ANGLE compiled for ARM64, but this pays off and the actions build script can be extended to other architecture later as well.

When trying to compiling it, unfortunately SDL, PhysFS, Vorbis, and OpenAL-soft fails to compile. I've filled issue tracker for OpenAL-soft but SDL (and others) probably needs to wait longer as I also need to attend online classes (univ related), thus slowing down this experiment as whole. Known libs to compile are FreeType, GLSLang, zlib, and Ogg. Others are unknown as MSBuild prevents me compiling other dependencies.

For the VM part, I haven't getting myself a way to pass OOBE in Windows 10 ARM64 running under QEMU. Mind you, it's slower than dirt in i5-7200U. Blogpost about setting up the VM need to wait.

Also this is me trying to get LÖVE compile with Windows 10 ARM64 toolchain:

Lumine is underrated.