vulkan: Initial Vulkan support!
authorRyan C. Gordon <icculus@icculus.org>
Sun, 27 Aug 2017 22:15:57 -0400
changeset 11365a9bd2625fa01
parent 11364 ec27c4fd6880
child 11366 1e4fe1678a00
vulkan: Initial Vulkan support!

This work was done by Jacob Lifshay and Mark Callow; I'm just merging it
into revision control.
CMakeLists.txt
Makefile.in
VisualC/SDL/SDL_VS2008.vcproj
VisualC/SDL_VS2008.sln
VisualC/tests/testvulkan/testvulkan_VS2008.vcproj
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
Xcode/SDL/SDL.xcodeproj/project.pbxproj
cmake/sdlchecks.cmake
configure
configure.in
debian/control
docs/README-ios.md
docs/README-linux.md
docs/README-macosx.md
docs/README-windows.md
include/SDL.h
include/SDL_config.h.cmake
include/SDL_config.h.in
include/SDL_config_android.h
include/SDL_config_iphoneos.h
include/SDL_config_macosx.h
include/SDL_config_windows.h
include/SDL_video.h
include/SDL_vulkan.h
src/test/SDL_test_common.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/SDL_vulkan_internal.h
src/video/SDL_vulkan_utils.c
src/video/android/SDL_androidvideo.c
src/video/android/SDL_androidvulkan.c
src/video/android/SDL_androidvulkan.h
src/video/cocoa/SDL_cocoametalview.h
src/video/cocoa/SDL_cocoametalview.m
src/video/cocoa/SDL_cocoavideo.m
src/video/cocoa/SDL_cocoavulkan.h
src/video/cocoa/SDL_cocoavulkan.m
src/video/mir/SDL_mirvideo.c
src/video/mir/SDL_mirvideo.h
src/video/mir/SDL_mirvulkan.c
src/video/mir/SDL_mirvulkan.h
src/video/uikit/SDL_uikitmetalview.h
src/video/uikit/SDL_uikitmetalview.m
src/video/uikit/SDL_uikitvideo.m
src/video/uikit/SDL_uikitvulkan.h
src/video/uikit/SDL_uikitvulkan.m
src/video/wayland/SDL_waylandvideo.c
src/video/wayland/SDL_waylandvulkan.c
src/video/wayland/SDL_waylandvulkan.h
src/video/windows/SDL_windowsvideo.c
src/video/windows/SDL_windowsvulkan.c
src/video/windows/SDL_windowsvulkan.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11vulkan.c
src/video/x11/SDL_x11vulkan.h
test/Makefile.in
test/configure
test/configure.in
test/testvulkan.c
     1.1 --- a/CMakeLists.txt	Sun Aug 27 19:10:30 2017 -0700
     1.2 +++ b/CMakeLists.txt	Sun Aug 27 22:15:57 2017 -0400
     1.3 @@ -20,6 +20,7 @@
     1.4  include(CheckIncludeFiles)
     1.5  include(CheckIncludeFile)
     1.6  include(CheckSymbolExists)
     1.7 +include(CheckCSourceCompiles)
     1.8  include(CheckCSourceRuns)
     1.9  include(CheckCCompilerFlag)
    1.10  include(CheckTypeSize)
    1.11 @@ -324,9 +325,14 @@
    1.12  set_option(DIRECTX             "Use DirectX for Windows audio/video" ${WINDOWS})
    1.13  set_option(RENDER_D3D          "Enable the Direct3D render driver" ${WINDOWS})
    1.14  set_option(VIDEO_VIVANTE       "Use Vivante EGL video driver" ${UNIX_SYS})
    1.15 +dep_option(VIDEO_VULKAN        "Enable Vulkan surface creation" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF)
    1.16  set_option(VIDEO_KMSDRM        "Use KMS DRM video driver" ${UNIX_SYS})
    1.17  dep_option(KMSDRM_SHARED       "Dynamically load KMS DRM support" ON "VIDEO_KMSDRM" OFF)
    1.18  
    1.19 +if(VIDEO_VULKAN)
    1.20 +  set(VULKAN_SDK $ENV{VULKAN_SDK} CACHE PATH "Location of Vulkan headers' grandparent, e.g. /foo when headers are in /foo/include/vulkan.")
    1.21 +endif()
    1.22 +
    1.23  # TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here
    1.24  # The options below are for compatibility to configure's default behaviour.
    1.25  set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library")
    1.26 @@ -855,6 +861,22 @@
    1.27        find_library(OpenGLES2_LIBRARY GLESv2)
    1.28        list(APPEND EXTRA_LIBS ${OpenGLES1_LIBRARY} ${OpenGLES2_LIBRARY})
    1.29      endif()
    1.30 +
    1.31 +    CHECK_C_SOURCE_COMPILES("
    1.32 +    #if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
    1.33 +    #error Vulkan doesn't work on this configuration
    1.34 +    #endif
    1.35 +    int main()
    1.36 +    {
    1.37 +        return 0;
    1.38 +    }
    1.39 +    " VULKAN_PASSED_ANDROID_CHECKS)
    1.40 +    if(NOT VULKAN_PASSED_ANDROID_CHECKS)
    1.41 +      set(VIDEO_VULKAN OFF)
    1.42 +      message(STATUS "Vulkan doesn't work on this configuration")
    1.43 +    else()
    1.44 +      CheckVulkanHeaders()
    1.45 +    endif()
    1.46    endif()
    1.47  
    1.48    CheckPTHREAD()
    1.49 @@ -1020,6 +1042,7 @@
    1.50  
    1.51      check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H)
    1.52  
    1.53 +    CheckVulkanHeaders()
    1.54    endif()
    1.55  
    1.56    if(INPUT_TSLIB)
    1.57 @@ -1278,6 +1301,8 @@
    1.58        set(SDL_VIDEO_RENDER_OGL_ES2 1)
    1.59        set(HAVE_VIDEO_OPENGLES TRUE)
    1.60      endif()
    1.61 +
    1.62 +    CheckVulkanHeaders()
    1.63    endif()
    1.64  
    1.65    if(SDL_JOYSTICK)
    1.66 @@ -1419,6 +1444,13 @@
    1.67    endif()
    1.68  
    1.69    # Actually load the frameworks at the end so we don't duplicate include.
    1.70 +  if (VIDEO_VULKAN)
    1.71 +    CheckVulkanHeaders()
    1.72 +    if(HAVE_VULKAN_H)
    1.73 +      find_library(QUARTZCORE QuartzCore)
    1.74 +      list(APPEND EXTRA_LIBS ${QUARTZCORE})
    1.75 +    endif()
    1.76 +  endif()
    1.77    if(SDL_FRAMEWORK_COREVIDEO)
    1.78      find_library(COREVIDEO CoreVideo)
    1.79      list(APPEND EXTRA_LIBS ${COREVIDEO})
    1.80 @@ -1498,6 +1530,10 @@
    1.81    CheckPTHREAD()
    1.82  endif()
    1.83  
    1.84 +if(VIDEO_VULKAN AND HAVE_VULKAN_H AND (NOT APPLE OR QUARTZCORE))
    1.85 +  set(SDL_VIDEO_VULKAN_SURFACE 1)
    1.86 +endif()
    1.87 +
    1.88  # Dummies
    1.89  # configure.in does it differently:
    1.90  # if not have X
     2.1 --- a/Makefile.in	Sun Aug 27 19:10:30 2017 -0700
     2.2 +++ b/Makefile.in	Sun Aug 27 22:15:57 2017 -0400
     2.3 @@ -112,6 +112,7 @@
     2.4  	SDL_types.h \
     2.5  	SDL_version.h \
     2.6  	SDL_video.h \
     2.7 +	SDL_vulkan.h \
     2.8  	begin_code.h \
     2.9  	close_code.h
    2.10  
     3.1 --- a/VisualC/SDL/SDL_VS2008.vcproj	Sun Aug 27 19:10:30 2017 -0700
     3.2 +++ b/VisualC/SDL/SDL_VS2008.vcproj	Sun Aug 27 22:15:57 2017 -0400
     3.3 @@ -52,7 +52,7 @@
     3.4  				Name="VCCLCompilerTool"
     3.5  				Optimization="0"
     3.6  				InlineFunctionExpansion="1"
     3.7 -				AdditionalIncludeDirectories="$(SolutionDir)/../include"
     3.8 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
     3.9  				AdditionalUsingDirectories=""
    3.10  				PreprocessorDefinitions="_DEBUG;_WINDOWS"
    3.11  				RuntimeLibrary="2"
    3.12 @@ -135,7 +135,7 @@
    3.13  				Name="VCCLCompilerTool"
    3.14  				Optimization="0"
    3.15  				InlineFunctionExpansion="1"
    3.16 -				AdditionalIncludeDirectories="$(SolutionDir)/../include"
    3.17 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
    3.18  				AdditionalUsingDirectories=""
    3.19  				PreprocessorDefinitions="_DEBUG;_WINDOWS"
    3.20  				RuntimeLibrary="2"
    3.21 @@ -216,7 +216,7 @@
    3.22  			<Tool
    3.23  				Name="VCCLCompilerTool"
    3.24  				InlineFunctionExpansion="1"
    3.25 -				AdditionalIncludeDirectories="$(SolutionDir)/../include"
    3.26 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
    3.27  				AdditionalUsingDirectories=""
    3.28  				PreprocessorDefinitions="NDEBUG;_WINDOWS"
    3.29  				RuntimeLibrary="2"
    3.30 @@ -299,7 +299,7 @@
    3.31  			<Tool
    3.32  				Name="VCCLCompilerTool"
    3.33  				InlineFunctionExpansion="1"
    3.34 -				AdditionalIncludeDirectories="$(SolutionDir)/../include"
    3.35 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
    3.36  				AdditionalUsingDirectories=""
    3.37  				PreprocessorDefinitions="NDEBUG;_WINDOWS"
    3.38  				RuntimeLibrary="2"
    3.39 @@ -644,6 +644,10 @@
    3.40  				RelativePath="..\..\include\SDL_video.h"
    3.41  				>
    3.42  			</File>
    3.43 +			<File
    3.44 +				RelativePath="..\..\include\SDL_vulkan.h"
    3.45 +				>
    3.46 +			</File>
    3.47  		</Filter>
    3.48  		<File
    3.49  			RelativePath="..\..\src\events\blank_cursor.h"
    3.50 @@ -878,6 +882,14 @@
    3.51  			>
    3.52  		</File>
    3.53  		<File
    3.54 +			RelativePath="..\..\src\SDL_dataqueue.c"
    3.55 +			>
    3.56 +		</File>
    3.57 +		<File
    3.58 +			RelativePath="..\..\src\SDL_dataqueue.h"
    3.59 +			>
    3.60 +		</File>
    3.61 +		<File
    3.62  			RelativePath="..\..\src\haptic\windows\SDL_dinputhaptic.c"
    3.63  			>
    3.64  		</File>
    3.65 @@ -1314,6 +1326,22 @@
    3.66  			>
    3.67  		</File>
    3.68  		<File
    3.69 +			RelativePath="..\..\src\video\SDL_vulkan_internal.h"
    3.70 +			>
    3.71 +		</File>
    3.72 +		<File
    3.73 +			RelativePath="..\..\src\video\SDL_vulkan_utils.c"
    3.74 +			>
    3.75 +		</File>
    3.76 +		<File
    3.77 +			RelativePath="..\..\src\audio\wasapi\SDL_wasapi.c"
    3.78 +			>
    3.79 +		</File>
    3.80 +		<File
    3.81 +			RelativePath="..\..\src\audio\wasapi\SDL_wasapi.h"
    3.82 +			>
    3.83 +		</File>
    3.84 +		<File
    3.85  			RelativePath="..\..\src\audio\SDL_wave.c"
    3.86  			>
    3.87  		</File>
    3.88 @@ -1438,6 +1466,14 @@
    3.89  			>
    3.90  		</File>
    3.91  		<File
    3.92 +			RelativePath="..\..\src\video\windows\SDL_windowsvulkan.c"
    3.93 +			>
    3.94 +		</File>
    3.95 +		<File
    3.96 +			RelativePath="..\..\src\video\windows\SDL_windowsvulkan.h"
    3.97 +			>
    3.98 +		</File>
    3.99 +		<File
   3.100  			RelativePath="..\..\src\video\windows\SDL_windowswindow.c"
   3.101  			>
   3.102  		</File>
     4.1 --- a/VisualC/SDL_VS2008.sln	Sun Aug 27 19:10:30 2017 -0700
     4.2 +++ b/VisualC/SDL_VS2008.sln	Sun Aug 27 22:15:57 2017 -0400
     4.3 @@ -48,6 +48,8 @@
     4.4  EndProject
     4.5  Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D69D5741-611F-4E14-8541-1FEE94F50B5A}"
     4.6  EndProject
     4.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testvulkan", "tests\testvulkan\testvulkan_VS2008.vcproj", "{0D604DFD-AAB6-442C-9368-F91A344146AB}"
     4.8 +EndProject
     4.9  Global
    4.10  	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    4.11  		Debug|Win32 = Debug|Win32
    4.12 @@ -240,6 +242,14 @@
    4.13  		{55812185-D13C-4022-9C81-32E0F4A08306}.Release|Win32.Build.0 = Release|Win32
    4.14  		{55812185-D13C-4022-9C81-32E0F4A08306}.Release|x64.ActiveCfg = Release|x64
    4.15  		{55812185-D13C-4022-9C81-32E0F4A08306}.Release|x64.Build.0 = Release|x64
    4.16 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|Win32.ActiveCfg = Debug|Win32
    4.17 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|Win32.Build.0 = Debug|Win32
    4.18 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|x64.ActiveCfg = Debug|x64
    4.19 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|x64.Build.0 = Debug|x64
    4.20 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|Win32.ActiveCfg = Release|Win32
    4.21 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|Win32.Build.0 = Release|Win32
    4.22 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|x64.ActiveCfg = Release|x64
    4.23 +		{0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|x64.Build.0 = Release|x64
    4.24  	EndGlobalSection
    4.25  	GlobalSection(SolutionProperties) = preSolution
    4.26  		HideSolutionNode = FALSE
    4.27 @@ -265,5 +275,6 @@
    4.28  		{E9558DFE-1961-4DD4-B09B-DD0EEFD5C315} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
    4.29  		{55812185-D13C-4022-9C81-32E0F4A08306} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
    4.30  		{26828762-C95D-4637-9CB1-7F0979523813} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
    4.31 +		{0D604DFD-AAB6-442C-9368-F91A344146AB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
    4.32  	EndGlobalSection
    4.33  EndGlobal
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/VisualC/tests/testvulkan/testvulkan_VS2008.vcproj	Sun Aug 27 22:15:57 2017 -0400
     5.3 @@ -0,0 +1,355 @@
     5.4 +<?xml version="1.0" encoding="Windows-1252"?>
     5.5 +<VisualStudioProject
     5.6 +	ProjectType="Visual C++"
     5.7 +	Version="9.00"
     5.8 +	Name="testvulkan"
     5.9 +	ProjectGUID="{0D604DFD-AAB6-442C-9368-F91A344146AB}"
    5.10 +	RootNamespace="testvulkan"
    5.11 +	TargetFrameworkVersion="131072"
    5.12 +	>
    5.13 +	<Platforms>
    5.14 +		<Platform
    5.15 +			Name="Win32"
    5.16 +		/>
    5.17 +		<Platform
    5.18 +			Name="x64"
    5.19 +		/>
    5.20 +	</Platforms>
    5.21 +	<ToolFiles>
    5.22 +	</ToolFiles>
    5.23 +	<Configurations>
    5.24 +		<Configuration
    5.25 +			Name="Debug|Win32"
    5.26 +			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
    5.27 +			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\"
    5.28 +			ConfigurationType="1"
    5.29 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
    5.30 +			UseOfMFC="0"
    5.31 +			ATLMinimizesCRunTimeLibraryUsage="false"
    5.32 +			>
    5.33 +			<Tool
    5.34 +				Name="VCPreBuildEventTool"
    5.35 +			/>
    5.36 +			<Tool
    5.37 +				Name="VCCustomBuildTool"
    5.38 +			/>
    5.39 +			<Tool
    5.40 +				Name="VCXMLDataGeneratorTool"
    5.41 +			/>
    5.42 +			<Tool
    5.43 +				Name="VCWebServiceProxyGeneratorTool"
    5.44 +			/>
    5.45 +			<Tool
    5.46 +				Name="VCMIDLTool"
    5.47 +				PreprocessorDefinitions="_DEBUG"
    5.48 +				MkTypLibCompatible="true"
    5.49 +				SuppressStartupBanner="true"
    5.50 +				TargetEnvironment="1"
    5.51 +				TypeLibraryName=".\Debug/testvulkan.tlb"
    5.52 +			/>
    5.53 +			<Tool
    5.54 +				Name="VCCLCompilerTool"
    5.55 +				Optimization="0"
    5.56 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
    5.57 +				AdditionalUsingDirectories=""
    5.58 +				PreprocessorDefinitions="_DEBUG,WIN32,_WINDOWS,HAVE_OPENGL"
    5.59 +				RuntimeLibrary="2"
    5.60 +				WarningLevel="3"
    5.61 +				DebugInformationFormat="1"
    5.62 +			/>
    5.63 +			<Tool
    5.64 +				Name="VCManagedResourceCompilerTool"
    5.65 +			/>
    5.66 +			<Tool
    5.67 +				Name="VCResourceCompilerTool"
    5.68 +				PreprocessorDefinitions="_DEBUG"
    5.69 +				Culture="1033"
    5.70 +			/>
    5.71 +			<Tool
    5.72 +				Name="VCPreLinkEventTool"
    5.73 +			/>
    5.74 +			<Tool
    5.75 +				Name="VCLinkerTool"
    5.76 +				GenerateDebugInformation="true"
    5.77 +				SubSystem="2"
    5.78 +			/>
    5.79 +			<Tool
    5.80 +				Name="VCALinkTool"
    5.81 +			/>
    5.82 +			<Tool
    5.83 +				Name="VCManifestTool"
    5.84 +			/>
    5.85 +			<Tool
    5.86 +				Name="VCXDCMakeTool"
    5.87 +			/>
    5.88 +			<Tool
    5.89 +				Name="VCBscMakeTool"
    5.90 +			/>
    5.91 +			<Tool
    5.92 +				Name="VCFxCopTool"
    5.93 +			/>
    5.94 +			<Tool
    5.95 +				Name="VCAppVerifierTool"
    5.96 +			/>
    5.97 +			<Tool
    5.98 +				Name="VCPostBuildEventTool"
    5.99 +			/>
   5.100 +		</Configuration>
   5.101 +		<Configuration
   5.102 +			Name="Debug|x64"
   5.103 +			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
   5.104 +			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\"
   5.105 +			ConfigurationType="1"
   5.106 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
   5.107 +			UseOfMFC="0"
   5.108 +			ATLMinimizesCRunTimeLibraryUsage="false"
   5.109 +			>
   5.110 +			<Tool
   5.111 +				Name="VCPreBuildEventTool"
   5.112 +			/>
   5.113 +			<Tool
   5.114 +				Name="VCCustomBuildTool"
   5.115 +			/>
   5.116 +			<Tool
   5.117 +				Name="VCXMLDataGeneratorTool"
   5.118 +			/>
   5.119 +			<Tool
   5.120 +				Name="VCWebServiceProxyGeneratorTool"
   5.121 +			/>
   5.122 +			<Tool
   5.123 +				Name="VCMIDLTool"
   5.124 +				PreprocessorDefinitions="_DEBUG"
   5.125 +				MkTypLibCompatible="true"
   5.126 +				SuppressStartupBanner="true"
   5.127 +				TargetEnvironment="3"
   5.128 +				TypeLibraryName=".\Debug/testvulkan.tlb"
   5.129 +			/>
   5.130 +			<Tool
   5.131 +				Name="VCCLCompilerTool"
   5.132 +				Optimization="0"
   5.133 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
   5.134 +				AdditionalUsingDirectories=""
   5.135 +				PreprocessorDefinitions="_DEBUG,WIN32,_WINDOWS,HAVE_OPENGL"
   5.136 +				RuntimeLibrary="3"
   5.137 +				WarningLevel="3"
   5.138 +				DebugInformationFormat="1"
   5.139 +			/>
   5.140 +			<Tool
   5.141 +				Name="VCManagedResourceCompilerTool"
   5.142 +			/>
   5.143 +			<Tool
   5.144 +				Name="VCResourceCompilerTool"
   5.145 +				PreprocessorDefinitions="_DEBUG"
   5.146 +				Culture="1033"
   5.147 +			/>
   5.148 +			<Tool
   5.149 +				Name="VCPreLinkEventTool"
   5.150 +			/>
   5.151 +			<Tool
   5.152 +				Name="VCLinkerTool"
   5.153 +				GenerateDebugInformation="true"
   5.154 +				SubSystem="2"
   5.155 +			/>
   5.156 +			<Tool
   5.157 +				Name="VCALinkTool"
   5.158 +			/>
   5.159 +			<Tool
   5.160 +				Name="VCManifestTool"
   5.161 +			/>
   5.162 +			<Tool
   5.163 +				Name="VCXDCMakeTool"
   5.164 +			/>
   5.165 +			<Tool
   5.166 +				Name="VCBscMakeTool"
   5.167 +			/>
   5.168 +			<Tool
   5.169 +				Name="VCFxCopTool"
   5.170 +			/>
   5.171 +			<Tool
   5.172 +				Name="VCAppVerifierTool"
   5.173 +			/>
   5.174 +			<Tool
   5.175 +				Name="VCPostBuildEventTool"
   5.176 +			/>
   5.177 +		</Configuration>
   5.178 +		<Configuration
   5.179 +			Name="Release|Win32"
   5.180 +			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
   5.181 +			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\"
   5.182 +			ConfigurationType="1"
   5.183 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
   5.184 +			UseOfMFC="0"
   5.185 +			ATLMinimizesCRunTimeLibraryUsage="false"
   5.186 +			>
   5.187 +			<Tool
   5.188 +				Name="VCPreBuildEventTool"
   5.189 +			/>
   5.190 +			<Tool
   5.191 +				Name="VCCustomBuildTool"
   5.192 +			/>
   5.193 +			<Tool
   5.194 +				Name="VCXMLDataGeneratorTool"
   5.195 +			/>
   5.196 +			<Tool
   5.197 +				Name="VCWebServiceProxyGeneratorTool"
   5.198 +			/>
   5.199 +			<Tool
   5.200 +				Name="VCMIDLTool"
   5.201 +				PreprocessorDefinitions="NDEBUG"
   5.202 +				MkTypLibCompatible="true"
   5.203 +				SuppressStartupBanner="true"
   5.204 +				TargetEnvironment="1"
   5.205 +				TypeLibraryName=".\Release/testvulkan.tlb"
   5.206 +			/>
   5.207 +			<Tool
   5.208 +				Name="VCCLCompilerTool"
   5.209 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
   5.210 +				AdditionalUsingDirectories=""
   5.211 +				PreprocessorDefinitions="NDEBUG,WIN32,_WINDOWS,HAVE_OPENGL"
   5.212 +				RuntimeLibrary="2"
   5.213 +				WarningLevel="3"
   5.214 +			/>
   5.215 +			<Tool
   5.216 +				Name="VCManagedResourceCompilerTool"
   5.217 +			/>
   5.218 +			<Tool
   5.219 +				Name="VCResourceCompilerTool"
   5.220 +				PreprocessorDefinitions="NDEBUG"
   5.221 +				Culture="1033"
   5.222 +			/>
   5.223 +			<Tool
   5.224 +				Name="VCPreLinkEventTool"
   5.225 +			/>
   5.226 +			<Tool
   5.227 +				Name="VCLinkerTool"
   5.228 +				SubSystem="2"
   5.229 +			/>
   5.230 +			<Tool
   5.231 +				Name="VCALinkTool"
   5.232 +			/>
   5.233 +			<Tool
   5.234 +				Name="VCManifestTool"
   5.235 +			/>
   5.236 +			<Tool
   5.237 +				Name="VCXDCMakeTool"
   5.238 +			/>
   5.239 +			<Tool
   5.240 +				Name="VCBscMakeTool"
   5.241 +			/>
   5.242 +			<Tool
   5.243 +				Name="VCFxCopTool"
   5.244 +			/>
   5.245 +			<Tool
   5.246 +				Name="VCAppVerifierTool"
   5.247 +			/>
   5.248 +			<Tool
   5.249 +				Name="VCPostBuildEventTool"
   5.250 +			/>
   5.251 +		</Configuration>
   5.252 +		<Configuration
   5.253 +			Name="Release|x64"
   5.254 +			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
   5.255 +			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\"
   5.256 +			ConfigurationType="1"
   5.257 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
   5.258 +			UseOfMFC="0"
   5.259 +			ATLMinimizesCRunTimeLibraryUsage="false"
   5.260 +			>
   5.261 +			<Tool
   5.262 +				Name="VCPreBuildEventTool"
   5.263 +			/>
   5.264 +			<Tool
   5.265 +				Name="VCCustomBuildTool"
   5.266 +			/>
   5.267 +			<Tool
   5.268 +				Name="VCXMLDataGeneratorTool"
   5.269 +			/>
   5.270 +			<Tool
   5.271 +				Name="VCWebServiceProxyGeneratorTool"
   5.272 +			/>
   5.273 +			<Tool
   5.274 +				Name="VCMIDLTool"
   5.275 +				PreprocessorDefinitions="NDEBUG"
   5.276 +				MkTypLibCompatible="true"
   5.277 +				SuppressStartupBanner="true"
   5.278 +				TargetEnvironment="3"
   5.279 +				TypeLibraryName=".\Release/testvulkan.tlb"
   5.280 +			/>
   5.281 +			<Tool
   5.282 +				Name="VCCLCompilerTool"
   5.283 +				AdditionalIncludeDirectories="&quot;$(SolutionDir)/../include&quot;;&quot;$(VULKAN_SDK)/include&quot;"
   5.284 +				AdditionalUsingDirectories=""
   5.285 +				PreprocessorDefinitions="NDEBUG,WIN32,_WINDOWS,HAVE_OPENGL"
   5.286 +				RuntimeLibrary="2"
   5.287 +				WarningLevel="3"
   5.288 +			/>
   5.289 +			<Tool
   5.290 +				Name="VCManagedResourceCompilerTool"
   5.291 +			/>
   5.292 +			<Tool
   5.293 +				Name="VCResourceCompilerTool"
   5.294 +				PreprocessorDefinitions="NDEBUG"
   5.295 +				Culture="1033"
   5.296 +			/>
   5.297 +			<Tool
   5.298 +				Name="VCPreLinkEventTool"
   5.299 +			/>
   5.300 +			<Tool
   5.301 +				Name="VCLinkerTool"
   5.302 +				SubSystem="2"
   5.303 +			/>
   5.304 +			<Tool
   5.305 +				Name="VCALinkTool"
   5.306 +			/>
   5.307 +			<Tool
   5.308 +				Name="VCManifestTool"
   5.309 +			/>
   5.310 +			<Tool
   5.311 +				Name="VCXDCMakeTool"
   5.312 +			/>
   5.313 +			<Tool
   5.314 +				Name="VCBscMakeTool"
   5.315 +			/>
   5.316 +			<Tool
   5.317 +				Name="VCFxCopTool"
   5.318 +			/>
   5.319 +			<Tool
   5.320 +				Name="VCAppVerifierTool"
   5.321 +			/>
   5.322 +			<Tool
   5.323 +				Name="VCPostBuildEventTool"
   5.324 +			/>
   5.325 +		</Configuration>
   5.326 +	</Configurations>
   5.327 +	<References>
   5.328 +		<ProjectReference
   5.329 +			ReferencedProjectIdentifier="{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
   5.330 +			CopyLocal="false"
   5.331 +			CopyLocalDependencies="false"
   5.332 +			CopyLocalSatelliteAssemblies="false"
   5.333 +			RelativePathToProject=".\SDL\SDL_VS2008.vcproj"
   5.334 +		/>
   5.335 +		<ProjectReference
   5.336 +			ReferencedProjectIdentifier="{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}"
   5.337 +			CopyLocal="false"
   5.338 +			CopyLocalDependencies="false"
   5.339 +			CopyLocalSatelliteAssemblies="false"
   5.340 +			RelativePathToProject=".\SDLmain\SDLmain_VS2008.vcproj"
   5.341 +		/>
   5.342 +		<ProjectReference
   5.343 +			ReferencedProjectIdentifier="{DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}"
   5.344 +			CopyLocal="false"
   5.345 +			CopyLocalDependencies="false"
   5.346 +			CopyLocalSatelliteAssemblies="false"
   5.347 +			RelativePathToProject=".\SDLtest\SDLtest_VS2008.vcproj"
   5.348 +		/>
   5.349 +	</References>
   5.350 +	<Files>
   5.351 +		<File
   5.352 +			RelativePath="..\..\..\test\testvulkan.c"
   5.353 +			>
   5.354 +		</File>
   5.355 +	</Files>
   5.356 +	<Globals>
   5.357 +	</Globals>
   5.358 +</VisualStudioProject>
     6.1 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 27 19:10:30 2017 -0700
     6.2 +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 27 22:15:57 2017 -0400
     6.3 @@ -67,6 +67,13 @@
     6.4  		04F7808512FB753F00FC43C0 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; };
     6.5  		04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
     6.6  		04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
     6.7 +		4D7516FB1EE1C28A00820EEA /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7516F81EE1C28A00820EEA /* SDL_uikitmetalview.m */; };
     6.8 +		4D7516FC1EE1C28A00820EEA /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D7516F91EE1C28A00820EEA /* SDL_uikitvulkan.h */; };
     6.9 +		4D7516FD1EE1C28A00820EEA /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7516FA1EE1C28A00820EEA /* SDL_uikitvulkan.m */; };
    6.10 +		4D7516FF1EE1C5B400820EEA /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D7516FE1EE1C5B400820EEA /* SDL_vulkan.h */; };
    6.11 +		4D75171A1EE1D32200820EEA /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D7517191EE1D32200820EEA /* SDL_uikitmetalview.h */; };
    6.12 +		4D75171F1EE1D98200820EEA /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D75171D1EE1D98200820EEA /* SDL_vulkan_internal.h */; };
    6.13 +		4D7517201EE1D98200820EEA /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D75171E1EE1D98200820EEA /* SDL_vulkan_utils.c */; };
    6.14  		566726451DF72CF5001DD3DB /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; };
    6.15  		566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 566726441DF72CF5001DD3DB /* SDL_dataqueue.h */; };
    6.16  		56A6702E18565E450007D20F /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6702D18565E450007D20F /* SDL_internal.h */; };
    6.17 @@ -364,6 +371,13 @@
    6.18  		04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_nullframebuffer.c; sourceTree = "<group>"; };
    6.19  		04FFAB8912E23B8D00BA343D /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
    6.20  		04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = "<group>"; };
    6.21 +		4D7516F81EE1C28A00820EEA /* SDL_uikitmetalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitmetalview.m; sourceTree = "<group>"; };
    6.22 +		4D7516F91EE1C28A00820EEA /* SDL_uikitvulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitvulkan.h; sourceTree = "<group>"; };
    6.23 +		4D7516FA1EE1C28A00820EEA /* SDL_uikitvulkan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitvulkan.m; sourceTree = "<group>"; };
    6.24 +		4D7516FE1EE1C5B400820EEA /* SDL_vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = "<group>"; };
    6.25 +		4D7517191EE1D32200820EEA /* SDL_uikitmetalview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitmetalview.h; sourceTree = "<group>"; };
    6.26 +		4D75171D1EE1D98200820EEA /* SDL_vulkan_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan_internal.h; sourceTree = "<group>"; };
    6.27 +		4D75171E1EE1D98200820EEA /* SDL_vulkan_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_vulkan_utils.c; sourceTree = "<group>"; };
    6.28  		566726431DF72CF5001DD3DB /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dataqueue.c; path = ../../src/SDL_dataqueue.c; sourceTree = "<group>"; };
    6.29  		566726441DF72CF5001DD3DB /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dataqueue.h; path = ../../src/SDL_dataqueue.h; sourceTree = "<group>"; };
    6.30  		56A6702D18565E450007D20F /* SDL_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_internal.h; path = ../../src/SDL_internal.h; sourceTree = "<group>"; };
    6.31 @@ -759,6 +773,8 @@
    6.32  				FD689F0D0E26E5D900F90B21 /* SDL_uikitevents.m */,
    6.33  				AABCC3921640643D00AB8930 /* SDL_uikitmessagebox.h */,
    6.34  				AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */,
    6.35 +				4D7517191EE1D32200820EEA /* SDL_uikitmetalview.h */,
    6.36 +				4D7516F81EE1C28A00820EEA /* SDL_uikitmetalview.m */,
    6.37  				AA126AD21617C5E6005ABC8F /* SDL_uikitmodes.h */,
    6.38  				AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */,
    6.39  				FD689F0E0E26E5D900F90B21 /* SDL_uikitopengles.h */,
    6.40 @@ -771,6 +787,8 @@
    6.41  				FD689F130E26E5D900F90B21 /* SDL_uikitview.m */,
    6.42  				93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */,
    6.43  				93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */,
    6.44 +				4D7516F91EE1C28A00820EEA /* SDL_uikitvulkan.h */,
    6.45 +				4D7516FA1EE1C28A00820EEA /* SDL_uikitvulkan.m */,
    6.46  				FD689F140E26E5D900F90B21 /* SDL_uikitwindow.h */,
    6.47  				FD689F150E26E5D900F90B21 /* SDL_uikitwindow.m */,
    6.48  			);
    6.49 @@ -852,6 +870,7 @@
    6.50  				AA7558941595D55500BBD41B /* SDL_types.h */,
    6.51  				AA7558951595D55500BBD41B /* SDL_version.h */,
    6.52  				AA7558961595D55500BBD41B /* SDL_video.h */,
    6.53 +				4D7516FE1EE1C5B400820EEA /* SDL_vulkan.h */,
    6.54  			);
    6.55  			name = "Public Headers";
    6.56  			path = ../../include;
    6.57 @@ -1041,6 +1060,8 @@
    6.58  				FDA683190DF2374E00F98A1A /* SDL_surface.c */,
    6.59  				FDA6831A0DF2374E00F98A1A /* SDL_sysvideo.h */,
    6.60  				FDA6831B0DF2374E00F98A1A /* SDL_video.c */,
    6.61 +				4D75171D1EE1D98200820EEA /* SDL_vulkan_internal.h */,
    6.62 +				4D75171E1EE1D98200820EEA /* SDL_vulkan_utils.c */,
    6.63  			);
    6.64  			name = video;
    6.65  			path = ../../src/video;
    6.66 @@ -1067,6 +1088,8 @@
    6.67  			buildActionMask = 2147483647;
    6.68  			files = (
    6.69  				FDA6844E0DF2374E00F98A1A /* SDL_blit.h in Headers */,
    6.70 +				4D75171A1EE1D32200820EEA /* SDL_uikitmetalview.h in Headers */,
    6.71 +				4D75171F1EE1D98200820EEA /* SDL_vulkan_internal.h in Headers */,
    6.72  				FDA684530DF2374E00F98A1A /* SDL_blit_auto.h in Headers */,
    6.73  				FDA684550DF2374E00F98A1A /* SDL_blit_copy.h in Headers */,
    6.74  				FDA6845D0DF2374E00F98A1A /* SDL_pixels_c.h in Headers */,
    6.75 @@ -1159,8 +1182,10 @@
    6.76  				AA7558C61595D55500BBD41B /* SDL_touch.h in Headers */,
    6.77  				AA7558C71595D55500BBD41B /* SDL_types.h in Headers */,
    6.78  				AA7558C81595D55500BBD41B /* SDL_version.h in Headers */,
    6.79 +				4D7516FF1EE1C5B400820EEA /* SDL_vulkan.h in Headers */,
    6.80  				AA7558C91595D55500BBD41B /* SDL_video.h in Headers */,
    6.81  				AA7558CA1595D55500BBD41B /* SDL.h in Headers */,
    6.82 +				4D7516FC1EE1C28A00820EEA /* SDL_uikitvulkan.h in Headers */,
    6.83  				AA126AD41617C5E7005ABC8F /* SDL_uikitmodes.h in Headers */,
    6.84  				AA704DD6162AA90A0076D1C1 /* SDL_dropevents_c.h in Headers */,
    6.85  				AA9FF9511637C6E5000DF050 /* SDL_messagebox.h in Headers */,
    6.86 @@ -1213,8 +1238,15 @@
    6.87  			attributes = {
    6.88  				LastUpgradeCheck = 0800;
    6.89  				TargetAttributes = {
    6.90 +					00B4F48B12F6A69C0084EC00 = {
    6.91 +						DevelopmentTeam = UZ5V327NE3;
    6.92 +					};
    6.93  					FAB598131BB5C1B100BE72C5 = {
    6.94  						CreatedOnToolsVersion = 7.1;
    6.95 +						DevelopmentTeam = UZ5V327NE3;
    6.96 +					};
    6.97 +					FD6526620DE8FCCB002AD96B = {
    6.98 +						DevelopmentTeam = UZ5V327NE3;
    6.99  					};
   6.100  				};
   6.101  			};
   6.102 @@ -1373,6 +1405,7 @@
   6.103  				FD65266A0DE8FCDD002AD96B /* SDL_audiotypecvt.c in Sources */,
   6.104  				FD65266B0DE8FCDD002AD96B /* SDL_mixer.c in Sources */,
   6.105  				FD65266F0DE8FCDD002AD96B /* SDL_wave.c in Sources */,
   6.106 +				4D7516FD1EE1C28A00820EEA /* SDL_uikitvulkan.m in Sources */,
   6.107  				FA1DC2731C62BE65008F99A0 /* SDL_uikitclipboard.m in Sources */,
   6.108  				FD6526700DE8FCDD002AD96B /* SDL_cpuinfo.c in Sources */,
   6.109  				FD6526710DE8FCDD002AD96B /* SDL_events.c in Sources */,
   6.110 @@ -1381,7 +1414,9 @@
   6.111  				FD6526730DE8FCDD002AD96B /* SDL_mouse.c in Sources */,
   6.112  				FD6526740DE8FCDD002AD96B /* SDL_quit.c in Sources */,
   6.113  				FD6526750DE8FCDD002AD96B /* SDL_windowevents.c in Sources */,
   6.114 +				4D7516FB1EE1C28A00820EEA /* SDL_uikitmetalview.m in Sources */,
   6.115  				FD6526760DE8FCDD002AD96B /* SDL_rwops.c in Sources */,
   6.116 +				4D7517201EE1D98200820EEA /* SDL_vulkan_utils.c in Sources */,
   6.117  				FD6526780DE8FCDD002AD96B /* SDL_error.c in Sources */,
   6.118  				FD65267A0DE8FCDD002AD96B /* SDL.c in Sources */,
   6.119  				FD65267B0DE8FCDD002AD96B /* SDL_syscond.c in Sources */,
   6.120 @@ -1613,6 +1648,7 @@
   6.121  				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
   6.122  				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
   6.123  				GCC_WARN_UNDECLARED_SELECTOR = YES;
   6.124 +				HEADER_SEARCH_PATHS = "$(VULKAN_SDK)/include";
   6.125  				PRODUCT_NAME = SDL2;
   6.126  				SKIP_INSTALL = YES;
   6.127  			};
   6.128 @@ -1628,6 +1664,7 @@
   6.129  				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
   6.130  				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
   6.131  				GCC_WARN_UNDECLARED_SELECTOR = YES;
   6.132 +				HEADER_SEARCH_PATHS = "$(VULKAN_SDK)/include";
   6.133  				PRODUCT_NAME = SDL2;
   6.134  				SKIP_INSTALL = YES;
   6.135  			};
     7.1 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 27 19:10:30 2017 -0700
     7.2 +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj	Sun Aug 27 22:15:57 2017 -0400
     7.3 @@ -377,6 +377,25 @@
     7.4  		04F7805D12FB74A200FC43C0 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804512FB74A200FC43C0 /* SDL_drawline.h */; };
     7.5  		04F7805E12FB74A200FC43C0 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */; };
     7.6  		04F7805F12FB74A200FC43C0 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */; };
     7.7 +		4D16644B1EDD5FE8003DE88E /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D16644A1EDD5FE8003DE88E /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; };
     7.8 +		4D16644E1EDD6023003DE88E /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D16644C1EDD6023003DE88E /* SDL_vulkan_internal.h */; };
     7.9 +		4D16644F1EDD6023003DE88E /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D16644D1EDD6023003DE88E /* SDL_vulkan_utils.c */; };
    7.10 +		4D1664531EDD60AD003DE88E /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664501EDD60AD003DE88E /* SDL_cocoametalview.m */; };
    7.11 +		4D1664541EDD60AD003DE88E /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D1664511EDD60AD003DE88E /* SDL_cocoavulkan.h */; };
    7.12 +		4D1664551EDD60AD003DE88E /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664521EDD60AD003DE88E /* SDL_cocoavulkan.m */; };
    7.13 +		4D1664561EDD61DA003DE88E /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D16644D1EDD6023003DE88E /* SDL_vulkan_utils.c */; };
    7.14 +		4D1664571EDD61F0003DE88E /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664501EDD60AD003DE88E /* SDL_cocoametalview.m */; };
    7.15 +		4D1664581EDD61F0003DE88E /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664521EDD60AD003DE88E /* SDL_cocoavulkan.m */; };
    7.16 +		4D1664591EDD621B003DE88E /* SDL_vulkan_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D16644D1EDD6023003DE88E /* SDL_vulkan_utils.c */; };
    7.17 +		4D16645A1EDD6235003DE88E /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664501EDD60AD003DE88E /* SDL_cocoametalview.m */; };
    7.18 +		4D16645B1EDD6235003DE88E /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1664521EDD60AD003DE88E /* SDL_cocoavulkan.m */; };
    7.19 +		4D16645E1EDD73E0003DE88E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D16645D1EDD73E0003DE88E /* Metal.framework */; };
    7.20 +		4D16645F1EDD73FE003DE88E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D16645D1EDD73E0003DE88E /* Metal.framework */; };
    7.21 +		4D1664601EDD741F003DE88E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D16645D1EDD73E0003DE88E /* Metal.framework */; };
    7.22 +		4D1664641EDD7528003DE88E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D1664611EDD74A9003DE88E /* QuartzCore.framework */; };
    7.23 +		4D1664651EDD7727003DE88E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D1664611EDD74A9003DE88E /* QuartzCore.framework */; };
    7.24 +		4D1664661EDD776A003DE88E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D1664611EDD74A9003DE88E /* QuartzCore.framework */; };
    7.25 +		4D7517291EE2562B00820EEA /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D7517281EE2562B00820EEA /* SDL_cocoametalview.h */; };
    7.26  		56115BBB1DF72C6D00F47E1E /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 56115BB91DF72C6D00F47E1E /* SDL_dataqueue.c */; };
    7.27  		56115BBC1DF72C6D00F47E1E /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 56115BBA1DF72C6D00F47E1E /* SDL_dataqueue.h */; };
    7.28  		562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; };
    7.29 @@ -1015,6 +1034,16 @@
    7.30  		04F7804512FB74A200FC43C0 /* SDL_drawline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_drawline.h; sourceTree = "<group>"; };
    7.31  		04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_drawpoint.c; sourceTree = "<group>"; };
    7.32  		04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_drawpoint.h; sourceTree = "<group>"; };
    7.33 +		4D16644A1EDD5FE8003DE88E /* SDL_vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = "<group>"; };
    7.34 +		4D16644C1EDD6023003DE88E /* SDL_vulkan_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan_internal.h; sourceTree = "<group>"; };
    7.35 +		4D16644D1EDD6023003DE88E /* SDL_vulkan_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_vulkan_utils.c; sourceTree = "<group>"; };
    7.36 +		4D1664501EDD60AD003DE88E /* SDL_cocoametalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoametalview.m; sourceTree = "<group>"; };
    7.37 +		4D1664511EDD60AD003DE88E /* SDL_cocoavulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoavulkan.h; sourceTree = "<group>"; };
    7.38 +		4D1664521EDD60AD003DE88E /* SDL_cocoavulkan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoavulkan.m; sourceTree = "<group>"; };
    7.39 +		4D16645D1EDD73E0003DE88E /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
    7.40 +		4D1664611EDD74A9003DE88E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
    7.41 +		4D4820431F0F10B400EDC31C /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDL_vulkan.h; path = ../../include/SDL_vulkan.h; sourceTree = "<group>"; };
    7.42 +		4D7517281EE2562B00820EEA /* SDL_cocoametalview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoametalview.h; sourceTree = "<group>"; };
    7.43  		56115BB91DF72C6D00F47E1E /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dataqueue.c; path = ../../src/SDL_dataqueue.c; sourceTree = "<group>"; };
    7.44  		56115BBA1DF72C6D00F47E1E /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dataqueue.h; path = ../../src/SDL_dataqueue.h; sourceTree = "<group>"; };
    7.45  		566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dropevents_c.h; sourceTree = "<group>"; };
    7.46 @@ -1123,6 +1152,8 @@
    7.47  				00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */,
    7.48  				00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */,
    7.49  				00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */,
    7.50 +				4D16645E1EDD73E0003DE88E /* Metal.framework in Frameworks */,
    7.51 +				4D1664651EDD7727003DE88E /* QuartzCore.framework in Frameworks */,
    7.52  			);
    7.53  			runOnlyForDeploymentPostprocessing = 0;
    7.54  		};
    7.55 @@ -1138,6 +1169,8 @@
    7.56  				007317C30858E15000B2BC32 /* Carbon.framework in Frameworks */,
    7.57  				DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */,
    7.58  				562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */,
    7.59 +				4D16645F1EDD73FE003DE88E /* Metal.framework in Frameworks */,
    7.60 +				4D1664661EDD776A003DE88E /* QuartzCore.framework in Frameworks */,
    7.61  			);
    7.62  			runOnlyForDeploymentPostprocessing = 0;
    7.63  		};
    7.64 @@ -1153,6 +1186,8 @@
    7.65  				DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */,
    7.66  				DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */,
    7.67  				562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */,
    7.68 +				4D1664601EDD741F003DE88E /* Metal.framework in Frameworks */,
    7.69 +				4D1664641EDD7528003DE88E /* QuartzCore.framework in Frameworks */,
    7.70  			);
    7.71  			runOnlyForDeploymentPostprocessing = 0;
    7.72  		};
    7.73 @@ -1221,6 +1256,7 @@
    7.74  				AA7557F61595D4D800BBD41B /* SDL_types.h */,
    7.75  				AA7557F71595D4D800BBD41B /* SDL_version.h */,
    7.76  				AA7557F81595D4D800BBD41B /* SDL_video.h */,
    7.77 +				4D16644A1EDD5FE8003DE88E /* SDL_vulkan.h */,
    7.78  			);
    7.79  			name = "Public Headers";
    7.80  			path = ../../include;
    7.81 @@ -1573,6 +1609,8 @@
    7.82  				04BDFF7412E6671800899322 /* SDL_surface.c */,
    7.83  				04BDFF7512E6671800899322 /* SDL_sysvideo.h */,
    7.84  				04BDFF7612E6671800899322 /* SDL_video.c */,
    7.85 +				4D16644C1EDD6023003DE88E /* SDL_vulkan_internal.h */,
    7.86 +				4D16644D1EDD6023003DE88E /* SDL_vulkan_utils.c */,
    7.87  			);
    7.88  			name = video;
    7.89  			path = ../../src/video;
    7.90 @@ -1589,6 +1627,8 @@
    7.91  				04BDFEC712E6671800899322 /* SDL_cocoakeyboard.m */,
    7.92  				AABCC38B164063D200AB8930 /* SDL_cocoamessagebox.h */,
    7.93  				AABCC38C164063D200AB8930 /* SDL_cocoamessagebox.m */,
    7.94 +				4D7517281EE2562B00820EEA /* SDL_cocoametalview.h */,
    7.95 +				4D1664501EDD60AD003DE88E /* SDL_cocoametalview.m */,
    7.96  				04BDFEC812E6671800899322 /* SDL_cocoamodes.h */,
    7.97  				04BDFEC912E6671800899322 /* SDL_cocoamodes.m */,
    7.98  				04BDFECA12E6671800899322 /* SDL_cocoamouse.h */,
    7.99 @@ -1601,6 +1641,8 @@
   7.100  				04BDFECF12E6671800899322 /* SDL_cocoashape.m */,
   7.101  				04BDFED012E6671800899322 /* SDL_cocoavideo.h */,
   7.102  				04BDFED112E6671800899322 /* SDL_cocoavideo.m */,
   7.103 +				4D1664511EDD60AD003DE88E /* SDL_cocoavulkan.h */,
   7.104 +				4D1664521EDD60AD003DE88E /* SDL_cocoavulkan.m */,
   7.105  				04BDFED212E6671800899322 /* SDL_cocoawindow.h */,
   7.106  				04BDFED312E6671800899322 /* SDL_cocoawindow.m */,
   7.107  			);
   7.108 @@ -1662,6 +1704,7 @@
   7.109  		0867D691FE84028FC02AAC07 /* SDLFramework */ = {
   7.110  			isa = PBXGroup;
   7.111  			children = (
   7.112 +				4D4820431F0F10B400EDC31C /* SDL_vulkan.h */,
   7.113  				F5A2EF3900C6A39A01000001 /* BUGS.txt */,
   7.114  				F59C70FC00D5CB5801000001 /* pkg-support */,
   7.115  				0153844A006D81B07F000001 /* Public Headers */,
   7.116 @@ -1669,6 +1712,7 @@
   7.117  				034768DDFF38A45A11DB9C8B /* Products */,
   7.118  				BECDF66B0761BA81005FE872 /* Info-Framework.plist */,
   7.119  				BEC562FE0761C0E800A33029 /* Linked Frameworks */,
   7.120 +				4D16645C1EDD73E0003DE88E /* Frameworks */,
   7.121  			);
   7.122  			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";
   7.123  			indentWidth = 4;
   7.124 @@ -1717,6 +1761,15 @@
   7.125  			name = "Library Source";
   7.126  			sourceTree = "<group>";
   7.127  		};
   7.128 +		4D16645C1EDD73E0003DE88E /* Frameworks */ = {
   7.129 +			isa = PBXGroup;
   7.130 +			children = (
   7.131 +				4D1664611EDD74A9003DE88E /* QuartzCore.framework */,
   7.132 +				4D16645D1EDD73E0003DE88E /* Metal.framework */,
   7.133 +			);
   7.134 +			name = Frameworks;
   7.135 +			sourceTree = "<group>";
   7.136 +		};
   7.137  		567E2F1F17C44BBB005F1892 /* filesystem */ = {
   7.138  			isa = PBXGroup;
   7.139  			children = (
   7.140 @@ -1834,8 +1887,10 @@
   7.141  				AA7558541595D4D800BBD41B /* SDL_timer.h in Headers */,
   7.142  				AA7558561595D4D800BBD41B /* SDL_touch.h in Headers */,
   7.143  				AA7558581595D4D800BBD41B /* SDL_types.h in Headers */,
   7.144 +				AA75585C1595D4D800BBD41B /* SDL_video.h in Headers */,
   7.145  				AA75585A1595D4D800BBD41B /* SDL_version.h in Headers */,
   7.146 -				AA75585C1595D4D800BBD41B /* SDL_video.h in Headers */,
   7.147 +				4D16644B1EDD5FE8003DE88E /* SDL_vulkan.h in Headers */,
   7.148 +				4D7517291EE2562B00820EEA /* SDL_cocoametalview.h in Headers */,
   7.149  				04BD000912E6671800899322 /* SDL_diskaudio.h in Headers */,
   7.150  				04BD001112E6671800899322 /* SDL_dummyaudio.h in Headers */,
   7.151  				04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */,
   7.152 @@ -1871,6 +1926,7 @@
   7.153  				04BD00CB12E6671800899322 /* SDL_thread_c.h in Headers */,
   7.154  				04BD00D812E6671800899322 /* SDL_timer_c.h in Headers */,
   7.155  				04BD00F312E6671800899322 /* SDL_cocoaclipboard.h in Headers */,
   7.156 +				4D1664541EDD60AD003DE88E /* SDL_cocoavulkan.h in Headers */,
   7.157  				04BD00F512E6671800899322 /* SDL_cocoaevents.h in Headers */,
   7.158  				04BD00F712E6671800899322 /* SDL_cocoakeyboard.h in Headers */,
   7.159  				04BD00F912E6671800899322 /* SDL_cocoamodes.h in Headers */,
   7.160 @@ -1891,6 +1947,7 @@
   7.161  				04BD019912E6671800899322 /* SDL_shape_internals.h in Headers */,
   7.162  				04BD019C12E6671800899322 /* SDL_sysvideo.h in Headers */,
   7.163  				04BD01DC12E6671800899322 /* imKStoUCS.h in Headers */,
   7.164 +				4D16644E1EDD6023003DE88E /* SDL_vulkan_internal.h in Headers */,
   7.165  				04BD01DE12E6671800899322 /* SDL_x11clipboard.h in Headers */,
   7.166  				04BD01E012E6671800899322 /* SDL_x11dyn.h in Headers */,
   7.167  				04BD01E212E6671800899322 /* SDL_x11events.h in Headers */,
   7.168 @@ -2325,14 +2382,6 @@
   7.169  			isa = PBXProject;
   7.170  			attributes = {
   7.171  				LastUpgradeCheck = 0730;
   7.172 -				TargetAttributes = {
   7.173 -					BECDF5FE0761BA81005FE872 = {
   7.174 -						DevelopmentTeam = EH385AYQ6F;
   7.175 -					};
   7.176 -					BECDF6BB0761BA81005FE872 = {
   7.177 -						DevelopmentTeam = EH385AYQ6F;
   7.178 -					};
   7.179 -				};
   7.180  			};
   7.181  			buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */;
   7.182  			compatibilityVersion = "Xcode 3.2";
   7.183 @@ -2425,12 +2474,14 @@
   7.184  				04BD005A12E6671800899322 /* SDL_rwops.c in Sources */,
   7.185  				04BD005B12E6671800899322 /* SDL_syshaptic.c in Sources */,
   7.186  				04BD005F12E6671800899322 /* SDL_haptic.c in Sources */,
   7.187 +				4D1664551EDD60AD003DE88E /* SDL_cocoavulkan.m in Sources */,
   7.188  				04BD006612E6671800899322 /* SDL_sysjoystick.c in Sources */,
   7.189  				04BD007012E6671800899322 /* SDL_joystick.c in Sources */,
   7.190  				04BD008812E6671800899322 /* SDL_sysloadso.c in Sources */,
   7.191  				04BD009412E6671800899322 /* SDL_syspower.c in Sources */,
   7.192  				04BD009612E6671800899322 /* SDL_power.c in Sources */,
   7.193  				04BD009C12E6671800899322 /* SDL_assert.c in Sources */,
   7.194 +				4D1664531EDD60AD003DE88E /* SDL_cocoametalview.m in Sources */,
   7.195  				04BD009F12E6671800899322 /* SDL_error.c in Sources */,
   7.196  				04BD00A212E6671800899322 /* SDL.c in Sources */,
   7.197  				04BD00A312E6671800899322 /* SDL_getenv.c in Sources */,
   7.198 @@ -2451,6 +2502,7 @@
   7.199  				04BD00F612E6671800899322 /* SDL_cocoaevents.m in Sources */,
   7.200  				04BD00F812E6671800899322 /* SDL_cocoakeyboard.m in Sources */,
   7.201  				04BD00FA12E6671800899322 /* SDL_cocoamodes.m in Sources */,
   7.202 +				4D16644F1EDD6023003DE88E /* SDL_vulkan_utils.c in Sources */,
   7.203  				04BD00FC12E6671800899322 /* SDL_cocoamouse.m in Sources */,
   7.204  				04BD00FE12E6671800899322 /* SDL_cocoaopengl.m in Sources */,
   7.205  				04BD010012E6671800899322 /* SDL_cocoashape.m in Sources */,
   7.206 @@ -2521,6 +2573,9 @@
   7.207  			isa = PBXSourcesBuildPhase;
   7.208  			buildActionMask = 2147483647;
   7.209  			files = (
   7.210 +				4D1664571EDD61F0003DE88E /* SDL_cocoametalview.m in Sources */,
   7.211 +				4D1664581EDD61F0003DE88E /* SDL_cocoavulkan.m in Sources */,
   7.212 +				4D1664561EDD61DA003DE88E /* SDL_vulkan_utils.c in Sources */,
   7.213  				04BD021712E6671800899322 /* SDL_atomic.c in Sources */,
   7.214  				04BD021812E6671800899322 /* SDL_spinlock.c in Sources */,
   7.215  				56F9D55C1DF73B6B00C15B5D /* SDL_dataqueue.c in Sources */,
   7.216 @@ -2641,6 +2696,9 @@
   7.217  			isa = PBXSourcesBuildPhase;
   7.218  			buildActionMask = 2147483647;
   7.219  			files = (
   7.220 +				4D16645A1EDD6235003DE88E /* SDL_cocoametalview.m in Sources */,
   7.221 +				4D16645B1EDD6235003DE88E /* SDL_cocoavulkan.m in Sources */,
   7.222 +				4D1664591EDD621B003DE88E /* SDL_vulkan_utils.c in Sources */,
   7.223  				DB313FFE17554B71006C0E22 /* SDL_atomic.c in Sources */,
   7.224  				DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */,
   7.225  				56F9D55D1DF73B6C00C15B5D /* SDL_dataqueue.c in Sources */,
   7.226 @@ -2810,7 +2868,10 @@
   7.227  				DYLIB_COMPATIBILITY_VERSION = 1.0.0;
   7.228  				DYLIB_CURRENT_VERSION = 7.0.0;
   7.229  				FRAMEWORK_VERSION = A;
   7.230 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.231 +				HEADER_SEARCH_PATHS = (
   7.232 +					/usr/X11R6/include,
   7.233 +					"$(VULKAN_SDK)/include",
   7.234 +				);
   7.235  				INFOPLIST_FILE = "Info-Framework.plist";
   7.236  				INSTALL_PATH = "@rpath";
   7.237  				OTHER_LDFLAGS = "-liconv";
   7.238 @@ -2833,7 +2894,10 @@
   7.239  					"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)",
   7.240  				);
   7.241  				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
   7.242 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.243 +				HEADER_SEARCH_PATHS = (
   7.244 +					/usr/X11R6/include,
   7.245 +					"$(VULKAN_SDK)/include",
   7.246 +				);
   7.247  				PRODUCT_NAME = SDL2;
   7.248  				SKIP_INSTALL = YES;
   7.249  			};
   7.250 @@ -2889,7 +2953,10 @@
   7.251  				DYLIB_COMPATIBILITY_VERSION = 1.0.0;
   7.252  				DYLIB_CURRENT_VERSION = 7.0.0;
   7.253  				FRAMEWORK_VERSION = A;
   7.254 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.255 +				HEADER_SEARCH_PATHS = (
   7.256 +					/usr/X11R6/include,
   7.257 +					"$(VULKAN_SDK)/include",
   7.258 +				);
   7.259  				INFOPLIST_FILE = "Info-Framework.plist";
   7.260  				INSTALL_PATH = "@rpath";
   7.261  				OTHER_LDFLAGS = "-liconv";
   7.262 @@ -2912,7 +2979,10 @@
   7.263  					"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)",
   7.264  				);
   7.265  				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
   7.266 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.267 +				HEADER_SEARCH_PATHS = (
   7.268 +					/usr/X11R6/include,
   7.269 +					"$(VULKAN_SDK)/include",
   7.270 +				);
   7.271  				PRODUCT_NAME = SDL2;
   7.272  				SKIP_INSTALL = YES;
   7.273  			};
   7.274 @@ -2939,7 +3009,10 @@
   7.275  					"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)",
   7.276  				);
   7.277  				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
   7.278 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.279 +				HEADER_SEARCH_PATHS = (
   7.280 +					/usr/X11R6/include,
   7.281 +					"$(VULKAN_SDK)/include",
   7.282 +				);
   7.283  				INSTALL_PATH = "@rpath";
   7.284  				PRODUCT_NAME = SDL2;
   7.285  				SKIP_INSTALL = YES;
   7.286 @@ -2959,7 +3032,10 @@
   7.287  					"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_4)",
   7.288  				);
   7.289  				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
   7.290 -				HEADER_SEARCH_PATHS = /usr/X11R6/include;
   7.291 +				HEADER_SEARCH_PATHS = (
   7.292 +					/usr/X11R6/include,
   7.293 +					"$(VULKAN_SDK)/include",
   7.294 +				);
   7.295  				INSTALL_PATH = "@rpath";
   7.296  				PRODUCT_NAME = SDL2;
   7.297  				SKIP_INSTALL = YES;
     8.1 --- a/cmake/sdlchecks.cmake	Sun Aug 27 19:10:30 2017 -0700
     8.2 +++ b/cmake/sdlchecks.cmake	Sun Aug 27 22:15:57 2017 -0400
     8.3 @@ -1153,6 +1153,25 @@
     8.4    endif(VIDEO_RPI)
     8.5  endmacro(CheckRPI)
     8.6  
     8.7 +macro(CheckVulkanHeaders)
     8.8 +  if(VIDEO_VULKAN)
     8.9 +    # ${VULKAN_SDK} could be unset during the first configure run with
    8.10 +    # cmake-gui resulting in vulkan.h not being found. If it's been
    8.11 +    # subsequently changed, unset is necessary to ensure check is run again.
    8.12 +    unset(HAVE_VULKAN_H CACHE)
    8.13 +    # Prefer ${VULKAN_SDK} header
    8.14 +    set(CMAKE_REQUIRED_INCLUDES "${VULKAN_SDK}/include")
    8.15 +    check_include_file("vulkan/vulkan.h" HAVE_VULKAN_H)
    8.16 +    if(HAVE_VULKAN_H)
    8.17 +      list(APPEND EXTRA_CFLAGS "-I${VULKAN_SDK}/include")
    8.18 +    else()
    8.19 +      # Check system includes.
    8.20 +      unset(HAVE_VULKAN_H CACHE)
    8.21 +      check_include_file("vulkan/vulkan.h" HAVE_VULKAN_H)
    8.22 +    endif()
    8.23 +  endif()
    8.24 +endmacro(CheckVulkanHeaders)
    8.25 +
    8.26  # Requires:
    8.27  # - EGL
    8.28  # - PkgCheckModules
     9.1 --- a/configure	Sun Aug 27 19:10:30 2017 -0700
     9.2 +++ b/configure	Sun Aug 27 22:15:57 2017 -0400
     9.3 @@ -745,6 +745,7 @@
     9.4  docdir
     9.5  oldincludedir
     9.6  includedir
     9.7 +runstatedir
     9.8  localstatedir
     9.9  sharedstatedir
    9.10  sysconfdir
    9.11 @@ -854,6 +855,7 @@
    9.12  enable_video_opengles
    9.13  enable_video_opengles1
    9.14  enable_video_opengles2
    9.15 +enable_video_vulkan
    9.16  enable_libudev
    9.17  enable_dbus
    9.18  enable_ime
    9.19 @@ -920,6 +922,7 @@
    9.20  sysconfdir='${prefix}/etc'
    9.21  sharedstatedir='${prefix}/com'
    9.22  localstatedir='${prefix}/var'
    9.23 +runstatedir='${localstatedir}/run'
    9.24  includedir='${prefix}/include'
    9.25  oldincludedir='/usr/include'
    9.26  docdir='${datarootdir}/doc/${PACKAGE}'
    9.27 @@ -1172,6 +1175,15 @@
    9.28    | -silent | --silent | --silen | --sile | --sil)
    9.29      silent=yes ;;
    9.30  
    9.31 +  -runstatedir | --runstatedir | --runstatedi | --runstated \
    9.32 +  | --runstate | --runstat | --runsta | --runst | --runs \
    9.33 +  | --run | --ru | --r)
    9.34 +    ac_prev=runstatedir ;;
    9.35 +  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
    9.36 +  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
    9.37 +  | --run=* | --ru=* | --r=*)
    9.38 +    runstatedir=$ac_optarg ;;
    9.39 +
    9.40    -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    9.41      ac_prev=sbindir ;;
    9.42    -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
    9.43 @@ -1309,7 +1321,7 @@
    9.44  for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
    9.45  		datadir sysconfdir sharedstatedir localstatedir includedir \
    9.46  		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
    9.47 -		libdir localedir mandir
    9.48 +		libdir localedir mandir runstatedir
    9.49  do
    9.50    eval ac_val=\$$ac_var
    9.51    # Remove trailing slashes.
    9.52 @@ -1462,6 +1474,7 @@
    9.53    --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
    9.54    --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
    9.55    --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
    9.56 +  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
    9.57    --libdir=DIR            object code libraries [EPREFIX/lib]
    9.58    --includedir=DIR        C header files [PREFIX/include]
    9.59    --oldincludedir=DIR     C header files for non-gcc [/usr/include]
    9.60 @@ -1603,6 +1616,7 @@
    9.61                            include OpenGL ES 1.1 support [[default=yes]]
    9.62    --enable-video-opengles2
    9.63                            include OpenGL ES 2.0 support [[default=yes]]
    9.64 +  --enable-video-vulkan   include Vulkan surface support [[default=yes]]
    9.65    --enable-libudev        enable libudev support [[default=yes]]
    9.66    --enable-dbus           enable D-Bus support [[default=yes]]
    9.67    --enable-ime            enable IME support [[default=yes]]
    9.68 @@ -21891,6 +21905,87 @@
    9.69      fi
    9.70  }
    9.71  
    9.72 +# Check whether --enable-video-vulkan was given.
    9.73 +if test "${enable_video_vulkan+set}" = set; then :
    9.74 +  enableval=$enable_video_vulkan;
    9.75 +else
    9.76 +  enable_video_vulkan=yes
    9.77 +fi
    9.78 +
    9.79 +
    9.80 +CheckVulkan()
    9.81 +{
    9.82 +    have_vulkan_hdr=no
    9.83 +    if test x$enable_video = xyes -a x$enable_video_vulkan = xyes; then
    9.84 +        case "$host" in
    9.85 +            *-*-androideabi*)
    9.86 +                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    9.87 +/* end confdefs.h.  */
    9.88 +
    9.89 +                  #if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
    9.90 +                  #error Vulkan doesn't work on this configuration
    9.91 +                  #endif
    9.92 +                  int main()
    9.93 +                  {
    9.94 +                     return 0;
    9.95 +                  }
    9.96 +
    9.97 +int
    9.98 +main ()
    9.99 +{
   9.100 +
   9.101 +                    enable_video_vulkan=no
   9.102 +
   9.103 +  ;
   9.104 +  return 0;
   9.105 +}
   9.106 +_ACEOF
   9.107 +if ac_fn_c_try_compile "$LINENO"; then :
   9.108 +
   9.109 +
   9.110 +fi
   9.111 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
   9.112 +                ;;
   9.113 +            *)
   9.114 +                ;;
   9.115 +        esac
   9.116 +        if test x$enable_video_vulkan = xno; then
   9.117 +            # For reasons I am totally unable to see, I get an undefined macro error if
   9.118 +            # I put this in the AC_TRY_COMPILE.
   9.119 +            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, Vulkan does not work on this configuration." >&5
   9.120 +$as_echo "$as_me: WARNING: Sorry, Vulkan does not work on this configuration." >&2;}
   9.121 +        fi
   9.122 +        if test x$enable_video_vulkan = xyes; then
   9.123 +            vsdk_include_dir="${VULKAN_SDK}/include"
   9.124 +            vulkan_header="vulkan/vulkan.h"
   9.125 +            save_CPPFLAGS="$CPPFLAGS"
   9.126 +            CPPFLAGS="${save_CPPFLAGS} -I$vsdk_include_dir"
   9.127 +            as_ac_Header=`$as_echo "ac_cv_header_$vulkan_header" | $as_tr_sh`
   9.128 +ac_fn_c_check_header_mongrel "$LINENO" "$vulkan_header" "$as_ac_Header" "$ac_includes_default"
   9.129 +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   9.130 +  have_vulkan_hdr=yes
   9.131 +else
   9.132 +  have_vulkan_hdr=no
   9.133 +fi
   9.134 +
   9.135 +
   9.136 +            CPPFLAGS="$save_CPPFLAGS"
   9.137 +        fi
   9.138 +    fi
   9.139 +    if test x$have_vulkan_hdr = xyes; then
   9.140 +        # vulkan.h has been found in either $VULKAN_SDK/include or along the
   9.141 +        # the standard include path. Unfortunately there seems no easy
   9.142 +        # way to find out which, so...
   9.143 +        if test -n "$VULKAN_SDK" -a -f "$vsdk_include_dir/$vulkan_header"; then
   9.144 +            EXTRA_CFLAGS="$EXTRA_CFLAGS -I$vsdk_include_dir"
   9.145 +        fi
   9.146 +
   9.147 +$as_echo "#define SDL_VIDEO_VULKAN_SURFACE 1" >>confdefs.h
   9.148 +
   9.149 +        SUMMARY_video="${SUMMARY_video} vulkan"
   9.150 +    fi
   9.151 +}
   9.152 +
   9.153  CheckInputEvents()
   9.154  {
   9.155              { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5
   9.156 @@ -23637,6 +23732,7 @@
   9.157          CheckKMSDRM
   9.158          CheckOpenGLX11
   9.159          CheckOpenGLESX11
   9.160 +        CheckVulkan
   9.161          CheckMir
   9.162          CheckWayland
   9.163          CheckLibUDev
   9.164 @@ -23806,6 +23902,7 @@
   9.165          CheckWINDOWS
   9.166          CheckWINDOWSGL
   9.167          CheckWINDOWSGLES
   9.168 +        CheckVulkan
   9.169          CheckDIRECTX
   9.170  
   9.171          # Set up the core platform files
   9.172 @@ -24092,6 +24189,7 @@
   9.173          CheckDummyAudio
   9.174          CheckDLOPEN
   9.175          CheckPTHREAD
   9.176 +        CheckVulkan
   9.177  
   9.178          # Set up files for the audio library
   9.179          if test x$enable_audio = xyes; then
   9.180 @@ -24174,6 +24272,9 @@
   9.181          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,OpenGLES"
   9.182          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
   9.183          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,UIKit"
   9.184 +        if test x$ac_cv_header_vulkan_vulkan_h = xyes; then
   9.185 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
   9.186 +        fi
   9.187          ;;
   9.188      *-*-darwin* )
   9.189          # This could be either full "Mac OS X", or plain "Darwin" which is
   9.190 @@ -24195,6 +24296,7 @@
   9.191          CheckX11
   9.192          CheckMacGL
   9.193          CheckOpenGLX11
   9.194 +        CheckVulkan
   9.195          CheckPTHREAD
   9.196  
   9.197          # Set up files for the audio library
   9.198 @@ -24260,6 +24362,9 @@
   9.199          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa"
   9.200          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
   9.201          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
   9.202 +        if test x$ac_cv_header_vulkan_vulkan_h = xyes; then
   9.203 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
   9.204 +        fi
   9.205          ;;
   9.206      *-nacl|*-pnacl)
   9.207          ARCH=nacl
    10.1 --- a/configure.in	Sun Aug 27 19:10:30 2017 -0700
    10.2 +++ b/configure.in	Sun Aug 27 22:15:57 2017 -0400
    10.3 @@ -2401,6 +2401,62 @@
    10.4      fi
    10.5  }
    10.6  
    10.7 +dnl Check to see if Vulkan surface support is desired
    10.8 +AC_ARG_ENABLE(video-vulkan,
    10.9 +AC_HELP_STRING([--enable-video-vulkan], [include Vulkan surface support [[default=yes]]]),
   10.10 +              , enable_video_vulkan=yes)
   10.11 +
   10.12 +dnl Find Vulkan Header
   10.13 +CheckVulkan()
   10.14 +{
   10.15 +    have_vulkan_hdr=no
   10.16 +    if test x$enable_video = xyes -a x$enable_video_vulkan = xyes; then
   10.17 +        case "$host" in
   10.18 +            *-*-androideabi*)
   10.19 +                AC_TRY_COMPILE([
   10.20 +                  #if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
   10.21 +                  #error Vulkan doesn't work on this configuration
   10.22 +                  #endif
   10.23 +                  int main()
   10.24 +                  {
   10.25 +                     return 0;
   10.26 +                  }
   10.27 +                ],[
   10.28 +                    enable_video_vulkan=no
   10.29 +                ],[
   10.30 +                ])
   10.31 +                ;;
   10.32 +            *)
   10.33 +                ;;
   10.34 +        esac
   10.35 +        if test x$enable_video_vulkan = xno; then
   10.36 +            # For reasons I am totally unable to see, I get an undefined macro error if
   10.37 +            # I put this in the AC_TRY_COMPILE.
   10.38 +            AC_MSG_WARN([Sorry, Vulkan does not work on this configuration.])
   10.39 +        fi
   10.40 +        if test x$enable_video_vulkan = xyes; then
   10.41 +            vsdk_include_dir="${VULKAN_SDK}/include"
   10.42 +            vulkan_header="vulkan/vulkan.h"
   10.43 +            save_CPPFLAGS="$CPPFLAGS"
   10.44 +            CPPFLAGS="${save_CPPFLAGS} -I$vsdk_include_dir"
   10.45 +            AC_CHECK_HEADER($vulkan_header,
   10.46 +                            have_vulkan_hdr=yes,
   10.47 +                            have_vulkan_hdr=no)
   10.48 +            CPPFLAGS="$save_CPPFLAGS"
   10.49 +        fi
   10.50 +    fi
   10.51 +    if test x$have_vulkan_hdr = xyes; then
   10.52 +        # vulkan.h has been found in either $VULKAN_SDK/include or along the
   10.53 +        # the standard include path. Unfortunately there seems no easy
   10.54 +        # way to find out which, so...
   10.55 +        if test -n "$VULKAN_SDK" -a -f "$vsdk_include_dir/$vulkan_header"; then 
   10.56 +            EXTRA_CFLAGS="$EXTRA_CFLAGS -I$vsdk_include_dir"
   10.57 +        fi
   10.58 +        AC_DEFINE(SDL_VIDEO_VULKAN_SURFACE, 1, [ ])
   10.59 +        SUMMARY_video="${SUMMARY_video} vulkan"
   10.60 +    fi
   10.61 +}
   10.62 +
   10.63  dnl See if we can use the new unified event interface in Linux 2.4
   10.64  CheckInputEvents()
   10.65  {
   10.66 @@ -3230,6 +3286,7 @@
   10.67          CheckKMSDRM
   10.68          CheckOpenGLX11
   10.69          CheckOpenGLESX11
   10.70 +        CheckVulkan
   10.71          CheckMir
   10.72          CheckWayland
   10.73          CheckLibUDev
   10.74 @@ -3375,6 +3432,7 @@
   10.75          CheckWINDOWS
   10.76          CheckWINDOWSGL
   10.77          CheckWINDOWSGLES
   10.78 +        CheckVulkan
   10.79          CheckDIRECTX
   10.80  
   10.81          # Set up the core platform files
   10.82 @@ -3559,6 +3617,7 @@
   10.83          CheckDummyAudio
   10.84          CheckDLOPEN
   10.85          CheckPTHREAD
   10.86 +        CheckVulkan
   10.87  
   10.88          # Set up files for the audio library
   10.89          if test x$enable_audio = xyes; then
   10.90 @@ -3621,6 +3680,9 @@
   10.91          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,OpenGLES"
   10.92          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
   10.93          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,UIKit"
   10.94 +        if test x$ac_cv_header_vulkan_vulkan_h = xyes; then
   10.95 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
   10.96 +        fi
   10.97          ;;
   10.98      *-*-darwin* )
   10.99          # This could be either full "Mac OS X", or plain "Darwin" which is
  10.100 @@ -3642,6 +3704,7 @@
  10.101          CheckX11
  10.102          CheckMacGL
  10.103          CheckOpenGLX11
  10.104 +        CheckVulkan
  10.105          CheckPTHREAD
  10.106  
  10.107          # Set up files for the audio library
  10.108 @@ -3695,6 +3758,9 @@
  10.109          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa"
  10.110          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
  10.111          EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
  10.112 +        if test x$ac_cv_header_vulkan_vulkan_h = xyes; then
  10.113 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
  10.114 +        fi
  10.115          ;;
  10.116      *-nacl|*-pnacl)
  10.117          ARCH=nacl
    11.1 --- a/debian/control	Sun Aug 27 19:10:30 2017 -0700
    11.2 +++ b/debian/control	Sun Aug 27 22:15:57 2017 -0400
    11.3 @@ -20,6 +20,7 @@
    11.4                 libibus-1.0-dev[linux-any],
    11.5                 libusb2-dev [kfreebsd-any],
    11.6                 libusbhid-dev [kfreebsd-any],
    11.7 +               libvulkan-dev,
    11.8                 libx11-dev,
    11.9                 libxcursor-dev,
   11.10                 libxext-dev,
    12.1 --- a/docs/README-ios.md	Sun Aug 27 19:10:30 2017 -0700
    12.2 +++ b/docs/README-ios.md	Sun Aug 27 22:15:57 2017 -0400
    12.3 @@ -7,9 +7,12 @@
    12.4  
    12.5  Requirements: Mac OS X 10.8 or later and the iOS 7+ SDK.
    12.6  
    12.7 -Instructions:
    12.8 -1.  Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode.
    12.9 -2.  Select your desired target, and hit build.
   12.10 +Instructions:
   12.11 +
   12.12 +1.  Either download [Molten](https://moltengl.com/free-trial/) and unzip it or download the Vulkan headers from Khronos's [Vulkan-Docs](https://github.com/KhronosGroup/Vulkan-Docs/tree/1.0/src/vulkan) repo and put them in a directory hierarchy `include/vulkan`.
   12.13 +2.  Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode.
   12.14 +3.  Set a `VULKAN_SDK` custom path in the Xcode preferences. Select *Custom Paths* on the *Locations* tab. The value should be either the `MoltenVK` directory within the unzipped Molten package or the parent of the `include/vulkan` hierarchy.
   12.15 +4.  Select your desired target, and hit build.
   12.16  
   12.17  There are three build targets:
   12.18  - libSDL.a:
   12.19 @@ -24,7 +27,9 @@
   12.20  Build SDL for iOS from the command line
   12.21  ==============================================================================
   12.22  
   12.23 -1. cd (PATH WHERE THE SDL CODE IS)/build-scripts
   12.24 +1. Follow step 1 above.
   12.25 +2. Either create and export a `VULKAN_SDK` environment variable with the value described in step 3 above or open Xcode, set the custom path described in step 3 above and close Xcode.
   12.26 +3. cd (PATH WHERE THE SDL CODE IS)/build-scripts
   12.27  2. ./iosbuild.sh
   12.28  
   12.29  If everything goes fine, you should see a build/ios directory, inside there's
    13.1 --- a/docs/README-linux.md	Sun Aug 27 19:10:30 2017 -0700
    13.2 +++ b/docs/README-linux.md	Sun Aug 27 22:15:57 2017 -0400
    13.3 @@ -22,8 +22,8 @@
    13.4  libgles1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev \
    13.5  fcitx-libs-dev libsamplerate0-dev libsndio-dev
    13.6  
    13.7 -Ubuntu 16.04 can also add "libwayland-dev libxkbcommon-dev wayland-protocols"
    13.8 -to that command line for Wayland support.
    13.9 +Ubuntu 16.04+ can also add "libwayland-dev libxkbcommon-dev wayland-protocols"
   13.10 +to that command line for Wayland support and "libvulkan-dev" for Vulkan surface support.
   13.11  
   13.12  Ubuntu 16.10 can also add "libmirclient-dev libxkbcommon-dev" to that command
   13.13  line for Mir support.
    14.1 --- a/docs/README-macosx.md	Sun Aug 27 19:10:30 2017 -0700
    14.2 +++ b/docs/README-macosx.md	Sun Aug 27 22:15:57 2017 -0400
    14.3 @@ -6,7 +6,19 @@
    14.4  
    14.5  From the developer's point of view, OS X is a sort of hybrid Mac and
    14.6  Unix system, and you have the option of using either traditional
    14.7 -command line tools or Apple's IDE Xcode.
    14.8 +command line tools or Apple's IDE Xcode.
    14.9 +
   14.10 +Preparation
   14.11 +===========
   14.12 +
   14.13 +1.  Either download [Molten](https://moltengl.com/free-trial/) and unzip it or download the Vulkan headers from Khronos's [Vulkan-Docs](https://github.com/KhronosGroup/Vulkan-Docs/tree/1.0/src/vulkan) repo and put them in a directory hierarchy `include/vulkan`.
   14.14 +2. Set a `VULKAN_SDK` variable in one of the ways described below. Its value should be either the `MoltenVK` directory within the unzipped Molten package or the parent of the `include/vulkan` hierarchy.
   14.15 +	- If you are going to use the command line, set and export a `VULKAN_SDK` environment variable in your shell's start-up file, e.g. `~/.bash_profile`.
   14.16 +	- If you are going to use CMake, either set and export a `VULKAN_SDK` environment variable before running `cmake` or set the `VULKAN_SDK` variable in `cmake-gui` and press *Configure*.
   14.17 +	- If you are going to use the provided Xcode projects, set a `VULKAN_SDK` custom path in Xcode's preferences. Select *Custom Paths* on the *Locations* tab of preferences.
   14.18 +
   14.19 +Command Line Build
   14.20 +==================
   14.21  
   14.22  To build SDL using the command line, use the standard configure and make
   14.23  process:
    15.1 --- a/docs/README-windows.md	Sun Aug 27 19:10:30 2017 -0700
    15.2 +++ b/docs/README-windows.md	Sun Aug 27 22:15:57 2017 -0400
    15.3 @@ -1,41 +1,45 @@
    15.4 -Windows
    15.5 -================================================================================
    15.6 -
    15.7 -================================================================================
    15.8 -OpenGL ES 2.x support
    15.9 -================================================================================
   15.10 -
   15.11 -SDL has support for OpenGL ES 2.x under Windows via two alternative 
   15.12 -implementations. 
   15.13 -The most straightforward method consists in running your app in a system with 
   15.14 -a graphic card paired with a relatively recent (as of November of 2013) driver 
   15.15 -which supports the WGL_EXT_create_context_es2_profile extension. Vendors known 
   15.16 -to ship said extension on Windows currently include nVidia and Intel.
   15.17 -
   15.18 -The other method involves using the ANGLE library (https://code.google.com/p/angleproject/)
   15.19 -If an OpenGL ES 2.x context is requested and no WGL_EXT_create_context_es2_profile
   15.20 -extension is found, SDL will try to load the libEGL.dll library provided by
   15.21 -ANGLE.
   15.22 -To obtain the ANGLE binaries, you can either compile from source from
   15.23 -https://chromium.googlesource.com/angle/angle or copy the relevant binaries from
   15.24 -a recent Chrome/Chromium install for Windows. The files you need are:
   15.25 -    
   15.26 -    * libEGL.dll
   15.27 -    * libGLESv2.dll
   15.28 -    * d3dcompiler_46.dll (supports Windows Vista or later, better shader compiler)
   15.29 -    or...
   15.30 -    * d3dcompiler_43.dll (supports Windows XP or later)
   15.31 -    
   15.32 -If you compile ANGLE from source, you can configure it so it does not need the
   15.33 -d3dcompiler_* DLL at all (for details on this, see their documentation). 
   15.34 -However, by default SDL will try to preload the d3dcompiler_46.dll to
   15.35 -comply with ANGLE's requirements. If you wish SDL to preload d3dcompiler_43.dll (to
   15.36 -support Windows XP) or to skip this step at all, you can use the 
   15.37 -SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more details).
   15.38 -
   15.39 -Known Bugs:
   15.40 -    
   15.41 -    * SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears
   15.42 -      that there's a bug in the library which prevents the window contents from
   15.43 -      refreshing if this is set to anything other than the default value.
   15.44 -      
   15.45 +Windows
   15.46 +================================================================================
   15.47 +
   15.48 +================================================================================
   15.49 +OpenGL ES 2.x support
   15.50 +================================================================================
   15.51 +
   15.52 +SDL has support for OpenGL ES 2.x under Windows via two alternative 
   15.53 +implementations. 
   15.54 +The most straightforward method consists in running your app in a system with 
   15.55 +a graphic card paired with a relatively recent (as of November of 2013) driver 
   15.56 +which supports the WGL_EXT_create_context_es2_profile extension. Vendors known 
   15.57 +to ship said extension on Windows currently include nVidia and Intel.
   15.58 +
   15.59 +The other method involves using the ANGLE library (https://code.google.com/p/angleproject/)
   15.60 +If an OpenGL ES 2.x context is requested and no WGL_EXT_create_context_es2_profile
   15.61 +extension is found, SDL will try to load the libEGL.dll library provided by
   15.62 +ANGLE.
   15.63 +To obtain the ANGLE binaries, you can either compile from source from
   15.64 +https://chromium.googlesource.com/angle/angle or copy the relevant binaries from
   15.65 +a recent Chrome/Chromium install for Windows. The files you need are:
   15.66 +    
   15.67 +    * libEGL.dll
   15.68 +    * libGLESv2.dll
   15.69 +    * d3dcompiler_46.dll (supports Windows Vista or later, better shader compiler)
   15.70 +    or...
   15.71 +    * d3dcompiler_43.dll (supports Windows XP or later)
   15.72 +    
   15.73 +If you compile ANGLE from source, you can configure it so it does not need the
   15.74 +d3dcompiler_* DLL at all (for details on this, see their documentation). 
   15.75 +However, by default SDL will try to preload the d3dcompiler_46.dll to
   15.76 +comply with ANGLE's requirements. If you wish SDL to preload d3dcompiler_43.dll (to
   15.77 +support Windows XP) or to skip this step at all, you can use the 
   15.78 +SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more details).
   15.79 +
   15.80 +Known Bugs:
   15.81 +    
   15.82 +    * SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears
   15.83 +      that there's a bug in the library which prevents the window contents from
   15.84 +      refreshing if this is set to anything other than the default value.
   15.85 +     
   15.86 +Vulkan Surface Support
   15.87 +==============
   15.88 +
   15.89 +Support for creating Vulkan surfaces is configured on by default. To disable it change the value of `SDL_VIDEO_VULKAN_SURFACE` to 0 in `SDL_config_windows`. When it is on you must install a  [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to build libSDL.
    16.1 --- a/include/SDL.h	Sun Aug 27 19:10:30 2017 -0700
    16.2 +++ b/include/SDL.h	Sun Aug 27 22:15:57 2017 -0400
    16.3 @@ -56,6 +56,7 @@
    16.4  #include "SDL_timer.h"
    16.5  #include "SDL_version.h"
    16.6  #include "SDL_video.h"
    16.7 +#include "SDL_vulkan.h"
    16.8  
    16.9  #include "begin_code.h"
   16.10  /* Set up for C function definitions, even when using C++ */
    17.1 --- a/include/SDL_config.h.cmake	Sun Aug 27 19:10:30 2017 -0700
    17.2 +++ b/include/SDL_config.h.cmake	Sun Aug 27 22:15:57 2017 -0400
    17.3 @@ -354,6 +354,9 @@
    17.4  #cmakedefine SDL_VIDEO_OPENGL_OSMESA @SDL_VIDEO_OPENGL_OSMESA@
    17.5  #cmakedefine SDL_VIDEO_OPENGL_OSMESA_DYNAMIC @SDL_VIDEO_OPENGL_OSMESA_DYNAMIC@
    17.6  
    17.7 +/* Enable Vulkan surface support */
    17.8 +#cmakedefine SDL_VIDEO_VULKAN_SURFACE @SDL_VIDEO_VULKAN_SURFACE@
    17.9 +
   17.10  /* Enable system power support */
   17.11  #cmakedefine SDL_POWER_ANDROID @SDL_POWER_ANDROID@
   17.12  #cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@
    18.1 --- a/include/SDL_config.h.in	Sun Aug 27 19:10:30 2017 -0700
    18.2 +++ b/include/SDL_config.h.in	Sun Aug 27 22:15:57 2017 -0400
    18.3 @@ -351,6 +351,9 @@
    18.4  #undef SDL_VIDEO_OPENGL_OSMESA
    18.5  #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
    18.6  
    18.7 +/* Enable Vulkan surface support */
    18.8 +#undef SDL_VIDEO_VULKAN_SURFACE
    18.9 +
   18.10  /* Enable system power support */
   18.11  #undef SDL_POWER_LINUX
   18.12  #undef SDL_POWER_WINDOWS
    19.1 --- a/include/SDL_config_android.h	Sun Aug 27 19:10:30 2017 -0700
    19.2 +++ b/include/SDL_config_android.h	Sun Aug 27 22:15:57 2017 -0400
    19.3 @@ -140,6 +140,14 @@
    19.4  #define SDL_VIDEO_RENDER_OGL_ES 1
    19.5  #define SDL_VIDEO_RENDER_OGL_ES2    1
    19.6  
    19.7 +/* Enable Vulkan surface support */
    19.8 +/* Android does not support Vulkan in native code using the "armeabi" ABI. */
    19.9 +#if !defined(__ARM_EABI__) || defined(__ARM_ARCH_7A__)
   19.10 +#define SDL_VIDEO_VULKAN_SURFACE 1
   19.11 +#else
   19.12 +#define SDL_VIDEO_VULKAN_SURFACE 0
   19.13 +#endif
   19.14 +
   19.15  /* Enable system power support */
   19.16  #define SDL_POWER_ANDROID 1
   19.17  
    20.1 --- a/include/SDL_config_iphoneos.h	Sun Aug 27 19:10:30 2017 -0700
    20.2 +++ b/include/SDL_config_iphoneos.h	Sun Aug 27 22:15:57 2017 -0400
    20.3 @@ -139,6 +139,13 @@
    20.4  #define SDL_VIDEO_RENDER_OGL_ES 1
    20.5  #define SDL_VIDEO_RENDER_OGL_ES2    1
    20.6  
    20.7 +/* Enable Vulkan surface support */
    20.8 +#if !TARGET_OS_SIMULATOR && !TARGET_CPU_ARM // Only 64-bit devices have Metal
    20.9 +#define SDL_VIDEO_VULKAN_SURFACE 1
   20.10 +#else
   20.11 +#define SDL_VIDEO_VULKAN_SURFACE 0
   20.12 +#endif
   20.13 +
   20.14  /* Enable system power support */
   20.15  #define SDL_POWER_UIKIT 1
   20.16  
    21.1 --- a/include/SDL_config_macosx.h	Sun Aug 27 19:10:30 2017 -0700
    21.2 +++ b/include/SDL_config_macosx.h	Sun Aug 27 22:15:57 2017 -0400
    21.3 @@ -174,6 +174,14 @@
    21.4  #define SDL_VIDEO_OPENGL_GLX    1
    21.5  #endif
    21.6  
    21.7 +/* enable Vulkan surface support */
    21.8 +#if TARGET_CPU_X86_64
    21.9 +/* Metal/MoltenVK/Vulkan not supported on 32-bit architectures. */
   21.10 +#define SDL_VIDEO_VULKAN_SURFACE 1
   21.11 +#else
   21.12 +#define  SDL_VIDEO_VULKAN_SURFACE 0
   21.13 +#endif
   21.14 +
   21.15  /* Enable system power support */
   21.16  #define SDL_POWER_MACOSX 1
   21.17  
    22.1 --- a/include/SDL_config_windows.h	Sun Aug 27 19:10:30 2017 -0700
    22.2 +++ b/include/SDL_config_windows.h	Sun Aug 27 22:15:57 2017 -0400
    22.3 @@ -208,6 +208,7 @@
    22.4  #define SDL_VIDEO_OPENGL_EGL    1
    22.5  #endif
    22.6  
    22.7 +#define SDL_VIDEO_VULKAN_SURFACE 1
    22.8  
    22.9  /* Enable system power support */
   22.10  #define SDL_POWER_WINDOWS 1
    23.1 --- a/include/SDL_video.h	Sun Aug 27 19:10:30 2017 -0700
    23.2 +++ b/include/SDL_video.h	Sun Aug 27 22:15:57 2017 -0400
    23.3 @@ -233,7 +233,6 @@
    23.4      SDL_GL_CONTEXT_RESET_LOSE_CONTEXT    = 0x0001
    23.5  } SDL_GLContextResetNotification;
    23.6  
    23.7 -
    23.8  /* Function prototypes */
    23.9  
   23.10  /**
   23.11 @@ -457,17 +456,32 @@
   23.12   *               ::SDL_WINDOW_HIDDEN,        ::SDL_WINDOW_BORDERLESS,
   23.13   *               ::SDL_WINDOW_RESIZABLE,     ::SDL_WINDOW_MAXIMIZED,
   23.14   *               ::SDL_WINDOW_MINIMIZED,     ::SDL_WINDOW_INPUT_GRABBED,
   23.15 - *               ::SDL_WINDOW_ALLOW_HIGHDPI.
   23.16 + *               ::SDL_WINDOW_ALLOW_HIGHDPI, ::SDL_WINDOW_VULKAN.
   23.17   *
   23.18   *  \return The created window, or NULL if window creation failed.
   23.19   *
   23.20   *  If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size
   23.21   *  in pixels may differ from its size in screen coordinates on platforms with
   23.22   *  high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query
   23.23 - *  the client area's size in screen coordinates, and SDL_GL_GetDrawableSize()
   23.24 - *  or SDL_GetRendererOutputSize() to query the drawable size in pixels.
   23.25 + *  the client area's size in screen coordinates, and SDL_GL_GetDrawableSize(),
   23.26 + *  SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to query the
   23.27 + *  drawable size in pixels.
   23.28 + *
   23.29 + *  If the window is created with any of the SDL_WINDOW_OPENGL or
   23.30 + *  SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
   23.31 + *  (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
   23.32 + *  corrensponding UnloadLibrary function is called by SDL_DestroyWindow().
   23.33 + *
   23.34 + *  If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver,
   23.35 + *  SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
   23.36 + *
   23.37 + *  \note On non-Apple devices, SDL requires you to either not link to the
   23.38 + *        Vulkan loader or link to a dynamic library version. This limitation
   23.39 + *        may be removed in a future version of SDL.
   23.40   *
   23.41   *  \sa SDL_DestroyWindow()
   23.42 + *  \sa SDL_GL_LoadLibrary()
   23.43 + *  \sa SDL_Vulkan_LoadLibrary()
   23.44   */
   23.45  extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title,
   23.46                                                        int x, int y, int w,
   23.47 @@ -879,7 +893,7 @@
   23.48   *  \param window The window which will be made transparent or opaque
   23.49   *  \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be
   23.50   *                 clamped internally between 0.0f and 1.0f.
   23.51 - * 
   23.52 + *
   23.53   *  \return 0 on success, or -1 if setting the opacity isn't supported.
   23.54   *
   23.55   *  \sa SDL_GetWindowOpacity()
   23.56 @@ -906,7 +920,7 @@
   23.57   *
   23.58   *  \param modal_window The window that should be modal
   23.59   *  \param parent_window The parent window
   23.60 - * 
   23.61 + *
   23.62   *  \return 0 on success, or -1 otherwise.
   23.63   */
   23.64  extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window);
   23.65 @@ -919,7 +933,7 @@
   23.66   *  obscured by other windows.
   23.67   *
   23.68   *  \param window The window that should get the input focus
   23.69 - * 
   23.70 + *
   23.71   *  \return 0 on success, or -1 otherwise.
   23.72   *  \sa SDL_RaiseWindow()
   23.73   */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/include/SDL_vulkan.h	Sun Aug 27 22:15:57 2017 -0400
    24.3 @@ -0,0 +1,251 @@
    24.4 +/*
    24.5 + Simple DirectMedia Layer
    24.6 + Copyright (C) 2017, Mark Callow.
    24.7 + 
    24.8 + This software is provided 'as-is', without any express or implied
    24.9 + warranty.  In no event will the authors be held liable for any damages
   24.10 + arising from the use of this software.
   24.11 + 
   24.12 + Permission is granted to anyone to use this software for any purpose,
   24.13 + including commercial applications, and to alter it and redistribute it
   24.14 + freely, subject to the following restrictions:
   24.15 + 
   24.16 + 1. The origin of this software must not be misrepresented; you must not
   24.17 + claim that you wrote the original software. If you use this software
   24.18 + in a product, an acknowledgment in the product documentation would be
   24.19 + appreciated but is not required.
   24.20 + 2. Altered source versions must be plainly marked as such, and must not be
   24.21 + misrepresented as being the original software.
   24.22 + 3. This notice may not be removed or altered from any source distribution.
   24.23 + */
   24.24 +
   24.25 +/**
   24.26 + *  \file SDL_vulkan.h
   24.27 + *
   24.28 + *  Header file for functions to creating Vulkan surfaces on SDL windows.
   24.29 + */
   24.30 +
   24.31 +#ifndef SDL_vulkan_h_
   24.32 +#define SDL_vulkan_h_
   24.33 +
   24.34 +#include "SDL_video.h"
   24.35 +
   24.36 +#include "begin_code.h"
   24.37 +/* Set up for C function definitions, even when using C++ */
   24.38 +#ifdef __cplusplus
   24.39 +extern "C" {
   24.40 +#endif
   24.41 +
   24.42 +/* Avoid including vulkan.h */
   24.43 +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
   24.44 +
   24.45 +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
   24.46 +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
   24.47 +#else
   24.48 +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
   24.49 +#endif
   24.50 +
   24.51 +VK_DEFINE_HANDLE(VkInstance)
   24.52 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
   24.53 +
   24.54 +typedef VkInstance SDL_vulkanInstance;
   24.55 +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
   24.56 +
   24.57 +/**
   24.58 + *  \name Vulkan support functions
   24.59 + *
   24.60 + *  \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API
   24.61 + *        is compatable with Tizen's implementation of Vulkan in SDL.
   24.62 + */
   24.63 +/* @{ */
   24.64 +
   24.65 +/**
   24.66 + *  \brief Dynamically load a Vulkan loader library.
   24.67 + *
   24.68 + *  \param [in] path The platform dependent Vulkan loader library name, or
   24.69 + *              \c NULL to open the default Vulkan loader library.
   24.70 + *
   24.71 + *  \return \c 0 on success, or \c -1 if the library couldn't be loaded.
   24.72 + *
   24.73 + *  This should be done after initializing the video driver, but before
   24.74 + *  creating any Vulkan windows. If no Vulkan loader library is loaded, the
   24.75 + *  default library will be loaded upon creation of the first Vulkan window.
   24.76 + *
   24.77 + *  \note If you specify a non-NULL \a path, you should retrieve all of the
   24.78 + *        Vulkan functions used in your program from the dynamic library using
   24.79 + *        \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
   24.80 + *        \a path points to the same vulkan loader library that you linked to.
   24.81 + *
   24.82 + *  \note On Apple devices, if \a path is NULL, SDL will attempt to find
   24.83 + *        the vkGetInstanceProcAddr address within all the mach-o images of
   24.84 + *        the current process. This is because the currently (v0.17.0)
   24.85 + *        recommended MoltenVK (Vulkan on Metal) usage is as a static library.
   24.86 + *        If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
   24.87 + *        Applications using the dylib alternative therefore do not need to do
   24.88 + *        anything special when calling SDL.
   24.89 + *
   24.90 + *  \note On non-Apple devices, SDL requires you to either not link to the
   24.91 + *        Vulkan loader or link to a dynamic library version. This limitation
   24.92 + *        may be removed in a future version of SDL.
   24.93 + *
   24.94 + *  \note This function will fail if there are no working Vulkan drivers
   24.95 + *        installed.
   24.96 + *
   24.97 + *  \sa SDL_Vulkan_GetVkGetInstanceProcAddr()
   24.98 + *  \sa SDL_Vulkan_UnloadLibrary()
   24.99 + */
  24.100 +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path);
  24.101 +
  24.102 +/**
  24.103 + *  \brief Get the address of the \c vkGetInstanceProcAddr function.
  24.104 + *
  24.105 + *  \note This should be called after either calling SDL_Vulkan_LoadLibrary
  24.106 + *        or creating an SDL_Window with the SDL_WINDOW_VULKAN flag.
  24.107 + */
  24.108 +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
  24.109 +
  24.110 +/**
  24.111 + *  \brief Unload the Vulkan loader library previously loaded by
  24.112 + *         \c SDL_Vulkan_LoadLibrary().
  24.113 + *
  24.114 + *  \sa SDL_Vulkan_LoadLibrary()
  24.115 + */
  24.116 +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  24.117 +
  24.118 +/**
  24.119 + *  \brief Get the names of the Vulkan instance extensions needed to create
  24.120 + *         a surface with \c SDL_Vulkan_CreateSurface().
  24.121 + *
  24.122 + *  \param [in]     window Window for which the required Vulkan instance
  24.123 + *                  extensions should be retrieved
  24.124 + *  \param [in,out] count pointer to an \c unsigned related to the number of
  24.125 + *                  required Vulkan instance extensions
  24.126 + *  \param [out]    names \c NULL or a pointer to an array to be filled with the
  24.127 + *                  required Vulkan instance extensions
  24.128 + *
  24.129 + *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
  24.130 + *
  24.131 + *  If \a pNames is \c NULL, then the number of required Vulkan instance
  24.132 + *  extensions is returned in pCount. Otherwise, \a pCount must point to a
  24.133 + *  variable set to the number of elements in the \a pNames array, and on
  24.134 + *  return the variable is overwritten with the number of names actually
  24.135 + *  written to \a pNames. If \a pCount is less than the number of required
  24.136 + *  extensions, at most \a pCount structures will be written. If \a pCount
  24.137 + *  is smaller than the number of required extensions, \c SDL_FALSE will be
  24.138 + *  returned instead of \c SDL_TRUE, to indicate that not all the required
  24.139 + *  extensions were returned.
  24.140 + *
  24.141 + *  \note The returned list of extensions will contain \c VK_KHR_surface
  24.142 + *        and zero or more platform specific extensions
  24.143 + *
  24.144 + *  \note The extension names queried here must be enabled when calling
  24.145 + *        VkCreateInstance, otherwise surface creation will fail.
  24.146 + *
  24.147 + *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
  24.148 + *
  24.149 + *  \code
  24.150 + *  unsigned count;
  24.151 + *  // get count of required extensions
  24.152 + *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
  24.153 + *      handle_error();
  24.154 + *
  24.155 + *  static const char *const additionalExtensions[] =
  24.156 + *  {
  24.157 + *      VK_EXT_DEBUG_REPORT_EXTENSION_NAME, // example additional extension
  24.158 + *  };
  24.159 + *  size_t additionalExtensionsCount = sizeof(additionalExtensions) / sizeof(additionalExtensions[0]);
  24.160 + *  size_t extensionCount = count + additionalExtensionsCount;
  24.161 + *  const char **names = malloc(sizeof(const char *) * extensionCount);
  24.162 + *  if(!names)
  24.163 + *      handle_error();
  24.164 + *
  24.165 + *  // get names of required extensions
  24.166 + *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
  24.167 + *      handle_error();
  24.168 + *
  24.169 + *  // copy additional extensions after required extensions
  24.170 + *  for(size_t i = 0; i < additionalExtensionsCount; i++)
  24.171 + *      names[i + count] = additionalExtensions[i];
  24.172 + *
  24.173 + *  VkInstanceCreateInfo instanceCreateInfo = {};
  24.174 + *  instanceCreateInfo.enabledExtensionCount = extensionCount;
  24.175 + *  instanceCreateInfo.ppEnabledExtensionNames = names;
  24.176 + *  // fill in rest of instanceCreateInfo
  24.177 + *
  24.178 + *  VkInstance instance;
  24.179 + *  // create the Vulkan instance
  24.180 + *  VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &instance);
  24.181 + *  free(names);
  24.182 + *  \endcode
  24.183 + *
  24.184 + *  \sa SDL_Vulkan_CreateSurface()
  24.185 + */
  24.186 +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(
  24.187 +														SDL_Window *window,
  24.188 +														unsigned *pCount,
  24.189 +														const char **pNames);
  24.190 +
  24.191 +/**
  24.192 + *  \brief Create a Vulkan rendering surface for a window.
  24.193 + *
  24.194 + *  \param [in]  window   SDL_Window to which to attach the rendering surface.
  24.195 + *  \param [in]  instance handle to the Vulkan instance to use.
  24.196 + *  \param [out] surface  pointer to a VkSurfaceKHR handle to receive the
  24.197 + *                        handle of the newly created surface.
  24.198 + *
  24.199 + *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
  24.200 + *
  24.201 + *  \code
  24.202 + *  VkInstance instance;
  24.203 + *  SDL_Window *window;
  24.204 + *
  24.205 + *  // create instance and window
  24.206 + *
  24.207 + *  // create the Vulkan surface
  24.208 + *  VkSurfaceKHR surface;
  24.209 + *  if(!SDL_Vulkan_CreateSurface(window, instance, &surface))
  24.210 + *      handle_error();
  24.211 + *  \endcode
  24.212 + *
  24.213 + *  \note \a window should have been created with the \c SDL_WINDOW_VULKAN flag.
  24.214 + *
  24.215 + *  \note \a instance should have been created with the extensions returned
  24.216 + *        by \c SDL_Vulkan_CreateSurface() enabled.
  24.217 + *
  24.218 + *  \sa SDL_Vulkan_GetInstanceExtensions()
  24.219 + */
  24.220 +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(
  24.221 +												SDL_Window *window,
  24.222 +												VkInstance instance,
  24.223 +												VkSurfaceKHR* surface);
  24.224 +
  24.225 +/**
  24.226 + *  \brief Get the size of a window's underlying drawable in pixels (for use
  24.227 + *         with setting viewport, scissor & etc).
  24.228 + *
  24.229 + *  \param window   SDL_Window from which the drawable size should be queried
  24.230 + *  \param w        Pointer to variable for storing the width in pixels,
  24.231 + *                  may be NULL
  24.232 + *  \param h        Pointer to variable for storing the height in pixels,
  24.233 + *                  may be NULL
  24.234 + *
  24.235 + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI
  24.236 + * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a
  24.237 + * platform with high-DPI support (Apple calls this "Retina"), and not disabled
  24.238 + * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
  24.239 + *
  24.240 + *  \sa SDL_GetWindowSize()
  24.241 + *  \sa SDL_CreateWindow()
  24.242 + */
  24.243 +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window,
  24.244 +                                                        int *w, int *h);
  24.245 +
  24.246 +/* @} *//* Vulkan support functions */
  24.247 +
  24.248 +/* Ends C function definitions when using C++ */
  24.249 +#ifdef __cplusplus
  24.250 +}
  24.251 +#endif
  24.252 +#include "close_code.h"
  24.253 +
  24.254 +#endif /* SDL_vulkan_h_ */
    25.1 --- a/src/test/SDL_test_common.c	Sun Aug 27 19:10:30 2017 -0700
    25.2 +++ b/src/test/SDL_test_common.c	Sun Aug 27 22:15:57 2017 -0400
    25.3 @@ -886,7 +886,7 @@
    25.4  
    25.5              if (!state->skip_renderer
    25.6                  && (state->renderdriver
    25.7 -                    || !(state->window_flags & SDL_WINDOW_OPENGL))) {
    25.8 +                    || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN)))) {
    25.9                  m = -1;
   25.10                  if (state->renderdriver) {
   25.11                      SDL_RendererInfo info;
    26.1 --- a/src/video/SDL_sysvideo.h	Sun Aug 27 19:10:30 2017 -0700
    26.2 +++ b/src/video/SDL_sysvideo.h	Sun Aug 27 22:15:57 2017 -0400
    26.3 @@ -26,6 +26,7 @@
    26.4  #include "SDL_messagebox.h"
    26.5  #include "SDL_shape.h"
    26.6  #include "SDL_thread.h"
    26.7 +#include "SDL_vulkan.h"
    26.8  
    26.9  /* The SDL video driver */
   26.10  
   26.11 @@ -262,6 +263,16 @@
   26.12  
   26.13      /* * * */
   26.14      /*
   26.15 +     * Vulkan support
   26.16 +     */
   26.17 +    int (*Vulkan_LoadLibrary) (_THIS, const char *path);
   26.18 +    void (*Vulkan_UnloadLibrary) (_THIS);
   26.19 +    SDL_bool (*Vulkan_GetInstanceExtensions) (_THIS, SDL_Window *window, unsigned *count, const char **names);
   26.20 +    SDL_bool (*Vulkan_CreateSurface) (_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface);
   26.21 +    void (*Vulkan_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h);
   26.22 +
   26.23 +    /* * * */
   26.24 +    /*
   26.25       * Event manager functions
   26.26       */
   26.27      void (*PumpEvents) (_THIS);
   26.28 @@ -349,6 +360,17 @@
   26.29      SDL_TLSID current_glctx_tls;
   26.30  
   26.31      /* * * */
   26.32 +    /* Data used by the Vulkan drivers */
   26.33 +    struct
   26.34 +    {
   26.35 +        void *vkGetInstanceProcAddr;
   26.36 +        void *vkEnumerateInstanceExtensionProperties;
   26.37 +        int loader_loaded;
   26.38 +        char loader_path[256];
   26.39 +        void *loader_handle;
   26.40 +    } vulkan_config;
   26.41 +
   26.42 +    /* * * */
   26.43      /* Data private to this driver */
   26.44      void *driverdata;
   26.45      struct SDL_GLDriverData *gl_data;
    27.1 --- a/src/video/SDL_video.c	Sun Aug 27 19:10:30 2017 -0700
    27.2 +++ b/src/video/SDL_video.c	Sun Aug 27 22:15:57 2017 -0400
    27.3 @@ -1329,7 +1329,7 @@
    27.4  }
    27.5  
    27.6  #define CREATE_FLAGS \
    27.7 -    (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN )
    27.8 +    (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN)
    27.9  
   27.10  static void
   27.11  SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
   27.12 @@ -1384,7 +1384,7 @@
   27.13  
   27.14      /* Some platforms have OpenGL enabled by default */
   27.15  #if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
   27.16 -    if (!_this->is_dummy) {
   27.17 +    if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) {
   27.18          flags |= SDL_WINDOW_OPENGL;
   27.19      }
   27.20  #endif
   27.21 @@ -1398,6 +1398,25 @@
   27.22          }
   27.23      }
   27.24  
   27.25 +    if(flags & SDL_WINDOW_VULKAN)
   27.26 +    {
   27.27 +        if(!_this->Vulkan_CreateSurface)
   27.28 +        {
   27.29 +            SDL_SetError("Vulkan support is either not configured in SDL "
   27.30 +            		     "or not available in video driver");
   27.31 +            return NULL;
   27.32 +        }
   27.33 +        if(flags & SDL_WINDOW_OPENGL)
   27.34 +        {
   27.35 +            SDL_SetError("Vulkan and OpenGL not supported on same window");
   27.36 +            return NULL;
   27.37 +        }
   27.38 +        if(SDL_Vulkan_LoadLibrary(NULL) < 0)
   27.39 +        {
   27.40 +            return NULL;
   27.41 +        }
   27.42 +    }
   27.43 +
   27.44      /* Unless the user has specified the high-DPI disabling hint, respect the
   27.45       * SDL_WINDOW_ALLOW_HIGHDPI flag.
   27.46       */
   27.47 @@ -1573,6 +1592,16 @@
   27.48          }
   27.49      }
   27.50  
   27.51 +    if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) {
   27.52 +        SDL_SetError("Can't change SDL_WINDOW_VULKAN window flag");
   27.53 +        return -1;
   27.54 +    }
   27.55 +
   27.56 +    if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
   27.57 +        SDL_SetError("Vulkan and OpenGL not supported on same window");
   27.58 +        return -1;
   27.59 +    }
   27.60 +
   27.61      window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
   27.62      window->last_fullscreen_flags = window->flags;
   27.63      window->is_destroying = SDL_FALSE;
   27.64 @@ -2632,6 +2661,9 @@
   27.65      if (window->flags & SDL_WINDOW_OPENGL) {
   27.66          SDL_GL_UnloadLibrary();
   27.67      }
   27.68 +    if (window->flags & SDL_WINDOW_VULKAN) {
   27.69 +        SDL_Vulkan_UnloadLibrary();
   27.70 +    }
   27.71  
   27.72      display = SDL_GetDisplayForWindow(window);
   27.73      if (display->fullscreen_window == window) {
   27.74 @@ -3946,4 +3978,128 @@
   27.75      }
   27.76  }
   27.77  
   27.78 +#define NOT_A_VULKAN_WINDOW "The specified window isn't a Vulkan window."
   27.79 +
   27.80 +int SDL_Vulkan_LoadLibrary(const char *path)
   27.81 +{
   27.82 +    int retval;
   27.83 +    if(!_this)
   27.84 +    {
   27.85 +        SDL_UninitializedVideo();
   27.86 +        return -1;
   27.87 +    }
   27.88 +    if(_this->vulkan_config.loader_loaded)
   27.89 +    {
   27.90 +        if(path && SDL_strcmp(path, _this->vulkan_config.loader_path) != 0)
   27.91 +        {
   27.92 +            return SDL_SetError("Vulkan loader library already loaded");
   27.93 +        }
   27.94 +        retval = 0;
   27.95 +    }
   27.96 +    else
   27.97 +    {
   27.98 +        if(!_this->Vulkan_LoadLibrary)
   27.99 +        {
  27.100 +            return SDL_SetError("No Vulkan support in video driver");
  27.101 +        }
  27.102 +        retval = _this->Vulkan_LoadLibrary(_this, path);
  27.103 +    }
  27.104 +    if(retval == 0)
  27.105 +    {
  27.106 +        _this->vulkan_config.loader_loaded++;
  27.107 +    }
  27.108 +    return retval;
  27.109 +}
  27.110 +
  27.111 +void *SDL_Vulkan_GetVkGetInstanceProcAddr(void)
  27.112 +{
  27.113 +    if(!_this)
  27.114 +    {
  27.115 +        SDL_UninitializedVideo();
  27.116 +        return NULL;
  27.117 +    }
  27.118 +    if(!_this->vulkan_config.loader_loaded)
  27.119 +    {
  27.120 +        SDL_SetError("No Vulkan loader has been loaded");
  27.121 +    }
  27.122 +    return _this->vulkan_config.vkGetInstanceProcAddr;
  27.123 +}
  27.124 +
  27.125 +void SDL_Vulkan_UnloadLibrary(void)
  27.126 +{
  27.127 +    if(!_this)
  27.128 +    {
  27.129 +        SDL_UninitializedVideo();
  27.130 +        return;
  27.131 +    }
  27.132 +    if(_this->vulkan_config.loader_loaded > 0)
  27.133 +    {
  27.134 +        if(--_this->vulkan_config.loader_loaded > 0)
  27.135 +        {
  27.136 +            return;
  27.137 +        }
  27.138 +        if(_this->Vulkan_UnloadLibrary)
  27.139 +        {
  27.140 +            _this->Vulkan_UnloadLibrary(_this);
  27.141 +        }
  27.142 +    }
  27.143 +}
  27.144 +
  27.145 +SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, const char **names)
  27.146 +{
  27.147 +    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
  27.148 +
  27.149 +    if(!(window->flags & SDL_WINDOW_VULKAN))
  27.150 +    {
  27.151 +        SDL_SetError(NOT_A_VULKAN_WINDOW);
  27.152 +        return SDL_FALSE;
  27.153 +    }
  27.154 +
  27.155 +    if(!count)
  27.156 +    {
  27.157 +        SDL_SetError("invalid count");
  27.158 +        return SDL_FALSE;
  27.159 +    }
  27.160 +
  27.161 +    return _this->Vulkan_GetInstanceExtensions(_this, window, count, names);
  27.162 +}
  27.163 +
  27.164 +SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
  27.165 +                                  VkInstance instance,
  27.166 +                                  VkSurfaceKHR *surface)
  27.167 +{
  27.168 +    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
  27.169 +
  27.170 +    if(!(window->flags & SDL_WINDOW_VULKAN))
  27.171 +    {
  27.172 +        SDL_SetError(NOT_A_VULKAN_WINDOW);
  27.173 +        return SDL_FALSE;
  27.174 +    }
  27.175 +
  27.176 +    if(!instance)
  27.177 +    {
  27.178 +        SDL_SetError("invalid instance");
  27.179 +        return SDL_FALSE;
  27.180 +    }
  27.181 +
  27.182 +    if(!surface)
  27.183 +    {
  27.184 +        SDL_SetError("invalid surface");
  27.185 +        return SDL_FALSE;
  27.186 +    }
  27.187 +
  27.188 +    return _this->Vulkan_CreateSurface(_this, window, instance, surface);
  27.189 +}
  27.190 +
  27.191 +void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h)
  27.192 +{
  27.193 +    CHECK_WINDOW_MAGIC(window,);
  27.194 +
  27.195 +    if (_this->Vulkan_GetDrawableSize) {
  27.196 +        _this->Vulkan_GetDrawableSize(_this, window, w, h);
  27.197 +    } else {
  27.198 +        SDL_GetWindowSize(window, w, h);
  27.199 +    }
  27.200 +}
  27.201 +
  27.202  /* vi: set ts=4 sw=4 expandtab: */
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/video/SDL_vulkan_internal.h	Sun Aug 27 22:15:57 2017 -0400
    28.3 @@ -0,0 +1,80 @@
    28.4 +/*
    28.5 +  Simple DirectMedia Layer
    28.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    28.7 +
    28.8 +  This software is provided 'as-is', without any express or implied
    28.9 +  warranty.  In no event will the authors be held liable for any damages
   28.10 +  arising from the use of this software.
   28.11 +
   28.12 +  Permission is granted to anyone to use this software for any purpose,
   28.13 +  including commercial applications, and to alter it and redistribute it
   28.14 +  freely, subject to the following restrictions:
   28.15 +
   28.16 +  1. The origin of this software must not be misrepresented; you must not
   28.17 +     claim that you wrote the original software. If you use this software
   28.18 +     in a product, an acknowledgment in the product documentation would be
   28.19 +     appreciated but is not required.
   28.20 +  2. Altered source versions must be plainly marked as such, and must not be
   28.21 +     misrepresented as being the original software.
   28.22 +  3. This notice may not be removed or altered from any source distribution.
   28.23 +*/
   28.24 +#ifndef _SDL_vulkan_internal_h
   28.25 +#define _SDL_vulkan_internal_h
   28.26 +
   28.27 +#include "../SDL_internal.h"
   28.28 +
   28.29 +#include "SDL_stdinc.h"
   28.30 +
   28.31 +#if defined(SDL_LOADSO_DISABLED)
   28.32 +#undef SDL_VIDEO_VULKAN_SURFACE
   28.33 +#define SDL_VIDEO_VULKAN_SURFACE 0
   28.34 +#endif
   28.35 +
   28.36 +#if SDL_VIDEO_DRIVER_ANDROID
   28.37 +#define VK_USE_PLATFORM_ANDROID_KHR
   28.38 +#endif
   28.39 +#if SDL_VIDEO_DRIVER_COCOA
   28.40 +#define VK_USE_PLATFORM_MACOS_MVK
   28.41 +#endif
   28.42 +#if SDL_VIDEO_DRIVER_MIR
   28.43 +#define VK_USE_PLATFORM_MIR_KHR
   28.44 +#endif
   28.45 +#if SDL_VIDEO_DRIVER_UIKIT
   28.46 +#define VK_USE_PLATFORM_IOS_MVK
   28.47 +#endif
   28.48 +#if SDL_VIDEO_DRIVER_WAYLAND
   28.49 +#define VK_USE_PLATFORM_WAYLAND_KHR
   28.50 +#endif
   28.51 +#if SDL_VIDEO_DRIVER_WINDOWS
   28.52 +#define VK_USE_PLATFORM_WIN32_KHR
   28.53 +#endif
   28.54 +#if SDL_VIDEO_DRIVER_X11
   28.55 +#define VK_USE_PLATFORM_XLIB_KHR
   28.56 +#define VK_USE_PLATFORM_XCB_KHR
   28.57 +#endif
   28.58 +
   28.59 +#if SDL_VIDEO_VULKAN_SURFACE
   28.60 +
   28.61 +/* Need vulkan.h for the following declarations. Must ensure the first
   28.62 + * inclusion of vulkan has the appropriate USE_PLATFORM defined, hence
   28.63 + * the above. */
   28.64 +#define VK_NO_PROTOTYPES
   28.65 +#include "vulkan/vulkan.h"
   28.66 +
   28.67 +extern const char *SDL_Vulkan_GetResultString(VkResult result);
   28.68 +
   28.69 +extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
   28.70 +    PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
   28.71 +    Uint32 *extensionCount); /* free returned list with SDL_free */
   28.72 +
   28.73 +/* Implements functionality of SDL_Vulkan_GetInstanceExtensions for a list of
   28.74 + * names passed in nameCount and names. */
   28.75 +extern SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
   28.76 +                                                        const char **userNames,
   28.77 +                                                        unsigned nameCount,
   28.78 +                                                        const char *const *names);
   28.79 +
   28.80 +#endif
   28.81 +
   28.82 +#endif
   28.83 +/* vi: set ts=4 sw=4 expandtab: */
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/video/SDL_vulkan_utils.c	Sun Aug 27 22:15:57 2017 -0400
    29.3 @@ -0,0 +1,191 @@
    29.4 +/*
    29.5 +  Simple DirectMedia Layer
    29.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    29.7 +
    29.8 +  This software is provided 'as-is', without any express or implied
    29.9 +  warranty.  In no event will the authors be held liable for any damages
   29.10 +  arising from the use of this software.
   29.11 +
   29.12 +  Permission is granted to anyone to use this software for any purpose,
   29.13 +  including commercial applications, and to alter it and redistribute it
   29.14 +  freely, subject to the following restrictions:
   29.15 +
   29.16 +  1. The origin of this software must not be misrepresented; you must not
   29.17 +     claim that you wrote the original software. If you use this software
   29.18 +     in a product, an acknowledgment in the product documentation would be
   29.19 +     appreciated but is not required.
   29.20 +  2. Altered source versions must be plainly marked as such, and must not be
   29.21 +     misrepresented as being the original software.
   29.22 +  3. This notice may not be removed or altered from any source distribution.
   29.23 +*/
   29.24 +#include "../SDL_internal.h"
   29.25 +
   29.26 +#include "SDL_vulkan_internal.h"
   29.27 +#include "SDL_error.h"
   29.28 +
   29.29 +#if SDL_VIDEO_VULKAN_SURFACE
   29.30 +
   29.31 +/* Based on the headers found in
   29.32 + * https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers
   29.33 + */
   29.34 +#if VK_HEADER_VERSION < 22
   29.35 +enum
   29.36 +{
   29.37 +    VK_ERROR_FRAGMENTED_POOL = -12,
   29.38 +};
   29.39 +#endif
   29.40 +#if VK_HEADER_VERSION < 38
   29.41 +enum {
   29.42 +    VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
   29.43 +};
   29.44 +#endif
   29.45 +
   29.46 +const char *SDL_Vulkan_GetResultString(VkResult result)
   29.47 +{
   29.48 +    switch((int)result)
   29.49 +    {
   29.50 +    case VK_SUCCESS:
   29.51 +        return "VK_SUCCESS";
   29.52 +    case VK_NOT_READY:
   29.53 +        return "VK_NOT_READY";
   29.54 +    case VK_TIMEOUT:
   29.55 +        return "VK_TIMEOUT";
   29.56 +    case VK_EVENT_SET:
   29.57 +        return "VK_EVENT_SET";
   29.58 +    case VK_EVENT_RESET:
   29.59 +        return "VK_EVENT_RESET";
   29.60 +    case VK_INCOMPLETE:
   29.61 +        return "VK_INCOMPLETE";
   29.62 +    case VK_ERROR_OUT_OF_HOST_MEMORY:
   29.63 +        return "VK_ERROR_OUT_OF_HOST_MEMORY";
   29.64 +    case VK_ERROR_OUT_OF_DEVICE_MEMORY:
   29.65 +        return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
   29.66 +    case VK_ERROR_INITIALIZATION_FAILED:
   29.67 +        return "VK_ERROR_INITIALIZATION_FAILED";
   29.68 +    case VK_ERROR_DEVICE_LOST:
   29.69 +        return "VK_ERROR_DEVICE_LOST";
   29.70 +    case VK_ERROR_MEMORY_MAP_FAILED:
   29.71 +        return "VK_ERROR_MEMORY_MAP_FAILED";
   29.72 +    case VK_ERROR_LAYER_NOT_PRESENT:
   29.73 +        return "VK_ERROR_LAYER_NOT_PRESENT";
   29.74 +    case VK_ERROR_EXTENSION_NOT_PRESENT:
   29.75 +        return "VK_ERROR_EXTENSION_NOT_PRESENT";
   29.76 +    case VK_ERROR_FEATURE_NOT_PRESENT:
   29.77 +        return "VK_ERROR_FEATURE_NOT_PRESENT";
   29.78 +    case VK_ERROR_INCOMPATIBLE_DRIVER:
   29.79 +        return "VK_ERROR_INCOMPATIBLE_DRIVER";
   29.80 +    case VK_ERROR_TOO_MANY_OBJECTS:
   29.81 +        return "VK_ERROR_TOO_MANY_OBJECTS";
   29.82 +    case VK_ERROR_FORMAT_NOT_SUPPORTED:
   29.83 +        return "VK_ERROR_FORMAT_NOT_SUPPORTED";
   29.84 +    case VK_ERROR_FRAGMENTED_POOL:
   29.85 +        return "VK_ERROR_FRAGMENTED_POOL";
   29.86 +    case VK_ERROR_SURFACE_LOST_KHR:
   29.87 +        return "VK_ERROR_SURFACE_LOST_KHR";
   29.88 +    case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
   29.89 +        return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
   29.90 +    case VK_SUBOPTIMAL_KHR:
   29.91 +        return "VK_SUBOPTIMAL_KHR";
   29.92 +    case VK_ERROR_OUT_OF_DATE_KHR:
   29.93 +        return "VK_ERROR_OUT_OF_DATE_KHR";
   29.94 +    case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
   29.95 +        return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
   29.96 +    case VK_ERROR_VALIDATION_FAILED_EXT:
   29.97 +        return "VK_ERROR_VALIDATION_FAILED_EXT";
   29.98 +    case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
   29.99 +        return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
  29.100 +    case VK_ERROR_INVALID_SHADER_NV:
  29.101 +        return "VK_ERROR_INVALID_SHADER_NV";
  29.102 +    case VK_RESULT_MAX_ENUM:
  29.103 +    case VK_RESULT_RANGE_SIZE:
  29.104 +        break;
  29.105 +    }
  29.106 +    if(result < 0)
  29.107 +        return "VK_ERROR_<Unknown>";
  29.108 +    return "VK_<Unknown>";
  29.109 +}
  29.110 +
  29.111 +VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
  29.112 +    PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties,
  29.113 +    Uint32 *extensionCount)
  29.114 +{
  29.115 +    Uint32 count = 0;
  29.116 +    VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
  29.117 +    VkExtensionProperties *retval;
  29.118 +    if(result == VK_ERROR_INCOMPATIBLE_DRIVER)
  29.119 +    {
  29.120 +        SDL_SetError(
  29.121 +            "You probably don't have a working Vulkan driver installed: getting Vulkan "
  29.122 +            "extensions failed: vkEnumerateInstanceExtensionProperties returned %s(%d)",
  29.123 +            SDL_Vulkan_GetResultString(result),
  29.124 +            (int)result);
  29.125 +        return NULL;
  29.126 +    }
  29.127 +    else if(result != VK_SUCCESS)
  29.128 +    {
  29.129 +        SDL_SetError(
  29.130 +            "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
  29.131 +            "%s(%d)",
  29.132 +            SDL_Vulkan_GetResultString(result),
  29.133 +            (int)result);
  29.134 +        return NULL;
  29.135 +    }
  29.136 +    if(count == 0)
  29.137 +    {
  29.138 +        retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null
  29.139 +        if(!retval)
  29.140 +        {
  29.141 +            SDL_OutOfMemory();
  29.142 +            return NULL;
  29.143 +        }
  29.144 +        *extensionCount = 0;
  29.145 +    }
  29.146 +    retval = SDL_calloc(count, sizeof(VkExtensionProperties));
  29.147 +    if(!retval)
  29.148 +    {
  29.149 +        SDL_OutOfMemory();
  29.150 +        return NULL;
  29.151 +    }
  29.152 +    result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval);
  29.153 +    if(result != VK_SUCCESS)
  29.154 +    {
  29.155 +        SDL_SetError(
  29.156 +            "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
  29.157 +            "%s(%d)",
  29.158 +            SDL_Vulkan_GetResultString(result),
  29.159 +            (int)result);
  29.160 +        SDL_free(retval);
  29.161 +        return NULL;
  29.162 +    }
  29.163 +    *extensionCount = count;
  29.164 +    return retval;
  29.165 +}
  29.166 +
  29.167 +SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
  29.168 +                                                 const char **userNames,
  29.169 +                                                 unsigned nameCount,
  29.170 +                                                 const char *const *names)
  29.171 +{
  29.172 +    if(userNames)
  29.173 +    {
  29.174 +		unsigned int i;
  29.175 +
  29.176 +        if(*userCount != nameCount)
  29.177 +        {
  29.178 +            SDL_SetError(
  29.179 +                "Count doesn't match count from previous call of SDL_Vulkan_GetInstanceExtensions");
  29.180 +            return SDL_FALSE;
  29.181 +        }
  29.182 +        for(i = 0; i < nameCount; i++)
  29.183 +        {
  29.184 +            userNames[i] = names[i];
  29.185 +        }
  29.186 +    }
  29.187 +    else
  29.188 +    {
  29.189 +        *userCount = nameCount;
  29.190 +    }
  29.191 +    return SDL_TRUE;
  29.192 +}
  29.193 +
  29.194 +#endif
    30.1 --- a/src/video/android/SDL_androidvideo.c	Sun Aug 27 19:10:30 2017 -0700
    30.2 +++ b/src/video/android/SDL_androidvideo.c	Sun Aug 27 22:15:57 2017 -0400
    30.3 @@ -40,6 +40,7 @@
    30.4  #include "SDL_androidmouse.h"
    30.5  #include "SDL_androidtouch.h"
    30.6  #include "SDL_androidwindow.h"
    30.7 +#include "SDL_androidvulkan.h"
    30.8  
    30.9  #define ANDROID_VID_DRIVER_NAME "Android"
   30.10  
   30.11 @@ -132,6 +133,13 @@
   30.12      device->GL_SwapWindow = Android_GLES_SwapWindow;
   30.13      device->GL_DeleteContext = Android_GLES_DeleteContext;
   30.14  
   30.15 +#if SDL_VIDEO_VULKAN_SURFACE
   30.16 +    device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
   30.17 +    device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary;
   30.18 +    device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions;
   30.19 +    device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface;
   30.20 +#endif
   30.21 +
   30.22      /* Screensaver */
   30.23      device->SuspendScreenSaver = Android_SuspendScreenSaver;
   30.24  
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/video/android/SDL_androidvulkan.c	Sun Aug 27 22:15:57 2017 -0400
    31.3 @@ -0,0 +1,174 @@
    31.4 +/*
    31.5 +  Simple DirectMedia Layer
    31.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    31.7 +
    31.8 +  This software is provided 'as-is', without any express or implied
    31.9 +  warranty.  In no event will the authors be held liable for any damages
   31.10 +  arising from the use of this software.
   31.11 +
   31.12 +  Permission is granted to anyone to use this software for any purpose,
   31.13 +  including commercial applications, and to alter it and redistribute it
   31.14 +  freely, subject to the following restrictions:
   31.15 +
   31.16 +  1. The origin of this software must not be misrepresented; you must not
   31.17 +     claim that you wrote the original software. If you use this software
   31.18 +     in a product, an acknowledgment in the product documentation would be
   31.19 +     appreciated but is not required.
   31.20 +  2. Altered source versions must be plainly marked as such, and must not be
   31.21 +     misrepresented as being the original software.
   31.22 +  3. This notice may not be removed or altered from any source distribution.
   31.23 +*/
   31.24 +
   31.25 +/*
   31.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   31.27 + * SDL_x11vulkan.c.
   31.28 + */
   31.29 +
   31.30 +#include "../../SDL_internal.h"
   31.31 +
   31.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_ANDROID
   31.33 +
   31.34 +#include "SDL_androidvideo.h"
   31.35 +#include "SDL_androidwindow.h"
   31.36 +#include "SDL_assert.h"
   31.37 +
   31.38 +#include "SDL_loadso.h"
   31.39 +#include "SDL_androidvulkan.h"
   31.40 +#include "SDL_syswm.h"
   31.41 +
   31.42 +int Android_Vulkan_LoadLibrary(_THIS, const char *path)
   31.43 +{
   31.44 +    VkExtensionProperties *extensions = NULL;
   31.45 +    Uint32 extensionCount = 0;
   31.46 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   31.47 +    SDL_bool hasAndroidSurfaceExtension = SDL_FALSE;
   31.48 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   31.49 +    if(_this->vulkan_config.loader_handle)
   31.50 +        return SDL_SetError("Vulkan already loaded");
   31.51 +
   31.52 +    /* Load the Vulkan loader library */
   31.53 +    if(!path)
   31.54 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   31.55 +    if(!path)
   31.56 +        path = "libvulkan.so.1";
   31.57 +    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   31.58 +    if(!_this->vulkan_config.loader_handle)
   31.59 +        return -1;
   31.60 +    SDL_strlcpy(_this->vulkan_config.loader_path, path,
   31.61 +                SDL_arraysize(_this->vulkan_config.loader_path));
   31.62 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   31.63 +        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   31.64 +    if(!vkGetInstanceProcAddr)
   31.65 +        goto fail;
   31.66 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
   31.67 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
   31.68 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
   31.69 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
   31.70 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
   31.71 +        goto fail;
   31.72 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
   31.73 +        (PFN_vkEnumerateInstanceExtensionProperties)
   31.74 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
   31.75 +        &extensionCount);
   31.76 +    if(!extensions)
   31.77 +        goto fail;
   31.78 +    for(Uint32 i = 0; i < extensionCount; i++)
   31.79 +    {
   31.80 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   31.81 +            hasSurfaceExtension = SDL_TRUE;
   31.82 +        else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   31.83 +            hasAndroidSurfaceExtension = SDL_TRUE;
   31.84 +    }
   31.85 +    SDL_free(extensions);
   31.86 +    if(!hasSurfaceExtension)
   31.87 +    {
   31.88 +        SDL_SetError("Installed Vulkan doesn't implement the "
   31.89 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
   31.90 +        goto fail;
   31.91 +    }
   31.92 +    else if(!hasAndroidSurfaceExtension)
   31.93 +    {
   31.94 +        SDL_SetError("Installed Vulkan doesn't implement the "
   31.95 +                     VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
   31.96 +        goto fail;
   31.97 +    }
   31.98 +    return 0;
   31.99 +
  31.100 +fail:
  31.101 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  31.102 +    _this->vulkan_config.loader_handle = NULL;
  31.103 +    return -1;
  31.104 +}
  31.105 +
  31.106 +void Android_Vulkan_UnloadLibrary(_THIS)
  31.107 +{
  31.108 +    if(_this->vulkan_config.loader_handle)
  31.109 +    {
  31.110 +        SDL_UnloadObject(_this->vulkan_config.loader_handle);
  31.111 +        _this->vulkan_config.loader_handle = NULL;
  31.112 +    }
  31.113 +}
  31.114 +
  31.115 +SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
  31.116 +                                          SDL_Window *window,
  31.117 +                                          unsigned *count,
  31.118 +                                          const char **names)
  31.119 +{
  31.120 +    static const char *const extensionsForAndroid[] = {
  31.121 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
  31.122 +    };
  31.123 +    if(!_this->vulkan_config.loader_handle)
  31.124 +    {
  31.125 +        SDL_SetError("Vulkan is not loaded");
  31.126 +        return SDL_FALSE;
  31.127 +    }
  31.128 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  31.129 +            count, names, SDL_arraysize(extensionsForMir),
  31.130 +            extensionsForAndroid);
  31.131 +}
  31.132 +
  31.133 +SDL_bool Android_Vulkan_CreateSurface(_THIS,
  31.134 +                                  SDL_Window *window,
  31.135 +                                  VkInstance instance,
  31.136 +                                  VkSurfaceKHR *surface)
  31.137 +{
  31.138 +    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
  31.139 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  31.140 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  31.141 +    PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
  31.142 +        (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
  31.143 +                                            (VkInstance)instance,
  31.144 +                                            "vkCreateAndroidSurfaceKHR");
  31.145 +    VkAndroidSurfaceCreateInfoKHR createInfo = {};
  31.146 +    VkResult result;
  31.147 +
  31.148 +    if(!_this->vulkan_config.loader_handle)
  31.149 +    {
  31.150 +        SDL_SetError("Vulkan is not loaded");
  31.151 +        return SDL_FALSE;
  31.152 +    }
  31.153 +
  31.154 +    if(!vkCreateAndroidSurfaceKHR)
  31.155 +    {
  31.156 +        SDL_SetError(VK_KHR_Android_SURFACE_EXTENSION_NAME
  31.157 +                     " extension is not enabled in the Vulkan instance.");
  31.158 +        return SDL_FALSE;
  31.159 +    }
  31.160 +    createInfo.sType = VK_STRUCTURE_TYPE_Android_SURFACE_CREATE_INFO_KHR;
  31.161 +    createInfo.pNext = NULL;
  31.162 +    createInfo.flags = 0;
  31.163 +    createInfo.window = windowData->native_window;
  31.164 +    result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
  31.165 +                                       NULL, surface);
  31.166 +    if(result != VK_SUCCESS)
  31.167 +    {
  31.168 +        SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
  31.169 +                     SDL_Vulkan_GetResultString(result));
  31.170 +        return SDL_FALSE;
  31.171 +    }
  31.172 +    return SDL_TRUE;
  31.173 +}
  31.174 +
  31.175 +#endif
  31.176 +
  31.177 +/* vi: set ts=4 sw=4 expandtab: */
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/src/video/android/SDL_androidvulkan.h	Sun Aug 27 22:15:57 2017 -0400
    32.3 @@ -0,0 +1,52 @@
    32.4 +/*
    32.5 +  Simple DirectMedia Layer
    32.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    32.7 +
    32.8 +  This software is provided 'as-is', without any express or implied
    32.9 +  warranty.  In no event will the authors be held liable for any damages
   32.10 +  arising from the use of this software.
   32.11 +
   32.12 +  Permission is granted to anyone to use this software for any purpose,
   32.13 +  including commercial applications, and to alter it and redistribute it
   32.14 +  freely, subject to the following restrictions:
   32.15 +
   32.16 +  1. The origin of this software must not be misrepresented; you must not
   32.17 +     claim that you wrote the original software. If you use this software
   32.18 +     in a product, an acknowledgment in the product documentation would be
   32.19 +     appreciated but is not required.
   32.20 +  2. Altered source versions must be plainly marked as such, and must not be
   32.21 +     misrepresented as being the original software.
   32.22 +  3. This notice may not be removed or altered from any source distribution.
   32.23 +*/
   32.24 +
   32.25 +/*
   32.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   32.27 + * SDL_x11vulkan.h.
   32.28 + */
   32.29 +
   32.30 +#include "../../SDL_internal.h"
   32.31 +
   32.32 +#ifndef _SDL_androidvulkan_h
   32.33 +#define _SDL_androidvulkan_h
   32.34 +
   32.35 +#include "../SDL_vulkan_internal.h"
   32.36 +#include "../SDL_sysvideo.h"
   32.37 +
   32.38 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_ANDROID
   32.39 +
   32.40 +int Android_Vulkan_LoadLibrary(_THIS, const char *path);
   32.41 +void Android_Vulkan_UnloadLibrary(_THIS);
   32.42 +SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
   32.43 +                                          SDL_Window *window,
   32.44 +                                          unsigned *count,
   32.45 +                                          const char **names);
   32.46 +SDL_bool Android_Vulkan_CreateSurface(_THIS,
   32.47 +                                  SDL_Window *window,
   32.48 +                                  VkInstance instance,
   32.49 +                                  VkSurfaceKHR *surface);
   32.50 +
   32.51 +#endif
   32.52 +
   32.53 +#endif /* _SDL_androidvulkan_h */
   32.54 +
   32.55 +/* vi: set ts=4 sw=4 expandtab: */
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/video/cocoa/SDL_cocoametalview.h	Sun Aug 27 22:15:57 2017 -0400
    33.3 @@ -0,0 +1,61 @@
    33.4 +/*
    33.5 + Simple DirectMedia Layer
    33.6 + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    33.7 + 
    33.8 + This software is provided 'as-is', without any express or implied
    33.9 + warranty.  In no event will the authors be held liable for any damages
   33.10 + arising from the use of this software.
   33.11 + 
   33.12 + Permission is granted to anyone to use this software for any purpose,
   33.13 + including commercial applications, and to alter it and redistribute it
   33.14 + freely, subject to the following restrictions:
   33.15 + 
   33.16 + 1. The origin of this software must not be misrepresented; you must not
   33.17 + claim that you wrote the original software. If you use this software
   33.18 + in a product, an acknowledgment in the product documentation would be
   33.19 + appreciated but is not required.
   33.20 + 2. Altered source versions must be plainly marked as such, and must not be
   33.21 + misrepresented as being the original software.
   33.22 + 3. This notice may not be removed or altered from any source distribution.
   33.23 + */
   33.24 +
   33.25 +/*
   33.26 + * @author Mark Callow, www.edgewise-consulting.com.
   33.27 + *
   33.28 + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
   33.29 + * how to add a CAMetalLayer backed view.
   33.30 + */
   33.31 +
   33.32 +#ifndef _SDL_cocoametalview_h
   33.33 +#define _SDL_cocoametalview_h
   33.34 +
   33.35 +#import "../SDL_sysvideo.h"
   33.36 +#import "SDL_cocoawindow.h"
   33.37 +
   33.38 +#import <Cocoa/Cocoa.h>
   33.39 +#import <Metal/Metal.h>
   33.40 +#import <QuartzCore/CAMetalLayer.h>
   33.41 +
   33.42 +#define METALVIEW_TAG 255
   33.43 +
   33.44 +@interface SDL_cocoametalview : NSView {
   33.45 +    NSInteger _tag;
   33.46 +    bool _useHighDPI;
   33.47 +}
   33.48 +
   33.49 +- (instancetype)initWithFrame:(NSRect)frame
   33.50 +                   useHighDPI:(bool)useHighDPI;
   33.51 +
   33.52 +/* Override superclass tag so this class can set it. */
   33.53 +@property (assign, readonly) NSInteger tag;
   33.54 +
   33.55 +@end
   33.56 +
   33.57 +SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
   33.58 +
   33.59 +void Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
   33.60 +
   33.61 +#endif /* _SDL_cocoametalview_h */
   33.62 +
   33.63 +/* vi: set ts=4 sw=4 expandtab: */
   33.64 +
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/video/cocoa/SDL_cocoametalview.m	Sun Aug 27 22:15:57 2017 -0400
    34.3 @@ -0,0 +1,124 @@
    34.4 +/*
    34.5 + Simple DirectMedia Layer
    34.6 + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    34.7 + 
    34.8 + This software is provided 'as-is', without any express or implied
    34.9 + warranty.  In no event will the authors be held liable for any damages
   34.10 + arising from the use of this software.
   34.11 + 
   34.12 + Permission is granted to anyone to use this software for any purpose,
   34.13 + including commercial applications, and to alter it and redistribute it
   34.14 + freely, subject to the following restrictions:
   34.15 + 
   34.16 + 1. The origin of this software must not be misrepresented; you must not
   34.17 + claim that you wrote the original software. If you use this software
   34.18 + in a product, an acknowledgment in the product documentation would be
   34.19 + appreciated but is not required.
   34.20 + 2. Altered source versions must be plainly marked as such, and must not be
   34.21 + misrepresented as being the original software.
   34.22 + 3. This notice may not be removed or altered from any source distribution.
   34.23 + */
   34.24 +
   34.25 +/*
   34.26 + * @author Mark Callow, www.edgewise-consulting.com.
   34.27 + *
   34.28 + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
   34.29 + * how to add a CAMetalLayer backed view.
   34.30 + */
   34.31 +
   34.32 +/* this is (currently) only used with Vulkan. Remove this #if when that changes! */
   34.33 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
   34.34 +
   34.35 +#import "SDL_cocoametalview.h"
   34.36 +
   34.37 +#include "SDL_assert.h"
   34.38 +#include "SDL_loadso.h"
   34.39 +#include <dlfcn.h>
   34.40 +
   34.41 +@implementation SDL_cocoametalview
   34.42 +
   34.43 +/* The synthesized getter should be called by super's viewWithTag. */
   34.44 +@synthesize tag = _tag;
   34.45 +
   34.46 +/* Return a Metal-compatible layer. */
   34.47 ++ (Class)layerClass
   34.48 +{
   34.49 +  return [CAMetalLayer class];
   34.50 +}
   34.51 +
   34.52 +/* Indicate the view wants to draw using a backing layer instead of drawRect. */
   34.53 +-(BOOL) wantsUpdateLayer { return YES; }
   34.54 +
   34.55 +/* When the wantsLayer property is set to YES, this method will be invoked to
   34.56 + * return a layer instance.
   34.57 + */
   34.58 +-(CALayer*) makeBackingLayer { return [self.class.layerClass layer]; }
   34.59 +
   34.60 +- (instancetype)initWithFrame:(NSRect)frame
   34.61 +                   useHighDPI:(bool)useHighDPI
   34.62 +{
   34.63 +  if ((self = [super initWithFrame:frame])) {
   34.64 +    
   34.65 +    /* Allow resize. */
   34.66 +    self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
   34.67 +    _tag = METALVIEW_TAG;
   34.68 +      
   34.69 +    _useHighDPI = useHighDPI;
   34.70 +    [self updateDrawableSize];
   34.71 +  }
   34.72 +  
   34.73 +  return self;
   34.74 +}
   34.75 +
   34.76 +/* Set the size of the metal drawables when the view is resized. */
   34.77 +- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
   34.78 +    [super resizeSubviewsWithOldSize:oldSize];
   34.79 +    [self updateDrawableSize];
   34.80 +}
   34.81 +
   34.82 +- (void)updateDrawableSize
   34.83 +{
   34.84 +    if (_useHighDPI) {
   34.85 +        NSSize size = [self convertRectToBacking:[self bounds]].size;
   34.86 +         /* Isn't there a better way to convert from NSSize to CGSize? */
   34.87 +        CGSize cgsize = *(CGSize*)&size;
   34.88 +        ((CAMetalLayer *) self.layer).drawableSize = cgsize;
   34.89 +    }
   34.90 +}
   34.91 +
   34.92 +@end
   34.93 +
   34.94 +SDL_cocoametalview*
   34.95 +Cocoa_Mtl_AddMetalView(SDL_Window* window)
   34.96 +{
   34.97 +    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   34.98 +    NSView *view = data->nswindow.contentView;
   34.99 +
  34.100 +    SDL_cocoametalview *metalview
  34.101 +        = [[SDL_cocoametalview alloc] initWithFrame:view.frame
  34.102 +                       useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)];
  34.103 +    [view addSubview:metalview];
  34.104 +  
  34.105 +    return metalview;
  34.106 +}
  34.107 +
  34.108 +void
  34.109 +Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
  34.110 +{
  34.111 +    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
  34.112 +    NSView *view = data->nswindow.contentView;
  34.113 +    SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
  34.114 +    if (metalview) {
  34.115 +        CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
  34.116 +        assert(layer != NULL);
  34.117 +        if (w)
  34.118 +            *w = layer.drawableSize.width;
  34.119 +        if (h)
  34.120 +            *h = layer.drawableSize.height;
  34.121 +    }
  34.122 +}
  34.123 +
  34.124 +#endif
  34.125 +
  34.126 +/* vi: set ts=4 sw=4 expandtab: */
  34.127 +
    35.1 --- a/src/video/cocoa/SDL_cocoavideo.m	Sun Aug 27 19:10:30 2017 -0700
    35.2 +++ b/src/video/cocoa/SDL_cocoavideo.m	Sun Aug 27 22:15:57 2017 -0400
    35.3 @@ -26,6 +26,7 @@
    35.4  #include "SDL_endian.h"
    35.5  #include "SDL_cocoavideo.h"
    35.6  #include "SDL_cocoashape.h"
    35.7 +#include "SDL_cocoavulkan.h"
    35.8  #include "SDL_assert.h"
    35.9  
   35.10  /* Initialization/Query functions */
   35.11 @@ -122,6 +123,14 @@
   35.12      device->GL_DeleteContext = Cocoa_GL_DeleteContext;
   35.13  #endif
   35.14  
   35.15 +#if SDL_VIDEO_VULKAN_SURFACE
   35.16 +    device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary;
   35.17 +    device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary;
   35.18 +    device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions;
   35.19 +    device->Vulkan_CreateSurface = Cocoa_Vulkan_CreateSurface;
   35.20 +    device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
   35.21 +#endif
   35.22 +
   35.23      device->StartTextInput = Cocoa_StartTextInput;
   35.24      device->StopTextInput = Cocoa_StopTextInput;
   35.25      device->SetTextInputRect = Cocoa_SetTextInputRect;
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/src/video/cocoa/SDL_cocoavulkan.h	Sun Aug 27 22:15:57 2017 -0400
    36.3 @@ -0,0 +1,55 @@
    36.4 +/*
    36.5 +  Simple DirectMedia Layer
    36.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    36.7 +
    36.8 +  This software is provided 'as-is', without any express or implied
    36.9 +  warranty.  In no event will the authors be held liable for any damages
   36.10 +  arising from the use of this software.
   36.11 +
   36.12 +  Permission is granted to anyone to use this software for any purpose,
   36.13 +  including commercial applications, and to alter it and redistribute it
   36.14 +  freely, subject to the following restrictions:
   36.15 +
   36.16 +  1. The origin of this software must not be misrepresented; you must not
   36.17 +     claim that you wrote the original software. If you use this software
   36.18 +     in a product, an acknowledgment in the product documentation would be
   36.19 +     appreciated but is not required.
   36.20 +  2. Altered source versions must be plainly marked as such, and must not be
   36.21 +     misrepresented as being the original software.
   36.22 +  3. This notice may not be removed or altered from any source distribution.
   36.23 +*/
   36.24 +
   36.25 +/*
   36.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   36.27 + * SDL_x11vulkan.h.
   36.28 + */
   36.29 +
   36.30 +
   36.31 +#include "../../SDL_internal.h"
   36.32 +
   36.33 +#ifndef _SDL_cocoavulkan_h
   36.34 +#define _SDL_cocoavulkan_h
   36.35 +
   36.36 +#include "../SDL_vulkan_internal.h"
   36.37 +#include "../SDL_sysvideo.h"
   36.38 +
   36.39 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
   36.40 +
   36.41 +int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path);
   36.42 +void Cocoa_Vulkan_UnloadLibrary(_THIS);
   36.43 +SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
   36.44 +                                          SDL_Window *window,
   36.45 +                                          unsigned *count,
   36.46 +                                          const char **names);
   36.47 +SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
   36.48 +                                  SDL_Window *window,
   36.49 +                                  VkInstance instance,
   36.50 +                                  VkSurfaceKHR *surface);
   36.51 +
   36.52 +void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
   36.53 +
   36.54 +#endif
   36.55 +
   36.56 +#endif /* _SDL_cocoavulkan_h */
   36.57 +
   36.58 +/* vi: set ts=4 sw=4 expandtab: */
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/src/video/cocoa/SDL_cocoavulkan.m	Sun Aug 27 22:15:57 2017 -0400
    37.3 @@ -0,0 +1,217 @@
    37.4 +/*
    37.5 +  Simple DirectMedia Layer
    37.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    37.7 +
    37.8 +  This software is provided 'as-is', without any express or implied
    37.9 +  warranty.  In no event will the authors be held liable for any damages
   37.10 +  arising from the use of this software.
   37.11 +
   37.12 +  Permission is granted to anyone to use this software for any purpose,
   37.13 +  including commercial applications, and to alter it and redistribute it
   37.14 +  freely, subject to the following restrictions:
   37.15 +
   37.16 +  1. The origin of this software must not be misrepresented; you must not
   37.17 +     claim that you wrote the original software. If you use this software
   37.18 +     in a product, an acknowledgment in the product documentation would be
   37.19 +     appreciated but is not required.
   37.20 +  2. Altered source versions must be plainly marked as such, and must not be
   37.21 +     misrepresented as being the original software.
   37.22 +  3. This notice may not be removed or altered from any source distribution.
   37.23 +*/
   37.24 +
   37.25 +/* 
   37.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   37.27 + * SDL_x11vulkan.c.
   37.28 + */
   37.29 +
   37.30 +#include "../../SDL_internal.h"
   37.31 +
   37.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
   37.33 +
   37.34 +#include "SDL_cocoavideo.h"
   37.35 +#include "SDL_cocoawindow.h"
   37.36 +#include "SDL_assert.h"
   37.37 +
   37.38 +#include "SDL_loadso.h"
   37.39 +#include "SDL_cocoametalview.h"
   37.40 +#include "SDL_cocoavulkan.h"
   37.41 +#include "SDL_syswm.h"
   37.42 +
   37.43 +#include <dlfcn.h>
   37.44 +
   37.45 +#define DEFAULT_MOLTENVK  "libMoltenVK.dylib"
   37.46 +/* Since libSDL is most likely a .dylib, need RTLD_DEFAULT not RTLD_SELF. */
   37.47 +#define DEFAULT_HANDLE RTLD_DEFAULT
   37.48 +
   37.49 +int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
   37.50 +{
   37.51 +    VkExtensionProperties *extensions = NULL;
   37.52 +    Uint32 extensionCount = 0;
   37.53 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   37.54 +    SDL_bool hasMacOSSurfaceExtension = SDL_FALSE;
   37.55 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   37.56 +    if(_this->vulkan_config.loader_handle)
   37.57 +    {
   37.58 +        SDL_SetError("MoltenVK/Vulkan already loaded");
   37.59 +        return -1;
   37.60 +    }
   37.61 +
   37.62 +    /* Load the Vulkan loader library */
   37.63 +    if(!path)
   37.64 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   37.65 +    if(!path)
   37.66 +    {
   37.67 +        /* MoltenVK framework, currently, v0.17.0, has a static library and is
   37.68 +         * the recommended way to use the package. There is likely no object to
   37.69 +         * load. */
   37.70 +        vkGetInstanceProcAddr =
   37.71 +         (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
   37.72 +                                          "vkGetInstanceProcAddr");
   37.73 +    }
   37.74 +    
   37.75 +    if(vkGetInstanceProcAddr)
   37.76 +    {
   37.77 +        _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
   37.78 +    }
   37.79 +    else
   37.80 +    {
   37.81 +        if (!path)
   37.82 +        {
   37.83 +            /* Look for the .dylib packaged with the application instead. */
   37.84 +            path = DEFAULT_MOLTENVK;
   37.85 +        }
   37.86 +        
   37.87 +        _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   37.88 +        if(!_this->vulkan_config.loader_handle)
   37.89 +            return -1;
   37.90 +        SDL_strlcpy(_this->vulkan_config.loader_path, path,
   37.91 +                    SDL_arraysize(_this->vulkan_config.loader_path));
   37.92 +        vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   37.93 +            _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   37.94 +    }
   37.95 +    if(!vkGetInstanceProcAddr)
   37.96 +    {
   37.97 +        SDL_SetError("Failed to find %s in either executable or %s: %s",
   37.98 +                     "vkGetInstanceProcAddr",
   37.99 +                     DEFAULT_MOLTENVK,
  37.100 +                     (const char *) dlerror());
  37.101 +        goto fail;
  37.102 +    }
  37.103 +
  37.104 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
  37.105 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
  37.106 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
  37.107 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
  37.108 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
  37.109 +        goto fail;
  37.110 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
  37.111 +        (PFN_vkEnumerateInstanceExtensionProperties)
  37.112 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
  37.113 +        &extensionCount);
  37.114 +    if(!extensions)
  37.115 +        goto fail;
  37.116 +    for(Uint32 i = 0; i < extensionCount; i++)
  37.117 +    {
  37.118 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
  37.119 +            hasSurfaceExtension = SDL_TRUE;
  37.120 +        else if(SDL_strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
  37.121 +            hasMacOSSurfaceExtension = SDL_TRUE;
  37.122 +    }
  37.123 +    SDL_free(extensions);
  37.124 +    if(!hasSurfaceExtension)
  37.125 +    {
  37.126 +        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
  37.127 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
  37.128 +        goto fail;
  37.129 +    }
  37.130 +    else if(!hasMacOSSurfaceExtension)
  37.131 +    {
  37.132 +        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
  37.133 +                     VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension");
  37.134 +        goto fail;
  37.135 +    }
  37.136 +    return 0;
  37.137 +
  37.138 +fail:
  37.139 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  37.140 +    _this->vulkan_config.loader_handle = NULL;
  37.141 +    return -1;
  37.142 +}
  37.143 +
  37.144 +void Cocoa_Vulkan_UnloadLibrary(_THIS)
  37.145 +{
  37.146 +    if(_this->vulkan_config.loader_handle)
  37.147 +    {
  37.148 +        if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE)
  37.149 +            SDL_UnloadObject(_this->vulkan_config.loader_handle);
  37.150 +        _this->vulkan_config.loader_handle = NULL;
  37.151 +    }
  37.152 +}
  37.153 +
  37.154 +SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS,
  37.155 +                                          SDL_Window *window,
  37.156 +                                          unsigned *count,
  37.157 +                                          const char **names)
  37.158 +{
  37.159 +    static const char *const extensionsForCocoa[] = {
  37.160 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_EXTENSION_NAME
  37.161 +    };
  37.162 +    if(!_this->vulkan_config.loader_handle)
  37.163 +    {
  37.164 +        SDL_SetError("Vulkan is not loaded");
  37.165 +        return SDL_FALSE;
  37.166 +    }
  37.167 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  37.168 +            count, names, SDL_arraysize(extensionsForCocoa),
  37.169 +            extensionsForCocoa);
  37.170 +}
  37.171 +
  37.172 +SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
  37.173 +                                  SDL_Window *window,
  37.174 +                                  VkInstance instance,
  37.175 +                                  VkSurfaceKHR *surface)
  37.176 +{
  37.177 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  37.178 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  37.179 +    PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
  37.180 +        (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(
  37.181 +                                            (VkInstance)instance,
  37.182 +                                            "vkCreateMacOSSurfaceMVK");
  37.183 +    VkMacOSSurfaceCreateInfoMVK createInfo = {};
  37.184 +    VkResult result;
  37.185 +
  37.186 +    if(!_this->vulkan_config.loader_handle)
  37.187 +    {
  37.188 +        SDL_SetError("Vulkan is not loaded");
  37.189 +        return SDL_FALSE;
  37.190 +    }
  37.191 +
  37.192 +    if(!vkCreateMacOSSurfaceMVK)
  37.193 +    {
  37.194 +        SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME
  37.195 +                     " extension is not enabled in the Vulkan instance.");
  37.196 +        return SDL_FALSE;
  37.197 +    }
  37.198 +    createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
  37.199 +    createInfo.pNext = NULL;
  37.200 +    createInfo.flags = 0;
  37.201 +    createInfo.pView = Cocoa_Mtl_AddMetalView(window);
  37.202 +    result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
  37.203 +                                       NULL, surface);
  37.204 +    if(result != VK_SUCCESS)
  37.205 +    {
  37.206 +        SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
  37.207 +                     SDL_Vulkan_GetResultString(result));
  37.208 +        return SDL_FALSE;
  37.209 +    }
  37.210 +    return SDL_TRUE;
  37.211 +}
  37.212 +
  37.213 +void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
  37.214 +{
  37.215 +    Cocoa_Mtl_GetDrawableSize(window, w, h);
  37.216 +}
  37.217 +
  37.218 +#endif
  37.219 +
  37.220 +/* vim: set ts=4 sw=4 expandtab: */
    38.1 --- a/src/video/mir/SDL_mirvideo.c	Sun Aug 27 19:10:30 2017 -0700
    38.2 +++ b/src/video/mir/SDL_mirvideo.c	Sun Aug 27 22:15:57 2017 -0400
    38.3 @@ -36,6 +36,7 @@
    38.4  #include "SDL_mirmouse.h"
    38.5  #include "SDL_miropengl.h"
    38.6  #include "SDL_mirvideo.h"
    38.7 +#include "SDL_mirvulkan.h"
    38.8  
    38.9  #include "SDL_mirdyn.h"
   38.10  
   38.11 @@ -232,6 +233,13 @@
   38.12  
   38.13      device->ShowMessageBox = NULL;
   38.14  
   38.15 +#if SDL_VIDEO_VULKAN_SURFACE
   38.16 +    device->Vulkan_LoadLibrary = MIR_Vulkan_LoadLibrary;
   38.17 +    device->Vulkan_UnloadLibrary = MIR_Vulkan_UnloadLibrary;
   38.18 +    device->Vulkan_GetInstanceExtensions = MIR_Vulkan_GetInstanceExtensions;
   38.19 +    device->Vulkan_CreateSurface = MIR_Vulkan_CreateSurface;
   38.20 +#endif
   38.21 +
   38.22      return device;
   38.23  }
   38.24  
    39.1 --- a/src/video/mir/SDL_mirvideo.h	Sun Aug 27 19:10:30 2017 -0700
    39.2 +++ b/src/video/mir/SDL_mirvideo.h	Sun Aug 27 22:15:57 2017 -0400
    39.3 @@ -28,6 +28,7 @@
    39.4  
    39.5  #include <EGL/egl.h>
    39.6  #include <mir_toolkit/mir_client_library.h>
    39.7 +#include "SDL_stdinc.h"
    39.8  
    39.9  typedef struct MIR_Window MIR_Window;
   39.10  
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/src/video/mir/SDL_mirvulkan.c	Sun Aug 27 22:15:57 2017 -0400
    40.3 @@ -0,0 +1,175 @@
    40.4 +/*
    40.5 +  Simple DirectMedia Layer
    40.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    40.7 +
    40.8 +  This software is provided 'as-is', without any express or implied
    40.9 +  warranty.  In no event will the authors be held liable for any damages
   40.10 +  arising from the use of this software.
   40.11 +
   40.12 +  Permission is granted to anyone to use this software for any purpose,
   40.13 +  including commercial applications, and to alter it and redistribute it
   40.14 +  freely, subject to the following restrictions:
   40.15 +
   40.16 +  1. The origin of this software must not be misrepresented; you must not
   40.17 +     claim that you wrote the original software. If you use this software
   40.18 +     in a product, an acknowledgment in the product documentation would be
   40.19 +     appreciated but is not required.
   40.20 +  2. Altered source versions must be plainly marked as such, and must not be
   40.21 +     misrepresented as being the original software.
   40.22 +  3. This notice may not be removed or altered from any source distribution.
   40.23 +*/
   40.24 +
   40.25 +/*
   40.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   40.27 + * SDL_x11vulkan.c.
   40.28 + */
   40.29 +
   40.30 +#include "../../SDL_internal.h"
   40.31 +
   40.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_MIR
   40.33 +
   40.34 +#include "SDL_mirvideo.h"
   40.35 +#include "SDL_mirwindow.h"
   40.36 +#include "SDL_assert.h"
   40.37 +
   40.38 +#include "SDL_loadso.h"
   40.39 +#include "SDL_mirvulkan.h"
   40.40 +#include "SDL_syswm.h"
   40.41 +
   40.42 +int MIR_Vulkan_LoadLibrary(_THIS, const char *path)
   40.43 +{
   40.44 +    VkExtensionProperties *extensions = NULL;
   40.45 +    Uint32 extensionCount = 0;
   40.46 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   40.47 +    SDL_bool hasMIRSurfaceExtension = SDL_FALSE;
   40.48 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   40.49 +    if(_this->vulkan_config.loader_handle)
   40.50 +        return SDL_SetError("Vulkan already loaded");
   40.51 +
   40.52 +    /* Load the Vulkan loader library */
   40.53 +    if(!path)
   40.54 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   40.55 +    if(!path)
   40.56 +        path = "libvulkan.so.1";
   40.57 +    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   40.58 +    if(!_this->vulkan_config.loader_handle)
   40.59 +        return -1;
   40.60 +    SDL_strlcpy(_this->vulkan_config.loader_path, path,
   40.61 +                SDL_arraysize(_this->vulkan_config.loader_path));
   40.62 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   40.63 +        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   40.64 +    if(!vkGetInstanceProcAddr)
   40.65 +        goto fail;
   40.66 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
   40.67 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
   40.68 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
   40.69 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
   40.70 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
   40.71 +        goto fail;
   40.72 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
   40.73 +        (PFN_vkEnumerateInstanceExtensionProperties)
   40.74 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
   40.75 +        &extensionCount);
   40.76 +    if(!extensions)
   40.77 +        goto fail;
   40.78 +    for(Uint32 i = 0; i < extensionCount; i++)
   40.79 +    {
   40.80 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   40.81 +            hasSurfaceExtension = SDL_TRUE;
   40.82 +        else if(SDL_strcmp(VK_KHR_MIR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   40.83 +            hasMIRSurfaceExtension = SDL_TRUE;
   40.84 +    }
   40.85 +    SDL_free(extensions);
   40.86 +    if(!hasSurfaceExtension)
   40.87 +    {
   40.88 +        SDL_SetError("Installed Vulkan doesn't implement the "
   40.89 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
   40.90 +        goto fail;
   40.91 +    }
   40.92 +    else if(!hasMIRSurfaceExtension)
   40.93 +    {
   40.94 +        SDL_SetError("Installed Vulkan doesn't implement the "
   40.95 +                     VK_KHR_MIR_SURFACE_EXTENSION_NAME "extension");
   40.96 +        goto fail;
   40.97 +    }
   40.98 +    return 0;
   40.99 +
  40.100 +fail:
  40.101 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  40.102 +    _this->vulkan_config.loader_handle = NULL;
  40.103 +    return -1;
  40.104 +}
  40.105 +
  40.106 +void MIR_Vulkan_UnloadLibrary(_THIS)
  40.107 +{
  40.108 +    if(_this->vulkan_config.loader_handle)
  40.109 +    {
  40.110 +        SDL_UnloadObject(_this->vulkan_config.loader_handle);
  40.111 +        _this->vulkan_config.loader_handle = NULL;
  40.112 +    }
  40.113 +}
  40.114 +
  40.115 +SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
  40.116 +                                          SDL_Window *window,
  40.117 +                                          unsigned *count,
  40.118 +                                          const char **names)
  40.119 +{
  40.120 +    static const char *const extensionsForMir[] = {
  40.121 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_MIR_SURFACE_EXTENSION_NAME
  40.122 +    };
  40.123 +    if(!_this->vulkan_config.loader_handle)
  40.124 +    {
  40.125 +        SDL_SetError("Vulkan is not loaded");
  40.126 +        return SDL_FALSE;
  40.127 +    }
  40.128 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  40.129 +            count, names, SDL_arraysize(extensionsForMir),
  40.130 +            extensionsForMir);
  40.131 +}
  40.132 +
  40.133 +SDL_bool MIR_Vulkan_CreateSurface(_THIS,
  40.134 +                                  SDL_Window *window,
  40.135 +                                  VkInstance instance,
  40.136 +                                  VkSurfaceKHR *surface)
  40.137 +{
  40.138 +    MIR_Window *windowData = (MIR_Window *)window->driverdata;
  40.139 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  40.140 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  40.141 +    PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR =
  40.142 +        (PFN_vkCreateMirSurfaceKHR)vkGetInstanceProcAddr(
  40.143 +                                            (VkInstance)instance,
  40.144 +                                            "vkCreateMirSurfaceKHR");
  40.145 +    VkMirSurfaceCreateInfoKHR createInfo = {};
  40.146 +    VkResult result;
  40.147 +
  40.148 +    if(!_this->vulkan_config.loader_handle)
  40.149 +    {
  40.150 +        SDL_SetError("Vulkan is not loaded");
  40.151 +        return SDL_FALSE;
  40.152 +    }
  40.153 +
  40.154 +    if(!vkCreateMirSurfaceKHR)
  40.155 +    {
  40.156 +        SDL_SetError(VK_KHR_MIR_SURFACE_EXTENSION_NAME
  40.157 +                     " extension is not enabled in the Vulkan instance.");
  40.158 +        return SDL_FALSE;
  40.159 +    }
  40.160 +    createInfo.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
  40.161 +    createInfo.pNext = NULL;
  40.162 +    createInfo.flags = 0;
  40.163 +    createInfo.connection = windowData->mir_data->connection;
  40.164 +    createInfo.mirSurface = windowData->window;
  40.165 +    result = vkCreateMirSurfaceKHR(instance, &createInfo,
  40.166 +                                       NULL, surface);
  40.167 +    if(result != VK_SUCCESS)
  40.168 +    {
  40.169 +        SDL_SetError("vkCreateMirSurfaceKHR failed: %s",
  40.170 +                     SDL_Vulkan_GetResultString(result));
  40.171 +        return SDL_FALSE;
  40.172 +    }
  40.173 +    return SDL_TRUE;
  40.174 +}
  40.175 +
  40.176 +#endif
  40.177 +
  40.178 +/* vim: set ts=4 sw=4 expandtab: */
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/src/video/mir/SDL_mirvulkan.h	Sun Aug 27 22:15:57 2017 -0400
    41.3 @@ -0,0 +1,52 @@
    41.4 +/*
    41.5 +  Simple DirectMedia Layer
    41.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    41.7 +
    41.8 +  This software is provided 'as-is', without any express or implied
    41.9 +  warranty.  In no event will the authors be held liable for any damages
   41.10 +  arising from the use of this software.
   41.11 +
   41.12 +  Permission is granted to anyone to use this software for any purpose,
   41.13 +  including commercial applications, and to alter it and redistribute it
   41.14 +  freely, subject to the following restrictions:
   41.15 +
   41.16 +  1. The origin of this software must not be misrepresented; you must not
   41.17 +     claim that you wrote the original software. If you use this software
   41.18 +     in a product, an acknowledgment in the product documentation would be
   41.19 +     appreciated but is not required.
   41.20 +  2. Altered source versions must be plainly marked as such, and must not be
   41.21 +     misrepresented as being the original software.
   41.22 +  3. This notice may not be removed or altered from any source distribution.
   41.23 +*/
   41.24 +
   41.25 +/*
   41.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   41.27 + * SDL_x11vulkan.h.
   41.28 + */
   41.29 +
   41.30 +#include "../../SDL_internal.h"
   41.31 +
   41.32 +#ifndef _SDL_mirvulkan_h
   41.33 +#define _SDL_mirvulkan_h
   41.34 +
   41.35 +#include "../SDL_vulkan_internal.h"
   41.36 +#include "../SDL_sysvideo.h"
   41.37 +
   41.38 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_MIR
   41.39 +
   41.40 +int MIR_Vulkan_LoadLibrary(_THIS, const char *path);
   41.41 +void MIR_Vulkan_UnloadLibrary(_THIS);
   41.42 +SDL_bool MIR_Vulkan_GetInstanceExtensions(_THIS,
   41.43 +                                          SDL_Window *window,
   41.44 +                                          unsigned *count,
   41.45 +                                          const char **names);
   41.46 +SDL_bool MIR_Vulkan_CreateSurface(_THIS,
   41.47 +                                  SDL_Window *window,
   41.48 +                                  VkInstance instance,
   41.49 +                                  VkSurfaceKHR *surface);
   41.50 +
   41.51 +#endif
   41.52 +
   41.53 +#endif /* _SDL_mirvulkan_h */
   41.54 +
   41.55 +/* vi: set ts=4 sw=4 expandtab: */
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/video/uikit/SDL_uikitmetalview.h	Sun Aug 27 22:15:57 2017 -0400
    42.3 @@ -0,0 +1,53 @@
    42.4 +/*
    42.5 + Simple DirectMedia Layer
    42.6 + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    42.7 + 
    42.8 + This software is provided 'as-is', without any express or implied
    42.9 + warranty.  In no event will the authors be held liable for any damages
   42.10 + arising from the use of this software.
   42.11 + 
   42.12 + Permission is granted to anyone to use this software for any purpose,
   42.13 + including commercial applications, and to alter it and redistribute it
   42.14 + freely, subject to the following restrictions:
   42.15 + 
   42.16 + 1. The origin of this software must not be misrepresented; you must not
   42.17 + claim that you wrote the original software. If you use this software
   42.18 + in a product, an acknowledgment in the product documentation would be
   42.19 + appreciated but is not required.
   42.20 + 2. Altered source versions must be plainly marked as such, and must not be
   42.21 + misrepresented as being the original software.
   42.22 + 3. This notice may not be removed or altered from any source distribution.
   42.23 + */
   42.24 +
   42.25 +/*
   42.26 + * @author Mark Callow, www.edgewise-consulting.com.
   42.27 + *
   42.28 + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
   42.29 + * how to add a CAMetalLayer backed view.
   42.30 + */
   42.31 +
   42.32 +#ifndef _SDL_uikitmetalview_h
   42.33 +#define _SDL_uikitmetalview_h
   42.34 +
   42.35 +#import "../SDL_sysvideo.h"
   42.36 +#import "SDL_uikitwindow.h"
   42.37 +
   42.38 +#import <UIKit/UIKit.h>
   42.39 +#import <Metal/Metal.h>
   42.40 +#import <QuartzCore/CAMetalLayer.h>
   42.41 +
   42.42 +#define METALVIEW_TAG 255
   42.43 +
   42.44 +@interface SDL_uikitmetalview : UIView
   42.45 +
   42.46 +- (instancetype)initWithFrame:(CGRect)frame
   42.47 +                        scale:(CGFloat)scale
   42.48 +                        tag:(int)tag;
   42.49 +
   42.50 +@end
   42.51 +
   42.52 +SDL_uikitmetalview* UIKit_Mtl_AddMetalView(SDL_Window* window);
   42.53 +
   42.54 +void UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
   42.55 +
   42.56 +#endif /* _SDL_uikitmetalview_h */
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/video/uikit/SDL_uikitmetalview.m	Sun Aug 27 22:15:57 2017 -0400
    43.3 @@ -0,0 +1,146 @@
    43.4 +/*
    43.5 + Simple DirectMedia Layer
    43.6 + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    43.7 + 
    43.8 + This software is provided 'as-is', without any express or implied
    43.9 + warranty.  In no event will the authors be held liable for any damages
   43.10 + arising from the use of this software.
   43.11 + 
   43.12 + Permission is granted to anyone to use this software for any purpose,
   43.13 + including commercial applications, and to alter it and redistribute it
   43.14 + freely, subject to the following restrictions:
   43.15 + 
   43.16 + 1. The origin of this software must not be misrepresented; you must not
   43.17 + claim that you wrote the original software. If you use this software
   43.18 + in a product, an acknowledgment in the product documentation would be
   43.19 + appreciated but is not required.
   43.20 + 2. Altered source versions must be plainly marked as such, and must not be
   43.21 + misrepresented as being the original software.
   43.22 + 3. This notice may not be removed or altered from any source distribution.
   43.23 + */
   43.24 +
   43.25 +/*
   43.26 + * @author Mark Callow, www.edgewise-consulting.com.
   43.27 + *
   43.28 + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
   43.29 + * how to add a CAMetalLayer backed view.
   43.30 + */
   43.31 +
   43.32 +#include "../../SDL_internal.h"
   43.33 +
   43.34 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
   43.35 +
   43.36 +#import "../SDL_sysvideo.h"
   43.37 +#import "SDL_uikitwindow.h"
   43.38 +#import "SDL_uikitmetalview.h"
   43.39 +
   43.40 +#include "SDL_assert.h"
   43.41 +#include "SDL_loadso.h"
   43.42 +#include <dlfcn.h>
   43.43 +
   43.44 +static void* loader_handle;
   43.45 +
   43.46 +@implementation SDL_uikitmetalview
   43.47 +
   43.48 +/* Returns a Metal-compatible layer. */
   43.49 ++ (Class)layerClass
   43.50 +{
   43.51 +    return [CAMetalLayer class];
   43.52 +}
   43.53 +
   43.54 +- (instancetype)initWithFrame:(CGRect)frame
   43.55 +                        scale:(CGFloat)scale
   43.56 +                          tag:(int)tag
   43.57 +{
   43.58 +    if ((self = [super initWithFrame:frame])) {
   43.59 +        /* Resize properly when rotated. */
   43.60 +        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
   43.61 +
   43.62 +        /* Set the appropriate scale (for retina display support) */
   43.63 +        self.contentScaleFactor = scale;
   43.64 +        self.tag = tag;
   43.65 +
   43.66 +        [self updateDrawableSize];
   43.67 +    }
   43.68 +
   43.69 +    return self;
   43.70 +}
   43.71 +
   43.72 +/* Set the size of the metal drawables when the view is resized. */
   43.73 +- (void)layoutSubviews
   43.74 +{
   43.75 +    [super layoutSubviews];
   43.76 +    [self updateDrawableSize];
   43.77 +}
   43.78 +
   43.79 +- (void)updateDrawableSize
   43.80 +{
   43.81 +    CGSize size  = self.bounds.size;
   43.82 +    size.width  *= self.contentScaleFactor;
   43.83 +    size.height *= self.contentScaleFactor;
   43.84 +
   43.85 +    ((CAMetalLayer *) self.layer).drawableSize = size;
   43.86 +}
   43.87 +
   43.88 +@end
   43.89 +
   43.90 +SDL_uikitmetalview*
   43.91 +UIKit_Mtl_AddMetalView(SDL_Window* window)
   43.92 +{
   43.93 +    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
   43.94 +    SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
   43.95 +    CGFloat scale = 1.0;
   43.96 +    
   43.97 +    if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
   43.98 +        /* Set the scale to the natural scale factor of the screen - the
   43.99 +         * backing dimensions of the Metal view will match the pixel
  43.100 +         * dimensions of the screen rather than the dimensions in points.
  43.101 +         */
  43.102 +#ifdef __IPHONE_8_0
  43.103 +        if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
  43.104 +            scale = data.uiwindow.screen.nativeScale;
  43.105 +        } else
  43.106 +#endif
  43.107 +        {
  43.108 +            scale = data.uiwindow.screen.scale;
  43.109 +        }
  43.110 +    }
  43.111 +    SDL_uikitmetalview *metalview
  43.112 +         = [[SDL_uikitmetalview alloc] initWithFrame:view.frame
  43.113 +                                          scale:scale
  43.114 +                                            tag:METALVIEW_TAG];
  43.115 +#if 1
  43.116 +    [view addSubview:metalview];
  43.117 +#else
  43.118 +    /* Sets this view as the controller's view, and adds the view to
  43.119 +     * the window hierarchy.
  43.120 +     *
  43.121 +     * Left here for information. Not used because I suspect that for correct
  43.122 +     * operation it will be necesary to copy everything from the window's
  43.123 +     * current SDL_uikitview instance to the SDL_uikitview portion of the
  43.124 +     * SDL_metalview. The latter would be derived from SDL_uikitview rather
  43.125 +     * than UIView. */
  43.126 +    [metalview setSDLWindow:window];
  43.127 +#endif
  43.128 +
  43.129 +    return metalview;
  43.130 +}
  43.131 +
  43.132 +void
  43.133 +UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
  43.134 +{
  43.135 +    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
  43.136 +    SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
  43.137 +    SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
  43.138 +    if (metalview) {
  43.139 +        CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
  43.140 +        assert(layer != NULL);
  43.141 +        if (w)
  43.142 +            *w = layer.drawableSize.width;
  43.143 +        if (h)
  43.144 +            *h = layer.drawableSize.height;
  43.145 +    } else
  43.146 +        SDL_GetWindowSize(window, w, h);
  43.147 +}
  43.148 +
  43.149 +#endif
    44.1 --- a/src/video/uikit/SDL_uikitvideo.m	Sun Aug 27 19:10:30 2017 -0700
    44.2 +++ b/src/video/uikit/SDL_uikitvideo.m	Sun Aug 27 22:15:57 2017 -0400
    44.3 @@ -37,6 +37,7 @@
    44.4  #include "SDL_uikitwindow.h"
    44.5  #include "SDL_uikitopengles.h"
    44.6  #include "SDL_uikitclipboard.h"
    44.7 +#include "SDL_uikitvulkan.h"
    44.8  
    44.9  #define UIKITVID_DRIVER_NAME "uikit"
   44.10  
   44.11 @@ -123,6 +124,15 @@
   44.12          device->GL_LoadLibrary      = UIKit_GL_LoadLibrary;
   44.13          device->free = UIKit_DeleteDevice;
   44.14  
   44.15 +    #if SDL_VIDEO_VULKAN_SURFACE
   44.16 +        device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary;
   44.17 +        device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary;
   44.18 +        device->Vulkan_GetInstanceExtensions
   44.19 +                                     = UIKit_Vulkan_GetInstanceExtensions;
   44.20 +        device->Vulkan_CreateSurface = UIKit_Vulkan_CreateSurface;
   44.21 +        device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize;
   44.22 +    #endif
   44.23 +
   44.24          device->gl_config.accelerated = 1;
   44.25  
   44.26          return device;
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/src/video/uikit/SDL_uikitvulkan.h	Sun Aug 27 22:15:57 2017 -0400
    45.3 @@ -0,0 +1,54 @@
    45.4 +/*
    45.5 +  Simple DirectMedia Layer
    45.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    45.7 +
    45.8 +  This software is provided 'as-is', without any express or implied
    45.9 +  warranty.  In no event will the authors be held liable for any damages
   45.10 +  arising from the use of this software.
   45.11 +
   45.12 +  Permission is granted to anyone to use this software for any purpose,
   45.13 +  including commercial applications, and to alter it and redistribute it
   45.14 +  freely, subject to the following restrictions:
   45.15 +
   45.16 +  1. The origin of this software must not be misrepresented; you must not
   45.17 +     claim that you wrote the original software. If you use this software
   45.18 +     in a product, an acknowledgment in the product documentation would be
   45.19 +     appreciated but is not required.
   45.20 +  2. Altered source versions must be plainly marked as such, and must not be
   45.21 +     misrepresented as being the original software.
   45.22 +  3. This notice may not be removed or altered from any source distribution.
   45.23 +*/
   45.24 +
   45.25 +/*
   45.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   45.27 + * SDL_x11vulkan.h.
   45.28 + */
   45.29 +
   45.30 +#include "../../SDL_internal.h"
   45.31 +
   45.32 +#ifndef _SDL_uikitvulkan_h
   45.33 +#define _SDL_uikitvulkan_h
   45.34 +
   45.35 +#include "../SDL_vulkan_internal.h"
   45.36 +#include "../SDL_sysvideo.h"
   45.37 +
   45.38 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
   45.39 +
   45.40 +int UIKit_Vulkan_LoadLibrary(_THIS, const char *path);
   45.41 +void UIKit_Vulkan_UnloadLibrary(_THIS);
   45.42 +SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
   45.43 +                                          SDL_Window *window,
   45.44 +                                          unsigned *count,
   45.45 +                                          const char **names);
   45.46 +SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
   45.47 +                                  SDL_Window *window,
   45.48 +                                  VkInstance instance,
   45.49 +                                  VkSurfaceKHR *surface);
   45.50 +
   45.51 +void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
   45.52 +
   45.53 +#endif
   45.54 +
   45.55 +#endif /* _SDL_uikitvulkan_h */
   45.56 +
   45.57 +/* vi: set ts=4 sw=4 expandtab: */
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/src/video/uikit/SDL_uikitvulkan.m	Sun Aug 27 22:15:57 2017 -0400
    46.3 @@ -0,0 +1,221 @@
    46.4 +/*
    46.5 +  Simple DirectMedia Layer
    46.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    46.7 +
    46.8 +  This software is provided 'as-is', without any express or implied
    46.9 +  warranty.  In no event will the authors be held liable for any damages
   46.10 +  arising from the use of this software.
   46.11 +
   46.12 +  Permission is granted to anyone to use this software for any purpose,
   46.13 +  including commercial applications, and to alter it and redistribute it
   46.14 +  freely, subject to the following restrictions:
   46.15 +
   46.16 +  1. The origin of this software must not be misrepresented; you must not
   46.17 +     claim that you wrote the original software. If you use this software
   46.18 +     in a product, an acknowledgment in the product documentation would be
   46.19 +     appreciated but is not required.
   46.20 +  2. Altered source versions must be plainly marked as such, and must not be
   46.21 +     misrepresented as being the original software.
   46.22 +  3. This notice may not be removed or altered from any source distribution.
   46.23 +*/
   46.24 +
   46.25 +/*
   46.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   46.27 + * SDL_x11vulkan.c.
   46.28 + */
   46.29 +
   46.30 +#include "../../SDL_internal.h"
   46.31 +
   46.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_UIKIT
   46.33 +
   46.34 +#include "SDL_uikitvideo.h"
   46.35 +#include "SDL_uikitwindow.h"
   46.36 +#include "SDL_assert.h"
   46.37 +
   46.38 +#include "SDL_loadso.h"
   46.39 +#include "SDL_uikitvulkan.h"
   46.40 +#include "SDL_uikitmetalview.h"
   46.41 +#include "SDL_syswm.h"
   46.42 +
   46.43 +#include <dlfcn.h>
   46.44 +
   46.45 +#define DEFAULT_MOLTENVK  "libMoltenVK.dylib"
   46.46 +/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future
   46.47 + * proofing. */
   46.48 +#define DEFAULT_HANDLE RTLD_DEFAULT
   46.49 +
   46.50 +int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
   46.51 +{
   46.52 +    VkExtensionProperties *extensions = NULL;
   46.53 +    Uint32 extensionCount = 0;
   46.54 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   46.55 +    SDL_bool hasIOSSurfaceExtension = SDL_FALSE;
   46.56 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   46.57 +
   46.58 +    if(_this->vulkan_config.loader_handle)
   46.59 +        return SDL_SetError("MoltenVK/Vulkan already loaded");
   46.60 +
   46.61 +    /* Load the Vulkan loader library */
   46.62 +    if(!path)
   46.63 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   46.64 +    if(!path)
   46.65 +    {
   46.66 +        /* MoltenVK framework, currently, v0.17.0, has a static library and is
   46.67 +         * the recommended way to use the package. There is likely no object to
   46.68 +         * load. */
   46.69 +        vkGetInstanceProcAddr =
   46.70 +        (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
   46.71 +                                         "vkGetInstanceProcAddr");
   46.72 +    }
   46.73 +    
   46.74 +    if(vkGetInstanceProcAddr)
   46.75 +    {
   46.76 +        _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
   46.77 +    }
   46.78 +    else
   46.79 +    {
   46.80 +        if (!path)
   46.81 +        {
   46.82 +            /* Look for the .dylib packaged with the application instead. */
   46.83 +            path = DEFAULT_MOLTENVK;
   46.84 +        }
   46.85 +        
   46.86 +        _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   46.87 +        if(!_this->vulkan_config.loader_handle)
   46.88 +            return -1;
   46.89 +        SDL_strlcpy(_this->vulkan_config.loader_path, path,
   46.90 +                    SDL_arraysize(_this->vulkan_config.loader_path));
   46.91 +        vkGetInstanceProcAddr =
   46.92 +            (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   46.93 +                                    _this->vulkan_config.loader_handle,
   46.94 +                                    "vkGetInstanceProcAddr");
   46.95 +    }
   46.96 +    if(!vkGetInstanceProcAddr)
   46.97 +    {
   46.98 +        SDL_SetError("Failed to find %s in either executable or %s: %s",
   46.99 +                     "vkGetInstanceProcAddr",
  46.100 +                     DEFAULT_MOLTENVK,
  46.101 +                     (const char *) dlerror());
  46.102 +        goto fail;
  46.103 +    }
  46.104 +
  46.105 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
  46.106 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
  46.107 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
  46.108 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
  46.109 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
  46.110 +    {
  46.111 +        SDL_SetError("No vkEnumerateInstanceExtensionProperties found.");
  46.112 +        goto fail;
  46.113 +    }
  46.114 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
  46.115 +        (PFN_vkEnumerateInstanceExtensionProperties)
  46.116 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
  46.117 +        &extensionCount);
  46.118 +    if(!extensions)
  46.119 +        goto fail;
  46.120 +    for(Uint32 i = 0; i < extensionCount; i++)
  46.121 +    {
  46.122 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
  46.123 +            hasSurfaceExtension = SDL_TRUE;
  46.124 +        else if(SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
  46.125 +            hasIOSSurfaceExtension = SDL_TRUE;
  46.126 +    }
  46.127 +    SDL_free(extensions);
  46.128 +    if(!hasSurfaceExtension)
  46.129 +    {
  46.130 +        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
  46.131 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
  46.132 +        goto fail;
  46.133 +    }
  46.134 +    else if(!hasIOSSurfaceExtension)
  46.135 +    {
  46.136 +        SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
  46.137 +                     VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
  46.138 +        goto fail;
  46.139 +    }
  46.140 +
  46.141 +    return 0;
  46.142 +
  46.143 +fail:
  46.144 +    _this->vulkan_config.loader_handle = NULL;
  46.145 +    return -1;
  46.146 +}
  46.147 +
  46.148 +void UIKit_Vulkan_UnloadLibrary(_THIS)
  46.149 +{
  46.150 +    if(_this->vulkan_config.loader_handle)
  46.151 +    {
  46.152 +        if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE)
  46.153 +            SDL_UnloadObject(_this->vulkan_config.loader_handle);
  46.154 +        _this->vulkan_config.loader_handle = NULL;
  46.155 +    }
  46.156 +}
  46.157 +
  46.158 +SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
  46.159 +                                          SDL_Window *window,
  46.160 +                                          unsigned *count,
  46.161 +                                          const char **names)
  46.162 +{
  46.163 +    static const char *const extensionsForUIKit[] = {
  46.164 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME
  46.165 +    };
  46.166 +    if(!_this->vulkan_config.loader_handle)
  46.167 +    {
  46.168 +        SDL_SetError("Vulkan is not loaded");
  46.169 +        return SDL_FALSE;
  46.170 +    }
  46.171 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  46.172 +            count, names, SDL_arraysize(extensionsForUIKit),
  46.173 +            extensionsForUIKit);
  46.174 +}
  46.175 +
  46.176 +SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
  46.177 +                                  SDL_Window *window,
  46.178 +                                  VkInstance instance,
  46.179 +                                  VkSurfaceKHR *surface)
  46.180 +{
  46.181 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  46.182 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  46.183 +    PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK =
  46.184 +        (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr(
  46.185 +                                            (VkInstance)instance,
  46.186 +                                            "vkCreateIOSSurfaceMVK");
  46.187 +    VkIOSSurfaceCreateInfoMVK createInfo = {};
  46.188 +    VkResult result;
  46.189 +
  46.190 +    if(!_this->vulkan_config.loader_handle)
  46.191 +    {
  46.192 +        SDL_SetError("Vulkan is not loaded");
  46.193 +        return SDL_FALSE;
  46.194 +    }
  46.195 +
  46.196 +    if(!vkCreateIOSSurfaceMVK)
  46.197 +    {
  46.198 +        SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME
  46.199 +                     " extension is not enabled in the Vulkan instance.");
  46.200 +        return SDL_FALSE;
  46.201 +    }
  46.202 +    createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
  46.203 +    createInfo.pNext = NULL;
  46.204 +    createInfo.flags = 0;
  46.205 +    createInfo.pView = (__bridge void *)UIKit_Mtl_AddMetalView(window);
  46.206 +    result = vkCreateIOSSurfaceMVK(instance, &createInfo,
  46.207 +                                       NULL, surface);
  46.208 +    if(result != VK_SUCCESS)
  46.209 +    {
  46.210 +        SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
  46.211 +                     SDL_Vulkan_GetResultString(result));
  46.212 +        return SDL_FALSE;
  46.213 +    }
  46.214 +    return SDL_TRUE;
  46.215 +}
  46.216 +
  46.217 +void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
  46.218 +{
  46.219 +    UIKit_Mtl_GetDrawableSize(window, w, h);
  46.220 +}
  46.221 +
  46.222 +#endif
  46.223 +
  46.224 +/* vi: set ts=4 sw=4 expandtab: */
    47.1 --- a/src/video/wayland/SDL_waylandvideo.c	Sun Aug 27 19:10:30 2017 -0700
    47.2 +++ b/src/video/wayland/SDL_waylandvideo.c	Sun Aug 27 22:15:57 2017 -0400
    47.3 @@ -35,6 +35,7 @@
    47.4  #include "SDL_waylandmouse.h"
    47.5  #include "SDL_waylandtouch.h"
    47.6  #include "SDL_waylandclipboard.h"
    47.7 +#include "SDL_waylandvulkan.h"
    47.8  
    47.9  #include <sys/types.h>
   47.10  #include <unistd.h>
   47.11 @@ -181,6 +182,13 @@
   47.12      device->GetClipboardText = Wayland_GetClipboardText;
   47.13      device->HasClipboardText = Wayland_HasClipboardText;
   47.14  
   47.15 +#if SDL_VIDEO_VULKAN_SURFACE
   47.16 +    device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary;
   47.17 +    device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary;
   47.18 +    device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions;
   47.19 +    device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface;
   47.20 +#endif
   47.21 +
   47.22      device->free = Wayland_DeleteDevice;
   47.23  
   47.24      return device;
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/src/video/wayland/SDL_waylandvulkan.c	Sun Aug 27 22:15:57 2017 -0400
    48.3 @@ -0,0 +1,175 @@
    48.4 +/*
    48.5 +  Simple DirectMedia Layer
    48.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    48.7 +
    48.8 +  This software is provided 'as-is', without any express or implied
    48.9 +  warranty.  In no event will the authors be held liable for any damages
   48.10 +  arising from the use of this software.
   48.11 +
   48.12 +  Permission is granted to anyone to use this software for any purpose,
   48.13 +  including commercial applications, and to alter it and redistribute it
   48.14 +  freely, subject to the following restrictions:
   48.15 +
   48.16 +  1. The origin of this software must not be misrepresented; you must not
   48.17 +     claim that you wrote the original software. If you use this software
   48.18 +     in a product, an acknowledgment in the product documentation would be
   48.19 +     appreciated but is not required.
   48.20 +  2. Altered source versions must be plainly marked as such, and must not be
   48.21 +     misrepresented as being the original software.
   48.22 +  3. This notice may not be removed or altered from any source distribution.
   48.23 +*/
   48.24 +
   48.25 +/*
   48.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   48.27 + * SDL_x11vulkan.c.
   48.28 + */
   48.29 +
   48.30 +#include "../../SDL_internal.h"
   48.31 +
   48.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WAYLAND
   48.33 +
   48.34 +#include "SDL_waylandvideo.h"
   48.35 +#include "SDL_waylandwindow.h"
   48.36 +#include "SDL_assert.h"
   48.37 +
   48.38 +#include "SDL_loadso.h"
   48.39 +#include "SDL_waylandvulkan.h"
   48.40 +#include "SDL_syswm.h"
   48.41 +
   48.42 +int Wayland_Vulkan_LoadLibrary(_THIS, const char *path)
   48.43 +{
   48.44 +    VkExtensionProperties *extensions = NULL;
   48.45 +    Uint32 extensionCount = 0;
   48.46 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   48.47 +    SDL_bool hasWaylandSurfaceExtension = SDL_FALSE;
   48.48 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   48.49 +    if(_this->vulkan_config.loader_handle)
   48.50 +        return SDL_SetError("Vulkan already loaded");
   48.51 +
   48.52 +    /* Load the Vulkan loader library */
   48.53 +    if(!path)
   48.54 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   48.55 +    if(!path)
   48.56 +        path = "libvulkan.so.1";
   48.57 +    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   48.58 +    if(!_this->vulkan_config.loader_handle)
   48.59 +        return -1;
   48.60 +    SDL_strlcpy(_this->vulkan_config.loader_path, path,
   48.61 +                SDL_arraysize(_this->vulkan_config.loader_path));
   48.62 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   48.63 +        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   48.64 +    if(!vkGetInstanceProcAddr)
   48.65 +        goto fail;
   48.66 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
   48.67 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
   48.68 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
   48.69 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
   48.70 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
   48.71 +        goto fail;
   48.72 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
   48.73 +        (PFN_vkEnumerateInstanceExtensionProperties)
   48.74 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
   48.75 +        &extensionCount);
   48.76 +    if(!extensions)
   48.77 +        goto fail;
   48.78 +    for(Uint32 i = 0; i < extensionCount; i++)
   48.79 +    {
   48.80 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   48.81 +            hasSurfaceExtension = SDL_TRUE;
   48.82 +        else if(SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   48.83 +            hasWaylandSurfaceExtension = SDL_TRUE;
   48.84 +    }
   48.85 +    SDL_free(extensions);
   48.86 +    if(!hasSurfaceExtension)
   48.87 +    {
   48.88 +        SDL_SetError("Installed Vulkan doesn't implement the "
   48.89 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
   48.90 +        goto fail;
   48.91 +    }
   48.92 +    else if(!hasWaylandSurfaceExtension)
   48.93 +    {
   48.94 +        SDL_SetError("Installed Vulkan doesn't implement the "
   48.95 +                     VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension");
   48.96 +        goto fail;
   48.97 +    }
   48.98 +    return 0;
   48.99 +
  48.100 +fail:
  48.101 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  48.102 +    _this->vulkan_config.loader_handle = NULL;
  48.103 +    return -1;
  48.104 +}
  48.105 +
  48.106 +void Wayland_Vulkan_UnloadLibrary(_THIS)
  48.107 +{
  48.108 +    if(_this->vulkan_config.loader_handle)
  48.109 +    {
  48.110 +        SDL_UnloadObject(_this->vulkan_config.loader_handle);
  48.111 +        _this->vulkan_config.loader_handle = NULL;
  48.112 +    }
  48.113 +}
  48.114 +
  48.115 +SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
  48.116 +                                          SDL_Window *window,
  48.117 +                                          unsigned *count,
  48.118 +                                          const char **names)
  48.119 +{
  48.120 +    static const char *const extensionsForWayland[] = {
  48.121 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
  48.122 +    };
  48.123 +    if(!_this->vulkan_config.loader_handle)
  48.124 +    {
  48.125 +        SDL_SetError("Vulkan is not loaded");
  48.126 +        return SDL_FALSE;
  48.127 +    }
  48.128 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  48.129 +            count, names, SDL_arraysize(extensionsForWayland),
  48.130 +            extensionsForWayland);
  48.131 +}
  48.132 +
  48.133 +SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
  48.134 +                                  SDL_Window *window,
  48.135 +                                  VkInstance instance,
  48.136 +                                  VkSurfaceKHR *surface)
  48.137 +{
  48.138 +    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
  48.139 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  48.140 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  48.141 +    PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR =
  48.142 +        (PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr(
  48.143 +                                            (VkInstance)instance,
  48.144 +                                            "vkCreateWaylandSurfaceKHR");
  48.145 +    VkWaylandSurfaceCreateInfoKHR createInfo = {};
  48.146 +    VkResult result;
  48.147 +
  48.148 +    if(!_this->vulkan_config.loader_handle)
  48.149 +    {
  48.150 +        SDL_SetError("Vulkan is not loaded");
  48.151 +        return SDL_FALSE;
  48.152 +    }
  48.153 +
  48.154 +    if(!vkCreateWaylandSurfaceKHR)
  48.155 +    {
  48.156 +        SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
  48.157 +                     " extension is not enabled in the Vulkan instance.");
  48.158 +        return SDL_FALSE;
  48.159 +    }
  48.160 +    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
  48.161 +    createInfo.pNext = NULL;
  48.162 +    createInfo.flags = 0;
  48.163 +    createInfo.display = windowData->waylandData->display;
  48.164 +    createInfo.surface =  windowData->surface;
  48.165 +    result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
  48.166 +                                       NULL, surface);
  48.167 +    if(result != VK_SUCCESS)
  48.168 +    {
  48.169 +        SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
  48.170 +                     SDL_Vulkan_GetResultString(result));
  48.171 +        return SDL_FALSE;
  48.172 +    }
  48.173 +    return SDL_TRUE;
  48.174 +}
  48.175 +
  48.176 +#endif
  48.177 +
  48.178 +/* vim: set ts=4 sw=4 expandtab: */
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/src/video/wayland/SDL_waylandvulkan.h	Sun Aug 27 22:15:57 2017 -0400
    49.3 @@ -0,0 +1,52 @@
    49.4 +/*
    49.5 +  Simple DirectMedia Layer
    49.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    49.7 +
    49.8 +  This software is provided 'as-is', without any express or implied
    49.9 +  warranty.  In no event will the authors be held liable for any damages
   49.10 +  arising from the use of this software.
   49.11 +
   49.12 +  Permission is granted to anyone to use this software for any purpose,
   49.13 +  including commercial applications, and to alter it and redistribute it
   49.14 +  freely, subject to the following restrictions:
   49.15 +
   49.16 +  1. The origin of this software must not be misrepresented; you must not
   49.17 +     claim that you wrote the original software. If you use this software
   49.18 +     in a product, an acknowledgment in the product documentation would be
   49.19 +     appreciated but is not required.
   49.20 +  2. Altered source versions must be plainly marked as such, and must not be
   49.21 +     misrepresented as being the original software.
   49.22 +  3. This notice may not be removed or altered from any source distribution.
   49.23 +*/
   49.24 +
   49.25 +/*
   49.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   49.27 + * SDL_x11vulkan.h.
   49.28 + */
   49.29 +
   49.30 +#include "../../SDL_internal.h"
   49.31 +
   49.32 +#ifndef _SDL_waylandvulkan_h
   49.33 +#define _SDL_waylandvulkan_h
   49.34 +
   49.35 +#include "../SDL_vulkan_internal.h"
   49.36 +#include "../SDL_sysvideo.h"
   49.37 +
   49.38 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WAYLAND
   49.39 +
   49.40 +int Wayland_Vulkan_LoadLibrary(_THIS, const char *path);
   49.41 +void Wayland_Vulkan_UnloadLibrary(_THIS);
   49.42 +SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS,
   49.43 +                                          SDL_Window *window,
   49.44 +                                          unsigned *count,
   49.45 +                                          const char **names);
   49.46 +SDL_bool Wayland_Vulkan_CreateSurface(_THIS,
   49.47 +                                  SDL_Window *window,
   49.48 +                                  VkInstance instance,
   49.49 +                                  VkSurfaceKHR *surface);
   49.50 +
   49.51 +#endif
   49.52 +
   49.53 +#endif /* _SDL_waylandvulkan_h */
   49.54 +
   49.55 +/* vi: set ts=4 sw=4 expandtab: */
    50.1 --- a/src/video/windows/SDL_windowsvideo.c	Sun Aug 27 19:10:30 2017 -0700
    50.2 +++ b/src/video/windows/SDL_windowsvideo.c	Sun Aug 27 22:15:57 2017 -0400
    50.3 @@ -33,6 +33,7 @@
    50.4  #include "SDL_windowsvideo.h"
    50.5  #include "SDL_windowsframebuffer.h"
    50.6  #include "SDL_windowsshape.h"
    50.7 +#include "SDL_windowsvulkan.h"
    50.8  
    50.9  /* Initialization/Query functions */
   50.10  static int WIN_VideoInit(_THIS);
   50.11 @@ -190,6 +191,13 @@
   50.12      device->GL_SwapWindow = WIN_GLES_SwapWindow;
   50.13      device->GL_DeleteContext = WIN_GLES_DeleteContext;
   50.14  #endif
   50.15 +#if SDL_VIDEO_VULKAN_SURFACE
   50.16 +    device->Vulkan_LoadLibrary = WIN_Vulkan_LoadLibrary;
   50.17 +    device->Vulkan_UnloadLibrary = WIN_Vulkan_UnloadLibrary;
   50.18 +    device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions;
   50.19 +    device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface;
   50.20 +#endif
   50.21 +
   50.22      device->StartTextInput = WIN_StartTextInput;
   50.23      device->StopTextInput = WIN_StopTextInput;
   50.24      device->SetTextInputRect = WIN_SetTextInputRect;
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/src/video/windows/SDL_windowsvulkan.c	Sun Aug 27 22:15:57 2017 -0400
    51.3 @@ -0,0 +1,176 @@
    51.4 +/*
    51.5 +  Simple DirectMedia Layer
    51.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    51.7 +
    51.8 +  This software is provided 'as-is', without any express or implied
    51.9 +  warranty.  In no event will the authors be held liable for any damages
   51.10 +  arising from the use of this software.
   51.11 +
   51.12 +  Permission is granted to anyone to use this software for any purpose,
   51.13 +  including commercial applications, and to alter it and redistribute it
   51.14 +  freely, subject to the following restrictions:
   51.15 +
   51.16 +  1. The origin of this software must not be misrepresented; you must not
   51.17 +     claim that you wrote the original software. If you use this software
   51.18 +     in a product, an acknowledgment in the product documentation would be
   51.19 +     appreciated but is not required.
   51.20 +  2. Altered source versions must be plainly marked as such, and must not be
   51.21 +     misrepresented as being the original software.
   51.22 +  3. This notice may not be removed or altered from any source distribution.
   51.23 +*/
   51.24 +
   51.25 +/*
   51.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   51.27 + * SDL_x11vulkan.c.
   51.28 + */
   51.29 +
   51.30 +#include "../../SDL_internal.h"
   51.31 +
   51.32 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WINDOWS
   51.33 +
   51.34 +#include "SDL_windowsvideo.h"
   51.35 +#include "SDL_windowswindow.h"
   51.36 +#include "SDL_assert.h"
   51.37 +
   51.38 +#include "SDL_loadso.h"
   51.39 +#include "SDL_windowsvulkan.h"
   51.40 +#include "SDL_syswm.h"
   51.41 +
   51.42 +int WIN_Vulkan_LoadLibrary(_THIS, const char *path)
   51.43 +{
   51.44 +    VkExtensionProperties *extensions = NULL;
   51.45 +    Uint32 extensionCount = 0;
   51.46 +	Uint32 i;
   51.47 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   51.48 +    SDL_bool hasWin32SurfaceExtension = SDL_FALSE;
   51.49 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   51.50 +    if(_this->vulkan_config.loader_handle)
   51.51 +        return SDL_SetError("Vulkan already loaded");
   51.52 +
   51.53 +    /* Load the Vulkan loader library */
   51.54 +    if(!path)
   51.55 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   51.56 +    if(!path)
   51.57 +        path = "vulkan-1.dll";
   51.58 +    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   51.59 +    if(!_this->vulkan_config.loader_handle)
   51.60 +        return -1;
   51.61 +    SDL_strlcpy(_this->vulkan_config.loader_path, path,
   51.62 +                SDL_arraysize(_this->vulkan_config.loader_path));
   51.63 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   51.64 +        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   51.65 +    if(!vkGetInstanceProcAddr)
   51.66 +        goto fail;
   51.67 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
   51.68 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
   51.69 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
   51.70 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
   51.71 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
   51.72 +        goto fail;
   51.73 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
   51.74 +        (PFN_vkEnumerateInstanceExtensionProperties)
   51.75 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
   51.76 +        &extensionCount);
   51.77 +    if(!extensions)
   51.78 +        goto fail;
   51.79 +    for(i = 0; i < extensionCount; i++)
   51.80 +    {
   51.81 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   51.82 +            hasSurfaceExtension = SDL_TRUE;
   51.83 +        else if(SDL_strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   51.84 +            hasWin32SurfaceExtension = SDL_TRUE;
   51.85 +    }
   51.86 +    SDL_free(extensions);
   51.87 +    if(!hasSurfaceExtension)
   51.88 +    {
   51.89 +        SDL_SetError("Installed Vulkan doesn't implement the "
   51.90 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
   51.91 +        goto fail;
   51.92 +    }
   51.93 +    else if(!hasWin32SurfaceExtension)
   51.94 +    {
   51.95 +        SDL_SetError("Installed Vulkan doesn't implement the "
   51.96 +                     VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension");
   51.97 +        goto fail;
   51.98 +    }
   51.99 +    return 0;
  51.100 +
  51.101 +fail:
  51.102 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  51.103 +    _this->vulkan_config.loader_handle = NULL;
  51.104 +    return -1;
  51.105 +}
  51.106 +
  51.107 +void WIN_Vulkan_UnloadLibrary(_THIS)
  51.108 +{
  51.109 +    if(_this->vulkan_config.loader_handle)
  51.110 +    {
  51.111 +        SDL_UnloadObject(_this->vulkan_config.loader_handle);
  51.112 +        _this->vulkan_config.loader_handle = NULL;
  51.113 +    }
  51.114 +}
  51.115 +
  51.116 +SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
  51.117 +                                          SDL_Window *window,
  51.118 +                                          unsigned *count,
  51.119 +                                          const char **names)
  51.120 +{
  51.121 +    static const char *const extensionsForWin32[] = {
  51.122 +        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME
  51.123 +    };
  51.124 +    if(!_this->vulkan_config.loader_handle)
  51.125 +    {
  51.126 +        SDL_SetError("Vulkan is not loaded");
  51.127 +        return SDL_FALSE;
  51.128 +    }
  51.129 +    return SDL_Vulkan_GetInstanceExtensions_Helper(
  51.130 +            count, names, SDL_arraysize(extensionsForWin32),
  51.131 +            extensionsForWin32);
  51.132 +}
  51.133 +
  51.134 +SDL_bool WIN_Vulkan_CreateSurface(_THIS,
  51.135 +                                  SDL_Window *window,
  51.136 +                                  VkInstance instance,
  51.137 +                                  VkSurfaceKHR *surface)
  51.138 +{
  51.139 +    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
  51.140 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
  51.141 +        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  51.142 +    PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
  51.143 +        (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(
  51.144 +                                            (VkInstance)instance,
  51.145 +                                            "vkCreateWin32SurfaceKHR");
  51.146 +    VkWin32SurfaceCreateInfoKHR createInfo;
  51.147 +    VkResult result;
  51.148 +
  51.149 +    if(!_this->vulkan_config.loader_handle)
  51.150 +    {
  51.151 +        SDL_SetError("Vulkan is not loaded");
  51.152 +        return SDL_FALSE;
  51.153 +    }
  51.154 +
  51.155 +    if(!vkCreateWin32SurfaceKHR)
  51.156 +    {
  51.157 +        SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
  51.158 +                     " extension is not enabled in the Vulkan instance.");
  51.159 +        return SDL_FALSE;
  51.160 +    }
  51.161 +    createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
  51.162 +    createInfo.pNext = NULL;
  51.163 +    createInfo.flags = 0;
  51.164 +    createInfo.hinstance = windowData->hinstance;
  51.165 +    createInfo.hwnd = windowData->hwnd;
  51.166 +    result = vkCreateWin32SurfaceKHR(instance, &createInfo,
  51.167 +                                       NULL, surface);
  51.168 +    if(result != VK_SUCCESS)
  51.169 +    {
  51.170 +        SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
  51.171 +                     SDL_Vulkan_GetResultString(result));
  51.172 +        return SDL_FALSE;
  51.173 +    }
  51.174 +    return SDL_TRUE;
  51.175 +}
  51.176 +
  51.177 +#endif
  51.178 +
  51.179 +/* vi: set ts=4 sw=4 expandtab: */
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/src/video/windows/SDL_windowsvulkan.h	Sun Aug 27 22:15:57 2017 -0400
    52.3 @@ -0,0 +1,52 @@
    52.4 +/*
    52.5 +  Simple DirectMedia Layer
    52.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    52.7 +
    52.8 +  This software is provided 'as-is', without any express or implied
    52.9 +  warranty.  In no event will the authors be held liable for any damages
   52.10 +  arising from the use of this software.
   52.11 +
   52.12 +  Permission is granted to anyone to use this software for any purpose,
   52.13 +  including commercial applications, and to alter it and redistribute it
   52.14 +  freely, subject to the following restrictions:
   52.15 +
   52.16 +  1. The origin of this software must not be misrepresented; you must not
   52.17 +     claim that you wrote the original software. If you use this software
   52.18 +     in a product, an acknowledgment in the product documentation would be
   52.19 +     appreciated but is not required.
   52.20 +  2. Altered source versions must be plainly marked as such, and must not be
   52.21 +     misrepresented as being the original software.
   52.22 +  3. This notice may not be removed or altered from any source distribution.
   52.23 +*/
   52.24 +
   52.25 +/*
   52.26 + * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
   52.27 + * SDL_x11vulkan.h.
   52.28 + */
   52.29 +
   52.30 +#include "../../SDL_internal.h"
   52.31 +
   52.32 +#ifndef _SDL_windowsvulkan_h
   52.33 +#define _SDL_windowsvulkan_h
   52.34 +
   52.35 +#include "../SDL_vulkan_internal.h"
   52.36 +#include "../SDL_sysvideo.h"
   52.37 +
   52.38 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_WINDOWS
   52.39 +
   52.40 +int WIN_Vulkan_LoadLibrary(_THIS, const char *path);
   52.41 +void WIN_Vulkan_UnloadLibrary(_THIS);
   52.42 +SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS,
   52.43 +                                          SDL_Window *window,
   52.44 +                                          unsigned *count,
   52.45 +                                          const char **names);
   52.46 +SDL_bool WIN_Vulkan_CreateSurface(_THIS,
   52.47 +                                  SDL_Window *window,
   52.48 +                                  VkInstance instance,
   52.49 +                                  VkSurfaceKHR *surface);
   52.50 +
   52.51 +#endif
   52.52 +
   52.53 +#endif /* _SDL_windowsvulkan_h */
   52.54 +
   52.55 +/* vi: set ts=4 sw=4 expandtab: */
    53.1 --- a/src/video/x11/SDL_x11video.c	Sun Aug 27 19:10:30 2017 -0700
    53.2 +++ b/src/video/x11/SDL_x11video.c	Sun Aug 27 22:15:57 2017 -0400
    53.3 @@ -40,6 +40,8 @@
    53.4  #include "SDL_x11opengles.h"
    53.5  #endif
    53.6  
    53.7 +#include "SDL_x11vulkan.h"
    53.8 +
    53.9  /* Initialization/Query functions */
   53.10  static int X11_VideoInit(_THIS);
   53.11  static void X11_VideoQuit(_THIS);
   53.12 @@ -107,6 +109,9 @@
   53.13  X11_DeleteDevice(SDL_VideoDevice * device)
   53.14  {
   53.15      SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
   53.16 +    if (device->vulkan_config.loader_handle) {
   53.17 +        device->Vulkan_UnloadLibrary(device);
   53.18 +    }
   53.19      if (data->display) {
   53.20          X11_XCloseDisplay(data->display);
   53.21      }
   53.22 @@ -291,6 +296,13 @@
   53.23  
   53.24      device->free = X11_DeleteDevice;
   53.25  
   53.26 +#if SDL_VIDEO_VULKAN_SURFACE
   53.27 +    device->Vulkan_LoadLibrary = X11_Vulkan_LoadLibrary;
   53.28 +    device->Vulkan_UnloadLibrary = X11_Vulkan_UnloadLibrary;
   53.29 +    device->Vulkan_GetInstanceExtensions = X11_Vulkan_GetInstanceExtensions;
   53.30 +    device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface;
   53.31 +#endif
   53.32 +
   53.33      return device;
   53.34  }
   53.35  
    54.1 --- a/src/video/x11/SDL_x11video.h	Sun Aug 27 19:10:30 2017 -0700
    54.2 +++ b/src/video/x11/SDL_x11video.h	Sun Aug 27 22:15:57 2017 -0400
    54.3 @@ -68,6 +68,7 @@
    54.4  #include "SDL_x11mouse.h"
    54.5  #include "SDL_x11opengl.h"
    54.6  #include "SDL_x11window.h"
    54.7 +#include "SDL_x11vulkan.h"
    54.8  
    54.9  /* Private display data */
   54.10  
   54.11 @@ -140,6 +141,12 @@
   54.12      KeyCode filter_code;
   54.13      Time    filter_time;
   54.14  
   54.15 +#if SDL_VIDEO_VULKAN_SURFACE
   54.16 +    /* Vulkan variables only valid if _this->vulkan_config.loader_handle is not NULL */
   54.17 +    void *vulkan_xlib_xcb_library;
   54.18 +    PFN_XGetXCBConnection vulkan_XGetXCBConnection;
   54.19 +#endif
   54.20 +
   54.21  } SDL_VideoData;
   54.22  
   54.23  extern SDL_bool X11_UseDirectColorVisuals(void);
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/src/video/x11/SDL_x11vulkan.c	Sun Aug 27 22:15:57 2017 -0400
    55.3 @@ -0,0 +1,239 @@
    55.4 +/*
    55.5 +  Simple DirectMedia Layer
    55.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    55.7 +
    55.8 +  This software is provided 'as-is', without any express or implied
    55.9 +  warranty.  In no event will the authors be held liable for any damages
   55.10 +  arising from the use of this software.
   55.11 +
   55.12 +  Permission is granted to anyone to use this software for any purpose,
   55.13 +  including commercial applications, and to alter it and redistribute it
   55.14 +  freely, subject to the following restrictions:
   55.15 +
   55.16 +  1. The origin of this software must not be misrepresented; you must not
   55.17 +     claim that you wrote the original software. If you use this software
   55.18 +     in a product, an acknowledgment in the product documentation would be
   55.19 +     appreciated but is not required.
   55.20 +  2. Altered source versions must be plainly marked as such, and must not be
   55.21 +     misrepresented as being the original software.
   55.22 +  3. This notice may not be removed or altered from any source distribution.
   55.23 +*/
   55.24 +#include "../../SDL_internal.h"
   55.25 +
   55.26 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_X11
   55.27 +
   55.28 +#include "SDL_x11video.h"
   55.29 +#include "SDL_assert.h"
   55.30 +
   55.31 +#include "SDL_loadso.h"
   55.32 +#include "SDL_x11vulkan.h"
   55.33 +
   55.34 +#include <X11/Xlib.h>
   55.35 +//#include <xcb/xcb.h>
   55.36 +typedef uint32_t xcb_window_t;
   55.37 +typedef uint32_t xcb_visualid_t;
   55.38 +
   55.39 +int X11_Vulkan_LoadLibrary(_THIS, const char *path)
   55.40 +{
   55.41 +    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
   55.42 +    VkExtensionProperties *extensions = NULL;
   55.43 +    Uint32 extensionCount = 0;
   55.44 +    SDL_bool hasSurfaceExtension = SDL_FALSE;
   55.45 +    SDL_bool hasXlibSurfaceExtension = SDL_FALSE;
   55.46 +    SDL_bool hasXCBSurfaceExtension = SDL_FALSE;
   55.47 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   55.48 +    Uint32 i;
   55.49 +    if(_this->vulkan_config.loader_handle)
   55.50 +        return SDL_SetError("Vulkan already loaded");
   55.51 +
   55.52 +    /* Load the Vulkan loader library */
   55.53 +    if(!path)
   55.54 +        path = SDL_getenv("SDL_VULKAN_LIBRARY");
   55.55 +    if(!path)
   55.56 +        path = "libvulkan.so.1";
   55.57 +    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
   55.58 +    if(!_this->vulkan_config.loader_handle)
   55.59 +        return -1;
   55.60 +    SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path));
   55.61 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
   55.62 +        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
   55.63 +    if(!vkGetInstanceProcAddr)
   55.64 +        goto fail;
   55.65 +    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
   55.66 +    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
   55.67 +        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
   55.68 +            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
   55.69 +    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
   55.70 +        goto fail;
   55.71 +    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
   55.72 +        (PFN_vkEnumerateInstanceExtensionProperties)
   55.73 +            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
   55.74 +        &extensionCount);
   55.75 +    if(!extensions)
   55.76 +        goto fail;
   55.77 +    for(i = 0; i < extensionCount; i++)
   55.78 +    {
   55.79 +        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   55.80 +            hasSurfaceExtension = SDL_TRUE;
   55.81 +        else if(SDL_strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   55.82 +            hasXCBSurfaceExtension = SDL_TRUE;
   55.83 +        else if(SDL_strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
   55.84 +            hasXlibSurfaceExtension = SDL_TRUE;
   55.85 +    }
   55.86 +    SDL_free(extensions);
   55.87 +    if(!hasSurfaceExtension)
   55.88 +    {
   55.89 +        SDL_SetError("Installed Vulkan doesn't implement the "
   55.90 +                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
   55.91 +        goto fail;
   55.92 +    }
   55.93 +    if(hasXlibSurfaceExtension)
   55.94 +    {
   55.95 +        videoData->vulkan_xlib_xcb_library = NULL;
   55.96 +    }
   55.97 +    else if(!hasXCBSurfaceExtension)
   55.98 +    {
   55.99 +        SDL_SetError("Installed Vulkan doesn't implement either the "
  55.100 +                     VK_KHR_XCB_SURFACE_EXTENSION_NAME "extension or the "
  55.101 +                     VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension");
  55.102 +        goto fail;
  55.103 +    }
  55.104 +    else
  55.105 +    {
  55.106 +        const char *libX11XCBLibraryName = SDL_getenv("SDL_X11_XCB_LIBRARY");
  55.107 +        if(!libX11XCBLibraryName)
  55.108 +            libX11XCBLibraryName = "libX11-xcb.so";
  55.109 +        videoData->vulkan_xlib_xcb_library = SDL_LoadObject(libX11XCBLibraryName);
  55.110 +        if(!videoData->vulkan_xlib_xcb_library)
  55.111 +            goto fail;
  55.112 +        videoData->vulkan_XGetXCBConnection =
  55.113 +            SDL_LoadFunction(videoData->vulkan_xlib_xcb_library, "XGetXCBConnection");
  55.114 +        if(!videoData->vulkan_XGetXCBConnection)
  55.115 +        {
  55.116 +            SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
  55.117 +            goto fail;
  55.118 +        }
  55.119 +    }
  55.120 +    return 0;
  55.121 +
  55.122 +fail:
  55.123 +    SDL_UnloadObject(_this->vulkan_config.loader_handle);
  55.124 +    _this->vulkan_config.loader_handle = NULL;
  55.125 +    return -1;
  55.126 +}
  55.127 +
  55.128 +void X11_Vulkan_UnloadLibrary(_THIS)
  55.129 +{
  55.130 +    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
  55.131 +    if(_this->vulkan_config.loader_handle)
  55.132 +    {
  55.133 +        if(videoData->vulkan_xlib_xcb_library)
  55.134 +            SDL_UnloadObject(videoData->vulkan_xlib_xcb_library);
  55.135 +        SDL_UnloadObject(_this->vulkan_config.loader_handle);
  55.136 +        _this->vulkan_config.loader_handle = NULL;
  55.137 +    }
  55.138 +}
  55.139 +
  55.140 +SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
  55.141 +                                          SDL_Window *window,
  55.142 +                                          unsigned *count,
  55.143 +                                          const char **names)
  55.144 +{
  55.145 +    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
  55.146 +    if(!_this->vulkan_config.loader_handle)
  55.147 +    {
  55.148 +        SDL_SetError("Vulkan is not loaded");
  55.149 +        return SDL_FALSE;
  55.150 +    }
  55.151 +    if(videoData->vulkan_xlib_xcb_library)
  55.152 +    {
  55.153 +        static const char *const extensionsForXCB[] = {
  55.154 +            VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME,
  55.155 +        };
  55.156 +        return SDL_Vulkan_GetInstanceExtensions_Helper(
  55.157 +            count, names, SDL_arraysize(extensionsForXCB), extensionsForXCB);
  55.158 +    }
  55.159 +    else
  55.160 +    {
  55.161 +        static const char *const extensionsForXlib[] = {
  55.162 +            VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
  55.163 +        };
  55.164 +        return SDL_Vulkan_GetInstanceExtensions_Helper(
  55.165 +            count, names, SDL_arraysize(extensionsForXlib), extensionsForXlib);
  55.166 +    }
  55.167 +}
  55.168 +
  55.169 +SDL_bool X11_Vulkan_CreateSurface(_THIS,
  55.170 +                                  SDL_Window *window,
  55.171 +                                  VkInstance instance,
  55.172 +                                  VkSurfaceKHR *surface)
  55.173 +{
  55.174 +    SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata;
  55.175 +    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
  55.176 +    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
  55.177 +    if(!_this->vulkan_config.loader_handle)
  55.178 +    {
  55.179 +        SDL_SetError("Vulkan is not loaded");
  55.180 +        return SDL_FALSE;
  55.181 +    }
  55.182 +    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
  55.183 +    if(videoData->vulkan_xlib_xcb_library)
  55.184 +    {
  55.185 +        PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR =
  55.186 +            (PFN_vkCreateXcbSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
  55.187 +                                                             "vkCreateXcbSurfaceKHR");
  55.188 +        VkXcbSurfaceCreateInfoKHR createInfo = {};
  55.189 +        VkResult result;
  55.190 +        if(!vkCreateXcbSurfaceKHR)
  55.191 +        {
  55.192 +            SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME
  55.193 +                         " extension is not enabled in the Vulkan instance.");
  55.194 +            return SDL_FALSE;
  55.195 +        }
  55.196 +        createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
  55.197 +        createInfo.connection = videoData->vulkan_XGetXCBConnection(videoData->display);
  55.198 +        if(!createInfo.connection)
  55.199 +        {
  55.200 +            SDL_SetError("XGetXCBConnection failed");
  55.201 +            return SDL_FALSE;
  55.202 +        }
  55.203 +        createInfo.window = (xcb_window_t)windowData->xwindow;
  55.204 +        result = vkCreateXcbSurfaceKHR(instance, &createInfo,
  55.205 +                                       NULL, surface);
  55.206 +        if(result != VK_SUCCESS)
  55.207 +        {
  55.208 +            SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
  55.209 +            return SDL_FALSE;
  55.210 +        }
  55.211 +        return SDL_TRUE;
  55.212 +    }
  55.213 +    else
  55.214 +    {
  55.215 +        PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
  55.216 +            (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr((VkInstance)instance,
  55.217 +                                                              "vkCreateXlibSurfaceKHR");
  55.218 +        VkXlibSurfaceCreateInfoKHR createInfo = {};
  55.219 +        VkResult result;
  55.220 +        if(!vkCreateXlibSurfaceKHR)
  55.221 +        {
  55.222 +            SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME
  55.223 +                         " extension is not enabled in the Vulkan instance.");
  55.224 +            return SDL_FALSE;
  55.225 +        }
  55.226 +        createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
  55.227 +        createInfo.dpy = videoData->display;
  55.228 +        createInfo.window = (xcb_window_t)windowData->xwindow;
  55.229 +        result = vkCreateXlibSurfaceKHR(instance, &createInfo,
  55.230 +                                        NULL, surface);
  55.231 +        if(result != VK_SUCCESS)
  55.232 +        {
  55.233 +            SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
  55.234 +            return SDL_FALSE;
  55.235 +        }
  55.236 +        return SDL_TRUE;
  55.237 +    }
  55.238 +}
  55.239 +
  55.240 +#endif
  55.241 +
  55.242 +/* vim: set ts=4 sw=4 expandtab: */
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/src/video/x11/SDL_x11vulkan.h	Sun Aug 27 22:15:57 2017 -0400
    56.3 @@ -0,0 +1,48 @@
    56.4 +/*
    56.5 +  Simple DirectMedia Layer
    56.6 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    56.7 +
    56.8 +  This software is provided 'as-is', without any express or implied
    56.9 +  warranty.  In no event will the authors be held liable for any damages
   56.10 +  arising from the use of this software.
   56.11 +
   56.12 +  Permission is granted to anyone to use this software for any purpose,
   56.13 +  including commercial applications, and to alter it and redistribute it
   56.14 +  freely, subject to the following restrictions:
   56.15 +
   56.16 +  1. The origin of this software must not be misrepresented; you must not
   56.17 +     claim that you wrote the original software. If you use this software
   56.18 +     in a product, an acknowledgment in the product documentation would be
   56.19 +     appreciated but is not required.
   56.20 +  2. Altered source versions must be plainly marked as such, and must not be
   56.21 +     misrepresented as being the original software.
   56.22 +  3. This notice may not be removed or altered from any source distribution.
   56.23 +*/
   56.24 +#include "../../SDL_internal.h"
   56.25 +
   56.26 +#ifndef _SDL_x11vulkan_h
   56.27 +#define _SDL_x11vulkan_h
   56.28 +
   56.29 +#include "../SDL_vulkan_internal.h"
   56.30 +
   56.31 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_X11
   56.32 +
   56.33 +typedef struct xcb_connection_t xcb_connection_t;
   56.34 +typedef xcb_connection_t *(*PFN_XGetXCBConnection)(Display *dpy);
   56.35 +
   56.36 +int X11_Vulkan_LoadLibrary(_THIS, const char *path);
   56.37 +void X11_Vulkan_UnloadLibrary(_THIS);
   56.38 +SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS,
   56.39 +                                          SDL_Window *window,
   56.40 +                                          unsigned *count,
   56.41 +                                          const char **names);
   56.42 +SDL_bool X11_Vulkan_CreateSurface(_THIS,
   56.43 +                                  SDL_Window *window,
   56.44 +                                  VkInstance instance,
   56.45 +                                  VkSurfaceKHR *surface);
   56.46 +
   56.47 +#endif
   56.48 +
   56.49 +#endif /* _SDL_x11vulkan_h */
   56.50 +
   56.51 +/* vi: set ts=4 sw=4 expandtab: */
    57.1 --- a/test/Makefile.in	Sun Aug 27 19:10:30 2017 -0700
    57.2 +++ b/test/Makefile.in	Sun Aug 27 22:15:57 2017 -0400
    57.3 @@ -66,6 +66,7 @@
    57.4  	testdisplayinfo$(EXE) \
    57.5  	testqsort$(EXE) \
    57.6  	controllermap$(EXE) \
    57.7 +	testvulkan$(EXE) \
    57.8  	
    57.9  all: Makefile $(TARGETS) copydatafiles
   57.10  
   57.11 @@ -289,6 +290,9 @@
   57.12  controllermap$(EXE): $(srcdir)/controllermap.c
   57.13  	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
   57.14  
   57.15 +testvulkan$(EXE): $(srcdir)/testvulkan.c
   57.16 +	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
   57.17 +
   57.18  
   57.19  clean:
   57.20  	rm -f $(TARGETS)
    58.1 --- a/test/configure	Sun Aug 27 19:10:30 2017 -0700
    58.2 +++ b/test/configure	Sun Aug 27 22:15:57 2017 -0400
    58.3 @@ -195,7 +195,8 @@
    58.4    as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
    58.5    as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
    58.6    eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
    58.7 -  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
    58.8 +  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
    58.9 +test \$(( 1 + 1 )) = 2 || exit 1"
   58.10    if (eval "$as_required") 2>/dev/null; then :
   58.11    as_have_required=yes
   58.12  else
   58.13 @@ -582,9 +583,47 @@
   58.14  PACKAGE_URL=
   58.15  
   58.16  ac_unique_file="README"
   58.17 +# Factoring default headers for most tests.
   58.18 +ac_includes_default="\
   58.19 +#include <stdio.h>
   58.20 +#ifdef HAVE_SYS_TYPES_H
   58.21 +# include <sys/types.h>
   58.22 +#endif
   58.23 +#ifdef HAVE_SYS_STAT_H
   58.24 +# include <sys/stat.h>
   58.25 +#endif
   58.26 +#ifdef STDC_HEADERS
   58.27 +# include <stdlib.h>
   58.28 +# include <stddef.h>
   58.29 +#else
   58.30 +# ifdef HAVE_STDLIB_H
   58.31 +#  include <stdlib.h>
   58.32 +# endif
   58.33 +#endif
   58.34 +#ifdef HAVE_STRING_H
   58.35 +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
   58.36 +#  include <memory.h>
   58.37 +# endif
   58.38 +# include <string.h>
   58.39 +#endif
   58.40 +#ifdef HAVE_STRINGS_H
   58.41 +# include <strings.h>
   58.42 +#endif
   58.43 +#ifdef HAVE_INTTYPES_H
   58.44 +# include <inttypes.h>
   58.45 +#endif
   58.46 +#ifdef HAVE_STDINT_H
   58.47 +# include <stdint.h>
   58.48 +#endif
   58.49 +#ifdef HAVE_UNISTD_H
   58.50 +# include <unistd.h>
   58.51 +#endif"
   58.52 +
   58.53  ac_subst_vars='LTLIBOBJS
   58.54  LIBOBJS
   58.55  SDL_TTF_LIB
   58.56 +EGREP
   58.57 +GREP
   58.58  XLIB
   58.59  GLES2LIB
   58.60  GLESLIB
   58.61 @@ -637,6 +676,7 @@
   58.62  docdir
   58.63  oldincludedir
   58.64  includedir
   58.65 +runstatedir
   58.66  localstatedir
   58.67  sharedstatedir
   58.68  sysconfdir
   58.69 @@ -717,6 +757,7 @@
   58.70  sysconfdir='${prefix}/etc'
   58.71  sharedstatedir='${prefix}/com'
   58.72  localstatedir='${prefix}/var'
   58.73 +runstatedir='${localstatedir}/run'
   58.74  includedir='${prefix}/include'
   58.75  oldincludedir='/usr/include'
   58.76  docdir='${datarootdir}/doc/${PACKAGE}'
   58.77 @@ -969,6 +1010,15 @@
   58.78    | -silent | --silent | --silen | --sile | --sil)
   58.79      silent=yes ;;
   58.80  
   58.81 +  -runstatedir | --runstatedir | --runstatedi | --runstated \
   58.82 +  | --runstate | --runstat | --runsta | --runst | --runs \
   58.83 +  | --run | --ru | --r)
   58.84 +    ac_prev=runstatedir ;;
   58.85 +  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
   58.86 +  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
   58.87 +  | --run=* | --ru=* | --r=*)
   58.88 +    runstatedir=$ac_optarg ;;
   58.89 +
   58.90    -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
   58.91      ac_prev=sbindir ;;
   58.92    -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   58.93 @@ -1106,7 +1156,7 @@
   58.94  for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
   58.95  		datadir sysconfdir sharedstatedir localstatedir includedir \
   58.96  		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
   58.97 -		libdir localedir mandir
   58.98 +		libdir localedir mandir runstatedir
   58.99  do
  58.100    eval ac_val=\$$ac_var
  58.101    # Remove trailing slashes.
  58.102 @@ -1259,6 +1309,7 @@
  58.103    --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  58.104    --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  58.105    --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  58.106 +  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  58.107    --libdir=DIR            object code libraries [EPREFIX/lib]
  58.108    --includedir=DIR        C header files [PREFIX/include]
  58.109    --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  58.110 @@ -1563,6 +1614,124 @@
  58.111    as_fn_set_status $ac_retval
  58.112  
  58.113  } # ac_fn_c_try_cpp
  58.114 +
  58.115 +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
  58.116 +# -------------------------------------------------------
  58.117 +# Tests whether HEADER exists, giving a warning if it cannot be compiled using
  58.118 +# the include files in INCLUDES and setting the cache variable VAR
  58.119 +# accordingly.
  58.120 +ac_fn_c_check_header_mongrel ()
  58.121 +{
  58.122 +  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  58.123 +  if eval \${$3+:} false; then :
  58.124 +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
  58.125 +$as_echo_n "checking for $2... " >&6; }
  58.126 +if eval \${$3+:} false; then :
  58.127 +  $as_echo_n "(cached) " >&6
  58.128 +fi
  58.129 +eval ac_res=\$$3
  58.130 +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
  58.131 +$as_echo "$ac_res" >&6; }
  58.132 +else
  58.133 +  # Is the header compilable?
  58.134 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
  58.135 +$as_echo_n "checking $2 usability... " >&6; }
  58.136 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.137 +/* end confdefs.h.  */
  58.138 +$4
  58.139 +#include <$2>
  58.140 +_ACEOF
  58.141 +if ac_fn_c_try_compile "$LINENO"; then :
  58.142 +  ac_header_compiler=yes
  58.143 +else
  58.144 +  ac_header_compiler=no
  58.145 +fi
  58.146 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  58.147 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
  58.148 +$as_echo "$ac_header_compiler" >&6; }
  58.149 +
  58.150 +# Is the header present?
  58.151 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
  58.152 +$as_echo_n "checking $2 presence... " >&6; }
  58.153 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.154 +/* end confdefs.h.  */
  58.155 +#include <$2>
  58.156 +_ACEOF
  58.157 +if ac_fn_c_try_cpp "$LINENO"; then :
  58.158 +  ac_header_preproc=yes
  58.159 +else
  58.160 +  ac_header_preproc=no
  58.161 +fi
  58.162 +rm -f conftest.err conftest.i conftest.$ac_ext
  58.163 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
  58.164 +$as_echo "$ac_header_preproc" >&6; }
  58.165 +
  58.166 +# So?  What about this header?
  58.167 +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
  58.168 +  yes:no: )
  58.169 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
  58.170 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
  58.171 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
  58.172 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
  58.173 +    ;;
  58.174 +  no:yes:* )
  58.175 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
  58.176 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
  58.177 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
  58.178 +$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
  58.179 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
  58.180 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
  58.181 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
  58.182 +$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
  58.183 +    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
  58.184 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
  58.185 +    ;;
  58.186 +esac
  58.187 +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
  58.188 +$as_echo_n "checking for $2... " >&6; }
  58.189 +if eval \${$3+:} false; then :
  58.190 +  $as_echo_n "(cached) " >&6
  58.191 +else
  58.192 +  eval "$3=\$ac_header_compiler"
  58.193 +fi
  58.194 +eval ac_res=\$$3
  58.195 +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
  58.196 +$as_echo "$ac_res" >&6; }
  58.197 +fi
  58.198 +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  58.199 +
  58.200 +} # ac_fn_c_check_header_mongrel
  58.201 +
  58.202 +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
  58.203 +# -------------------------------------------------------
  58.204 +# Tests whether HEADER exists and can be compiled using the include files in
  58.205 +# INCLUDES, setting the cache variable VAR accordingly.
  58.206 +ac_fn_c_check_header_compile ()
  58.207 +{
  58.208 +  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
  58.209 +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
  58.210 +$as_echo_n "checking for $2... " >&6; }
  58.211 +if eval \${$3+:} false; then :
  58.212 +  $as_echo_n "(cached) " >&6
  58.213 +else
  58.214 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.215 +/* end confdefs.h.  */
  58.216 +$4
  58.217 +#include <$2>
  58.218 +_ACEOF
  58.219 +if ac_fn_c_try_compile "$LINENO"; then :
  58.220 +  eval "$3=yes"
  58.221 +else
  58.222 +  eval "$3=no"
  58.223 +fi
  58.224 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  58.225 +fi
  58.226 +eval ac_res=\$$3
  58.227 +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
  58.228 +$as_echo "$ac_res" >&6; }
  58.229 +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  58.230 +
  58.231 +} # ac_fn_c_check_header_compile
  58.232  cat >config.log <<_ACEOF
  58.233  This file contains any messages produced by compilers while
  58.234  running configure, to aid debugging if configure makes a mistake.
  58.235 @@ -3919,6 +4088,289 @@
  58.236  
  58.237  
  58.238  
  58.239 +have_vulkan_hdr=no
  58.240 +vsdk_include_dir="${VULKAN_SDK}/include"
  58.241 +vulkan_header="vulkan/vulkan.h"
  58.242 +save_CPPFLAGS="$CPPFLAGS"
  58.243 +CPPFLAGS="${save_CPPFLAGS} -I$vsdk_include_dir"
  58.244 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
  58.245 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
  58.246 +if ${ac_cv_path_GREP+:} false; then :
  58.247 +  $as_echo_n "(cached) " >&6
  58.248 +else
  58.249 +  if test -z "$GREP"; then
  58.250 +  ac_path_GREP_found=false
  58.251 +  # Loop through the user's path and test for each of PROGNAME-LIST
  58.252 +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
  58.253 +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
  58.254 +do
  58.255 +  IFS=$as_save_IFS
  58.256 +  test -z "$as_dir" && as_dir=.
  58.257 +    for ac_prog in grep ggrep; do
  58.258 +    for ac_exec_ext in '' $ac_executable_extensions; do
  58.259 +      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
  58.260 +      as_fn_executable_p "$ac_path_GREP" || continue
  58.261 +# Check for GNU ac_path_GREP and select it if it is found.
  58.262 +  # Check for GNU $ac_path_GREP
  58.263 +case `"$ac_path_GREP" --version 2>&1` in
  58.264 +*GNU*)
  58.265 +  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
  58.266 +*)
  58.267 +  ac_count=0
  58.268 +  $as_echo_n 0123456789 >"conftest.in"
  58.269 +  while :
  58.270 +  do
  58.271 +    cat "conftest.in" "conftest.in" >"conftest.tmp"
  58.272 +    mv "conftest.tmp" "conftest.in"
  58.273 +    cp "conftest.in" "conftest.nl"
  58.274 +    $as_echo 'GREP' >> "conftest.nl"
  58.275 +    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
  58.276 +    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
  58.277 +    as_fn_arith $ac_count + 1 && ac_count=$as_val
  58.278 +    if test $ac_count -gt ${ac_path_GREP_max-0}; then
  58.279 +      # Best one so far, save it but keep looking for a better one
  58.280 +      ac_cv_path_GREP="$ac_path_GREP"
  58.281 +      ac_path_GREP_max=$ac_count
  58.282 +    fi
  58.283 +    # 10*(2^10) chars as input seems more than enough
  58.284 +    test $ac_count -gt 10 && break
  58.285 +  done
  58.286 +  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
  58.287 +esac
  58.288 +
  58.289 +      $ac_path_GREP_found && break 3
  58.290 +    done
  58.291 +  done
  58.292 +  done
  58.293 +IFS=$as_save_IFS
  58.294 +  if test -z "$ac_cv_path_GREP"; then
  58.295 +    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  58.296 +  fi
  58.297 +else
  58.298 +  ac_cv_path_GREP=$GREP
  58.299 +fi
  58.300 +
  58.301 +fi
  58.302 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
  58.303 +$as_echo "$ac_cv_path_GREP" >&6; }
  58.304 + GREP="$ac_cv_path_GREP"
  58.305 +
  58.306 +
  58.307 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
  58.308 +$as_echo_n "checking for egrep... " >&6; }
  58.309 +if ${ac_cv_path_EGREP+:} false; then :
  58.310 +  $as_echo_n "(cached) " >&6
  58.311 +else
  58.312 +  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
  58.313 +   then ac_cv_path_EGREP="$GREP -E"
  58.314 +   else
  58.315 +     if test -z "$EGREP"; then
  58.316 +  ac_path_EGREP_found=false
  58.317 +  # Loop through the user's path and test for each of PROGNAME-LIST
  58.318 +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
  58.319 +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
  58.320 +do
  58.321 +  IFS=$as_save_IFS
  58.322 +  test -z "$as_dir" && as_dir=.
  58.323 +    for ac_prog in egrep; do
  58.324 +    for ac_exec_ext in '' $ac_executable_extensions; do
  58.325 +      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
  58.326 +      as_fn_executable_p "$ac_path_EGREP" || continue
  58.327 +# Check for GNU ac_path_EGREP and select it if it is found.
  58.328 +  # Check for GNU $ac_path_EGREP
  58.329 +case `"$ac_path_EGREP" --version 2>&1` in
  58.330 +*GNU*)
  58.331 +  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
  58.332 +*)
  58.333 +  ac_count=0
  58.334 +  $as_echo_n 0123456789 >"conftest.in"
  58.335 +  while :
  58.336 +  do
  58.337 +    cat "conftest.in" "conftest.in" >"conftest.tmp"
  58.338 +    mv "conftest.tmp" "conftest.in"
  58.339 +    cp "conftest.in" "conftest.nl"
  58.340 +    $as_echo 'EGREP' >> "conftest.nl"
  58.341 +    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
  58.342 +    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
  58.343 +    as_fn_arith $ac_count + 1 && ac_count=$as_val
  58.344 +    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
  58.345 +      # Best one so far, save it but keep looking for a better one
  58.346 +      ac_cv_path_EGREP="$ac_path_EGREP"
  58.347 +      ac_path_EGREP_max=$ac_count
  58.348 +    fi
  58.349 +    # 10*(2^10) chars as input seems more than enough
  58.350 +    test $ac_count -gt 10 && break
  58.351 +  done
  58.352 +  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
  58.353 +esac
  58.354 +
  58.355 +      $ac_path_EGREP_found && break 3
  58.356 +    done
  58.357 +  done
  58.358 +  done
  58.359 +IFS=$as_save_IFS
  58.360 +  if test -z "$ac_cv_path_EGREP"; then
  58.361 +    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
  58.362 +  fi
  58.363 +else
  58.364 +  ac_cv_path_EGREP=$EGREP
  58.365 +fi
  58.366 +
  58.367 +   fi
  58.368 +fi
  58.369 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
  58.370 +$as_echo "$ac_cv_path_EGREP" >&6; }
  58.371 + EGREP="$ac_cv_path_EGREP"
  58.372 +
  58.373 +
  58.374 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
  58.375 +$as_echo_n "checking for ANSI C header files... " >&6; }
  58.376 +if ${ac_cv_header_stdc+:} false; then :
  58.377 +  $as_echo_n "(cached) " >&6
  58.378 +else
  58.379 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.380 +/* end confdefs.h.  */
  58.381 +#include <stdlib.h>
  58.382 +#include <stdarg.h>
  58.383 +#include <string.h>
  58.384 +#include <float.h>
  58.385 +
  58.386 +int
  58.387 +main ()
  58.388 +{
  58.389 +
  58.390 +  ;
  58.391 +  return 0;
  58.392 +}
  58.393 +_ACEOF
  58.394 +if ac_fn_c_try_compile "$LINENO"; then :
  58.395 +  ac_cv_header_stdc=yes
  58.396 +else
  58.397 +  ac_cv_header_stdc=no
  58.398 +fi
  58.399 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
  58.400 +
  58.401 +if test $ac_cv_header_stdc = yes; then
  58.402 +  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
  58.403 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.404 +/* end confdefs.h.  */
  58.405 +#include <string.h>
  58.406 +
  58.407 +_ACEOF
  58.408 +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  58.409 +  $EGREP "memchr" >/dev/null 2>&1; then :
  58.410 +
  58.411 +else
  58.412 +  ac_cv_header_stdc=no
  58.413 +fi
  58.414 +rm -f conftest*
  58.415 +
  58.416 +fi
  58.417 +
  58.418 +if test $ac_cv_header_stdc = yes; then
  58.419 +  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
  58.420 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.421 +/* end confdefs.h.  */
  58.422 +#include <stdlib.h>
  58.423 +
  58.424 +_ACEOF
  58.425 +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  58.426 +  $EGREP "free" >/dev/null 2>&1; then :
  58.427 +
  58.428 +else
  58.429 +  ac_cv_header_stdc=no
  58.430 +fi
  58.431 +rm -f conftest*
  58.432 +
  58.433 +fi
  58.434 +
  58.435 +if test $ac_cv_header_stdc = yes; then
  58.436 +  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
  58.437 +  if test "$cross_compiling" = yes; then :
  58.438 +  :
  58.439 +else
  58.440 +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  58.441 +/* end confdefs.h.  */
  58.442 +#include <ctype.h>
  58.443 +#include <stdlib.h>
  58.444 +#if ((' ' & 0x0FF) == 0x020)
  58.445 +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
  58.446 +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
  58.447 +#else
  58.448 +# define ISLOWER(c) \
  58.449 +		   (('a' <= (c) && (c) <= 'i') \
  58.450 +		     || ('j' <= (c) && (c) <= 'r') \
  58.451 +		     || ('s' <= (c) && (c) <= 'z'))
  58.452 +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
  58.453 +#endif
  58.454 +
  58.455 +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
  58.456 +int
  58.457 +main ()
  58.458 +{
  58.459 +  int i;
  58.460 +  for (i = 0; i < 256; i++)
  58.461 +    if (XOR (islower (i), ISLOWER (i))
  58.462 +	|| toupper (i) != TOUPPER (i))
  58.463 +      return 2;
  58.464 +  return 0;
  58.465 +}
  58.466 +_ACEOF
  58.467 +if ac_fn_c_try_run "$LINENO"; then :
  58.468 +
  58.469 +else
  58.470 +  ac_cv_header_stdc=no
  58.471 +fi
  58.472 +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
  58.473 +  conftest.$ac_objext conftest.beam conftest.$ac_ext
  58.474 +fi
  58.475 +
  58.476 +fi
  58.477 +fi
  58.478 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
  58.479 +$as_echo "$ac_cv_header_stdc" >&6; }
  58.480 +if test $ac_cv_header_stdc = yes; then
  58.481 +
  58.482 +$as_echo "#define STDC_HEADERS 1" >>confdefs.h
  58.483 +
  58.484 +fi
  58.485 +
  58.486 +# On IRIX 5.3, sys/types and inttypes.h are conflicting.
  58.487 +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
  58.488 +		  inttypes.h stdint.h unistd.h
  58.489 +do :
  58.490 +  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
  58.491 +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
  58.492 +"
  58.493 +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
  58.494 +  cat >>confdefs.h <<_ACEOF
  58.495 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
  58.496 +_ACEOF
  58.497 +
  58.498 +fi
  58.499 +
  58.500 +done
  58.501 +
  58.502 +
  58.503 +as_ac_Header=`$as_echo "ac_cv_header_$vulkan_header" | $as_tr_sh`
  58.504 +ac_fn_c_check_header_mongrel "$LINENO" "$vulkan_header" "$as_ac_Header" "$ac_includes_default"
  58.505 +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
  58.506 +  have_vulkan_hdr=yes
  58.507 +else
  58.508 +  have_vulkan_hdr=no
  58.509 +fi
  58.510 +
  58.511 +
  58.512 +CPPFLAGS="$save_CPPFLAGS"
  58.513 +if test x$have_vulkan_hdr = xyes; then
  58.514 +    # vulkan.h has been found in either $VULKAN_SDK/include or along the
  58.515 +    # the standard include path. Unfortunately there seems no easy
  58.516 +    # way to find out which, so...
  58.517 +    if test -n "$VULKAN_SDK" -a -f "$vsdk_include_dir/$vulkan_header"; then
  58.518 +        CFLAGS="$CFLAGS -I$vsdk_include_dir"
  58.519 +    fi
  58.520 +fi
  58.521 +
  58.522  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TTF_Init in -lSDL2_ttf" >&5
  58.523  $as_echo_n "checking for TTF_Init in -lSDL2_ttf... " >&6; }
  58.524  if ${ac_cv_lib_SDL2_ttf_TTF_Init+:} false; then :
    59.1 --- a/test/configure.in	Sun Aug 27 19:10:30 2017 -0700
    59.2 +++ b/test/configure.in	Sun Aug 27 22:15:57 2017 -0400
    59.3 @@ -179,6 +179,25 @@
    59.4  AC_SUBST(GLES2LIB)
    59.5  AC_SUBST(XLIB)
    59.6  
    59.7 +dnl Check for Vulkan Header
    59.8 +have_vulkan_hdr=no
    59.9 +vsdk_include_dir="${VULKAN_SDK}/include"
   59.10 +vulkan_header="vulkan/vulkan.h"
   59.11 +save_CPPFLAGS="$CPPFLAGS"
   59.12 +CPPFLAGS="${save_CPPFLAGS} -I$vsdk_include_dir"
   59.13 +AC_CHECK_HEADER($vulkan_header,
   59.14 +                have_vulkan_hdr=yes,
   59.15 +                have_vulkan_hdr=no)
   59.16 +CPPFLAGS="$save_CPPFLAGS"
   59.17 +if test x$have_vulkan_hdr = xyes; then
   59.18 +    # vulkan.h has been found in either $VULKAN_SDK/include or along the
   59.19 +    # the standard include path. Unfortunately there seems no easy
   59.20 +    # way to find out which, so...
   59.21 +    if test -n "$VULKAN_SDK" -a -f "$vsdk_include_dir/$vulkan_header"; then 
   59.22 +        CFLAGS="$CFLAGS -I$vsdk_include_dir"
   59.23 +    fi
   59.24 +fi
   59.25 +
   59.26  dnl Check for SDL_ttf
   59.27  AC_CHECK_LIB(SDL2_ttf, TTF_Init, have_SDL_ttf=yes)
   59.28  if test x$have_SDL_ttf = xyes; then
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/test/testvulkan.c	Sun Aug 27 22:15:57 2017 -0400
    60.3 @@ -0,0 +1,1195 @@
    60.4 +/*
    60.5 +  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
    60.6 +
    60.7 +  This software is provided 'as-is', without any express or implied
    60.8 +  warranty.  In no event will the authors be held liable for any damages
    60.9 +  arising from the use of this software.
   60.10 +
   60.11 +  Permission is granted to anyone to use this software for any purpose,
   60.12 +  including commercial applications, and to alter it and redistribute it
   60.13 +  freely.
   60.14 +*/
   60.15 +#include <stdlib.h>
   60.16 +#include <stdio.h>
   60.17 +#include <string.h>
   60.18 +#include <math.h>
   60.19 +
   60.20 +#ifndef UINT64_MAX /* VS2008 */
   60.21 +#define UINT64_MAX 18446744073709551615
   60.22 +#endif
   60.23 +
   60.24 +#include "SDL_test_common.h"
   60.25 +
   60.26 +#if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
   60.27 +
   60.28 +int main(int argc, char *argv[])
   60.29 +{
   60.30 +    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Vulkan support on this system\n");
   60.31 +    return 1;
   60.32 +}
   60.33 +
   60.34 +#else
   60.35 +
   60.36 +#define VK_NO_PROTOTYPES
   60.37 +#include "vulkan/vulkan.h"
   60.38 +
   60.39 +#define VULKAN_FUNCTIONS()                                              \
   60.40 +    VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR)                       \
   60.41 +    VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers)                    \
   60.42 +    VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer)                        \
   60.43 +    VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage)                        \
   60.44 +    VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier)                        \
   60.45 +    VULKAN_DEVICE_FUNCTION(vkCreateCommandPool)                         \
   60.46 +    VULKAN_DEVICE_FUNCTION(vkCreateFence)                               \
   60.47 +    VULKAN_DEVICE_FUNCTION(vkCreateImageView)                           \
   60.48 +    VULKAN_DEVICE_FUNCTION(vkCreateSemaphore)                           \
   60.49 +    VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR)                        \
   60.50 +    VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool)                        \
   60.51 +    VULKAN_DEVICE_FUNCTION(vkDestroyDevice)                             \
   60.52 +    VULKAN_DEVICE_FUNCTION(vkDestroyFence)                              \
   60.53 +    VULKAN_DEVICE_FUNCTION(vkDestroyImageView)                          \
   60.54 +    VULKAN_DEVICE_FUNCTION(vkDestroySemaphore)                          \
   60.55 +    VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR)                       \
   60.56 +    VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle)                            \
   60.57 +    VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer)                          \
   60.58 +    VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers)                        \
   60.59 +    VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue)                            \
   60.60 +    VULKAN_DEVICE_FUNCTION(vkGetFenceStatus)                            \
   60.61 +    VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR)                     \
   60.62 +    VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR)                           \
   60.63 +    VULKAN_DEVICE_FUNCTION(vkQueueSubmit)                               \
   60.64 +    VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer)                        \
   60.65 +    VULKAN_DEVICE_FUNCTION(vkResetFences)                               \
   60.66 +    VULKAN_DEVICE_FUNCTION(vkWaitForFences)                             \
   60.67 +    VULKAN_GLOBAL_FUNCTION(vkCreateInstance)                            \
   60.68 +    VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)      \
   60.69 +    VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)          \
   60.70 +    VULKAN_INSTANCE_FUNCTION(vkCreateDevice)                            \
   60.71 +    VULKAN_INSTANCE_FUNCTION(vkDestroyInstance)                         \
   60.72 +    VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR)                       \
   60.73 +    VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)      \
   60.74 +    VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)                \
   60.75 +    VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr)                       \
   60.76 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)               \
   60.77 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)             \
   60.78 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)  \
   60.79 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
   60.80 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)      \
   60.81 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) \
   60.82 +    VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)
   60.83 +
   60.84 +#define VULKAN_DEVICE_FUNCTION(name) static PFN_##name name = NULL;
   60.85 +#define VULKAN_GLOBAL_FUNCTION(name) static PFN_##name name = NULL;
   60.86 +#define VULKAN_INSTANCE_FUNCTION(name) static PFN_##name name = NULL;
   60.87 +VULKAN_FUNCTIONS()
   60.88 +#undef VULKAN_DEVICE_FUNCTION
   60.89 +#undef VULKAN_GLOBAL_FUNCTION
   60.90 +#undef VULKAN_INSTANCE_FUNCTION
   60.91 +static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
   60.92 +
   60.93 +/* Based on the headers found in
   60.94 + * https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers
   60.95 + */
   60.96 +#if VK_HEADER_VERSION < 22
   60.97 +enum
   60.98 +{
   60.99 +    VK_ERROR_FRAGMENTED_POOL = -12,
  60.100 +};
  60.101 +#endif
  60.102 +#if VK_HEADER_VERSION < 38
  60.103 +enum {
  60.104 +    VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000
  60.105 +};
  60.106 +#endif
  60.107 +
  60.108 +static const char *getVulkanResultString(VkResult result)
  60.109 +{
  60.110 +    switch((int)result)
  60.111 +    {
  60.112 +    case VK_SUCCESS:
  60.113 +        return "VK_SUCCESS";
  60.114 +    case VK_NOT_READY:
  60.115 +        return "VK_NOT_READY";
  60.116 +    case VK_TIMEOUT:
  60.117 +        return "VK_TIMEOUT";
  60.118 +    case VK_EVENT_SET:
  60.119 +        return "VK_EVENT_SET";
  60.120 +    case VK_EVENT_RESET:
  60.121 +        return "VK_EVENT_RESET";
  60.122 +    case VK_INCOMPLETE:
  60.123 +        return "VK_INCOMPLETE";
  60.124 +    case VK_ERROR_OUT_OF_HOST_MEMORY:
  60.125 +        return "VK_ERROR_OUT_OF_HOST_MEMORY";
  60.126 +    case VK_ERROR_OUT_OF_DEVICE_MEMORY:
  60.127 +        return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
  60.128 +    case VK_ERROR_INITIALIZATION_FAILED:
  60.129 +        return "VK_ERROR_INITIALIZATION_FAILED";
  60.130 +    case VK_ERROR_DEVICE_LOST:
  60.131 +        return "VK_ERROR_DEVICE_LOST";
  60.132 +    case VK_ERROR_MEMORY_MAP_FAILED:
  60.133 +        return "VK_ERROR_MEMORY_MAP_FAILED";
  60.134 +    case VK_ERROR_LAYER_NOT_PRESENT:
  60.135 +        return "VK_ERROR_LAYER_NOT_PRESENT";
  60.136 +    case VK_ERROR_EXTENSION_NOT_PRESENT:
  60.137 +        return "VK_ERROR_EXTENSION_NOT_PRESENT";
  60.138 +    case VK_ERROR_FEATURE_NOT_PRESENT:
  60.139 +        return "VK_ERROR_FEATURE_NOT_PRESENT";
  60.140 +    case VK_ERROR_INCOMPATIBLE_DRIVER:
  60.141 +        return "VK_ERROR_INCOMPATIBLE_DRIVER";
  60.142 +    case VK_ERROR_TOO_MANY_OBJECTS:
  60.143 +        return "VK_ERROR_TOO_MANY_OBJECTS";
  60.144 +    case VK_ERROR_FORMAT_NOT_SUPPORTED:
  60.145 +        return "VK_ERROR_FORMAT_NOT_SUPPORTED";
  60.146 +    case VK_ERROR_FRAGMENTED_POOL:
  60.147 +        return "VK_ERROR_FRAGMENTED_POOL";
  60.148 +    case VK_ERROR_SURFACE_LOST_KHR:
  60.149 +        return "VK_ERROR_SURFACE_LOST_KHR";
  60.150 +    case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
  60.151 +        return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
  60.152 +    case VK_SUBOPTIMAL_KHR:
  60.153 +        return "VK_SUBOPTIMAL_KHR";
  60.154 +    case VK_ERROR_OUT_OF_DATE_KHR:
  60.155 +        return "VK_ERROR_OUT_OF_DATE_KHR";
  60.156 +    case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
  60.157 +        return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
  60.158 +    case VK_ERROR_VALIDATION_FAILED_EXT:
  60.159 +        return "VK_ERROR_VALIDATION_FAILED_EXT";
  60.160 +    case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
  60.161 +        return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
  60.162 +    case VK_ERROR_INVALID_SHADER_NV:
  60.163 +        return "VK_ERROR_INVALID_SHADER_NV";
  60.164 +    case VK_RESULT_MAX_ENUM:
  60.165 +    case VK_RESULT_RANGE_SIZE:
  60.166 +        break;
  60.167 +    }
  60.168 +    if(result < 0)
  60.169 +        return "VK_ERROR_<Unknown>";
  60.170 +    return "VK_<Unknown>";
  60.171 +}
  60.172 +
  60.173 +typedef struct VulkanContext
  60.174 +{
  60.175 +    VkInstance instance;
  60.176 +    VkDevice device;
  60.177 +    VkSurfaceKHR surface;
  60.178 +    VkSwapchainKHR swapchain;
  60.179 +    VkPhysicalDeviceProperties physicalDeviceProperties;
  60.180 +    VkPhysicalDeviceFeatures physicalDeviceFeatures;
  60.181 +    uint32_t graphicsQueueFamilyIndex;
  60.182 +    uint32_t presentQueueFamilyIndex;
  60.183 +    VkPhysicalDevice physicalDevice;
  60.184 +    VkQueue graphicsQueue;
  60.185 +    VkQueue presentQueue;
  60.186 +    VkSemaphore imageAvailableSemaphore;
  60.187 +    VkSemaphore renderingFinishedSemaphore;
  60.188 +    VkSurfaceCapabilitiesKHR surfaceCapabilities;
  60.189 +    VkSurfaceFormatKHR *surfaceFormats;
  60.190 +    uint32_t surfaceFormatsAllocatedCount;
  60.191 +    uint32_t surfaceFormatsCount;
  60.192 +    uint32_t swapchainDesiredImageCount;
  60.193 +    VkSurfaceFormatKHR surfaceFormat;
  60.194 +    VkExtent2D swapchainSize;
  60.195 +    VkCommandPool commandPool;
  60.196 +    uint32_t swapchainImageCount;
  60.197 +    VkImage *swapchainImages;
  60.198 +    VkCommandBuffer *commandBuffers;
  60.199 +    VkFence *fences;
  60.200 +} VulkanContext;
  60.201 +
  60.202 +static SDLTest_CommonState *state;
  60.203 +static VulkanContext vulkanContext = {0};
  60.204 +
  60.205 +static void shutdownVulkan(void);
  60.206 +
  60.207 +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
  60.208 +static void quit(int rc)
  60.209 +{
  60.210 +    shutdownVulkan();
  60.211 +    SDLTest_CommonQuit(state);
  60.212 +    exit(rc);
  60.213 +}
  60.214 +
  60.215 +static void loadGlobalFunctions(void)
  60.216 +{
  60.217 +    vkGetInstanceProcAddr = SDL_Vulkan_GetVkGetInstanceProcAddr();
  60.218 +    if(!vkGetInstanceProcAddr)
  60.219 +    {
  60.220 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.221 +                     "SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n",
  60.222 +                     SDL_GetError());
  60.223 +        quit(2);
  60.224 +    }
  60.225 +
  60.226 +#define VULKAN_DEVICE_FUNCTION(name)
  60.227 +#define VULKAN_GLOBAL_FUNCTION(name)                                                   \
  60.228 +    name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name);                   \
  60.229 +    if(!name)                                                                          \
  60.230 +    {                                                                                  \
  60.231 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                                     \
  60.232 +                     "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
  60.233 +        quit(2);                                                                       \
  60.234 +    }
  60.235 +#define VULKAN_INSTANCE_FUNCTION(name)
  60.236 +    VULKAN_FUNCTIONS()
  60.237 +#undef VULKAN_DEVICE_FUNCTION
  60.238 +#undef VULKAN_GLOBAL_FUNCTION
  60.239 +#undef VULKAN_INSTANCE_FUNCTION
  60.240 +}
  60.241 +
  60.242 +static void createInstance(void)
  60.243 +{
  60.244 +    VkApplicationInfo appInfo = {0};
  60.245 +    VkInstanceCreateInfo instanceCreateInfo = {0};
  60.246 +    const char **extensions = NULL;
  60.247 +    unsigned extensionCount = 0;
  60.248 +	VkResult result;
  60.249 +
  60.250 +
  60.251 +	appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  60.252 +    appInfo.apiVersion = VK_API_VERSION_1_0;
  60.253 +    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  60.254 +    instanceCreateInfo.pApplicationInfo = &appInfo;
  60.255 +    if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, NULL))
  60.256 +    {
  60.257 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.258 +                     "SDL_Vulkan_GetInstanceExtensions(): %s\n",
  60.259 +                     SDL_GetError());
  60.260 +        quit(2);
  60.261 +    }
  60.262 +    extensions = SDL_malloc(sizeof(const char *) * extensionCount);
  60.263 +    if(!extensions)
  60.264 +    {
  60.265 +        SDL_OutOfMemory();
  60.266 +        quit(2);
  60.267 +    }
  60.268 +    if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, extensions))
  60.269 +    {
  60.270 +        SDL_free((void*)extensions);
  60.271 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.272 +                     "SDL_Vulkan_GetInstanceExtensions(): %s\n",
  60.273 +                     SDL_GetError());
  60.274 +        quit(2);
  60.275 +    }
  60.276 +    instanceCreateInfo.enabledExtensionCount = extensionCount;
  60.277 +    instanceCreateInfo.ppEnabledExtensionNames = extensions;
  60.278 +    result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance);
  60.279 +    SDL_free((void*)extensions);
  60.280 +    if(result != VK_SUCCESS)
  60.281 +    {
  60.282 +        vulkanContext.instance = VK_NULL_HANDLE;
  60.283 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.284 +                     "vkCreateInstance(): %s\n",
  60.285 +                     getVulkanResultString(result));
  60.286 +        quit(2);
  60.287 +    }
  60.288 +}
  60.289 +
  60.290 +static void loadInstanceFunctions(void)
  60.291 +{
  60.292 +#define VULKAN_DEVICE_FUNCTION(name)
  60.293 +#define VULKAN_GLOBAL_FUNCTION(name)
  60.294 +#define VULKAN_INSTANCE_FUNCTION(name)                                           \
  60.295 +    name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name);     \
  60.296 +    if(!name)                                                                    \
  60.297 +    {                                                                            \
  60.298 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                               \
  60.299 +                     "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
  60.300 +        quit(2);                                                                 \
  60.301 +    }
  60.302 +    VULKAN_FUNCTIONS()
  60.303 +#undef VULKAN_DEVICE_FUNCTION
  60.304 +#undef VULKAN_GLOBAL_FUNCTION
  60.305 +#undef VULKAN_INSTANCE_FUNCTION
  60.306 +}
  60.307 +
  60.308 +static void createSurface(void)
  60.309 +{
  60.310 +    if(!SDL_Vulkan_CreateSurface(state->windows[0],
  60.311 +                                 vulkanContext.instance,
  60.312 +                                 &vulkanContext.surface))
  60.313 +    {
  60.314 +        vulkanContext.surface = VK_NULL_HANDLE;
  60.315 +        SDL_LogError(
  60.316 +            SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError());
  60.317 +        quit(2);
  60.318 +    }
  60.319 +}
  60.320 +
  60.321 +static void findPhysicalDevice(void)
  60.322 +{
  60.323 +    uint32_t physicalDeviceCount = 0;
  60.324 +	VkPhysicalDevice *physicalDevices;
  60.325 +	VkQueueFamilyProperties *queueFamiliesProperties = NULL;
  60.326 +    uint32_t queueFamiliesPropertiesAllocatedSize = 0;
  60.327 +    VkExtensionProperties *deviceExtensions = NULL;
  60.328 +    uint32_t deviceExtensionsAllocatedSize = 0;
  60.329 +	uint32_t physicalDeviceIndex;
  60.330 +
  60.331 +    VkResult result =
  60.332 +        vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL);
  60.333 +    if(result != VK_SUCCESS)
  60.334 +    {
  60.335 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.336 +                     "vkEnumeratePhysicalDevices(): %s\n",
  60.337 +                     getVulkanResultString(result));
  60.338 +        quit(2);
  60.339 +    }
  60.340 +    if(physicalDeviceCount == 0)
  60.341 +    {
  60.342 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.343 +                     "vkEnumeratePhysicalDevices(): no physical devices\n");
  60.344 +        quit(2);
  60.345 +    }
  60.346 +    physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
  60.347 +    if(!physicalDevices)
  60.348 +    {
  60.349 +        SDL_OutOfMemory();
  60.350 +        quit(2);
  60.351 +    }
  60.352 +    result =
  60.353 +        vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices);
  60.354 +    if(result != VK_SUCCESS)
  60.355 +    {
  60.356 +        SDL_free(physicalDevices);
  60.357 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.358 +                     "vkEnumeratePhysicalDevices(): %s\n",
  60.359 +                     getVulkanResultString(result));
  60.360 +        quit(2);
  60.361 +    }
  60.362 +    vulkanContext.physicalDevice = NULL;
  60.363 +    for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount;
  60.364 +        physicalDeviceIndex++)
  60.365 +    {
  60.366 +        uint32_t queueFamiliesCount = 0;
  60.367 +		uint32_t queueFamilyIndex;
  60.368 +        uint32_t deviceExtensionCount = 0;
  60.369 +		SDL_bool hasSwapchainExtension = SDL_FALSE;
  60.370 +		uint32_t i;
  60.371 +
  60.372 +
  60.373 +		VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
  60.374 +        vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties);
  60.375 +        if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1)
  60.376 +            continue;
  60.377 +        vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures);
  60.378 +        vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL);
  60.379 +        if(queueFamiliesCount == 0)
  60.380 +            continue;
  60.381 +        if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount)
  60.382 +        {
  60.383 +            SDL_free(queueFamiliesProperties);
  60.384 +            queueFamiliesPropertiesAllocatedSize = queueFamiliesCount;
  60.385 +            queueFamiliesProperties =
  60.386 +                SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize);
  60.387 +            if(!queueFamiliesProperties)
  60.388 +            {
  60.389 +                SDL_free(physicalDevices);
  60.390 +                SDL_free(deviceExtensions);
  60.391 +                SDL_OutOfMemory();
  60.392 +                quit(2);
  60.393 +            }
  60.394 +        }
  60.395 +        vkGetPhysicalDeviceQueueFamilyProperties(
  60.396 +            physicalDevice, &queueFamiliesCount, queueFamiliesProperties);
  60.397 +        vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount;
  60.398 +        vulkanContext.presentQueueFamilyIndex = queueFamiliesCount;
  60.399 +        for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount;
  60.400 +            queueFamilyIndex++)
  60.401 +        {
  60.402 +            VkBool32 supported = 0;
  60.403 +
  60.404 +			if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0)
  60.405 +                continue;
  60.406 +            if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
  60.407 +                vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex;
  60.408 +            result = vkGetPhysicalDeviceSurfaceSupportKHR(
  60.409 +                physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported);
  60.410 +            if(result != VK_SUCCESS)
  60.411 +            {
  60.412 +                SDL_free(physicalDevices);
  60.413 +                SDL_free(queueFamiliesProperties);
  60.414 +                SDL_free(deviceExtensions);
  60.415 +                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.416 +                             "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n",
  60.417 +                             getVulkanResultString(result));
  60.418 +                quit(2);
  60.419 +            }
  60.420 +            if(supported)
  60.421 +            {
  60.422 +                vulkanContext.presentQueueFamilyIndex = queueFamilyIndex;
  60.423 +                if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
  60.424 +                    break; // use this queue because it can present and do graphics
  60.425 +            }
  60.426 +        }
  60.427 +        if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found
  60.428 +            continue;
  60.429 +        if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found
  60.430 +            continue;
  60.431 +        result =
  60.432 +            vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL);
  60.433 +        if(result != VK_SUCCESS)
  60.434 +        {
  60.435 +            SDL_free(physicalDevices);
  60.436 +            SDL_free(queueFamiliesProperties);
  60.437 +            SDL_free(deviceExtensions);
  60.438 +            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.439 +                         "vkEnumerateDeviceExtensionProperties(): %s\n",
  60.440 +                         getVulkanResultString(result));
  60.441 +            quit(2);
  60.442 +        }
  60.443 +        if(deviceExtensionCount == 0)
  60.444 +            continue;
  60.445 +        if(deviceExtensionsAllocatedSize < deviceExtensionCount)
  60.446 +        {
  60.447 +            SDL_free(deviceExtensions);
  60.448 +            deviceExtensionsAllocatedSize = deviceExtensionCount;
  60.449 +            deviceExtensions =
  60.450 +                SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize);
  60.451 +            if(!deviceExtensions)
  60.452 +            {
  60.453 +                SDL_free(physicalDevices);
  60.454 +                SDL_free(queueFamiliesProperties);
  60.455 +                SDL_OutOfMemory();
  60.456 +                quit(2);
  60.457 +            }
  60.458 +        }
  60.459 +        result = vkEnumerateDeviceExtensionProperties(
  60.460 +            physicalDevice, NULL, &deviceExtensionCount, deviceExtensions);
  60.461 +        if(result != VK_SUCCESS)
  60.462 +        {
  60.463 +            SDL_free(physicalDevices);
  60.464 +            SDL_free(queueFamiliesProperties);
  60.465 +            SDL_free(deviceExtensions);
  60.466 +            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.467 +                         "vkEnumerateDeviceExtensionProperties(): %s\n",
  60.468 +                         getVulkanResultString(result));
  60.469 +            quit(2);
  60.470 +        }
  60.471 +        for(i = 0; i < deviceExtensionCount; i++)
  60.472 +        {
  60.473 +            if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
  60.474 +            {
  60.475 +                hasSwapchainExtension = SDL_TRUE;
  60.476 +                break;
  60.477 +            }
  60.478 +        }
  60.479 +        if(!hasSwapchainExtension)
  60.480 +            continue;
  60.481 +        vulkanContext.physicalDevice = physicalDevice;
  60.482 +        break;
  60.483 +    }
  60.484 +    SDL_free(physicalDevices);
  60.485 +    SDL_free(queueFamiliesProperties);
  60.486 +    SDL_free(deviceExtensions);
  60.487 +    if(!vulkanContext.physicalDevice)
  60.488 +    {
  60.489 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found");
  60.490 +        quit(2);
  60.491 +    }
  60.492 +}
  60.493 +
  60.494 +static void createDevice(void)
  60.495 +{
  60.496 +    VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {0};
  60.497 +    static const float queuePriority[] = {1.0f};
  60.498 +    VkDeviceCreateInfo deviceCreateInfo = {0};
  60.499 +    static const char *const deviceExtensionNames[] = {
  60.500 +        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
  60.501 +    };
  60.502 +	VkResult result;
  60.503 +
  60.504 +	deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  60.505 +    deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex;
  60.506 +    deviceQueueCreateInfo->queueCount = 1;
  60.507 +    deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0];
  60.508 +
  60.509 +    deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  60.510 +    deviceCreateInfo.queueCreateInfoCount = 1;
  60.511 +    deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
  60.512 +    deviceCreateInfo.pEnabledFeatures = NULL;
  60.513 +    deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames);
  60.514 +    deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;
  60.515 +    result = vkCreateDevice(
  60.516 +        vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device);
  60.517 +    if(result != VK_SUCCESS)
  60.518 +    {
  60.519 +        vulkanContext.device = VK_NULL_HANDLE;
  60.520 +        SDL_LogError(
  60.521 +            SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result));
  60.522 +        quit(2);
  60.523 +    }
  60.524 +}
  60.525 +
  60.526 +static void loadDeviceFunctions(void)
  60.527 +{
  60.528 +#define VULKAN_DEVICE_FUNCTION(name)                                         \
  60.529 +    name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name);     \
  60.530 +    if(!name)                                                                \
  60.531 +    {                                                                        \
  60.532 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,                           \
  60.533 +                     "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
  60.534 +        quit(2);                                                             \
  60.535 +    }
  60.536 +#define VULKAN_GLOBAL_FUNCTION(name)
  60.537 +#define VULKAN_INSTANCE_FUNCTION(name)
  60.538 +    VULKAN_FUNCTIONS()
  60.539 +#undef VULKAN_DEVICE_FUNCTION
  60.540 +#undef VULKAN_GLOBAL_FUNCTION
  60.541 +#undef VULKAN_INSTANCE_FUNCTION
  60.542 +}
  60.543 +
  60.544 +#undef VULKAN_FUNCTIONS
  60.545 +
  60.546 +static void getQueues(void)
  60.547 +{
  60.548 +    vkGetDeviceQueue(vulkanContext.device,
  60.549 +                     vulkanContext.graphicsQueueFamilyIndex,
  60.550 +                     0,
  60.551 +                     &vulkanContext.graphicsQueue);
  60.552 +    if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex)
  60.553 +        vkGetDeviceQueue(vulkanContext.device,
  60.554 +                         vulkanContext.presentQueueFamilyIndex,
  60.555 +                         0,
  60.556 +                         &vulkanContext.presentQueue);
  60.557 +    else
  60.558 +        vulkanContext.presentQueue = vulkanContext.graphicsQueue;
  60.559 +}
  60.560 +
  60.561 +static void createSemaphore(VkSemaphore *semaphore)
  60.562 +{
  60.563 +	VkResult result;
  60.564 +
  60.565 +    VkSemaphoreCreateInfo createInfo = {0};
  60.566 +    createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
  60.567 +    result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore);
  60.568 +    if(result != VK_SUCCESS)
  60.569 +    {
  60.570 +        *semaphore = VK_NULL_HANDLE;
  60.571 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.572 +                     "vkCreateSemaphore(): %s\n",
  60.573 +                     getVulkanResultString(result));
  60.574 +        quit(2);
  60.575 +    }
  60.576 +}
  60.577 +
  60.578 +static void createSemaphores(void)
  60.579 +{
  60.580 +    createSemaphore(&vulkanContext.imageAvailableSemaphore);
  60.581 +    createSemaphore(&vulkanContext.renderingFinishedSemaphore);
  60.582 +}
  60.583 +
  60.584 +static void getSurfaceCaps(void)
  60.585 +{
  60.586 +    VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
  60.587 +        vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities);
  60.588 +    if(result != VK_SUCCESS)
  60.589 +    {
  60.590 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.591 +                     "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n",
  60.592 +                     getVulkanResultString(result));
  60.593 +        quit(2);
  60.594 +    }
  60.595 +
  60.596 +    // check surface usage
  60.597 +    if(!(vulkanContext.surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
  60.598 +    {
  60.599 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.600 +                     "Vulkan surface doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT\n");
  60.601 +        quit(2);
  60.602 +    }
  60.603 +}
  60.604 +
  60.605 +static void getSurfaceFormats(void)
  60.606 +{
  60.607 +    VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
  60.608 +                                                           vulkanContext.surface,
  60.609 +                                                           &vulkanContext.surfaceFormatsCount,
  60.610 +                                                           NULL);
  60.611 +    if(result != VK_SUCCESS)
  60.612 +    {
  60.613 +        vulkanContext.surfaceFormatsCount = 0;
  60.614 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.615 +                     "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
  60.616 +                     getVulkanResultString(result));
  60.617 +        quit(2);
  60.618 +    }
  60.619 +    if(vulkanContext.surfaceFormatsCount > vulkanContext.surfaceFormatsAllocatedCount)
  60.620 +    {
  60.621 +        vulkanContext.surfaceFormatsAllocatedCount = vulkanContext.surfaceFormatsCount;
  60.622 +        SDL_free(vulkanContext.surfaceFormats);
  60.623 +        vulkanContext.surfaceFormats =
  60.624 +            SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext.surfaceFormatsAllocatedCount);
  60.625 +        if(!vulkanContext.surfaceFormats)
  60.626 +        {
  60.627 +            vulkanContext.surfaceFormatsCount = 0;
  60.628 +            SDL_OutOfMemory();
  60.629 +            quit(2);
  60.630 +        }
  60.631 +    }
  60.632 +    result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice,
  60.633 +                                                  vulkanContext.surface,
  60.634 +                                                  &vulkanContext.surfaceFormatsCount,
  60.635 +                                                  vulkanContext.surfaceFormats);
  60.636 +    if(result != VK_SUCCESS)
  60.637 +    {
  60.638 +        vulkanContext.surfaceFormatsCount = 0;
  60.639 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.640 +                     "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n",
  60.641 +                     getVulkanResultString(result));
  60.642 +        quit(2);
  60.643 +    }
  60.644 +}
  60.645 +
  60.646 +static void getSwapchainImages(void)
  60.647 +{
  60.648 +	VkResult result;
  60.649 +
  60.650 +    SDL_free(vulkanContext.swapchainImages);
  60.651 +    vulkanContext.swapchainImages = NULL;
  60.652 +    result = vkGetSwapchainImagesKHR(
  60.653 +        vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL);
  60.654 +    if(result != VK_SUCCESS)
  60.655 +    {
  60.656 +        vulkanContext.swapchainImageCount = 0;
  60.657 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.658 +                     "vkGetSwapchainImagesKHR(): %s\n",
  60.659 +                     getVulkanResultString(result));
  60.660 +        quit(2);
  60.661 +    }
  60.662 +    vulkanContext.swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext.swapchainImageCount);
  60.663 +    if(!vulkanContext.swapchainImages)
  60.664 +    {
  60.665 +        SDL_OutOfMemory();
  60.666 +        quit(2);
  60.667 +    }
  60.668 +    result = vkGetSwapchainImagesKHR(vulkanContext.device,
  60.669 +                                     vulkanContext.swapchain,
  60.670 +                                     &vulkanContext.swapchainImageCount,
  60.671 +                                     vulkanContext.swapchainImages);
  60.672 +    if(result != VK_SUCCESS)
  60.673 +    {
  60.674 +        SDL_free(vulkanContext.swapchainImages);
  60.675 +        vulkanContext.swapchainImages = NULL;
  60.676 +        vulkanContext.swapchainImageCount = 0;
  60.677 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.678 +                     "vkGetSwapchainImagesKHR(): %s\n",
  60.679 +                     getVulkanResultString(result));
  60.680 +        quit(2);
  60.681 +    }
  60.682 +}
  60.683 +
  60.684 +static SDL_bool createSwapchain(void)
  60.685 +{
  60.686 +	uint32_t i;
  60.687 +	int w, h;
  60.688 +	VkSwapchainCreateInfoKHR createInfo = {0};
  60.689 +	VkResult result;
  60.690 +
  60.691 +    // pick an image count
  60.692 +    vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.minImageCount + 1;
  60.693 +    if(vulkanContext.swapchainDesiredImageCount > vulkanContext.surfaceCapabilities.maxImageCount
  60.694 +       && vulkanContext.surfaceCapabilities.maxImageCount > 0)
  60.695 +        vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.maxImageCount;
  60.696 +
  60.697 +    // pick a format
  60.698 +    if(vulkanContext.surfaceFormatsCount == 1
  60.699 +       && vulkanContext.surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
  60.700 +    {
  60.701 +        // aren't any preferred formats, so we pick
  60.702 +        vulkanContext.surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
  60.703 +        vulkanContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM;
  60.704 +    }
  60.705 +    else
  60.706 +    {
  60.707 +        vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0];
  60.708 +        for(i = 0; i < vulkanContext.surfaceFormatsCount; i++)
  60.709 +        {
  60.710 +            if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM)
  60.711 +            {
  60.712 +                vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i];
  60.713 +                break;
  60.714 +            }
  60.715 +        }
  60.716 +    }
  60.717 +
  60.718 +    // get size
  60.719 +    SDL_GL_GetDrawableSize(state->windows[0], &w, &h);
  60.720 +    vulkanContext.swapchainSize.width = w;
  60.721 +    vulkanContext.swapchainSize.height = h;
  60.722 +    if(w == 0 || h == 0)
  60.723 +        return SDL_FALSE;
  60.724 +
  60.725 +    createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  60.726 +    createInfo.surface = vulkanContext.surface;
  60.727 +    createInfo.minImageCount = vulkanContext.swapchainDesiredImageCount;
  60.728 +    createInfo.imageFormat = vulkanContext.surfaceFormat.format;
  60.729 +    createInfo.imageColorSpace = vulkanContext.surfaceFormat.colorSpace;
  60.730 +    createInfo.imageExtent = vulkanContext.swapchainSize;
  60.731 +    createInfo.imageArrayLayers = 1;
  60.732 +    createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
  60.733 +    createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
  60.734 +    createInfo.preTransform = vulkanContext.surfaceCapabilities.currentTransform;
  60.735 +    createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  60.736 +    createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
  60.737 +    createInfo.clipped = VK_TRUE;
  60.738 +    createInfo.oldSwapchain = vulkanContext.swapchain;
  60.739 +    result =
  60.740 +        vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain);
  60.741 +    if(createInfo.oldSwapchain)
  60.742 +        vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL);
  60.743 +    if(result != VK_SUCCESS)
  60.744 +    {
  60.745 +        vulkanContext.swapchain = VK_NULL_HANDLE;
  60.746 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.747 +                     "vkCreateSwapchainKHR(): %s\n",
  60.748 +                     getVulkanResultString(result));
  60.749 +        quit(2);
  60.750 +    }
  60.751 +    getSwapchainImages();
  60.752 +    return SDL_TRUE;
  60.753 +}
  60.754 +
  60.755 +static void destroySwapchain(void)
  60.756 +{
  60.757 +    if(vulkanContext.swapchain)
  60.758 +        vkDestroySwapchainKHR(vulkanContext.device, vulkanContext.swapchain, NULL);
  60.759 +    vulkanContext.swapchain = VK_NULL_HANDLE;
  60.760 +    SDL_free(vulkanContext.swapchainImages);
  60.761 +    vulkanContext.swapchainImages = NULL;
  60.762 +}
  60.763 +
  60.764 +static void destroyCommandBuffers(void)
  60.765 +{
  60.766 +    if(vulkanContext.commandBuffers)
  60.767 +        vkFreeCommandBuffers(vulkanContext.device,
  60.768 +                             vulkanContext.commandPool,
  60.769 +                             vulkanContext.swapchainImageCount,
  60.770 +                             vulkanContext.commandBuffers);
  60.771 +    SDL_free(vulkanContext.commandBuffers);
  60.772 +    vulkanContext.commandBuffers = NULL;
  60.773 +}
  60.774 +
  60.775 +static void destroyCommandPool(void)
  60.776 +{
  60.777 +    if(vulkanContext.commandPool)
  60.778 +        vkDestroyCommandPool(vulkanContext.device, vulkanContext.commandPool, NULL);
  60.779 +    vulkanContext.commandPool = VK_NULL_HANDLE;
  60.780 +}
  60.781 +
  60.782 +static void createCommandPool(void)
  60.783 +{
  60.784 +	VkResult result;
  60.785 +
  60.786 +    VkCommandPoolCreateInfo createInfo = {0};
  60.787 +    createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
  60.788 +    createInfo.flags =
  60.789 +        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
  60.790 +    createInfo.queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex;
  60.791 +    result =
  60.792 +        vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool);
  60.793 +    if(result != VK_SUCCESS)
  60.794 +    {
  60.795 +        vulkanContext.commandPool = VK_NULL_HANDLE;
  60.796 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.797 +                     "vkCreateCommandPool(): %s\n",
  60.798 +                     getVulkanResultString(result));
  60.799 +        quit(2);
  60.800 +    }
  60.801 +}
  60.802 +
  60.803 +static void createCommandBuffers(void)
  60.804 +{
  60.805 +	VkResult result;
  60.806 +
  60.807 +    VkCommandBufferAllocateInfo allocateInfo = {0};
  60.808 +    allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  60.809 +    allocateInfo.commandPool = vulkanContext.commandPool;
  60.810 +    allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  60.811 +    allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount;
  60.812 +    vulkanContext.commandBuffers =
  60.813 +        SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount);
  60.814 +    result =
  60.815 +        vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers);
  60.816 +    if(result != VK_SUCCESS)
  60.817 +    {
  60.818 +        SDL_free(vulkanContext.commandBuffers);
  60.819 +        vulkanContext.commandBuffers = NULL;
  60.820 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.821 +                     "vkAllocateCommandBuffers(): %s\n",
  60.822 +                     getVulkanResultString(result));
  60.823 +        quit(2);
  60.824 +    }
  60.825 +}
  60.826 +
  60.827 +static void createFences(void)
  60.828 +{
  60.829 +	uint32_t i;
  60.830 +
  60.831 +    vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount);
  60.832 +    if(!vulkanContext.fences)
  60.833 +    {
  60.834 +        SDL_OutOfMemory();
  60.835 +        quit(2);
  60.836 +    }
  60.837 +    for(i = 0; i < vulkanContext.swapchainImageCount; i++)
  60.838 +    {
  60.839 +		VkResult result;
  60.840 +
  60.841 +        VkFenceCreateInfo createInfo = {0};
  60.842 +        createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
  60.843 +        createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
  60.844 +        result =
  60.845 +            vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]);
  60.846 +        if(result != VK_SUCCESS)
  60.847 +        {
  60.848 +            for(; i > 0; i--)
  60.849 +            {
  60.850 +                vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL);
  60.851 +            }
  60.852 +            SDL_free(vulkanContext.fences);
  60.853 +            vulkanContext.fences = NULL;
  60.854 +            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.855 +                         "vkCreateFence(): %s\n",
  60.856 +                         getVulkanResultString(result));
  60.857 +            quit(2);
  60.858 +        }
  60.859 +    }
  60.860 +}
  60.861 +
  60.862 +static void destroyFences(void)
  60.863 +{
  60.864 +	uint32_t i;
  60.865 +
  60.866 +    if(!vulkanContext.fences)
  60.867 +        return;
  60.868 +    for(i = 0; i < vulkanContext.swapchainImageCount; i++)
  60.869 +    {
  60.870 +        vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL);
  60.871 +    }
  60.872 +    SDL_free(vulkanContext.fences);
  60.873 +    vulkanContext.fences = NULL;
  60.874 +}
  60.875 +
  60.876 +static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer,
  60.877 +                                       VkAccessFlags sourceAccessMask,
  60.878 +                                       VkAccessFlags destAccessMask,
  60.879 +                                       VkImageLayout sourceLayout,
  60.880 +                                       VkImageLayout destLayout,
  60.881 +                                       VkImage image)
  60.882 +{
  60.883 +    VkImageMemoryBarrier barrier = {0};
  60.884 +    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  60.885 +    barrier.srcAccessMask = sourceAccessMask;
  60.886 +    barrier.dstAccessMask = destAccessMask;
  60.887 +    barrier.oldLayout = sourceLayout;
  60.888 +    barrier.newLayout = destLayout;
  60.889 +    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  60.890 +    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  60.891 +    barrier.image = image;
  60.892 +    barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  60.893 +    barrier.subresourceRange.baseMipLevel = 0;
  60.894 +    barrier.subresourceRange.levelCount = 1;
  60.895 +    barrier.subresourceRange.baseArrayLayer = 0;
  60.896 +    barrier.subresourceRange.layerCount = 1;
  60.897 +    vkCmdPipelineBarrier(commandBuffer,
  60.898 +                         VK_PIPELINE_STAGE_TRANSFER_BIT,
  60.899 +                         VK_PIPELINE_STAGE_TRANSFER_BIT,
  60.900 +                         0,
  60.901 +                         0,
  60.902 +                         NULL,
  60.903 +                         0,
  60.904 +                         NULL,
  60.905 +                         1,
  60.906 +                         &barrier);
  60.907 +}
  60.908 +
  60.909 +static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor)
  60.910 +{
  60.911 +    VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex];
  60.912 +    VkImage image = vulkanContext.swapchainImages[frameIndex];
  60.913 +	VkCommandBufferBeginInfo beginInfo = {0};
  60.914 +    VkImageSubresourceRange clearRange = {0};
  60.915 +
  60.916 +    VkResult result = vkResetCommandBuffer(commandBuffer, 0);
  60.917 +    if(result != VK_SUCCESS)
  60.918 +    {
  60.919 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.920 +                     "vkResetCommandBuffer(): %s\n",
  60.921 +                     getVulkanResultString(result));
  60.922 +        quit(2);
  60.923 +    }
  60.924 +    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  60.925 +    beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
  60.926 +    result = vkBeginCommandBuffer(commandBuffer, &beginInfo);
  60.927 +    if(result != VK_SUCCESS)
  60.928 +    {
  60.929 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.930 +                     "vkBeginCommandBuffer(): %s\n",
  60.931 +                     getVulkanResultString(result));
  60.932 +        quit(2);
  60.933 +    }
  60.934 +    recordPipelineImageBarrier(commandBuffer,
  60.935 +                               0,
  60.936 +                               VK_ACCESS_TRANSFER_WRITE_BIT,
  60.937 +                               VK_IMAGE_LAYOUT_UNDEFINED,
  60.938 +                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
  60.939 +                               image);
  60.940 +    clearRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  60.941 +    clearRange.baseMipLevel = 0;
  60.942 +    clearRange.levelCount = 1;
  60.943 +    clearRange.baseArrayLayer = 0;
  60.944 +    clearRange.layerCount = 1;
  60.945 +    vkCmdClearColorImage(
  60.946 +        commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange);
  60.947 +    recordPipelineImageBarrier(commandBuffer,
  60.948 +                               VK_ACCESS_TRANSFER_WRITE_BIT,
  60.949 +                               VK_ACCESS_MEMORY_READ_BIT,
  60.950 +                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
  60.951 +                               VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
  60.952 +                               image);
  60.953 +    result = vkEndCommandBuffer(commandBuffer);
  60.954 +    if(result != VK_SUCCESS)
  60.955 +    {
  60.956 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
  60.957 +                     "vkEndCommandBuffer(): %s\n",
  60.958 +                     getVulkanResultString(result));
  60.959 +        quit(2);
  60.960 +    }
  60.961 +}
  60.962 +
  60.963 +static void destroySwapchainAndSwapchainSpecificStuff(SDL_bool doDestroySwapchain)
  60.964 +{
  60.965 +    destroyFences();
  60.966 +    destroyCommandBuffers();
  60.967 +    destroyCommandPool();
  60.968 +    if(doDestroySwapchain)
  60.969 +        destroySwapchain();
  60.970 +}
  60.971 +
  60.972 +static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void)
  60.973 +{
  60.974 +    destroySwapchainAndSwapchainSpecificStuff(SDL_FALSE);
  60.975 +    getSurfaceCaps();
  60.976 +    getSurfaceFormats();
  60.977 +    if(!createSwapchain())
  60.978 +        return SDL_FALSE;
  60.979 +    createCommandPool();
  60.980 +    createCommandBuffers();
  60.981 +    createFences();
  60.982 +    return SDL_TRUE;
  60.983 +}
  60.984 +
  60.985 +static void initVulkan(void)
  60.986 +{
  60.987 +    SDL_Vulkan_LoadLibrary(NULL);
  60.988 +    SDL_memset(&vulkanContext, 0, sizeof(VulkanContext));
  60.989 +    loadGlobalFunctions();
  60.990 +    createInstance();
  60.991 +    loadInstanceFunctions();
  60.992 +    createSurface();
  60.993 +    findPhysicalDevice();
  60.994 +    createDevice();
  60.995 +    loadDeviceFunctions();
  60.996 +    getQueues();
  60.997 +    createSemaphores();
  60.998 +    createNewSwapchainAndSwapchainSpecificStuff();
  60.999 +}
 60.1000 +
 60.1001 +static void shutdownVulkan(void)
 60.1002 +{
 60.1003 +    if(vulkanContext.device && vkDeviceWaitIdle)
 60.1004 +        vkDeviceWaitIdle(vulkanContext.device);
 60.1005 +    destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE);
 60.1006 +    if(vulkanContext.imageAvailableSemaphore && vkDestroySemaphore)
 60.1007 +        vkDestroySemaphore(vulkanContext.device, vulkanContext.imageAvailableSemaphore, NULL);
 60.1008 +    if(vulkanContext.renderingFinishedSemaphore && vkDestroySemaphore)
 60.1009 +        vkDestroySemaphore(vulkanContext.device, vulkanContext.renderingFinishedSemaphore, NULL);
 60.1010 +    if(vulkanContext.device && vkDestroyDevice)
 60.1011 +        vkDestroyDevice(vulkanContext.device, NULL);
 60.1012 +    if(vulkanContext.surface && vkDestroySurfaceKHR)
 60.1013 +        vkDestroySurfaceKHR(vulkanContext.instance, vulkanContext.surface, NULL);
 60.1014 +    if(vulkanContext.instance && vkDestroyInstance)
 60.1015 +        vkDestroyInstance(vulkanContext.instance, NULL);
 60.1016 +    SDL_free(vulkanContext.surfaceFormats);
 60.1017 +    SDL_Vulkan_UnloadLibrary();
 60.1018 +}
 60.1019 +
 60.1020 +static SDL_bool render(void)
 60.1021 +{
 60.1022 +    uint32_t frameIndex;
 60.1023 +    VkResult result;
 60.1024 +    double currentTime;
 60.1025 +    VkClearColorValue clearColor = {0};
 60.1026 +    VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
 60.1027 +    VkSubmitInfo submitInfo = {0};
 60.1028 +    VkPresentInfoKHR presentInfo = {0};
 60.1029 +    int w, h;
 60.1030 +
 60.1031 +    if(!vulkanContext.swapchain)
 60.1032 +    {
 60.1033 +        SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff();
 60.1034 +        if(!retval)
 60.1035 +            SDL_Delay(100);
 60.1036 +        return retval;
 60.1037 +    }
 60.1038 +    result = vkAcquireNextImageKHR(vulkanContext.device,
 60.1039 +                                            vulkanContext.swapchain,
 60.1040 +                                            UINT64_MAX,
 60.1041 +                                            vulkanContext.imageAvailableSemaphore,
 60.1042 +                                            VK_NULL_HANDLE,
 60.1043 +                                            &frameIndex);
 60.1044 +    if(result == VK_ERROR_OUT_OF_DATE_KHR)
 60.1045 +        return createNewSwapchainAndSwapchainSpecificStuff();
 60.1046 +    if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS)
 60.1047 +    {
 60.1048 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
 60.1049 +                     "vkAcquireNextImageKHR(): %s\n",
 60.1050 +                     getVulkanResultString(result));
 60.1051 +        quit(2);
 60.1052 +    }
 60.1053 +    result = vkWaitForFences(
 60.1054 +        vulkanContext.device, 1, &vulkanContext.fences[frameIndex], VK_FALSE, UINT64_MAX);
 60.1055 +    if(result != VK_SUCCESS)
 60.1056 +    {
 60.1057 +        SDL_LogError(
 60.1058 +            SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result));
 60.1059 +        quit(2);
 60.1060 +    }
 60.1061 +    result = vkResetFences(vulkanContext.device, 1, &vulkanContext.fences[frameIndex]);
 60.1062 +    if(result != VK_SUCCESS)
 60.1063 +    {
 60.1064 +        SDL_LogError(
 60.1065 +            SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result));
 60.1066 +        quit(2);
 60.1067 +    }
 60.1068 +    currentTime = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency();
 60.1069 +    clearColor.float32[0] = (float)(0.5 + 0.5 * SDL_sin(currentTime));
 60.1070 +    clearColor.float32[1] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 2 / 3));
 60.1071 +    clearColor.float32[2] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 4 / 3));
 60.1072 +    clearColor.float32[3] = 1;
 60.1073 +    rerecordCommandBuffer(frameIndex, &clearColor);
 60.1074 +    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
 60.1075 +    submitInfo.waitSemaphoreCount = 1;
 60.1076 +    submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore;
 60.1077 +    submitInfo.pWaitDstStageMask = &waitDestStageMask;
 60.1078 +    submitInfo.commandBufferCount = 1;
 60.1079 +    submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex];
 60.1080 +    submitInfo.signalSemaphoreCount = 1;
 60.1081 +    submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore;
 60.1082 +    result = vkQueueSubmit(
 60.1083 +        vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]);
 60.1084 +    if(result != VK_SUCCESS)
 60.1085 +    {
 60.1086 +        SDL_LogError(
 60.1087 +            SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result));
 60.1088 +        quit(2);
 60.1089 +    }
 60.1090 +    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
 60.1091 +    presentInfo.waitSemaphoreCount = 1;
 60.1092 +    presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore;
 60.1093 +    presentInfo.swapchainCount = 1;
 60.1094 +    presentInfo.pSwapchains = &vulkanContext.swapchain;
 60.1095 +    presentInfo.pImageIndices = &frameIndex;
 60.1096 +    result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo);
 60.1097 +    if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
 60.1098 +    {
 60.1099 +        return createNewSwapchainAndSwapchainSpecificStuff();
 60.1100 +    }
 60.1101 +    if(result != VK_SUCCESS)
 60.1102 +    {
 60.1103 +        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
 60.1104 +                     "vkQueuePresentKHR(): %s\n",
 60.1105 +                     getVulkanResultString(result));
 60.1106 +        quit(2);
 60.1107 +    }
 60.1108 +    SDL_GL_GetDrawableSize(state->windows[0], &w, &h);
 60.1109 +    if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height)
 60.1110 +    {
 60.1111 +        return createNewSwapchainAndSwapchainSpecificStuff();
 60.1112 +    }
 60.1113 +    return SDL_TRUE;
 60.1114 +}
 60.1115 +
 60.1116 +int main(int argc, char *argv[])
 60.1117 +{
 60.1118 +    int fsaa, accel;
 60.1119 +    int i, done;
 60.1120 +    SDL_DisplayMode mode;
 60.1121 +    SDL_Event event;
 60.1122 +    Uint32 then, now, frames;
 60.1123 +    int dw, dh;
 60.1124 +
 60.1125 +    /* Enable standard application logging */
 60.1126 +    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
 60.1127 +
 60.1128 +    /* Initialize parameters */
 60.1129 +    fsaa = 0;
 60.1130 +    accel = -1;
 60.1131 +
 60.1132 +    /* Initialize test framework */
 60.1133 +    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
 60.1134 +    if(!state)
 60.1135 +    {
 60.1136 +        return 1;
 60.1137 +    }
 60.1138 +    for(i = 1; i < argc;)
 60.1139 +    {
 60.1140 +        int consumed;
 60.1141 +
 60.1142 +        consumed = SDLTest_CommonArg(state, i);
 60.1143 +        if(consumed < 0)
 60.1144 +        {
 60.1145 +            SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
 60.1146 +            quit(1);
 60.1147 +        }
 60.1148 +        i += consumed;
 60.1149 +    }
 60.1150 +
 60.1151 +    /* Set Vulkan parameters */
 60.1152 +    state->window_flags |= SDL_WINDOW_VULKAN;
 60.1153 +    state->num_windows = 1;
 60.1154 +    state->skip_renderer = 1;
 60.1155 +
 60.1156 +    if(!SDLTest_CommonInit(state))
 60.1157 +    {
 60.1158 +        quit(2);
 60.1159 +    }
 60.1160 +
 60.1161 +    SDL_GetCurrentDisplayMode(0, &mode);
 60.1162 +    SDL_Log("Screen BPP    : %d\n", SDL_BITSPERPIXEL(mode.format));
 60.1163 +    SDL_GetWindowSize(state->windows[0], &dw, &dh);
 60.1164 +    SDL_Log("Window Size   : %d,%d\n", dw, dh);
 60.1165 +    SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
 60.1166 +    SDL_Log("Draw Size     : %d,%d\n", dw, dh);
 60.1167 +    SDL_Log("\n");
 60.1168 +
 60.1169 +    initVulkan();
 60.1170 +
 60.1171 +    /* Main render loop */
 60.1172 +    frames = 0;
 60.1173 +    then = SDL_GetTicks();
 60.1174 +    done = 0;
 60.1175 +    while(!done)
 60.1176 +    {
 60.1177 +        /* Check for events */
 60.1178 +        ++frames;
 60.1179 +        while(SDL_PollEvent(&event))
 60.1180 +        {
 60.1181 +            SDLTest_CommonEvent(state, &event, &done);
 60.1182 +        }
 60.1183 +
 60.1184 +        if(!done)
 60.1185 +            render();
 60.1186 +    }
 60.1187 +
 60.1188 +    /* Print out some timing information */
 60.1189 +    now = SDL_GetTicks();
 60.1190 +    if(now > then)
 60.1191 +    {
 60.1192 +        SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then));
 60.1193 +    }
 60.1194 +    quit(0);
 60.1195 +    return 0;
 60.1196 +}
 60.1197 +
 60.1198 +#endif