From 443d116f49fe37ef0a56ac6d5ad03ba040f53c7f Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 12 Jul 2018 14:52:11 +0200 Subject: [PATCH 1/4] Added Vulkan support --- README.md | 49 ++++ sdl2-sys/sdl_bindings.rs | 549 ++++++++++++++++++++++++++++++++++++++- sdl2-sys/wrapper.h | 1 + src/sdl2/video.rs | 92 ++++++- 4 files changed, 676 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4e7c8126636..dbdbf29ae27 100644 --- a/README.md +++ b/README.md @@ -459,6 +459,55 @@ fn main() { This method is useful when you don't care about sdl2's render capabilities, but you do care about its audio, controller and other neat features that sdl2 has. +# Vulkan + +To use Vulkan, you need a Vulkan library for Rust. This example uses the [Vulkano][vulkano] +library. Other libraries may use different data types for raw Vulkan object handles. The +procedure to interface SDL2's Vulkan functions with these will be different for each one. + +```rust +extern crate sdl2; +extern crate vulkano; + +use sdl2::event::Event; +use sdl2::keyboard::Keycode; +use std::ffi::CString; +use vulkano::VulkanObject; +use vulkano::instance::{Instance, RawInstanceExtensions}; +use vulkano::swapchain::Surface; + +fn main() { + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + + let window = video_subsystem.window("Window", 800, 600) + .vulkan() + .build() + .unwrap(); + + let instance_extensions = window.vulkan_instance_extensions().unwrap(); + let raw_instance_extensions = RawInstanceExtensions::new(instance_extensions.iter().map(|&v| CString::new(v).unwrap())); + let instance = Instance::new(None, raw_instance_extensions, None).unwrap(); + let surface_handle = window.vulkan_create_surface(instance.internal_object()).unwrap(); + let surface = unsafe { Surface::from_raw_surface(instance, surface_handle, window.context()) }; + + let mut event_pump = sdl_context.event_pump().unwrap(); + + 'running: loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { + break 'running + }, + _ => {} + } + } + ::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60)); + } +} + +``` + # When things go wrong Rust, and Rust-SDL2, are both still heavily in development, and you may run into teething issues when using this. Before panicking, check that you're using diff --git a/sdl2-sys/sdl_bindings.rs b/sdl2-sys/sdl_bindings.rs index 48975838e73..576fb4529bd 100644 --- a/sdl2-sys/sdl_bindings.rs +++ b/sdl2-sys/sdl_bindings.rs @@ -41,7 +41,7 @@ pub const __STDC_ISO_10646__: u32 = 201706; pub const __STDC_NO_THREADS__: u32 = 1; pub const __GNU_LIBRARY__: u32 = 6; pub const __GLIBC__: u32 = 2; -pub const __GLIBC_MINOR__: u32 = 26; +pub const __GLIBC_MINOR__: u32 = 27; pub const _SYS_CDEFS_H: u32 = 1; pub const __glibc_c99_flexarr_available: u32 = 1; pub const __WORDSIZE: u32 = 64; @@ -168,10 +168,25 @@ pub const WNOWAIT: u32 = 16777216; pub const __WNOTHREAD: u32 = 536870912; pub const __WALL: u32 = 1073741824; pub const __WCLONE: u32 = 2147483648; +pub const __ENUM_IDTYPE_T: u32 = 1; pub const __W_CONTINUED: u32 = 65535; pub const __WCOREFLAG: u32 = 128; pub const __HAVE_FLOAT128: u32 = 0; pub const __HAVE_DISTINCT_FLOAT128: u32 = 0; +pub const __HAVE_FLOAT64X: u32 = 1; +pub const __HAVE_FLOAT64X_LONG_DOUBLE: u32 = 1; +pub const __HAVE_FLOAT16: u32 = 0; +pub const __HAVE_FLOAT32: u32 = 1; +pub const __HAVE_FLOAT64: u32 = 1; +pub const __HAVE_FLOAT32X: u32 = 1; +pub const __HAVE_FLOAT128X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT16: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT128X: u32 = 0; +pub const __HAVE_FLOATN_NOT_TYPEDEF: u32 = 0; pub const __ldiv_t_defined: u32 = 1; pub const __lldiv_t_defined: u32 = 1; pub const RAND_MAX: u32 = 2147483647; @@ -210,6 +225,8 @@ pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1; pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; pub const __have_pthread_attr_t: u32 = 1; pub const _ALLOCA_H: u32 = 1; +pub const _MM_HINT_ET0: u32 = 7; +pub const _MM_HINT_ET1: u32 = 6; pub const _MM_HINT_T0: u32 = 3; pub const _MM_HINT_T1: u32 = 2; pub const _MM_HINT_T2: u32 = 1; @@ -311,6 +328,8 @@ pub const SDL_HINT_VIDEO_X11_XVIDMODE: &'static [u8; 23usize] = b"SDL_VIDEO_X11_ pub const SDL_HINT_VIDEO_X11_XINERAMA: &'static [u8; 23usize] = b"SDL_VIDEO_X11_XINERAMA\0"; pub const SDL_HINT_VIDEO_X11_XRANDR: &'static [u8; 21usize] = b"SDL_VIDEO_X11_XRANDR\0"; pub const SDL_HINT_VIDEO_X11_NET_WM_PING: &'static [u8; 26usize] = b"SDL_VIDEO_X11_NET_WM_PING\0"; +pub const SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR: &'static [u8; 39usize] = + b"SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR\0"; pub const SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN: &'static [u8; 44usize] = b"SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN\0"; pub const SDL_HINT_WINDOWS_INTRESOURCE_ICON: &'static [u8; 29usize] = @@ -337,8 +356,11 @@ pub const SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS: &'static [u8; 34usize] = b"SDL_APPLE_TV_CONTROLLER_UI_EVENTS\0"; pub const SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION: &'static [u8; 35usize] = b"SDL_APPLE_TV_REMOTE_ALLOW_ROTATION\0"; +pub const SDL_HINT_IOS_HIDE_HOME_INDICATOR: &'static [u8; 28usize] = + b"SDL_IOS_HIDE_HOME_INDICATOR\0"; pub const SDL_HINT_ACCELEROMETER_AS_JOYSTICK: &'static [u8; 30usize] = b"SDL_ACCELEROMETER_AS_JOYSTICK\0"; +pub const SDL_HINT_TV_REMOTE_AS_JOYSTICK: &'static [u8; 26usize] = b"SDL_TV_REMOTE_AS_JOYSTICK\0"; pub const SDL_HINT_XINPUT_ENABLED: &'static [u8; 19usize] = b"SDL_XINPUT_ENABLED\0"; pub const SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING: &'static [u8; 36usize] = b"SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING\0"; @@ -377,6 +399,7 @@ pub const SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION: &'static [u8; 45usi pub const SDL_HINT_IME_INTERNAL_EDITING: &'static [u8; 25usize] = b"SDL_IME_INTERNAL_EDITING\0"; pub const SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH: &'static [u8; 37usize] = b"SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH\0"; +pub const SDL_HINT_RETURN_KEY_HIDES_IME: &'static [u8; 25usize] = b"SDL_RETURN_KEY_HIDES_IME\0"; pub const SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT: &'static [u8; 32usize] = b"SDL_EMSCRIPTEN_KEYBOARD_ELEMENT\0"; pub const SDL_HINT_NO_SIGNAL_HANDLERS: &'static [u8; 23usize] = b"SDL_NO_SIGNAL_HANDLERS\0"; @@ -386,6 +409,7 @@ pub const SDL_HINT_BMP_SAVE_LEGACY_FORMAT: &'static [u8; 27usize] = b"SDL_BMP_SA pub const SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING: &'static [u8; 34usize] = b"SDL_WINDOWS_DISABLE_THREAD_NAMING\0"; pub const SDL_HINT_RPI_VIDEO_LAYER: &'static [u8; 20usize] = b"SDL_RPI_VIDEO_LAYER\0"; +pub const SDL_HINT_VIDEO_DOUBLE_BUFFER: &'static [u8; 24usize] = b"SDL_VIDEO_DOUBLE_BUFFER\0"; pub const SDL_HINT_OPENGL_ES_DRIVER: &'static [u8; 21usize] = b"SDL_OPENGL_ES_DRIVER\0"; pub const SDL_HINT_AUDIO_RESAMPLING_MODE: &'static [u8; 26usize] = b"SDL_AUDIO_RESAMPLING_MODE\0"; pub const SDL_HINT_AUDIO_CATEGORY: &'static [u8; 19usize] = b"SDL_AUDIO_CATEGORY\0"; @@ -395,7 +419,7 @@ pub const SDL_INVALID_SHAPE_ARGUMENT: i32 = -2; pub const SDL_WINDOW_LACKS_SHAPE: i32 = -3; pub const SDL_MAJOR_VERSION: u32 = 2; pub const SDL_MINOR_VERSION: u32 = 0; -pub const SDL_PATCHLEVEL: u32 = 6; +pub const SDL_PATCHLEVEL: u32 = 8; pub const SDL_INIT_TIMER: u32 = 1; pub const SDL_INIT_AUDIO: u32 = 16; pub const SDL_INIT_VIDEO: u32 = 32; @@ -942,7 +966,6 @@ pub type __ssize_t = ::std::os::raw::c_long; pub type __syscall_slong_t = ::std::os::raw::c_long; pub type __syscall_ulong_t = ::std::os::raw::c_ulong; pub type __loff_t = __off64_t; -pub type __qaddr_t = *mut __quad_t; pub type __caddr_t = *mut ::std::os::raw::c_char; pub type __intptr_t = ::std::os::raw::c_long; pub type __socklen_t = ::std::os::raw::c_uint; @@ -971,21 +994,13 @@ pub enum SDL_bool { SDL_FALSE = 0, SDL_TRUE = 1, } -/// \brief A signed 8-bit integer type. pub type Sint8 = i8; -/// \brief An unsigned 8-bit integer type. pub type Uint8 = u8; -/// \brief A signed 16-bit integer type. pub type Sint16 = i16; -/// \brief An unsigned 16-bit integer type. pub type Uint16 = u16; -/// \brief A signed 32-bit integer type. pub type Sint32 = i32; -/// \brief An unsigned 32-bit integer type. pub type Uint32 = u32; -/// \brief A signed 64-bit integer type. pub type Sint64 = i64; -/// \brief An unsigned 64-bit integer type. pub type Uint64 = u64; pub type SDL_compile_time_assert_uint8 = [::std::os::raw::c_int; 1usize]; pub type SDL_compile_time_assert_sint8 = [::std::os::raw::c_int; 1usize]; @@ -1016,6 +1031,44 @@ extern "C" { extern "C" { pub fn SDL_free(mem: *mut ::std::os::raw::c_void); } +pub type SDL_malloc_func = + ::std::option::Option *mut ::std::os::raw::c_void>; +pub type SDL_calloc_func = ::std::option::Option< + unsafe extern "C" fn(nmemb: usize, size: usize) -> *mut ::std::os::raw::c_void, +>; +pub type SDL_realloc_func = ::std::option::Option< + unsafe extern "C" fn(mem: *mut ::std::os::raw::c_void, size: usize) + -> *mut ::std::os::raw::c_void, +>; +pub type SDL_free_func = + ::std::option::Option; +extern "C" { + /// \brief Get the current set of SDL memory functions + pub fn SDL_GetMemoryFunctions( + malloc_func: *mut SDL_malloc_func, + calloc_func: *mut SDL_calloc_func, + realloc_func: *mut SDL_realloc_func, + free_func: *mut SDL_free_func, + ); +} +extern "C" { + /// \brief Replace SDL's memory allocation functions with a custom set + /// + /// \note If you are replacing SDL's memory functions, you should call + /// SDL_GetNumAllocations() and be very careful if it returns non-zero. + /// That means that your free function will be called with memory + /// allocated by the previous memory allocation functions. + pub fn SDL_SetMemoryFunctions( + malloc_func: SDL_malloc_func, + calloc_func: SDL_calloc_func, + realloc_func: SDL_realloc_func, + free_func: SDL_free_func, + ) -> ::std::os::raw::c_int; +} +extern "C" { + /// \brief Get the number of outstanding (unfreed) allocations + pub fn SDL_GetNumAllocations() -> ::std::os::raw::c_int; +} extern "C" { pub fn SDL_getenv(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } @@ -1292,21 +1345,39 @@ extern "C" { extern "C" { pub fn SDL_acos(x: f64) -> f64; } +extern "C" { + pub fn SDL_acosf(x: f32) -> f32; +} extern "C" { pub fn SDL_asin(x: f64) -> f64; } +extern "C" { + pub fn SDL_asinf(x: f32) -> f32; +} extern "C" { pub fn SDL_atan(x: f64) -> f64; } +extern "C" { + pub fn SDL_atanf(x: f32) -> f32; +} extern "C" { pub fn SDL_atan2(x: f64, y: f64) -> f64; } +extern "C" { + pub fn SDL_atan2f(x: f32, y: f32) -> f32; +} extern "C" { pub fn SDL_ceil(x: f64) -> f64; } +extern "C" { + pub fn SDL_ceilf(x: f32) -> f32; +} extern "C" { pub fn SDL_copysign(x: f64, y: f64) -> f64; } +extern "C" { + pub fn SDL_copysignf(x: f32, y: f32) -> f32; +} extern "C" { pub fn SDL_cos(x: f64) -> f64; } @@ -1316,18 +1387,45 @@ extern "C" { extern "C" { pub fn SDL_fabs(x: f64) -> f64; } +extern "C" { + pub fn SDL_fabsf(x: f32) -> f32; +} extern "C" { pub fn SDL_floor(x: f64) -> f64; } +extern "C" { + pub fn SDL_floorf(x: f32) -> f32; +} +extern "C" { + pub fn SDL_fmod(x: f64, y: f64) -> f64; +} +extern "C" { + pub fn SDL_fmodf(x: f32, y: f32) -> f32; +} extern "C" { pub fn SDL_log(x: f64) -> f64; } +extern "C" { + pub fn SDL_logf(x: f32) -> f32; +} +extern "C" { + pub fn SDL_log10(x: f64) -> f64; +} +extern "C" { + pub fn SDL_log10f(x: f32) -> f32; +} extern "C" { pub fn SDL_pow(x: f64, y: f64) -> f64; } +extern "C" { + pub fn SDL_powf(x: f32, y: f32) -> f32; +} extern "C" { pub fn SDL_scalbn(x: f64, n: ::std::os::raw::c_int) -> f64; } +extern "C" { + pub fn SDL_scalbnf(x: f32, n: ::std::os::raw::c_int) -> f32; +} extern "C" { pub fn SDL_sin(x: f64) -> f64; } @@ -2482,6 +2580,15 @@ pub type SDL_AudioCallback = ::std::option::Option< ), >; /// The calculated values in this structure are calculated by SDL_OpenAudio(). +/// +/// For multi-channel audio, the default SDL channel mapping is: +/// 2: FL FR (stereo) +/// 3: FL FR LFE (2.1 surround) +/// 4: FL FR BL BR (quad) +/// 5: FL FR FC BL BR (quad + center) +/// 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) +/// 7: FL FR FC LFE BC SL SR (6.1 surround) +/// 8: FL FR FC LFE BL BR SL SR (7.1 surround) #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct SDL_AudioSpec { @@ -2962,6 +3069,130 @@ extern "C" { /// \return 0 on success or -1 if \c cvt->buf is NULL. pub fn SDL_ConvertAudio(cvt: *mut SDL_AudioCVT) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _SDL_AudioStream { + _unused: [u8; 0], +} +pub type SDL_AudioStream = _SDL_AudioStream; +extern "C" { + /// Create a new audio stream + /// + /// \param src_format The format of the source audio + /// \param src_channels The number of channels of the source audio + /// \param src_rate The sampling rate of the source audio + /// \param dst_format The format of the desired audio output + /// \param dst_channels The number of channels of the desired audio output + /// \param dst_rate The sampling rate of the desired audio output + /// \return 0 on success, or -1 on error. + /// + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamFlush + /// \sa SDL_AudioStreamClear + /// \sa SDL_FreeAudioStream + pub fn SDL_NewAudioStream( + src_format: SDL_AudioFormat, + src_channels: Uint8, + src_rate: ::std::os::raw::c_int, + dst_format: SDL_AudioFormat, + dst_channels: Uint8, + dst_rate: ::std::os::raw::c_int, + ) -> *mut SDL_AudioStream; +} +extern "C" { + /// Add data to be converted/resampled to the stream + /// + /// \param stream The stream the audio data is being added to + /// \param buf A pointer to the audio data to add + /// \param len The number of bytes to write to the stream + /// \return 0 on success, or -1 on error. + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamFlush + /// \sa SDL_AudioStreamClear + /// \sa SDL_FreeAudioStream + pub fn SDL_AudioStreamPut( + stream: *mut SDL_AudioStream, + buf: *const ::std::os::raw::c_void, + len: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + /// Get converted/resampled data from the stream + /// + /// \param stream The stream the audio is being requested from + /// \param buf A buffer to fill with audio data + /// \param len The maximum number of bytes to fill + /// \return The number of bytes read from the stream, or -1 on error + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamFlush + /// \sa SDL_AudioStreamClear + /// \sa SDL_FreeAudioStream + pub fn SDL_AudioStreamGet( + stream: *mut SDL_AudioStream, + buf: *mut ::std::os::raw::c_void, + len: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + /// Get the number of converted/resampled bytes available. The stream may be + /// buffering data behind the scenes until it has enough to resample + /// correctly, so this number might be lower than what you expect, or even + /// be zero. Add more data or flush the stream if you need the data now. + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamFlush + /// \sa SDL_AudioStreamClear + /// \sa SDL_FreeAudioStream + pub fn SDL_AudioStreamAvailable(stream: *mut SDL_AudioStream) -> ::std::os::raw::c_int; +} +extern "C" { + /// Tell the stream that you're done sending data, and anything being buffered + /// should be converted/resampled and made available immediately. + /// + /// It is legal to add more data to a stream after flushing, but there will + /// be audio gaps in the output. Generally this is intended to signal the + /// end of input, so the complete output becomes available. + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamClear + /// \sa SDL_FreeAudioStream + pub fn SDL_AudioStreamFlush(stream: *mut SDL_AudioStream) -> ::std::os::raw::c_int; +} +extern "C" { + /// Clear any pending data in the stream without converting it + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamFlush + /// \sa SDL_FreeAudioStream + pub fn SDL_AudioStreamClear(stream: *mut SDL_AudioStream); +} +extern "C" { + /// Free an audio stream + /// + /// \sa SDL_NewAudioStream + /// \sa SDL_AudioStreamPut + /// \sa SDL_AudioStreamGet + /// \sa SDL_AudioStreamAvailable + /// \sa SDL_AudioStreamFlush + /// \sa SDL_AudioStreamClear + pub fn SDL_FreeAudioStream(stream: *mut SDL_AudioStream); +} extern "C" { /// This takes two audio buffers of the playing audio format and mixes /// them, performing addition, volume adjustment, and overflow clipping. @@ -3021,7 +3252,7 @@ extern "C" { /// \param dev The device ID to which we will queue audio. /// \param data The data to queue to the device for later playback. /// \param len The number of bytes (not samples!) to which (data) points. - /// \return zero on success, -1 on error. + /// \return 0 on success, or -1 on error. /// /// \sa SDL_GetQueuedAudioSize /// \sa SDL_ClearQueuedAudio @@ -3196,6 +3427,17 @@ pub type __v4si = [::std::os::raw::c_int; 4usize]; pub type __v4sf = [f32; 4usize]; pub type __m128 = [f32; 4usize]; pub type __v4su = [::std::os::raw::c_uint; 4usize]; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum idtype_t { + P_ALL = 0, + P_PID = 1, + P_PGID = 2, +} +pub type _Float32 = f32; +pub type _Float64 = f64; +pub type _Float32x = f64; +pub type _Float64x = f64; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct div_t { @@ -5372,6 +5614,7 @@ pub const SDL_PIXELFORMAT_UYVY: _bindgen_ty_6 = _bindgen_ty_6::SDL_PIXELFORMAT_U pub const SDL_PIXELFORMAT_YVYU: _bindgen_ty_6 = _bindgen_ty_6::SDL_PIXELFORMAT_YVYU; pub const SDL_PIXELFORMAT_NV12: _bindgen_ty_6 = _bindgen_ty_6::SDL_PIXELFORMAT_NV12; pub const SDL_PIXELFORMAT_NV21: _bindgen_ty_6 = _bindgen_ty_6::SDL_PIXELFORMAT_NV21; +pub const SDL_PIXELFORMAT_EXTERNAL_OES: _bindgen_ty_6 = _bindgen_ty_6::SDL_PIXELFORMAT_EXTERNAL_OES; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum _bindgen_ty_6 { @@ -5420,6 +5663,8 @@ pub enum _bindgen_ty_6 { SDL_PIXELFORMAT_NV12 = 842094158, /// < Planar mode: Y + V/U interleaved (2 planes) SDL_PIXELFORMAT_NV21 = 825382478, + /// < Android video texture format + SDL_PIXELFORMAT_EXTERNAL_OES = 542328143, } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -6312,6 +6557,19 @@ pub type SDL_blit = ::std::option::Option< dstrect: *mut SDL_Rect, ) -> ::std::os::raw::c_int, >; +#[repr(u32)] +/// \brief The formula used for converting between YUV and RGB +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum SDL_YUV_CONVERSION_MODE { + /// < Full range JPEG + SDL_YUV_CONVERSION_JPEG = 0, + /// < BT.601 (the default) + SDL_YUV_CONVERSION_BT601 = 1, + /// < BT.709 + SDL_YUV_CONVERSION_BT709 = 2, + /// < BT.601 for SD content, BT.709 for HD content + SDL_YUV_CONVERSION_AUTOMATIC = 3, +} extern "C" { /// Allocate and free an RGB surface. /// @@ -6703,6 +6961,21 @@ extern "C" { dstrect: *mut SDL_Rect, ) -> ::std::os::raw::c_int; } +extern "C" { + /// \brief Set the YUV conversion mode + pub fn SDL_SetYUVConversionMode(mode: SDL_YUV_CONVERSION_MODE); +} +extern "C" { + /// \brief Get the YUV conversion mode + pub fn SDL_GetYUVConversionMode() -> SDL_YUV_CONVERSION_MODE; +} +extern "C" { + /// \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + pub fn SDL_GetYUVConversionModeForResolution( + width: ::std::os::raw::c_int, + height: ::std::os::raw::c_int, + ) -> SDL_YUV_CONVERSION_MODE; +} /// \brief The structure that defines a display mode /// /// \sa SDL_GetNumDisplayModes() @@ -6825,7 +7098,9 @@ pub enum SDL_WindowFlags { SDL_WINDOW_FULLSCREEN_DESKTOP = 4097, /// < window not created by SDL SDL_WINDOW_FOREIGN = 2048, - /// < window should be created in high-DPI mode if supported + /// < window should be created in high-DPI mode if supported. + /// On macOS NSHighResolutionCapable must be set true in the + /// application's Info.plist for this to have any effect. SDL_WINDOW_ALLOW_HIGHDPI = 8192, /// < window has mouse captured (unrelated to INPUT_GRABBED) SDL_WINDOW_MOUSE_CAPTURE = 16384, @@ -7190,7 +7465,7 @@ extern "C" { /// If the window is created with any of the SDL_WINDOW_OPENGL or /// SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function /// (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the - /// corrensponding UnloadLibrary function is called by SDL_DestroyWindow(). + /// corresponding UnloadLibrary function is called by SDL_DestroyWindow(). /// /// If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, /// SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. @@ -9312,6 +9587,20 @@ pub enum SDL_JoystickPowerLevel { SDL_JOYSTICK_POWER_WIRED = 4, SDL_JOYSTICK_POWER_MAX = 5, } +extern "C" { + /// Locking for multi-threaded access to the joystick API + /// + /// If you are using the joystick API or handling events from multiple threads + /// you should use these locking functions to protect access to the joysticks. + /// + /// In particular, you are guaranteed that the joystick list won't change, so + /// the API functions that take a joystick index will be valid, and joystick + /// and game controller events will not be delivered. + pub fn SDL_LockJoysticks(); +} +extern "C" { + pub fn SDL_UnlockJoysticks(); +} extern "C" { /// Count the number of joysticks attached to the system right now pub fn SDL_NumJoysticks() -> ::std::os::raw::c_int; @@ -16423,6 +16712,28 @@ extern "C" { /// \return 0 on success, or -1 if the operation is not supported pub fn SDL_GL_UnbindTexture(texture: *mut SDL_Texture) -> ::std::os::raw::c_int; } +extern "C" { + /// \brief Get the CAMetalLayer associated with the given Metal renderer + /// + /// \param renderer The renderer to query + /// + /// \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer + /// + /// \sa SDL_RenderGetMetalCommandEncoder() + pub fn SDL_RenderGetMetalLayer(renderer: *mut SDL_Renderer) -> *mut ::std::os::raw::c_void; +} +extern "C" { + /// \brief Get the Metal command encoder for the current frame + /// + /// \param renderer The renderer to query + /// + /// \return id on success, or NULL if the renderer isn't a Metal renderer + /// + /// \sa SDL_RenderGetMetalLayer() + pub fn SDL_RenderGetMetalCommandEncoder( + renderer: *mut SDL_Renderer, + ) -> *mut ::std::os::raw::c_void; +} extern "C" { /// \brief Create a window that can be shaped with the specified position, dimensions, and flags. /// @@ -28967,6 +29278,216 @@ extern "C" { /// \endcode pub fn SDL_GetWindowWMInfo(window: *mut SDL_Window, info: *mut SDL_SysWMinfo) -> SDL_bool; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct VkInstance_T { + _unused: [u8; 0], +} +pub type VkInstance = *mut VkInstance_T; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct VkSurfaceKHR_T { + _unused: [u8; 0], +} +pub type VkSurfaceKHR = *mut VkSurfaceKHR_T; +pub type SDL_vulkanInstance = VkInstance; +pub type SDL_vulkanSurface = VkSurfaceKHR; +extern "C" { + /// \brief Dynamically load a Vulkan loader library. + /// + /// \param [in] path The platform dependent Vulkan loader library name, or + /// \c NULL. + /// + /// \return \c 0 on success, or \c -1 if the library couldn't be loaded. + /// + /// If \a path is NULL SDL will use the value of the environment variable + /// \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan + /// loader library. + /// + /// This should be called after initializing the video driver, but before + /// creating any Vulkan windows. If no Vulkan loader library is loaded, the + /// default library will be loaded upon creation of the first Vulkan window. + /// + /// \note It is fairly common for Vulkan applications to link with \a libvulkan + /// instead of explicitly loading it at run time. This will work with + /// SDL provided the application links to a dynamic library and both it + /// and SDL use the same search path. + /// + /// \note If you specify a non-NULL \c path, an application should retrieve all + /// of the Vulkan functions it uses from the dynamic library using + /// \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee + /// \c path points to the same vulkan loader library the application + /// linked to. + /// + /// \note On Apple devices, if \a path is NULL, SDL will attempt to find + /// the vkGetInstanceProcAddr address within all the mach-o images of + /// the current process. This is because it is fairly common for Vulkan + /// applications to link with libvulkan (and historically MoltenVK was + /// provided as a static library). If it is not found then, on macOS, SDL + /// will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib, + /// \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order. + /// On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications + /// using a dynamic framework or .dylib must ensure it is included in its + /// application bundle. + /// + /// \note On non-Apple devices, application linking with a static libvulkan is + /// not supported. Either do not link to the Vulkan loader or link to a + /// dynamic library version. + /// + /// \note This function will fail if there are no working Vulkan drivers + /// installed. + /// + /// \sa SDL_Vulkan_GetVkGetInstanceProcAddr() + /// \sa SDL_Vulkan_UnloadLibrary() + pub fn SDL_Vulkan_LoadLibrary(path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + /// \brief Get the address of the \c vkGetInstanceProcAddr function. + /// + /// \note This should be called after either calling SDL_Vulkan_LoadLibrary + /// or creating an SDL_Window with the SDL_WINDOW_VULKAN flag. + pub fn SDL_Vulkan_GetVkGetInstanceProcAddr() -> *mut ::std::os::raw::c_void; +} +extern "C" { + /// \brief Unload the Vulkan loader library previously loaded by + /// \c SDL_Vulkan_LoadLibrary(). + /// + /// \sa SDL_Vulkan_LoadLibrary() + pub fn SDL_Vulkan_UnloadLibrary(); +} +extern "C" { + /// \brief Get the names of the Vulkan instance extensions needed to create + /// a surface with \c SDL_Vulkan_CreateSurface(). + /// + /// \param [in] window Window for which the required Vulkan instance + /// extensions should be retrieved + /// \param [in,out] count pointer to an \c unsigned related to the number of + /// required Vulkan instance extensions + /// \param [out] names \c NULL or a pointer to an array to be filled with the + /// required Vulkan instance extensions + /// + /// \return \c SDL_TRUE on success, \c SDL_FALSE on error. + /// + /// If \a pNames is \c NULL, then the number of required Vulkan instance + /// extensions is returned in pCount. Otherwise, \a pCount must point to a + /// variable set to the number of elements in the \a pNames array, and on + /// return the variable is overwritten with the number of names actually + /// written to \a pNames. If \a pCount is less than the number of required + /// extensions, at most \a pCount structures will be written. If \a pCount + /// is smaller than the number of required extensions, \c SDL_FALSE will be + /// returned instead of \c SDL_TRUE, to indicate that not all the required + /// extensions were returned. + /// + /// \note The returned list of extensions will contain \c VK_KHR_surface + /// and zero or more platform specific extensions + /// + /// \note The extension names queried here must be enabled when calling + /// VkCreateInstance, otherwise surface creation will fail. + /// + /// \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag. + /// + /// \code + /// unsigned int count; + /// // get count of required extensions + /// if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL)) + /// handle_error(); + /// + /// static const char *const additionalExtensions[] = + /// { + /// VK_EXT_DEBUG_REPORT_EXTENSION_NAME, // example additional extension + /// }; + /// size_t additionalExtensionsCount = sizeof(additionalExtensions) / sizeof(additionalExtensions[0]); + /// size_t extensionCount = count + additionalExtensionsCount; + /// const char **names = malloc(sizeof(const char *) * extensionCount); + /// if(!names) + /// handle_error(); + /// + /// // get names of required extensions + /// if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names)) + /// handle_error(); + /// + /// // copy additional extensions after required extensions + /// for(size_t i = 0; i < additionalExtensionsCount; i++) + /// names[i + count] = additionalExtensions[i]; + /// + /// VkInstanceCreateInfo instanceCreateInfo = {}; + /// instanceCreateInfo.enabledExtensionCount = extensionCount; + /// instanceCreateInfo.ppEnabledExtensionNames = names; + /// // fill in rest of instanceCreateInfo + /// + /// VkInstance instance; + /// // create the Vulkan instance + /// VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &instance); + /// free(names); + /// \endcode + /// + /// \sa SDL_Vulkan_CreateSurface() + pub fn SDL_Vulkan_GetInstanceExtensions( + window: *mut SDL_Window, + pCount: *mut ::std::os::raw::c_uint, + pNames: *mut *const ::std::os::raw::c_char, + ) -> SDL_bool; +} +extern "C" { + /// \brief Create a Vulkan rendering surface for a window. + /// + /// \param [in] window SDL_Window to which to attach the rendering surface. + /// \param [in] instance handle to the Vulkan instance to use. + /// \param [out] surface pointer to a VkSurfaceKHR handle to receive the + /// handle of the newly created surface. + /// + /// \return \c SDL_TRUE on success, \c SDL_FALSE on error. + /// + /// \code + /// VkInstance instance; + /// SDL_Window *window; + /// + /// // create instance and window + /// + /// // create the Vulkan surface + /// VkSurfaceKHR surface; + /// if(!SDL_Vulkan_CreateSurface(window, instance, &surface)) + /// handle_error(); + /// \endcode + /// + /// \note \a window should have been created with the \c SDL_WINDOW_VULKAN flag. + /// + /// \note \a instance should have been created with the extensions returned + /// by \c SDL_Vulkan_CreateSurface() enabled. + /// + /// \sa SDL_Vulkan_GetInstanceExtensions() + pub fn SDL_Vulkan_CreateSurface( + window: *mut SDL_Window, + instance: VkInstance, + surface: *mut VkSurfaceKHR, + ) -> SDL_bool; +} +extern "C" { + /// \brief Get the size of a window's underlying drawable in pixels (for use + /// with setting viewport, scissor & etc). + /// + /// \param window SDL_Window from which the drawable size should be queried + /// \param w Pointer to variable for storing the width in pixels, + /// may be NULL + /// \param h Pointer to variable for storing the height in pixels, + /// may be NULL + /// + /// This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + /// drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a + /// platform with high-DPI support (Apple calls this "Retina"), and not disabled + /// by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint. + /// + /// \note On macOS high-DPI support must be enabled for an application by + /// setting NSHighResolutionCapable to true in its Info.plist. + /// + /// \sa SDL_GetWindowSize() + /// \sa SDL_CreateWindow() + pub fn SDL_Vulkan_GetDrawableSize( + window: *mut SDL_Window, + w: *mut ::std::os::raw::c_int, + h: *mut ::std::os::raw::c_int, + ); +} pub type __builtin_va_list = [__va_list_tag; 1usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/sdl2-sys/wrapper.h b/sdl2-sys/wrapper.h index ec2ef478ef6..7ae5a3a38c2 100644 --- a/sdl2-sys/wrapper.h +++ b/sdl2-sys/wrapper.h @@ -1,2 +1,3 @@ #include #include +#include diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index cd314fb92fc..9022a97b233 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -1,4 +1,4 @@ -use libc::{c_int, c_float, uint32_t, c_char}; +use libc::{c_int, c_uint, c_float, uint32_t, c_char}; use std::ffi::{CStr, CString, NulError}; use std::{mem, ptr, fmt}; use std::rc::Rc; @@ -19,6 +19,9 @@ use get_error; use sys; +type VkInstance = usize; +type VkSurfaceKHR = u64; + pub struct WindowSurfaceRef<'a>(&'a mut SurfaceRef, &'a Window); impl<'a> Deref for WindowSurfaceRef<'a> { @@ -807,6 +810,61 @@ impl VideoSubsystem { mem::transmute(interval) } } + + /// Loads the default Vulkan library. + /// + /// This should be done after initializing the video driver, but before creating any Vulkan windows. + /// If no Vulkan library is loaded, the default library will be loaded upon creation of the first Vulkan window. + /// + /// If a different library is already loaded, this function will return an error. + pub fn vulkan_load_library_default(&self) -> Result<(), String> { + unsafe { + if sys::SDL_Vulkan_LoadLibrary(ptr::null()) == 0 { + Ok(()) + } else { + Err(get_error()) + } + } + } + + /// Loads the Vulkan library using a platform-dependent Vulkan library name (usually a file path). + /// + /// This should be done after initializing the video driver, but before creating any Vulkan windows. + /// If no Vulkan library is loaded, the default library will be loaded upon creation of the first Vulkan window. + /// + /// If a different library is already loaded, this function will return an error. + pub fn vulkan_load_library>(&self, path: P) -> Result<(), String> { + unsafe { + // TODO: use OsStr::to_cstring() once it's stable + let path = CString::new(path.as_ref().to_str().unwrap()).unwrap(); + if sys::SDL_Vulkan_LoadLibrary(path.as_ptr() as *const c_char) == 0 { + Ok(()) + } else { + Err(get_error()) + } + } + } + + /// Unloads the current Vulkan library. + /// + /// To completely unload the library, this should be called for every successful load of the + /// Vulkan library. + pub fn vulkan_unload_library(&self) { + unsafe { sys::SDL_Vulkan_UnloadLibrary(); } + } + + /// Gets the pointer to the + /// [`vkGetInstanceProcAddr`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkGetInstanceProcAddr.html) + /// Vulkan function. This function can be called to retrieve the address of other Vulkan + /// functions. + pub fn vulkan_get_proc_address_function(&self) -> Result<*const (), String> { + let result = unsafe { sys::SDL_Vulkan_GetVkGetInstanceProcAddr() as *const () }; + if result.is_null() { + Err(get_error()) + } else { + Ok(result) + } + } } #[derive(Debug)] @@ -1070,6 +1128,31 @@ impl Window { unsafe { sys::SDL_GL_SwapWindow(self.context.raw) } } + /// Get the names of the Vulkan instance extensions needed to create a surface with `vulkan_create_surface`. + pub fn vulkan_instance_extensions(&self) -> Result, String> { + let mut count: c_uint = 0; + if unsafe { sys::SDL_Vulkan_GetInstanceExtensions(self.context.raw, &mut count, ptr::null_mut()) } == sys::SDL_bool::SDL_FALSE { + return Err(get_error()); + } + let mut names: Vec<*const c_char> = vec![ptr::null(); count as usize]; + if unsafe { sys::SDL_Vulkan_GetInstanceExtensions(self.context.raw, &mut count, names.as_mut_ptr()) } == sys::SDL_bool::SDL_FALSE { + return Err(get_error()); + } + Ok(names.iter().map(|&val| unsafe { CStr::from_ptr(val) }.to_str().unwrap()).collect()) + } + + /// Create a Vulkan rendering surface for a window. + /// + /// The `VkInstance` must be created using a prior call to the `vkCreateInstance` function in the Vulkan library. + pub fn vulkan_create_surface(&self, instance: VkInstance) -> Result { + let mut surface: sys::VkSurfaceKHR = ptr::null_mut(); + if unsafe { sys::SDL_Vulkan_CreateSurface(self.context.raw, instance as *mut _, &mut surface) } == sys::SDL_bool::SDL_FALSE { + Err(get_error()) + } else { + Ok(surface as VkSurfaceKHR) + } + } + pub fn display_index(&self) -> Result { let result = unsafe { sys::SDL_GetWindowDisplayIndex(self.context.raw) }; if result < 0 { @@ -1205,6 +1288,13 @@ impl Window { (w as u32, h as u32) } + pub fn vulkan_drawable_size(&self) -> (u32, u32) { + let mut w: c_int = 0; + let mut h: c_int = 0; + unsafe { sys::SDL_Vulkan_GetDrawableSize(self.context.raw, &mut w, &mut h) }; + (w as u32, h as u32) + } + pub fn set_minimum_size(&mut self, width: u32, height: u32) -> Result<(), IntegerOrSdlError> { let w = try!(validate_int(width, "width")); From 83d7ba7e682f1bbb9a5dcb6e7f4ed50fa2c8267d Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 12 Jul 2018 15:01:25 +0200 Subject: [PATCH 2/4] Fixed some display problems in the readme --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dbdbf29ae27..eef7b814511 100644 --- a/README.md +++ b/README.md @@ -461,9 +461,10 @@ its audio, controller and other neat features that sdl2 has. # Vulkan -To use Vulkan, you need a Vulkan library for Rust. This example uses the [Vulkano][vulkano] -library. Other libraries may use different data types for raw Vulkan object handles. The -procedure to interface SDL2's Vulkan functions with these will be different for each one. +To use Vulkan, you need a Vulkan library for Rust. This example uses the +[Vulkano](https://github.com/vulkano-rs/vulkano) library. Other libraries may use different data +types for raw Vulkan object handles. The procedure to interface SDL2's Vulkan functions with these +will be different for each one. ```rust extern crate sdl2; @@ -486,7 +487,9 @@ fn main() { .unwrap(); let instance_extensions = window.vulkan_instance_extensions().unwrap(); - let raw_instance_extensions = RawInstanceExtensions::new(instance_extensions.iter().map(|&v| CString::new(v).unwrap())); + let raw_instance_extensions = RawInstanceExtensions::new(instance_extensions.iter().map( + |&v| CString::new(v).unwrap() + )); let instance = Instance::new(None, raw_instance_extensions, None).unwrap(); let surface_handle = window.vulkan_create_surface(instance.internal_object()).unwrap(); let surface = unsafe { Surface::from_raw_surface(instance, surface_handle, window.context()) }; From 22c896e360d119f3dfcb208a8cc3171745b5a255 Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 12 Jul 2018 15:06:57 +0200 Subject: [PATCH 3/4] Added link to vkCreateInstance documentation --- src/sdl2/video.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index 9022a97b233..c63b23b15ab 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -1143,7 +1143,9 @@ impl Window { /// Create a Vulkan rendering surface for a window. /// - /// The `VkInstance` must be created using a prior call to the `vkCreateInstance` function in the Vulkan library. + /// The `VkInstance` must be created using a prior call to the + /// [`vkCreateInstance`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCreateInstance.html) + /// function in the Vulkan library. pub fn vulkan_create_surface(&self, instance: VkInstance) -> Result { let mut surface: sys::VkSurfaceKHR = ptr::null_mut(); if unsafe { sys::SDL_Vulkan_CreateSurface(self.context.raw, instance as *mut _, &mut surface) } == sys::SDL_bool::SDL_FALSE { From 0a313da48502fb66fa8b1223c6259e0f0a15d8ed Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 12 Jul 2018 16:54:42 +0200 Subject: [PATCH 4/4] Use plain integers for Vulkan handle types in auto-generated bindings --- sdl2-sys/sdl_bindings.rs | 6 ++++-- sdl2-sys/wrapper.h | 10 ++++++++++ src/sdl2/video.rs | 9 ++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sdl2-sys/sdl_bindings.rs b/sdl2-sys/sdl_bindings.rs index 576fb4529bd..dd7ad950d78 100644 --- a/sdl2-sys/sdl_bindings.rs +++ b/sdl2-sys/sdl_bindings.rs @@ -29283,13 +29283,11 @@ extern "C" { pub struct VkInstance_T { _unused: [u8; 0], } -pub type VkInstance = *mut VkInstance_T; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct VkSurfaceKHR_T { _unused: [u8; 0], } -pub type VkSurfaceKHR = *mut VkSurfaceKHR_T; pub type SDL_vulkanInstance = VkInstance; pub type SDL_vulkanSurface = VkSurfaceKHR; extern "C" { @@ -29488,6 +29486,10 @@ extern "C" { h: *mut ::std::os::raw::c_int, ); } +///
+pub type VkInstance = usize; +///
+pub type VkSurfaceKHR = u64; pub type __builtin_va_list = [__va_list_tag; 1usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/sdl2-sys/wrapper.h b/sdl2-sys/wrapper.h index 7ae5a3a38c2..8412a434bed 100644 --- a/sdl2-sys/wrapper.h +++ b/sdl2-sys/wrapper.h @@ -1,3 +1,13 @@ #include #include #include + +/** + *
+ */ +typedef uintptr_t VkInstance_int; + +/** + *
+ */ +typedef uint64_t VkSurfaceKHR_int; diff --git a/src/sdl2/video.rs b/src/sdl2/video.rs index c63b23b15ab..20cd7f5f3d3 100644 --- a/src/sdl2/video.rs +++ b/src/sdl2/video.rs @@ -18,9 +18,8 @@ use get_error; use sys; +pub use sys::{VkInstance, VkSurfaceKHR}; -type VkInstance = usize; -type VkSurfaceKHR = u64; pub struct WindowSurfaceRef<'a>(&'a mut SurfaceRef, &'a Window); @@ -1147,11 +1146,11 @@ impl Window { /// [`vkCreateInstance`](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCreateInstance.html) /// function in the Vulkan library. pub fn vulkan_create_surface(&self, instance: VkInstance) -> Result { - let mut surface: sys::VkSurfaceKHR = ptr::null_mut(); - if unsafe { sys::SDL_Vulkan_CreateSurface(self.context.raw, instance as *mut _, &mut surface) } == sys::SDL_bool::SDL_FALSE { + let mut surface: VkSurfaceKHR = 0; + if unsafe { sys::SDL_Vulkan_CreateSurface(self.context.raw, instance, &mut surface) } == sys::SDL_bool::SDL_FALSE { Err(get_error()) } else { - Ok(surface as VkSurfaceKHR) + Ok(surface) } }