Posted by Adam Rehn and Luke Bermingham on 3 June 2021
Last updated on 7 June 2021 (changelog)
Overview
GPU accelerated Linux containers have been available for many years thanks to technologies such as the NVIDIA Container Toolkit, and the Unreal Containers community hub features a great deal of information about performing rendering with Unreal Engine projects in Linux containers. Support for GPU acceleration in Windows containers is far newer and the use of the Unreal Engine for rendering inside Windows containers has received relatively little attention by the authors of the community hub documentation. This blog post aims to address this gap by providing an overview of how to perform offscreen rendering with Unreal projects inside both GPU accelerated Windows containers and inside regular Windows containers through the use of software rendering.
Special thanks to the team at Epic Games for their feedback on this blog post and for providing the authors with details of the Unreal Engine’s support for the Windows Advanced Rasterization Platform (WARP).
Correction: DirectX Raytracing (DXR) support
The original wording of this blog post indicated that the Unreal Engine’s DirectX 12 raytracing support did not function correctly inside GPU accelerated Windows containers and caused the Engine to crash due to an assertion failure when it was enabled. The authors have subsequently discovered that this was caused by the absence of the required library files dxcompiler.dll
and dxil.dll
from the DirectX Shader Compiler project, and that raytracing functions as expected once these files are present in the container. The example Dockerfile code and surrounding text have been revised to reflect this information.
Contents
- Preparing your Unreal project
- Creating a runtime container image
- Recommended command-line flags
- Rendering with GPU acceleration
- Software rendering with WARP
Preparing your Unreal project
By default, Unreal Engine projects packaged for Windows are built using the WINDOWS subsystem rather than the CONSOLE subsystem, which means that they behave like GUI applications rather than command-line applications. This is problematic when attempting to run packaged projects inside Windows containers, since they do not display any log output and cannot be controlled properly from a command prompt. You can instruct UnrealBuildTool to build an additional executable with the CONSOLE subsystem by specifying the bBuildAdditionalConsoleApp
configuration value in your project’s .Target.cs
file like so:
When you package your project, an additional executable with the suffix -Cmd
will be produced alongside the regular binary. For example, if your project is called “MyProject” and you packaged it in the Development configuration then you will see two executables named as follows:
-
MyProject.exe
: this is the executable built with the WINDOWS subsystem, and is not suitable for use in a container. -
MyProject-Cmd.exe
this is the executable built with the CONSOLE subsystem, and is suitable for use in a container.
Creating a runtime container image
Performing rendering with the Unreal Engine inside a Windows container requires both the Visual C++ runtime files and a number of DirectX runtime files that are not included in any of the available Windows base images. As such, these files will need to be copied into the base image of your choice in order to build a suitable development image or runtime image.
Although the Microsoft documentation states that only the full Windows base image and the upcoming Windows Server base image are officially supported for GPU acceleration, this is not a technical limitation and testing confirms that GPU acceleration also functions correctly in the significantly smaller Windows Server Core base image. (Code in Microsoft’s hcsshim project even suggests that GPU acceleration should function in Nano Server containers, although the Windows Nano Server base image lacks so many components required by the Unreal Engine that it would not be practical to use it for rendering.) Since the full Windows base image contains only a handful of DLL files needed by Unreal Engine that are not present in the Windows Server Core base image, we recommend copying the files into a Server Core image to ensure the final container image size is as small as possible.
The example Dockerfile below demonstrates how to copy the necessary files into a Windows Server Core base image to create an Unreal Engine runtime image. Note that the variable BASETAG
represents the tag for the appropriate Windows release (1909
, 2004
, 20H2
, etc.), which should be specified using a Docker build argument:
Once you have built the runtime container image then it can be used for rendering in packaged Unreal Engine projects with either GPU acceleration or software rendering.
Recommended command-line flags
When running packaged Unreal Engine applications inside Windows containers, we recommend specifying the following command-line flags:
-
-stdout
and-FullStdOutLogOutput
: these flags ensure all log output is sent to standard output and thus printed in the container’s output. -
-unattended
: this flag suppresses the generation of dialog boxes in the event that an error is encountered. This is extremely important when running the Unreal Engine inside a Windows container because calls to GUI-related Windows API functions such as DialogBoxW and MessageBoxW will hang indefinitely inside a containerised environment, blocking execution until the Unreal Engine process or the container itself is forcibly stopped. -
-RenderOffscreen
: this flag enables offscreen rendering mode, which is required when there is no physical display device.
Rendering with GPU acceleration
To start a GPU accelerated container for performing rendering with a packaged Unreal project, run the following command:
This will start an interactive container with GPU acceleration enabled and the host filesystem directory for your packaged Unreal project bind-mounted to the path C:\hostdir
. To run your project with offscreen rendering, invoke the -Cmd
suffixed version of the executable like so:
You should see log output indicating that the project has loaded and is rendering with DirectX using the GPU from your host system. Note that you may see log output lines starting with the text LogRHI: Display: New Graphics PSO
followed by a large block of numbers. These messages are normal and can be safely ignored.
Software rendering with WARP
When running without GPU acceleration, Windows containers can still leverage the Windows Advanced Rasterization Platform (WARP) to perform software rendering. Although performance will be insufficient for real-time applications, software rendering may still be useful for Unreal projects that render individual frames for linear media or non-interactive use. The Unreal Engine has included support for using WARP with the Direct3D 12 rendering backend since version 4.14.0.
To start a regular Windows container for performing software rendering with a packaged Unreal project, run the following command:
This will start an interactive container with the host filesystem directory for your packaged Unreal project bind-mounted to the path C:\hostdir
. To run your project with offscreen rendering using WARP, invoke the -Cmd
suffixed version of the executable like so:
You should see log output indicating that the project has loaded and is rendering with DirectX using the device Microsoft Basic Render Driver
. You may see the same log output lines starting with the text LogRHI: Display: New Graphics PSO
followed by a large block of numbers that can be seen when running with GPU acceleration, which can be safely ignored.