diff --git a/command/src/buffer/encoder.rs b/command/src/buffer/encoder.rs index 4975980f..4abf92cb 100644 --- a/command/src/buffer/encoder.rs +++ b/command/src/buffer/encoder.rs @@ -126,11 +126,10 @@ where /// device limit. /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindVertexBuffers.html - pub unsafe fn bind_vertex_buffers<'b>( - &mut self, - first_binding: u32, - buffers: impl IntoIterator, - ) where + pub unsafe fn bind_vertex_buffers<'b, I>(&mut self, first_binding: u32, buffers: I) + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -168,13 +167,17 @@ where /// # Safety /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindDescriptorSets.html - pub unsafe fn bind_graphics_descriptor_sets<'b>( + pub unsafe fn bind_graphics_descriptor_sets<'b, I, J>( &mut self, layout: &B::PipelineLayout, first_set: u32, - sets: impl IntoIterator, - offsets: impl IntoIterator, + sets: I, + offsets: J, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + J: IntoIterator, + J::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -205,13 +208,17 @@ where /// # Safety /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindDescriptorSets.html - pub unsafe fn bind_compute_descriptor_sets<'b>( + pub unsafe fn bind_compute_descriptor_sets<'b, I, J>( &mut self, layout: &B::PipelineLayout, first_set: u32, - sets: impl IntoIterator, - offsets: impl IntoIterator, + sets: I, + offsets: J, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + J: IntoIterator, + J::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -268,11 +275,10 @@ where /// Set viewports /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetViewport.html - pub unsafe fn set_viewports<'b>( - &mut self, - first_viewport: u32, - viewports: impl IntoIterator, - ) where + pub unsafe fn set_viewports<'b, I>(&mut self, first_viewport: u32, viewports: I) + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -287,11 +293,10 @@ where /// `maxViewports` device limit. /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetScissor.html - pub unsafe fn set_scissors<'b>( - &mut self, - first_scissor: u32, - rects: impl IntoIterator, - ) where + pub unsafe fn set_scissors<'b, I>(&mut self, first_scissor: u32, rects: I) + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -430,13 +435,15 @@ where /// Clear regions within bound framebuffer attachments /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdClearAttachments.html#vkCmdBeginRenderPass - pub unsafe fn clear_attachments( - &mut self, - clears: impl IntoIterator< - Item = impl std::borrow::Borrow, - >, - rects: impl IntoIterator>, - ) { + pub unsafe fn clear_attachments(&mut self, clears: I, rects: J) + where + I: IntoIterator, + I::Item: std::borrow::Borrow, + I::IntoIter: ExactSizeIterator, + J: IntoIterator, + J::Item: std::borrow::Borrow, + J::IntoIter: ExactSizeIterator, + { rendy_core::hal::command::CommandBuffer::clear_attachments(self.inner.raw, clears, rects); } @@ -631,10 +638,12 @@ where B: rendy_core::hal::Backend, { /// Execute commands from secondary buffers. - pub fn execute_commands( - &mut self, - submittables: impl IntoIterator>, - ) { + pub fn execute_commands(&mut self, submittables: I) + where + I: IntoIterator, + I::Item: Submittable, + I::IntoIter: ExactSizeIterator, + { let family = self.inner.family; unsafe { rendy_core::hal::command::CommandBuffer::execute_commands( @@ -771,10 +780,12 @@ where } /// Execute commands from secondary buffers. - pub fn execute_commands( - &mut self, - submittables: impl IntoIterator>, - ) { + pub fn execute_commands(&mut self, submittables: I) + where + I: IntoIterator, + I::Item: Submittable, + I::IntoIter: ExactSizeIterator, + { let family = self.inner.family; unsafe { rendy_core::hal::command::CommandBuffer::execute_commands( @@ -811,12 +822,10 @@ where /// length of the corresponding buffer. /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyBuffer.html - pub unsafe fn copy_buffer( - &mut self, - src: &B::Buffer, - dst: &B::Buffer, - regions: impl IntoIterator, - ) where + pub unsafe fn copy_buffer(&mut self, src: &B::Buffer, dst: &B::Buffer, regions: I) + where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -831,13 +840,15 @@ where /// Same as `copy_buffer()` /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyBufferToImage.html - pub unsafe fn copy_buffer_to_image( + pub unsafe fn copy_buffer_to_image( &mut self, src: &B::Buffer, dst: &B::Image, dst_layout: rendy_core::hal::image::Layout, - regions: impl IntoIterator, + regions: I, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -858,14 +869,16 @@ where /// Same as `copy_buffer()` /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyImage.html - pub unsafe fn copy_image( + pub unsafe fn copy_image( &mut self, src: &B::Image, src_layout: rendy_core::hal::image::Layout, dst: &B::Image, dst_layout: rendy_core::hal::image::Layout, - regions: impl IntoIterator, + regions: I, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -887,13 +900,15 @@ where /// Same as `copy_buffer()` /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyImageToBuffer.html - pub unsafe fn copy_image_to_buffer( + pub unsafe fn copy_image_to_buffer( &mut self, src: &B::Image, src_layout: rendy_core::hal::image::Layout, dst: &B::Buffer, - regions: impl IntoIterator, + regions: I, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); @@ -914,15 +929,17 @@ where /// Same as `copy_buffer()` /// /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBlitImage.html - pub unsafe fn blit_image( + pub unsafe fn blit_image( &mut self, src: &B::Image, src_layout: rendy_core::hal::image::Layout, dst: &B::Image, dst_layout: rendy_core::hal::image::Layout, filter: rendy_core::hal::image::Filter, - regions: impl IntoIterator, + regions: I, ) where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, C: Supports, { self.capability.assert(); diff --git a/core/Cargo.toml b/core/Cargo.toml index 61fd4544..bfc0c56a 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -26,9 +26,9 @@ vulkan = ["gfx-backend-vulkan"] no-slow-safety-checks = [] [dependencies] -gfx-hal = "0.5" -gfx-backend-empty = { version = "0.5", optional = true } -gfx-backend-gl = { version = "0.5", features = ["glutin"], default_features = false, optional = true } +gfx-hal = "0.6" +gfx-backend-empty = { version = "0.6", optional = true } +gfx-backend-gl = { version = "0.6", default_features = false, optional = true } lazy_static = "1.4.0" log = "0.4.11" parking_lot = "0.11.1" @@ -37,10 +37,10 @@ thread_profiler = "0.3.0" raw-window-handle = "0.3.3" [target.'cfg(all(target_os = "windows", not(target_arch = "wasm32")))'.dependencies] -gfx-backend-dx12 = { version = "0.5", optional = true } +gfx-backend-dx12 = { version = "0.6", optional = true } [target.'cfg(any(all(not(target_arch = "wasm32"), target_os = "macos"), all(target_arch = "aarch64", target_os = "ios")))'.dependencies] -gfx-backend-metal = { version = "0.5", optional = true } +gfx-backend-metal = { version = "0.6", optional = true } [target.'cfg(all(any(target_os = "windows", all(unix, not(any(target_os = "macos", target_os = "ios")))), not(target_arch = "wasm32")))'.dependencies] -gfx-backend-vulkan = { version = "0.5", features = ["x11"], optional = true } +gfx-backend-vulkan = { version = "0.6", features = ["x11"], optional = true } diff --git a/descriptor/Cargo.toml b/descriptor/Cargo.toml index 3771d0d4..d3dfd9c2 100644 --- a/descriptor/Cargo.toml +++ b/descriptor/Cargo.toml @@ -11,7 +11,7 @@ categories = ["rendering"] description = "Rendy's descriptor allocator" [dependencies] -gfx-hal = "0.5" +gfx-hal = "0.6" log = "0.4.11" relevant = { version = "0.4.2", features = ["log"] } smallvec = "1.5.1" diff --git a/descriptor/src/allocator.rs b/descriptor/src/allocator.rs index eae135db..75c06e2e 100644 --- a/descriptor/src/allocator.rs +++ b/descriptor/src/allocator.rs @@ -77,8 +77,7 @@ unsafe fn allocate_from_pool( let sets_were = allocation.len(); raw.allocate(std::iter::repeat(layout).take(count as usize), allocation) .map_err(|err| match err { - AllocationError::Host => OutOfMemory::Host, - AllocationError::Device => OutOfMemory::Device, + AllocationError::OutOfMemory(err) => err, err => { // We check pool for free descriptors and sets before calling this function, // so it can't be exhausted. diff --git a/descriptor/src/ranges.rs b/descriptor/src/ranges.rs index d936ab1d..90a9514d 100644 --- a/descriptor/src/ranges.rs +++ b/descriptor/src/ranges.rs @@ -276,3 +276,15 @@ impl<'a> Iterator for DescriptorRangesIter<'a> { } } } + +impl<'a> ExactSizeIterator for DescriptorRangesIter<'a> { + fn len(&self) -> usize { + let (lower, upper) = self.size_hint(); + // Note: This assertion is overly defensive, but it checks the invariant + // guaranteed by the trait. If this trait were rust-internal, + // we could use debug_assert!; assert_eq! will check all Rust user + // implementations too. + assert_eq!(upper, Some(lower)); + lower + } +} diff --git a/factory/src/blitter.rs b/factory/src/blitter.rs index d6b7b888..aee1d0b8 100644 --- a/factory/src/blitter.rs +++ b/factory/src/blitter.rs @@ -21,16 +21,6 @@ pub struct Blitter { family_ops: Vec>>>, } -fn subresource_to_range( - sub: &rendy_core::hal::image::SubresourceLayers, -) -> rendy_core::hal::image::SubresourceRange { - rendy_core::hal::image::SubresourceRange { - aspects: sub.aspects, - levels: sub.level..sub.level + 1, - layers: sub.layers.clone(), - } -} - /// A region to be blitted including the source and destination images and states, #[derive(Debug, Clone)] pub struct BlitRegion { @@ -331,7 +321,7 @@ pub unsafe fn blit_image( .map(|reg| { read_barriers.add_image( src_image.clone(), - subresource_to_range(®.src.subresource), + reg.src.subresource.clone().into(), reg.src.last_stage, reg.src.last_access, reg.src.last_layout, @@ -343,7 +333,7 @@ pub unsafe fn blit_image( write_barriers.add_image( dst_image.clone(), - subresource_to_range(®.dst.subresource), + reg.dst.subresource.clone().into(), reg.dst.last_stage, reg.dst.last_access, reg.dst.last_layout, diff --git a/factory/src/upload.rs b/factory/src/upload.rs index 75e06971..92ff3b21 100644 --- a/factory/src/upload.rs +++ b/factory/src/upload.rs @@ -293,11 +293,7 @@ where let whole_level = image_offset == rendy_core::hal::image::Offset::ZERO && image_extent == whole_extent; - let image_range = rendy_core::hal::image::SubresourceRange { - aspects: image_layers.aspects, - levels: image_layers.level..image_layers.level + 1, - layers: image_layers.layers.clone(), - }; + let image_range = image_layers.clone().into(); let (last_stage, mut last_access, last_layout) = match last { ImageStateOrLayout::State(last) => { diff --git a/graph/src/graph/mod.rs b/graph/src/graph/mod.rs index bca493fc..6b5a630b 100644 --- a/graph/src/graph/mod.rs +++ b/graph/src/graph/mod.rs @@ -601,8 +601,10 @@ fn build_node<'a, B: Backend, T: ?Sized>( id, range: rendy_core::hal::image::SubresourceRange { aspects: image.format().surface_desc().aspects, - levels: 0..image.levels(), - layers: 0..image.layers(), + level_start: 0, + level_count: Some(image.levels()), + layer_start: 0, + layer_count: Some(image.layers()), }, layout: chains.images[&chain_id].links()[link] .submission_state(submission.id()) diff --git a/graph/src/node/present.rs b/graph/src/node/present.rs index e508cc56..f0d51de4 100644 --- a/graph/src/node/present.rs +++ b/graph/src/node/present.rs @@ -130,8 +130,10 @@ fn create_per_image_data( target: target_image.raw(), range: rendy_core::hal::image::SubresourceRange { aspects: rendy_core::hal::format::Aspects::COLOR, - levels: 0..1, - layers: 0..1, + level_start: 0, + level_count: Some(1), + layer_start: 0, + layer_count: Some(1), }, }); log::trace!("Acquire {:?} : {:#?}", stages, barriers); @@ -165,7 +167,7 @@ fn create_per_image_data( src_subresource: rendy_core::hal::image::SubresourceLayers { aspects: input_image.range.aspects, level: 0, - layers: input_image.range.layers.start..input_image.range.layers.start + 1, + layers: input_image.range.layer_start..input_image.range.layer_start + 1, }, src_bounds: rendy_core::hal::image::Offset::ZERO .into_bounds(&input_image_res.kind().extent()), @@ -191,7 +193,7 @@ fn create_per_image_data( src_subresource: rendy_core::hal::image::SubresourceLayers { aspects: input_image.range.aspects, level: 0, - layers: input_image.range.layers.start..input_image.range.layers.start + 1, + layers: input_image.range.layer_start..input_image.range.layer_start + 1, }, src_offset: rendy_core::hal::image::Offset::ZERO, dst_subresource: rendy_core::hal::image::SubresourceLayers { @@ -228,9 +230,11 @@ fn create_per_image_data( target: target_image.raw(), range: rendy_core::hal::image::SubresourceRange { aspects: rendy_core::hal::format::Aspects::COLOR, - levels: 0..1, - layers: 0..1, - }, + level_start: 0, + level_count: Some(1), + layer_start: 0, + layer_count: Some(1), + }, }); log::trace!("Release {:?} : {:#?}", stages, barriers); diff --git a/graph/src/node/render/group/simple.rs b/graph/src/node/render/group/simple.rs index 1b824e63..3a674bdf 100644 --- a/graph/src/node/render/group/simple.rs +++ b/graph/src/node/render/group/simple.rs @@ -292,23 +292,10 @@ where h: framebuffer_height as i16, }; - let shaders = match shader_set.raw() { - Err(e) => { - shader_set.dispose(factory); - log::warn!("Shader error {:?}", e); - return Err(rendy_core::hal::pso::CreationError::Other); - } - Ok(s) => s, - }; - let graphics_pipeline = unsafe { factory.device().create_graphics_pipelines( Some(rendy_core::hal::pso::GraphicsPipelineDesc { - shaders, rasterizer: pipeline.rasterizer, - vertex_buffers, - attributes, - input_assembler: pipeline.input_assembler_desc, blender: rendy_core::hal::pso::BlendDesc { logic_op: None, targets: pipeline.colors.clone(), @@ -328,6 +315,10 @@ where subpass, flags: rendy_core::hal::pso::PipelineCreationFlags::empty(), parent: rendy_core::hal::pso::BasePipeline::None, + + // FIXME FIXME + primitive_assembler: (), + fragment: None, }), None, ) diff --git a/graph/src/node/render/pass.rs b/graph/src/node/render/pass.rs index 189caa5b..7b5baa2d 100644 --- a/graph/src/node/render/pass.rs +++ b/graph/src/node/render/pass.rs @@ -479,7 +479,7 @@ where framebuffer_height = min(framebuffer_height, extent.height); framebuffer_layers = min( framebuffer_layers, - node_image.range.layers.end - node_image.range.layers.start, + node_image.range.layer_count.unwrap_or(1), ); Ok(vec![unsafe { factory @@ -493,7 +493,7 @@ where // NOTE: Framebuffer must always be created with only one mip level. If image contains multiple levels, // only the first one is bound as an attachment. // TODO: Allow customizing this behaviour to choose which level to bind. - levels: 0 .. 1, + level_count: Some(1), ..node_image.range.clone() } ) @@ -555,8 +555,10 @@ where rendy_core::hal::format::Swizzle::NO, rendy_core::hal::image::SubresourceRange { aspects: image.format().surface_desc().aspects, - levels: 0 .. 1, - layers: 0 .. 1, + level_start: 0, + level_count: Some(1), + layer_start: 0, + layer_count: Some(1) }, ) .map_err(NodeBuildError::View) diff --git a/init/src/windowed.rs b/init/src/windowed.rs index 331ee331..fc25e4f0 100644 --- a/init/src/windowed.rs +++ b/init/src/windowed.rs @@ -133,7 +133,7 @@ impl WindowedRendy { #![allow(unused_variables)] rendy_backend!(match (EnabledBackend::which::()): EnabledBackend { - Gl => { identical_cast(WindowedRendy::init_gl(config, window_builder, event_loop)) } + // Gl => { identical_cast(WindowedRendy::init_gl(config, window_builder, event_loop)) } _ => { Self::init_non_gl(config, Cow::Owned(window_builder), event_loop) } }) } @@ -147,7 +147,7 @@ impl WindowedRendy { #![allow(unused_variables)] rendy_backend!(match (EnabledBackend::which::()): EnabledBackend { - Gl => { identical_cast(WindowedRendy::init_gl(config, window_builder.clone(), event_loop)) } + // Gl => { identical_cast(WindowedRendy::init_gl(config, window_builder.clone(), event_loop)) } _ => { Self::init_non_gl(config, Cow::Borrowed(window_builder), event_loop) } }) } @@ -267,58 +267,58 @@ impl AnyWindowedRendy { } } -rendy_with_gl_backend! { - /// Wrap raw GL surface. - #[allow(unused)] - unsafe fn wrap_surface(factory: &Factory, surface: rendy_core::gl::Surface) -> Surface { - Surface::from_raw(surface, factory.instance_id()) - } - - rendy_not_wasm32! { - impl WindowedRendy { - pub fn init_gl(config: &Config, window_builder: WindowBuilder, event_loop: &EventLoop) -> Result { - use {hal::format::AsFormat, rendy_core::Instance}; - - let windowed_context = unsafe { - let builder = rendy_core::gl::config_context( - rendy_core::gl::glutin::ContextBuilder::new(), - hal::format::Rgba8Srgb::SELF, - None, - ) - .with_vsync(true); // TODO: Unhardcode it. - - builder - .build_windowed(window_builder, event_loop) - .map_err(|err| WindowedRendyInitError::Other(format!("{}", err)))? - .make_current() - .map_err(|(_ctx, err)| WindowedRendyInitError::Other(format!("{}", err)))? - }; - let (context, window) = unsafe { windowed_context.split() }; - let surface = rendy_core::gl::Surface::from_context(context); - let instance = Instance::new(rendy_core::gl::Instance::Surface(surface)); - - let (factory, families) = rendy_factory::init_with_instance_ref(&instance, config)?; - let surface = match rendy_core::Instance::into_raw(instance) { - rendy_core::gl::Instance::Surface(surface) => surface, - _ => unreachable!(), - }; - let surface = unsafe { wrap_surface(&factory, surface) }; - Ok(WindowedRendy {factory, families, surface, window }) - } - } - } - - rendy_wasm32! { - impl WindowedRendy { - pub fn init_gl(config: &Config, window_builder: WindowBuilder, event_loop: &EventLoop) -> Result { - let window = window_builder.build(event_loop)?; - let surface = rendy_core::gl::Surface::from_raw_handle(&window); - let instance = rendy_core::Instance::new(surface); - - let (factory, families) = rendy_factory::init_with_instance_ref(&instance, config)?; - let surface = unsafe { wrap_surface(&factory, instance.into_raw()) }; - Ok(WindowedRendy {factory, families, surface, window }) - } - } - } -} +// rendy_with_gl_backend! { +// /// Wrap raw GL surface. +// #[allow(unused)] +// unsafe fn wrap_surface(factory: &Factory, surface: rendy_core::gl::Surface) -> Surface { +// Surface::from_raw(surface, factory.instance_id()) +// } + +// rendy_not_wasm32! { +// impl WindowedRendy { +// pub fn init_gl(config: &Config, window_builder: WindowBuilder, event_loop: &EventLoop) -> Result { +// use {hal::format::AsFormat, rendy_core::Instance}; + +// let windowed_context = unsafe { +// let builder = rendy_core::gl::config_context( +// rendy_core::gl::glutin::ContextBuilder::new(), +// hal::format::Rgba8Srgb::SELF, +// None, +// ) +// .with_vsync(true); // TODO: Unhardcode it. + +// builder +// .build_windowed(window_builder, event_loop) +// .map_err(|err| WindowedRendyInitError::Other(format!("{}", err)))? +// .make_current() +// .map_err(|(_ctx, err)| WindowedRendyInitError::Other(format!("{}", err)))? +// }; +// let (context, window) = unsafe { windowed_context.split() }; +// let surface = rendy_core::gl::Surface::from_context(context); +// let instance = Instance::new(rendy_core::gl::Instance::Surface(surface)); + +// let (factory, families) = rendy_factory::init_with_instance_ref(&instance, config)?; +// let surface = match rendy_core::Instance::into_raw(instance) { +// rendy_core::gl::Instance::Surface(surface) => surface, +// _ => unreachable!(), +// }; +// let surface = unsafe { wrap_surface(&factory, surface) }; +// Ok(WindowedRendy {factory, families, surface, window }) +// } +// } +// } + +// rendy_wasm32! { +// impl WindowedRendy { +// pub fn init_gl(config: &Config, window_builder: WindowBuilder, event_loop: &EventLoop) -> Result { +// let window = window_builder.build(event_loop)?; +// let surface = rendy_core::gl::Surface::from_raw_handle(&window); +// let instance = rendy_core::Instance::new(surface); + +// let (factory, families) = rendy_factory::init_with_instance_ref(&instance, config)?; +// let surface = unsafe { wrap_surface(&factory, instance.into_raw()) }; +// Ok(WindowedRendy {factory, families, surface, window }) +// } +// } +// } +// } diff --git a/memory/Cargo.toml b/memory/Cargo.toml index 22d32b54..114c8640 100644 --- a/memory/Cargo.toml +++ b/memory/Cargo.toml @@ -14,7 +14,7 @@ description = "Rendy's memory manager" serde-1 = ["serde", "gfx-hal/serde"] [dependencies] -gfx-hal = "0.5" +gfx-hal = "0.6" log = "0.4.11" hibitset = { version = "0.6.3", default-features = false } relevant = { version = "0.4.2", features = ["log"] } diff --git a/mesh/src/mesh.rs b/mesh/src/mesh.rs index 99e77616..1fb73c69 100644 --- a/mesh/src/mesh.rs +++ b/mesh/src/mesh.rs @@ -382,7 +382,7 @@ where fn get_vertex_iter<'a>( &'a self, formats: &[VertexFormat], - ) -> Result, Incompatible> { + ) -> Result, Incompatible> { debug_assert!(is_slice_sorted(formats), "Formats: {:#?}", formats); debug_assert!(is_slice_sorted_by_key(&self.vertex_layouts, |l| &l.format)); @@ -407,7 +407,11 @@ where } let buffer = self.vertex_buffer.raw(); - Ok(vertex.into_iter().map(move |offset| (buffer, offset))) + Ok(vertex + .into_iter() + .map(move |offset| (buffer, offset)) + .collect::>() + .into_iter()) } /// Bind buffers to specified attribute locations. diff --git a/resource/src/buffer.rs b/resource/src/buffer.rs index 7575a620..6df48cf2 100644 --- a/resource/src/buffer.rs +++ b/resource/src/buffer.rs @@ -69,7 +69,7 @@ where let block = heaps .allocate( device, - reqs.type_mask as u32, + reqs.type_mask, memory_usage, reqs.size, reqs.alignment, diff --git a/resource/src/image.rs b/resource/src/image.rs index 0efd94fe..cc4b4723 100644 --- a/resource/src/image.rs +++ b/resource/src/image.rs @@ -73,10 +73,10 @@ where memory_usage: impl MemoryUsage, ) -> Result { assert!( - info.levels <= info.kind.num_levels(), + info.levels <= info.kind.compute_num_levels(), "Number of mip leves ({}) cannot be greater than {} for given kind {:?}", info.levels, - info.kind.num_levels(), + info.kind.compute_num_levels(), info.kind, ); @@ -96,7 +96,7 @@ where let block = heaps .allocate( device, - reqs.type_mask as u32, + reqs.type_mask, memory_usage, reqs.size, reqs.alignment, @@ -116,17 +116,6 @@ where }) } - /// Create image handler for swapchain image. - pub unsafe fn create_from_swapchain(device: DeviceId, info: ImageInfo, raw: B::Image) -> Self { - Image { - device, - raw, - block: None, - info, - relevant: Relevant, - } - } - /// Destroy image resource. pub unsafe fn dispose(self, device: &Device, heaps: &mut Heaps) { self.assert_device_owner(device); @@ -249,8 +238,10 @@ where info.swizzle, SubresourceRange { aspects: info.range.aspects, - layers: info.range.layers.clone(), - levels: info.range.levels.clone(), + level_start: info.range.level_start, + level_count: info.range.level_count, + layer_start: info.range.layer_start, + layer_count: info.range.layer_count, }, ) .map_err(CreationError::Create)? diff --git a/shader/Cargo.toml b/shader/Cargo.toml index abb3d9f5..60fc63f1 100644 --- a/shader/Cargo.toml +++ b/shader/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "rendy-shader" version = "0.5.1" -authors = ["omni-viral ", "Walter Pearce "] +authors = [ + "omni-viral ", + "Walter Pearce ", +] edition = "2018" repository = "https://github.com/amethyst/rendy" license = "MIT OR Apache-2.0" @@ -12,7 +15,7 @@ description = "Rendy's shader compilation tool" [features] shader-compiler = ["shaderc"] -spirv-reflection = [ "spirv-reflect" ] +spirv-reflection = ["spirv-reflect"] serde-1 = ["serde", "rendy-core/serde-1"] [dependencies] @@ -23,3 +26,4 @@ rendy-core = { version = "0.5.1", path = "../core" } shaderc = { version = "0.7.0", optional = true } serde = { version = "1.0.118", optional = true, features = ["derive"] } spirv-reflect = { version = "0.2.3", optional = true } +gfx-auxil = "0.7.0" diff --git a/shader/src/lib.rs b/shader/src/lib.rs index 795796e1..f39b877e 100644 --- a/shader/src/lib.rs +++ b/shader/src/lib.rs @@ -84,8 +84,12 @@ pub struct SpirvShader { entry: String, } +use gfx_auxil::read_spirv; + #[cfg(feature = "serde")] mod serde_spirv { + use gfx_auxil::read_spirv; + pub fn serialize(data: &Vec, serializer: S) -> Result where S: serde::Serializer, @@ -99,8 +103,7 @@ mod serde_spirv { { // Via the serde::Deserialize impl for &[u8]. let bytes: &[u8] = serde::Deserialize::deserialize(deserializer)?; - rendy_core::hal::pso::read_spirv(std::io::Cursor::new(bytes)) - .map_err(serde::de::Error::custom) + read_spirv(std::io::Cursor::new(bytes)).map_err(serde::de::Error::custom) } } @@ -123,7 +126,7 @@ impl SpirvShader { entrypoint: &str, ) -> std::io::Result { Ok(Self::new( - rendy_core::hal::pso::read_spirv(std::io::Cursor::new(spirv))?, + read_spirv(std::io::Cursor::new(spirv))?, stage, entrypoint, )) @@ -176,36 +179,6 @@ impl ShaderSet { Ok(self) } - /// Returns the `GraphicsShaderSet` structure to provide all the runtime information needed to use the shaders in this set in rendy_core::hal. - pub fn raw<'a>( - &'a self, - ) -> Result, ShaderError> { - Ok(rendy_core::hal::pso::GraphicsShaderSet { - vertex: self - .shaders - .get(&ShaderStageFlags::VERTEX) - .expect("ShaderSet doesn't contain vertex shader") - .get_entry_point()? - .unwrap(), - fragment: match self.shaders.get(&ShaderStageFlags::FRAGMENT) { - Some(fragment) => fragment.get_entry_point()?, - None => None, - }, - domain: match self.shaders.get(&ShaderStageFlags::DOMAIN) { - Some(domain) => domain.get_entry_point()?, - None => None, - }, - hull: match self.shaders.get(&ShaderStageFlags::HULL) { - Some(hull) => hull.get_entry_point()?, - None => None, - }, - geometry: match self.shaders.get(&ShaderStageFlags::GEOMETRY) { - Some(geometry) => geometry.get_entry_point()?, - None => None, - }, - }) - } - /// Must be called to perform a drop of the Backend ShaderModule object otherwise the shader will never be destroyed in memory. pub fn dispose(&mut self, factory: &rendy_factory::Factory) { for (_, shader) in self.shaders.iter_mut() { diff --git a/texture/src/texture.rs b/texture/src/texture.rs index d71b2bb3..97fd4586 100644 --- a/texture/src/texture.rs +++ b/texture/src/texture.rs @@ -447,8 +447,10 @@ impl<'a> TextureBuilder<'a> { image.clone(), image::SubresourceRange { aspects: info.format.surface_desc().aspects, - levels: 1..mip_levels, - layers: 0..info.kind.num_layers(), + level_start: 1, + level_count: Some(mip_levels), + layer_start: 0, + layer_count: Some(info.kind.num_layers()), }, image::Layout::Undefined, next_state, @@ -467,8 +469,10 @@ impl<'a> TextureBuilder<'a> { swizzle: double_swizzle(self.swizzle, transform_swizzle), range: image::SubresourceRange { aspects: info.format.surface_desc().aspects, - levels: 0..info.levels, - layers: 0..info.kind.num_layers(), + level_start: 0, + level_count: Some(info.levels), + layer_start: 0, + layer_count: Some(info.kind.num_layers()), }, }, ) diff --git a/wsi/src/lib.rs b/wsi/src/lib.rs index 7e818382..c5d6d899 100644 --- a/wsi/src/lib.rs +++ b/wsi/src/lib.rs @@ -11,9 +11,13 @@ unused_qualifications )] +use hal::window::AcquireError; +use hal::window::PresentationSurface; +use relevant::Relevant; +use rendy_core::hal; + use { - rendy_core::hal::{ - device::Device as _, + hal::{ format::Format, window::{Extent2D, Surface as _, SurfaceCapabilities}, Backend, Instance as _, @@ -21,18 +25,18 @@ use { rendy_core::{ device_owned, instance_owned, Device, DeviceId, HasRawWindowHandle, Instance, InstanceId, }, - rendy_resource::{Image, ImageInfo}, + rendy_resource::Image, }; /// Error creating a new swapchain. #[derive(Debug)] pub enum SwapchainError { /// Internal error in gfx-hal. - Create(rendy_core::hal::window::CreationError), + Create(hal::window::CreationError), /// Present mode is not supported. - BadPresentMode(rendy_core::hal::window::PresentMode), + BadPresentMode(hal::window::PresentMode), /// Image count is not supported. - BadImageCount(rendy_core::hal::window::SwapImageIndex), + BadImageCount(hal::window::SwapImageIndex), } impl std::fmt::Display for SwapchainError { @@ -93,7 +97,7 @@ where pub fn new( instance: &Instance, handle: &impl HasRawWindowHandle, - ) -> Result { + ) -> Result { let raw = unsafe { instance.create_surface(handle) }?; Ok(Surface { raw, @@ -134,6 +138,10 @@ where &self.raw } + pub fn raw_mut(&mut self) -> &mut B::Surface { + &mut self.raw + } + /// Get current extent of the surface. pub unsafe fn extent(&self, physical_device: &B::PhysicalDevice) -> Option { self.capabilities(physical_device).current_extent @@ -149,7 +157,7 @@ where let desc = base.0.desc(); ( !desc.is_compressed(), - base.1 == rendy_core::hal::format::ChannelType::Srgb, + base.1 == hal::format::ChannelType::Srgb, desc.bits, ) }) @@ -187,8 +195,8 @@ where device: &Device, suggest_extent: Extent2D, image_count: u32, - present_mode: rendy_core::hal::window::PresentMode, - usage: rendy_core::hal::image::Usage, + present_mode: hal::window::PresentMode, + usage: hal::image::Usage, ) -> Result, SwapchainError> { assert_eq!( device.id().instance, @@ -196,7 +204,7 @@ where "Resource is not owned by specified instance" ); - let (swapchain, backbuffer, extent) = create_swapchain( + let extent = create_swapchain( &mut self, physical_device, device, @@ -208,10 +216,8 @@ where Ok(Target { device: device.id(), - relevant: relevant::Relevant, + relevant: Relevant, surface: self, - swapchain: Some(swapchain), - backbuffer: Some(backbuffer), extent, present_mode, usage, @@ -225,9 +231,9 @@ unsafe fn create_swapchain( device: &Device, suggest_extent: Extent2D, image_count: u32, - present_mode: rendy_core::hal::window::PresentMode, - usage: rendy_core::hal::image::Usage, -) -> Result<(B::Swapchain, Vec>, Extent2D), SwapchainError> { + present_mode: hal::window::PresentMode, + usage: hal::image::Usage, +) -> Result { let capabilities = surface.capabilities(physical_device); let format = surface.format(physical_device); @@ -248,23 +254,6 @@ unsafe fn create_swapchain( log::trace!("Surface chosen format {:#?}", format); - if image_count < *capabilities.image_count.start() - || image_count > *capabilities.image_count.end() - { - log::warn!( - "Image count not supported. Supported: {:#?}, requested: {:#?}", - capabilities.image_count, - image_count - ); - return Err(SwapchainError::BadImageCount(image_count)); - } - - log::trace!( - "Surface capabilities: {:#?}. Pick {} images", - capabilities.image_count, - image_count - ); - assert!( capabilities.usage.contains(usage), "Surface supports {:?}, but {:?} was requested", @@ -274,50 +263,49 @@ unsafe fn create_swapchain( let extent = capabilities.current_extent.unwrap_or(suggest_extent); - let (swapchain, images) = device - .create_swapchain( - &mut surface.raw, - rendy_core::hal::window::SwapchainConfig { - present_mode, - format, - extent, - image_count, - image_layers: 1, - image_usage: usage, - composite_alpha_mode: [ - rendy_core::hal::window::CompositeAlphaMode::INHERIT, - rendy_core::hal::window::CompositeAlphaMode::OPAQUE, - rendy_core::hal::window::CompositeAlphaMode::PREMULTIPLIED, - rendy_core::hal::window::CompositeAlphaMode::POSTMULTIPLIED, - ] - .iter() - .cloned() - .find(|&bit| capabilities.composite_alpha_modes.contains(bit)) - .expect("No CompositeAlphaMode modes supported"), - }, - None, - ) - .map_err(SwapchainError::Create)?; - - let backbuffer = images - .into_iter() - .map(|image| { - Image::create_from_swapchain( - device.id(), - ImageInfo { - kind: rendy_core::hal::image::Kind::D2(extent.width, extent.height, 1, 1), - levels: 1, - format, - tiling: rendy_core::hal::image::Tiling::Optimal, - view_caps: rendy_core::hal::image::ViewCapabilities::empty(), - usage, - }, - image, - ) - }) - .collect(); - - Ok((swapchain, backbuffer, extent)) + let swap_config = hal::window::SwapchainConfig { + present_mode, + format, + extent, + image_count, + image_layers: 1, + image_usage: usage, + composite_alpha_mode: [ + hal::window::CompositeAlphaMode::INHERIT, + hal::window::CompositeAlphaMode::OPAQUE, + hal::window::CompositeAlphaMode::PREMULTIPLIED, + hal::window::CompositeAlphaMode::POSTMULTIPLIED, + ] + .iter() + .cloned() + .find(|&bit| capabilities.composite_alpha_modes.contains(bit)) + .expect("No CompositeAlphaMode modes supported"), + }; + + surface + .raw_mut() + .configure_swapchain(&device, swap_config) + .expect("Could not configure swapchain."); + + // let backbuffer = images + // .into_iter() + // .map(|image| Image { + // device: device.id(), + // block: None, + // relevant: Relevant, + // raw: image, + // info: ImageInfo { + // kind: hal::image::Kind::D2(extent.width, extent.height, 1, 1), + // levels: 1, + // format, + // tiling: hal::image::Tiling::Optimal, + // view_caps: hal::image::ViewCapabilities::empty(), + // usage, + // }, + // }) + // .collect(); + + Ok(extent) } /// Rendering target bound to window. @@ -325,12 +313,10 @@ unsafe fn create_swapchain( pub struct Target { device: DeviceId, surface: Surface, - swapchain: Option, - backbuffer: Option>>, extent: Extent2D, - present_mode: rendy_core::hal::window::PresentMode, - usage: rendy_core::hal::image::Usage, - relevant: relevant::Relevant, + present_mode: hal::window::PresentMode, + usage: hal::image::Usage, + relevant: Relevant, } device_owned!(Target); @@ -340,9 +326,7 @@ where B: Backend, { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt.debug_struct("Target") - .field("backbuffer", &self.backbuffer) - .finish() + fmt.debug_struct("Target").finish() } } @@ -355,22 +339,19 @@ where /// # Safety /// /// Swapchain must be not in use. - pub unsafe fn dispose(mut self, device: &Device) -> Surface { + pub unsafe fn dispose(self, device: &Device) -> Surface { self.assert_device_owner(device); - match self.backbuffer { - Some(images) => { - images - .into_iter() - .for_each(|image| image.dispose_swapchain_image(device.id())); - } - _ => {} - }; + // match self.backbuffer { + // Some(images) => { + // images + // .into_iter() + // .for_each(|image| image.dispose_swapchain_image(device.id())); + // } + // _ => {} + // }; self.relevant.dispose(); - if let Some(s) = self.swapchain.take() { - device.destroy_swapchain(s) - } self.surface } @@ -379,11 +360,6 @@ where &self.surface } - /// Get raw surface handle. - pub fn swapchain(&self) -> &B::Swapchain { - self.swapchain.as_ref().expect("Swapchain already disposed") - } - /// Recreate swapchain. /// /// #Safety @@ -397,52 +373,35 @@ where ) -> Result<(), SwapchainError> { self.assert_device_owner(device); - let image_count = match self.backbuffer.take() { - Some(images) => { - let count = images.len(); - images - .into_iter() - .for_each(|image| image.dispose_swapchain_image(device.id())); - count - } - None => 0, - }; - - if let Some(s) = self.swapchain.take() { - device.destroy_swapchain(s) - } - - let (swapchain, backbuffer, extent) = create_swapchain( + // let image_count = match self.backbuffer.take() { + // Some(images) => { + // let count = images.len(); + // images + // .into_iter() + // .for_each(|image| image.dispose_swapchain_image(device.id())); + // count + // } + // None => 0, + // }; + + let extent = create_swapchain( &mut self.surface, physical_device, device, suggest_extent, - image_count as u32, + 3, self.present_mode, self.usage, )?; - self.swapchain.replace(swapchain); - self.backbuffer.replace(backbuffer); self.extent = extent; Ok(()) } - /// Get swapchain impl trait. - /// - /// # Safety - /// - /// Trait usage should not violate this type valid usage. - pub unsafe fn swapchain_mut(&mut self) -> &mut impl rendy_core::hal::window::Swapchain { - self.swapchain.as_mut().expect("Swapchain already disposed") - } - /// Get raw handlers for the swapchain images. - pub fn backbuffer(&self) -> &Vec> { - self.backbuffer - .as_ref() - .expect("Swapchain already disposed") + pub fn backbuffer(&self) -> Vec> { + Vec::new() } /// Get render target size. @@ -451,28 +410,25 @@ where } /// Get image usage flags. - pub fn usage(&self) -> rendy_core::hal::image::Usage { + pub fn usage(&self) -> hal::image::Usage { self.usage } /// Acquire next image. pub unsafe fn next_image( &mut self, - signal: &B::Semaphore, - ) -> Result, rendy_core::hal::window::AcquireError> { - let index = rendy_core::hal::window::Swapchain::acquire_image( - // Missing swapchain is equivalent to OutOfDate, as it has to be recreated anyway. - self.swapchain - .as_mut() - .ok_or(rendy_core::hal::window::AcquireError::OutOfDate)?, - !0, - Some(signal), - None, - )? - .0; + _signal: &B::Semaphore, + ) -> Result, AcquireError> { + let surface_image = match self.surface.raw.acquire_image(!0) { + Ok((image, _)) => image, + Err(_) => { + // FIXME self.recreate_swapchain(); + return Err(AcquireError::OutOfDate); + } + }; Ok(NextImages { - targets: std::iter::once((&*self, index)).collect(), + targets: std::iter::once((&mut *self, surface_image)).collect(), }) } } @@ -480,53 +436,31 @@ where /// Represents acquire frames that will be presented next. #[derive(Debug)] pub struct NextImages<'a, B: Backend> { - targets: smallvec::SmallVec<[(&'a Target, u32); 8]>, + targets: smallvec::SmallVec< + [( + &'a mut Target, + <::Surface as PresentationSurface>::SwapchainImage, + ); 8], + >, } impl<'a, B> NextImages<'a, B> where B: Backend, { - /// Get indices. - pub fn indices(&self) -> impl IntoIterator + '_ { - self.targets.iter().map(|(_s, i)| *i) - } - /// Present images by the queue. - /// - /// # TODO - /// - /// Use specific presentation error type. pub unsafe fn present<'b>( self, - queue: &mut impl rendy_core::hal::queue::CommandQueue, - wait: impl IntoIterator + 'b)>, - ) -> Result, rendy_core::hal::window::PresentError> + queue: &mut impl hal::queue::CommandQueue, + wait: Option<&B::Semaphore>, + ) -> Result, hal::window::PresentError> where 'a: 'b, { - queue.present( - self.targets.iter().map(|(target, index)| { - ( - target - .swapchain - .as_ref() - .expect("Swapchain already disposed"), - *index, - ) - }), - wait, - ) - } -} - -impl<'a, B> std::ops::Index for NextImages<'a, B> -where - B: Backend, -{ - type Output = u32; - - fn index(&self, index: usize) -> &u32 { - &self.targets[index].1 + if let Some((target, image)) = self.targets.into_iter().next() { + queue.present(target.surface.raw_mut(), image, wait) + } else { + Err(hal::window::PresentError::OutOfDate) + } } }