1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 use crate::error::ErrorBufferType;
8 pub use wgc::command::{compute_ffi::*, render_ffi::*};
15 pub use wgc::device::trace::Command as CommandEncoderAction;
17 use std::marker::PhantomData;
18 use std::{borrow::Cow, mem, slice};
20 use nsstring::nsACString;
22 type RawString = *const std::os::raw::c_char;
24 //TODO: figure out why 'a and 'b have to be different here
26 fn cow_label<'a, 'b>(raw: &'a RawString) -> Option<Cow<'b, str>> {
30 let cstr = unsafe { std::ffi::CStr::from_ptr(*raw) };
31 cstr.to_str().ok().map(Cow::Borrowed)
35 // Hides the repeated boilerplate of turning a `Option<&nsACString>` into a `Option<Cow<str>`.
36 pub fn wgpu_string(gecko_string: Option<&nsACString>) -> Option<Cow<str>> {
37 gecko_string.map(|s| s.to_utf8())
40 /// An equivalent of `&[T]` for ffi structures and function parameters.
42 pub struct FfiSlice<'a, T> {
43 // `data` may be null.
46 pub _marker: PhantomData<&'a T>,
49 impl<'a, T> FfiSlice<'a, T> {
50 pub unsafe fn as_slice(&self) -> &'a [T] {
51 if self.data.is_null() {
52 // It is invalid to construct a rust slice with a null pointer.
56 std::slice::from_raw_parts(self.data, self.length)
60 impl<'a, T> Copy for FfiSlice<'a, T> {}
61 impl<'a, T> Clone for FfiSlice<'a, T> {
62 fn clone(&self) -> Self {
75 fn from_vec(vec: Vec<u8>) -> Self {
78 data: std::ptr::null(),
86 capacity: vec.capacity(),
93 unsafe fn as_slice(&self) -> &[u8] {
94 slice::from_raw_parts(self.data, self.len)
99 #[derive(serde::Serialize, serde::Deserialize)]
100 pub struct AdapterInformation<S> {
103 features: wgt::Features,
107 device_type: wgt::DeviceType,
110 backend: wgt::Backend,
113 #[derive(serde::Serialize, serde::Deserialize)]
114 struct ImplicitLayout<'a> {
115 pipeline: id::PipelineLayoutId,
116 bind_groups: Cow<'a, [id::BindGroupLayoutId]>,
119 #[derive(serde::Serialize, serde::Deserialize)]
120 enum DeviceAction<'a> {
123 wgc::resource::TextureDescriptor<'a>,
126 CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
127 CreateBindGroupLayout(
128 id::BindGroupLayoutId,
129 wgc::binding_model::BindGroupLayoutDescriptor<'a>,
131 RenderPipelineGetBindGroupLayout(id::RenderPipelineId, u32, id::BindGroupLayoutId),
132 ComputePipelineGetBindGroupLayout(id::ComputePipelineId, u32, id::BindGroupLayoutId),
133 CreatePipelineLayout(
134 id::PipelineLayoutId,
135 wgc::binding_model::PipelineLayoutDescriptor<'a>,
137 CreateBindGroup(id::BindGroupId, wgc::binding_model::BindGroupDescriptor<'a>),
140 wgc::pipeline::ShaderModuleDescriptor<'a>,
143 CreateComputePipeline(
144 id::ComputePipelineId,
145 wgc::pipeline::ComputePipelineDescriptor<'a>,
146 Option<ImplicitLayout<'a>>,
148 CreateRenderPipeline(
149 id::RenderPipelineId,
150 wgc::pipeline::RenderPipelineDescriptor<'a>,
151 Option<ImplicitLayout<'a>>,
155 wgc::command::RenderBundleEncoder,
156 wgc::command::RenderBundleDescriptor<'a>,
158 CreateRenderBundleError(id::RenderBundleId, wgc::Label<'a>),
159 CreateCommandEncoder(
160 id::CommandEncoderId,
161 wgt::CommandEncoderDescriptor<wgc::Label<'a>>,
165 r#type: ErrorBufferType,
169 #[derive(serde::Serialize, serde::Deserialize)]
170 enum QueueWriteAction {
173 offset: wgt::BufferAddress,
176 dst: wgt::ImageCopyTexture<id::TextureId>,
177 layout: wgt::ImageDataLayout,
182 #[derive(serde::Serialize, serde::Deserialize)]
183 enum TextureAction<'a> {
184 CreateView(id::TextureViewId, wgc::resource::TextureViewDescriptor<'a>),
188 #[derive(serde::Serialize, serde::Deserialize)]
190 Adapter(id::AdapterId),
191 Device(id::DeviceId),
192 ShaderModule(id::ShaderModuleId),
193 PipelineLayout(id::PipelineLayoutId),
194 BindGroupLayout(id::BindGroupLayoutId),
195 BindGroup(id::BindGroupId),
196 CommandBuffer(id::CommandBufferId),
197 RenderBundle(id::RenderBundleId),
198 RenderPipeline(id::RenderPipelineId),
199 ComputePipeline(id::ComputePipelineId),
200 Buffer(id::BufferId),
201 Texture(id::TextureId),
202 TextureView(id::TextureViewId),
203 Sampler(id::SamplerId),
207 // helper function to construct byte bufs
208 fn to_byte_buf(&self) -> ByteBuf {
209 let mut data = Vec::new();
210 bincode::serialize_into(&mut data, self).unwrap();
211 ByteBuf::from_vec(data)
216 pub struct ImageDataLayout<'a> {
217 pub offset: wgt::BufferAddress,
218 pub bytes_per_row: Option<&'a u32>,
219 pub rows_per_image: Option<&'a u32>,
222 impl<'a> ImageDataLayout<'a> {
223 fn into_wgt(&self) -> wgt::ImageDataLayout {
224 wgt::ImageDataLayout {
226 bytes_per_row: self.bytes_per_row.map(|bpr| *bpr),
227 rows_per_image: self.rows_per_image.map(|rpi| *rpi),
233 #[derive(Copy, Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
234 pub struct SwapChainId(pub u64);