Skip to content

Commit 538c23b

Browse files
committed
Implement shutdown for the remote server
1 parent e37149b commit 538c23b

File tree

10 files changed

+204
-60
lines changed

10 files changed

+204
-60
lines changed

examples/remote/main.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1+
#define WGPU_INLINE
2+
#define WGPU_FUNC
3+
14
#include "./../../ffi/wgpu-remote.h"
25
#include <stdio.h>
36

47
int main() {
5-
WGPUInfrastructure infra = wgpu_initialize();
8+
WGPUInfrastructure infra = wgpu_client_new();
9+
10+
if (!infra.client || infra.error) {
11+
printf("Cannot initialize WGPU client: %s", infra.error);
12+
return 1;
13+
}
14+
15+
WGPUGlobal* server = wgpu_server_new();
616

7-
if (!infra.client || !infra.server || infra.error) {
8-
printf("Cannot initialize WGPU: %s", infra.error);
17+
if (!server) {
18+
printf("Cannot initialize WGPU client: %s", server);
919
return 1;
1020
}
1121

1222
//TODO: do something meaningful
1323

14-
wgpu_terminate(infra.client);
24+
wgpu_server_delete(server);
25+
wgpu_client_delete(infra.client);
1526

1627
return 0;
1728
}

ffi/wgpu-remote.h

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,62 +14,67 @@
1414
typedef void WGPUEmpty;
1515

1616

17-
#include <cstdarg>
18-
#include <cstdint>
19-
#include <cstdlib>
20-
#include <new>
17+
#include <stdarg.h>
18+
#include <stdbool.h>
19+
#include <stdint.h>
20+
#include <stdlib.h>
2121

22-
enum class WGPUPowerPreference {
22+
typedef enum {
2323
WGPUPowerPreference_Default = 0,
2424
WGPUPowerPreference_LowPower = 1,
2525
WGPUPowerPreference_HighPerformance = 2,
26-
};
26+
} WGPUPowerPreference;
2727

28-
template<typename B>
29-
struct WGPUAdapter;
28+
typedef struct WGPUClient WGPUClient;
3029

31-
struct WGPUClient;
30+
typedef struct WGPUGlobal WGPUGlobal;
3231

33-
template<typename B>
34-
struct WGPUDevice;
32+
typedef uint64_t WGPUId_Adapter_Dummy;
3533

36-
struct WGPUGlobal;
34+
typedef WGPUId_Adapter_Dummy WGPUAdapterId;
3735

38-
using WGPUDummy = WGPUEmpty;
36+
typedef uint64_t WGPUId_Device_Dummy;
3937

40-
template<typename T>
41-
using WGPUId = uint64_t;
38+
typedef WGPUId_Device_Dummy WGPUDeviceId;
4239

43-
using WGPUAdapterId = WGPUId<WGPUAdapter<WGPUDummy>>;
44-
45-
using WGPUDeviceId = WGPUId<WGPUDevice<WGPUDummy>>;
46-
47-
struct WGPUInfrastructure {
40+
typedef struct {
4841
WGPUClient *client;
4942
const uint8_t *error;
43+
} WGPUInfrastructure;
44+
45+
typedef struct {
46+
bool anisotropic_filtering;
47+
} WGPUExtensions;
48+
49+
typedef struct {
50+
uint32_t max_bind_groups;
51+
} WGPULimits;
5052

51-
bool operator==(const WGPUInfrastructure& aOther) const {
52-
return client == aOther.client &&
53-
error == aOther.error;
54-
}
55-
};
53+
typedef struct {
54+
WGPUExtensions extensions;
55+
WGPULimits limits;
56+
} WGPUDeviceDescriptor;
5657

57-
using WGPUBackendBit = uint32_t;
58+
typedef uint32_t WGPUBackendBit;
5859

59-
struct WGPURequestAdapterOptions {
60+
typedef struct {
6061
WGPUPowerPreference power_preference;
6162
WGPUBackendBit backends;
63+
} WGPURequestAdapterOptions;
6264

63-
bool operator==(const WGPURequestAdapterOptions& aOther) const {
64-
return power_preference == aOther.power_preference &&
65-
backends == aOther.backends;
66-
}
67-
};
65+
WGPU_INLINE
66+
void wgpu_client_delete(WGPUClient *aClient)
67+
WGPU_FUNC;
6868

69-
extern "C" {
69+
WGPU_INLINE
70+
void wgpu_client_kill_adapter_ids(const WGPUClient *aClient,
71+
const WGPUAdapterId *aIds,
72+
uintptr_t aIdLength)
73+
WGPU_FUNC;
7074

7175
WGPU_INLINE
72-
void wgpu_client_delete(WGPUClient *aClient)
76+
void wgpu_client_kill_device_id(const WGPUClient *aClient,
77+
WGPUDeviceId aId)
7378
WGPU_FUNC;
7479

7580
WGPU_INLINE
@@ -84,22 +89,32 @@ WGPUDeviceId wgpu_client_make_device_id(const WGPUClient *aClient,
8489
WGPU_FUNC;
8590

8691
WGPU_INLINE
87-
WGPUInfrastructure wgpu_client_new()
92+
WGPUInfrastructure wgpu_client_new(void)
93+
WGPU_FUNC;
94+
95+
WGPU_INLINE
96+
void wgpu_server_adapter_request_device(const WGPUGlobal *aGlobal,
97+
WGPUAdapterId aSelfId,
98+
const WGPUDeviceDescriptor *aDesc,
99+
WGPUDeviceId aNewId)
88100
WGPU_FUNC;
89101

90102
WGPU_INLINE
91103
void wgpu_server_delete(WGPUGlobal *aGlobal)
92104
WGPU_FUNC;
93105

94106
WGPU_INLINE
95-
WGPUGlobal *wgpu_server_new()
107+
void wgpu_server_device_destroy(const WGPUGlobal *aGlobal,
108+
WGPUDeviceId aSelfId)
96109
WGPU_FUNC;
97110

98111
WGPU_INLINE
99-
WGPUAdapterId wgpu_server_request_adapter(const WGPUGlobal *aGlobal,
100-
const WGPURequestAdapterOptions *aDesc,
101-
const WGPUAdapterId *aIds,
102-
uintptr_t aIdLength)
112+
WGPUAdapterId wgpu_server_instance_request_adapter(const WGPUGlobal *aGlobal,
113+
const WGPURequestAdapterOptions *aDesc,
114+
const WGPUAdapterId *aIds,
115+
uintptr_t aIdLength)
103116
WGPU_FUNC;
104117

105-
} // extern "C"
118+
WGPU_INLINE
119+
WGPUGlobal *wgpu_server_new(void)
120+
WGPU_FUNC;

wgpu-native/cbindgen.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ bitflags = true
3232

3333
[defines]
3434
"feature = local" = "WGPU_LOCAL"
35-
"feature = remote" = "WGPU_REMOTE"
3635
"feature = gfx-backend-gl" = "WGPU_BACKEND_GL"
3736
"feature = winit" = "WGPU_WINIT"
3837
"feature = glutin" = "WGPU_GLUTIN"

wgpu-native/src/command/allocator.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,6 @@ pub struct CommandAllocator<B: hal::Backend> {
6060
}
6161

6262
impl<B: GfxBackend> CommandAllocator<B> {
63-
pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self {
64-
CommandAllocator {
65-
queue_family,
66-
inner: Mutex::new(Inner {
67-
pools: HashMap::new(),
68-
pending: Vec::new(),
69-
}),
70-
}
71-
}
72-
7363
pub(crate) fn allocate(
7464
&self,
7565
device_id: Stored<DeviceId>,
@@ -103,6 +93,18 @@ impl<B: GfxBackend> CommandAllocator<B> {
10393
features,
10494
}
10595
}
96+
}
97+
98+
impl<B: hal::Backend> CommandAllocator<B> {
99+
pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self {
100+
CommandAllocator {
101+
queue_family,
102+
inner: Mutex::new(Inner {
103+
pools: HashMap::new(),
104+
pending: Vec::new(),
105+
}),
106+
}
107+
}
106108

107109
pub fn extend(&self, cmd_buf: &CommandBuffer<B>) -> B::CommandBuffer {
108110
let mut inner = self.inner.lock();

wgpu-native/src/command/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub struct CommandBuffer<B: hal::Backend> {
112112
pub(crate) raw: Vec<B::CommandBuffer>,
113113
is_recording: bool,
114114
recorded_thread_id: ThreadId,
115-
device_id: Stored<DeviceId>,
115+
pub(crate) device_id: Stored<DeviceId>,
116116
pub(crate) life_guard: LifeGuard,
117117
pub(crate) trackers: TrackerSet,
118118
pub(crate) used_swap_chain: Option<(Stored<TextureViewId>, B::Framebuffer)>,

wgpu-native/src/device.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,21 @@ impl<B: GfxBackend> Device<B> {
768768
}
769769
}
770770

771+
impl<B: hal::Backend> Device<B> {
772+
pub(crate) fn destroy_bind_group(&self, bind_group: binding_model::BindGroup<B>) {
773+
unsafe {
774+
self.desc_allocator.lock().free(iter::once(bind_group.raw));
775+
}
776+
}
777+
778+
pub(crate) fn destroy_self(self) {
779+
self.com_allocator.destroy(&self.raw);
780+
unsafe {
781+
self.desc_allocator.lock().cleanup(&self.raw);
782+
}
783+
}
784+
}
785+
771786
#[cfg(feature = "local")]
772787
#[no_mangle]
773788
pub extern "C" fn wgpu_device_get_limits(_device_id: DeviceId, limits: &mut Limits) {

wgpu-native/src/hub.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,67 @@ impl<B: GfxBackend> Default for Hub<B> {
389389
}
390390
}
391391

392+
impl<B: hal::Backend> Drop for Hub<B> {
393+
fn drop(&mut self) {
394+
use crate::resource::TextureViewInner;
395+
use hal::device::Device as _;
396+
397+
let mut devices = self.devices.data.write();
398+
399+
for (_, (sampler, _)) in self.samplers.data.write().map.drain() {
400+
unsafe {
401+
devices[sampler.device_id.value].raw.destroy_sampler(sampler.raw);
402+
}
403+
}
404+
{
405+
let textures = self.textures.data.read();
406+
for (_, (texture_view, _)) in self.texture_views.data.write().map.drain() {
407+
match texture_view.inner {
408+
TextureViewInner::Native { raw, source_id } => {
409+
let device = &devices[textures[source_id.value].device_id.value];
410+
unsafe {
411+
device.raw.destroy_image_view(raw);
412+
}
413+
}
414+
TextureViewInner::SwapChain { .. } => {} //TODO
415+
}
416+
}
417+
}
418+
for (_, (texture, _)) in self.textures.data.write().map.drain() {
419+
unsafe {
420+
devices[texture.device_id.value].raw.destroy_image(texture.raw);
421+
}
422+
}
423+
for (_, (buffer, _)) in self.buffers.data.write().map.drain() {
424+
unsafe {
425+
devices[buffer.device_id.value].raw.destroy_buffer(buffer.raw);
426+
}
427+
}
428+
for (_, (command_buffer, _)) in self.command_buffers.data.write().map.drain() {
429+
devices[command_buffer.device_id.value].com_allocator.after_submit(command_buffer, 0);
430+
}
431+
for (_, (bind_group, _)) in self.bind_groups.data.write().map.drain() {
432+
let device = &devices[bind_group.device_id.value];
433+
device.destroy_bind_group(bind_group);
434+
}
435+
436+
//TODO:
437+
// self.compute_pipelines
438+
// self.compute_passes
439+
// self.render_pipelines
440+
// self.render_passes
441+
// self.bind_group_layouts
442+
// self.pipeline_layouts
443+
// self.shader_modules
444+
// self.swap_chains
445+
// self.adapters
446+
447+
for (_, (device, _)) in devices.map.drain() {
448+
device.destroy_self();
449+
}
450+
}
451+
}
452+
392453
#[derive(Debug, Default)]
393454
pub struct Hubs {
394455
#[cfg(any(
@@ -424,6 +485,16 @@ impl Global {
424485
pub fn new(name: &str) -> Self {
425486
Self::new_impl(name)
426487
}
488+
489+
#[cfg(not(feature = "local"))]
490+
pub fn delete(self) {
491+
let Global { mut instance, surfaces, hubs } = self;
492+
drop(hubs);
493+
// destroy surfaces
494+
for (_, (surface, _)) in surfaces.data.write().map.drain() {
495+
instance.destroy_surface(surface);
496+
}
497+
}
427498
}
428499

429500
#[cfg(feature = "local")]

wgpu-native/src/instance.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,31 @@ impl Instance {
5858
dx11: gfx_backend_dx11::Instance::create(name, version).unwrap(),
5959
}
6060
}
61+
62+
#[cfg(not(feature = "local"))]
63+
pub(crate) fn destroy_surface(&mut self, surface: Surface) {
64+
//TODO: fill out the proper destruction once we are on gfx-0.4
65+
#[cfg(any(
66+
not(any(target_os = "ios", target_os = "macos")),
67+
feature = "gfx-backend-vulkan"
68+
))]
69+
{
70+
if let Some(_suf) = surface.vulkan {
71+
//self.vulkan.as_mut().unwrap().destroy_surface(suf);
72+
}
73+
}
74+
#[cfg(any(target_os = "ios", target_os = "macos"))]
75+
{
76+
//self.metal.destroy_surface(surface.metal);
77+
}
78+
#[cfg(windows)]
79+
{
80+
if let Some(_suf) = surface.dx12 {
81+
//self.dx12.as_mut().unwrap().destroy_surface(suf);
82+
}
83+
//self.dx11.destroy_surface(surface.dx11);
84+
}
85+
}
6186
}
6287

6388
type GfxSurface<B> = <B as hal::Backend>::Surface;

wgpu-remote/cbindgen.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ include_version = true
1414
braces = "SameLine"
1515
line_length = 100
1616
tab_width = 2
17-
language = "C++"
17+
language = "C"
1818

1919
[export]
2020
prefix = "WGPU"

wgpu-remote/src/server.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ pub extern "C" fn wgpu_server_new() -> *mut wgn::Global {
1313
#[no_mangle]
1414
pub extern "C" fn wgpu_server_delete(global: *mut wgn::Global) {
1515
log::info!("Terminating WGPU server");
16-
//TODO: proper cleanup
17-
let _ = unsafe { Box::from_raw(global) };
16+
unsafe { Box::from_raw(global) }.delete();
17+
log::info!("\t...done");
1818
}
1919

2020
#[no_mangle]
@@ -38,3 +38,9 @@ pub extern "C" fn wgpu_server_adapter_request_device(
3838
use wgn::adapter_request_device as func;
3939
wgn::gfx_select!(self_id => func(global, self_id, desc, new_id));
4040
}
41+
42+
#[no_mangle]
43+
pub extern "C" fn wgpu_server_device_destroy(global: &wgn::Global, self_id: wgn::DeviceId) {
44+
use wgn::device_destroy as func;
45+
wgn::gfx_select!(self_id => func(global, self_id))
46+
}

0 commit comments

Comments
 (0)