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

nannou v0.9 - Vulkan graphics, simpler event API and much more #240

Merged
merged 97 commits into from
May 28, 2019

Conversation

mitchmindtree
Copy link
Member

@mitchmindtree mitchmindtree commented Jan 2, 2019

This is easily the biggest update for nannou so far!

OpenGL -> Vulkan

The switch from OpenGL to Vulkan for cross-platform graphics is the main story here. You can find more details at #208 and #216, but the primary reasons for switching to Vulkan are:

  • Gaining support for compiling and running languages other than GLSL (e.g. RLSL, HLSL) on the GPU via Vulkan's low-level SPIR-V representation.
  • Access to finer-grained control over the GPU for more thorough optimisation if necessary.
  • No longer having to deal with OpenGL bugs resulting from inconsistent implementations across different devices and versions.
  • Switching to a more modern, future-proof, cross-platform graphics standard.

Both High-level and Low-level Access

While the existing high-level graphics APIs should behave almost exactly the same (apart from smoother graphics and slightly better performance), this PR also allows for much lower level access to the graphics stack than was previously available. In other words, nannou now allows for fully custom graphics pipeline creation, access to each window's unique swapchain, custom vulkan instance creation, custom device selection and loads more. To demonstrate this low level access, @JoshuaBatty and I have started a new series of vk_*.rs examples in the examples/vulkan/ directory. These demonstrate how to work with basic geometry, images, 3D, first-person cameras, compute shaders and more. We'll continue adding to these over time - requests are very welcome!

GLSL

Note that GLSL is still well supported so you can still reach into your existing bag of shader tricks! Note however that currently only the most recent versions of GLSL are supported, so you may need to update older versions. Funnily enough, this might make it easier to run GLSL 450 code on macOS as I believe support for more recent versions of OpenGL and GLSL from Apple have been lacking.

MacOS

For folks wondering about how macOS is supported, nannou uses vulkano under the hood which links to MoltenVK on macOS for translating Vulkan to Apple's Metal API. We're hoping that by the time this is merged, @freesig's work on automating the MoltenVK installation process at build time will have landed. In theory this means that you should be able to run cargo build like normal and everything should Just Work™ (you might have to restart your terminal), though don't be surprised if there are hiccups as this is all still very new.

Tradeoffs

All that said, this change will mean that nannou may no longer be compatible on some older systems that don't yet have Vulkan support. Nannou aims to foster the next generation of creative coding and with our small team's limited capacity this unfortunately means we must draw a line in the sand at some point. If you're curious about the level of support for Vulkan on your system's GPU you can search for it here to find detailed reports. If you're not sure what GPU you have or it's not listed in that database, the site will allow you to download the tool for generating your own report.

If nannou was working for you in 0.8 but stopped in 0.9 we would love for you to leave an issue and let us know. We'll do our best to address each issue, though keep in mind that our ability will be limited in cases where Vulkan driver support is lacking.

Simpler Event API

One glaring issue with nannou's current event API is the way that user's are expected to handle events via the event function. While the event type is thorough and allows for accessing loads of hardware, application and window events, handling the Event type itself could be quite verbose and confronting for new users who might be unfamiliar with the fancy pattern matching required.

This update allows for using functions to handle events in a way that will be much more familiar to users coming from Processing, OF and Cinder and reduces the amount of language-learning users have to go through before they can start being creative.

For a closer look at these changes check out #221 and in particular the changes to the examples in the diff. The new all_functions.rs example demonstrates all of the new event functions that may be registered with apps and windows in one place.


For details on the other small tweaks, patches, fixes and features check out the CHANGELOG diff and the commit messages below.

Merging is currently pending:

@freesig
Copy link
Collaborator

freesig commented Jan 2, 2019

Awesome stuff!!
I might suggest waiting for the next release of the lunarg SDK because otherwise we might have to distribute a build of MoltenVK for this to actually work. Looks like they usually release monthly and we are already over due for one. Hopefully there's a release while we are waiting for the moltenvk_deps to merge.

mitchmindtree and others added 22 commits May 11, 2019 17:27
This switches the windowed-graphics API from OpenGL (via glium) to
Vulkan (via vulkano). You can read more about the motivations, thoughts
and discussion behind this switch at #208 and #108.

There are still a few items left to complete before this PR is ready:

- [ ] Fix bug where view seems to be vertically flipped (probably in
  vertex mapping process).
- [ ] Fix bug where clearing an image that is then multisampled does not
  work. vulkano-rs/vulkano#1123
- [ ] Add depth attachment to draw renderpass.
- [ ] Fix bug where alpha channels always seem opaque.
- [ ] Update old loop modes for changes in the application loop.
- [ ] Merge conrod vulkan backend and switch to it.
- [ ] Merge and publish vulkano-rs/vulkano#1117 or related fix so we can
  switch to crates.io dep.

Closes #208.
Closes #108.
Also removes the use of `Frame::clear_all` in favour of `Frame::clear`
as a `Frame` now only represents the frame for a single window.
In Vulkan, the *y* axis increases in the downwards direction rather than
the upwards direction like in OpenGL.
The new `gpu` module contains items related to interfacing with one or
more GPUs via Vulkan.

The `App` builder now allows for specifying a custom Vulkan instance and
also allows for easily setting up a debug callback for receiving
messages from validation layers..
Still need to:

- Allow for custom depth formats
- Validate depth format
This involved refactoring the `RefreshSync` run loop into a set of
modular functions for easier re-use between loop modes.

Note that while each loop mode is now supported, the `Wait` and `Rate`
present modes are not yet optimal. If using the `Wait` or `Rate` we
should attempt to use the `Mailbox` present mode with triple-buffering
in order to avoid blocking when acquiring an image. This is different to
the `RefreshSync` mode as the `RefreshSync` mode is *driven* by the rate
at which swapchain images can be retrieved for each window.
This allows for specifying a set of custom swapchain parameters during
the window building process.

The swapchain will now be recreated each time the `LoopMode` is changed
at runtime. It will attempt to use optimal `PresentMode` and image count
for the new swapchain unless the user has chosen a specific value for
either of these parameters.

The `loop_mode` example has been updated with some short docs along with
the addition of the new loop mode. The window title now displays the
current `LoopMode`.
The `simple_ui.rs` example works!

There is an issue on my machine where, once I added MSAA, the `Ui`
drawing now clears over the top of the existing window contents. I think
this is just another case of vulkano-rs/vulkano#1123 and probably only
affects linux machines running the intel mesa drivers.
Previously a unique set of images was created for each framebuffer
unnecessarily. Now, a single set of `RenderPassImages` is created only
when dimensions have changed and these are shared between each of the
swapchain image framebuffers.
This should allow the `draw` renderer to draw on top of existing
graphics in the case that a background was not specified.
Now that vulkano 0.12.0 is out we're able to start stabilising
dependencies!

All that's left is to stabilise the `shade_runner` dev-dependency (used
within the `vk_hotload.rs` example) and we'll be able to publish v0.9!
Switch to stable dependencies for vulkano and conrod!
@mitchmindtree mitchmindtree added the v0.9 Specific to v0.9 label May 25, 2019
This saves on info duplication and keeps the README a bit cleaner!
Remove most README contents in favour of pointing to the guide
@Walther
Copy link

Walther commented May 26, 2019

Awesome work here, I'm excited for this to land! Is there any way in which i (or others) could help?

@freesig
Copy link
Collaborator

freesig commented May 27, 2019

I've bumped both shade_runner and moltenvk_deps so that should be all ready to go.
I've run nannou on windows and it works fine but I still want to run all the examples.
The only exception is it has an additional dependency of ninja which is not super simple to install. I might add to the readme on how to do that. Also add the cmake and python are required for all os.

I'd like to get to the bottom of this slow framerate on @JoshuaBatty laptop. I'm not seeing this unless the application is in the background #307 Can you please confirm josh if you are seeing a slow framerate with the application in the foreground?

MoltenVK segfault is fixed and just waiting on the next vulkansdk to be released

I'm going to run some profiling on windows and ubuntu. See what I can find.

Hey @Walther welcome. I'm excited to we are very close now. The only blockers are the website and the sdk.
I think the most helpful thing right now would be to checkout this branch and run the examples. Let us know if anything goes wrong or you get stuck on anything.

With a change this big and a team this small we are no doubt going run into some issues initially after release into the wild but the more people playing with it, the quicker we can find and fix them.

@Walther
Copy link

Walther commented May 27, 2019

A couple of hours of testing later:

nannou v0.9 branch testing

System details:

  • macOS Mojave 10.14.5 (18F132)
  • MacBook Pro (15-inch, 2018)
  • 2.6 GHz Intel Core i7
  • 16 GB 2400 MHz DDR4
  • Radeon Pro 560X 4 GB
  • Intel UHD Graphics 630 1536 MB

Key takeaways:

  • Exits can be unclean: segfaults, illegal hardware instruction
  • Resizing the window(s) has an extremely high likelihood for crashing immediately (>50% on an unscientific guesstimate)
  • All the examples that I tried seemed to run, possibly even correctly
    • Except for the Laser examples: couldn't figure those out on a quick test through
    • I skipped the examples/nature_of_code/ directories, because there's just so many examples there. Perhaps someone else can verify them?
  • One of the vulkan examples (vk_image_sequence) took disproportionately long time to load / even start the window
    • Would it be better to draw an empty window first or a loading screen?
  • vk_hotload example is magical, i'm in awe of both the hot reloading and the debug prints if one uses invalid values. Wish i had heard of this earlier! <3 This will make demoscene stuff so much easier to work with

Let me know if there's something you'd like to get more details on - happy to help!

Below, more verbose & individual comments on the test runs, in the order I ran the examples.

all_functions

  • Creates a window with a blue background
  • Interestingly enough, if I have Amethyst window manager on and it wants to resize the window, the example segfaults
  • On further testing, even manual repeated resizing can segafult the example

basics/1_nannou_events

  • Creates a window with a grey background
  • Prints out key events in the console
  • Pressing escape quits the example
    • Sometimes cleanly
    • Sometimes zsh: illegal hardware instruction
    • Sometimes zsh: segmentation fault

basics/2_variables_window_console

  • Creates a window with a grey background
  • Prints out a couple of variables in the console
  • Similar unclean quit issues

basics/3_variable_scope

  • Similar behaviors as above

basics/4_conditionals

  • Creates a window with a colored background and a colored dot in the middle
  • Colors change depending on mouse position within the window
  • Similar unclean quit issues

basics/5_loops

  • Creates a window with a grey background
  • Prints out a bunch of variables from loops to the console
  • Similar unclean quit issues

basics/6_functions

  • Creates a window with a grey background
  • On keypresses, various functions are called & their results are printed in the console
  • Similar unclean quit issues

loop_mode

  • Creates a window with a grey background
  • Events are printed on the console, e.g. mouse movement
  • Keypresses cause the loop mode to change, resulting in e.g. continuous logging
  • Really easy to get to crash via segfault! Press e.g. different arrow keys a couple of times

multi_window

  • Creates three windows, titles a b c, with different background colors
  • Mouse and keyboard events are printed in the console, including which window they targeted
  • Didn't crash on key and mouse events! (at least based on a limited time of attempts)
  • Crashes on resizes

osc_receiver && osc_sender

  • Requires two examples to be run
  • Receiver creates a blue window with white text
  • Sender creates a red window with white text
  • Mouse events in the sender window get transmitted to the receiver
  • The events are printed within the window itself, instead of the console log
  • Resizing windows segfaults again

simple_audio

  • Creates a window with a grey background
  • A sine wave sound plays
  • Controls: space stops/starts the sound, up arrow raises pitch, down arrow lowers pitch
  • Yup, still getting segfaults on resize

simple_draw

  • Creates a window with lots of simple graphical elements
  • Time and mouse position affect the elements
  • Resize = segfault

simple_mesh

  • Creates a window with a black background and a moving blue sine wave -esque filled path
  • Mouse position affects the frequency and amplitude of the "signal"
  • Resize caused zsh: illegal hardware instruction this time

simple_polygon

  • Creates a window with a black background and two pentagons, one in white and one with color gradient
  • Resize segfault

simple_polyline

  • Creates a window with a black background and a colored line consisting of blocks, animated to approximate a sine wave
  • Mouse movement again affects frequency
  • Resize crash

simple_ui

  • Creates a window with a simple ui for controlling a polygon
  • Resolution, Scale, Rotation, and Random Color controls are fast
  • Position control is super slow slideshow
  • Resize crash

simple_window

  • Creates a simple window with a blue background
  • Mouse and key events are printed to the console
  • Resize crash

template_app

  • Creates a window with a background color and a circle in the middle
  • Does not react to any key events
  • Resize crash

template_sketch

  • Effectively a 1:1 copy of the above

generative_design/p_1_0_01

  • Creates a large window with a colored background and a colored square in the middle
  • Mouse position affects the colors and the size of the square
  • Could not crash with resizing!

generative_design/p_1_1_01

  • Creates a small window with a grid of color hues and saturations
  • Mouse position affects the amount of grid elements and hence visible color choices
  • Could not crash with resizing!

generative_design/p_1_2_3_01

  • Creates a small window with a grid of various colors
  • Mouse position affects the amount of grid elements and colors
  • Crashes with resizing

generative_design/p_1_2_3_02

  • Creates a window with continuously appearing rectangles in various colors, painted on top of each other
  • Crashes with resizing

laser/laser_frame_stream

  • Creates a window with a grey background
  • Does not appear to do anything else?

laser/laser_frame_stream_gui

  • Creates a GUI window for controlling parameters
  • Doesn't seem to affect anything, even with the other laser_frame_stream windows open

laser/laser_raw_stream

  • Creates a window with a grey background and a white dot at the middle
    • On a second run, the white dot follows the mouse
  • Doesn't appear to do anything else?
  • Stacktrace from a crash (possibly related to having another of the examples running at the same time?)
    Finished dev [unoptimized + debuginfo] target(s) in 0.38s
     Running `target/debug/examples/laser_raw_stream`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', src/libcore/result.rs:997:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:59
             at src/libstd/panicking.rs:197
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:211
   4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at src/libstd/panicking.rs:474
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:381
   6: std::panicking::try::do_call
             at src/libstd/panicking.rs:308
   7: <T as core::any::Any>::type_id
             at src/libcore/panicking.rs:85
   8: core::result::unwrap_failed
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/macros.rs:18
   9: core::result::Result<T,E>::unwrap
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/result.rs:798
  10: laser_raw_stream::mouse_moved
             at examples/laser/laser_raw_stream.rs:70
  11: nannou::app::process_and_emit_winit_event
             at ./src/app.rs:1948
  12: nannou::app::poll_and_process_events
             at ./src/app.rs:1676
  13: nannou::app::run_loop_mode_refresh_sync
             at ./src/app.rs:1485
  14: nannou::app::run_loop
             at ./src/app.rs:1246
  15: nannou::app::Builder<M,E>::run
             at ./src/app.rs:636
  16: laser_raw_stream::main
             at examples/laser/laser_raw_stream.rs:7
  17: std::rt::lang_start::{{closure}}
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
  18: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:293
  19: panic_unwind::dwarf::eh::read_encoded_pointer
             at src/libpanic_unwind/lib.rs:87
  20: std::panicking::update_count_then_panic
             at src/libstd/panicking.rs:272
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  21: std::rt::lang_start
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
  22: laser_raw_stream::view

vulkan/vk_quad_warp

  • Creates two windows: one with a rotating Utah teapot, another with a GUI for controlling the corners
  • Moving the control dots causes the teapot to warp
  • Somehow the control dots are sometimes connected with a white line, sometimes not, depending on positions?
  • Resize crashes

vulkan/vk_shader_include

  • Creates a window with a grey background and a moving circle
  • Circle's color changes periodically
  • Resize crash

vulkan/vk_compute_shader

  • Creates a window with a black background and a blue-to-purple gradient in the shape of a pencil (sharp tip, then fills rest of rectangle)
  • Doesn't change over time
  • Starts with a wide window and the color gradient has gaps
  • Resizing to a smaller size makes the gradient full
  • Resizing can again cause crashes

vulkan/vk_debug

  • Creates a window with a blue background
  • Lots of debug prints in the console
  • Resizing crashes

vulkan/vk_hotload

  • Creates a window with a blue background and a white triangle
  • Editing the hotload shader files hot reloads the window
  • Adding invalid values in the shader file gives debug prints in the terminal
  • Hot dang this is magic, and would be so useful in demoscene stuff, i love this <3
  • Yup, same resize crash

vulkan/vk_image_sequence

  • Loads for quite a while compared to other examples (about 5 ish seconds without a window)
  • Colorful clock icon with super-fast spinning handles
  • Yup, same resize crash

vulkan/vk_image

  • Creates a window with a colorful background gradient that moves and nannou logo in white
  • Resize crash

vulkan/vk_images

  • Creates a window with image tiles
  • Resize crash

vulkan/vk_teapot_camera

  • Creates a window with a black background and a white teapot
  • WASD + mouse controls for moving around
  • Captures mouse, esc terminates example
  • Space unlocks / toggles mouse control
  • Resize crashes

vulkan/vk_teapot

  • Creates a window with a black background and a spinning teapot
  • No controls
  • Resize crashes

vulkan/vk_triangle_raw_frame

  • Creates a window with a blue background and a red triangle
  • Resize crashes

vulkan/vk_triangle

  • Effectively 1:1 copy of above

@freesig
Copy link
Collaborator

freesig commented May 27, 2019

Hey @Walther
Wow thanks for doing such a detailed test! This is very useful.
The segfault on close and resize is actually the Moltenvk bug I was talking about and is fixed in the lastest MoltenVK code but we need them to release the next vulkan sdk so that we can use this fix. This should be happening any day now.

The load time on the images example is interesting. I'll look into that.

I'm not sure about the laser examples perhaps @mitchmindtree or @JoshuaBatty might be of more help as they wrote it.

I'm glad you like the hot loader!

@freesig
Copy link
Collaborator

freesig commented May 27, 2019

Ok I can confirm all examples are working on Windows in release and debug. Nothing errors printed.

@freesig
Copy link
Collaborator

freesig commented May 27, 2019

Also @Walther did you run the vk_image_sequence like cargo run --release --example vk_image_sequence or cargo run --example vk_image_sequence?

@Walther
Copy link

Walther commented May 27, 2019

I ran the examples in default aka debug mode. Running it in release mode launches the window pretty quickly. I still found it interesting how big the difference was compared to the other examples - others launch the window under a second, vk_image_sequence takes 5+. Additionally, there's no indication that anything is loading, as the window gets drawn only after the whole thing is ready. (Should nannou have some setting/mode/default of drawing a base window immediately, while still loading/computing the content?)

These were not intended as a complaint or anything severe, just an interesting observation :)

@freesig
Copy link
Collaborator

freesig commented May 27, 2019

Ah yep so debug is way slower then release mode for rust.
I see what you mean. It's basically happening because the images are loaded (from disk) in the model function but the screen won't draw till until after that function returns.

The way you'd handle this in a proper application is to load the images on another thread but this might be adding a bit too much complexity to this example.
It might be worth making an example showing multi-threading in a Rust / nannou as some point though.

These were not intended as a complaint or anything severe, just an interesting observation :)

No worries at all. All feedback is welcome and valuable.

@mitchmindtree
Copy link
Member Author

Alright, I think it might be finally time to land this behemoth!

@mitchmindtree mitchmindtree merged commit 3f80293 into master May 28, 2019
@JoshuaBatty
Copy link
Member

JoshuaBatty commented May 28, 2019

Epic work everyone, amazing to have this merged now! Onwards to 0.10 :)

mitchmindtree added a commit to mitchmindtree/nannou-website that referenced this pull request May 30, 2019
cc @JoshuaBatty, @freesig This is mostly just all the text for now!
Feel free to make any PRs to this branch to remove or add anything or
let me know here and I'll have a look again tomoz :)

TODO:

- [ ] Add inline links to "post contents" section near top.
- [ ] Syntax highlighting for code.
- [ ] Add some sweet pics and animations.
- [ ] Add the Vulkan-specific post (mostly a copy of [this stuff](nannou-org/nannou#240 (comment)) should be sweet?).
mitchmindtree added a commit to mitchmindtree/nannou-website that referenced this pull request Jun 7, 2019
cc @JoshuaBatty, @freesig This is mostly just all the text for now!
Feel free to make any PRs to this branch to remove or add anything or
let me know here and I'll have a look again tomoz :)

TODO:

- [ ] Add inline links to "post contents" section near top.
- [ ] Syntax highlighting for code.
- [ ] Add some sweet pics and animations.
- [ ] Add the Vulkan-specific post (mostly a copy of [this stuff](nannou-org/nannou#240 (comment)) should be sweet?).
mitchmindtree added a commit to mitchmindtree/nannou-website that referenced this pull request Jun 8, 2019
cc @JoshuaBatty, @freesig This is mostly just all the text for now!
Feel free to make any PRs to this branch to remove or add anything or
let me know here and I'll have a look again tomoz :)

TODO:

- [ ] Add inline links to "post contents" section near top.
- [ ] Syntax highlighting for code.
- [ ] Add some sweet pics and animations.
- [ ] Add the Vulkan-specific post (mostly a copy of [this stuff](nannou-org/nannou#240 (comment)) should be sweet?).
mitchmindtree added a commit to mitchmindtree/nannou-website that referenced this pull request Jun 8, 2019
cc @JoshuaBatty, @freesig This is mostly just all the text for now!
Feel free to make any PRs to this branch to remove or add anything or
let me know here and I'll have a look again tomoz :)

TODO:

- [ ] Add inline links to "post contents" section near top.
- [ ] Syntax highlighting for code.
- [ ] Add some sweet pics and animations.
- [ ] Add the Vulkan-specific post (mostly a copy of [this stuff](nannou-org/nannou#240 (comment)) should be sweet?).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v0.9 Specific to v0.9
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants