diff --git a/examples/remote/main.c b/examples/remote/main.c index 81229e173..fc0f93ab1 100644 --- a/examples/remote/main.c +++ b/examples/remote/main.c @@ -1,17 +1,28 @@ +#define WGPU_INLINE +#define WGPU_FUNC + #include "./../../ffi/wgpu-remote.h" #include int main() { - WGPUInfrastructure infra = wgpu_initialize(); + WGPUInfrastructure infra = wgpu_client_new(); - if (!infra.client || !infra.server || infra.error) { - printf("Cannot initialize WGPU: %s", infra.error); + if (!infra.client || infra.error) { + printf("Cannot initialize WGPU client: %s", infra.error); + return 1; + } + + WGPUGlobal* server = wgpu_server_new(); + + if (!server) { + printf("Cannot initialize WGPU client: %s", server); return 1; } //TODO: do something meaningful - wgpu_terminate(infra.client); + wgpu_server_delete(server); + wgpu_client_delete(infra.client); return 0; } diff --git a/ffi/wgpu-remote.h b/ffi/wgpu-remote.h index 555c7dff2..d920eef42 100644 --- a/ffi/wgpu-remote.h +++ b/ffi/wgpu-remote.h @@ -14,64 +14,69 @@ typedef void WGPUEmpty; -#include -#include -#include -#include +#include +#include +#include +#include -enum class WGPUPowerPreference { +typedef enum { WGPUPowerPreference_Default = 0, WGPUPowerPreference_LowPower = 1, WGPUPowerPreference_HighPerformance = 2, -}; +} WGPUPowerPreference; -template -struct WGPUAdapter; +typedef struct WGPUClient WGPUClient; -struct WGPUClient; +typedef struct WGPUGlobal WGPUGlobal; -template -struct WGPUDevice; +typedef uint64_t WGPUId_Adapter_Dummy; -struct WGPUGlobal; +typedef WGPUId_Adapter_Dummy WGPUAdapterId; -using WGPUDummy = WGPUEmpty; +typedef uint64_t WGPUId_Device_Dummy; -template -using WGPUId = uint64_t; +typedef WGPUId_Device_Dummy WGPUDeviceId; -using WGPUAdapterId = WGPUId>; - -using WGPUDeviceId = WGPUId>; - -struct WGPUInfrastructure { +typedef struct { WGPUClient *client; const uint8_t *error; +} WGPUInfrastructure; - bool operator==(const WGPUInfrastructure& aOther) const { - return client == aOther.client && - error == aOther.error; - } -}; +typedef struct { + bool anisotropic_filtering; +} WGPUExtensions; -using WGPUBackendBit = uint32_t; +typedef struct { + uint32_t max_bind_groups; +} WGPULimits; -struct WGPURequestAdapterOptions { +typedef struct { + WGPUExtensions extensions; + WGPULimits limits; +} WGPUDeviceDescriptor; + +typedef uint32_t WGPUBackendBit; + +typedef struct { WGPUPowerPreference power_preference; WGPUBackendBit backends; - - bool operator==(const WGPURequestAdapterOptions& aOther) const { - return power_preference == aOther.power_preference && - backends == aOther.backends; - } -}; - -extern "C" { +} WGPURequestAdapterOptions; WGPU_INLINE void wgpu_client_delete(WGPUClient *aClient) WGPU_FUNC; +WGPU_INLINE +void wgpu_client_kill_adapter_ids(const WGPUClient *aClient, + const WGPUAdapterId *aIds, + uintptr_t aIdLength) +WGPU_FUNC; + +WGPU_INLINE +void wgpu_client_kill_device_id(const WGPUClient *aClient, + WGPUDeviceId aId) +WGPU_FUNC; + WGPU_INLINE uintptr_t wgpu_client_make_adapter_ids(const WGPUClient *aClient, WGPUAdapterId *aIds, @@ -84,7 +89,14 @@ WGPUDeviceId wgpu_client_make_device_id(const WGPUClient *aClient, WGPU_FUNC; WGPU_INLINE -WGPUInfrastructure wgpu_client_new() +WGPUInfrastructure wgpu_client_new(void) +WGPU_FUNC; + +WGPU_INLINE +void wgpu_server_adapter_request_device(const WGPUGlobal *aGlobal, + WGPUAdapterId aSelfId, + const WGPUDeviceDescriptor *aDesc, + WGPUDeviceId aNewId) WGPU_FUNC; WGPU_INLINE @@ -92,14 +104,17 @@ void wgpu_server_delete(WGPUGlobal *aGlobal) WGPU_FUNC; WGPU_INLINE -WGPUGlobal *wgpu_server_new() +void wgpu_server_device_destroy(const WGPUGlobal *aGlobal, + WGPUDeviceId aSelfId) WGPU_FUNC; WGPU_INLINE -WGPUAdapterId wgpu_server_request_adapter(const WGPUGlobal *aGlobal, - const WGPURequestAdapterOptions *aDesc, - const WGPUAdapterId *aIds, - uintptr_t aIdLength) +WGPUAdapterId wgpu_server_instance_request_adapter(const WGPUGlobal *aGlobal, + const WGPURequestAdapterOptions *aDesc, + const WGPUAdapterId *aIds, + uintptr_t aIdLength) WGPU_FUNC; -} // extern "C" +WGPU_INLINE +WGPUGlobal *wgpu_server_new(void) +WGPU_FUNC; diff --git a/wgpu-native/cbindgen.toml b/wgpu-native/cbindgen.toml index 9e296d5de..f111779e1 100644 --- a/wgpu-native/cbindgen.toml +++ b/wgpu-native/cbindgen.toml @@ -32,7 +32,6 @@ bitflags = true [defines] "feature = local" = "WGPU_LOCAL" -"feature = remote" = "WGPU_REMOTE" "feature = gfx-backend-gl" = "WGPU_BACKEND_GL" "feature = winit" = "WGPU_WINIT" "feature = glutin" = "WGPU_GLUTIN" diff --git a/wgpu-native/src/command/allocator.rs b/wgpu-native/src/command/allocator.rs index 07ce1bfe9..fd33c367b 100644 --- a/wgpu-native/src/command/allocator.rs +++ b/wgpu-native/src/command/allocator.rs @@ -60,16 +60,6 @@ pub struct CommandAllocator { } impl CommandAllocator { - pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self { - CommandAllocator { - queue_family, - inner: Mutex::new(Inner { - pools: HashMap::new(), - pending: Vec::new(), - }), - } - } - pub(crate) fn allocate( &self, device_id: Stored, @@ -103,6 +93,18 @@ impl CommandAllocator { features, } } +} + +impl CommandAllocator { + pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self { + CommandAllocator { + queue_family, + inner: Mutex::new(Inner { + pools: HashMap::new(), + pending: Vec::new(), + }), + } + } pub fn extend(&self, cmd_buf: &CommandBuffer) -> B::CommandBuffer { let mut inner = self.inner.lock(); diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index 4313ffe50..efa2d9956 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -112,7 +112,7 @@ pub struct CommandBuffer { pub(crate) raw: Vec, is_recording: bool, recorded_thread_id: ThreadId, - device_id: Stored, + pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) trackers: TrackerSet, pub(crate) used_swap_chain: Option<(Stored, B::Framebuffer)>, diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index ac07e7f8c..0510655a8 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -768,6 +768,21 @@ impl Device { } } +impl Device { + pub(crate) fn destroy_bind_group(&self, bind_group: binding_model::BindGroup) { + unsafe { + self.desc_allocator.lock().free(iter::once(bind_group.raw)); + } + } + + pub(crate) fn destroy_self(self) { + self.com_allocator.destroy(&self.raw); + unsafe { + self.desc_allocator.lock().cleanup(&self.raw); + } + } +} + #[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_device_get_limits(_device_id: DeviceId, limits: &mut Limits) { diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs index a51ac6eae..0e21b512d 100644 --- a/wgpu-native/src/hub.rs +++ b/wgpu-native/src/hub.rs @@ -389,6 +389,67 @@ impl Default for Hub { } } +impl Drop for Hub { + fn drop(&mut self) { + use crate::resource::TextureViewInner; + use hal::device::Device as _; + + let mut devices = self.devices.data.write(); + + for (_, (sampler, _)) in self.samplers.data.write().map.drain() { + unsafe { + devices[sampler.device_id.value].raw.destroy_sampler(sampler.raw); + } + } + { + let textures = self.textures.data.read(); + for (_, (texture_view, _)) in self.texture_views.data.write().map.drain() { + match texture_view.inner { + TextureViewInner::Native { raw, source_id } => { + let device = &devices[textures[source_id.value].device_id.value]; + unsafe { + device.raw.destroy_image_view(raw); + } + } + TextureViewInner::SwapChain { .. } => {} //TODO + } + } + } + for (_, (texture, _)) in self.textures.data.write().map.drain() { + unsafe { + devices[texture.device_id.value].raw.destroy_image(texture.raw); + } + } + for (_, (buffer, _)) in self.buffers.data.write().map.drain() { + unsafe { + devices[buffer.device_id.value].raw.destroy_buffer(buffer.raw); + } + } + for (_, (command_buffer, _)) in self.command_buffers.data.write().map.drain() { + devices[command_buffer.device_id.value].com_allocator.after_submit(command_buffer, 0); + } + for (_, (bind_group, _)) in self.bind_groups.data.write().map.drain() { + let device = &devices[bind_group.device_id.value]; + device.destroy_bind_group(bind_group); + } + + //TODO: + // self.compute_pipelines + // self.compute_passes + // self.render_pipelines + // self.render_passes + // self.bind_group_layouts + // self.pipeline_layouts + // self.shader_modules + // self.swap_chains + // self.adapters + + for (_, (device, _)) in devices.map.drain() { + device.destroy_self(); + } + } +} + #[derive(Debug, Default)] pub struct Hubs { #[cfg(any( @@ -424,6 +485,16 @@ impl Global { pub fn new(name: &str) -> Self { Self::new_impl(name) } + + #[cfg(not(feature = "local"))] + pub fn delete(self) { + let Global { mut instance, surfaces, hubs } = self; + drop(hubs); + // destroy surfaces + for (_, (surface, _)) in surfaces.data.write().map.drain() { + instance.destroy_surface(surface); + } + } } #[cfg(feature = "local")] diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index b5b733a6f..ab9e08231 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -58,6 +58,31 @@ impl Instance { dx11: gfx_backend_dx11::Instance::create(name, version).unwrap(), } } + + #[cfg(not(feature = "local"))] + pub(crate) fn destroy_surface(&mut self, surface: Surface) { + //TODO: fill out the proper destruction once we are on gfx-0.4 + #[cfg(any( + not(any(target_os = "ios", target_os = "macos")), + feature = "gfx-backend-vulkan" + ))] + { + if let Some(_suf) = surface.vulkan { + //self.vulkan.as_mut().unwrap().destroy_surface(suf); + } + } + #[cfg(any(target_os = "ios", target_os = "macos"))] + { + //self.metal.destroy_surface(surface.metal); + } + #[cfg(windows)] + { + if let Some(_suf) = surface.dx12 { + //self.dx12.as_mut().unwrap().destroy_surface(suf); + } + //self.dx11.destroy_surface(surface.dx11); + } + } } type GfxSurface = ::Surface; diff --git a/wgpu-remote/cbindgen.toml b/wgpu-remote/cbindgen.toml index d139f9f2a..2d552f481 100644 --- a/wgpu-remote/cbindgen.toml +++ b/wgpu-remote/cbindgen.toml @@ -14,7 +14,7 @@ include_version = true braces = "SameLine" line_length = 100 tab_width = 2 -language = "C++" +language = "C" [export] prefix = "WGPU" diff --git a/wgpu-remote/src/server.rs b/wgpu-remote/src/server.rs index a249df84c..719591ee4 100644 --- a/wgpu-remote/src/server.rs +++ b/wgpu-remote/src/server.rs @@ -13,8 +13,8 @@ pub extern "C" fn wgpu_server_new() -> *mut wgn::Global { #[no_mangle] pub extern "C" fn wgpu_server_delete(global: *mut wgn::Global) { log::info!("Terminating WGPU server"); - //TODO: proper cleanup - let _ = unsafe { Box::from_raw(global) }; + unsafe { Box::from_raw(global) }.delete(); + log::info!("\t...done"); } #[no_mangle] @@ -38,3 +38,9 @@ pub extern "C" fn wgpu_server_adapter_request_device( use wgn::adapter_request_device as func; wgn::gfx_select!(self_id => func(global, self_id, desc, new_id)); } + +#[no_mangle] +pub extern "C" fn wgpu_server_device_destroy(global: &wgn::Global, self_id: wgn::DeviceId) { + use wgn::device_destroy as func; + wgn::gfx_select!(self_id => func(global, self_id)) +}