From 1e52987fd802ae9cfc22f730e961d9582c9bf951 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Tue, 5 Jun 2018 18:56:24 +0200 Subject: [PATCH 1/4] hal,dx12: Add preliminary dynamic descriptor buffers --- src/backend/dx12/src/command.rs | 37 +++++++++++++++++++----------- src/backend/dx12/src/conv.rs | 7 +++--- src/backend/dx12/src/native.rs | 4 ++-- src/hal/src/command/compute.rs | 14 +++++++---- src/hal/src/command/graphics.rs | 14 +++++++---- src/hal/src/command/mod.rs | 5 +++- src/hal/src/command/raw.rs | 24 ++++++++++++------- src/hal/src/command/render_pass.rs | 14 +++++++---- src/hal/src/pso/descriptor.rs | 2 +- 9 files changed, 77 insertions(+), 44 deletions(-) diff --git a/src/backend/dx12/src/command.rs b/src/backend/dx12/src/command.rs index f36f6564827..2d098475797 100644 --- a/src/backend/dx12/src/command.rs +++ b/src/backend/dx12/src/command.rs @@ -166,15 +166,18 @@ impl PipelineCache { } } - fn bind_descriptor_sets<'a, T>( + fn bind_descriptor_sets<'a, I, J>( &mut self, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) -> [*mut d3d12::ID3D12DescriptorHeap; 2] where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { let mut sets = sets.into_iter().peekable(); let ( @@ -1739,16 +1742,19 @@ impl com::RawCommandBuffer for CommandBuffer { } } - fn bind_graphics_descriptor_sets<'a, T>( + fn bind_graphics_descriptor_sets<'a, I, J>( &mut self, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - self.active_descriptor_heaps = self.gr_pipeline.bind_descriptor_sets(layout, first_set, sets); + self.active_descriptor_heaps = self.gr_pipeline.bind_descriptor_sets(layout, first_set, sets, offsets); self.bind_descriptor_heaps(); } @@ -1773,16 +1779,19 @@ impl com::RawCommandBuffer for CommandBuffer { self.comp_pipeline.pipeline = Some((pipeline.raw, pipeline.signature)); } - fn bind_compute_descriptor_sets( + fn bind_compute_descriptor_sets( &mut self, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - self.active_descriptor_heaps = self.comp_pipeline.bind_descriptor_sets(layout, first_set, sets); + self.active_descriptor_heaps = self.comp_pipeline.bind_descriptor_sets(layout, first_set, sets, offsets); self.bind_descriptor_heaps(); } diff --git a/src/backend/dx12/src/conv.rs b/src/backend/dx12/src/conv.rs index 27372ee7c24..9169039f221 100644 --- a/src/backend/dx12/src/conv.rs +++ b/src/backend/dx12/src/conv.rs @@ -455,15 +455,16 @@ pub fn map_descriptor_range(bind: &DescriptorSetLayoutBinding, register_space: u pso::DescriptorType::InputAttachment | pso::DescriptorType::UniformTexelBuffer => D3D12_DESCRIPTOR_RANGE_TYPE_SRV, pso::DescriptorType::StorageBuffer | + pso::DescriptorType::StorageBufferDynamic | pso::DescriptorType::StorageTexelBuffer | pso::DescriptorType::StorageImage => D3D12_DESCRIPTOR_RANGE_TYPE_UAV, - pso::DescriptorType::UniformBuffer => D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + pso::DescriptorType::UniformBuffer | + pso::DescriptorType::UniformBufferDynamic => D3D12_DESCRIPTOR_RANGE_TYPE_CBV, pso::DescriptorType::CombinedImageSampler => if sampler { D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER } else { D3D12_DESCRIPTOR_RANGE_TYPE_SRV - }, - _ => panic!("unsupported binding type {:?}", bind.ty) + } }, NumDescriptors: bind.count as _, BaseShaderRegister: bind.binding as _, diff --git a/src/backend/dx12/src/native.rs b/src/backend/dx12/src/native.rs index c5a77b5d6fd..77ddd3fe302 100644 --- a/src/backend/dx12/src/native.rs +++ b/src/backend/dx12/src/native.rs @@ -556,12 +556,12 @@ impl HeapProperties { pso::DescriptorType::InputAttachment | pso::DescriptorType::SampledImage | pso::DescriptorType::UniformTexelBuffer | + pso::DescriptorType::UniformBufferDynamic | pso::DescriptorType::UniformBuffer => HeapProperties::new(true, false, false), pso::DescriptorType::StorageImage | pso::DescriptorType::StorageTexelBuffer | + pso::DescriptorType::StorageBufferDynamic | pso::DescriptorType::StorageBuffer => HeapProperties::new(true, false, true), - pso::DescriptorType::UniformBufferDynamic | - pso::DescriptorType::UniformImageDynamic => unimplemented!(), } } diff --git a/src/hal/src/command/compute.rs b/src/hal/src/command/compute.rs index 24a474425a3..9fccf2105a5 100644 --- a/src/hal/src/command/compute.rs +++ b/src/hal/src/command/compute.rs @@ -4,6 +4,7 @@ use std::borrow::Borrow; use {Backend, WorkGroupCount}; use buffer::Offset; +use command::raw::DescriptorSetOffset; use queue::capability::{Compute, Supports}; use super::{CommandBuffer, RawCommandBuffer, Shot, Level}; @@ -14,16 +15,19 @@ impl<'a, B: Backend, C: Supports, S: Shot, L: Level> CommandBuffer<'a, } /// Identical to the `RawCommandBuffer` method of the same name. - pub fn bind_compute_descriptor_sets( + pub fn bind_compute_descriptor_sets( &mut self, layout: &B::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - self.raw.bind_compute_descriptor_sets(layout, first_set, sets) + self.raw.bind_compute_descriptor_sets(layout, first_set, sets, offsets) } /// Identical to the `RawCommandBuffer` method of the same name. diff --git a/src/hal/src/command/graphics.rs b/src/hal/src/command/graphics.rs index 9a53e45cf73..1cf41174216 100644 --- a/src/hal/src/command/graphics.rs +++ b/src/hal/src/command/graphics.rs @@ -5,6 +5,7 @@ use std::ops::Range; use Backend; use {image, pso}; use buffer::IndexBufferView; +use command::raw::DescriptorSetOffset; use query::{Query, QueryControl, QueryId}; use queue::capability::{Graphics, GraphicsOrCompute, Supports}; use super::{ @@ -192,16 +193,19 @@ impl<'a, B: Backend, C: Supports, S: Shot, L: Level> CommandBuffer<'a, } /// Identical to the `RawCommandBuffer` method of the same name. - pub fn bind_graphics_descriptor_sets( + pub fn bind_graphics_descriptor_sets( &mut self, layout: &B::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - self.raw.bind_graphics_descriptor_sets(layout, first_set, sets) + self.raw.bind_graphics_descriptor_sets(layout, first_set, sets, offsets) } /// Identical to the `RawCommandBuffer` method of the same name. diff --git a/src/hal/src/command/mod.rs b/src/hal/src/command/mod.rs index 17c597f65e7..ab772f00851 100644 --- a/src/hal/src/command/mod.rs +++ b/src/hal/src/command/mod.rs @@ -24,7 +24,10 @@ mod render_pass; mod transfer; pub use self::graphics::*; -pub use self::raw::{ClearValueRaw, ClearColorRaw, ClearDepthStencilRaw, RawCommandBuffer, CommandBufferFlags, Level as RawLevel, CommandBufferInheritanceInfo}; +pub use self::raw::{ + ClearValueRaw, ClearColorRaw, ClearDepthStencilRaw, DescriptorSetOffset, + RawCommandBuffer, CommandBufferFlags, Level as RawLevel, CommandBufferInheritanceInfo, +}; pub use self::render_pass::*; pub use self::transfer::*; diff --git a/src/hal/src/command/raw.rs b/src/hal/src/command/raw.rs index 0cf08642a0c..991195925ec 100644 --- a/src/hal/src/command/raw.rs +++ b/src/hal/src/command/raw.rs @@ -48,6 +48,8 @@ pub union ClearValueRaw { _align: [u32; 4], } +/// Offset for dynamic descriptors. +pub type DescriptorSetOffset = u32; bitflags! { /// Option flags for various command buffer settings. @@ -304,14 +306,17 @@ pub trait RawCommandBuffer: Clone + Any + Send + Sync { /// Takes an iterator of graphics `DescriptorSet`'s, and binds them to the command buffer. /// `first_set` is the index that the first descriptor is mapped to in the command buffer. - fn bind_graphics_descriptor_sets( + fn bind_graphics_descriptor_sets( &mut self, layout: &B::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow; + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow; /// Bind a compute pipeline. /// @@ -326,14 +331,17 @@ pub trait RawCommandBuffer: Clone + Any + Send + Sync { /// Takes an iterator of compute `DescriptorSet`'s, and binds them to the command buffer, /// `first_set` is the index that the first descriptor is mapped to in the command buffer. - fn bind_compute_descriptor_sets( + fn bind_compute_descriptor_sets( &mut self, layout: &B::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow; + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow; /// Execute a workgroup in the compute pipeline. `x`, `y` and `z` are the /// number of local workgroups to dispatch along each "axis"; a total of `x`*`y`*`z` diff --git a/src/hal/src/command/render_pass.rs b/src/hal/src/command/render_pass.rs index 9d73aafcc92..06dbca7af6c 100644 --- a/src/hal/src/command/render_pass.rs +++ b/src/hal/src/command/render_pass.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use {buffer, pso}; use {Backend, DrawCount, IndexCount, InstanceCount, VertexCount, VertexOffset}; +use command::raw::DescriptorSetOffset; use queue::{Supports, Graphics}; use super::{ AttachmentClear, ClearValue, ClearValueRaw, CommandBuffer, RawCommandBuffer, @@ -75,16 +76,19 @@ impl<'a, B: Backend> RenderSubpassCommon<'a, B> { } /// - pub fn bind_graphics_descriptor_sets( + pub fn bind_graphics_descriptor_sets( &mut self, layout: &B::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - self.0.bind_graphics_descriptor_sets(layout, first_set, sets) + self.0.bind_graphics_descriptor_sets(layout, first_set, sets, offsets) } /// diff --git a/src/hal/src/pso/descriptor.rs b/src/hal/src/pso/descriptor.rs index 9415a27d9d9..db533a7e7bd 100644 --- a/src/hal/src/pso/descriptor.rs +++ b/src/hal/src/pso/descriptor.rs @@ -48,7 +48,7 @@ pub enum DescriptorType { /// UniformBufferDynamic = 8, /// - UniformImageDynamic = 9, + StorageBufferDynamic = 9, /// Allows unfiltered loads of pixel local data in the fragment shader. InputAttachment = 10, } From fb7ee6990eaf20f63815b29e4d163038e0757c4d Mon Sep 17 00:00:00 2001 From: msiglreith Date: Tue, 5 Jun 2018 19:37:12 +0200 Subject: [PATCH 2/4] gl,vk,empty: Adopt dynamic offset API changes --- src/backend/empty/src/lib.rs | 8 ++++-- src/backend/gl/src/command.rs | 22 ++++++++++------ src/backend/vulkan/src/command.rs | 41 +++++++++++++++++++----------- src/hal/src/command/compute.rs | 3 +-- src/hal/src/command/graphics.rs | 3 +-- src/hal/src/command/render_pass.rs | 3 +-- 6 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/backend/empty/src/lib.rs b/src/backend/empty/src/lib.rs index ef014531158..e30db8732aa 100644 --- a/src/backend/empty/src/lib.rs +++ b/src/backend/empty/src/lib.rs @@ -563,10 +563,12 @@ impl command::RawCommandBuffer for RawCommandBuffer { unimplemented!() } - fn bind_graphics_descriptor_sets(&mut self, _: &(), _: usize, _: I) + fn bind_graphics_descriptor_sets(&mut self, _: &(), _: usize, _: I, _: J) where I: IntoIterator, I::Item: Borrow<()>, + J: IntoIterator, + J::Item: Borrow, { unimplemented!() } @@ -575,10 +577,12 @@ impl command::RawCommandBuffer for RawCommandBuffer { unimplemented!() } - fn bind_compute_descriptor_sets(&mut self, _: &(), _: usize, _: I) + fn bind_compute_descriptor_sets(&mut self, _: &(), _: usize, _: I, _: J) where I: IntoIterator, I::Item: Borrow<()>, + J: IntoIterator, + J::Item: Borrow, { unimplemented!() } diff --git a/src/backend/gl/src/command.rs b/src/backend/gl/src/command.rs index 53a2d0b7f42..ccf0be8e742 100644 --- a/src/backend/gl/src/command.rs +++ b/src/backend/gl/src/command.rs @@ -834,14 +834,17 @@ impl command::RawCommandBuffer for RawCommandBuffer { self.update_blend_targets(blend_targets); } - fn bind_graphics_descriptor_sets( + fn bind_graphics_descriptor_sets( &mut self, _layout: &n::PipelineLayout, _first_set: usize, - _sets: T, + _sets: I, + _offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { // TODO } @@ -857,14 +860,17 @@ impl command::RawCommandBuffer for RawCommandBuffer { } } - fn bind_compute_descriptor_sets( + fn bind_compute_descriptor_sets( &mut self, _layout: &n::PipelineLayout, _first_set: usize, - _sets: T, + _sets: I, + _offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { // TODO } diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 4e0da80c671..b54af380e15 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -53,18 +53,21 @@ where } impl CommandBuffer { - fn bind_descriptor_sets( + fn bind_descriptor_sets( &mut self, bind_point: vk::PipelineBindPoint, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { - let sets: SmallVec<[vk::DescriptorSet; 16]> = sets.into_iter().map(|set| set.borrow().raw).collect(); - let dynamic_offsets = &[]; // TODO + let sets: SmallVec<[_; 16]> = sets.into_iter().map(|set| set.borrow().raw).collect(); + let dynamic_offsets: SmallVec<[_; 16]> = offsets.into_iter().map(|offset| *offset.borrow()).collect(); unsafe { self.device.0.cmd_bind_descriptor_sets( @@ -73,7 +76,7 @@ impl CommandBuffer { layout.raw, first_set as u32, &sets, - dynamic_offsets, + &dynamic_offsets, ); } } @@ -605,20 +608,24 @@ impl com::RawCommandBuffer for CommandBuffer { } } - fn bind_graphics_descriptor_sets( + fn bind_graphics_descriptor_sets( &mut self, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { self.bind_descriptor_sets( vk::PipelineBindPoint::Graphics, layout, first_set, sets, + offsets, ); } @@ -632,20 +639,24 @@ impl com::RawCommandBuffer for CommandBuffer { } } - fn bind_compute_descriptor_sets( + fn bind_compute_descriptor_sets( &mut self, layout: &n::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { self.bind_descriptor_sets( vk::PipelineBindPoint::Compute, layout, first_set, sets, + offsets, ); } diff --git a/src/hal/src/command/compute.rs b/src/hal/src/command/compute.rs index 9fccf2105a5..6a47b6f5723 100644 --- a/src/hal/src/command/compute.rs +++ b/src/hal/src/command/compute.rs @@ -4,9 +4,8 @@ use std::borrow::Borrow; use {Backend, WorkGroupCount}; use buffer::Offset; -use command::raw::DescriptorSetOffset; use queue::capability::{Compute, Supports}; -use super::{CommandBuffer, RawCommandBuffer, Shot, Level}; +use super::{CommandBuffer, DescriptorSetOffset, RawCommandBuffer, Shot, Level}; impl<'a, B: Backend, C: Supports, S: Shot, L: Level> CommandBuffer<'a, B, C, S, L> { /// Identical to the `RawCommandBuffer` method of the same name. diff --git a/src/hal/src/command/graphics.rs b/src/hal/src/command/graphics.rs index 1cf41174216..10b0679426d 100644 --- a/src/hal/src/command/graphics.rs +++ b/src/hal/src/command/graphics.rs @@ -5,14 +5,13 @@ use std::ops::Range; use Backend; use {image, pso}; use buffer::IndexBufferView; -use command::raw::DescriptorSetOffset; use query::{Query, QueryControl, QueryId}; use queue::capability::{Graphics, GraphicsOrCompute, Supports}; use super::{ CommandBuffer, RawCommandBuffer, RenderPassInlineEncoder, RenderPassSecondaryEncoder, Shot, Level, Primary, - ClearColorRaw, ClearDepthStencilRaw, ClearValueRaw, + ClearColorRaw, ClearDepthStencilRaw, ClearValueRaw, DescriptorSetOffset, }; diff --git a/src/hal/src/command/render_pass.rs b/src/hal/src/command/render_pass.rs index 06dbca7af6c..ef1ab451ed9 100644 --- a/src/hal/src/command/render_pass.rs +++ b/src/hal/src/command/render_pass.rs @@ -4,11 +4,10 @@ use std::marker::PhantomData; use {buffer, pso}; use {Backend, DrawCount, IndexCount, InstanceCount, VertexCount, VertexOffset}; -use command::raw::DescriptorSetOffset; use queue::{Supports, Graphics}; use super::{ AttachmentClear, ClearValue, ClearValueRaw, CommandBuffer, RawCommandBuffer, - Shot, Level, Primary, Secondary, Submittable, Submit + Shot, Level, Primary, Secondary, Submittable, Submit, DescriptorSetOffset, }; /// Specifies how commands for the following renderpasses will be recorded. From 191ce46a180b79d6b2ea0d50cb31c1a0f4e4d6b3 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Tue, 5 Jun 2018 19:47:53 +0200 Subject: [PATCH 3/4] Update examples, warden and dx11 to match dynamic offset API --- examples/hal/compute/main.rs | 2 +- examples/hal/quad/main.rs | 2 +- src/backend/dx11/src/lib.rs | 30 +++++++++++++++++------------- src/render/src/macros/pipeline.rs | 2 +- src/warden/src/gpu.rs | 2 ++ 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/examples/hal/compute/main.rs b/examples/hal/compute/main.rs index 9be7e5680c3..20ac017c27f 100644 --- a/examples/hal/compute/main.rs +++ b/examples/hal/compute/main.rs @@ -130,7 +130,7 @@ fn main() { }), ); command_buffer.bind_compute_pipeline(&pipeline); - command_buffer.bind_compute_descriptor_sets(&pipeline_layout, 0, &[desc_set]); + command_buffer.bind_compute_descriptor_sets(&pipeline_layout, 0, &[desc_set], &[]); command_buffer.dispatch([numbers.len() as u32, 1, 1]); command_buffer.pipeline_barrier( pso::PipelineStage::COMPUTE_SHADER .. pso::PipelineStage::TRANSFER, diff --git a/examples/hal/quad/main.rs b/examples/hal/quad/main.rs index 296cb2a7002..fbe814a9d5f 100644 --- a/examples/hal/quad/main.rs +++ b/examples/hal/quad/main.rs @@ -560,7 +560,7 @@ fn main() { cmd_buffer.set_scissors(0, &[viewport.rect]); cmd_buffer.bind_graphics_pipeline(&pipeline.as_ref().unwrap()); cmd_buffer.bind_vertex_buffers(0, pso::VertexBufferSet(vec![(&vertex_buffer, 0)])); - cmd_buffer.bind_graphics_descriptor_sets(&pipeline_layout, 0, Some(&desc_set)); //TODO + cmd_buffer.bind_graphics_descriptor_sets(&pipeline_layout, 0, Some(&desc_set), &[]); //TODO { let mut encoder = cmd_buffer.begin_render_pass_inline( diff --git a/src/backend/dx11/src/lib.rs b/src/backend/dx11/src/lib.rs index 2b49bb68ea6..c0f3a1d7372 100644 --- a/src/backend/dx11/src/lib.rs +++ b/src/backend/dx11/src/lib.rs @@ -308,7 +308,7 @@ impl hal::PhysicalDevice for PhysicalDevice { }; let device = device::Device::new(device, cxt, self.memory_properties.clone()); - + // TODO: deferred context => 1 cxt/queue? let queues = Queues::new( families @@ -490,7 +490,7 @@ pub struct CommandBuffer { } unsafe impl Send for CommandBuffer {} -unsafe impl Sync for CommandBuffer {} +unsafe impl Sync for CommandBuffer {} impl CommandBuffer { fn create_deferred(device: ComPtr, internal: internal::BufferImageCopy) -> Self { @@ -544,7 +544,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { let depth_view = framebuffer.attachments.iter().find(|a| a.dsv_handle.is_some()); - + unsafe { for (clear, view) in clear_values.into_iter().zip(framebuffer.attachments.iter()) { let clear = clear.borrow(); @@ -729,10 +729,12 @@ impl hal::command::RawCommandBuffer for CommandBuffer { } } - fn bind_graphics_descriptor_sets<'a, T>(&mut self, layout: &PipelineLayout, first_set: usize, sets: T) + fn bind_graphics_descriptor_sets<'a, I, J>(&mut self, layout: &PipelineLayout, first_set: usize, sets: I, _offsets: J) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { for set in sets.into_iter() { let set = set.borrow(); @@ -759,10 +761,12 @@ impl hal::command::RawCommandBuffer for CommandBuffer { } - fn bind_compute_descriptor_sets(&mut self, layout: &PipelineLayout, first_set: usize, sets: T) + fn bind_compute_descriptor_sets(&mut self, layout: &PipelineLayout, first_set: usize, sets: I, offsets: J) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { unimplemented!() } @@ -900,7 +904,7 @@ pub struct Memory { } unsafe impl Send for Memory {} -unsafe impl Sync for Memory {} +unsafe impl Sync for Memory {} pub struct CommandPool { device: ComPtr, @@ -908,7 +912,7 @@ pub struct CommandPool { } unsafe impl Send for CommandPool {} -unsafe impl Sync for CommandPool {} +unsafe impl Sync for CommandPool {} impl hal::pool::RawCommandPool for CommandPool { fn reset(&mut self) { @@ -996,7 +1000,7 @@ impl Buffer { } unsafe impl Send for Buffer {} -unsafe impl Sync for Buffer {} +unsafe impl Sync for Buffer {} #[derive(Debug)] pub struct BufferView; @@ -1129,7 +1133,7 @@ pub struct DescriptorSet { } unsafe impl Send for DescriptorSet {} -unsafe impl Sync for DescriptorSet {} +unsafe impl Sync for DescriptorSet {} impl DescriptorSet { pub fn new() -> Self { diff --git a/src/render/src/macros/pipeline.rs b/src/render/src/macros/pipeline.rs index d5b75131300..e5fb6e5d3d4 100644 --- a/src/render/src/macros/pipeline.rs +++ b/src/render/src/macros/pipeline.rs @@ -141,7 +141,7 @@ macro_rules! gfx_graphics_pipeline { $( descs.extend(<$cmp as pso::Component<'a, B>>::descriptor_set(&self.$cmp_name)); )* - cmd_buffer.bind_graphics_descriptor_sets(meta.layout.resource(), 0, descs); + cmd_buffer.bind_graphics_descriptor_sets(meta.layout.resource(), 0, descs, &[]); // TODO: difference with viewport ? let extent = self.framebuffer.info().extent; let render_rect = pso::Rect { diff --git a/src/warden/src/gpu.rs b/src/warden/src/gpu.rs index 380960efcd9..4d8704e8e3c 100644 --- a/src/warden/src/gpu.rs +++ b/src/warden/src/gpu.rs @@ -967,6 +967,7 @@ impl Scene { .get(name) .expect(&format!("Missing descriptor set: {}", name)) }), + &[], ); } Dc::Draw { ref vertices, ref instances } => { @@ -998,6 +999,7 @@ impl Scene { .get(name) .expect(&format!("Missing descriptor set: {}", name)) }), + &[], ); command_buf.dispatch(dispatch); } From b61f215595d0a9182161fcb9ba0bf444b6facd00 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 5 Jun 2018 14:19:35 -0400 Subject: [PATCH 4/4] [mtl] dynamic buffers --- src/backend/metal/src/command.rs | 61 +++++++++++++++++++++++--------- src/backend/metal/src/device.rs | 8 ++--- src/backend/metal/src/native.rs | 14 ++++++-- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/backend/metal/src/command.rs b/src/backend/metal/src/command.rs index 053446a26be..dc2f2394d26 100644 --- a/src/backend/metal/src/command.rs +++ b/src/backend/metal/src/command.rs @@ -2008,18 +2008,22 @@ impl com::RawCommandBuffer for CommandBuffer { .pre_render_commands(commands); } - fn bind_graphics_descriptor_sets<'a, T>( + fn bind_graphics_descriptor_sets<'a, I, J>( &mut self, layout: &native::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { use spirv_cross::{msl, spirv}; let mut commands = Vec::new(); //TODO: re-use the storage + let mut offset_iter = offsets.into_iter(); for (set_index, desc_set) in sets.into_iter().enumerate() { let location_vs = msl::ResourceBindingLocation { @@ -2089,8 +2093,17 @@ impl com::RawCommandBuffer for CommandBuffer { Buffer(ref buffers) => { let start = res.buffer_id as usize; for (i, bref) in buffers.iter().enumerate() { - let (buffer, offset) = match *bref { - Some((ref buffer, offset)) => (Some(buffer.clone()), offset), + let (buffer, offset) = match bref.base { + Some((ref buffer, mut offset)) => { + if bref.dynamic { + offset += *offset_iter + .next() + .expect("No dynamic offset provided!") + .borrow() as u64; + } + resources.add_buffer(start + i, buffer.as_ref(), offset as _); + (Some(buffer.clone()), offset) + } None => (None, 0), }; commands.push(soft::RenderCommand::BindBuffer { @@ -2099,9 +2112,6 @@ impl com::RawCommandBuffer for CommandBuffer { buffer, offset, }); - if let Some((ref buffer, offset)) = *bref { - resources.add_buffer(start + i, buffer.as_ref(), offset as _); - } } } } @@ -2156,8 +2166,14 @@ impl com::RawCommandBuffer for CommandBuffer { Buffer(ref buffers) => { let start = res.buffer_id as usize; for (i, bref) in buffers.iter().enumerate() { - let (buffer, offset) = match *bref { - Some((ref buffer, offset)) => { + let (buffer, offset) = match bref.base { + Some((ref buffer, mut offset)) => { + if bref.dynamic { + offset += *offset_iter + .next() + .expect("No dynamic offset provided!") + .borrow() as u64; + } resources.add_buffer(start + i, buffer.as_ref(), offset as _); (Some(buffer.clone()), offset) }, @@ -2218,17 +2234,22 @@ impl com::RawCommandBuffer for CommandBuffer { .pre_compute_commands(iter::once(command)); } - fn bind_compute_descriptor_sets<'a, T>( + fn bind_compute_descriptor_sets<'a, I, J>( &mut self, layout: &native::PipelineLayout, first_set: usize, - sets: T, + sets: I, + offsets: J, ) where - T: IntoIterator, - T::Item: Borrow, + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow, { use spirv_cross::{msl, spirv}; + let mut commands = Vec::new(); + let mut offset_iter = offsets.into_iter(); for (set_index, desc_set) in sets.into_iter().enumerate() { let resources = &mut self.state.resources_cs; @@ -2289,8 +2310,14 @@ impl com::RawCommandBuffer for CommandBuffer { Buffer(ref buffers) => { let start = res.buffer_id as usize; for (i, bref) in buffers.iter().enumerate() { - let (buffer, offset) = match *bref { - Some((ref buffer, offset)) => { + let (buffer, offset) = match bref.base { + Some((ref buffer, mut offset)) => { + if bref.dynamic { + offset += *offset_iter + .next() + .expect("No dynamic offset provided!") + .borrow() as u64; + } resources.add_buffer(start + i, buffer.as_ref(), offset as _); (Some(buffer.clone()), offset) }, diff --git a/src/backend/metal/src/device.rs b/src/backend/metal/src/device.rs index ad1a7abba1b..41530196d7e 100644 --- a/src/backend/metal/src/device.rs +++ b/src/backend/metal/src/device.rs @@ -683,7 +683,9 @@ impl hal::Device for Device { }; match set_binding.ty { pso::DescriptorType::UniformBuffer | - pso::DescriptorType::StorageBuffer => { + pso::DescriptorType::StorageBuffer | + pso::DescriptorType::UniformBufferDynamic | + pso::DescriptorType::StorageBufferDynamic => { res.buffer_id = counters.buffers as _; counters.buffers += 1; } @@ -705,8 +707,6 @@ impl hal::Device for Device { counters.textures += 1; counters.samplers += 1; } - pso::DescriptorType::UniformBufferDynamic | - pso::DescriptorType::UniformImageDynamic => unimplemented!(), }; assert_eq!(set_binding.count, 1); //TODO let location = msl::ResourceBindingLocation { @@ -1378,7 +1378,7 @@ impl hal::Device for Device { let start = range.start.unwrap_or(0); let end = range.end.unwrap_or(buf_length); assert!(end <= buf_length); - vec[array_offset] = Some((buffer.raw.clone(), start)); + vec[array_offset].base = Some((buffer.raw.clone(), start)); } (&pso::Descriptor::Sampler(..), _) | (&pso::Descriptor::Image(..), _) | diff --git a/src/backend/metal/src/native.rs b/src/backend/metal/src/native.rs index 4f8cdd9eed5..816301247cf 100644 --- a/src/backend/metal/src/native.rs +++ b/src/backend/metal/src/native.rs @@ -238,10 +238,12 @@ impl hal::DescriptorPool for DescriptorPool { } pso::DescriptorType::UniformBuffer | pso::DescriptorType::StorageBuffer => { - DescriptorSetBinding::Buffer(vec![None; layout.count]) + DescriptorSetBinding::Buffer(vec![BufferBinding { base: None, dynamic: false }; layout.count]) } pso::DescriptorType::UniformBufferDynamic | - pso::DescriptorType::UniformImageDynamic => unimplemented!() + pso::DescriptorType::StorageBufferDynamic => { + DescriptorSetBinding::Buffer(vec![BufferBinding { base: None, dynamic: true }; layout.count]) + } }; (layout.binding, binding) }).collect(); @@ -336,12 +338,18 @@ pub struct DescriptorSetInner { } unsafe impl Send for DescriptorSetInner {} +#[derive(Clone, Debug)] +pub struct BufferBinding { + pub base: Option<(metal::Buffer, u64)>, + pub dynamic: bool, +} + #[derive(Debug)] pub enum DescriptorSetBinding { Sampler(Vec>), Image(Vec>), Combined(Vec<(Option<(metal::Texture, image::Layout)>, Option)>), - Buffer(Vec>), + Buffer(Vec), //InputAttachment(Vec<(metal::Texture, image::Layout)>), }