Skip to content

Commit

Permalink
Add iOS build support, fix Metal command buffer leaks.
Browse files Browse the repository at this point in the history
  • Loading branch information
bruvzg committed Jan 9, 2024
1 parent 9e33007 commit 446e874
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 18 deletions.
61 changes: 48 additions & 13 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ if profile:
customs.append(profile + ".py")
opts = Variables(customs, ARGUMENTS)

platforms = ("macos", "windows")
platforms = ("macos", "ios", "windows")
opts.Add(
EnumVariable(
key="platform",
Expand Down Expand Up @@ -512,11 +512,37 @@ angle_sources = [
]
if env["platform"] == "macos":
angle_sources += [
"src/common/apple_platform_utils.mm",
"src/common/system_utils_apple.cpp",
"src/common/system_utils_posix.cpp",
"src/common/system_utils_mac.cpp",
"src/gpu_info_util/SystemInfo_macos.mm",
"src/libANGLE/renderer/driver_utils_mac.mm",
"src/common/gl/cgl/FunctionsCGL.cpp",
"src/libANGLE/renderer/gl/cgl/ContextCGL.cpp",
"src/libANGLE/renderer/gl/cgl/DisplayCGL.mm",
"src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/RendererCGL.cpp",
"src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm",
]
if env["platform"] == "ios":
angle_sources += [
"src/common/system_utils_ios.mm",
"src/gpu_info_util/SystemInfo_ios.cpp",
"src/libANGLE/renderer/driver_utils_ios.mm",
"src/libANGLE/renderer/gl/eagl/ContextEAGL.cpp",
"src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp",
"src/libANGLE/renderer/gl/eagl/DisplayEAGL.mm",
"src/libANGLE/renderer/gl/eagl/FunctionsEAGL.mm",
"src/libANGLE/renderer/gl/eagl/IOSurfaceSurfaceEAGL.mm",
"src/libANGLE/renderer/gl/eagl/PbufferSurfaceEAGL.cpp",
"src/libANGLE/renderer/gl/eagl/RendererEAGL.cpp",
"src/libANGLE/renderer/gl/eagl/WindowSurfaceEAGL.mm",
]
if env["platform"] == "macos" or env["platform"] == "ios":
angle_sources += [
"src/common/apple_platform_utils.mm",
"src/common/system_utils_posix.cpp",
"src/compiler/translator/msl/AstHelpers.cpp",
"src/compiler/translator/msl/ConstantNames.cpp",
"src/compiler/translator/msl/DiscoverDependentFunctions.cpp",
Expand Down Expand Up @@ -559,8 +585,6 @@ if env["platform"] == "macos":
"src/compiler/translator/tree_ops/msl/TransposeRowMajorMatrices.cpp",
"src/compiler/translator/tree_ops/msl/WrapMain.cpp",
"src/gpu_info_util/SystemInfo_apple.mm",
"src/gpu_info_util/SystemInfo_macos.mm",
"src/libANGLE/renderer/driver_utils_mac.mm",
"src/libANGLE/renderer/metal/BufferMtl.mm",
"src/libANGLE/renderer/metal/CompilerMtl.mm",
"src/libANGLE/renderer/metal/ContextMtl.mm",
Expand Down Expand Up @@ -629,13 +653,6 @@ if env["platform"] == "macos":
"src/libANGLE/renderer/gl/RenderbufferGL.cpp",
"src/libANGLE/renderer/gl/SurfaceGL.cpp",
"src/libANGLE/renderer/gl/null_functions.cpp",
"src/libANGLE/renderer/gl/cgl/ContextCGL.cpp",
"src/libANGLE/renderer/gl/cgl/DisplayCGL.mm",
"src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/IOSurfaceSurfaceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.cpp",
"src/libANGLE/renderer/gl/cgl/RendererCGL.cpp",
"src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm",
]
if env["platform"] == "windows":
angle_sources += [
Expand Down Expand Up @@ -760,18 +777,36 @@ env.Append(CPPDEFINES=[("ANGLE_CAPTURE_ENABLED", 0)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_ESSL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_GLSL", 1)])
env.Append(CPPDEFINES=[("ANGLE_EXPORT", '""')])

extra_suffix = ""

if env["arch"] in ["x86_64", "arm64"]:
env.Append(CPPDEFINES=[("ANGLE_IS_64_BIT_CPU", 1)])
else:
env.Append(CPPDEFINES=[("ANGLE_IS_32_BIT_CPU", 1)])

if env["platform"] == "macos":
env.Append(CPPDEFINES=["ANGLE_PLATFORM_MACOS"])
env.Append(CPPDEFINES=[("ANGLE_IS_MAC", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_METAL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_OPENGL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_GL_DESKTOP_BACKEND", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_GL_NULL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_CGL", 1)])
env.Append(CCFLAGS=["-fno-objc-arc", "-fno-objc-msgsend-selector-stubs", "-Wno-unused-command-line-argument"])

if env["platform"] == "ios":
if env["ios_simulator"]:
env.Append(CPPDEFINES=["ANGLE_PLATFORM_IOS_FAMILY"])
extra_suffix = ".simulator" + extra_suffix
else:
env.Append(CPPDEFINES=["ANGLE_PLATFORM_IOS_FAMILY_SIMULATOR"])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_METAL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_OPENGL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_GL_NULL", 1)])
env.Append(CPPDEFINES=[("ANGLE_ENABLE_EAGL", 1)])
env.Append(CCFLAGS=["-fno-objc-arc", "-fno-objc-msgsend-selector-stubs", "-Wno-unused-command-line-argument"])

if env["platform"] == "windows":
env.Append(CPPDEFINES=[("ANGLE_IS_WIN", 1)])
env.Append(
Expand Down Expand Up @@ -833,7 +868,7 @@ env_gles.Append(CPPDEFINES=[("LIBGLESV2_IMPLEMENTATION", 1)])
env_gles.Append(CPPDEFINES=[("EGL_EGL_PROTOTYPES", 0)])
env_gles.Append(CPPDEFINES=[("GL_GLES_PROTOTYPES", 0)])

suffix = ".{}.{}".format(env["platform"], env["arch"])
suffix = ".{}.{}".format(env["platform"], env["arch"]) + extra_suffix

# Expose it when included from another project
env["suffix"] = suffix
Expand Down
39 changes: 39 additions & 0 deletions godot-patches/patch_metal_cmd_buf_leak.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
diff --git a/src/libANGLE/renderer/metal/ProgramMtl.mm b/src/libANGLE/renderer/metal/ProgramMtl.mm
index 04fc45023..b2a4f3f96 100644
--- a/src/libANGLE/renderer/metal/ProgramMtl.mm
+++ b/src/libANGLE/renderer/metal/ProgramMtl.mm
@@ -350,7 +350,7 @@ void InitArgumentBufferEncoder(mtl::Context *context,
if (encoder->metalArgBufferEncoder)
{
encoder->bufferPool.initialize(context, encoder->metalArgBufferEncoder.get().encodedLength,
- mtl::kArgumentBufferOffsetAlignment, 0);
+ mtl::kArgumentBufferOffsetAlignment, 10);
}
}

diff --git a/src/libANGLE/renderer/metal/ProvokingVertexHelper.mm b/src/libANGLE/renderer/metal/ProvokingVertexHelper.mm
index 3c3b47be1..0a186b63a 100644
--- a/src/libANGLE/renderer/metal/ProvokingVertexHelper.mm
+++ b/src/libANGLE/renderer/metal/ProvokingVertexHelper.mm
@@ -101,7 +101,7 @@ static inline gl::PrimitiveMode getNewPrimitiveMode(const uint fixIndexBufferKey
}
ProvokingVertexHelper::ProvokingVertexHelper(ContextMtl *context) : mIndexBuffers(false)
{
- mIndexBuffers.initialize(context, kInitialIndexBufferSize, mtl::kIndexBufferOffsetAlignment, 0);
+ mIndexBuffers.initialize(context, kInitialIndexBufferSize, mtl::kIndexBufferOffsetAlignment, 10);
}

void ProvokingVertexHelper::onDestroy(ContextMtl *context)
diff --git a/src/libANGLE/renderer/metal/VertexArrayMtl.mm b/src/libANGLE/renderer/metal/VertexArrayMtl.mm
index 1d30b2534..50e894ac3 100644
--- a/src/libANGLE/renderer/metal/VertexArrayMtl.mm
+++ b/src/libANGLE/renderer/metal/VertexArrayMtl.mm
@@ -198,7 +198,7 @@ VertexArrayMtl::VertexArrayMtl(const gl::VertexArrayState &state, ContextMtl *co
/** maxBuffers */ 10 * mtl::kMaxVertexAttribs);

mDynamicIndexData.initialize(context, kDynamicIndexDataSize, mtl::kIndexBufferOffsetAlignment,
- 0);
+ 10);
}
VertexArrayMtl::~VertexArrayMtl() {}

107 changes: 107 additions & 0 deletions godot-tools/ios.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import sys
import subprocess
from SCons.Variables import *

if sys.version_info < (3,):

def decode_utf8(x):
return x

else:
import codecs

def decode_utf8(x):
return codecs.utf_8_decode(x)[0]


def has_ios_osxcross():
return "OSXCROSS_IOS" in os.environ


def options(opts):
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
opts.Add(BoolVariable("ios_static", "Build iOS library", True))
opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "12.0")
opts.Add(
"IOS_TOOLCHAIN_PATH",
"Path to iOS toolchain",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
)
opts.Add("IOS_SDK_PATH", "Path to the iOS SDK", "")

if has_ios_osxcross():
opts.Add("ios_triple", "Triple for ios toolchain", "")


def exists(env):
return sys.platform == "darwin" or has_ios_osxcross()


def generate(env):
if env["arch"] not in ("universal", "arm64", "x86_64"):
raise ValueError("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")

if env["ios_simulator"]:
sdk_name = "iphonesimulator"
env.Append(CCFLAGS=["-mios-simulator-version-min=" + env["ios_min_version"]])
else:
sdk_name = "iphoneos"
env.Append(CCFLAGS=["-miphoneos-version-min=" + env["ios_min_version"]])

if sys.platform == "darwin":
if env["IOS_SDK_PATH"] == "":
try:
env["IOS_SDK_PATH"] = decode_utf8(
subprocess.check_output(["xcrun", "--sdk", sdk_name, "--show-sdk-path"]).strip()
)
except (subprocess.CalledProcessError, OSError):
raise ValueError(
"Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name)
)

compiler_path = env["IOS_TOOLCHAIN_PATH"] + "/usr/bin/"
env["CC"] = compiler_path + "clang"
env["CXX"] = compiler_path + "clang++"
env["AR"] = compiler_path + "ar"
env["RANLIB"] = compiler_path + "ranlib"
env["SHLIBSUFFIX"] = ".dylib"
env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]

else:
# OSXCross
compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
env["CC"] = compiler_path + "clang"
env["CXX"] = compiler_path + "clang++"
env["AR"] = compiler_path + "ar"
env["RANLIB"] = compiler_path + "ranlib"
env["SHLIBSUFFIX"] = ".dylib"

env.Prepend(
CPPPATH=[
"$IOS_SDK_PATH/usr/include",
"$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
]
)

env.Append(CCFLAGS=["-stdlib=libc++"])

binpath = os.path.join(env["IOS_TOOLCHAIN_PATH"], "usr", "bin")
if binpath not in env["ENV"]["PATH"]:
env.PrependENVPath("PATH", binpath)

if env["arch"] == "universal":
if env["ios_simulator"]:
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
else:
env.Append(LINKFLAGS=["-arch", "arm64"])
env.Append(CCFLAGS=["-arch", "arm64"])
else:
env.Append(LINKFLAGS=["-arch", env["arch"]])
env.Append(CCFLAGS=["-arch", env["arch"]])

env.Append(CCFLAGS=["-isysroot", env["IOS_SDK_PATH"]])
env.Append(LINKFLAGS=["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])

env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/metal/ProgramMtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void InitArgumentBufferEncoder(mtl::Context *context,
if (encoder->metalArgBufferEncoder)
{
encoder->bufferPool.initialize(context, encoder->metalArgBufferEncoder.get().encodedLength,
mtl::kArgumentBufferOffsetAlignment, 0);
mtl::kArgumentBufferOffsetAlignment, 10);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/metal/ProvokingVertexHelper.mm
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ static inline uint indexCountForPrimCount(const uint fixIndexBufferKey, const ui
}
ProvokingVertexHelper::ProvokingVertexHelper(ContextMtl *context) : mIndexBuffers(false)
{
mIndexBuffers.initialize(context, kInitialIndexBufferSize, mtl::kIndexBufferOffsetAlignment, 0);
mIndexBuffers.initialize(context, kInitialIndexBufferSize, mtl::kIndexBufferOffsetAlignment, 10);
}

void ProvokingVertexHelper::onDestroy(ContextMtl *context)
Expand Down
2 changes: 1 addition & 1 deletion src/libANGLE/renderer/metal/VertexArrayMtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ inline void SetDefaultVertexBufferLayout(mtl::VertexBufferLayoutDesc *layout)
/** maxBuffers */ 10 * mtl::kMaxVertexAttribs);

mDynamicIndexData.initialize(context, kDynamicIndexDataSize, mtl::kIndexBufferOffsetAlignment,
0);
10);
}
VertexArrayMtl::~VertexArrayMtl() {}

Expand Down
4 changes: 2 additions & 2 deletions src/libANGLE/renderer/metal/mtl_buffer_pool.mm
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@

angle::Result BufferPool::allocateNewBuffer(ContextMtl *contextMtl)
{
if (mMaxBuffers > 0 && mBuffersAllocated >= mMaxBuffers)
if ((mMaxBuffers > 0 && mBuffersAllocated >= mMaxBuffers))
{
// We reach the max number of buffers allowed.
// Try to deallocate old and smaller size inflight buffers.
releaseInFlightBuffers(contextMtl);
}

if (mMaxBuffers > 0 && mBuffersAllocated >= mMaxBuffers)
if ((mMaxBuffers > 0 && mBuffersAllocated >= mMaxBuffers))
{
// If we reach this point, it means there was no buffer deallocated inside
// releaseInFlightBuffers() thus, the number of buffers allocated still exceeds number
Expand Down

0 comments on commit 446e874

Please sign in to comment.