232 lines
6.2 KiB
Rust
232 lines
6.2 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::error::ErrorBufferType;
|
|
use wgc::id;
|
|
|
|
pub mod client;
|
|
pub mod command;
|
|
pub mod error;
|
|
pub mod server;
|
|
|
|
pub use wgc::device::trace::Command as CommandEncoderAction;
|
|
|
|
use std::marker::PhantomData;
|
|
use std::{borrow::Cow, mem, slice};
|
|
|
|
use nsstring::nsACString;
|
|
|
|
type RawString = *const std::os::raw::c_char;
|
|
|
|
fn cow_label(raw: &RawString) -> Option<Cow<'_, str>> {
|
|
if raw.is_null() {
|
|
None
|
|
} else {
|
|
let cstr = unsafe { std::ffi::CStr::from_ptr(*raw) };
|
|
cstr.to_str().ok().map(Cow::Borrowed)
|
|
}
|
|
}
|
|
|
|
// Hides the repeated boilerplate of turning a `Option<&nsACString>` into a `Option<Cow<str>`.
|
|
pub fn wgpu_string(gecko_string: Option<&nsACString>) -> Option<Cow<'_, str>> {
|
|
gecko_string.map(|s| s.to_utf8())
|
|
}
|
|
|
|
/// An equivalent of `&[T]` for ffi structures and function parameters.
|
|
#[repr(C)]
|
|
pub struct FfiSlice<'a, T> {
|
|
// `data` may be null.
|
|
pub data: *const T,
|
|
pub length: usize,
|
|
pub _marker: PhantomData<&'a T>,
|
|
}
|
|
|
|
impl<'a, T> FfiSlice<'a, T> {
|
|
pub unsafe fn as_slice(&self) -> &'a [T] {
|
|
if self.data.is_null() {
|
|
// It is invalid to construct a rust slice with a null pointer.
|
|
return &[];
|
|
}
|
|
|
|
std::slice::from_raw_parts(self.data, self.length)
|
|
}
|
|
}
|
|
|
|
impl<'a, T> Copy for FfiSlice<'a, T> {}
|
|
impl<'a, T> Clone for FfiSlice<'a, T> {
|
|
fn clone(&self) -> Self {
|
|
*self
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct ByteBuf {
|
|
data: *const u8,
|
|
len: usize,
|
|
capacity: usize,
|
|
}
|
|
|
|
impl ByteBuf {
|
|
fn from_vec(vec: Vec<u8>) -> Self {
|
|
if vec.is_empty() {
|
|
ByteBuf {
|
|
data: std::ptr::null(),
|
|
len: 0,
|
|
capacity: 0,
|
|
}
|
|
} else {
|
|
let bb = ByteBuf {
|
|
data: vec.as_ptr(),
|
|
len: vec.len(),
|
|
capacity: vec.capacity(),
|
|
};
|
|
mem::forget(vec);
|
|
bb
|
|
}
|
|
}
|
|
|
|
unsafe fn as_slice(&self) -> &[u8] {
|
|
slice::from_raw_parts(self.data, self.len)
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
pub struct AdapterInformation<S> {
|
|
id: id::AdapterId,
|
|
limits: wgt::Limits,
|
|
features: wgt::FeaturesWebGPU,
|
|
name: S,
|
|
vendor: u32,
|
|
device: u32,
|
|
device_type: wgt::DeviceType,
|
|
driver: S,
|
|
driver_info: S,
|
|
backend: wgt::Backend,
|
|
support_use_external_texture_in_swap_chain: bool,
|
|
}
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
struct ImplicitLayout<'a> {
|
|
pipeline: id::PipelineLayoutId,
|
|
bind_groups: Cow<'a, [id::BindGroupLayoutId]>,
|
|
}
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
enum DeviceAction<'a> {
|
|
CreateTexture(
|
|
id::TextureId,
|
|
wgc::resource::TextureDescriptor<'a>,
|
|
Option<SwapChainId>,
|
|
),
|
|
CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
|
|
CreateBindGroupLayout(
|
|
id::BindGroupLayoutId,
|
|
wgc::binding_model::BindGroupLayoutDescriptor<'a>,
|
|
),
|
|
RenderPipelineGetBindGroupLayout(id::RenderPipelineId, u32, id::BindGroupLayoutId),
|
|
ComputePipelineGetBindGroupLayout(id::ComputePipelineId, u32, id::BindGroupLayoutId),
|
|
CreatePipelineLayout(
|
|
id::PipelineLayoutId,
|
|
wgc::binding_model::PipelineLayoutDescriptor<'a>,
|
|
),
|
|
CreateBindGroup(id::BindGroupId, wgc::binding_model::BindGroupDescriptor<'a>),
|
|
CreateShaderModule(
|
|
id::ShaderModuleId,
|
|
wgc::pipeline::ShaderModuleDescriptor<'a>,
|
|
Cow<'a, str>,
|
|
),
|
|
CreateComputePipeline(
|
|
id::ComputePipelineId,
|
|
wgc::pipeline::ComputePipelineDescriptor<'a>,
|
|
Option<ImplicitLayout<'a>>,
|
|
),
|
|
CreateRenderPipeline(
|
|
id::RenderPipelineId,
|
|
wgc::pipeline::RenderPipelineDescriptor<'a>,
|
|
Option<ImplicitLayout<'a>>,
|
|
),
|
|
CreateRenderBundle(
|
|
id::RenderBundleId,
|
|
wgc::command::RenderBundleEncoder,
|
|
wgc::command::RenderBundleDescriptor<'a>,
|
|
),
|
|
CreateRenderBundleError(id::RenderBundleId, wgc::Label<'a>),
|
|
CreateQuerySet(id::QuerySetId, wgc::resource::QuerySetDescriptor<'a>),
|
|
CreateCommandEncoder(
|
|
id::CommandEncoderId,
|
|
wgt::CommandEncoderDescriptor<wgc::Label<'a>>,
|
|
),
|
|
Error {
|
|
message: String,
|
|
r#type: ErrorBufferType,
|
|
},
|
|
}
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
enum QueueWriteAction {
|
|
Buffer {
|
|
dst: id::BufferId,
|
|
offset: wgt::BufferAddress,
|
|
},
|
|
Texture {
|
|
dst: wgt::TexelCopyTextureInfo<id::TextureId>,
|
|
layout: wgt::TexelCopyBufferLayout,
|
|
size: wgt::Extent3d,
|
|
},
|
|
}
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
enum TextureAction<'a> {
|
|
CreateView(id::TextureViewId, wgc::resource::TextureViewDescriptor<'a>),
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
enum DropAction {
|
|
Adapter(id::AdapterId),
|
|
Device(id::DeviceId),
|
|
ShaderModule(id::ShaderModuleId),
|
|
PipelineLayout(id::PipelineLayoutId),
|
|
BindGroupLayout(id::BindGroupLayoutId),
|
|
BindGroup(id::BindGroupId),
|
|
CommandBuffer(id::CommandBufferId),
|
|
RenderBundle(id::RenderBundleId),
|
|
RenderPipeline(id::RenderPipelineId),
|
|
ComputePipeline(id::ComputePipelineId),
|
|
Buffer(id::BufferId),
|
|
Texture(id::TextureId),
|
|
TextureView(id::TextureViewId),
|
|
Sampler(id::SamplerId),
|
|
}
|
|
|
|
impl DropAction {
|
|
// helper function to construct byte bufs
|
|
fn to_byte_buf(&self) -> ByteBuf {
|
|
let mut data = Vec::new();
|
|
bincode::serialize_into(&mut data, self).unwrap();
|
|
ByteBuf::from_vec(data)
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct TexelCopyBufferLayout<'a> {
|
|
pub offset: wgt::BufferAddress,
|
|
pub bytes_per_row: Option<&'a u32>,
|
|
pub rows_per_image: Option<&'a u32>,
|
|
}
|
|
|
|
impl<'a> TexelCopyBufferLayout<'a> {
|
|
fn into_wgt(&self) -> wgt::TexelCopyBufferLayout {
|
|
wgt::TexelCopyBufferLayout {
|
|
offset: self.offset,
|
|
bytes_per_row: self.bytes_per_row.map(|bpr| *bpr),
|
|
rows_per_image: self.rows_per_image.map(|rpi| *rpi),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
pub struct SwapChainId(pub u64);
|