diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2019-06-22 19:34:26 +0300 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2020-02-11 11:57:11 +0100 |
commit | eb48be51dbe97aa4fbbbe0d0ebd8a98bee6b263e (patch) | |
tree | 9a5b6bfd50e7ddb5b348c97bd60d30b290d27d49 /platform/osx | |
parent | 4fe3ee1730167b90ec8ae70c871c1dad032981d5 (diff) |
Add static Vulkan loader.
Initial Vulkan support for Windows.
Initial Vulkan support for macOS.
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/SCsub | 3 | ||||
-rw-r--r-- | platform/osx/detect.py | 29 | ||||
-rw-r--r-- | platform/osx/godot_main_osx.mm | 6 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 15 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 107 | ||||
-rw-r--r-- | platform/osx/vulkan_context_osx.h | 48 | ||||
-rw-r--r-- | platform/osx/vulkan_context_osx.mm | 56 |
7 files changed, 239 insertions, 25 deletions
diff --git a/platform/osx/SCsub b/platform/osx/SCsub index e15b4339a7..2632c4f032 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -15,6 +15,9 @@ files = [ 'power_osx.cpp', ] +if (env["renderer"] == "vulkan"): + files += ['vulkan_context_osx.mm'] + prog = env.add_program('#bin/godot', files) if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: diff --git a/platform/osx/detect.py b/platform/osx/detect.py index fe839199e8..989bf6d425 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -1,5 +1,6 @@ import os import sys +import subprocess from methods import detect_darwin_sdk_path @@ -25,6 +26,7 @@ def get_opts(): return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), ('MACOS_SDK_PATH', 'Path to the macOS SDK', ''), + BoolVariable('use_static_mvk', 'Link MoltenVK statically as Level-0 driver (better portability) or use Vulkan ICD loader (enables validation layers)', False), EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')), BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False), BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False), @@ -148,9 +150,24 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/osx']) - env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreVideo']) - env.Append(LIBS=['pthread']) - - env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) + env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo', '-framework', 'AVFoundation', '-framework', 'CoreMedia']) + env.Append(LIBS=['pthread', 'z']) + + if (env["renderer"] == "vulkan"): + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) + if (env['use_static_mvk']): + env.Append(LINKFLAGS=['-framework', 'MoltenVK']) + elif not env["builtin_vulkan_loader"]: + env.Append(LIBS=['vulkan']) + + env.Append(CCFLAGS=['-mmacosx-version-min=10.11']) + env.Append(LINKFLAGS=['-mmacosx-version-min=10.11']) + else: + env.Append(CPPDEFINES=['GLES_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'OpenGL', '-framework', 'AGL']) + + env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) + env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index e6f8cbecf1..eacd2b5cc6 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -36,6 +36,12 @@ #include <unistd.h> int main(int argc, char **argv) { + +#if defined(VULKAN_ENABLED) + //MoltenVK - enable full component swizzling support + setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); +#endif + int first_arg = 1; const char *dbg_arg = "-NSDocumentRevisionsDebugMode"; printf("arguments\n"); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 190dbcf662..97da467ce4 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -46,6 +46,11 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/osx/vulkan_context_osx.h" +#endif + #include <AppKit/AppKit.h> #include <AppKit/NSCursor.h> #include <ApplicationServices/ApplicationServices.h> @@ -93,7 +98,6 @@ public: void process_events(); void process_key_events(); - void *framework; // pthread_key_t current; bool mouse_grab; Point2 mouse_pos; @@ -104,8 +108,17 @@ public: id window_view; id autoreleasePool; id cursor; + +#if defined(OPENGL_ENABLED) + void *framework; NSOpenGLPixelFormat *pixelFormat; NSOpenGLContext *context; +#endif + +#if defined(VULKAN_ENABLED) + VulkanContextOSX *context_vulkan; + RenderingDeviceVulkan *rendering_device; +#endif bool layered_window; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 43012220b6..5a64aa5698 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -34,11 +34,19 @@ #include "core/print_string.h" #include "core/version_generated.gen.h" #include "dir_access_osx.h" + +#if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" +#endif +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer/rasterizer_rd.h" +#endif + #include "main/main.h" #include "semaphore_osx.h" #include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" #include <mach-o/dyld.h> @@ -52,6 +60,9 @@ #include <os/log.h> #endif +#import <QuartzCore/CAMetalLayer.h> +#include <vulkan/vulkan_metal.h> + #include <dlfcn.h> #include <fcntl.h> #include <libproc.h> @@ -336,11 +347,13 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { NSWindow *window = (NSWindow *)[notification object]; CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; +#if defined(OPENGL_ENABLED) if (OS_OSX::singleton->is_hidpi_allowed()) { [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; } else { [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; } +#endif if (newBackingScaleFactor != oldBackingScaleFactor) { //Set new display scale and window size @@ -361,7 +374,9 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { } - (void)windowDidResize:(NSNotification *)notification { +#if defined(OPENGL_ENABLED) [OS_OSX::singleton->context update]; +#endif const NSRect contentRect = [OS_OSX::singleton->window_view frame]; const NSRect fbRect = contentRect; @@ -370,6 +385,12 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { OS_OSX::singleton->window_size.width = fbRect.size.width * displayScale; OS_OSX::singleton->window_size.height = fbRect.size.height * displayScale; +#if defined(VULKAN_ENABLED) + CALayer* layer = [OS_OSX::singleton->window_view layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); +#endif + if (OS_OSX::singleton->main_loop) { Main::force_redraw(); //Event retrieval blocks until resize is over. Call Main::iteration() directly. @@ -450,8 +471,12 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { bool imeInputEventInProgress; } - (void)cancelComposition; + +- (CALayer*)makeBackingLayer; + - (BOOL)wantsUpdateLayer; - (void)updateLayer; + @end @implementation GodotContentView @@ -462,12 +487,28 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { } } -- (BOOL)wantsUpdateLayer { - return YES; +- (CALayer*)makeBackingLayer { +#if defined(VULKAN_ENABLED) + CALayer* layer = [[CAMetalLayer class] layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + return layer; +#endif +#if defined(OPENGL_ENABLED) + return [super makeBackingLayer]; +#endif } - (void)updateLayer { +#if defined(OPENGL_ENABLED) [OS_OSX::singleton->context update]; +#endif +#if defined(VULKAN_ENABLED) + [super updateLayer]; +#endif +} + +- (BOOL)wantsUpdateLayer { + return YES; } - (id)init { @@ -1498,7 +1539,9 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a window_size.height = p_desired.height * displayScale; if (displayScale > 1.0) { +#if defined(OPENGL_ENABLED) [window_view setWantsBestResolutionOpenGLSurface:YES]; +#endif //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } else { @@ -1513,13 +1556,16 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [window_object setRestorable:NO]; +#if defined(OPENGL_ENABLED) + framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + ERR_FAIL_COND(!framework); + unsigned int attributeCount = 0; // OS X needs non-zero color size, so set reasonable values int colorBits = 32; // Fail if a robustness strategy was requested - #define ADD_ATTR(x) \ { attributes[attributeCount++] = x; } #define ADD_ATTR2(x, y) \ @@ -1584,6 +1630,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [context makeCurrentContext]; set_use_vsync(p_desired.use_vsync); +#endif [NSApp activateIgnoringOtherApps:YES]; @@ -1596,6 +1643,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a /*** END OSX INITIALIZATION ***/ +#if defined(OPENGL_ENABLED) bool gles3 = true; if (p_video_driver == VIDEO_DRIVER_GLES2) { gles3 = false; @@ -1640,6 +1688,19 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a } video_driver_index = p_video_driver; +#endif +#if defined(VULKAN_ENABLED) + video_driver_index = VIDEO_DRIVER_VULKAN; + + context_vulkan = memnew(VulkanContextOSX); + context_vulkan->initialize(); + context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height); + + //temporary + rendering_device = memnew(RenderingDeviceVulkan); + rendering_device->initialize(context_vulkan); + RasterizerRD::make_current(); +#endif visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { @@ -1684,6 +1745,14 @@ void OS_OSX::finalize() { cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); + +#if defined(VULKAN_ENABLED) + rendering_device->finalize(); + memdelete(rendering_device); + + memdelete(context_vulkan); +#endif + //memdelete(rasterizer); } @@ -1916,7 +1985,6 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c image->lock(); - /* Premultiply the alpha channel */ for (int i = 0; i < len; i++) { int row_index = floor(i / texture_size.width) + atlas_rect.position.y; int column_index = (i % int(texture_size.width)) + atlas_rect.position.x; @@ -1971,6 +2039,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c cursors_cache.erase(p_shape); } + } void OS_OSX::set_mouse_show(bool p_show) { @@ -2228,13 +2297,15 @@ String OS_OSX::get_clipboard() const { } void OS_OSX::release_rendering_thread() { - +#if defined(OPENGL_ENABLED) [NSOpenGLContext clearCurrentContext]; +#endif } void OS_OSX::make_rendering_thread() { - +#if defined(OPENGL_ENABLED) [context makeCurrentContext]; +#endif } Error OS_OSX::shell_open(String p_uri) { @@ -2250,6 +2321,10 @@ String OS_OSX::get_locale() const { void OS_OSX::swap_buffers() { [context flushBuffer]; +#endif +#if defined(VULKAN_ENABLED) + context_vulkan->swap_buffers(); +#endif } void OS_OSX::wm_minimized(bool p_minimized) { @@ -2659,21 +2734,27 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { if (layered_window != p_enabled) { if (p_enabled) { set_borderless_window(true); - GLint opacity = 0; [window_object setBackgroundColor:[NSColor clearColor]]; [window_object setOpaque:NO]; [window_object setHasShadow:NO]; +#if defined(OPENGL_ENABLED) + GLint opacity = 0; [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +#endif layered_window = true; } else { - GLint opacity = 1; [window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]]; [window_object setOpaque:YES]; [window_object setHasShadow:YES]; +#if defined(OPENGL_ENABLED) + GLint opacity = 1; [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +#endif layered_window = false; } +#if defined(OPENGL_ENABLED) [context update]; +#endif NSRect frame = [window_object frame]; [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; [window_object setFrame:frame display:YES]; @@ -3018,16 +3099,6 @@ OS_OSX::OS_OSX() { CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0); - /* - if (pthread_key_create(&_Godot.nsgl.current, NULL) != 0) { - _GodotInputError(Godot_PLATFORM_ERROR, "NSGL: Failed to create context TLS"); - return GL_FALSE; - } -*/ - - framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - ERR_FAIL_COND(!framework); - // Implicitly create shared NSApplication instance [GodotApplication sharedApplication]; diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h new file mode 100644 index 0000000000..c048de509e --- /dev/null +++ b/platform/osx/vulkan_context_osx.h @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* vulkan_context_osx.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VULKAN_DEVICE_OSX_H +#define VULKAN_DEVICE_OSX_H + +#include "drivers/vulkan/vulkan_context.h" +#include <AppKit/AppKit.h> + +class VulkanContextOSX : public VulkanContext { + + virtual const char *_get_platform_surface_extension() const; + +public: + int window_create(id p_window, int p_width, int p_height); + + VulkanContextOSX(); + ~VulkanContextOSX(); +}; + +#endif // VULKAN_DEVICE_OSX_H diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm new file mode 100644 index 0000000000..b4c663062c --- /dev/null +++ b/platform/osx/vulkan_context_osx.mm @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* vulkan_context_osx.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vulkan_context_osx.h" +#include <vulkan/vulkan_macos.h> + +const char *VulkanContextOSX::_get_platform_surface_extension() const { + return VK_MVK_MACOS_SURFACE_EXTENSION_NAME; +} + +int VulkanContextOSX::window_create(id p_window, int p_width, int p_height) { + + VkMacOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = p_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateMacOSSurfaceMVK(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); +} + +VulkanContextOSX::VulkanContextOSX() { +} + +VulkanContextOSX::~VulkanContextOSX() { +} |