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

[WIP] Merge window creation between backends #2136

Closed

Conversation

goddessfreya
Copy link
Contributor

@goddessfreya goddessfreya commented Jun 10, 2018

Signed-off-by: Hal Gentz zegentzy@protonmail.com

Fixes #1619
PR checklist:

  • Make the gl backend work
  • Make the types better (I don't like wrapping everything in Arcs and Mutexes)
  • Make vulkan backend compile
  • Make metal backend compile
  • Make dx backend compile
  • Insure it still compiles when winit is disabled
  • Insure it won't make it harder for people in the future to disable glutin
  • make succeeds (on *nix)
  • make reftests succeeds
  • tested examples with the following backends: OpenGL and Vulkan back ends in ArchLinux

Sorry, something went wrong.

@goddessfreya goddessfreya force-pushed the merge-window-creation branch from 77af818 to c98b8b8 Compare June 12, 2018 02:11
@@ -375,6 +375,8 @@ pub trait Backend: 'static + Sized + Eq + Clone + Hash + fmt::Debug + Any + Send
type Fence: fmt::Debug + Any + Send + Sync;
type Semaphore: fmt::Debug + Any + Send + Sync;
type QueryPool: fmt::Debug + Any + Send + Sync;

type Window: Any + Send + Sync;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be here, ideally.
Could you explain the thought process that leaded you to this decision? GL should not affect our HAL API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the gl backend and the non gl backends use a different type for their windows, so I wanted to avoid having to define a type in the examples based on which backend is in use. But then I relized that we won't have a type to use for people not using either winit or glutin, so I'm already aware that it's going to need to get stripped out.

@goddessfreya goddessfreya force-pushed the merge-window-creation branch from 07fee6c to 15d9dc4 Compare June 25, 2018 04:45
@goddessfreya
Copy link
Contributor Author

Latest version was tested against rust-windowing/winit@c873c2d and goddessfreya/glutin@cdad4a9 FYI

@@ -886,9 +886,13 @@ impl command::RawCommandBuffer<Backend> for RawCommandBuffer {
for new_binding in &*desc_set.bindings.lock().unwrap() {
match new_binding {
n::DescSetBindings::Buffer {ty: btype, binding, buffer, offset, size} => {
let btype = match btype {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly necessary and could be separated into a separate PR.

@goddessfreya goddessfreya force-pushed the merge-window-creation branch from 15d9dc4 to cd1a044 Compare June 25, 2018 07:15
@goddessfreya
Copy link
Contributor Author

goddessfreya commented Jun 25, 2018

A couple notes:

  • While the changes here haven't been tested with multiwindow setups w/ the opengl backend, it should make supporting them easier.
  • Cargo.tomls will be returned to there prior state
  • The changes here limit users of gfx to one events loop per instance (and given they will likely only have one instance, that's basically one events loop per program). I think this is 100% OK because after talking with Franseska I discovered that they don't officially support more than 1 event loop per application. Nor do they support event loops not on the main thread on macOS.
  • The gl code isn't the most simplistic and I'd be up for ideas at simplifying it.
  • Insuring we are always on the main context (unless when we need to not be) is a possible source of bugs which might be hard to track down. Up for ideas on how to eliminate their possibility. (Maybe accessing a share should make it's context current? What if they try to access multiple contexts simultaneously?)
  • Now respecting the user's swap chain config is a couple changes away. I opted to not include it in this PR because I consider it out of this PRs scope (and more importantly, I'm lazy.)
  • We do open separate devices per window, but those are "handled" internally.)
  • Currently only works on linux (every backend) & windows (wgl), see Context sharing not implemented for many platforms rust-windowing/glutin#899 and Adds context sharing support for the X11 & Wayland backends rust-windowing/glutin#1031
  • Once this is in, hopefully we can do the portability cts stuff with the opengl backend (yay!)
  • Some changes here are to support glutin's (or was it winit?) new hidpi support model. (Don't remember which changes tho :( )

Anyways, I quick summary of this PR off the top of my head is that we:

  • Have instances make a windowed headless context.
  • We delay window making till swapchain creation.
  • When recreating a swapchain we don't recreate the window (comment in code for why)
  • When creating a swapchain the first time we make an vao, some shaders, a vbo with stuff for rendering a quad which we share between all instances.
  • When creating a swapchain, we open them a new share + window + context + image. This is stuff we can't share
  • When recreating a swapchain, we only recreate the image.
  • When the surface's compatibilities are queried for and the window has been already made, we give it the window's settings (cause we can't change them). If it hasn't we just give them everything because it doesn't matter since we ignore it anyways.
  • When doing rendering stuff, we render to the image belonging to the swapchain they want to render to.
  • When presenting, we switch to that swapchain's context, bind the texture & then render a quad (with that texture) to that window's framebuffer.

Edit: I've typed this big block of text at 1:34 AM so forgive me for any errors (and for the block of text).

Copy link
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I skimmed through it, need to re-read your comments and have another look.

let (window, _instance, mut adapters, mut surface) = {
let window = wb.build(&events_loop).unwrap();
let instance = back::Instance::create("gfx-rs quad", 1);
let instance = back::Instance::create("gfx-rs quad", 1, Arc::clone(&events_loop));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would this map to gfx-portability? We don't have the event loop when we are creating an instance there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no clue, I'd have to look into it.

@@ -424,6 +428,74 @@ impl Device {
}
}
}

pub fn create_shader_program<'a>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these changes a part of the windowing PR? or just refactoring accidentally got mixed in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to avoid re implementing create_shader_programs when making the shader for the swapchain quad stuff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need a shader?

pub struct Instance {
el: Arc<Mutex<glutin::EventsLoop>>,
context: glutin::Context,
pub(crate) quadvbo: Arc<Mutex<Option<u32>>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you can insert _ between words

Arc::new(Instance {
el,
context,
quadvbo: Arc::new(Mutex::new(None)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why aren't we initializing those here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't loaded the gl pointers yet nor done the stuff which is done when opening the device. I'm not actually sure what the opening the device stuff is done for so I avoided changing that code and just made the stuff get initialized when making a swap chain the first time.

Copy link
Contributor Author

@goddessfreya goddessfreya Jun 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could make the physical device & open the device once in the instance then just return those. I think that's what I'll change it to do, and then we can avoid reloading the gl ptrs in drop.

impl Drop for Instance {
fn drop(&mut self) {
unsafe {
let gl = gl::Gl::load_with(|s| self.context.get_proc_address(s) as *const _);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we loading GL pointers here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the instance doesn't have a copy of the share or the gl ptrs, so it's easier (and still correct) to just load them in again.

@kvark
Copy link
Member

kvark commented Jun 26, 2018

@zegentzy what do you think about my earlier plan to go with the "pure" GL context (for the Instance) and sharing for all the others (created per window/swapchain)? Would it still be compatible with your approach if we get rust-windowing/glutin#942 merged eventually?

@goddessfreya
Copy link
Contributor Author

I don't see why it wouldn't work, instead of sharing everything with the instance's context, we share them with each other. Then we need to make current the context for the window we are using.

Which method is preferable is up to debate, and I personally don't have an opinion on this.

@goddessfreya goddessfreya force-pushed the merge-window-creation branch 2 times, most recently from 964ff92 to 48c51b7 Compare June 27, 2018 00:22
@goddessfreya
Copy link
Contributor Author

We now all the shared stuff in the instance. We now automatically change contexts only when necessary.
Tested against rust-windowing/winit@c873c2d and goddessfreya/glutin@cdad4a9 FYI

@goddessfreya goddessfreya force-pushed the merge-window-creation branch from 48c51b7 to 291833c Compare June 27, 2018 20:51
@goddessfreya
Copy link
Contributor Author

We just blit fbo's now as discussed on gitter with @kvark .
Tested against rust-windowing/winit@c873c2d and goddessfreya/glutin@cdad4a9 FYI

@goddessfreya goddessfreya force-pushed the merge-window-creation branch 2 times, most recently from 073ed46 to cacdb1f Compare June 27, 2018 22:47

Unverified

This user has not yet uploaded their public signing key.
Signed-off-by: Hal Gentz <zegentzy@protonmail.com>
Fixes

Unverified

This user has not yet uploaded their public signing key.
Signed-off-by: Hal Gentz <zegentzy@protonmail.com>

Unverified

This user has not yet uploaded their public signing key.
Signed-off-by: Hal Gentz <zegentzy@protonmail.com>
Fixes

Unverified

This user has not yet uploaded their public signing key.
Signed-off-by: Hal Gentz <zegentzy@protonmail.com>
@goddessfreya
Copy link
Contributor Author

Honestly, this just makes the code a lot uglier, and after a five second glance at gfx-portability I relied that this wouldn't work. Shame, because the only reason I tried this was to get the GL backend to be added to gfx-portability.

I'll sleep on this and think of a different solution.

bors bot added a commit that referenced this pull request Jul 8, 2018
2211: Latest winit, dpi bugfix and remap descriptors fix. r=kvark a=ZeGentzy

Some minor fixes I did while working on #2136
PR checklist:
- [ ] `make` succeeds (on *nix)
- [ ] `make reftests` succeeds
- [x] tested examples with the following backends: gl + vulkan on archlinux


Co-authored-by: Hal Gentz <zegentzy@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants