Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VK_KHR_swapchain is broken on Vulkan 1.0 #307

Closed
kvark opened this issue Jun 18, 2020 · 26 comments
Closed

VK_KHR_swapchain is broken on Vulkan 1.0 #307

kvark opened this issue Jun 18, 2020 · 26 comments
Labels

Comments

@kvark
Copy link
Collaborator

kvark commented Jun 18, 2020

See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_swapchain.html
Also downstream issue in gfx-rs/wgpu-rs#313 (comment)
Basically, looks like Ash requests an address of vkGetPhysicalDevicePresentRectanglesKHR even when on Vulkan 1.0 instance, where it doesn't exist.

This is a blocker for gfx/wgpu on Android today.

@MaikKlein
Copy link
Member

I am not sure if that is an ash bug. The spec says any other case, not covered above | NULL from https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetDeviceProcAddr.html so it should just return a nullptr.

@kvark
Copy link
Collaborator Author

kvark commented Jun 18, 2020

@MaikKlein good point. It does seem allowed according to this wording. I guess the question is, who prints this then:

[2020-06-18T06:37:16Z ERROR gfx_backend_vulkan] [vulkan] invalid vkGetDeviceProcAddr(0x73683eb2c0, "vkGetPhysicalDevicePresentRectanglesKHR") call

@msiglreith
Copy link
Contributor

msiglreith commented Jun 18, 2020

That's from android's vulkan loader and should also return a nullptr.

edit: https://android.googlesource.com/platform/frameworks/native/+/refs/heads/master/vulkan/libvulkan/api_gen.cpp#608

@kvark
Copy link
Collaborator Author

kvark commented Jun 18, 2020

Thanks @msiglreith !
Hmm, so it looks like asking for these addresses is technically valid, but is suspicious and reported nevertheless. This brings us back to Ash, maybe it shouldn't ask for these pointers then?

@TheRawMeatball
Copy link

That's from android's vulkan loader and should also return a nullptr.

edit: https://android.googlesource.com/platform/frameworks/native/+/refs/heads/master/vulkan/libvulkan/api_gen.cpp#608

If its from android's vulkan loader, why is it prefixed with RustStdoutStderr? That doesn't add up.

@MaikKlein
Copy link
Member

Ash, maybe it shouldn't ask for these pointers then?

Possibly, but ash follows the spec here. Not sure how hard it would be to change that. I don't know if there is a way of querying the version of an instance at runtime, otherwise you'd have to pass in the spec version every time you want to create an extension, which doesn't seem that nice either.

I guess technically we could carry the version around in an instance, but that just feels hacky just to make android happy here. But still a possibility.

If its from android's vulkan loader, why is it prefixed with RustStdoutStderr? That doesn't add up.

Maybe it is coming from the validation layer?

@msiglreith
Copy link
Contributor

If its from android's vulkan loader, why is it prefixed with RustStdoutStderr? That doesn't add up.

The vulkan backend forwards debug messages, which are generated by the loader here, into log which end in the android logger sink when build in debug mode.

@MaikKlein
Copy link
Member

After thinking about it for a while, I think the situation can be improved. As in only load function pointers for 1.1 if you have requested it.

KhrSwapchainFn_1_0, KhrSwapchainFn_1_1 etc

pub struct Swapchain {
    handle: vk::Device,
    swapchain_fn_1_0: vk::KhrSwapchainFn_1_0,
    swapchain_fn_1_1: vk::KhrSwapchainFn_1_1,
}

Ash already does that internally for Instance and Device. We can do the same for extensions. My current priority is to rewrite the generator so I can't tell you when I'll implement it.

As to your bug report:

This is not a blocker for you right?

It is just an incorrect error log from the vulkan loader on android. You can even see it has names such as vkGetPhysicalDeviceFeatures2 which are only available in 1.2. But it is missing vkGetPhysicalDevicePresentRectanglesKHR. Maybe you can open an issue for it?

@kvark
Copy link
Collaborator Author

kvark commented Jun 19, 2020

It's our only clue so far on why Android fails to wok, according to the gfx-rs/wgpu-rs#313 (comment) , so might as well be a blocker.

As for filing this upstream, I don't do Android development yet, and not even sure where exactly to file it. (https://github.com/KhronosGroup/Vulkan-Loader doesn't seem to have the code @msiglreith linked to). Will look into it...

@TheRawMeatball
Copy link

While I don't know if this is a breaking bug, there is at least one breaking bug in the stack somewhere as the downstream issue shows. It could be this one, or it could be

541 I hwservicemanager: getTransport: Cannot find entry [email protected]::IMapper/default in either framework or device manifest.
06-18 09:37:16.647  2134  2158 W Gralloc3: mapper 3.x is not supported

I don't know. Gralloc3: mapper 3.x is not supported also shows up in flutter/flutter#50405 , though I don't know how relevant that is. On top of that, I'm running these tests on a rooted Mi 8 with Lineage OS 17 (Android 10), so thats also a possible error source.

If anyone can test the downstream issue on a diffrent phne, preferrabily not running android 9, it would be great.

@VZout
Copy link

VZout commented Jun 29, 2020

I get the same hwservicemanager: getTransport: Cannot find entry [email protected]::IMapper/default in either framework or device manifest. message.

However I have no problem rendering on Android with ash on Android 10.

@TheRawMeatball
Copy link

Would you mind sharing the code so I can test it as well?

@VZout
Copy link

VZout commented Jul 13, 2020

Would you mind sharing the code so I can test it as well?

I don't think my employer would like that 😉
But you can try running the ash-window example using android-ndk-rs and cargo-apk

@MarijnS95
Copy link
Collaborator

@TheRawMeatball
Copy link

But you can try running the ash-window example using android-ndk-rs and cargo-apk

Doesn't work 😞 It doesn't even compile, instead throwing a linker error with the folloving note:

/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/examples/winit-606ab4e862112a4b.pjjagpai5vemqgm.rcgu.o: In function `android_glue::get_native_window::hd8e40d0b894c7089':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::add_sender::h38498a4fefebf87c':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:77: undefined reference to `cargo_apk_injected_glue_add_sender'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::set_multitouch::h7f13395a4f79df40':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:102: undefined reference to `cargo_apk_injected_glue_set_multitouch'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::get_native_window::he8f3c1840b00b87b':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@VZout
Copy link

VZout commented Jul 13, 2020

But you can try running the ash-window example using android-ndk-rs and cargo-apk

Doesn't work 😞 It doesn't even compile, instead throwing a linker error with the folloving note:

/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/examples/winit-606ab4e862112a4b.pjjagpai5vemqgm.rcgu.o: In function `android_glue::get_native_window::hd8e40d0b894c7089':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::add_sender::h38498a4fefebf87c':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:77: undefined reference to `cargo_apk_injected_glue_add_sender'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::set_multitouch::h7f13395a4f79df40':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:102: undefined reference to `cargo_apk_injected_glue_set_multitouch'
/mnt/33CA263211FBF90F/ash/ash/target/aarch64-linux-android/debug/deps/libwinit-feefb20804020e87.rlib(winit-feefb20804020e87.winit.da2imn84-cgu.6.rcgu.o): In function `android_glue::get_native_window::he8f3c1840b00b87b':
/home/user/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/android_glue-0.2.3/src/lib.rs:123: undefined reference to `cargo_apk_injected_glue_get_native_window'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I think you didn't read the documentation of https://github.com/rust-windowing/android-ndk-rs properly. Using it correctly should solve those issues. Straight up compiling the ash example for android won't work without changing the code.

Here is a deprecated repo with some extra documentation: https://github.com/rust-windowing/android-rs-glue

@TheRawMeatball
Copy link

Well, I changed the code, but it still doesn't work. Here's my modified version:

//! Demonstrate interop with beryllium/SDL windows.
//!
//! Sample creates a surface from a window through the
//! platform agnostic window handle trait.
//!
//! On instance extensions platform specific extensions need to be enabled.

use ash::{version::EntryV1_0, vk};
use std::error::Error;

#[cfg_attr(target_os = "android", ndk_glue::main(backtrace))]
pub fn main()
{
    println!("-------------------------RUST-------------------------");
    _main().unwrap();
}

fn _main() -> Result<(), Box<dyn Error>> {
    let event_loop = winit::event_loop::EventLoop::new();
    let window = winit::window::WindowBuilder::new()
        .build(&event_loop)?;

    unsafe {
        let entry = ash::Entry::new()?;
        #[cfg(target_os = "android")]
        {
            println!("Waiting for NativeScreen");
            loop
            {
                match ndk_glue::native_window().as_ref() {
                    Some(_) => 
                    {
                        println!("NativeScreen Found:{:?}", ndk_glue::native_window());
                        break;
                    },
                    None => ()
                }
            }
        }
        let surface_extensions = ash_window::enumerate_required_extensions(&window)?;
        let instance_extensions = surface_extensions
            .iter()
            .map(|ext| ext.as_ptr())
            .collect::<Vec<_>>();
        let app_desc = vk::ApplicationInfo::builder().api_version(vk::make_version(1, 0, 0));
        let instance_desc = vk::InstanceCreateInfo::builder()
            .application_info(&app_desc)
            .enabled_extension_names(&instance_extensions);

        let instance = entry.create_instance(&instance_desc, None)?;

        // Create a surface from winit window.
        let surface = ash_window::create_surface(&entry, &instance, &window, None)?;
        let surface_fn = ash::extensions::khr::Surface::new(&entry, &instance);
        println!("surface: {:?}", surface);

        event_loop.run(move |event, _, control_flow| match event {
            winit::event::Event::WindowEvent {
                event: winit::event::WindowEvent::CloseRequested,
                ..
            } => {
                    *control_flow = winit::event_loop::ControlFlow::Exit;
                    surface_fn.destroy_surface(surface, None);
                },
            _ => (),
        });
    }
}

And here is the modified Cargo.toml:

[package]
name = "ash-window"
version = "0.4.1"
authors = ["msiglreith <[email protected]>"]
edition = "2018"
license = "MIT OR Apache-2.0"
description = "Interop library between ash and raw-window-handle"
documentation = "https://docs.rs/ash-window"
repository = "https://github.com/MaikKlein/ash"
readme = "README.md"
keywords = ["window", "ash", "graphics"]
categories = ["game-engines", "graphics"]
exclude = [".github/*"]
workspace = ".."

[dependencies]
ash = { path = "../ash" }
raw-window-handle = "0.3"

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
raw-window-metal = "0.1"

[dev-dependencies]
winit = "0.22.1"
ndk-glue = { path = "/mnt/33CA263211FBF90F/android-ndk-rs/android-ndk-rs/ndk-glue" }

[[example]]
name = "winit"
crate-type = ["lib", "cdylib"]

I upgraded winit and did a couple minor tweaks to remove the dependency on the deprecated android-glue, and the ndk-glue path points to an unmodified clone of the master branch. I also installed cargo-apk from said clone, so there shouldn't be any issues. However, it still doesn't work. Here's the error message:

07-14 11:20:39.220 10511 10534 I RustStdoutStderr: -------------------------RUST-------------------------
07-14 11:20:39.220 10511 10534 I RustStdoutStderr: Waiting for NativeScreen
07-14 11:20:39.231 10511 10534 I RustStdoutStderr: NativeScreen Found:RwLockReadGuard { lock: RwLock { data: Some(NativeWindow { ptr: 0x7673d18010 }) } }
07-14 11:20:39.231 10511 10534 I RustStdoutStderr: thread '<unnamed>' panicked at 'native window null', /home/oguz/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/android/mod.rs:418:13
07-14 11:20:39.231 10511 10534 I RustStdoutStderr: stack backtrace:
07-14 11:20:39.241  1414  1558 I ActivityTaskManager: Displayed rust.example.winit/android.app.NativeActivity: +172ms
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:    0: backtrace::backtrace::libunwind::trace
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:              at ./cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:    1: backtrace::backtrace::trace_unsynchronized
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:              at ./cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:    2: std::sys_common::backtrace::_print_fmt
07-14 11:20:39.338 10511 10534 I RustStdoutStderr:              at src/libstd/sys_common/backtrace.rs:78
07-14 11:20:39.339 10511 10534 I RustStdoutStderr:    3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
07-14 11:20:39.339 10511 10534 I RustStdoutStderr:              at src/libstd/sys_common/backtrace.rs:59
07-14 11:20:39.349 10511 10534 I RustStdoutStderr:    4: core::fmt::write
07-14 11:20:39.349 10511 10534 I RustStdoutStderr:              at src/libcore/fmt/mod.rs:1069
07-14 11:20:39.349 10511 10534 I RustStdoutStderr:    5: std::io::Write::write_fmt
07-14 11:20:39.349 10511 10534 I RustStdoutStderr:              at src/libstd/io/mod.rs:1504
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:    6: std::sys_common::backtrace::_print
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:              at src/libstd/sys_common/backtrace.rs:62
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:    7: std::sys_common::backtrace::print
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:              at src/libstd/sys_common/backtrace.rs:49
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:    8: std::panicking::default_hook::{{closure}}
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:              at src/libstd/panicking.rs:198
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:    9: std::panicking::default_hook
07-14 11:20:39.350 10511 10534 I RustStdoutStderr:              at src/libstd/panicking.rs:218
07-14 11:20:39.351 10511 10534 I RustStdoutStderr:   10: std::panicking::rust_panic_with_hook
07-14 11:20:39.351 10511 10534 I RustStdoutStderr:              at src/libstd/panicking.rs:511
07-14 11:20:39.351 10511 10534 I RustStdoutStderr:   11: std::panicking::begin_panic
07-14 11:20:39.351 10511 10534 I RustStdoutStderr:              at ./home/oguz/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:438
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:   12: winit::platform_impl::platform::Window::raw_window_handle
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:              at ./home/oguz/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/winit-0.22.2/src/platform_impl/android/mod.rs:418
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:   13: <winit::window::Window as raw_window_handle::HasRawWindowHandle>::raw_window_handle
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:              at ./home/oguz/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/winit-0.22.2/src/window.rs:791
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:   14: ash_window::enumerate_required_extensions
07-14 11:20:39.352 10511 10534 I RustStdoutStderr:              at ash-window/src/lib.rs:133
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:   15: winit::_main
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:              at ash-window/examples/winit.rs:40
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:   16: winit::main
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:              at ash-window/examples/winit.rs:15
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:   17: ndk_glue::init::{{closure}}
07-14 11:20:39.353 10511 10534 I RustStdoutStderr:              at ./mnt/33CA263211FBF90F/android-ndk-rs/android-ndk-rs/ndk-glue/src/lib.rs:177
07-14 11:20:39.353 10511 10534 I RustStdoutStderr: note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

I had fixed a very similar bug with the loop statement, but that trick apparently doesn't work with ash.

@msiglreith
Copy link
Contributor

msiglreith commented Jul 14, 2020

ash_window::enumerate_required_extensions(&window)?

currently panics, requires rust-windowing/winit#1624 or manually specifying the extensions.
In case you use the branch linked, you would further need to comment out this line here (rust-windowing/winit#1604 (comment)) otherwise the application will close immediately on entering the event loop.

Furthemore, the creation of the surface must be moved into the event loop:

Event::Resumed => {
      // destroy surface if already have some
     // ANativeWindow handle only valid between Resumed and Suspended
     // might change when getting a new Resumed event -> destroy old one
      surface = ash_window::create_surface(&entry, &instance, &window, None)?;
      println!("surface: {:?}", surface);
}
Event::Suspended => /* destroy surface here */

Then everything should work for this example at least (:

@TheRawMeatball
Copy link

TheRawMeatball commented Jul 14, 2020

It worked! Well, almost. There is still no output to the screen, and touching it gives an ANR. But, the reason for that is winit doesn't poll the android event queue, meaning inputs go unhandled. I'll probably look into that some other day, and if its not implemented on the master branch open an issue.

EDIT:
I cloned the winit repo, and did the mentioned modification. Now I'm really confused. The source code for winit suggests the events from ndk_glue::poll_events should be relayed to the event loop, but they are not. Here's updated event loop:

event_loop.run(move |event, _, control_flow| {
            *control_flow = ControlFlow::Poll;
            match event {
                Event::WindowEvent{event : window_event, ..} => 
                {
                    match window_event
                    {
                        WindowEvent::CloseRequested => 
                        {
                            println!("----------------------RUST EXITING---------------------");
                            *control_flow = winit::event_loop::ControlFlow::Exit;
                        },
                        WindowEvent::Touch(_) => 
                        {
                            println!("-----------------------RUST TOUCH-----------------------");
                        }
                        _ => 
                        {
                            println!("--------------------RUST WINDOW EVENT--------------------");
                        }
                    }
                },
                Event::Resumed =>
                {
                    println!("----------------------RUST RESUME----------------------");
                    if let Some(sfc) = surface {
                        surface_fn.destroy_surface(sfc, None);
                        surface = None;
                    }

                    surface = Some(ash_window::create_surface(&entry, &instance, &window, None).unwrap());
                    println!("surface: {:?}", surface);
                },
                Event::Suspended => 
                {
                    println!("----------------------RUST SUSPEND---------------------");
                    if let Some(sfc) = surface {
                        surface_fn.destroy_surface(sfc, None);
                    }
                },
                Event::RedrawRequested(_) => 
                {
                    println!("----------------------RUST REDRAW----------------------")
                },
                Event::MainEventsCleared => 
                {
                    println!("MainEventsCleared");
                    #[cfg(target_os = "android")]
                    {
                        println!("{:?}", ndk_glue::poll_events());
                    }
                },
                Event::RedrawEventsCleared => 
                {
                    //println!("RedrawEventsCleared");
                },
                Event::LoopDestroyed => 
                {
                    println!("-----------------------RUST QUIT-----------------------");
                },
                Event::NewEvents(cause) => 
                {
                    println!("RUST NEW EVENT:{:?}", cause);
                }
                _ => 
                {
                    println!("-----------------------RUST EVENT-----------------------");
                }
        
            }    
        });

And here is the output :

07-14 14:38:23.286  8846  8869 I RustStdoutStderr: -------------------------RUST-------------------------
07-14 14:38:23.288  8846  8870 D vulkan  : searching for layers in '/data/app/rust.example.winit-EbEw2uoavoBWrvMyzt2dnQ==/lib/arm64'
07-14 14:38:23.289  8846  8870 D vulkan  : searching for layers in '/data/app/rust.example.winit-EbEw2uoavoBWrvMyzt2dnQ==/base.apk!/lib/arm64-v8a'
07-14 14:38:23.290  8846  8870 I AdrenoVK: QUALCOMM build          : 033a5b0, I0e419467bc
07-14 14:38:23.290  8846  8870 I AdrenoVK: Build Date              : 03/11/20
07-14 14:38:23.290  8846  8870 I AdrenoVK: Shader Compiler Version : EV031.27.05.01
07-14 14:38:23.290  8846  8870 I AdrenoVK: Local Branch            : 
07-14 14:38:23.290  8846  8870 I AdrenoVK: Remote Branch           : refs/tags/AU_LINUX_ANDROID_LA.UM.8.3.R1.10.00.00.520.058
07-14 14:38:23.290  8846  8870 I AdrenoVK: Remote Branch           : NONE
07-14 14:38:23.290  8846  8870 I AdrenoVK: Reconstruct Branch      : NOTHING
07-14 14:38:23.290  8846  8870 I AdrenoVK: Build Config            : S P 8.0.11 AArch64
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Init
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: Some(Start)
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: Some(Resume)
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.291  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.297  8846  8869 I RustStdoutStderr: Some(InputQueueCreated)
07-14 14:38:23.297  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.297  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: Some(WindowCreated)
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: Some(WindowResized)
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.306  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.307  8846  8869 I RustStdoutStderr: Some(ContentRectChanged)
07-14 14:38:23.307  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.307  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.308  8846  8869 I RustStdoutStderr: Some(WindowRedrawNeeded)
07-14 14:38:23.308  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.308  8846  8869 I RustStdoutStderr: MainEventsCleared
07-14 14:38:23.311  8846  8869 I RustStdoutStderr: Some(WindowHasFocus)
07-14 14:38:23.311  8846  8869 I RustStdoutStderr: RUST NEW EVENT:Poll
07-14 14:38:23.311  8846  8869 I RustStdoutStderr: MainEventsCleared

The WindowRedrawNeeded, for example should cause ----------------------RUST REDRAW---------------------- to be printed, but it doesn't. I have no clue as to whythis isn't working.

@msiglreith
Copy link
Contributor

ControlFlow::Poll currently doesn't poll the events it seems compared to the others variants.
Nonetheless, I think we drifted a bit from the original issue -> input&event handling should be rather discussed over at winit or android-ndk-rs

@msiglreith
Copy link
Contributor

Doing the necessary steps listed above (patching winit, ndk-* versions, ndk::main, cdylib, surface/swapchain creation on Resumed, etc.) the wgpu example should also run. A few more wgpu related parts needed to adjusted as well: surface format was not supported and compatible surface needs to be changed to None (on Android presentation is always supported for all devices).

The error message

[2020-06-18T06:37:16Z ERROR gfx_backend_vulkan] [vulkan] invalid vkGetDeviceProcAddr(0x73683eb2c0, "vkGetPhysicalDevicePresentRectanglesKHR") call

is still there and can be ignored as mentioned in my opinion.

Funny enough, touch input handling also works once drawing something on screen..

Proof:
Screenshot_2020-07-14-21-31-03-225_rust example triangle

@TheRawMeatball
Copy link

ControlFlow::Poll currently doesn't poll the events it seems compared to the others variants.
Nonetheless, I think we drifted a bit from the original issue -> input&event handling should be rather discussed over at winit or android-ndk-rs

I figured out that recently as well, cant wait to get wgpu working!

@enfipy
Copy link

enfipy commented Sep 17, 2020

@msiglreith Any updates on this? Trying to make the same thing work but facing VK and similar issues. Is there a working example of running wgpu on android?

@msiglreith
Copy link
Contributor

@enfipy this branch should work. Currently built around latest android-ndk,
cargo apk run --example hello_triangle

@enfipy
Copy link

enfipy commented Sep 17, 2020

@msiglreith Thank you a lot! I was able to run your example on my Mi Mix 2S phone.

Also, I tried to run it on the Pixel_3_API_29 emulator but got Vulkan errors. I think it's just because it's not installed on my mac and not specified in the emulator settings but is it possible to make wgpu fallback to GLES in this kind of situation?

@MarijnS95
Copy link
Collaborator

This looks like an old issue that I think we can close (as the downstream wgpu issue was closed as well): there is no harm in loading function pointers that do not exist on a given version (or because a specific combination of extensions wasn't enabled) as it'll simply return NULL from the driver, and in the current version of Ash that means you should simply not call that function or get a guaranteed panic.

In addition this Vulkan 1.1 dependency was mentioned in the function docs when a high-level wrapper was finally added in #629, just a few days short of two years after this issue was filed.

Then we very recently discovered a major flaw in that PR and a few other extension wrapper loaders: #727 - in short you cannot load instance-level functions like vkGetPhysicalDevicePresentRectanglesKHR via vkGetDeviceProcAddr or get a guaranteed NULL. This appears to be why this issue was originally reported, but everyone seems to have glossed over that fact (even though any other case, not covered above | NULL was clearly quoted from https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetDeviceProcAddr.html#_description) and focused on the API compatibility mismatch alone.

Will close this and track that issue in #727.

Separately we are thinking about making loader functions fail on NULL rather than having possibly panicking functions. But this does require a much more sophisticated combination of Vulkan version and possibly multiple extensions beyond @MaikKlein's Extension+Version proposal in #307 (comment) - not to mention the instance-level and device-level split mentioned above in #727.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants