-
Notifications
You must be signed in to change notification settings - Fork 535
WIP: Feature multiview #3323
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
base: master
Are you sure you want to change the base?
WIP: Feature multiview #3323
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an autogenerated code review.New suggestions: 2
Co-authored-by: monocodus[bot] <49363530+monocodus[bot]@users.noreply.github.com>
| pub struct PhysicalDeviceMultiviewProperties { | ||
| pub max_multiview_view_count: u32, | ||
| pub max_multiview_instance_index: u32, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Substitute for vk::PhysicalDeviceMultiviewProperties without any pointers that would prevent PhysicalDeviceProperties below from being Sync.
kvark
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Have a few small concerns about the current state of PR
src/backend/vulkan/src/device.rs
Outdated
|
|
||
| let dependencies = dependencies | ||
| .into_iter() | ||
| .collect::<Vec<ID::Item>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's use inplace_or_alloc_array instead
src/backend/vulkan/src/lib.rs
Outdated
| } | ||
|
|
||
| pub struct PhysicalDeviceProperties { | ||
| properties: vk::PhysicalDeviceProperties, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the properties.properies look a bit awful :)
maybe this field name should be raw or inner?
src/hal/src/lib.rs
Outdated
| const MESH_SHADER = 0x0000_0002_0000_0000 << 64; | ||
|
|
||
| /// Supports multiview | ||
| const MULTIVIEW = 0x0001_0000_0000_0000 << 64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be 0x0000_0004_0000_0000 and so on. No need to leave such a big gap with the mesh shader
| let mut multiview = None; | ||
|
|
||
| // Add extension infos to the p_next chain | ||
| if supports_extension(extensions, *KHR_MULTIVIEW) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something is not right here. Why are we checking for this extension in two places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is performed only once during the initialization of PhysicalDevices, I have now replaced the same check within PhysicalDevice::features(): https://github.com/gfx-rs/gfx/pull/3323/files#diff-44198a1b71ecb41e695db8b6967cd689R1028
src/backend/vulkan/src/lib.rs
Outdated
|
|
||
| Self { | ||
| properties: properties2.properties, | ||
| multiview: multiview.map(|multiview| multiview.into()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could write this as muiltiview.map(PhysicalDeviceMultiviewProperties::from)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an autogenerated code review.New suggestions: 6
| let (clear_attachments_mask, result) = inplace_it::inplace_or_alloc_array(dependencies.len(), |uninit_guard_dependencies| { | ||
| let dependencies = uninit_guard_dependencies.init_with_iter(dependencies); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let (clear_attachments_mask, result) = inplace_it::inplace_or_alloc_array(dependencies.len(), |uninit_guard_dependencies| { | |
| let dependencies = uninit_guard_dependencies.init_with_iter(dependencies); | |
| let (clear_attachments_mask, result) = | |
| inplace_it::inplace_or_alloc_array(dependencies.len(), |uninit_guard_dependencies| { | |
| let dependencies = uninit_guard_dependencies.init_with_iter(dependencies); |
generated by rustfmt
| let (clear_attachments_mask, result) = inplace_it::inplace_or_alloc_array(attachments.len(), |uninit_guard_attachments| { | ||
| let attachments = uninit_guard_attachments.init_with_iter(attachments); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let (clear_attachments_mask, result) = inplace_it::inplace_or_alloc_array(attachments.len(), |uninit_guard_attachments| { | |
| let attachments = uninit_guard_attachments.init_with_iter(attachments); | |
| let (clear_attachments_mask, result) = inplace_it::inplace_or_alloc_array( | |
| attachments.len(), | |
| |uninit_guard_attachments| { | |
| let attachments = uninit_guard_attachments.init_with_iter(attachments); |
generated by rustfmt
| .map(|&id| id as u32) | ||
| .collect::<Box<[_]>>(); | ||
| let resolves = subpass.resolves.iter().map(make_ref).collect::<Box<[_]>>(); | ||
|
|
||
| (colors, depth_stencil, inputs, preserves, resolves, subpass.view_mask) | ||
| }) | ||
| .collect::<Box<[_]>>(); | ||
|
|
||
| let result = inplace_it::inplace_or_alloc_array(dependencies.len(), |uninit_guard| { | ||
| let dependencies = | ||
| uninit_guard.init_with_iter(dependencies); | ||
| let subpasses = attachment_refs | ||
| .iter() | ||
| .map(|(colors, depth_stencil, inputs, preserves, resolves, _view_mask)| { | ||
| vk::SubpassDescription { | ||
| flags: vk::SubpassDescriptionFlags::empty(), | ||
| pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS, | ||
| input_attachment_count: inputs.len() as u32, | ||
| p_input_attachments: inputs.as_ptr(), | ||
| color_attachment_count: colors.len() as u32, | ||
| p_color_attachments: colors.as_ptr(), | ||
| p_resolve_attachments: if resolves.is_empty() { | ||
| ptr::null() | ||
| } else { | ||
| resolves.as_ptr() | ||
| }, | ||
| p_depth_stencil_attachment: match depth_stencil { | ||
| Some(ref aref) => aref as *const _, | ||
| None => ptr::null(), | ||
| }, | ||
| preserve_attachment_count: preserves.len() as u32, | ||
| p_preserve_attachments: preserves.as_ptr(), | ||
| } | ||
| }) | ||
| .collect::<Box<[_]>>(); | ||
|
|
||
| let multiview_enabled = self.shared.features.contains(Features::MULTIVIEW); | ||
|
|
||
| let view_masks = if multiview_enabled { | ||
| Some( | ||
| attachment_refs | ||
| .iter() | ||
| .map(|(_colors, _depth_stencil, _inputs, _preserves, _resolves, view_mask)| { | ||
| *view_mask |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .map(|&id| id as u32) | |
| .collect::<Box<[_]>>(); | |
| let resolves = subpass.resolves.iter().map(make_ref).collect::<Box<[_]>>(); | |
| (colors, depth_stencil, inputs, preserves, resolves, subpass.view_mask) | |
| }) | |
| .collect::<Box<[_]>>(); | |
| let result = inplace_it::inplace_or_alloc_array(dependencies.len(), |uninit_guard| { | |
| let dependencies = | |
| uninit_guard.init_with_iter(dependencies); | |
| let subpasses = attachment_refs | |
| .iter() | |
| .map(|(colors, depth_stencil, inputs, preserves, resolves, _view_mask)| { | |
| vk::SubpassDescription { | |
| flags: vk::SubpassDescriptionFlags::empty(), | |
| pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS, | |
| input_attachment_count: inputs.len() as u32, | |
| p_input_attachments: inputs.as_ptr(), | |
| color_attachment_count: colors.len() as u32, | |
| p_color_attachments: colors.as_ptr(), | |
| p_resolve_attachments: if resolves.is_empty() { | |
| ptr::null() | |
| } else { | |
| resolves.as_ptr() | |
| }, | |
| p_depth_stencil_attachment: match depth_stencil { | |
| Some(ref aref) => aref as *const _, | |
| None => ptr::null(), | |
| }, | |
| preserve_attachment_count: preserves.len() as u32, | |
| p_preserve_attachments: preserves.as_ptr(), | |
| } | |
| }) | |
| .collect::<Box<[_]>>(); | |
| let multiview_enabled = self.shared.features.contains(Features::MULTIVIEW); | |
| let view_masks = if multiview_enabled { | |
| Some( | |
| attachment_refs | |
| .iter() | |
| .map(|(_colors, _depth_stencil, _inputs, _preserves, _resolves, view_mask)| { | |
| *view_mask | |
| .enumerate() | |
| .filter_map(|(i, at)| { | |
| if at.load_op == vk::AttachmentLoadOp::CLEAR | |
| || at.stencil_load_op == vk::AttachmentLoadOp::CLEAR | |
| { | |
| Some(1 << i as u64) | |
| } else { | |
| None | |
| } |
generated by rustfmt
| .collect::<Vec<u32>>() | ||
| ) | ||
| } else { | ||
| None | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .collect::<Vec<u32>>() | |
| ) | |
| } else { | |
| None | |
| }; | |
| .sum(); | |
| let attachment_refs = subpasses | |
| .into_iter() | |
| .map(|subpass| { | |
| let subpass = subpass.borrow(); | |
| fn make_ref( | |
| &(id, layout): &pass::AttachmentRef, | |
| ) -> vk::AttachmentReference { | |
| vk::AttachmentReference { | |
| attachment: id as _, | |
| layout: conv::map_image_layout(layout), | |
| } | |
| } | |
| let colors = | |
| subpass.colors.iter().map(make_ref).collect::<Box<[_]>>(); | |
| let depth_stencil = subpass.depth_stencil.map(make_ref); | |
| let inputs = | |
| subpass.inputs.iter().map(make_ref).collect::<Box<[_]>>(); | |
| let preserves = subpass | |
| .preserves | |
| .iter() | |
| .map(|&id| id as u32) | |
| .collect::<Box<[_]>>(); | |
| let resolves = | |
| subpass.resolves.iter().map(make_ref).collect::<Box<[_]>>(); | |
| ( | |
| colors, | |
| depth_stencil, | |
| inputs, | |
| preserves, | |
| resolves, | |
| subpass.view_mask, | |
| ) | |
| }) | |
| .collect::<Box<[_]>>(); |
generated by rustfmt
| info_builder = info_builder.push_next(&mut multiview); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| info_builder = info_builder.push_next(&mut multiview); | |
| } | |
| let multiview_enabled = self.shared.features.contains(Features::MULTIVIEW); | |
| let view_masks = if multiview_enabled { | |
| Some( | |
| attachment_refs | |
| .iter() | |
| .map( | |
| |( | |
| _colors, | |
| _depth_stencil, | |
| _inputs, | |
| _preserves, | |
| _resolves, | |
| view_mask, | |
| )| { *view_mask }, | |
| ) | |
| .collect::<Vec<u32>>(), | |
| ) | |
| } else { | |
| None | |
| }; | |
| let view_offsets = if multiview_enabled { | |
| Some( | |
| dependencies | |
| .iter() | |
| .map(|dependency| dependency.borrow().view_offset) | |
| .collect::<Vec<i32>>(), | |
| ) | |
| } else { | |
| None | |
| }; | |
| let result = inplace_it::inplace_or_alloc_array( | |
| vk_dependencies.len(), | |
| |uninit_guard| { | |
| let vk_dependencies = uninit_guard.init_with_iter(vk_dependencies); | |
| let mut info_builder = vk::RenderPassCreateInfo::builder() | |
| .flags(vk::RenderPassCreateFlags::empty()) | |
| .attachments(&attachments) | |
| .subpasses(&subpasses) | |
| .dependencies(&vk_dependencies); | |
| let mut multiview; | |
| if multiview_enabled { | |
| multiview = vk::RenderPassMultiviewCreateInfo::builder() | |
| .view_masks(&view_masks.unwrap()) | |
| .view_offsets(&view_offsets.unwrap()) | |
| .correlation_masks(correlation_masks.unwrap()) | |
| .build(); | |
| info_builder = info_builder.push_next(&mut multiview); | |
| } | |
| self.shared | |
| .raw | |
| .create_render_pass(&info_builder.build(), None) | |
| }, | |
| ); |
generated by rustfmt
| self.shared.raw.create_render_pass(&info_builder.build(), None) | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| self.shared.raw.create_render_pass(&info_builder.build(), None) | |
| }); | |
| (clear_attachments_mask, result) | |
| }, | |
| ); |
generated by rustfmt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an autogenerated code review, only first 25 of 30 new suggestions are shown
| buffer, | ||
| command, | ||
| format as f, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| buffer, | |
| command, | |
| format as f, | |
| buffer, command, format as f, |
generated by rustfmt
| image as i, | ||
| memory as m, | ||
| pass, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| image as i, | |
| memory as m, | |
| pass, | |
| image as i, memory as m, pass, |
generated by rustfmt
| levels: 0 .. 1, | ||
| layers: 0 .. 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| levels: 0 .. 1, | |
| layers: 0 .. 1, | |
| levels: 0..1, | |
| layers: 0..1, |
generated by rustfmt
| wb.clone().with_title("quad view 1".to_string()).build(&event_loop).unwrap(), | ||
| wb.clone().with_title("quad view 2".to_string()).build(&event_loop).unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| wb.clone().with_title("quad view 1".to_string()).build(&event_loop).unwrap(), | |
| wb.clone().with_title("quad view 2".to_string()).build(&event_loop).unwrap(), | |
| wb.clone() | |
| .with_title("quad view 1".to_string()) | |
| .build(&event_loop) | |
| .unwrap(), | |
| wb.clone() | |
| .with_title("quad view 2".to_string()) | |
| .build(&event_loop) | |
| .unwrap(), |
generated by rustfmt
| *control_flow = winit::event_loop::ControlFlow::Wait; | ||
|
|
||
| match event { | ||
| winit::event::Event::WindowEvent { event, window_id, .. } => match event { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| winit::event::Event::WindowEvent { event, window_id, .. } => match event { | |
| winit::event::Event::WindowEvent { | |
| event, window_id, .. | |
| } => match event { |
generated by rustfmt
| unsafe { | ||
| device.create_pipeline_layout( | ||
| iter::once(&*set_layout), | ||
| &[(pso::ShaderStageFlags::VERTEX, 0 .. 8)], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| &[(pso::ShaderStageFlags::VERTEX, 0 .. 8)], | |
| &[(pso::ShaderStageFlags::VERTEX, 0..8)], |
generated by rustfmt
| let vertex_buffers = vec![ | ||
| pso::VertexBufferDesc { | ||
| binding: 0, | ||
| stride: mem::size_of::<Vertex>() as u32, | ||
| rate: VertexInputRate::Vertex, | ||
| }, | ||
| ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let vertex_buffers = vec![ | |
| pso::VertexBufferDesc { | |
| binding: 0, | |
| stride: mem::size_of::<Vertex>() as u32, | |
| rate: VertexInputRate::Vertex, | |
| }, | |
| ]; | |
| let vertex_buffers = vec![pso::VertexBufferDesc { | |
| binding: 0, | |
| stride: mem::size_of::<Vertex>() as u32, | |
| rate: VertexInputRate::Vertex, | |
| }]; |
generated by rustfmt
| w: extents[0].width as _, | ||
| h: extents[0].height as _, | ||
| }, | ||
| depth: 0.0 .. 1.0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| depth: 0.0 .. 1.0, | |
| depth: 0.0..1.0, |
generated by rustfmt
| w: extents[1].width as _, | ||
| h: extents[1].height as _, | ||
| }, | ||
| depth: 0.0 .. 1.0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| depth: 0.0 .. 1.0, | |
| depth: 0.0..1.0, |
generated by rustfmt
| } | ||
|
|
||
| fn get_window_index(&self, window_id: winit::window::WindowId) -> usize { | ||
| if window_id == self.windows[0].id() { 0 } else { 1 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if window_id == self.windows[0].id() { 0 } else { 1 } | |
| if window_id == self.windows[0].id() { | |
| 0 | |
| } else { | |
| 1 | |
| } |
generated by rustfmt
|
The @monocodus bot seems to have been recommending odd style changes, such as incorrect indentation, so I did not apply their suggestions this time. |
|
@Limeth we can deal with monocodus later. |
|
@Limeth Hey, I noticed you're having some problem with monocodus. I've tried to run rustfmt locally on a given code to figure out which part of the suggestion is wrong but it seems like it gives the same result as listed in the suggestion. Could you please point out the wrong indentation in the suggestion? Also please feel free to use our issue tracker to describe what exactly is wrong, so that our team can resolve the issue in a timely manner. |
|
@P-ignatovich Please see the suggested changes I approved previously: 2bfbd4d |
|
@Limeth Thank you for your answer! For now, I've disabled rustfmt in out default config so users don't get confused with its behavior. Thank you very much for your report! Hope we'll make it work better soon :) |
3e1f8b1 to
375af89
Compare
|
@Limeth are you going to come back to this PR? |
|
I would like to, but I've been hesitant because there's some kind of UB making it crash on the example, and I couldn't figure out what it was caused by. |
Once finished, Fixes #3303.
Hopefully the API usage is correct. An example demonstrating the Multiview feature would be desirable. Feedback is appreciated.
PR checklist:
makesucceeds (on *nix)make reftestssucceedsrustfmtrun on changed code