From 1fd05608fb6eb330227b598394ad6fbd77acebdf Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 2 Oct 2018 11:43:26 -0400 Subject: [PATCH 1/4] native: compute pass boilerplate --- wgpu-native/src/command/compute.rs | 32 +++++++++++++++++++++++++++++- wgpu-native/src/command/mod.rs | 13 ++++++++++-- wgpu-native/src/command/render.rs | 19 ++++++++---------- wgpu-native/src/lib.rs | 1 + wgpu-native/src/registry.rs | 4 +++- 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index fdf5473d5..245921fce 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -1,7 +1,37 @@ use hal; -//use {CommandBuffer, CommandBufferId, ComputePassId}; +use registry::{self, Items, Registry}; +use { + Stored, + CommandBufferId, ComputePassId +}; + pub struct ComputePass { raw: B::CommandBuffer, + cmb_id: Stored, +} + +impl ComputePass { + pub fn new(raw: B::CommandBuffer, cmb_id: CommandBufferId) -> Self { + ComputePass { + raw, + cmb_id: Stored(cmb_id), + } + } +} + +#[no_mangle] +pub extern "C" fn wgpu_compute_pass_end_pass( + pass_id: ComputePassId, +) -> CommandBufferId { + let pass = registry::COMPUTE_PASS_REGISTRY + .lock() + .take(pass_id); + + registry::COMMAND_BUFFER_REGISTRY + .lock() + .get_mut(pass.cmb_id.0) + .raw = Some(pass.raw); + pass.cmb_id.0 } diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index c90f9c34f..7b6eacb56 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -112,6 +112,15 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass( } #[no_mangle] -pub extern "C" fn wgpu_command_buffer_begin_compute_pass() -> ComputePassId { - unimplemented!() +pub extern "C" fn wgpu_command_buffer_begin_compute_pass( + command_buffer_id: CommandBufferId, +) -> ComputePassId { + 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(); + + registry::COMPUTE_PASS_REGISTRY + .lock() + .register(ComputePass::new(raw, command_buffer_id)) } diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index 94df08394..b807d4214 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -7,15 +7,12 @@ use { CommandBufferId, RenderPassId, }; + pub struct RenderPass { raw: B::CommandBuffer, cmb_id: Stored, } -// 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 { @@ -27,16 +24,16 @@ impl RenderPass { #[no_mangle] pub extern "C" fn wgpu_render_pass_end_pass( - render_pass_id: RenderPassId, + pass_id: RenderPassId, ) -> CommandBufferId { - let mut rp = registry::RENDER_PASS_REGISTRY + let mut pass = registry::RENDER_PASS_REGISTRY .lock() - .take(render_pass_id); - rp.raw.end_render_pass(); + .take(pass_id); + pass.raw.end_render_pass(); registry::COMMAND_BUFFER_REGISTRY .lock() - .get_mut(rp.cmb_id.0) - .raw = Some(rp.raw); - rp.cmb_id.0 + .get_mut(pass.cmb_id.0) + .raw = Some(pass.raw); + pass.cmb_id.0 } diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index 69e695f82..30a4b905b 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -126,3 +126,4 @@ type CommandBufferHandle = CommandBuffer; pub type RenderPassId = Id; type RenderPassHandle = RenderPass; pub type ComputePassId = Id; +type ComputePassHandle = ComputePass; diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index c55ca6ecc..89c6030b8 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -12,7 +12,7 @@ use std::sync::Arc; use { AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, - RenderPassHandle, + RenderPassHandle, ComputePassHandle, PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, }; @@ -178,4 +178,6 @@ lazy_static! { ConcreteRegistry::new(); pub(crate) static ref RENDER_PASS_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref COMPUTE_PASS_REGISTRY: ConcreteRegistry = + ConcreteRegistry::new(); } From d713f3e3804ecc5811de407665408e538e4cb7fd Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 2 Oct 2018 12:18:54 -0400 Subject: [PATCH 2/4] Consolidate all the registries together --- wgpu-native/src/command/compute.rs | 6 +- wgpu-native/src/command/mod.rs | 18 ++--- wgpu-native/src/command/render.rs | 6 +- wgpu-native/src/device.rs | 112 +++++++++++++++++------------ wgpu-native/src/instance.rs | 12 ++-- wgpu-native/src/registry.rs | 80 ++++++++++----------- 6 files changed, 125 insertions(+), 109 deletions(-) diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index 245921fce..2ab7d2926 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -1,6 +1,6 @@ use hal; -use registry::{self, Items, Registry}; +use registry::{HUB, Items, Registry}; use { Stored, CommandBufferId, ComputePassId @@ -25,11 +25,11 @@ impl ComputePass { pub extern "C" fn wgpu_compute_pass_end_pass( pass_id: ComputePassId, ) -> CommandBufferId { - let pass = registry::COMPUTE_PASS_REGISTRY + let pass = HUB.compute_passes .lock() .take(pass_id); - registry::COMMAND_BUFFER_REGISTRY + HUB.command_buffers .lock() .get_mut(pass.cmb_id.0) .raw = Some(pass.raw); diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index 7b6eacb56..25c44a745 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -12,7 +12,7 @@ use { Color, Origin3d, Stored, BufferId, CommandBufferId, ComputePassId, DeviceId, RenderPassId, TextureId, TextureViewId, }; -use registry::{self, Items, Registry}; +use registry::{HUB, Items, Registry}; use std::thread::ThreadId; @@ -86,13 +86,13 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass( command_buffer_id: CommandBufferId, _descriptor: RenderPassDescriptor, ) -> RenderPassId { - let mut cmb_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); - let mut cmb = cmb_guard.get_mut(command_buffer_id); + let mut cmb_guard = HUB.command_buffers.lock(); + let 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 device_guard = HUB.devices.lock(); + let _device = &device_guard.get(cmb.device_id.0).raw; //let render_pass = device.create_render_pass(); //let framebuffer = device.create_framebuffer(); @@ -106,7 +106,7 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass( hal::SubpassContents::Inline, );*/ - registry::RENDER_PASS_REGISTRY + HUB.render_passes .lock() .register(RenderPass::new(raw, command_buffer_id)) } @@ -115,12 +115,12 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass( pub extern "C" fn wgpu_command_buffer_begin_compute_pass( command_buffer_id: CommandBufferId, ) -> ComputePassId { - let mut cmb_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); - let mut cmb = cmb_guard.get_mut(command_buffer_id); + let mut cmb_guard = HUB.command_buffers.lock(); + let cmb = cmb_guard.get_mut(command_buffer_id); let raw = cmb.raw.take().unwrap(); - registry::COMPUTE_PASS_REGISTRY + HUB.compute_passes .lock() .register(ComputePass::new(raw, command_buffer_id)) } diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index b807d4214..d382bbf8d 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -1,7 +1,7 @@ use hal; use hal::command::RawCommandBuffer; -use registry::{self, Items, Registry}; +use registry::{HUB, Items, Registry}; use { Stored, CommandBufferId, RenderPassId, @@ -26,12 +26,12 @@ impl RenderPass { pub extern "C" fn wgpu_render_pass_end_pass( pass_id: RenderPassId, ) -> CommandBufferId { - let mut pass = registry::RENDER_PASS_REGISTRY + let mut pass = HUB.render_passes .lock() .take(pass_id); pass.raw.end_render_pass(); - registry::COMMAND_BUFFER_REGISTRY + HUB.command_buffers .lock() .get_mut(pass.cmb_id.0) .raw = Some(pass.raw); diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index cc4f230b0..28c4c8694 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1,15 +1,17 @@ -use hal::command::RawCommandBuffer; -use hal::queue::RawCommandQueue; -use hal::{self, Device as _Device}; use {back, binding_model, command, conv, memory, pipeline}; - -use registry::{self, Items, Registry}; -use std::{ffi, iter, slice}; +use registry::{HUB, Items, Registry}; use { AttachmentStateId, BindGroupLayoutId, BlendStateId, CommandBufferId, DepthStencilStateId, DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, }; +use hal::command::RawCommandBuffer; +use hal::queue::RawCommandQueue; +use hal::{self, Device as _Device}; + +use std::{ffi, slice}; + + pub struct Device { pub(crate) raw: B::Device, queue_group: hal::QueueGroup, @@ -42,7 +44,7 @@ pub extern "C" fn wgpu_device_create_bind_group_layout( desc: binding_model::BindGroupLayoutDescriptor, ) -> BindGroupLayoutId { let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; - let device_guard = registry::DEVICE_REGISTRY.lock(); + let device_guard = HUB.devices.lock(); let device = device_guard.get(device_id); let descriptor_set_layout = device.raw.create_descriptor_set_layout( bindings.iter().map(|binding| { @@ -56,7 +58,7 @@ pub extern "C" fn wgpu_device_create_bind_group_layout( }), &[], ); - registry::BIND_GROUP_LAYOUT_REGISTRY + HUB.bind_group_layouts .lock() .register(binding_model::BindGroupLayout { raw: descriptor_set_layout, @@ -68,17 +70,17 @@ pub extern "C" fn wgpu_device_create_pipeline_layout( device_id: DeviceId, desc: binding_model::PipelineLayoutDescriptor, ) -> PipelineLayoutId { - let bind_group_layout_guard = registry::BIND_GROUP_LAYOUT_REGISTRY.lock(); + let bind_group_layout_guard = HUB.bind_group_layouts.lock(); let descriptor_set_layouts = unsafe { slice::from_raw_parts(desc.bind_group_layouts, desc.bind_group_layouts_length) } .iter() .map(|id| bind_group_layout_guard.get(id.clone())) .collect::>(); - let device_guard = registry::DEVICE_REGISTRY.lock(); + let device_guard = HUB.devices.lock(); 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 + HUB.pipeline_layouts .lock() .register(binding_model::PipelineLayout { raw: pipeline_layout, @@ -90,7 +92,7 @@ pub extern "C" fn wgpu_device_create_blend_state( _device_id: DeviceId, desc: pipeline::BlendStateDescriptor, ) -> BlendStateId { - registry::BLEND_STATE_REGISTRY + HUB.blend_states .lock() .register(pipeline::BlendState { raw: conv::map_blend_state_descriptor(desc), @@ -102,7 +104,7 @@ pub extern "C" fn wgpu_device_create_depth_stencil_state( _device_id: DeviceId, desc: pipeline::DepthStencilStateDescriptor, ) -> DepthStencilStateId { - registry::DEPTH_STENCIL_STATE_REGISTRY + HUB.depth_stencil_states .lock() .register(pipeline::DepthStencilState { raw: conv::map_depth_stencil_state(desc), @@ -114,12 +116,12 @@ pub extern "C" fn wgpu_device_create_shader_module( device_id: DeviceId, desc: pipeline::ShaderModuleDescriptor, ) -> ShaderModuleId { - let device_guard = registry::DEVICE_REGISTRY.lock(); + let device_guard = HUB.devices.lock(); 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(); - registry::SHADER_MODULE_REGISTRY + HUB.shader_modules .lock() .register(ShaderModule { raw: shader }) } @@ -129,14 +131,14 @@ pub extern "C" fn wgpu_device_create_command_buffer( device_id: DeviceId, _desc: command::CommandBufferDescriptor, ) -> CommandBufferId { - let mut device_guard = registry::DEVICE_REGISTRY.lock(); + let mut device_guard = HUB.devices.lock(); let device = device_guard.get_mut(device_id); 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(), ); - registry::COMMAND_BUFFER_REGISTRY.lock().register(cmd_buf) + HUB.command_buffers.lock().register(cmd_buf) } #[no_mangle] @@ -150,28 +152,48 @@ pub extern "C" fn wgpu_queue_submit( command_buffer_ptr: *const CommandBufferId, command_buffer_count: usize, ) { - let mut device_guard = registry::DEVICE_REGISTRY.lock(); + let mut device_guard = HUB.devices.lock(); let device = device_guard.get_mut(queue_id); - let command_buffer_ids = - unsafe { slice::from_raw_parts(command_buffer_ptr, command_buffer_count) }; - //TODO: submit at once, requires `get_all()` - let mut command_buffer_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); + let mut command_buffer_guard = HUB.command_buffers.lock(); + let command_buffer_ids = unsafe { + slice::from_raw_parts(command_buffer_ptr, command_buffer_count) + }; + + // finish all the command buffers first for &cmb_id in command_buffer_ids { - let mut cmd_buf = command_buffer_guard.take(cmb_id); - { - let mut raw = cmd_buf.raw.as_mut().unwrap(); - raw.finish(); - let submission = hal::queue::RawSubmission { - cmd_buffers: iter::once(raw), - wait_semaphores: &[], - signal_semaphores: &[], - }; - unsafe { - device.queue_group.queues[0] - .as_raw_mut() - .submit_raw(submission, None); - } + command_buffer_guard + .get_mut(cmb_id) + .raw + .as_mut() + .unwrap() + .finish(); + } + + // now prepare the GPU submission + { + let submission = hal::queue::RawSubmission { + cmd_buffers: command_buffer_ids + .iter() + .map(|&cmb_id| { + command_buffer_guard + .get(cmb_id) + .raw + .as_ref() + .unwrap() + }), + wait_semaphores: &[], + signal_semaphores: &[], + }; + unsafe { + device.queue_group.queues[0] + .as_raw_mut() + .submit_raw(submission, None); } + } + + // finally, return the command buffers to the allocator + for &cmb_id in command_buffer_ids { + let cmd_buf = command_buffer_guard.take(cmb_id); device.com_allocator.submit(cmd_buf); } } @@ -181,7 +203,7 @@ pub extern "C" fn wgpu_device_create_attachment_state( device_id: DeviceId, desc: pipeline::AttachmentStateDescriptor, ) -> AttachmentStateId { - let device_guard = registry::DEVICE_REGISTRY.lock(); + let device_guard = HUB.devices.lock(); let device = &device_guard.get(device_id).raw; let color_formats = unsafe { @@ -224,7 +246,7 @@ pub extern "C" fn wgpu_device_create_attachment_state( depth_stencil_format, }; - registry::ATTACHMENT_STATE_REGISTRY + HUB.attachment_states .lock() .register(at_state) } @@ -240,12 +262,12 @@ pub extern "C" fn wgpu_device_create_render_pipeline( height: 100, }; - let device_guard = registry::DEVICE_REGISTRY.lock(); + let device_guard = HUB.devices.lock(); let device = &device_guard.get(device_id).raw; - let pipeline_layout_guard = registry::PIPELINE_LAYOUT_REGISTRY.lock(); + let pipeline_layout_guard = HUB.pipeline_layouts.lock(); let layout = &pipeline_layout_guard.get(desc.layout).raw; let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) }; - let shader_module_guard = registry::SHADER_MODULE_REGISTRY.lock(); + let shader_module_guard = HUB.shader_modules.lock(); let shaders = { let mut vertex = None; let mut fragment = None; @@ -303,7 +325,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline( primitive_restart: hal::pso::PrimitiveRestart::Disabled, // TODO }; - let blend_state_guard = registry::BLEND_STATE_REGISTRY.lock(); + let blend_state_guard = HUB.blend_states.lock(); let blend_state = unsafe { slice::from_raw_parts(desc.blend_state, desc.blend_state_length) } .iter() .map(|id| blend_state_guard.get(id.clone()).raw) @@ -314,7 +336,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline( targets: blend_state, }; - let depth_stencil_state_guard = registry::DEPTH_STENCIL_STATE_REGISTRY.lock(); + let depth_stencil_state_guard = HUB.depth_stencil_states.lock(); let depth_stencil = depth_stencil_state_guard.get(desc.depth_stencil_state).raw; // TODO @@ -341,7 +363,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline( depth_bounds: None, }; - let attachment_state_guard = registry::ATTACHMENT_STATE_REGISTRY.lock(); + let attachment_state_guard = HUB.attachment_states.lock(); let attachment_state = attachment_state_guard.get(desc.attachment_state); // TODO @@ -377,7 +399,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline( .create_graphics_pipeline(&pipeline_desc, None) .unwrap(); - registry::RENDER_PIPELINE_REGISTRY + HUB.render_pipelines .lock() .register(pipeline::RenderPipeline { raw: pipeline }) } diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index e534e4785..5217bae11 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -1,6 +1,6 @@ use hal::{self, Instance as _Instance, PhysicalDevice as _PhysicalDevice}; -use registry::{self, Items, Registry}; +use registry::{HUB, Items, Registry}; use {AdapterId, Device, DeviceId, InstanceId}; #[repr(C)] @@ -35,7 +35,7 @@ pub extern "C" fn wgpu_create_instance() -> InstanceId { ))] { let inst = ::back::Instance::create("wgpu", 1); - registry::INSTANCE_REGISTRY.lock().register(inst) + HUB.instances.lock().register(inst) } #[cfg(not(any( feature = "gfx-backend-vulkan", @@ -52,7 +52,7 @@ pub extern "C" fn wgpu_instance_get_adapter( instance_id: InstanceId, desc: AdapterDescriptor, ) -> AdapterId { - let instance_guard = registry::INSTANCE_REGISTRY.lock(); + let instance_guard = HUB.instances.lock(); let instance = instance_guard.get(instance_id); let (mut low, mut high, mut other) = (None, None, None); for adapter in instance.enumerate_adapters() { @@ -67,7 +67,7 @@ pub extern "C" fn wgpu_instance_get_adapter( PowerPreference::LowPower => low.or(high), PowerPreference::HighPerformance | PowerPreference::Default => high.or(low), }; - registry::ADAPTER_REGISTRY + HUB.adapters .lock() .register(some.or(other).unwrap()) } @@ -77,11 +77,11 @@ pub extern "C" fn wgpu_adapter_create_device( adapter_id: AdapterId, _desc: DeviceDescriptor, ) -> DeviceId { - let mut adapter_guard = registry::ADAPTER_REGISTRY.lock(); + let mut adapter_guard = HUB.adapters.lock(); let adapter = adapter_guard.get_mut(adapter_id); let (device, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap(); let mem_props = adapter.physical_device.memory_properties(); - registry::DEVICE_REGISTRY + HUB.devices .lock() .register(Device::new(device, queue_group, mem_props)) } diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index 89c6030b8..b5b450146 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -17,9 +17,9 @@ use { }; #[cfg(not(feature = "remote"))] -pub(crate) type Id = *mut c_void; +pub type Id = *mut c_void; #[cfg(feature = "remote")] -pub(crate) type Id = u32; +pub type Id = u32; type Item<'a, T> = &'a T; type ItemMut<'a, T> = &'a mut T; @@ -29,12 +29,11 @@ type ItemsGuard<'a, T> = LocalItems; #[cfg(feature = "remote")] type ItemsGuard<'a, T> = MutexGuard<'a, RemoteItems>; -pub(crate) trait Registry { - fn new() -> Self; +pub trait Registry: Default { fn lock(&self) -> ItemsGuard; } -pub(crate) trait Items { +pub trait Items { fn register(&mut self, handle: T) -> Id; fn get(&self, id: Id) -> Item; fn get_mut(&mut self, id: Id) -> ItemMut; @@ -42,7 +41,7 @@ pub(crate) trait Items { } #[cfg(not(feature = "remote"))] -pub(crate) struct LocalItems { +pub struct LocalItems { marker: PhantomData, } @@ -66,18 +65,19 @@ impl Items for LocalItems { } #[cfg(not(feature = "remote"))] -pub(crate) struct LocalRegistry { +pub struct LocalRegistry { marker: PhantomData, } - #[cfg(not(feature = "remote"))] -impl Registry for LocalRegistry { - fn new() -> Self { +impl Default for LocalRegistry { + fn default() -> Self { LocalRegistry { marker: PhantomData, } } - +} +#[cfg(not(feature = "remote"))] +impl Registry for LocalRegistry { fn lock(&self) -> ItemsGuard { LocalItems { marker: PhantomData, @@ -86,7 +86,7 @@ impl Registry for LocalRegistry { } #[cfg(feature = "remote")] -pub(crate) struct RemoteItems { +pub struct RemoteItems { next_id: Id, tracked: FastHashMap, free: Vec, @@ -132,18 +132,19 @@ impl Items for RemoteItems { } #[cfg(feature = "remote")] -pub(crate) struct RemoteRegistry { +pub struct RemoteRegistry { items: Arc>>, } - #[cfg(feature = "remote")] -impl Registry for RemoteRegistry { - fn new() -> Self { +impl Default for RemoteRegistry { + fn default() -> Self { RemoteRegistry { items: Arc::new(Mutex::new(RemoteItems::new())), } } - +} +#[cfg(feature = "remote")] +impl Registry for RemoteRegistry { fn lock(&self) -> ItemsGuard { self.items.lock() } @@ -154,30 +155,23 @@ type ConcreteRegistry = LocalRegistry; #[cfg(feature = "remote")] type ConcreteRegistry = RemoteRegistry; -lazy_static! { - pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref ATTACHMENT_STATE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref BIND_GROUP_LAYOUT_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref BLEND_STATE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref DEPTH_STENCIL_STATE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); - pub(crate) static ref COMMAND_BUFFER_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref PIPELINE_LAYOUT_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref RENDER_PIPELINE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref RENDER_PASS_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); - pub(crate) static ref COMPUTE_PASS_REGISTRY: ConcreteRegistry = - ConcreteRegistry::new(); +#[derive(Default)] +pub struct Hub { + pub(crate) instances: ConcreteRegistry, + pub(crate) adapters: ConcreteRegistry, + pub(crate) devices: ConcreteRegistry, + pub(crate) pipeline_layouts: ConcreteRegistry, + pub(crate) bind_group_layouts: ConcreteRegistry, + pub(crate) attachment_states: ConcreteRegistry, + pub(crate) blend_states: ConcreteRegistry, + pub(crate) depth_stencil_states: ConcreteRegistry, + pub(crate) shader_modules: ConcreteRegistry, + pub(crate) command_buffers: ConcreteRegistry, + pub(crate) render_pipelines: ConcreteRegistry, + pub(crate) render_passes: ConcreteRegistry, + pub(crate) compute_passes: ConcreteRegistry, +} + +lazy_static! { + pub static ref HUB: Hub = Hub::default(); } From 17527544891e5ccdef9f384694cb6095cc2b80a4 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 2 Oct 2018 12:31:02 -0400 Subject: [PATCH 3/4] Modularize the registry --- wgpu-native/src/registry.rs | 177 ----------------------------- wgpu-native/src/registry/local.rs | 48 ++++++++ wgpu-native/src/registry/mod.rs | 52 +++++++++ wgpu-native/src/registry/remote.rs | 68 +++++++++++ 4 files changed, 168 insertions(+), 177 deletions(-) delete mode 100644 wgpu-native/src/registry.rs create mode 100644 wgpu-native/src/registry/local.rs create mode 100644 wgpu-native/src/registry/mod.rs create mode 100644 wgpu-native/src/registry/remote.rs diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs deleted file mode 100644 index b5b450146..000000000 --- a/wgpu-native/src/registry.rs +++ /dev/null @@ -1,177 +0,0 @@ -#[cfg(feature = "remote")] -use hal::backend::FastHashMap; -#[cfg(feature = "remote")] -use parking_lot::{Mutex, MutexGuard}; -#[cfg(not(feature = "remote"))] -use std::marker::PhantomData; -#[cfg(not(feature = "remote"))] -use std::os::raw::c_void; -#[cfg(feature = "remote")] -use std::sync::Arc; - -use { - AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, - CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, - RenderPassHandle, ComputePassHandle, - PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, -}; - -#[cfg(not(feature = "remote"))] -pub type Id = *mut c_void; -#[cfg(feature = "remote")] -pub type Id = u32; - -type Item<'a, T> = &'a T; -type ItemMut<'a, T> = &'a mut T; - -#[cfg(not(feature = "remote"))] -type ItemsGuard<'a, T> = LocalItems; -#[cfg(feature = "remote")] -type ItemsGuard<'a, T> = MutexGuard<'a, RemoteItems>; - -pub trait Registry: Default { - fn lock(&self) -> ItemsGuard; -} - -pub trait Items { - fn register(&mut self, handle: T) -> Id; - fn get(&self, id: Id) -> Item; - fn get_mut(&mut self, id: Id) -> ItemMut; - fn take(&mut self, id: Id) -> T; -} - -#[cfg(not(feature = "remote"))] -pub struct LocalItems { - marker: PhantomData, -} - -#[cfg(not(feature = "remote"))] -impl Items for LocalItems { - fn register(&mut self, handle: T) -> Id { - Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void - } - - fn get(&self, id: Id) -> Item { - unsafe { (id as *mut T).as_ref() }.unwrap() - } - - fn get_mut(&mut self, id: Id) -> ItemMut { - unsafe { (id as *mut T).as_mut() }.unwrap() - } - - fn take(&mut self, id: Id) -> T { - unsafe { *Box::from_raw(id as *mut T) } - } -} - -#[cfg(not(feature = "remote"))] -pub struct LocalRegistry { - marker: PhantomData, -} -#[cfg(not(feature = "remote"))] -impl Default for LocalRegistry { - fn default() -> Self { - LocalRegistry { - marker: PhantomData, - } - } -} -#[cfg(not(feature = "remote"))] -impl Registry for LocalRegistry { - fn lock(&self) -> ItemsGuard { - LocalItems { - marker: PhantomData, - } - } -} - -#[cfg(feature = "remote")] -pub struct RemoteItems { - next_id: Id, - tracked: FastHashMap, - free: Vec, -} - -#[cfg(feature = "remote")] -impl RemoteItems { - fn new() -> Self { - RemoteItems { - next_id: 0, - tracked: FastHashMap::default(), - free: Vec::new(), - } - } -} - -#[cfg(feature = "remote")] -impl Items for RemoteItems { - fn register(&mut self, handle: T) -> Id { - let id = match self.free.pop() { - Some(id) => id, - None => { - self.next_id += 1; - self.next_id - 1 - } - }; - self.tracked.insert(id, handle); - id - } - - fn get(&self, id: Id) -> Item { - self.tracked.get(&id).unwrap() - } - - fn get_mut(&mut self, id: Id) -> ItemMut { - self.tracked.get_mut(&id).unwrap() - } - - fn take(&mut self, id: Id) -> T { - self.free.push(id); - self.tracked.remove(&id).unwrap() - } -} - -#[cfg(feature = "remote")] -pub struct RemoteRegistry { - items: Arc>>, -} -#[cfg(feature = "remote")] -impl Default for RemoteRegistry { - fn default() -> Self { - RemoteRegistry { - items: Arc::new(Mutex::new(RemoteItems::new())), - } - } -} -#[cfg(feature = "remote")] -impl Registry for RemoteRegistry { - fn lock(&self) -> ItemsGuard { - self.items.lock() - } -} - -#[cfg(not(feature = "remote"))] -type ConcreteRegistry = LocalRegistry; -#[cfg(feature = "remote")] -type ConcreteRegistry = RemoteRegistry; - -#[derive(Default)] -pub struct Hub { - pub(crate) instances: ConcreteRegistry, - pub(crate) adapters: ConcreteRegistry, - pub(crate) devices: ConcreteRegistry, - pub(crate) pipeline_layouts: ConcreteRegistry, - pub(crate) bind_group_layouts: ConcreteRegistry, - pub(crate) attachment_states: ConcreteRegistry, - pub(crate) blend_states: ConcreteRegistry, - pub(crate) depth_stencil_states: ConcreteRegistry, - pub(crate) shader_modules: ConcreteRegistry, - pub(crate) command_buffers: ConcreteRegistry, - pub(crate) render_pipelines: ConcreteRegistry, - pub(crate) render_passes: ConcreteRegistry, - pub(crate) compute_passes: ConcreteRegistry, -} - -lazy_static! { - pub static ref HUB: Hub = Hub::default(); -} diff --git a/wgpu-native/src/registry/local.rs b/wgpu-native/src/registry/local.rs new file mode 100644 index 000000000..e4e4bae6d --- /dev/null +++ b/wgpu-native/src/registry/local.rs @@ -0,0 +1,48 @@ +use std::marker::PhantomData; +use std::os::raw::c_void; + + +pub type Id = *mut c_void; +pub type ItemsGuard<'a, T> = Items; + +pub struct Items { + marker: PhantomData, +} + +impl super::Items for Items { + fn register(&mut self, handle: T) -> Id { + Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void + } + + fn get(&self, id: Id) -> super::Item { + unsafe { (id as *mut T).as_ref() }.unwrap() + } + + fn get_mut(&mut self, id: Id) -> super::ItemMut { + unsafe { (id as *mut T).as_mut() }.unwrap() + } + + fn take(&mut self, id: Id) -> T { + unsafe { *Box::from_raw(id as *mut T) } + } +} + +pub struct Registry { + marker: PhantomData, +} + +impl Default for Registry { + fn default() -> Self { + Registry { + marker: PhantomData, + } + } +} + +impl super::Registry for Registry { + fn lock(&self) -> ItemsGuard { + Items { + marker: PhantomData, + } + } +} diff --git a/wgpu-native/src/registry/mod.rs b/wgpu-native/src/registry/mod.rs new file mode 100644 index 000000000..fecdf2c2b --- /dev/null +++ b/wgpu-native/src/registry/mod.rs @@ -0,0 +1,52 @@ +#[cfg(not(feature = "remote"))] +mod local; +#[cfg(feature = "remote")] +mod remote; + +#[cfg(not(feature = "remote"))] +pub use self::local::{Id, ItemsGuard, Registry as ConcreteRegistry}; +#[cfg(feature = "remote")] +pub use self::remote::{Id, ItemsGuard, Registry as ConcreteRegistry}; + +use { + AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, + CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, + RenderPassHandle, ComputePassHandle, + PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, +}; + + +type Item<'a, T> = &'a T; +type ItemMut<'a, T> = &'a mut T; + +pub trait Registry: Default { + fn lock(&self) -> ItemsGuard; +} + +pub trait Items { + fn register(&mut self, handle: T) -> Id; + fn get(&self, id: Id) -> Item; + fn get_mut(&mut self, id: Id) -> ItemMut; + fn take(&mut self, id: Id) -> T; +} + +#[derive(Default)] +pub struct Hub { + pub(crate) instances: ConcreteRegistry, + pub(crate) adapters: ConcreteRegistry, + pub(crate) devices: ConcreteRegistry, + pub(crate) pipeline_layouts: ConcreteRegistry, + pub(crate) bind_group_layouts: ConcreteRegistry, + pub(crate) attachment_states: ConcreteRegistry, + pub(crate) blend_states: ConcreteRegistry, + pub(crate) depth_stencil_states: ConcreteRegistry, + pub(crate) shader_modules: ConcreteRegistry, + pub(crate) command_buffers: ConcreteRegistry, + pub(crate) render_pipelines: ConcreteRegistry, + pub(crate) render_passes: ConcreteRegistry, + pub(crate) compute_passes: ConcreteRegistry, +} + +lazy_static! { + pub static ref HUB: Hub = Hub::default(); +} diff --git a/wgpu-native/src/registry/remote.rs b/wgpu-native/src/registry/remote.rs new file mode 100644 index 000000000..1253ef05e --- /dev/null +++ b/wgpu-native/src/registry/remote.rs @@ -0,0 +1,68 @@ +use hal::backend::FastHashMap; +use parking_lot::{Mutex, MutexGuard}; +use std::sync::Arc; + + +pub type Id = u32; +pub type ItemsGuard<'a, T> = MutexGuard<'a, Items>; + +pub struct Items { + next_id: Id, + tracked: FastHashMap, + free: Vec, +} + +impl Items { + fn new() -> Self { + Items { + next_id: 0, + tracked: FastHashMap::default(), + free: Vec::new(), + } + } +} + +impl super::Items for Items { + fn register(&mut self, handle: T) -> Id { + let id = match self.free.pop() { + Some(id) => id, + None => { + self.next_id += 1; + self.next_id - 1 + } + }; + self.tracked.insert(id, handle); + id + } + + fn get(&self, id: Id) -> super::Item { + self.tracked.get(&id).unwrap() + } + + fn get_mut(&mut self, id: Id) -> super::ItemMut { + self.tracked.get_mut(&id).unwrap() + } + + fn take(&mut self, id: Id) -> T { + self.free.push(id); + self.tracked.remove(&id).unwrap() + } +} + +pub struct Registry { + items: Arc>>, +} + +impl Default for Registry { + fn default() -> Self { + Registry { + items: Arc::new(Mutex::new(Items::new())), + } + } +} + +impl super::Registry for Registry { + fn lock(&self) -> ItemsGuard { + self.items.lock() + } +} From a00c23e350bd7b65380abaab8aa9be6bcd882be8 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 2 Oct 2018 12:32:39 -0400 Subject: [PATCH 4/4] Basic compute passes on Rust side --- wgpu-rs/src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 630074918..3b859990c 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -68,6 +68,11 @@ pub struct RenderPass<'a> { parent: &'a mut CommandBuffer, } +pub struct ComputePass<'a> { + id: wgn::ComputePassId, + parent: &'a mut CommandBuffer, +} + pub struct Queue { id: wgn::QueueId, } @@ -247,6 +252,13 @@ impl CommandBuffer { parent: self, } } + + pub fn begin_compute_pass(&mut self) -> ComputePass { + ComputePass { + id: wgn::wgpu_command_buffer_begin_compute_pass(self.id), + parent: self, + } + } } impl<'a> RenderPass<'a> { @@ -256,6 +268,13 @@ impl<'a> RenderPass<'a> { } } +impl<'a> ComputePass<'a> { + pub fn end_pass(self) -> &'a mut CommandBuffer { + wgn::wgpu_compute_pass_end_pass(self.id); + self.parent + } +} + impl Queue { pub fn submit(&self, command_buffers: &[CommandBuffer]) { wgn::wgpu_queue_submit(