1pub mod encoders;
6pub mod error;
7pub mod ids;
8pub mod messages;
9
10use std::ops::Range;
11
12use malloc_size_of_derive::MallocSizeOf;
13use serde::{Deserialize, Serialize};
14use servo_base::generic_channel::{GenericOneshotSender, GenericSender, GenericSharedMemory};
15use webrender_api::euclid::default::Size2D;
16use webrender_api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat};
17pub mod markers {
18 pub use wgpu_core::id::markers::{
19 Adapter, BindGroup, BindGroupLayout, Buffer, CommandBuffer, CommandEncoder,
20 ComputePassEncoder, ComputePipeline, Device, ExternalTexture, PipelineLayout, QuerySet,
21 Queue, RenderBundle, RenderBundleEncoder, RenderPassEncoder, RenderPipeline, Sampler,
22 ShaderModule, Texture, TextureView,
23 };
24}
25pub mod id {
26 pub use wgpu_core::id::{
27 AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandBufferId, CommandEncoderId,
28 ComputePassEncoderId, ComputePipelineId, DeviceId, ExternalTextureId, PipelineLayoutId,
29 QuerySetId, QueueId, RenderBundleEncoderId, RenderBundleId, RenderPassEncoderId,
30 RenderPipelineId, SamplerId, ShaderModuleId, TextureId, TextureViewId,
31 };
32}
33pub use wgpu_core::Label;
34pub use wgpu_core::binding_model::{
35 BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindingResource, BufferBinding,
36 PipelineLayoutDescriptor,
37};
38pub use wgpu_core::command::{
39 ComputePassDescriptor, LoadOp, PassChannel, PassTimestampWrites, RenderBundleDescriptor,
40 RenderBundleEncoderDescriptor, RenderPassColorAttachment, RenderPassDepthStencilAttachment,
41 RenderPassDescriptor, StoreOp, TexelCopyBufferInfo, TexelCopyTextureInfo,
42};
43pub use wgpu_core::device::HostMap;
44use wgpu_core::id::{ComputePipelineId, DeviceId, QueueId, RenderPipelineId};
45pub use wgpu_core::identity::IdentityManager;
46pub use wgpu_core::instance::RequestAdapterOptions;
47use wgpu_core::limits::FailedLimit;
48pub use wgpu_core::naga::front::wgsl::ImplementedLanguageExtension;
49use wgpu_core::pipeline::CreateShaderModuleError;
50pub use wgpu_core::pipeline::{
51 ComputePipelineDescriptor, FragmentState, ProgrammableStageDescriptor,
52 RenderPipelineDescriptor, ShaderModuleDescriptor, VertexBufferLayout, VertexState,
53};
54pub use wgpu_core::resource::{
55 BufferAccessError, BufferDescriptor, QuerySetDescriptor, SamplerDescriptor, TextureDescriptor,
56 TextureViewDescriptor,
57};
58use wgpu_types::COPY_BYTES_PER_ROW_ALIGNMENT;
59pub use wgpu_types::{
60 AdapterInfo, AddressMode, AstcBlock, AstcChannel, BindGroupLayoutEntry, BindingType,
61 BlendComponent, BlendFactor, BlendOperation, BlendState, BufferAddress, BufferBindingType,
62 BufferSize, BufferUsages, COPY_BUFFER_ALIGNMENT, Color, ColorTargetState, ColorWrites,
63 CommandBufferDescriptor, CommandEncoderDescriptor, CompareFunction, DepthBiasState,
64 DepthStencilState, DeviceDescriptor, DeviceType, ExperimentalFeatures, Extent3d, Face,
65 Features, FilterMode, FrontFace, ImageSubresourceRange, IndexFormat, Limits, MAP_ALIGNMENT,
66 MemoryHints, MipmapFilterMode, MultisampleState, Origin2d, Origin3d, PowerPreference,
67 PredefinedColorSpace, PrimitiveState, PrimitiveTopology, QueryType, RenderBundleDepthStencil,
68 SamplerBindingType, ShaderStages, StencilFaceState, StencilOperation, StencilState,
69 StorageTextureAccess, TexelCopyBufferLayout, TextureAspect, TextureDimension, TextureFormat,
70 TextureSampleType, TextureUsages, TextureViewDimension, Trace, VertexAttribute, VertexFormat,
71 VertexStepMode,
72};
73
74pub use crate::encoders::*;
75pub use crate::error::*;
76pub use crate::ids::*;
77pub use crate::messages::*;
78
79pub const PRESENTATION_BUFFER_COUNT: usize = 10;
80
81pub type WebGPUAdapterResponse = Option<Result<Adapter, String>>;
82pub type WebGPUComputePipelineResponse = Result<Pipeline<ComputePipelineId>, Error>;
83pub type WebGPUPoppedErrorScopeResponse = Result<Option<Error>, PopError>;
84pub type WebGPURenderPipelineResponse = Result<Pipeline<RenderPipelineId>, Error>;
85
86#[derive(Clone, Debug, Deserialize, Serialize, MallocSizeOf)]
87pub struct WebGPU(pub GenericSender<WebGPURequest>);
88
89impl WebGPU {
90 pub fn exit(&self, sender: GenericOneshotSender<()>) -> Result<(), &'static str> {
91 self.0
92 .send(WebGPURequest::Exit(sender))
93 .map_err(|_| "Failed to send Exit message")
94 }
95}
96
97#[derive(Debug, Deserialize, Serialize)]
98pub struct Adapter {
99 pub adapter_info: AdapterInfo,
100 pub adapter_id: WebGPUAdapter,
101 pub features: Features,
102 pub limits: Limits,
103 pub channel: WebGPU,
104}
105
106#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
107pub struct ContextConfiguration {
108 pub device_id: DeviceId,
109 pub queue_id: QueueId,
110 pub format: ImageFormat,
111 pub is_opaque: bool,
112 pub size: Size2D<u32>,
113}
114
115impl ContextConfiguration {
116 pub fn stride(&self) -> u32 {
117 (self.size.width * self.format.bytes_per_pixel() as u32)
118 .next_multiple_of(COPY_BYTES_PER_ROW_ALIGNMENT)
119 }
120
121 pub fn buffer_size(&self) -> u64 {
122 self.stride() as u64 * self.size.height as u64
123 }
124}
125
126impl From<ContextConfiguration> for ImageDescriptor {
127 fn from(config: ContextConfiguration) -> Self {
128 ImageDescriptor {
129 format: config.format,
130 size: config.size.cast().cast_unit(),
131 stride: Some(config.stride() as i32),
132 offset: 0,
133 flags: if config.is_opaque {
134 ImageDescriptorFlags::IS_OPAQUE
135 } else {
136 ImageDescriptorFlags::empty()
137 },
138 }
139 }
140}
141
142#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
144pub enum DeviceLostReason {
145 Unknown,
146 Destroyed,
147}
148
149#[derive(Clone, Debug, Default, Deserialize, Serialize)]
150pub struct ShaderCompilationInfo {
151 pub line_number: u64,
152 pub line_pos: u64,
153 pub offset: u64,
154 pub length: u64,
155 pub message: String,
156}
157
158impl ShaderCompilationInfo {
159 pub fn from(error: &CreateShaderModuleError, source: &str) -> Self {
160 let location = match error {
161 CreateShaderModuleError::Parsing(e) => e.inner.location(source),
162 CreateShaderModuleError::Validation(e) => e.inner.location(source),
163 _ => None,
164 };
165
166 if let Some(location) = location {
167 fn len_utf16(s: &str) -> u64 {
170 s.chars().map(|c| c.len_utf16() as u64).sum()
171 }
172 let start = location.offset as usize;
173 let end = start + location.length as usize;
174 let line_start = source[0..start].rfind('\n').map(|pos| pos + 1).unwrap_or(0);
175 Self {
176 line_number: location.line_number as u64,
177 line_pos: len_utf16(&source[line_start..start]) + 1,
178 offset: len_utf16(&source[0..start]),
179 length: len_utf16(&source[start..end]),
180 message: error.to_string(),
181 }
182 } else {
183 Self {
184 message: error.to_string(),
185 ..Default::default()
186 }
187 }
188 }
189}
190
191#[derive(Debug, Deserialize, Serialize)]
192pub struct Pipeline<T: std::fmt::Debug + Serialize> {
193 pub id: T,
194 pub label: String,
195}
196
197#[derive(Debug, Deserialize, Serialize)]
198pub struct Mapping {
199 pub data: GenericSharedMemory,
200 pub mode: HostMap,
201 pub range: Range<u64>,
202}
203
204pub type WebGPUDeviceResponse = (
205 WebGPUDevice,
206 WebGPUQueue,
207 Result<DeviceDescriptor<Option<String>>, RequestDeviceError>,
208);
209
210#[derive(Clone, Debug, Deserialize, Serialize)]
211pub enum RequestDeviceError {
212 LimitsExceeded(FailedLimit),
213 UnsupportedFeature(Features),
214 Other(String),
215}
216
217impl From<wgpu_core::instance::RequestDeviceError> for RequestDeviceError {
218 fn from(value: wgpu_core::instance::RequestDeviceError) -> Self {
219 match value {
220 wgpu_core::instance::RequestDeviceError::LimitsExceeded(failed_limit) => {
221 RequestDeviceError::LimitsExceeded(failed_limit)
222 },
223 wgpu_core::instance::RequestDeviceError::UnsupportedFeature(features) => {
224 RequestDeviceError::UnsupportedFeature(features)
225 },
226 e => RequestDeviceError::Other(e.to_string()),
227 }
228 }
229}