Implement shutdown for the remote server

This commit is contained in:
Dzmitry Malyshau 2019-10-25 22:12:07 -04:00
parent e37149b3a8
commit 538c23b039
10 changed files with 205 additions and 61 deletions

View File

@ -1,17 +1,28 @@
#define WGPU_INLINE
#define WGPU_FUNC
#include "./../../ffi/wgpu-remote.h"
#include <stdio.h>
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;
}

View File

@ -14,64 +14,69 @@
typedef void WGPUEmpty;
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
enum class WGPUPowerPreference {
typedef enum {
WGPUPowerPreference_Default = 0,
WGPUPowerPreference_LowPower = 1,
WGPUPowerPreference_HighPerformance = 2,
};
} WGPUPowerPreference;
template<typename B>
struct WGPUAdapter;
typedef struct WGPUClient WGPUClient;
struct WGPUClient;
typedef struct WGPUGlobal WGPUGlobal;
template<typename B>
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<typename T>
using WGPUId = uint64_t;
typedef WGPUId_Device_Dummy WGPUDeviceId;
using WGPUAdapterId = WGPUId<WGPUAdapter<WGPUDummy>>;
using WGPUDeviceId = WGPUId<WGPUDevice<WGPUDummy>>;
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;

View File

@ -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"

View File

@ -60,16 +60,6 @@ pub struct CommandAllocator<B: hal::Backend> {
}
impl<B: GfxBackend> CommandAllocator<B> {
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<DeviceId>,
@ -103,6 +93,18 @@ impl<B: GfxBackend> CommandAllocator<B> {
features,
}
}
}
impl<B: hal::Backend> CommandAllocator<B> {
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>) -> B::CommandBuffer {
let mut inner = self.inner.lock();

View File

@ -112,7 +112,7 @@ pub struct CommandBuffer<B: hal::Backend> {
pub(crate) raw: Vec<B::CommandBuffer>,
is_recording: bool,
recorded_thread_id: ThreadId,
device_id: Stored<DeviceId>,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) life_guard: LifeGuard,
pub(crate) trackers: TrackerSet,
pub(crate) used_swap_chain: Option<(Stored<TextureViewId>, B::Framebuffer)>,

View File

@ -768,6 +768,21 @@ impl<B: GfxBackend> Device<B> {
}
}
impl<B: hal::Backend> Device<B> {
pub(crate) fn destroy_bind_group(&self, bind_group: binding_model::BindGroup<B>) {
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) {

View File

@ -389,6 +389,67 @@ impl<B: GfxBackend> Default for Hub<B> {
}
}
impl<B: hal::Backend> Drop for Hub<B> {
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")]

View File

@ -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<B> = <B as hal::Backend>::Surface;

View File

@ -14,7 +14,7 @@ include_version = true
braces = "SameLine"
line_length = 100
tab_width = 2
language = "C++"
language = "C"
[export]
prefix = "WGPU"

View File

@ -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))
}