Repository: Rust-SDL2/rust-sdl2 (language: rust)

Issue:
Incorrect `SurfaceApi` for Vulkan example in readme
This line currently specifies `Xlib` every time, which is incorrect:

https://github.com/Rust-SDL2/rust-sdl2/blob/master/README.md?plain=1#L633

The API that is specified here must match the API that was used to create the surface (presumably in `vulkan_create_surface`), which in turn will be the windowing API to which the window belongs. So if the window belongs to Wayland, then it will be created using Vulkan's `vkCreateWaylandSurfaceKHR`, and you must specify `SurfaceApi::Wayland` when calling `from_handle`.

I don't know if SDL offers any way to retrieve this information via its own API. I'm not familiar with it, so I'll leave that to the people here who know it better.


Discussion / hints:
There is a way from SDL2, but the problem is that, in typical SDL fashion, we don't know the values it can output from the documentation. So we either have to dig in the source code, or test on different platforms.

Here is an example:

```rust

pub fn main() {
    let sdl_context = sdl2::init()?;
    let video_subsystem = sdl_context.video()?;

    println!("video driver: {}", video_subsystem.current_video_driver());
}
```

output on my machine:
```
video driver: x11
```

By the way, here is [the source code in C](https://github.com/libsdl-org/SDL/blob/4db2b968af2fbb586e19d2aea71898c4a87780bc/src/video/SDL_video.c#L584). If we can know how `_this->name` is populated, then we may have a chance to list all of them in advance, but I think it would be easier to go on each platform and just get the output there. 
Ah, it's a stringy API, that's unfortunate...
I looked at it a bit further, and we actually do have a way:

https://github.com/libsdl-org/SDL/blob/4db2b968af2fbb586e19d2aea71898c4a87780bc/src/video/SDL_video.c#L67

There are about 20 which are directly referenced here, and a few important ones are directly written in the code:

* `x11`
* `wayland`
* `windows`
* `Android`
* `emscripten`

Only a few like the cocoa / uikit ones are not available, I assume it's because it's a struct directly in the macOS files but I'm not sure...
Unless I'm missing something, `HasRawWindowHandle + HasRawDisplayHandle` are implemented for `Window`. We can just use that, together with [this constructor](https://github.com/vulkano-rs/vulkano/blob/f5c441b076f6459a3eb5db8251be699e8966d3b9/vulkano/src/swapchain/surface.rs#L94-L139) once we release vulkano 0.34, and once you release the update to raw-window-handle 0.5.

Fix patch:
diff --git a/README.md b/README.md
index 5c2a0deaf7..279e4c0d04 100644
--- a/README.md
+++ b/README.md
@@ -590,16 +590,17 @@ To use Vulkan, you need a Vulkan library for Rust. This example uses the
 types for raw Vulkan object handles. The procedure to interface SDL2's Vulkan functions with these
 will be different for each one.
 
+First, make sure you enable the [`raw-window-handle`](#support-for-raw-window-handle) feature.
+
 ```rust
 extern crate sdl2;
 extern crate vulkano;
 
 use sdl2::event::Event;
 use sdl2::keyboard::Keycode;
-use std::sync::Arc;
 use vulkano::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
-use vulkano::swapchain::{Surface, SurfaceApi};
-use vulkano::{Handle, VulkanLibrary, VulkanObject};
+use vulkano::swapchain::Surface;
+use vulkano::VulkanLibrary;
 
 fn main() {
     let sdl_context = sdl2::init().unwrap();
@@ -614,26 +615,18 @@ fn main() {
     let instance_extensions =
         InstanceExtensions::from_iter(window.vulkan_instance_extensions().unwrap());
 
-    let instance = Instance::new(VulkanLibrary::new().unwrap(), {
-        let mut instance_info = InstanceCreateInfo::application_from_cargo_toml();
-        instance_info.enabled_extensions = instance_extensions;
-        instance_info
-    })
-        .unwrap();
-
-    let surface_handle = window
-        .vulkan_create_surface(instance.handle().as_raw() as _)
-        .unwrap();
+    let instance = Instance::new(
+        VulkanLibrary::new().unwrap(),
+        InstanceCreateInfo {
+            enabled_extensions: instance_extensions,
+            ..Default::default()
+        },
+    )
+    .unwrap();
 
-    // SAFETY: Be sure not to drop the `window` before the `Surface` or vulkan `Swapchain`! (SIGSEGV otherwise)
-    let surface = unsafe {
-        Surface::from_handle(
-            Arc::clone(&instance),
-            <_ as Handle>::from_raw(surface_handle),
-            SurfaceApi::Xlib,
-            None,
-        )
-    };
+    // SAFETY: Be sure not to drop the `window` before the `Surface` or vulkan `Swapchain`!
+    // (SIGSEGV otherwise)
+    let surface = unsafe { Surface::from_window_ref(instance.clone(), &window) };
 
     let mut event_pump = sdl_context.event_pump().unwrap();
 
@@ -653,8 +646,6 @@ fn main() {
         ::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
     }
 }
-
-
 ```
 
 # Support for raw-window-handle


Test patch: