Files
wgpu/wgpu-remote/src/server.rs
2020-04-13 11:44:10 -04:00

417 lines
12 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::identity::IdentityRecyclerFactory;
use core::{gfx_select, id};
use std::slice;
pub type Global = core::hub::Global<IdentityRecyclerFactory>;
#[no_mangle]
pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Global {
log::info!("Initializing WGPU server");
Box::into_raw(Box::new(Global::new("wgpu", factory)))
}
/// # Safety
///
/// This function is unsafe because improper use may lead to memory
/// problems. For example, a double-free may occur if the function is called
/// twice on the same raw pointer.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_delete(global: *mut Global) {
log::info!("Terminating WGPU server");
Box::from_raw(global).delete();
log::info!("\t...done");
}
#[no_mangle]
pub extern "C" fn wgpu_server_poll_all_devices(global: &Global, force_wait: bool) {
global.poll_all_devices(force_wait);
}
/// Request an adapter according to the specified options.
/// Provide the list of IDs to pick from.
///
/// Returns the index in this list, or -1 if unable to pick.
///
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `id_length` elements.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
global: &Global,
desc: &core::instance::RequestAdapterOptions,
ids: *const id::AdapterId,
id_length: usize,
) -> i8 {
let ids = slice::from_raw_parts(ids, id_length);
match global.pick_adapter(
desc,
core::instance::AdapterInputs::IdSet(ids, |i| i.backend()),
) {
Some(id) => ids.iter().position(|&i| i == id).unwrap() as i8,
None => -1,
}
}
#[no_mangle]
pub extern "C" fn wgpu_server_adapter_request_device(
global: &Global,
self_id: id::AdapterId,
desc: &wgt::DeviceDescriptor,
new_id: id::DeviceId,
) {
gfx_select!(self_id => global.adapter_request_device(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_adapter_destroy(global: &Global, adapter_id: id::AdapterId) {
gfx_select!(adapter_id => global.adapter_destroy(adapter_id))
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_destroy(global: &Global, self_id: id::DeviceId) {
gfx_select!(self_id => global.device_destroy(self_id))
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_buffer(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::BufferDescriptor,
new_id: id::BufferId,
) {
gfx_select!(self_id => global.device_create_buffer(self_id, desc, new_id));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `size` elements.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_device_set_buffer_sub_data(
global: &Global,
self_id: id::DeviceId,
buffer_id: id::BufferId,
offset: wgt::BufferAddress,
data: *const u8,
size: wgt::BufferAddress,
) {
let slice = slice::from_raw_parts(data, size as usize);
gfx_select!(self_id => global.device_set_buffer_sub_data(self_id, buffer_id, offset, slice));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `size` elements.
#[no_mangle]
pub extern "C" fn wgpu_server_buffer_map_read(
global: &Global,
buffer_id: id::BufferId,
start: wgt::BufferAddress,
size: wgt::BufferAddress,
callback: core::device::BufferMapReadCallback,
userdata: *mut u8,
) {
let operation = core::resource::BufferMapOperation::Read { callback, userdata };
gfx_select!(buffer_id => global.buffer_map_async(
buffer_id,
wgt::BufferUsage::MAP_READ,
start .. start + size,
operation
));
}
#[no_mangle]
pub extern "C" fn wgpu_server_buffer_unmap(global: &Global, buffer_id: id::BufferId) {
gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_buffer_destroy(global: &Global, self_id: id::BufferId) {
gfx_select!(self_id => global.buffer_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_encoder(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::CommandEncoderDescriptor,
new_id: id::CommandEncoderId,
) {
gfx_select!(self_id => global.device_create_command_encoder(self_id, &desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_encoder_finish(
global: &Global,
self_id: id::CommandEncoderId,
desc: &wgt::CommandBufferDescriptor,
) {
gfx_select!(self_id => global.command_encoder_finish(self_id, desc));
}
#[no_mangle]
pub extern "C" fn wgpu_server_encoder_destroy(global: &Global, self_id: id::CommandEncoderId) {
gfx_select!(self_id => global.command_encoder_destroy(self_id));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `byte_length` elements.
#[no_mangle]
pub extern "C" fn wgpu_server_command_buffer_destroy(
global: &Global,
self_id: id::CommandBufferId,
) {
gfx_select!(self_id => global.command_buffer_destroy(self_id));
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encoder_copy_buffer_to_buffer(
global: &Global,
self_id: id::CommandEncoderId,
source_id: id::BufferId,
source_offset: wgt::BufferAddress,
destination_id: id::BufferId,
destination_offset: wgt::BufferAddress,
size: wgt::BufferAddress,
) {
gfx_select!(self_id => global.command_encoder_copy_buffer_to_buffer(self_id, source_id, source_offset, destination_id, destination_offset, size));
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encoder_copy_texture_to_buffer(
global: &Global,
self_id: id::CommandEncoderId,
source: &core::command::TextureCopyView,
destination: &core::command::BufferCopyView,
size: wgt::Extent3d,
) {
gfx_select!(self_id => global.command_encoder_copy_texture_to_buffer(self_id, source, destination, size));
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encoder_copy_buffer_to_texture(
global: &Global,
self_id: id::CommandEncoderId,
source: &core::command::BufferCopyView,
destination: &core::command::TextureCopyView,
size: wgt::Extent3d,
) {
gfx_select!(self_id => global.command_encoder_copy_buffer_to_texture(self_id, source, destination, size));
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encoder_copy_texture_to_texture(
global: &Global,
self_id: id::CommandEncoderId,
source: &core::command::TextureCopyView,
destination: &core::command::TextureCopyView,
size: wgt::Extent3d,
) {
gfx_select!(self_id => global.command_encoder_copy_texture_to_texture(self_id, source, destination, size));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointers are
/// valid for `color_attachments_length` and `command_length` elements,
/// respectively.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encode_compute_pass(
global: &Global,
self_id: id::CommandEncoderId,
bytes: *const u8,
byte_length: usize,
) {
let raw_data = slice::from_raw_parts(bytes, byte_length);
gfx_select!(self_id => global.command_encoder_run_compute_pass(self_id, raw_data));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointers are
/// valid for `color_attachments_length` and `command_length` elements,
/// respectively.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_encode_render_pass(
global: &Global,
self_id: id::CommandEncoderId,
commands: *const u8,
command_length: usize,
) {
let raw_pass = slice::from_raw_parts(commands, command_length);
gfx_select!(self_id => global.command_encoder_run_render_pass(self_id, raw_pass));
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `command_buffer_id_length` elements.
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_queue_submit(
global: &Global,
self_id: id::QueueId,
command_buffer_ids: *const id::CommandBufferId,
command_buffer_id_length: usize,
) {
let command_buffers = slice::from_raw_parts(command_buffer_ids, command_buffer_id_length);
gfx_select!(self_id => global.queue_submit(self_id, command_buffers));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_bind_group_layout(
global: &Global,
self_id: id::DeviceId,
desc: &core::binding_model::BindGroupLayoutDescriptor,
new_id: id::BindGroupLayoutId,
) {
gfx_select!(self_id => global.device_create_bind_group_layout(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_bind_group_layout_destroy(
global: &Global,
self_id: id::BindGroupLayoutId,
) {
gfx_select!(self_id => global.bind_group_layout_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_pipeline_layout(
global: &Global,
self_id: id::DeviceId,
desc: &core::binding_model::PipelineLayoutDescriptor,
new_id: id::PipelineLayoutId,
) {
gfx_select!(self_id => global.device_create_pipeline_layout(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_pipeline_layout_destroy(
global: &Global,
self_id: id::PipelineLayoutId,
) {
gfx_select!(self_id => global.pipeline_layout_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_bind_group(
global: &Global,
self_id: id::DeviceId,
desc: &core::binding_model::BindGroupDescriptor,
new_id: id::BindGroupId,
) {
gfx_select!(self_id => global.device_create_bind_group(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_bind_group_destroy(global: &Global, self_id: id::BindGroupId) {
gfx_select!(self_id => global.bind_group_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_shader_module(
global: &Global,
self_id: id::DeviceId,
desc: &core::pipeline::ShaderModuleDescriptor,
new_id: id::ShaderModuleId,
) {
gfx_select!(self_id => global.device_create_shader_module(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_shader_module_destroy(global: &Global, self_id: id::ShaderModuleId) {
gfx_select!(self_id => global.shader_module_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_compute_pipeline(
global: &Global,
self_id: id::DeviceId,
desc: &core::pipeline::ComputePipelineDescriptor,
new_id: id::ComputePipelineId,
) {
gfx_select!(self_id => global.device_create_compute_pipeline(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_compute_pipeline_destroy(
global: &Global,
self_id: id::ComputePipelineId,
) {
gfx_select!(self_id => global.compute_pipeline_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_render_pipeline(
global: &Global,
self_id: id::DeviceId,
desc: &core::pipeline::RenderPipelineDescriptor,
new_id: id::RenderPipelineId,
) {
gfx_select!(self_id => global.device_create_render_pipeline(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_render_pipeline_destroy(
global: &Global,
self_id: id::RenderPipelineId,
) {
gfx_select!(self_id => global.render_pipeline_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_texture(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::TextureDescriptor,
new_id: id::TextureId,
) {
gfx_select!(self_id => global.device_create_texture(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_texture_create_view(
global: &Global,
self_id: id::TextureId,
desc: Option<&wgt::TextureViewDescriptor>,
new_id: id::TextureViewId,
) {
gfx_select!(self_id => global.texture_create_view(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_texture_destroy(global: &Global, self_id: id::TextureId) {
gfx_select!(self_id => global.texture_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_texture_view_destroy(global: &Global, self_id: id::TextureViewId) {
gfx_select!(self_id => global.texture_view_destroy(self_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_device_create_sampler(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::SamplerDescriptor,
new_id: id::SamplerId,
) {
gfx_select!(self_id => global.device_create_sampler(self_id, desc, new_id));
}
#[no_mangle]
pub extern "C" fn wgpu_server_sampler_destroy(global: &Global, self_id: id::SamplerId) {
gfx_select!(self_id => global.sampler_destroy(self_id));
}