diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c31b413..027fc35e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,9 @@ option(MOBILEGL_BUILD_BENCHMARK "Build MobileGL benchmarks" option(MOBILEGL_FORCE_RELEASE_OPT "Enable Release optimization flags in Debug build" ON ) option(MOBILEGL_ENABLE_TRACY "Enable tracy for profiling" OFF) option(MOBILEGL_BUILD_TRACE_REPLAY "Build desktop apitrace replay runner" OFF) +option(MOBILEGL_IOS "Build MobileGL for iOS instead of macOS when APPLE is set" OFF) set(MOBILEGL_LOG_ACTIVE_LEVEL "MOBILEGL_LOG_LEVEL_INFO" CACHE STRING "MobileGL active log level macro") +set(MOBILEGL_VULKAN_LIBRARY "" CACHE FILEPATH "Vulkan loader/MoltenVK library to link for iOS builds") if (ANDROID) set(MOBILEGL_BUILD_TEST OFF CACHE BOOL "Build MobileGL tests" FORCE) @@ -273,7 +275,7 @@ set(SOURCE_FILES MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp ) -if (APPLE) +if (APPLE AND NOT MOBILEGL_IOS) list(APPEND SOURCE_FILES MobileGL/MG_Impl/CGLImpl/CGLImpl.cpp MobileGL/MG_Impl/CGLImpl/Exporting/Definitions.cpp @@ -393,7 +395,7 @@ if (ANDROID) ) endif() -if (APPLE) +if (APPLE AND NOT MOBILEGL_IOS) target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC "-framework Cocoa" "-framework QuartzCore" @@ -410,7 +412,31 @@ if (APPLE) endif() endif() -if (NOT ANDROID) +if (APPLE AND MOBILEGL_IOS) + target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC MOBILEGL_IOS=1 _LIBCPP_DISABLE_AVAILABILITY) + target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC + "-framework CoreGraphics" + "-framework Foundation" + "-framework QuartzCore" + objc) + if (MOBILEGL_VULKAN_LIBRARY) + target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC "${MOBILEGL_VULKAN_LIBRARY}") + endif() + + if(TARGET ${CMAKE_PROJECT_NAME}_s) + target_compile_definitions(${CMAKE_PROJECT_NAME}_s PUBLIC MOBILEGL_IOS=1 _LIBCPP_DISABLE_AVAILABILITY) + target_link_libraries(${CMAKE_PROJECT_NAME}_s PUBLIC + "-framework CoreGraphics" + "-framework Foundation" + "-framework QuartzCore" + objc) + if (MOBILEGL_VULKAN_LIBRARY) + target_link_libraries(${CMAKE_PROJECT_NAME}_s PUBLIC "${MOBILEGL_VULKAN_LIBRARY}") + endif() + endif() +endif() + +if (NOT ANDROID AND NOT MOBILEGL_IOS) find_package(Vulkan) if (Vulkan_FOUND) target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Vulkan::Vulkan Vulkan::Headers) @@ -418,7 +444,9 @@ if (NOT ANDROID) target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${Vulkan_INCLUDE_DIR}) target_include_directories(${CMAKE_PROJECT_NAME}_s PUBLIC ${Vulkan_INCLUDE_DIR}) endif () +endif () +if (NOT ANDROID) if (MOBILEGL_BUILD_TEST) add_subdirectory(MobileGL/MG_Test) endif() diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index fa4c5f4f..e22648a9 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -666,8 +666,11 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } - if ((handle.Backend != WindowBackend::Android && handle.Backend != WindowBackend::X11) || !handle.Handle) { - MGLOG_E("DirectGLES backend only supports Android and X11 native windows"); + if ((handle.Backend != WindowBackend::Android && + handle.Backend != WindowBackend::X11 && + handle.Backend != WindowBackend::MetalLayer) || + !handle.Handle) { + MGLOG_E("DirectGLES backend only supports Android, X11, and CAMetalLayer native windows"); return false; } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 6d3c6a35..79a8c756 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -5476,15 +5476,28 @@ void main() { } // TODO: support more platforms #if defined(VK_USE_PLATFORM_METAL_EXT) - exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); - instanceInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + if (IsExtensionSupported(m_extensions, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { + exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + instanceInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + } else { + MGLOG_I("Optional Vulkan instance extension not supported: %s", + VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + } #endif if (m_validationLayersEnabled) { exts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } + MGLOG_I("Enabling %d Vulkan instance extensions:", exts.size()); for (const char* ext : exts) { + MGLOG_I(" %s", ext); + } + + for (const char* ext : exts) { + if (!IsExtensionSupported(m_extensions, ext)) { + MGLOG_E("Required Vulkan instance extension not found: %s", ext); + } MOBILEGL_ASSERT(IsExtensionSupported(m_extensions, ext), "Required Vulkan instance extension not found: %s", ext); } diff --git a/MobileGL/MG_Impl/GetProcAddress.cpp b/MobileGL/MG_Impl/GetProcAddress.cpp index 7a959ee4..ca9167bd 100644 --- a/MobileGL/MG_Impl/GetProcAddress.cpp +++ b/MobileGL/MG_Impl/GetProcAddress.cpp @@ -7,7 +7,7 @@ // End of Source File Header #include "GetProcAddress.h" -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(MOBILEGL_IOS) #ifndef GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION #endif @@ -67,7 +67,7 @@ namespace MobileGL::MG_Impl { GETPROC(eglCreatePlatformPixmapSurface, name); GETPROC(eglWaitSync, name); -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(MOBILEGL_IOS) GETPROC(CGLChoosePixelFormat, name); GETPROC(CGLDestroyPixelFormat, name); GETPROC(CGLDescribePixelFormat, name); diff --git a/MobileGL/MG_Impl/Init.cpp b/MobileGL/MG_Impl/Init.cpp index fca3a261..87fdab19 100644 --- a/MobileGL/MG_Impl/Init.cpp +++ b/MobileGL/MG_Impl/Init.cpp @@ -10,7 +10,7 @@ #include "GLImpl/Texture/ProxyTexture.h" #include "GLImpl/Framebuffer/GL_Framebuffer.h" -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(MOBILEGL_IOS) #include "NSOpenGLImpl/NSOpenGLImpl.h" #endif @@ -48,7 +48,7 @@ namespace MobileGL::MG_Impl { MakeUnique(fbo0, colorTex, depthTex, stencilTex); MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).Bind(fbo0); MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).Bind(fbo0); -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(MOBILEGL_IOS) NSOpenGLImpl::InstallHooks(); #endif } diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 7def518c..e5747bb9 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -8,6 +8,9 @@ #include "Loader.h" #include "MG_Util/Types.h" +#if defined(MOBILEGL_IOS) +#include +#endif namespace MobileGL::MG_Util::BackendLoader { static Bool UseRetraceAngle() { @@ -29,10 +32,14 @@ namespace MobileGL::MG_Util::BackendLoader { } static void* OpenLib(const Vector& names) { -#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__) +#if !defined(__WIN32) && !defined(_WIN32) && (!defined(__APPLE__) || defined(MOBILEGL_IOS)) static const String LibPathPrefixes[] = { +#if defined(MOBILEGL_IOS) + "@rpath/", "@executable_path/Frameworks/", "@loader_path/Frameworks/", +#else "/opt/vc/lib/", "/usr/local/lib/", "/usr/lib/", "/usr/lib/x86_64-linux-gnu/", "/usr/lib64/", "/lib64/", +#endif "" // We should put this to the end of the list to avoid breaking `LD_LIBRARY_PATH` usage }; @@ -53,7 +60,7 @@ namespace MobileGL::MG_Util::BackendLoader { } inline void* ProcAddress(void* lib, const char* name) { -#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__) +#if !defined(__WIN32) && !defined(_WIN32) && (!defined(__APPLE__) || defined(MOBILEGL_IOS)) return dlsym(lib, name); #else return nullptr; @@ -465,7 +472,11 @@ namespace MobileGL::MG_Util::BackendLoader { return; } } else { +#if defined(MOBILEGL_IOS) + eglLib = OpenLib({"libtinygl4angle.dylib"}); +#else eglLib = OpenLib({"libEGL.so"}); +#endif } if (!eglLib) {