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(); }