From 982ef5090cc9d1194883672ab887e52293e08c38 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 6 Mar 2022 17:22:15 -0500 Subject: [PATCH] Fixup MoltenVK support This makes MoltenVK work on iOS again if you have #1539 applied :-) --- CMakeLists.txt | 5 +- engine/gfx/vulkan/src/gfx_vulkan.cpp | 2 +- platforms/ios/CMakeLists.txt | 24 ++-- platforms/sdl/CMakeLists.txt | 2 +- platforms/uikit/ViewController.mm.in | 174 ++++++++++++++++++++++----- 5 files changed, 166 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 710d0d3..5d5f7ea 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/cmake/Common.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cmake/AddPlatformExecutable.cmake) include(FetchContent) -#set(SHADER_COMPILER_COMMAND $) -# set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool") - if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") message("Linux build detected!") @@ -44,7 +41,7 @@ endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS") message("iOS build detected!") - #set(ENABLE_VULKAN TRUE) + set(ENABLE_VULKAN TRUE) set(ENABLE_DARWIN TRUE) set(ENABLE_IOS TRUE) set(ENABLE_METAL TRUE) diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index 627c671..fdce4bc 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -1809,7 +1809,7 @@ void GFXVulkan::createInstance(std::vector layers, std::vector/../Resources/shaders - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/shaders $/../Resources/shaders + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/bin/shaders $/../Resources/shaders ) add_dependencies(${target} ${DUMMY_NAME}) diff --git a/platforms/uikit/ViewController.mm.in b/platforms/uikit/ViewController.mm.in index 5121549..69a4f88 100644 --- a/platforms/uikit/ViewController.mm.in +++ b/platforms/uikit/ViewController.mm.in @@ -1,15 +1,31 @@ +#define VK_USE_PLATFORM_METAL_EXT + #include -#include #include #import "QuartzCore/QuartzCore.hpp" #import #include - #include <@APP_INCLUDE@> +#ifdef ENABLE_VULKAN +#ifdef PLATFORM_IOS +#define VK_USE_PLATFORM_IOS_MVK +#else +#define VK_USE_PLATFORM_TVOS_MVK +#endif +#include "gfx_vulkan.hpp" +#endif + +#ifdef ENABLE_METAL +#include "gfx_metal.hpp" +#endif + +#include "gfx_dummy.hpp" + @APP_CLASS@* app = nullptr; +GFX* gfx_interface = nullptr; int maxFPS = 60; @@ -18,6 +34,15 @@ std::array inputKeys; float rightX = 0.0f, rightY = 0.0f; float leftX = 0.0f, leftY = 0.0f; +#ifdef ENABLE_METAL +void* create_metal_surface(platform::window_ptr window, void* surface_creation_info); +void* get_next_metal_drawable(platform::window_ptr window); +#endif + +#ifdef ENABLE_VULKAN +void* create_vulkan_surface(platform::window_ptr window, void* surface_creation_info); +#endif + @interface GameView : UIView @end @@ -116,6 +141,20 @@ int width, height; int drawable_width, drawable_height; CAMetalLayer* layer; +template +void try_initialize() { + if(gfx_interface == nullptr) { + auto backend = new GFXBackend(); + const bool supported = backend->is_supported() && platform::supports_context(backend->required_context()); + if(!supported) { + prism::log("Failed to initialize GFX backend... trying next..."); + } else { + gfx_interface = backend; + platform::initialize_context(gfx_interface->required_context()); + } + } +} + - (void)viewDidLoad { [super viewDidLoad]; view = (GameView*)self.view; @@ -134,18 +173,27 @@ CAMetalLayer* layer; drawable_height = [view frame].size.height * [view contentScaleFactor]; engine = new prism::engine(0, nullptr); - + + #ifdef ENABLE_METAL + try_initialize(); + #endif + + #ifdef ENABLE_VULKAN + try_initialize(); + #endif + + try_initialize(); + + GFXCreateInfo info = {}; + if(gfx_interface->initialize(info)) { + engine->set_gfx(gfx_interface); + } else { + return -1; + } + app = new @APP_CLASS@(); - engine->set_app(app); - - GFXCreateInfo createInfo = {}; - createInfo.api_validation_enabled = true; - - GFXMetal* gfx = new GFXMetal(); - gfx->initialize(createInfo); - engine->set_gfx(gfx); - app_main(engine); + engine->set_app(app); engine->add_window((void*)CFBridgingRetain([view layer]), (void*)1, {static_cast(width), static_cast(height)}); @@ -169,6 +217,71 @@ CAMetalLayer* layer; @end +bool platform::supports_context(GFXContext context) { +#ifdef ENABLE_DX12 + if(context == GFXContext::DirectX) + return true; +#endif + +#ifdef ENABLE_VULKAN + if(context == GFXContext::Vulkan) + return true; +#endif + +#ifdef ENABLE_METAL + if(context == GFXContext::Metal) + return true; +#endif + + if(context == GFXContext::None) + return true; + + return false; +} + +void platform::initialize_context(const GFXContext context) { + +} + +void* platform::get_context_information() { +#ifdef ENABLE_VULKAN + if(gfx_interface->required_context() == GFXContext::Vulkan) { + auto info = new vulkan_information(); + info->surface_extensions = {VK_EXT_METAL_SURFACE_EXTENSION_NAME}; + + return (void*)info; + } +#endif + + return nullptr; +} + +void* platform::create_surface(window_ptr window, void* surface_creation_info) { +#ifdef ENABLE_VULKAN + if(gfx_interface->required_context() == GFXContext::Vulkan) { + return create_vulkan_surface(window, surface_creation_info); + } +#endif + +#ifdef ENABLE_METAL + if(gfx_interface->required_context() == GFXContext::Metal) { + return create_metal_surface(window, surface_creation_info); + } +#endif + + return nullptr; +} + +void* platform::get_next_image(window_ptr window) { +#ifdef ENABLE_METAL + if(gfx_interface->required_context() == GFXContext::Metal) { + return get_next_metal_drawable(window); + } +#endif + + return nullptr; +} + void platform::capture_mouse(const bool capture) { } @@ -186,39 +299,44 @@ void platform::end_text_input() { // TODO: stub } -void* platform::create_native_surface(platform::window_ptr index, void* instance) { - /*VkMetalSurfaceCreateInfoEXT surfaceInfo = {}; +void* create_vulkan_surface(platform::window_ptr index, void* surface_creation_info) { + auto vulkan_surface_info = (vulkan_surface_creation_info*)surface_creation_info; + + VkMetalSurfaceCreateInfoEXT surfaceInfo = {}; surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; surfaceInfo.pNext = 0; surfaceInfo.flags = 0; surfaceInfo.pLayer = layer; - VkSurfaceKHR surface; - vkCreateMetalSurfaceEXT((VkInstance)instance, &surfaceInfo, nullptr, &surface); + auto vk_surface = new vulkan_surface(); + vkCreateMetalSurfaceEXT((VkInstance)vulkan_surface_info->instance, &surfaceInfo, nullptr, &vk_surface->surface); - return surface;*/ - return nullptr; + return vk_surface; } -unsigned int platform::initialize_metal_layer(platform::window_ptr index, void* device) { - layer.device = (__bridge id)device; + +void* create_metal_surface(platform::window_ptr window, void* surface_creation_info) { + auto metal_surface_info = (metal_surface_creation_info*)surface_creation_info; + + layer.device = (__bridge id)metal_surface_info->device; layer.allowsNextDrawableTimeout = true; - return (unsigned int)layer.pixelFormat; + auto return_surface = new metal_surface(); + return_surface->format = static_cast(layer.pixelFormat); + + return return_surface; } -void* platform::get_next_drawable(window_ptr window) { - return (__bridge CA::MetalDrawable*)[layer nextDrawable]; +void* get_next_metal_drawable(platform::window_ptr window) { + auto drawable = (__bridge CA::MetalDrawable*)[layer nextDrawable]; + drawable->retain(); + + return drawable; } bool platform::is_main_window(platform::window_ptr index) { return true; } -std::vector platform::get_native_surface_extension() { - //return {VK_EXT_METAL_SURFACE_EXTENSION_NAME}; - return {}; -} - void platform::show_window(const platform::window_ptr index) { }