| /* 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 https://mozilla.org/MPL/2.0/. */ |
| |
| pub mod error; |
| pub mod ids; |
| pub mod messages; |
| pub mod render_commands; |
| |
| use std::ops::Range; |
| |
| use ipc_channel::ipc::{IpcSender, IpcSharedMemory}; |
| use serde::{Deserialize, Serialize}; |
| use webrender_api::ImageFormat; |
| use wgpu_core::device::HostMap; |
| pub use wgpu_core::id::markers::{ |
| ComputePassEncoder as ComputePass, RenderPassEncoder as RenderPass, |
| }; |
| pub use wgpu_core::id::{ |
| ComputePassEncoderId as ComputePassId, RenderPassEncoderId as RenderPassId, |
| }; |
| use wgpu_core::id::{ComputePipelineId, DeviceId, QueueId, RenderPipelineId}; |
| use wgpu_core::instance::FailedLimit; |
| use wgpu_core::pipeline::CreateShaderModuleError; |
| use wgpu_types::{AdapterInfo, DeviceDescriptor, Features, Limits, TextureFormat}; |
| |
| pub use crate::error::*; |
| pub use crate::ids::*; |
| pub use crate::messages::*; |
| pub use crate::render_commands::*; |
| |
| pub const PRESENTATION_BUFFER_COUNT: usize = 10; |
| |
| pub type WebGPUAdapterResponse = Option<Result<Adapter, String>>; |
| pub type WebGPUComputePipelineResponse = Result<Pipeline<ComputePipelineId>, Error>; |
| pub type WebGPUPoppedErrorScopeResponse = Result<Option<Error>, PopError>; |
| pub type WebGPURenderPipelineResponse = Result<Pipeline<RenderPipelineId>, Error>; |
| |
| #[derive(Clone, Debug, Deserialize, Serialize)] |
| pub struct WebGPU(pub IpcSender<WebGPURequest>); |
| |
| impl WebGPU { |
| pub fn exit(&self, sender: IpcSender<()>) -> Result<(), &'static str> { |
| self.0 |
| .send(WebGPURequest::Exit(sender)) |
| .map_err(|_| "Failed to send Exit message") |
| } |
| } |
| |
| #[derive(Debug, Deserialize, Serialize)] |
| pub struct Adapter { |
| pub adapter_info: AdapterInfo, |
| pub adapter_id: WebGPUAdapter, |
| pub features: Features, |
| pub limits: Limits, |
| pub channel: WebGPU, |
| } |
| |
| #[derive(Clone, Copy, Debug, Deserialize, Serialize)] |
| pub struct ContextConfiguration { |
| pub device_id: DeviceId, |
| pub queue_id: QueueId, |
| pub format: TextureFormat, |
| pub is_opaque: bool, |
| } |
| |
| impl ContextConfiguration { |
| pub fn format(&self) -> ImageFormat { |
| match self.format { |
| TextureFormat::Rgba8Unorm => ImageFormat::RGBA8, |
| TextureFormat::Bgra8Unorm => ImageFormat::BGRA8, |
| // TODO: wgt::TextureFormat::Rgba16Float |
| _ => unreachable!("Unsupported canvas context format in configuration"), |
| } |
| } |
| } |
| |
| /// <https://gpuweb.github.io/gpuweb/#enumdef-gpudevicelostreason> |
| #[derive(Clone, Copy, Debug, Deserialize, Serialize)] |
| pub enum DeviceLostReason { |
| Unknown, |
| Destroyed, |
| } |
| |
| #[derive(Clone, Debug, Default, Deserialize, Serialize)] |
| pub struct ShaderCompilationInfo { |
| pub line_number: u64, |
| pub line_pos: u64, |
| pub offset: u64, |
| pub length: u64, |
| pub message: String, |
| } |
| |
| impl ShaderCompilationInfo { |
| pub fn from(error: &CreateShaderModuleError, source: &str) -> Self { |
| let location = match error { |
| CreateShaderModuleError::Parsing(e) => e.inner.location(source), |
| CreateShaderModuleError::Validation(e) => e.inner.location(source), |
| _ => None, |
| }; |
| |
| if let Some(location) = location { |
| // Naga reports locations in UTF-8 code units, but spec requires location in UTF-16 code units |
| // Based on https://searchfox.org/mozilla-central/rev/5b037d9c6ecdb0729f39ad519f0b867d80a92aad/gfx/wgpu_bindings/src/server.rs#353 |
| fn len_utf16(s: &str) -> u64 { |
| s.chars().map(|c| c.len_utf16() as u64).sum() |
| } |
| let start = location.offset as usize; |
| let end = start + location.length as usize; |
| let line_start = source[0..start].rfind('\n').map(|pos| pos + 1).unwrap_or(0); |
| Self { |
| line_number: location.line_number as u64, |
| line_pos: len_utf16(&source[line_start..start]) + 1, |
| offset: len_utf16(&source[0..start]), |
| length: len_utf16(&source[start..end]), |
| message: error.to_string(), |
| } |
| } else { |
| Self { |
| message: error.to_string(), |
| ..Default::default() |
| } |
| } |
| } |
| } |
| |
| #[derive(Debug, Deserialize, Serialize)] |
| pub struct Pipeline<T: std::fmt::Debug + Serialize> { |
| pub id: T, |
| pub label: String, |
| } |
| |
| #[derive(Debug, Deserialize, Serialize)] |
| pub struct Mapping { |
| pub data: IpcSharedMemory, |
| pub mode: HostMap, |
| pub range: Range<u64>, |
| } |
| |
| pub type WebGPUDeviceResponse = ( |
| WebGPUDevice, |
| WebGPUQueue, |
| Result<DeviceDescriptor<Option<String>>, RequestDeviceError>, |
| ); |
| |
| #[derive(Clone, Debug, Deserialize, Serialize)] |
| pub enum RequestDeviceError { |
| LimitsExceeded(FailedLimit), |
| UnsupportedFeature(Features), |
| Other(String), |
| } |
| |
| impl From<wgpu_core::instance::RequestDeviceError> for RequestDeviceError { |
| fn from(value: wgpu_core::instance::RequestDeviceError) -> Self { |
| match value { |
| wgpu_core::instance::RequestDeviceError::LimitsExceeded(failed_limit) => { |
| RequestDeviceError::LimitsExceeded(failed_limit) |
| }, |
| wgpu_core::instance::RequestDeviceError::UnsupportedFeature(features) => { |
| RequestDeviceError::UnsupportedFeature(features) |
| }, |
| e => RequestDeviceError::Other(e.to_string()), |
| } |
| } |
| } |