mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Implement shutdown for the remote server
This commit is contained in:
parent
e37149b3a8
commit
538c23b039
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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)>,
|
||||
|
@ -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) {
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -14,7 +14,7 @@ include_version = true
|
||||
braces = "SameLine"
|
||||
line_length = 100
|
||||
tab_width = 2
|
||||
language = "C++"
|
||||
language = "C"
|
||||
|
||||
[export]
|
||||
prefix = "WGPU"
|
||||
|
@ -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))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user