diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d6886a..77f58af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,10 @@ set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE}) set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) +dep_option(VIDEO_VULKAN "Enable Vulkan surface creation" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) +if(VIDEO_VULKAN) + set(VULKAN_SDK $ENV{VULKAN_SDK} CACHE PATH "Location of Vulkan library & headers") +endif() # TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here # The options below are for compatibility to configure's default behaviour. @@ -946,6 +950,18 @@ elseif(UNIX AND NOT APPLE) check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H) + if(VIDEO_VULKAN) + if(VIDEO_X11) + check_include_file("X11/Xlib-xcb.h" HAVE_XCB_H) + find_library(X11_XCB_LIB X11-xcb) + list(APPEND EXTRA_LIBS ${X11_XCB_LIB}) + endif() + set(CMAKE_REQUIRED_INCLUDES "${VULKAN_SDK}/include") + check_include_file("vulkan/vulkan.h" HAVE_VULKAN_H) + find_library(VULKAN_LIB NAMES vulkan vulkan-1 PATHS "${VULKAN_SDK}/lib") + list(APPEND EXTRA_LIBS ${VULKAN_LIB}) + endif() + endif() if(INPUT_TSLIB) @@ -1193,6 +1209,12 @@ elseif(WINDOWS) set(SDL_VIDEO_RENDER_OGL_ES2 1) set(HAVE_VIDEO_OPENGLES TRUE) endif() + + if(VIDEO_VULKAN) + set(CMAKE_REQUIRED_INCLUDES "${VULKAN_SDK}/include") + check_include_file("vulkan/vulkan.h" HAVE_VULKAN_H) + find_library(VULKAN_LIB vulkan-1 ${VULKAN_SDK}/lib) + endif() endif() if(SDL_JOYSTICK) @@ -1324,6 +1346,18 @@ elseif(APPLE) endif() # Actually load the frameworks at the end so we don't duplicate include. + if (VIDEO_VULKAN) + set(CMAKE_REQUIRED_INCLUDES "${VULKAN_SDK}/include") + check_include_file("vulkan/vulkan.h" HAVE_VULKAN_H) + if(MACOSX) + find_library(VULKAN_LIB MoltenVK ${VULKAN_SDK}/macOS) + else() + find_library(VULKAN_LIB MoltenVK ${VULKAN_SDK}/iOS) + endif() + list(APPEND EXTRA_LIBS ${VULKAN_LIB}) + find_library(COREANIMATION CoreAnimation) + list(APPEND EXTRA_LIBS ${COREANIMATION}) + endif() if(SDL_FRAMEWORK_COREVIDEO) find_library(COREVIDEO CoreVideo) list(APPEND EXTRA_LIBS ${COREVIDEO}) @@ -1403,6 +1437,12 @@ elseif(HAIKU) CheckPTHREAD() endif() +if(VIDEO_VULKAN AND VULKAN_LIB AND HAVE_VULKAN_H) + if(NOT LINUX OR NOT VIDEO_X11 OR (X11_XCB_LIB AND HAVE_XCB_H)) + set(SDL_VIDEO_VULKAN 1) + endif() +endif() + # Dummies # configure.in does it differently: # if not have X diff --git a/VisualC/SDL/SDL_VS2008.vcproj b/VisualC/SDL/SDL_VS2008.vcproj index ad52597..56541fc 100644 --- a/VisualC/SDL/SDL_VS2008.vcproj +++ b/VisualC/SDL/SDL_VS2008.vcproj @@ -75,7 +75,8 @@ /> + + + + + + @@ -962,14 +978,6 @@ > - - - - @@ -1306,6 +1314,50 @@ > + + + + + + + + + + + + + + + + + + @@ -1438,14 +1490,6 @@ > - - - - diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj index d1bacc1..ee78b29 100755 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj @@ -67,6 +67,9 @@ 04F7808512FB753F00FC43C0 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; }; 04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; }; 04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; }; + 4D4D63C41E7BFA2500515ED4 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D4D63C31E7BFA2500515ED4 /* SDL_vulkan.h */; }; + 4D4D63C61E7CB3C500515ED4 /* SDL_vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63C51E7CB3C500515ED4 /* SDL_vulkan.c */; }; + 4D4D63C81E7CB3E800515ED4 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63C71E7CB3E800515ED4 /* SDL_uikitmetalview.m */; }; 566726451DF72CF5001DD3DB /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; }; 566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 566726441DF72CF5001DD3DB /* SDL_dataqueue.h */; }; 56A6702E18565E450007D20F /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6702D18565E450007D20F /* SDL_internal.h */; }; @@ -364,6 +367,9 @@ 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_nullframebuffer.c; sourceTree = ""; }; 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = ""; }; 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = ""; }; + 4D4D63C31E7BFA2500515ED4 /* SDL_vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = ""; }; + 4D4D63C51E7CB3C500515ED4 /* SDL_vulkan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_vulkan.c; sourceTree = ""; }; + 4D4D63C71E7CB3E800515ED4 /* SDL_uikitmetalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitmetalview.m; sourceTree = ""; }; 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dataqueue.c; path = ../../src/SDL_dataqueue.c; sourceTree = ""; }; 566726441DF72CF5001DD3DB /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dataqueue.h; path = ../../src/SDL_dataqueue.h; sourceTree = ""; }; 56A6702D18565E450007D20F /* SDL_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_internal.h; path = ../../src/SDL_internal.h; sourceTree = ""; }; @@ -759,6 +765,7 @@ FD689F0D0E26E5D900F90B21 /* SDL_uikitevents.m */, AABCC3921640643D00AB8930 /* SDL_uikitmessagebox.h */, AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */, + 4D4D63C71E7CB3E800515ED4 /* SDL_uikitmetalview.m */, AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */, AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */, FD689F0E0E26E5D900F90B21 /* SDL_uikitopengles.h */, @@ -852,6 +859,7 @@ AA7558941595D55500BBD41B /* SDL_types.h */, AA7558951595D55500BBD41B /* SDL_version.h */, AA7558961595D55500BBD41B /* SDL_video.h */, + 4D4D63C31E7BFA2500515ED4 /* SDL_vulkan.h */, ); name = "Public Headers"; path = ../../include; @@ -1041,6 +1049,7 @@ FDA683190DF2374E00F98A1A /* SDL_surface.c */, FDA6831A0DF2374E00F98A1A /* SDL_sysvideo.h */, FDA6831B0DF2374E00F98A1A /* SDL_video.c */, + 4D4D63C51E7CB3C500515ED4 /* SDL_vulkan.c */, ); name = video; path = ../../src/video; @@ -1119,6 +1128,7 @@ AA7558A01595D55500BBD41B /* SDL_config.h in Headers */, AA7558A11595D55500BBD41B /* SDL_copying.h in Headers */, AA7558A21595D55500BBD41B /* SDL_cpuinfo.h in Headers */, + 4D4D63C41E7BFA2500515ED4 /* SDL_vulkan.h in Headers */, AA7558A31595D55500BBD41B /* SDL_endian.h in Headers */, AA7558A41595D55500BBD41B /* SDL_error.h in Headers */, 56A6702E18565E450007D20F /* SDL_internal.h in Headers */, @@ -1213,8 +1223,15 @@ attributes = { LastUpgradeCheck = 0800; TargetAttributes = { + 00B4F48B12F6A69C0084EC00 = { + DevelopmentTeam = UZ5V327NE3; + }; FAB598131BB5C1B100BE72C5 = { CreatedOnToolsVersion = 7.1; + DevelopmentTeam = UZ5V327NE3; + }; + FD6526620DE8FCCB002AD96B = { + DevelopmentTeam = UZ5V327NE3; }; }; }; @@ -1410,6 +1427,7 @@ FDA684640DF2374E00F98A1A /* SDL_stretch.c in Sources */, FDA684660DF2374E00F98A1A /* SDL_surface.c in Sources */, FDA684680DF2374E00F98A1A /* SDL_video.c in Sources */, + 4D4D63C61E7CB3C500515ED4 /* SDL_vulkan.c in Sources */, FDA685FB0DF244C800F98A1A /* SDL_nullevents.c in Sources */, FDA685FF0DF244C800F98A1A /* SDL_nullvideo.c in Sources */, FD5F9D2F0E0E08B3008E885B /* SDL_joystick.c in Sources */, @@ -1424,6 +1442,7 @@ FD8BD8250E27E25900B52CD5 /* SDL_sysloadso.c in Sources */, 047677BB0EA76A31008ABAF1 /* SDL_syshaptic.c in Sources */, 047677BC0EA76A31008ABAF1 /* SDL_haptic.c in Sources */, + 4D4D63C81E7CB3E800515ED4 /* SDL_uikitmetalview.m in Sources */, 047AF1B30EA98D6C00811173 /* SDL_sysloadso.c in Sources */, 046387460F0B5B7D0041FD65 /* SDL_fillrect.c in Sources */, 04F2AF561104ABD200D6DDF7 /* SDL_assert.c in Sources */, @@ -1613,6 +1632,7 @@ GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; GCC_WARN_STRICT_SELECTOR_MATCH = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; + HEADER_SEARCH_PATHS = "$(VULKAN_SDK)/include"; PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; }; @@ -1628,6 +1648,7 @@ GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; GCC_WARN_STRICT_SELECTOR_MATCH = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; + HEADER_SEARCH_PATHS = "$(VULKAN_SDK)/include"; PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; }; diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index d74b12b..a36201d 100755 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -377,6 +377,22 @@ 04F7805D12FB74A200FC43C0 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804512FB74A200FC43C0 /* SDL_drawline.h */; }; 04F7805E12FB74A200FC43C0 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */; }; 04F7805F12FB74A200FC43C0 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */; }; + 4D4D63ED1E7D335B00515ED4 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D4D63EC1E7D335B00515ED4 /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4D4D63EF1E7D339900515ED4 /* SDL_vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63EE1E7D339900515ED4 /* SDL_vulkan.c */; }; + 4D4D63F11E7D33AD00515ED4 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63F01E7D33AD00515ED4 /* SDL_cocoametalview.m */; }; + 4D4D63F41E7D359C00515ED4 /* MoltenVK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F31E7D359C00515ED4 /* MoltenVK.framework */; }; + 4D4D63F61E7D35B600515ED4 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F51E7D35B600515ED4 /* Metal.framework */; }; + 4D4D63FB1E7D3BFE00515ED4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F91E7D3BA700515ED4 /* QuartzCore.framework */; }; + 4D4D641E1E814DB600515ED4 /* SDL_vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63EE1E7D339900515ED4 /* SDL_vulkan.c */; }; + 4D4D641F1E814E0D00515ED4 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7412E6671700899322 /* SDL_atomic.c */; }; + 4D4D64201E814E1F00515ED4 /* SDL_vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63EE1E7D339900515ED4 /* SDL_vulkan.c */; }; + 4D4D64211E814F0F00515ED4 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7512E6671700899322 /* SDL_spinlock.c */; }; + 4D4D64221E814F3800515ED4 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D63F01E7D33AD00515ED4 /* SDL_cocoametalview.m */; }; + 4D4D64231E814FF200515ED4 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F51E7D35B600515ED4 /* Metal.framework */; }; + 4D4D64261E81502000515ED4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F91E7D3BA700515ED4 /* QuartzCore.framework */; }; + 4D4D64281E81527A00515ED4 /* MoltenVK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D63F31E7D359C00515ED4 /* MoltenVK.framework */; }; + 4D4D642B1E8153BB00515ED4 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D64291E81538100515ED4 /* libc++.tbd */; }; + 4D4D642C1E81542400515ED4 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D4D64291E81538100515ED4 /* libc++.tbd */; }; 56115BBB1DF72C6D00F47E1E /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 56115BB91DF72C6D00F47E1E /* SDL_dataqueue.c */; }; 56115BBC1DF72C6D00F47E1E /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 56115BBA1DF72C6D00F47E1E /* SDL_dataqueue.h */; }; 562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; @@ -699,8 +715,6 @@ DB313FFA17554B71006C0E22 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AABCC38B164063D200AB8930 /* SDL_cocoamessagebox.h */; }; DB313FFB17554B71006C0E22 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; DB313FFC17554B71006C0E22 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DB313FFE17554B71006C0E22 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7412E6671700899322 /* SDL_atomic.c */; }; - DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7512E6671700899322 /* SDL_spinlock.c */; }; DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD8812E6671700899322 /* SDL_diskaudio.c */; }; DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; }; DB31400317554B71006C0E22 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; }; @@ -1015,6 +1029,13 @@ 04F7804512FB74A200FC43C0 /* SDL_drawline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_drawline.h; sourceTree = ""; }; 04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_drawpoint.c; sourceTree = ""; }; 04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_drawpoint.h; sourceTree = ""; }; + 4D4D63EC1E7D335B00515ED4 /* SDL_vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = ""; }; + 4D4D63EE1E7D339900515ED4 /* SDL_vulkan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_vulkan.c; sourceTree = ""; }; + 4D4D63F01E7D33AD00515ED4 /* SDL_cocoametalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoametalview.m; sourceTree = ""; }; + 4D4D63F31E7D359C00515ED4 /* MoltenVK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MoltenVK.framework; path = macOS/MoltenVK.framework; sourceTree = VULKAN_SDK; }; + 4D4D63F51E7D35B600515ED4 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + 4D4D63F91E7D3BA700515ED4 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 4D4D64291E81538100515ED4 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; 56115BB91DF72C6D00F47E1E /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dataqueue.c; path = ../../src/SDL_dataqueue.c; sourceTree = ""; }; 56115BBA1DF72C6D00F47E1E /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dataqueue.h; path = ../../src/SDL_dataqueue.h; sourceTree = ""; }; 566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dropevents_c.h; sourceTree = ""; }; @@ -1115,6 +1136,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4D4D63F41E7D359C00515ED4 /* MoltenVK.framework in Frameworks */, + 4D4D642C1E81542400515ED4 /* libc++.tbd in Frameworks */, + 4D4D63F61E7D35B600515ED4 /* Metal.framework in Frameworks */, + 4D4D63FB1E7D3BFE00515ED4 /* QuartzCore.framework in Frameworks */, A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */, A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */, FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */, @@ -1145,6 +1170,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4D4D64281E81527A00515ED4 /* MoltenVK.framework in Frameworks */, + 4D4D642B1E8153BB00515ED4 /* libc++.tbd in Frameworks */, + 4D4D64231E814FF200515ED4 /* Metal.framework in Frameworks */, + 4D4D64261E81502000515ED4 /* QuartzCore.framework in Frameworks */, 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */, FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */, DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */, @@ -1221,6 +1250,7 @@ AA7557F61595D4D800BBD41B /* SDL_types.h */, AA7557F71595D4D800BBD41B /* SDL_version.h */, AA7557F81595D4D800BBD41B /* SDL_video.h */, + 4D4D63EC1E7D335B00515ED4 /* SDL_vulkan.h */, ); name = "Public Headers"; path = ../../include; @@ -1573,6 +1603,7 @@ 04BDFF7412E6671800899322 /* SDL_surface.c */, 04BDFF7512E6671800899322 /* SDL_sysvideo.h */, 04BDFF7612E6671800899322 /* SDL_video.c */, + 4D4D63EE1E7D339900515ED4 /* SDL_vulkan.c */, ); name = video; path = ../../src/video; @@ -1589,6 +1620,7 @@ 04BDFEC712E6671800899322 /* SDL_cocoakeyboard.m */, AABCC38B164063D200AB8930 /* SDL_cocoamessagebox.h */, AABCC38C164063D200AB8930 /* SDL_cocoamessagebox.m */, + 4D4D63F01E7D33AD00515ED4 /* SDL_cocoametalview.m */, 04BDFEC812E6671800899322 /* SDL_cocoamodes.h */, 04BDFEC912E6671800899322 /* SDL_cocoamodes.m */, 04BDFECA12E6671800899322 /* SDL_cocoamouse.h */, @@ -1669,6 +1701,7 @@ 034768DDFF38A45A11DB9C8B /* Products */, BECDF66B0761BA81005FE872 /* Info-Framework.plist */, BEC562FE0761C0E800A33029 /* Linked Frameworks */, + 4D4D63F21E7D359C00515ED4 /* Frameworks */, ); comments = "To build Universal Binaries, we have experimented with a variety of different options.\nThe complication is that we must retain compatibility with at least 10.2. \nThe Universal Binary defaults only work for > 10.3.9\n\nSo far, we have found:\ngcc 4.0.0 with Xcode 2.1 always links against libgcc_s. gcc 4.0.1 from Xcode 2.2 fixes this problem.\n\nBut gcc 4.0 will not work with < 10.3.9 because we continue to get an undefined symbol to _fprintf$LDBL128.\nSo we must use gcc 3.3 on PPC to accomplish 10.2 support. (But 4.0 is required for i386.)\n\nSetting the deployment target to 10.4 will disable prebinding, so for PPC, we set it less than 10.4 to preserve prebinding for legacy support.\n\nSetting the PPC SDKROOT to /Developers/SDKs/MacOSX10.2.8.sdk will link to 63.0.0 libSystem.B.dylib. Leaving it at current or 10.4u links to 88.1.2. However, as long as we are using gcc 3.3, it doesn't seem to matter as testing has demonstrated both will run. We have decided not to invoke the 10.2.8 SDK because it is not a default installed component with Xcode which will probably cause most people problems. However, rather than deleting the SDKROOT_ppc entry entirely, we have mapped it to 10.4u in case we decide we need to change this setting.\n\nTo use Altivec or SSE, we needed architecture specific flags:\nOTHER_CFLAGS_ppc\nOTHER_CFLAGS_i386\nOTHER_CFLAGS=$(OTHER_CFLAGS_($CURRENT_ARCH))\n\nThe general OTHER_CFLAGS needed to be manually mapped to architecture specific options because Xcode didn't do this automatically for us.\n\n\n"; indentWidth = 4; @@ -1717,6 +1750,17 @@ name = "Library Source"; sourceTree = ""; }; + 4D4D63F21E7D359C00515ED4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4D4D64291E81538100515ED4 /* libc++.tbd */, + 4D4D63F91E7D3BA700515ED4 /* QuartzCore.framework */, + 4D4D63F51E7D35B600515ED4 /* Metal.framework */, + 4D4D63F31E7D359C00515ED4 /* MoltenVK.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 567E2F1F17C44BBB005F1892 /* filesystem */ = { isa = PBXGroup; children = ( @@ -1834,8 +1878,9 @@ AA7558541595D4D800BBD41B /* SDL_timer.h in Headers */, AA7558561595D4D800BBD41B /* SDL_touch.h in Headers */, AA7558581595D4D800BBD41B /* SDL_types.h in Headers */, - AA75585A1595D4D800BBD41B /* SDL_version.h in Headers */, AA75585C1595D4D800BBD41B /* SDL_video.h in Headers */, + AA75585A1595D4D800BBD41B /* SDL_version.h in Headers */, + 4D4D63ED1E7D335B00515ED4 /* SDL_vulkan.h in Headers */, 04BD000912E6671800899322 /* SDL_diskaudio.h in Headers */, 04BD001112E6671800899322 /* SDL_dummyaudio.h in Headers */, 04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */, @@ -2327,10 +2372,16 @@ LastUpgradeCheck = 0730; TargetAttributes = { BECDF5FE0761BA81005FE872 = { - DevelopmentTeam = EH385AYQ6F; + DevelopmentTeam = UZ5V327NE3; + }; + BECDF66D0761BA81005FE872 = { + DevelopmentTeam = UZ5V327NE3; }; BECDF6BB0761BA81005FE872 = { - DevelopmentTeam = EH385AYQ6F; + DevelopmentTeam = UZ5V327NE3; + }; + DB313F7217554B71006C0E22 = { + DevelopmentTeam = UZ5V327NE3; }; }; }; @@ -2425,11 +2476,13 @@ 04BD005A12E6671800899322 /* SDL_rwops.c in Sources */, 04BD005B12E6671800899322 /* SDL_syshaptic.c in Sources */, 04BD005F12E6671800899322 /* SDL_haptic.c in Sources */, + 4D4D63EF1E7D339900515ED4 /* SDL_vulkan.c in Sources */, 04BD006612E6671800899322 /* SDL_sysjoystick.c in Sources */, 04BD007012E6671800899322 /* SDL_joystick.c in Sources */, 04BD008812E6671800899322 /* SDL_sysloadso.c in Sources */, 04BD009412E6671800899322 /* SDL_syspower.c in Sources */, 04BD009612E6671800899322 /* SDL_power.c in Sources */, + 4D4D63F11E7D33AD00515ED4 /* SDL_cocoametalview.m in Sources */, 04BD009C12E6671800899322 /* SDL_assert.c in Sources */, 04BD009F12E6671800899322 /* SDL_error.c in Sources */, 04BD00A212E6671800899322 /* SDL.c in Sources */, @@ -2446,9 +2499,9 @@ 04BD00C112E6671800899322 /* SDL_systhread.c in Sources */, 04BD00CA12E6671800899322 /* SDL_thread.c in Sources */, 04BD00D712E6671800899322 /* SDL_timer.c in Sources */, - 04BD00D912E6671800899322 /* SDL_systimer.c in Sources */, 04BD00F412E6671800899322 /* SDL_cocoaclipboard.m in Sources */, 04BD00F612E6671800899322 /* SDL_cocoaevents.m in Sources */, + 04BD00D912E6671800899322 /* SDL_systimer.c in Sources */, 04BD00F812E6671800899322 /* SDL_cocoakeyboard.m in Sources */, 04BD00FA12E6671800899322 /* SDL_cocoamodes.m in Sources */, 04BD00FC12E6671800899322 /* SDL_cocoamouse.m in Sources */, @@ -2598,6 +2651,7 @@ 04BD03B412E6671800899322 /* SDL_stretch.c in Sources */, 04BD03B512E6671800899322 /* SDL_surface.c in Sources */, 04BD03B712E6671800899322 /* SDL_video.c in Sources */, + 4D4D641E1E814DB600515ED4 /* SDL_vulkan.c in Sources */, 04BD03F312E6671800899322 /* imKStoUCS.c in Sources */, 04BD03F512E6671800899322 /* SDL_x11clipboard.c in Sources */, 04BD03F712E6671800899322 /* SDL_x11dyn.c in Sources */, @@ -2641,8 +2695,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DB313FFE17554B71006C0E22 /* SDL_atomic.c in Sources */, - DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */, + 4D4D64211E814F0F00515ED4 /* SDL_spinlock.c in Sources */, + 4D4D641F1E814E0D00515ED4 /* SDL_atomic.c in Sources */, 56F9D55D1DF73B6C00C15B5D /* SDL_dataqueue.c in Sources */, DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */, DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */, @@ -2692,6 +2746,7 @@ DB31402E17554B71006C0E22 /* SDL_cocoaclipboard.m in Sources */, DB31402F17554B71006C0E22 /* SDL_cocoaevents.m in Sources */, DB31403017554B71006C0E22 /* SDL_cocoakeyboard.m in Sources */, + 4D4D64221E814F3800515ED4 /* SDL_cocoametalview.m in Sources */, DB31403117554B71006C0E22 /* SDL_cocoamodes.m in Sources */, DB31403217554B71006C0E22 /* SDL_cocoamouse.m in Sources */, DB31403317554B71006C0E22 /* SDL_cocoaopengl.m in Sources */, @@ -2718,6 +2773,7 @@ DB31404817554B71006C0E22 /* SDL_stretch.c in Sources */, DB31404917554B71006C0E22 /* SDL_surface.c in Sources */, DB31404A17554B71006C0E22 /* SDL_video.c in Sources */, + 4D4D64201E814E1F00515ED4 /* SDL_vulkan.c in Sources */, DB31404B17554B71006C0E22 /* imKStoUCS.c in Sources */, DB31404C17554B71006C0E22 /* SDL_x11clipboard.c in Sources */, DB31404D17554B71006C0E22 /* SDL_x11dyn.c in Sources */, @@ -2805,12 +2861,18 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_CXX_LIBRARY = "compiler-default"; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_CURRENT_VERSION = 5.1.0; + FRAMEWORK_SEARCH_PATHS = "$(VULKAN_SDK)/macOS"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); INFOPLIST_FILE = "Info-Framework.plist"; INSTALL_PATH = "@rpath"; OTHER_LDFLAGS = "-liconv"; @@ -2833,7 +2895,10 @@ "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; }; @@ -2884,12 +2949,18 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_CXX_LIBRARY = "compiler-default"; + CLANG_ENABLE_OBJC_ARC = NO; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_CURRENT_VERSION = 5.1.0; + FRAMEWORK_SEARCH_PATHS = "$(VULKAN_SDK)/macOS"; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); INFOPLIST_FILE = "Info-Framework.plist"; INSTALL_PATH = "@rpath"; OTHER_LDFLAGS = "-liconv"; @@ -2912,7 +2983,10 @@ "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; }; @@ -2931,6 +3005,7 @@ buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; + FRAMEWORK_SEARCH_PATHS = "$(VULKAN_SDK)/macOS"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(GCC_PREPROCESSOR_DEFINITIONS)", "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1)", @@ -2939,7 +3014,10 @@ "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); INSTALL_PATH = "@rpath"; PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; @@ -2951,6 +3029,7 @@ buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; + FRAMEWORK_SEARCH_PATHS = "$(VULKAN_SDK)/macOS"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(GCC_PREPROCESSOR_DEFINITIONS)", "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1)", @@ -2959,7 +3038,10 @@ "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; - HEADER_SEARCH_PATHS = /usr/X11R6/include; + HEADER_SEARCH_PATHS = ( + /usr/X11R6/include, + "$(VULKAN_SDK)/include", + ); INSTALL_PATH = "@rpath"; PRODUCT_NAME = SDL2; SKIP_INSTALL = YES; diff --git a/include/SDL.h b/include/SDL.h index 4a6b453..4cd6108 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -56,6 +56,7 @@ #include "SDL_timer.h" #include "SDL_version.h" #include "SDL_video.h" +#include "SDL_vulkan.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 7c82e52..7505eba 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -338,6 +338,9 @@ #cmakedefine SDL_VIDEO_OPENGL_OSMESA @SDL_VIDEO_OPENGL_OSMESA@ #cmakedefine SDL_VIDEO_OPENGL_OSMESA_DYNAMIC @SDL_VIDEO_OPENGL_OSMESA_DYNAMIC@ +/* Enable Vulkan surface support */ +#cmakedefine SDL_VIDEO_VULKAN @SDL_VIDEO_VULKAN@ + /* Enable system power support */ #cmakedefine SDL_POWER_ANDROID @SDL_POWER_ANDROID@ #cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@ diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index 7d5af2c..4e090f6 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -139,6 +139,9 @@ #define SDL_VIDEO_RENDER_OGL_ES 1 #define SDL_VIDEO_RENDER_OGL_ES2 1 +/* enable Vulkan surface support */ +#define SDL_VIDEO_VULKAN 1 + /* Enable system power support */ #define SDL_POWER_UIKIT 1 diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 4b29f62..b5c3dbf 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -174,6 +174,9 @@ #define SDL_VIDEO_OPENGL_GLX 1 #endif +/* enable Vulkan surface support */ +#define SDL_VIDEO_VULKAN 1 + /* Enable system power support */ #define SDL_POWER_MACOSX 1 diff --git a/include/SDL_config_windows.h b/include/SDL_config_windows.h index 007e11c..6cbca12 100644 --- a/include/SDL_config_windows.h +++ b/include/SDL_config_windows.h @@ -208,6 +208,7 @@ typedef unsigned int uintptr_t; #define SDL_VIDEO_OPENGL_EGL 1 #endif +#define SDL_VIDEO_VULKAN 1 /* Enable system power support */ #define SDL_POWER_WINDOWS 1 diff --git a/include/SDL_vulkan.h b/include/SDL_vulkan.h new file mode 100644 index 0000000..3e59f6c --- /dev/null +++ b/include/SDL_vulkan.h @@ -0,0 +1,118 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +/** + * \file SDL_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef _SDL_vulkan_h +#define _SDL_vulkan_h + +#include "SDL_video.h" +#if defined(USE_VULKAN_HEADER_IN_SDL_VULKAN_H) +#include +#else +/* Avoid including vulkan.h */ +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Get the names of the Vulkan instance extensions needed to create + * a surface on the current video driver. + * + * \param [in] length the length of the array pointed to by \a names + * \param [out] names an array of char* into which the names of the + * extensions are written. The length of the array needed + * can be queried by passing NULL. + * + * \return the number of extensions, or 0 on error. + * + * \note The extension names queried here must be passed along when calling + * VkCreateInstance, otherwise surface creation will fail. + * + * + * \sa SDL_Vulkan_CreateSurface() + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_GetInstanceExtensions(unsigned int length, + const char** names); + +/** + * \brief Create a Vulkan rendering surface attached to the passed window. + * + * \param [in] window SDL_Window to which to attach the rendering surface. + * \param [in] instance handle to the Vulkan instance to use. + * \param [out] surface a pointer to a VkSurfaceKHR handle to receive the + * handle of the newly created surface. + * + * \return 0 on success, or -1 on error. + * + * \note Before calling this, the application must call + * SDL_Vulkan_GetInstanceExtensions() and pass the needed extensions + * along when creating the Vulkan instance \a instance. + * + * \sa SDL_Vulkan_GetInstanceExtensions() + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_CreateSurface(SDL_Window* window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * \brief Get the size of a window's underlying drawable in pixels (for use + * with setting viewport, scissor & etc). + * + * \param window Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, + * may be NULL + * \param h Pointer to variable for storing the height in pixels, + * may be NULL + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a + * platform with high-DPI support (Apple calls this "Retina"), and not disabled + * by the SDL_HINT_VIDEO_HIGHDPI_DISABLED hint. + * + * \sa SDL_GetWindowSize() + * \sa SDL_CreateWindow() + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SDL_vulkan_h */ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 1817e7f..91e723d 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -624,3 +624,6 @@ #define SDL_MemoryBarrierReleaseFunction SDL_MemoryBarrierReleaseFunction_REAL #define SDL_MemoryBarrierAcquireFunction SDL_MemoryBarrierAcquireFunction_REAL #define SDL_JoystickGetDeviceInstanceID SDL_JoystickGetDeviceInstanceID_REAL +#define SDL_Vulkan_GetInstanceExtensions SDL_Vulkan_GetInstanceExtensions_REAL +#define SDL_Vulkan_CreateSurface SDL_Vulkan_CreateSurface_REAL +#define SDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 457001b..14109fc 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -656,3 +656,6 @@ SDL_DYNAPI_PROC(SDL_JoystickType,SDL_JoystickGetType,(SDL_Joystick *a),(a),retur SDL_DYNAPI_PROC(void,SDL_MemoryBarrierReleaseFunction,(void),(),) SDL_DYNAPI_PROC(void,SDL_MemoryBarrierAcquireFunction,(void),(),) SDL_DYNAPI_PROC(SDL_JoystickID,SDL_JoystickGetDeviceInstanceID,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_Vulkan_GetInstanceExtensions,(unsigned int a, const char **b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, VkSurfaceKHR *c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) diff --git a/src/video/SDL_vulkan.c b/src/video/SDL_vulkan.c new file mode 100644 index 0000000..82e1cb8 --- /dev/null +++ b/src/video/SDL_vulkan.c @@ -0,0 +1,368 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +/** + * \file SDL_vulkan.c + * + * Functions for creating Vulkan surfaces on SDL windows. + * + * Thanks to David McFarland (@corngood on GitHub) for providing the starting + * point for this. + * + */ + +#include "../SDL_internal.h" + +#include "SDL_config.h" +#include "SDL_video.h" +#include + +#if SDL_VIDEO_VULKAN + +#if SDL_VIDEO_DRIVER_ANDROID +#define VK_USE_PLATFORM_ANDROID_KHR +#elif SDL_VIDEO_DRIVER_COCOA +#define VK_USE_PLATFORM_MACOS_MVK +typedef struct _SDL_metalview SDL_metalview; +SDL_metalview* Cocoa_Mtl_AddMetalView(SDL_Window* window); +void Cocoa_Mtl_GetDrawableSize(SDL_Window*, int* w, int* h); +#elif SDL_VIDEO_DRIVER_UIKIT +#define VK_USE_PLATFORM_IOS_MVK +typedef struct _SDL_metalview SDL_metalview; +SDL_metalview* UIKit_Mtl_AddMetalView(SDL_Window* window); +void UIKit_Mtl_GetDrawableSize(SDL_Window*, int* w, int* h); +#elif SDL_VIDEO_DRIVER_WINDOWS +#define VK_USE_PLATFORM_WIN32_KHR +#else +/* On Linux all these drivers could be present */ +#if SDL_VIDEO_DRIVER_MIR +#define VK_USE_PLATFORM_MIR_KHR +#endif +#if SDL_VIDEO_DRIVER_WAYLAND +#define VK_USE_PLATFORM_WAYLAND_KHR +#endif +#if SDL_VIDEO_DRIVER_X11 +#define VK_USE_PLATFORM_XCB_KHR +#include +#endif +#endif +#include + +#include + +static int +SetNames(unsigned int capacity, const char** names, + unsigned inCount, const char* const* inNames) +{ + unsigned int i; + + if (names) { + if (capacity < inCount) { + SDL_SetError("Insufficient capacity for extension names: %u < %u", + capacity, inCount); + return 0; + } + for (i = 0; i < inCount; ++i) + names[i] = inNames[i]; + } + return inCount; +} + +int +SDL_Vulkan_GetInstanceExtensions(unsigned length, const char** names) +{ + const char *driver = SDL_GetCurrentVideoDriver(); + if (!driver) { + SDL_SetError("No video driver - has SDL_Init(SDL_INIT_VIDEO) been called?"); + return 0; + } +#if SDL_VIDEO_DRIVER_ANDROID + if (!SDL_strcmp(driver, "android")) { + const char* ext[] = { VK_KHR_ANDROID_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_COCOA + if (!SDL_strcmp(driver, "cocoa")) { + const char* ext[] = { VK_MVK_MACOS_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_UIKIT + if (!SDL_strcmp(driver, "uikit")) { + const char* ext[] = { VK_MVK_IOS_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_MIR + if (!SDL_strcmp(driver, "mir")) { + const char* ext[] = { VK_KHR_MIR_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_WAYLAND + if (!SDL_strcmp(driver, "wayland")) { + const char* ext[] = { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_X11 + if (!SDL_strcmp(driver, "x11")) { + const char* ext[] = { VK_KHR_XCB_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif +#if SDL_VIDEO_DRIVER_WINDOWS + if (!SDL_strcmp(driver, "windows")) { + const char* ext[] = { VK_KHR_WIN32_SURFACE_EXTENSION_NAME }; + return SetNames(length, names, 1, ext); + } +#endif + + (void)SetNames; + (void)names; + + SDL_SetError("Unsupported video driver '%s'", driver); + return 0; +} + +int +SDL_Vulkan_CreateSurface(SDL_Window* window, + VkInstance instance, VkSurfaceKHR* surface) +{ + SDL_SysWMinfo wminfo; + + if (!window) { + SDL_SetError("'window' is null"); + return -1; + } + if (instance == VK_NULL_HANDLE) { + SDL_SetError("'instance' is null"); + return -1; + } + + SDL_VERSION(&wminfo.version); + if (!SDL_GetWindowWMInfo(window, &wminfo)) + return -1; + + switch (wminfo.subsystem) { +#if SDL_VIDEO_DRIVER_ANDROID + case SDL_SYSWM_ANDROID: + { + VkAndroidSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.window = wminfo.info.android.window; + + VkResult r = + vkCreateAndroidSurfaceKHR(instance, &createInfo, NULL, surface); + if (r != VK_SUCCESS) { + SDL_SetError("vkCreateAndroidSurfaceKHR failed: %i", (int)r); + return -1; + } + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_UIKIT + case SDL_SYSWM_UIKIT: + { +#if !TARGET_OS_SIMULATOR && !TARGET_CPU_ARM // Only 64-bit devices have Metal + VkIOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + // pView must be a reference to an NSView backed by a CALayer + // instance of type CAMetalLayer. + createInfo.pView = UIKit_Mtl_AddMetalView(window); + + if (createInfo.pView != NULL) { + VkResult r = + vkCreateIOSSurfaceMVK(instance, &createInfo, NULL, surface); + if (r == VK_SUCCESS) { + return 0; + } else { + SDL_SetError("vkCreateIOSSurfaceMVK failed: %i", (int)r); + } + } + return -1; +#else + SDL_SetError("Metal (& MoltenVK) not supported %s", + TARGET_OS_SIMULATOR ? "by the iOS simulator." + : "on 32-bit architectures."); + return -1; +#endif + } +#endif +#if SDL_VIDEO_DRIVER_COCOA + case SDL_SYSWM_COCOA: + { +#if TARGET_CPU_X86_64 + VkMacOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + // pView must be a reference to an NSView backed by a CALayer + // instance of type CAMetalLayer. + createInfo.pView = Cocoa_Mtl_AddMetalView(window); + + if (createInfo.pView != NULL) { + VkResult r = + vkCreateMacOSSurfaceMVK(instance, &createInfo, NULL, surface); + if (r == VK_SUCCESS) { + return 0; + } else { + SDL_SetError("vkCreateMacOSSurfaceMVK failed: %i", (int)r); + } + } + return -1; +#else + SDL_SetError("MoltenVK is not supported on 32-bit architectures."); + return -1; +#endif + } +#endif +#if SDL_VIDEO_DRIVER_WINDOWS + case SDL_SYSWM_WINDOWS: + { + VkWin32SurfaceCreateInfoKHR createInfo; + VkResult r; + + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.hinstance = wminfo.info.win.hinstance; + createInfo.hwnd = wminfo.info.win.window; + + r = vkCreateWin32SurfaceKHR(instance, &createInfo, NULL, surface); + if (r != VK_SUCCESS) { + SDL_SetError("vkCreateWin32SurfaceKHR failed: %i", (int)r); + return -1; + } + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_MIR + case SDL_SYSWM_MIR: + { + VkMirSurfaceCreateInfoKHR createInfo; + VkResult r; + + createInfo.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.connection = wminfo.info.mir.connection; + createInfo.mirSurface = wminfo.info.mir.surface; + + r = vkCreateMirSurfaceKHR(instance, &createInfo, NULL, surface); + if (r != VK_SUCCESS) { + SDL_SetError("vkCreateMirSurfaceKHR failed: %i", (int)r); + return -1; + } + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_WAYLAND + case SDL_SYSWM_WAYLAND: + { + VkWaylandSurfaceCreateInfoKHR createInfo; + VkResult r; + + createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.display = wminfo.info.wl.display; + createInfo.surface = wminfo.info.wl.window; + + r = vkCreateWaylandSurfaceKHR(instance, &createInfo, NULL, surface); + if (r != VK_SUCCESS) { + SDL_SetError("vkCreateWaylandSurfaceKHR failed: %i", (int)r); + return -1; + } + return 0; + } +#endif +#if SDL_VIDEO_DRIVER_X11 + case SDL_SYSWM_X11: + { + /* Xlib surfaces are not well supported in the Vulkan ecosystem. + Use XCB instead. */ + VkXcbSurfaceCreateInfoKHR createInfo; + VkResult r; + + createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.connection = XGetXCBConnection(wminfo.info.x11.display); + createInfo.window = wminfo.info.x11.window; + + r = vkCreateXcbSurfaceKHR(instance, &createInfo, NULL, surface); + if (r != VK_SUCCESS) { + SDL_SetError("vkCreateXcbSurfaceKHR failed: %i", (int)r); + return -1; + } + return 0; + } +#endif + default: + (void)surface; + SDL_SetError("Video driver (subsystem %i) does not support Vulkan", + (int)wminfo.subsystem); + return 0; + } +} + +void +SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h) +{ +#if SDL_VIDEO_DRIVER_UIKIT + UIKit_Mtl_GetDrawableSize(window, w, h); +#elif SDL_VIDEO_DRIVER_COCOA + Cocoa_Mtl_GetDrawableSize(window, w, h); +#else + SDL_GetWindowSize(window, w, h); +#endif +} + +#else /* !SDL_VIDEO_VULKAN */ + +int +SDL_Vulkan_GetInstanceExtensions(unsigned length, const char** names) +{ + SDL_SetError("Vulkan surface support not configured"); + return 0; +} + +int +SDL_Vulkan_CreateSurface(SDL_Window* window, + VkInstance instance, VkSurfaceKHR* surface) +{ + SDL_SetError("Vulkan surface support not configured"); + return -1; +} + +void +SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h) +{ + SDL_GetWindowSize(window, w, h); +} + +#endif /* SDL_VIDEO_VULKAN */ diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m new file mode 100644 index 0000000..9f5f12a --- /dev/null +++ b/src/video/cocoa/SDL_cocoametalview.m @@ -0,0 +1,140 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +#import +#import +#import + +#import "../SDL_sysvideo.h" +#import "SDL_cocoawindow.h" + +#define METALVIEW_TAG 255 + +@interface SDL_metalview : NSView { + CAMetalLayer* _metalLayer; + NSInteger _tag; + bool _useHighDPI; +} + +- (instancetype)initWithFrame:(NSRect)frame + useHighDPI:(bool)useHighDPI; + +@property (retain, nonatomic) CAMetalLayer *metalLayer; +/* Override superclass tag so this class can set it. */ +@property (assign, readonly) NSInteger tag; + +@end + +@implementation SDL_metalview + +@synthesize metalLayer = _metalLayer; +/* The synthesized getter should be called by super's viewWithTag. */ +@synthesize tag = _tag; + ++ (Class)layerClass +{ + return [CAMetalLayer class]; +} + +- (instancetype)initWithFrame:(NSRect)frame + useHighDPI:(bool)useHighDPI +{ + if ((self = [super initWithFrame:frame])) { + + /* Allow resize. */ + self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + _tag = METALVIEW_TAG; + + // There is a contentsScale property. + + _metalLayer = [CAMetalLayer layer]; + _metalLayer.framebufferOnly = YES; + _metalLayer.opaque = YES; + _metalLayer.device = MTLCreateSystemDefaultDevice(); + _useHighDPI = useHighDPI; + if (_useHighDPI) { + /* Isn't there a better way to convert from NSSize to CGSize? */ + NSSize size = [self convertRectToBacking:[self bounds]].size; + CGSize cgsize = *(CGSize*)&size; + _metalLayer.drawableSize = cgsize; + } + [self setLayer:_metalLayer]; + [self setWantsLayer:YES]; + [self updateDrawableSize]; + } + + return self; +} + +/* Set the size of the metal drawables when the view is resized. */ +- (void)resizeSubviewsWithOldSize:(NSSize)oldSize { + [super resizeSubviewsWithOldSize:oldSize]; + [self updateDrawableSize]; +} + +- (void)updateDrawableSize +{ + if (_useHighDPI) { + NSSize size = [self convertRectToBacking:[self bounds]].size; + CGSize cgsize = *(CGSize*)&size; + _metalLayer.drawableSize = cgsize; + } +} + +@end + +SDL_metalview* +Cocoa_Mtl_AddMetalView(SDL_Window* window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + NSView *view = data->nswindow.contentView; + SDL_metalview *metalview + = [[SDL_metalview alloc] initWithFrame:view.frame + useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)]; + [view addSubview:metalview]; + + return metalview; +} + +void +Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h) +{ + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + NSView *view = data->nswindow.contentView; + SDL_metalview* metalview = [view viewWithTag:METALVIEW_TAG]; + if (metalview) { +#if 1 + CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; + assert(layer != NULL); + if (w) + *w = layer.drawableSize.width; + if (h) + *h = layer.drawableSize.height; +#else + /* Fallback in case the above doesn't work. */ + NSSize size = [view convertRectToBacking:[view bounds]].size; + if (w) + *w = size.width; + if (h) + *h = size.height; +#endif + } +} diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m new file mode 100644 index 0000000..35e253a --- /dev/null +++ b/src/video/uikit/SDL_uikitmetalview.m @@ -0,0 +1,164 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +/* + * Devices that do not support Metal are not handled currently. + * + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing + * how to add a CAMetalLayer backed view. + */ + +#import "SDL_sysvideo.h" +#import "SDL_uikitwindow.h" + +#if !TARGET_OS_SIMULATOR +#import +#import +#import + +#define METALVIEW_TAG 255 + +@interface SDL_metalview : UIView + +- (instancetype)initWithFrame:(CGRect)frame + scale:(CGFloat)scale + tag:(int)tag; + +@property (retain, nonatomic) CAMetalLayer *metalLayer; + +@end + +@implementation SDL_metalview + ++ (Class)layerClass +{ + return [CAMetalLayer class]; +} + +- (instancetype)initWithFrame:(CGRect)frame + scale:(CGFloat)scale + tag:(int)tag +{ + if ((self = [super initWithFrame:frame])) { + /* Resize properly when rotated. */ + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + _metalLayer = (CAMetalLayer *) self.layer; + _metalLayer.opaque = YES; + _metalLayer.device = MTLCreateSystemDefaultDevice(); + + /* Set the appropriate scale (for retina display support) */ + self.contentScaleFactor = scale; + self.tag = tag; + + [self updateDrawableSize]; + } + + return self; +} + +/* Set the size of the metal drawables when the view is resized. */ +- (void)layoutSubviews +{ + [super layoutSubviews]; + [self updateDrawableSize]; +} + +- (void)updateDrawableSize +{ + CGSize size = self.bounds.size; + size.width *= self.contentScaleFactor; + size.height *= self.contentScaleFactor; + + _metalLayer.drawableSize = size; +} + +@end +#else +typedef struct _SDL_metalview SDL_metalview; +#endif + +SDL_metalview* +UIKit_Mtl_AddMetalView(SDL_Window* window) +{ +#if !TARGET_IPHONE_SIMULATOR + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view; + CGFloat scale = 1.0; + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + /* Set the scale to the natural scale factor of the screen - the + * backing dimensions of the Metal view will match the pixel + * dimensions of the screen rather than the dimensions in points. + */ +#ifdef __IPHONE_8_0 + if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) { + scale = data.uiwindow.screen.nativeScale; + } else +#endif + { + scale = data.uiwindow.screen.scale; + } + } + SDL_metalview *metalview + = [[SDL_metalview alloc] initWithFrame:view.frame + scale:scale + tag:METALVIEW_TAG]; +#if 1 + [view addSubview:metalview]; +#else + /* Sets this view as the controller's view, and adds the view to + * the window hierarchy. + * + * Left here for information. Not used because I suspect that for correct + * operation it will be necesary to copy everything from the window's + * current SDL_uikitview instance to the SDL_uikitview portion of the + * SDL_metalview. The latter would be derived from SDL_uikitview rather + * than UIView. */ + [metalview setSDLWindow:window]; +#endif + + return metalview; +#else + return NULL; +#endif +} + +void +UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h) +{ + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view; +#if !TARGET_IPHONE_SIMULATOR + SDL_metalview* metalview = [view viewWithTag:METALVIEW_TAG]; + if (metalview) { + CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; + assert(layer != NULL); + // XXX Something is setting drawable size back to the size in points. + // Possiby a bug in MoltenVK. May need to * metalview.contentScaleFactor + if (w) + *w = layer.drawableSize.width; + if (h) + *h = layer.drawableSize.height; + } else +#endif + SDL_GetWindowSize(window, w, h); +}