aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webgpu/gpuconvert.rs
diff options
context:
space:
mode:
authoratbrakhi <atbrakhi@igalia.com>2024-11-28 15:24:15 +0100
committerGitHub <noreply@github.com>2024-11-28 14:24:15 +0000
commitd2d3407501b83d03db522b5dde5e159073fd9e4b (patch)
tree299be7d04ca2470f1c6c8741e46784a2c7e85dd7 /components/script/dom/webgpu/gpuconvert.rs
parenta37ccc3e64c92e8ba10a3cdc48ebd7f031bb7298 (diff)
downloadservo-d2d3407501b83d03db522b5dde5e159073fd9e4b.tar.gz
servo-d2d3407501b83d03db522b5dde5e159073fd9e4b.zip
Move script gpu files into webgpu folder (#34415)
Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Diffstat (limited to 'components/script/dom/webgpu/gpuconvert.rs')
-rw-r--r--components/script/dom/webgpu/gpuconvert.rs680
1 files changed, 680 insertions, 0 deletions
diff --git a/components/script/dom/webgpu/gpuconvert.rs b/components/script/dom/webgpu/gpuconvert.rs
new file mode 100644
index 00000000000..db2390a03b0
--- /dev/null
+++ b/components/script/dom/webgpu/gpuconvert.rs
@@ -0,0 +1,680 @@
+/* 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/. */
+
+use std::borrow::Cow;
+use std::num::NonZeroU64;
+
+use webgpu::wgc::binding_model::{BindGroupEntry, BindingResource, BufferBinding};
+use webgpu::wgc::command as wgpu_com;
+use webgpu::wgc::pipeline::ProgrammableStageDescriptor;
+use webgpu::wgc::resource::TextureDescriptor;
+use webgpu::wgt::{self, AstcBlock, AstcChannel};
+
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUAddressMode, GPUBindGroupEntry, GPUBindGroupLayoutEntry, GPUBindingResource,
+ GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUBufferBindingType, GPUColor,
+ GPUCompareFunction, GPUCullMode, GPUExtent3D, GPUFilterMode, GPUFrontFace, GPUImageCopyBuffer,
+ GPUImageCopyTexture, GPUImageDataLayout, GPUIndexFormat, GPULoadOp, GPUObjectDescriptorBase,
+ GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology, GPUProgrammableStage,
+ GPUSamplerBindingType, GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp,
+ GPUTextureAspect, GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat,
+ GPUTextureSampleType, GPUTextureViewDimension, GPUVertexFormat,
+};
+use crate::dom::bindings::error::{Error, Fallible};
+use crate::dom::types::GPUDevice;
+
+impl From<GPUTextureFormat> for wgt::TextureFormat {
+ fn from(format: GPUTextureFormat) -> Self {
+ match format {
+ GPUTextureFormat::R8unorm => wgt::TextureFormat::R8Unorm,
+ GPUTextureFormat::R8snorm => wgt::TextureFormat::R8Snorm,
+ GPUTextureFormat::R8uint => wgt::TextureFormat::R8Uint,
+ GPUTextureFormat::R8sint => wgt::TextureFormat::R8Sint,
+ GPUTextureFormat::R16uint => wgt::TextureFormat::R16Uint,
+ GPUTextureFormat::R16sint => wgt::TextureFormat::R16Sint,
+ GPUTextureFormat::R16float => wgt::TextureFormat::R16Float,
+ GPUTextureFormat::Rg8unorm => wgt::TextureFormat::Rg8Unorm,
+ GPUTextureFormat::Rg8snorm => wgt::TextureFormat::Rg8Snorm,
+ GPUTextureFormat::Rg8uint => wgt::TextureFormat::Rg8Uint,
+ GPUTextureFormat::Rg8sint => wgt::TextureFormat::Rg8Sint,
+ GPUTextureFormat::R32uint => wgt::TextureFormat::R32Uint,
+ GPUTextureFormat::R32sint => wgt::TextureFormat::R32Sint,
+ GPUTextureFormat::R32float => wgt::TextureFormat::R32Float,
+ GPUTextureFormat::Rg16uint => wgt::TextureFormat::Rg16Uint,
+ GPUTextureFormat::Rg16sint => wgt::TextureFormat::Rg16Sint,
+ GPUTextureFormat::Rg16float => wgt::TextureFormat::Rg16Float,
+ GPUTextureFormat::Rgba8unorm => wgt::TextureFormat::Rgba8Unorm,
+ GPUTextureFormat::Rgba8unorm_srgb => wgt::TextureFormat::Rgba8UnormSrgb,
+ GPUTextureFormat::Rgba8snorm => wgt::TextureFormat::Rgba8Snorm,
+ GPUTextureFormat::Rgba8uint => wgt::TextureFormat::Rgba8Uint,
+ GPUTextureFormat::Rgba8sint => wgt::TextureFormat::Rgba8Sint,
+ GPUTextureFormat::Bgra8unorm => wgt::TextureFormat::Bgra8Unorm,
+ GPUTextureFormat::Bgra8unorm_srgb => wgt::TextureFormat::Bgra8UnormSrgb,
+ GPUTextureFormat::Rgb10a2unorm => wgt::TextureFormat::Rgb10a2Unorm,
+ GPUTextureFormat::Rg32uint => wgt::TextureFormat::Rg32Uint,
+ GPUTextureFormat::Rg32sint => wgt::TextureFormat::Rg32Sint,
+ GPUTextureFormat::Rg32float => wgt::TextureFormat::Rg32Float,
+ GPUTextureFormat::Rgba16uint => wgt::TextureFormat::Rgba16Uint,
+ GPUTextureFormat::Rgba16sint => wgt::TextureFormat::Rgba16Sint,
+ GPUTextureFormat::Rgba16float => wgt::TextureFormat::Rgba16Float,
+ GPUTextureFormat::Rgba32uint => wgt::TextureFormat::Rgba32Uint,
+ GPUTextureFormat::Rgba32sint => wgt::TextureFormat::Rgba32Sint,
+ GPUTextureFormat::Rgba32float => wgt::TextureFormat::Rgba32Float,
+ GPUTextureFormat::Depth32float => wgt::TextureFormat::Depth32Float,
+ GPUTextureFormat::Depth24plus => wgt::TextureFormat::Depth24Plus,
+ GPUTextureFormat::Depth24plus_stencil8 => wgt::TextureFormat::Depth24PlusStencil8,
+ GPUTextureFormat::Bc1_rgba_unorm => wgt::TextureFormat::Bc1RgbaUnorm,
+ GPUTextureFormat::Bc1_rgba_unorm_srgb => wgt::TextureFormat::Bc1RgbaUnormSrgb,
+ GPUTextureFormat::Bc2_rgba_unorm => wgt::TextureFormat::Bc2RgbaUnorm,
+ GPUTextureFormat::Bc2_rgba_unorm_srgb => wgt::TextureFormat::Bc2RgbaUnormSrgb,
+ GPUTextureFormat::Bc3_rgba_unorm => wgt::TextureFormat::Bc3RgbaUnorm,
+ GPUTextureFormat::Bc3_rgba_unorm_srgb => wgt::TextureFormat::Bc3RgbaUnormSrgb,
+ GPUTextureFormat::Bc4_r_unorm => wgt::TextureFormat::Bc4RUnorm,
+ GPUTextureFormat::Bc4_r_snorm => wgt::TextureFormat::Bc4RSnorm,
+ GPUTextureFormat::Bc5_rg_unorm => wgt::TextureFormat::Bc5RgUnorm,
+ GPUTextureFormat::Bc5_rg_snorm => wgt::TextureFormat::Bc5RgSnorm,
+ GPUTextureFormat::Bc6h_rgb_ufloat => wgt::TextureFormat::Bc6hRgbUfloat,
+ GPUTextureFormat::Bc7_rgba_unorm => wgt::TextureFormat::Bc7RgbaUnorm,
+ GPUTextureFormat::Bc7_rgba_unorm_srgb => wgt::TextureFormat::Bc7RgbaUnormSrgb,
+ GPUTextureFormat::Bc6h_rgb_float => wgt::TextureFormat::Bc6hRgbFloat,
+ GPUTextureFormat::Rgb9e5ufloat => wgt::TextureFormat::Rgb9e5Ufloat,
+ GPUTextureFormat::Rgb10a2uint => wgt::TextureFormat::Rgb10a2Uint,
+ GPUTextureFormat::Rg11b10ufloat => wgt::TextureFormat::Rg11b10Ufloat,
+ GPUTextureFormat::Stencil8 => wgt::TextureFormat::Stencil8,
+ GPUTextureFormat::Depth16unorm => wgt::TextureFormat::Depth16Unorm,
+ GPUTextureFormat::Depth32float_stencil8 => wgt::TextureFormat::Depth32FloatStencil8,
+ GPUTextureFormat::Etc2_rgb8unorm => wgt::TextureFormat::Etc2Rgb8Unorm,
+ GPUTextureFormat::Etc2_rgb8unorm_srgb => wgt::TextureFormat::Etc2Rgb8UnormSrgb,
+ GPUTextureFormat::Etc2_rgb8a1unorm => wgt::TextureFormat::Etc2Rgb8A1Unorm,
+ GPUTextureFormat::Etc2_rgb8a1unorm_srgb => wgt::TextureFormat::Etc2Rgb8A1UnormSrgb,
+ GPUTextureFormat::Etc2_rgba8unorm => wgt::TextureFormat::Etc2Rgba8Unorm,
+ GPUTextureFormat::Etc2_rgba8unorm_srgb => wgt::TextureFormat::Etc2Rgba8UnormSrgb,
+ GPUTextureFormat::Eac_r11unorm => wgt::TextureFormat::EacR11Unorm,
+ GPUTextureFormat::Eac_r11snorm => wgt::TextureFormat::EacR11Snorm,
+ GPUTextureFormat::Eac_rg11unorm => wgt::TextureFormat::EacRg11Unorm,
+ GPUTextureFormat::Eac_rg11snorm => wgt::TextureFormat::EacRg11Snorm,
+ GPUTextureFormat::Astc_4x4_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B4x4,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_4x4_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B4x4,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_5x4_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B5x4,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_5x4_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B5x4,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_5x5_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B5x5,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_5x5_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B5x5,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_6x5_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B6x5,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_6x5_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B6x5,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_6x6_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B6x6,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_6x6_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B6x6,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_8x5_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x5,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_8x5_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x5,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_8x6_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x6,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_8x6_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x6,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_8x8_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x8,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_8x8_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B8x8,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_10x5_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x5,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_10x5_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x5,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_10x6_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x6,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_10x6_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x6,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_10x8_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x8,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_10x8_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x8,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_10x10_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x10,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_10x10_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B10x10,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_12x10_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B12x10,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_12x10_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B12x10,
+ channel: AstcChannel::UnormSrgb,
+ },
+ GPUTextureFormat::Astc_12x12_unorm => wgt::TextureFormat::Astc {
+ block: AstcBlock::B12x12,
+ channel: AstcChannel::Unorm,
+ },
+ GPUTextureFormat::Astc_12x12_unorm_srgb => wgt::TextureFormat::Astc {
+ block: AstcBlock::B12x12,
+ channel: AstcChannel::UnormSrgb,
+ },
+ }
+ }
+}
+
+impl TryFrom<&GPUExtent3D> for wgt::Extent3d {
+ type Error = Error;
+
+ fn try_from(size: &GPUExtent3D) -> Result<Self, Self::Error> {
+ match *size {
+ GPUExtent3D::GPUExtent3DDict(ref dict) => Ok(wgt::Extent3d {
+ width: dict.width,
+ height: dict.height,
+ depth_or_array_layers: dict.depthOrArrayLayers,
+ }),
+ GPUExtent3D::RangeEnforcedUnsignedLongSequence(ref v) => {
+ // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuextent3d-shape
+ if v.is_empty() || v.len() > 3 {
+ Err(Error::Type(
+ "GPUExtent3D size must be between 1 and 3 (inclusive)".to_string(),
+ ))
+ } else {
+ Ok(wgt::Extent3d {
+ width: v[0],
+ height: v.get(1).copied().unwrap_or(1),
+ depth_or_array_layers: v.get(2).copied().unwrap_or(1),
+ })
+ }
+ },
+ }
+ }
+}
+
+impl From<&GPUImageDataLayout> for wgt::ImageDataLayout {
+ fn from(data_layout: &GPUImageDataLayout) -> Self {
+ wgt::ImageDataLayout {
+ offset: data_layout.offset as wgt::BufferAddress,
+ bytes_per_row: data_layout.bytesPerRow,
+ rows_per_image: data_layout.rowsPerImage,
+ }
+ }
+}
+
+impl From<GPUVertexFormat> for wgt::VertexFormat {
+ fn from(format: GPUVertexFormat) -> Self {
+ match format {
+ GPUVertexFormat::Uint8x2 => wgt::VertexFormat::Uint8x2,
+ GPUVertexFormat::Uint8x4 => wgt::VertexFormat::Uint8x4,
+ GPUVertexFormat::Sint8x2 => wgt::VertexFormat::Sint8x2,
+ GPUVertexFormat::Sint8x4 => wgt::VertexFormat::Sint8x4,
+ GPUVertexFormat::Unorm8x2 => wgt::VertexFormat::Unorm8x2,
+ GPUVertexFormat::Unorm8x4 => wgt::VertexFormat::Unorm8x4,
+ GPUVertexFormat::Snorm8x2 => wgt::VertexFormat::Unorm8x2,
+ GPUVertexFormat::Snorm8x4 => wgt::VertexFormat::Unorm8x4,
+ GPUVertexFormat::Uint16x2 => wgt::VertexFormat::Uint16x2,
+ GPUVertexFormat::Uint16x4 => wgt::VertexFormat::Uint16x4,
+ GPUVertexFormat::Sint16x2 => wgt::VertexFormat::Sint16x2,
+ GPUVertexFormat::Sint16x4 => wgt::VertexFormat::Sint16x4,
+ GPUVertexFormat::Unorm16x2 => wgt::VertexFormat::Unorm16x2,
+ GPUVertexFormat::Unorm16x4 => wgt::VertexFormat::Unorm16x4,
+ GPUVertexFormat::Snorm16x2 => wgt::VertexFormat::Snorm16x2,
+ GPUVertexFormat::Snorm16x4 => wgt::VertexFormat::Snorm16x4,
+ GPUVertexFormat::Float16x2 => wgt::VertexFormat::Float16x2,
+ GPUVertexFormat::Float16x4 => wgt::VertexFormat::Float16x4,
+ GPUVertexFormat::Float32 => wgt::VertexFormat::Float32,
+ GPUVertexFormat::Float32x2 => wgt::VertexFormat::Float32x2,
+ GPUVertexFormat::Float32x3 => wgt::VertexFormat::Float32x3,
+ GPUVertexFormat::Float32x4 => wgt::VertexFormat::Float32x4,
+ GPUVertexFormat::Uint32 => wgt::VertexFormat::Uint32,
+ GPUVertexFormat::Uint32x2 => wgt::VertexFormat::Uint32x2,
+ GPUVertexFormat::Uint32x3 => wgt::VertexFormat::Uint32x3,
+ GPUVertexFormat::Uint32x4 => wgt::VertexFormat::Uint32x4,
+ GPUVertexFormat::Sint32 => wgt::VertexFormat::Sint32,
+ GPUVertexFormat::Sint32x2 => wgt::VertexFormat::Sint32x2,
+ GPUVertexFormat::Sint32x3 => wgt::VertexFormat::Sint32x3,
+ GPUVertexFormat::Sint32x4 => wgt::VertexFormat::Sint32x4,
+ }
+ }
+}
+
+impl From<&GPUPrimitiveState> for wgt::PrimitiveState {
+ fn from(primitive_state: &GPUPrimitiveState) -> Self {
+ wgt::PrimitiveState {
+ topology: wgt::PrimitiveTopology::from(&primitive_state.topology),
+ strip_index_format: primitive_state.stripIndexFormat.map(|index_format| {
+ match index_format {
+ GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
+ GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
+ }
+ }),
+ front_face: match primitive_state.frontFace {
+ GPUFrontFace::Ccw => wgt::FrontFace::Ccw,
+ GPUFrontFace::Cw => wgt::FrontFace::Cw,
+ },
+ cull_mode: match primitive_state.cullMode {
+ GPUCullMode::None => None,
+ GPUCullMode::Front => Some(wgt::Face::Front),
+ GPUCullMode::Back => Some(wgt::Face::Back),
+ },
+ unclipped_depth: primitive_state.clampDepth,
+ ..Default::default()
+ }
+ }
+}
+
+impl From<&GPUPrimitiveTopology> for wgt::PrimitiveTopology {
+ fn from(primitive_topology: &GPUPrimitiveTopology) -> Self {
+ match primitive_topology {
+ GPUPrimitiveTopology::Point_list => wgt::PrimitiveTopology::PointList,
+ GPUPrimitiveTopology::Line_list => wgt::PrimitiveTopology::LineList,
+ GPUPrimitiveTopology::Line_strip => wgt::PrimitiveTopology::LineStrip,
+ GPUPrimitiveTopology::Triangle_list => wgt::PrimitiveTopology::TriangleList,
+ GPUPrimitiveTopology::Triangle_strip => wgt::PrimitiveTopology::TriangleStrip,
+ }
+ }
+}
+
+impl From<GPUAddressMode> for wgt::AddressMode {
+ fn from(address_mode: GPUAddressMode) -> Self {
+ match address_mode {
+ GPUAddressMode::Clamp_to_edge => wgt::AddressMode::ClampToEdge,
+ GPUAddressMode::Repeat => wgt::AddressMode::Repeat,
+ GPUAddressMode::Mirror_repeat => wgt::AddressMode::MirrorRepeat,
+ }
+ }
+}
+
+impl From<GPUFilterMode> for wgt::FilterMode {
+ fn from(filter_mode: GPUFilterMode) -> Self {
+ match filter_mode {
+ GPUFilterMode::Nearest => wgt::FilterMode::Nearest,
+ GPUFilterMode::Linear => wgt::FilterMode::Linear,
+ }
+ }
+}
+
+impl From<GPUTextureViewDimension> for wgt::TextureViewDimension {
+ fn from(view_dimension: GPUTextureViewDimension) -> Self {
+ match view_dimension {
+ GPUTextureViewDimension::_1d => wgt::TextureViewDimension::D1,
+ GPUTextureViewDimension::_2d => wgt::TextureViewDimension::D2,
+ GPUTextureViewDimension::_2d_array => wgt::TextureViewDimension::D2Array,
+ GPUTextureViewDimension::Cube => wgt::TextureViewDimension::Cube,
+ GPUTextureViewDimension::Cube_array => wgt::TextureViewDimension::CubeArray,
+ GPUTextureViewDimension::_3d => wgt::TextureViewDimension::D3,
+ }
+ }
+}
+
+impl From<GPUCompareFunction> for wgt::CompareFunction {
+ fn from(compare: GPUCompareFunction) -> Self {
+ match compare {
+ GPUCompareFunction::Never => wgt::CompareFunction::Never,
+ GPUCompareFunction::Less => wgt::CompareFunction::Less,
+ GPUCompareFunction::Equal => wgt::CompareFunction::Equal,
+ GPUCompareFunction::Less_equal => wgt::CompareFunction::LessEqual,
+ GPUCompareFunction::Greater => wgt::CompareFunction::Greater,
+ GPUCompareFunction::Not_equal => wgt::CompareFunction::NotEqual,
+ GPUCompareFunction::Greater_equal => wgt::CompareFunction::GreaterEqual,
+ GPUCompareFunction::Always => wgt::CompareFunction::Always,
+ }
+ }
+}
+
+impl From<&GPUBlendFactor> for wgt::BlendFactor {
+ fn from(factor: &GPUBlendFactor) -> Self {
+ match factor {
+ GPUBlendFactor::Zero => wgt::BlendFactor::Zero,
+ GPUBlendFactor::One => wgt::BlendFactor::One,
+ GPUBlendFactor::Src => wgt::BlendFactor::Src,
+ GPUBlendFactor::One_minus_src => wgt::BlendFactor::OneMinusSrc,
+ GPUBlendFactor::Src_alpha => wgt::BlendFactor::SrcAlpha,
+ GPUBlendFactor::One_minus_src_alpha => wgt::BlendFactor::OneMinusSrcAlpha,
+ GPUBlendFactor::Dst => wgt::BlendFactor::Dst,
+ GPUBlendFactor::One_minus_dst => wgt::BlendFactor::OneMinusDst,
+ GPUBlendFactor::Dst_alpha => wgt::BlendFactor::DstAlpha,
+ GPUBlendFactor::One_minus_dst_alpha => wgt::BlendFactor::OneMinusDstAlpha,
+ GPUBlendFactor::Src_alpha_saturated => wgt::BlendFactor::SrcAlphaSaturated,
+ GPUBlendFactor::Constant => wgt::BlendFactor::Constant,
+ GPUBlendFactor::One_minus_constant => wgt::BlendFactor::OneMinusConstant,
+ }
+ }
+}
+
+impl From<&GPUBlendComponent> for wgt::BlendComponent {
+ fn from(blend_component: &GPUBlendComponent) -> Self {
+ wgt::BlendComponent {
+ src_factor: wgt::BlendFactor::from(&blend_component.srcFactor),
+ dst_factor: wgt::BlendFactor::from(&blend_component.dstFactor),
+ operation: match blend_component.operation {
+ GPUBlendOperation::Add => wgt::BlendOperation::Add,
+ GPUBlendOperation::Subtract => wgt::BlendOperation::Subtract,
+ GPUBlendOperation::Reverse_subtract => wgt::BlendOperation::ReverseSubtract,
+ GPUBlendOperation::Min => wgt::BlendOperation::Min,
+ GPUBlendOperation::Max => wgt::BlendOperation::Max,
+ },
+ }
+ }
+}
+
+pub fn convert_load_op(op: Option<GPULoadOp>) -> wgpu_com::LoadOp {
+ match op {
+ Some(GPULoadOp::Load) => wgpu_com::LoadOp::Load,
+ Some(GPULoadOp::Clear) => wgpu_com::LoadOp::Clear,
+ None => wgpu_com::LoadOp::Clear,
+ }
+}
+
+pub fn convert_store_op(op: Option<GPUStoreOp>) -> wgpu_com::StoreOp {
+ match op {
+ Some(GPUStoreOp::Store) => wgpu_com::StoreOp::Store,
+ Some(GPUStoreOp::Discard) => wgpu_com::StoreOp::Discard,
+ None => wgpu_com::StoreOp::Discard,
+ }
+}
+
+impl From<GPUStencilOperation> for wgt::StencilOperation {
+ fn from(operation: GPUStencilOperation) -> Self {
+ match operation {
+ GPUStencilOperation::Keep => wgt::StencilOperation::Keep,
+ GPUStencilOperation::Zero => wgt::StencilOperation::Zero,
+ GPUStencilOperation::Replace => wgt::StencilOperation::Replace,
+ GPUStencilOperation::Invert => wgt::StencilOperation::Invert,
+ GPUStencilOperation::Increment_clamp => wgt::StencilOperation::IncrementClamp,
+ GPUStencilOperation::Decrement_clamp => wgt::StencilOperation::DecrementClamp,
+ GPUStencilOperation::Increment_wrap => wgt::StencilOperation::IncrementWrap,
+ GPUStencilOperation::Decrement_wrap => wgt::StencilOperation::DecrementWrap,
+ }
+ }
+}
+
+impl From<&GPUImageCopyBuffer> for wgpu_com::ImageCopyBuffer {
+ fn from(ic_buffer: &GPUImageCopyBuffer) -> Self {
+ wgpu_com::ImageCopyBuffer {
+ buffer: ic_buffer.buffer.id().0,
+ layout: wgt::ImageDataLayout::from(&ic_buffer.parent),
+ }
+ }
+}
+
+impl TryFrom<&GPUOrigin3D> for wgt::Origin3d {
+ type Error = Error;
+
+ fn try_from(origin: &GPUOrigin3D) -> Result<Self, Self::Error> {
+ match origin {
+ GPUOrigin3D::RangeEnforcedUnsignedLongSequence(v) => {
+ // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuorigin3d-shape
+ if v.len() > 3 {
+ Err(Error::Type(
+ "sequence is too long for GPUOrigin3D".to_string(),
+ ))
+ } else {
+ Ok(wgt::Origin3d {
+ x: v.first().copied().unwrap_or(0),
+ y: v.get(1).copied().unwrap_or(0),
+ z: v.get(2).copied().unwrap_or(0),
+ })
+ }
+ },
+ GPUOrigin3D::GPUOrigin3DDict(d) => Ok(wgt::Origin3d {
+ x: d.x,
+ y: d.y,
+ z: d.z,
+ }),
+ }
+ }
+}
+
+impl TryFrom<&GPUImageCopyTexture> for wgpu_com::ImageCopyTexture {
+ type Error = Error;
+
+ fn try_from(ic_texture: &GPUImageCopyTexture) -> Result<Self, Self::Error> {
+ Ok(wgpu_com::ImageCopyTexture {
+ texture: ic_texture.texture.id().0,
+ mip_level: ic_texture.mipLevel,
+ origin: ic_texture
+ .origin
+ .as_ref()
+ .map(wgt::Origin3d::try_from)
+ .transpose()?
+ .unwrap_or_default(),
+ aspect: match ic_texture.aspect {
+ GPUTextureAspect::All => wgt::TextureAspect::All,
+ GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
+ GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
+ },
+ })
+ }
+}
+
+impl<'a> From<&GPUObjectDescriptorBase> for Option<Cow<'a, str>> {
+ fn from(val: &GPUObjectDescriptorBase) -> Self {
+ if val.label.is_empty() {
+ None
+ } else {
+ Some(Cow::Owned(val.label.to_string()))
+ }
+ }
+}
+
+pub fn convert_bind_group_layout_entry(
+ bgle: &GPUBindGroupLayoutEntry,
+ device: &GPUDevice,
+) -> Fallible<Result<wgt::BindGroupLayoutEntry, webgpu::Error>> {
+ let number_of_provided_bindings = bgle.buffer.is_some() as u8 +
+ bgle.sampler.is_some() as u8 +
+ bgle.storageTexture.is_some() as u8 +
+ bgle.texture.is_some() as u8;
+ let ty = if let Some(buffer) = &bgle.buffer {
+ Some(wgt::BindingType::Buffer {
+ ty: match buffer.type_ {
+ GPUBufferBindingType::Uniform => wgt::BufferBindingType::Uniform,
+ GPUBufferBindingType::Storage => {
+ wgt::BufferBindingType::Storage { read_only: false }
+ },
+ GPUBufferBindingType::Read_only_storage => {
+ wgt::BufferBindingType::Storage { read_only: true }
+ },
+ },
+ has_dynamic_offset: buffer.hasDynamicOffset,
+ min_binding_size: NonZeroU64::new(buffer.minBindingSize),
+ })
+ } else if let Some(sampler) = &bgle.sampler {
+ Some(wgt::BindingType::Sampler(match sampler.type_ {
+ GPUSamplerBindingType::Filtering => wgt::SamplerBindingType::Filtering,
+ GPUSamplerBindingType::Non_filtering => wgt::SamplerBindingType::NonFiltering,
+ GPUSamplerBindingType::Comparison => wgt::SamplerBindingType::Comparison,
+ }))
+ } else if let Some(storage) = &bgle.storageTexture {
+ Some(wgt::BindingType::StorageTexture {
+ access: match storage.access {
+ GPUStorageTextureAccess::Write_only => wgt::StorageTextureAccess::WriteOnly,
+ GPUStorageTextureAccess::Read_only => wgt::StorageTextureAccess::ReadOnly,
+ GPUStorageTextureAccess::Read_write => wgt::StorageTextureAccess::ReadWrite,
+ },
+ format: device.validate_texture_format_required_features(&storage.format)?,
+ view_dimension: storage.viewDimension.into(),
+ })
+ } else if let Some(texture) = &bgle.texture {
+ Some(wgt::BindingType::Texture {
+ sample_type: match texture.sampleType {
+ GPUTextureSampleType::Float => wgt::TextureSampleType::Float { filterable: true },
+ GPUTextureSampleType::Unfilterable_float => {
+ wgt::TextureSampleType::Float { filterable: false }
+ },
+ GPUTextureSampleType::Depth => wgt::TextureSampleType::Depth,
+ GPUTextureSampleType::Sint => wgt::TextureSampleType::Sint,
+ GPUTextureSampleType::Uint => wgt::TextureSampleType::Uint,
+ },
+ view_dimension: texture.viewDimension.into(),
+ multisampled: texture.multisampled,
+ })
+ } else {
+ assert_eq!(number_of_provided_bindings, 0);
+ None
+ };
+ // Check for number of bindings should actually be done in device-timeline,
+ // but we do it last on content-timeline to have some visible effect
+ let ty = if number_of_provided_bindings != 1 {
+ None
+ } else {
+ ty
+ }
+ .ok_or(webgpu::Error::Validation(
+ "Exactly on entry type must be provided".to_string(),
+ ));
+
+ Ok(ty.map(|ty| wgt::BindGroupLayoutEntry {
+ binding: bgle.binding,
+ visibility: wgt::ShaderStages::from_bits_retain(bgle.visibility),
+ ty,
+ count: None,
+ }))
+}
+
+pub fn convert_texture_descriptor(
+ descriptor: &GPUTextureDescriptor,
+ device: &GPUDevice,
+) -> Fallible<(TextureDescriptor<'static>, wgt::Extent3d)> {
+ let size = (&descriptor.size).try_into()?;
+ let desc = TextureDescriptor {
+ label: (&descriptor.parent).into(),
+ size,
+ mip_level_count: descriptor.mipLevelCount,
+ sample_count: descriptor.sampleCount,
+ dimension: descriptor.dimension.into(),
+ format: device.validate_texture_format_required_features(&descriptor.format)?,
+ usage: wgt::TextureUsages::from_bits_retain(descriptor.usage),
+ view_formats: descriptor
+ .viewFormats
+ .iter()
+ .map(|tf| device.validate_texture_format_required_features(tf))
+ .collect::<Fallible<_>>()?,
+ };
+ Ok((desc, size))
+}
+
+impl TryFrom<&GPUColor> for wgt::Color {
+ type Error = Error;
+
+ fn try_from(color: &GPUColor) -> Result<Self, Self::Error> {
+ match color {
+ GPUColor::DoubleSequence(s) => {
+ // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpucolor-shape
+ if s.len() != 4 {
+ Err(Error::Type("GPUColor sequence must be len 4".to_string()))
+ } else {
+ Ok(wgt::Color {
+ r: *s[0],
+ g: *s[1],
+ b: *s[2],
+ a: *s[3],
+ })
+ }
+ },
+ GPUColor::GPUColorDict(d) => Ok(wgt::Color {
+ r: *d.r,
+ g: *d.g,
+ b: *d.b,
+ a: *d.a,
+ }),
+ }
+ }
+}
+
+impl<'a> From<&GPUProgrammableStage> for ProgrammableStageDescriptor<'a> {
+ fn from(stage: &GPUProgrammableStage) -> Self {
+ Self {
+ module: stage.module.id().0,
+ entry_point: stage
+ .entryPoint
+ .as_ref()
+ .map(|ep| Cow::Owned(ep.to_string())),
+ constants: Cow::Owned(
+ stage
+ .constants
+ .as_ref()
+ .map(|records| records.iter().map(|(k, v)| (k.0.clone(), **v)).collect())
+ .unwrap_or_default(),
+ ),
+ zero_initialize_workgroup_memory: true,
+ }
+ }
+}
+
+impl From<&GPUBindGroupEntry> for BindGroupEntry<'_> {
+ fn from(entry: &GPUBindGroupEntry) -> Self {
+ Self {
+ binding: entry.binding,
+ resource: match entry.resource {
+ GPUBindingResource::GPUSampler(ref s) => BindingResource::Sampler(s.id().0),
+ GPUBindingResource::GPUTextureView(ref t) => BindingResource::TextureView(t.id().0),
+ GPUBindingResource::GPUBufferBinding(ref b) => {
+ BindingResource::Buffer(BufferBinding {
+ buffer_id: b.buffer.id().0,
+ offset: b.offset,
+ size: b.size.and_then(wgt::BufferSize::new),
+ })
+ },
+ },
+ }
+ }
+}
+
+impl From<GPUTextureDimension> for wgt::TextureDimension {
+ fn from(dimension: GPUTextureDimension) -> Self {
+ match dimension {
+ GPUTextureDimension::_1d => wgt::TextureDimension::D1,
+ GPUTextureDimension::_2d => wgt::TextureDimension::D2,
+ GPUTextureDimension::_3d => wgt::TextureDimension::D3,
+ }
+ }
+}