From 71b170979d2de70156085a6384d9e7cf92287aa8 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 30 Sep 2018 23:36:29 -0400 Subject: [PATCH 1/3] render pass begin/end --- wgpu-native/src/command/allocator.rs | 6 +- wgpu-native/src/command/mod.rs | 26 +++++- wgpu-native/src/command/render.rs | 34 +++++++- wgpu-native/src/conv.rs | 2 +- wgpu-native/src/device.rs | 113 ++++++++++++++------------- wgpu-native/src/lib.rs | 3 +- wgpu-native/src/pipeline.rs | 6 +- wgpu-native/src/registry.rs | 3 + 8 files changed, 127 insertions(+), 66 deletions(-) diff --git a/wgpu-native/src/command/allocator.rs b/wgpu-native/src/command/allocator.rs index cf7b05adf..2f80c06d4 100644 --- a/wgpu-native/src/command/allocator.rs +++ b/wgpu-native/src/command/allocator.rs @@ -51,9 +51,9 @@ impl CommandAllocator { return cmd_buf; } - for raw in pool.raw.allocate(20, hal::command::RawLevel::Primary) { + for cmbuf in pool.raw.allocate(20, hal::command::RawLevel::Primary) { pool.available.push(CommandBuffer { - raw, + raw: Some(cmbuf), fence: device.create_fence(false), recorded_thread_id: thread_id, }); @@ -66,7 +66,7 @@ impl CommandAllocator { } pub fn recycle(&self, mut cmd_buf: CommandBuffer) { - cmd_buf.raw.reset(false); + cmd_buf.raw.as_mut().unwrap().reset(false); self.inner .lock() .unwrap() diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index b0501094b..1d1780950 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -12,6 +12,7 @@ use { BufferId, Color, CommandBufferId, ComputePassId, Origin3d, RenderPassId, TextureId, TextureViewId, }; +use registry::{self, Items, Registry}; use std::thread::ThreadId; @@ -71,7 +72,7 @@ pub struct TextureCopyView { } pub struct CommandBuffer { - pub(crate) raw: B::CommandBuffer, + pub(crate) raw: Option, fence: B::Fence, recorded_thread_id: ThreadId, } @@ -81,9 +82,28 @@ pub struct CommandBufferDescriptor {} #[no_mangle] pub extern "C" fn wgpu_command_buffer_begin_render_pass( - _command_buffer: CommandBufferId, + command_buffer_id: CommandBufferId, + _descriptor: RenderPassDescriptor, ) -> RenderPassId { - unimplemented!() + let raw = registry::COMMAND_BUFFER_REGISTRY + .lock() + .get_mut(command_buffer_id) + .raw + .take() + .unwrap(); + + /*TODO: + raw.begin_render_pass( + render_pass: &B::RenderPass, + framebuffer: &B::Framebuffer, + render_area: pso::Rect, + clear_values: T, + hal::SubpassContents::Inline, + );*/ + + registry::RENDER_PASS_REGISTRY + .lock() + .register(RenderPass::new(raw, command_buffer_id)) } #[no_mangle] diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index 4ab967a39..edf7dd2b3 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -1,7 +1,39 @@ use hal; +use hal::command::RawCommandBuffer; -//use {CommandBuffer, CommandBufferId, RenderPassId}; +use registry::{self, Items, Registry}; +use {CommandBufferId, RenderPassId}; pub struct RenderPass { raw: B::CommandBuffer, + cmb_id: CommandBufferId, +} + +// This is needed for `cmb_id` - would be great to remove. +#[cfg(not(feature = "remote"))] +unsafe impl Sync for RenderPass {} + +impl RenderPass { + pub fn new(raw: B::CommandBuffer, cmb_id: CommandBufferId) -> Self { + RenderPass { + raw, + cmb_id, + } + } +} + +#[no_mangle] +pub extern "C" fn wgpu_render_pass_end_pass( + render_pass_id: RenderPassId, +) -> CommandBufferId { + let mut rp = registry::RENDER_PASS_REGISTRY + .lock() + .take(render_pass_id); + rp.raw.end_render_pass(); + + registry::COMMAND_BUFFER_REGISTRY + .lock() + .get_mut(rp.cmb_id) + .raw = Some(rp.raw); + rp.cmb_id } diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index 8c2cae0ce..3d6c8e312 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -189,7 +189,7 @@ fn map_stencil_face( hal::pso::StencilFace { fun: map_compare_function(stencil_state_face_desc.compare), mask_read: hal::pso::State::Static(stencil_read_mask), // TODO dynamic? - mask_write: hal::pso::State::Static(stencil_read_mask), // TODO dynamic? + mask_write: hal::pso::State::Static(stencil_write_mask), // TODO dynamic? op_fail: map_stencil_operation(stencil_state_face_desc.stencil_fail_op), op_depth_fail: map_stencil_operation(stencil_state_face_desc.depth_fail_op), op_pass: map_stencil_operation(stencil_state_face_desc.pass_op), diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index fde26ac6e..a47dad4c4 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -11,7 +11,7 @@ use { }; pub struct Device { - device: B::Device, + raw: B::Device, queue_group: hal::QueueGroup, mem_allocator: memory::SmartAllocator, com_allocator: command::CommandAllocator, @@ -19,12 +19,12 @@ pub struct Device { impl Device { pub(crate) fn new( - device: B::Device, + raw: B::Device, queue_group: hal::QueueGroup, mem_props: hal::MemoryProperties, ) -> Self { Device { - device, + raw, mem_allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1), com_allocator: command::CommandAllocator::new(queue_group.family()), queue_group, @@ -44,7 +44,7 @@ pub extern "C" fn wgpu_device_create_bind_group_layout( let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; let device_guard = registry::DEVICE_REGISTRY.lock(); let device = device_guard.get(device_id); - let descriptor_set_layout = device.device.create_descriptor_set_layout( + let descriptor_set_layout = device.raw.create_descriptor_set_layout( bindings.iter().map(|binding| { hal::pso::DescriptorSetLayoutBinding { binding: binding.binding, @@ -75,7 +75,7 @@ pub extern "C" fn wgpu_device_create_pipeline_layout( .map(|id| bind_group_layout_guard.get(id.clone())) .collect::>(); let device_guard = registry::DEVICE_REGISTRY.lock(); - let device = &device_guard.get(device_id).device; + let device = &device_guard.get(device_id).raw; let pipeline_layout = device.create_pipeline_layout(descriptor_set_layouts.iter().map(|d| &d.raw), &[]); // TODO: push constants registry::PIPELINE_LAYOUT_REGISTRY @@ -99,7 +99,7 @@ pub extern "C" fn wgpu_device_create_blend_state( #[no_mangle] pub extern "C" fn wgpu_device_create_depth_stencil_state( - device_id: DeviceId, + _device_id: DeviceId, desc: pipeline::DepthStencilStateDescriptor, ) -> DepthStencilStateId { registry::DEPTH_STENCIL_STATE_REGISTRY @@ -115,7 +115,7 @@ pub extern "C" fn wgpu_device_create_shader_module( desc: pipeline::ShaderModuleDescriptor, ) -> ShaderModuleId { let device_guard = registry::DEVICE_REGISTRY.lock(); - let device = &device_guard.get(device_id).device; + let device = &device_guard.get(device_id).raw; let shader = device .create_shader_module(unsafe { slice::from_raw_parts(desc.code.bytes, desc.code.length) }) .unwrap(); @@ -131,8 +131,8 @@ pub extern "C" fn wgpu_device_create_command_buffer( ) -> CommandBufferId { let mut device_guard = registry::DEVICE_REGISTRY.lock(); let device = device_guard.get_mut(device_id); - let mut cmd_buf = device.com_allocator.allocate(&device.device); - cmd_buf.raw.begin( + let mut cmd_buf = device.com_allocator.allocate(&device.raw); + cmd_buf.raw.as_mut().unwrap().begin( hal::command::CommandBufferFlags::ONE_TIME_SUBMIT, hal::command::CommandBufferInheritanceInfo::default(), ); @@ -158,10 +158,11 @@ pub extern "C" fn wgpu_queue_submit( let mut command_buffer_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); for &cmb_id in command_buffer_ids { let mut cmd_buf = command_buffer_guard.take(cmb_id); - cmd_buf.raw.finish(); { + let mut raw = cmd_buf.raw.as_mut().unwrap(); + raw.finish(); let submission = hal::queue::RawSubmission { - cmd_buffers: iter::once(&cmd_buf.raw), + cmd_buffers: iter::once(raw), wait_semaphores: &[], signal_semaphores: &[], }; @@ -180,29 +181,52 @@ pub extern "C" fn wgpu_device_create_attachment_state( device_id: DeviceId, desc: pipeline::AttachmentStateDescriptor, ) -> AttachmentStateId { - // TODO: Assume that `AttachmentStateDescriptor` contains multiple attachments. - let attachments = unsafe { slice::from_raw_parts(desc.formats, desc.formats_length) } + let device_guard = registry::DEVICE_REGISTRY.lock(); + let device = &device_guard.get(device_id).raw; + + let color_formats = unsafe { + slice::from_raw_parts(desc.formats, desc.formats_length) + }; + let color_formats: Vec<_> = color_formats .iter() - .map(|format| { - hal::pass::Attachment { - format: Some(conv::map_texture_format(*format)), - samples: 1, // TODO map - ops: hal::pass::AttachmentOps { - // TODO map - load: hal::pass::AttachmentLoadOp::Clear, - store: hal::pass::AttachmentStoreOp::Store, - }, - stencil_ops: hal::pass::AttachmentOps { - // TODO map - load: hal::pass::AttachmentLoadOp::DontCare, - store: hal::pass::AttachmentStoreOp::DontCare, - }, - layouts: hal::image::Layout::Undefined..hal::image::Layout::Present, // TODO map - } - }).collect(); + .cloned() + .map(conv::map_texture_format) + .collect(); + let depth_stencil_format = None; + + let base_pass = { + let attachments = color_formats.iter().map(|cf| hal::pass::Attachment { + format: Some(*cf), + samples: 1, + ops: hal::pass::AttachmentOps::DONT_CARE, + stencil_ops: hal::pass::AttachmentOps::DONT_CARE, + layouts: hal::image::Layout::General .. hal::image::Layout::General, + }); + + let subpass = hal::pass::SubpassDesc { + colors: &[(0, hal::image::Layout::ColorAttachmentOptimal)], + depth_stencil: None, + inputs: &[], + resolves: &[], + preserves: &[], + }; + + device.create_render_pass( + attachments, + &[subpass], + &[], + ) + }; + + let at_state = pipeline::AttachmentState { + base_pass, + color_formats, + depth_stencil_format, + }; + registry::ATTACHMENT_STATE_REGISTRY .lock() - .register(pipeline::AttachmentState { raw: attachments }) + .register(at_state) } #[no_mangle] @@ -217,7 +241,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline( }; let device_guard = registry::DEVICE_REGISTRY.lock(); - let device = &device_guard.get(device_id).device; + let device = &device_guard.get(device_id).raw; let pipeline_layout_guard = registry::PIPELINE_LAYOUT_REGISTRY.lock(); let layout = &pipeline_layout_guard.get(desc.layout).raw; let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) }; @@ -318,33 +342,12 @@ pub extern "C" fn wgpu_device_create_render_pipeline( }; let attachment_state_guard = registry::ATTACHMENT_STATE_REGISTRY.lock(); - let attachments = &attachment_state_guard.get(desc.attachment_state).raw; - - // TODO - let subpass = hal::pass::SubpassDesc { - colors: &[(0, hal::image::Layout::ColorAttachmentOptimal)], - depth_stencil: None, - inputs: &[], - resolves: &[], - preserves: &[], - }; - - // TODO - let subpass_dependency = hal::pass::SubpassDependency { - passes: hal::pass::SubpassRef::External..hal::pass::SubpassRef::Pass(0), - stages: hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT - ..hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT, - accesses: hal::image::Access::empty() - ..(hal::image::Access::COLOR_ATTACHMENT_READ - | hal::image::Access::COLOR_ATTACHMENT_WRITE), - }; - - let main_pass = &device.create_render_pass(&attachments[..], &[subpass], &[subpass_dependency]); + let attachment_state = attachment_state_guard.get(desc.attachment_state); // TODO let subpass = hal::pass::Subpass { index: 0, - main_pass, + main_pass: &attachment_state.base_pass, }; // TODO diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index 704653642..f150bd564 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -97,7 +97,7 @@ pub type InputStateId = Id; pub type ShaderModuleId = Id; type ShaderModuleHandle = ShaderModule; pub type AttachmentStateId = Id; -type AttachmentStateHandle = AttachmentState; +type AttachmentStateHandle = AttachmentState; pub type ComputePipelineId = Id; pub type RenderPipelineId = Id; type RenderPipelineHandle = RenderPipeline; @@ -105,4 +105,5 @@ type RenderPipelineHandle = RenderPipeline; pub type CommandBufferId = Id; type CommandBufferHandle = CommandBuffer; pub type RenderPassId = Id; +type RenderPassHandle = RenderPass; pub type ComputePassId = Id; diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index 3c186471b..5f876224d 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -200,8 +200,10 @@ pub struct AttachmentStateDescriptor { pub formats_length: usize, } -pub(crate) struct AttachmentState { - pub raw: Vec, +pub(crate) struct AttachmentState { + pub base_pass: B::RenderPass, + pub color_formats: Vec, + pub depth_stencil_format: Option, } #[repr(C)] diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index eb56750df..c55ca6ecc 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -12,6 +12,7 @@ use std::sync::Arc; use { AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, + RenderPassHandle, PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, }; @@ -175,4 +176,6 @@ lazy_static! { ConcreteRegistry::new(); pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref RENDER_PASS_REGISTRY: ConcreteRegistry = + ConcreteRegistry::new(); } From da95fe6b1e6994b3aaa184d08f95afdb85cfd536 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 1 Oct 2018 10:11:44 -0400 Subject: [PATCH 2/3] Rust side render pass begin/end --- examples/hello_triangle_rust/main.rs | 21 +++++++++++- wgpu-native/src/command/mod.rs | 16 ++++----- wgpu-native/src/lib.rs | 12 +++++++ wgpu-rs/src/lib.rs | 51 ++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/examples/hello_triangle_rust/main.rs b/examples/hello_triangle_rust/main.rs index 519e17640..a00d6b8e1 100644 --- a/examples/hello_triangle_rust/main.rs +++ b/examples/hello_triangle_rust/main.rs @@ -9,6 +9,7 @@ fn main() { anisotropic_filtering: false, }, }); + let vs_bytes = include_bytes!("./../data/hello_triangle.vert.spv"); let vs_module = device.create_shader_module(vs_bytes); let fs_bytes = include_bytes!("./../data/hello_triangle.frag.spv"); @@ -49,7 +50,25 @@ fn main() { attachment_state: &attachment_state, }); - let cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {}); + let mut cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {}); + + { + let color_view = unimplemented!(); //TODO! + let rpass = cmd_buf.begin_render_pass(wgpu::RenderPassDescriptor { + color_attachments: &[ + wgpu::RenderPassColorAttachmentDescriptor { + attachment: &color_view, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: wgpu::Color::GREEN, + }, + ], + depth_stencil_attachment: None, + }); + rpass.end_pass(); + } + + let queue = device.get_queue(); queue.submit(&[cmd_buf]); } diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index 1d1780950..c40d0279b 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -30,16 +30,16 @@ pub enum StoreOp { } #[repr(C)] -pub struct RenderPassColorAttachmentDescriptor { - pub attachment: TextureViewId, +pub struct RenderPassColorAttachmentDescriptor { + pub attachment: T, pub load_op: LoadOp, pub store_op: StoreOp, pub clear_color: Color, } #[repr(C)] -pub struct RenderPassDepthStencilAttachmentDescriptor { - pub attachment: TextureViewId, +pub struct RenderPassDepthStencilAttachmentDescriptor { + pub attachment: T, pub depth_load_op: LoadOp, pub depth_store_op: StoreOp, pub clear_depth: f32, @@ -49,9 +49,9 @@ pub struct RenderPassDepthStencilAttachmentDescriptor { } #[repr(C)] -pub struct RenderPassDescriptor<'a> { - pub color_attachments: &'a [RenderPassColorAttachmentDescriptor], - pub depth_stencil_attachment: RenderPassDepthStencilAttachmentDescriptor, +pub struct RenderPassDescriptor<'a, T: 'a> { + pub color_attachments: &'a [RenderPassColorAttachmentDescriptor], + pub depth_stencil_attachment: Option>, } #[repr(C)] @@ -83,7 +83,7 @@ pub struct CommandBufferDescriptor {} #[no_mangle] pub extern "C" fn wgpu_command_buffer_begin_render_pass( command_buffer_id: CommandBufferId, - _descriptor: RenderPassDescriptor, + _descriptor: RenderPassDescriptor, ) -> RenderPassId { let raw = registry::COMMAND_BUFFER_REGISTRY .lock() diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index f150bd564..9fe0a8eb5 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -41,6 +41,7 @@ use back::Backend as B; use registry::Id; #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct Color { pub r: f32, pub g: f32, @@ -48,7 +49,17 @@ pub struct Color { pub a: f32, } +impl Color { + pub const TRANSPARENT : Self = Color { r: 0.0, g: 0.0, b: 0.0, a: 0.0 }; + pub const BLACK : Self = Color { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }; + pub const WHITE : Self = Color { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }; + pub const RED : Self = Color { r: 1.0, g: 0.0, b: 0.0, a: 1.0 }; + pub const GREEN : Self = Color { r: 0.0, g: 1.0, b: 0.0, a: 1.0 }; + pub const BLUE : Self = Color { r: 0.0, g: 0.0, b: 1.0, a: 1.0 }; +} + #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct Origin3d { pub x: f32, pub y: f32, @@ -56,6 +67,7 @@ pub struct Origin3d { } #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct Extent3d { pub width: f32, pub height: f32, diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 32e14cbab..630074918 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -10,6 +10,8 @@ pub use wgn::{ Origin3d, PowerPreference, ShaderModuleDescriptor, ShaderStage, BindGroupLayoutBinding, TextureFormat, PrimitiveTopology, BlendStateDescriptor, ColorWriteFlags, DepthStencilStateDescriptor, + RenderPassDescriptor, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, + LoadOp, StoreOp, }; @@ -25,6 +27,10 @@ pub struct Device { id: wgn::DeviceId, } +pub struct TextureView { + id: wgn::TextureViewId, +} + pub struct BindGroupLayout { id: wgn::BindGroupLayoutId, } @@ -57,6 +63,11 @@ pub struct CommandBuffer { id: wgn::CommandBufferId, } +pub struct RenderPass<'a> { + id: wgn::RenderPassId, + parent: &'a mut CommandBuffer, +} + pub struct Queue { id: wgn::QueueId, } @@ -205,6 +216,46 @@ impl Device { } } +impl CommandBuffer { + pub fn begin_render_pass(&mut self, desc: RenderPassDescriptor<&TextureView>) -> RenderPass { + let colors = desc.color_attachments + .iter() + .map(|ca| RenderPassColorAttachmentDescriptor { + attachment: ca.attachment.id, + load_op: ca.load_op, + store_op: ca.store_op, + clear_color: ca.clear_color, + }) + .collect::>(); + + let depth_stencil = desc.depth_stencil_attachment + .map(|dsa| RenderPassDepthStencilAttachmentDescriptor { + attachment: dsa.attachment.id, + depth_load_op: dsa.depth_load_op, + depth_store_op: dsa.depth_store_op, + clear_depth: dsa.clear_depth, + stencil_load_op: dsa.stencil_load_op, + stencil_store_op: dsa.stencil_store_op, + clear_stencil: dsa.clear_stencil, + }); + + RenderPass { + id: wgn::wgpu_command_buffer_begin_render_pass(self.id, RenderPassDescriptor { + color_attachments: &colors, + depth_stencil_attachment: depth_stencil, + }), + parent: self, + } + } +} + +impl<'a> RenderPass<'a> { + pub fn end_pass(self) -> &'a mut CommandBuffer { + wgn::wgpu_render_pass_end_pass(self.id); + self.parent + } +} + impl Queue { pub fn submit(&self, command_buffers: &[CommandBuffer]) { wgn::wgpu_queue_submit( From e4341603d74d4f1a4f4f61ffa485b84796c3850e Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 1 Oct 2018 11:41:55 -0400 Subject: [PATCH 3/3] Keep a reference to DeviceID in the command buffer --- wgpu-native/src/command/allocator.rs | 9 +++++++-- wgpu-native/src/command/mod.rs | 23 ++++++++++++++--------- wgpu-native/src/command/render.rs | 13 ++++++++----- wgpu-native/src/device.rs | 4 ++-- wgpu-native/src/lib.rs | 7 +++++++ 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/wgpu-native/src/command/allocator.rs b/wgpu-native/src/command/allocator.rs index 2f80c06d4..6c45be2c2 100644 --- a/wgpu-native/src/command/allocator.rs +++ b/wgpu-native/src/command/allocator.rs @@ -1,4 +1,5 @@ use super::CommandBuffer; +use {DeviceId, Stored}; use hal::command::RawCommandBuffer; use hal::pool::RawCommandPool; @@ -14,7 +15,7 @@ struct CommandPool { available: Vec>, } -pub struct Inner { +struct Inner { pools: HashMap>, pending: Vec>, } @@ -35,7 +36,9 @@ impl CommandAllocator { } } - pub fn allocate(&self, device: &B::Device) -> CommandBuffer { + pub fn allocate( + &self, device_id: DeviceId, device: &B::Device + ) -> CommandBuffer { let thread_id = thread::current().id(); let mut inner = self.inner.lock().unwrap(); let pool = inner.pools.entry(thread_id).or_insert_with(|| CommandPool { @@ -47,6 +50,7 @@ impl CommandAllocator { }); if let Some(cmd_buf) = pool.available.pop() { + assert_eq!(device_id, cmd_buf.device_id.0); device.reset_fence(&cmd_buf.fence); return cmd_buf; } @@ -56,6 +60,7 @@ impl CommandAllocator { raw: Some(cmbuf), fence: device.create_fence(false), recorded_thread_id: thread_id, + device_id: Stored(device_id), }); } pool.available.pop().unwrap() diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index c40d0279b..c90f9c34f 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -2,15 +2,15 @@ mod allocator; mod compute; mod render; -pub use self::allocator::*; +pub use self::allocator::CommandAllocator; pub use self::compute::*; pub use self::render::*; use hal; use { - BufferId, Color, CommandBufferId, ComputePassId, Origin3d, RenderPassId, TextureId, - TextureViewId, + Color, Origin3d, Stored, + BufferId, CommandBufferId, ComputePassId, DeviceId, RenderPassId, TextureId, TextureViewId, }; use registry::{self, Items, Registry}; @@ -75,6 +75,7 @@ pub struct CommandBuffer { pub(crate) raw: Option, fence: B::Fence, recorded_thread_id: ThreadId, + device_id: Stored, } #[repr(C)] @@ -85,12 +86,16 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass( command_buffer_id: CommandBufferId, _descriptor: RenderPassDescriptor, ) -> RenderPassId { - let raw = registry::COMMAND_BUFFER_REGISTRY - .lock() - .get_mut(command_buffer_id) - .raw - .take() - .unwrap(); + let mut cmb_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); + let mut cmb = cmb_guard.get_mut(command_buffer_id); + + let raw = cmb.raw.take().unwrap(); + + let mut device_guard = registry::DEVICE_REGISTRY.lock(); + let device = &device_guard.get(cmb.device_id.0).raw; + + //let render_pass = device.create_render_pass(); + //let framebuffer = device.create_framebuffer(); /*TODO: raw.begin_render_pass( diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index edf7dd2b3..94df08394 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -2,11 +2,14 @@ use hal; use hal::command::RawCommandBuffer; use registry::{self, Items, Registry}; -use {CommandBufferId, RenderPassId}; +use { + Stored, + CommandBufferId, RenderPassId, +}; pub struct RenderPass { raw: B::CommandBuffer, - cmb_id: CommandBufferId, + cmb_id: Stored, } // This is needed for `cmb_id` - would be great to remove. @@ -17,7 +20,7 @@ impl RenderPass { pub fn new(raw: B::CommandBuffer, cmb_id: CommandBufferId) -> Self { RenderPass { raw, - cmb_id, + cmb_id: Stored(cmb_id), } } } @@ -33,7 +36,7 @@ pub extern "C" fn wgpu_render_pass_end_pass( registry::COMMAND_BUFFER_REGISTRY .lock() - .get_mut(rp.cmb_id) + .get_mut(rp.cmb_id.0) .raw = Some(rp.raw); - rp.cmb_id + rp.cmb_id.0 } diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index a47dad4c4..cc4f230b0 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -11,7 +11,7 @@ use { }; pub struct Device { - raw: B::Device, + pub(crate) raw: B::Device, queue_group: hal::QueueGroup, mem_allocator: memory::SmartAllocator, com_allocator: command::CommandAllocator, @@ -131,7 +131,7 @@ pub extern "C" fn wgpu_device_create_command_buffer( ) -> CommandBufferId { let mut device_guard = registry::DEVICE_REGISTRY.lock(); let device = device_guard.get_mut(device_id); - let mut cmd_buf = device.com_allocator.allocate(&device.raw); + let mut cmd_buf = device.com_allocator.allocate(device_id, &device.raw); cmd_buf.raw.as_mut().unwrap().begin( hal::command::CommandBufferFlags::ONE_TIME_SUBMIT, hal::command::CommandBufferInheritanceInfo::default(), diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index 9fe0a8eb5..69e695f82 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -40,6 +40,13 @@ pub use self::resource::*; use back::Backend as B; use registry::Id; +#[derive(Debug, PartialEq)] +struct Stored(T); +#[cfg(not(feature = "remote"))] +unsafe impl Sync for Stored {} +#[cfg(not(feature = "remote"))] +unsafe impl Send for Stored {} + #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct Color {