mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
webgpu: Sync various parts of spec (#33009)
* Sync `GPUObjectDescriptorBase` (label is not option anymore) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Sync `GPUFeatureName` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * shader_f16 feature is not usable in wgpu so disable it Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * sync `GPUTextureFormat` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * `validate_texture_format_required_features` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Sync `GPUTexture` attributes Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Make `entryPoint` in `GPUProgrammableStage` optional Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Set good expectations Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Bad expectations because naga does not support cons declarations Also fail on firefox, where skipped before due to missing device features Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Bad expectation, also fails on firefox Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Bad expectations, because naga does not support `let pos = positions[vertex_index];` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Set expectation external texture does not work in firefox too (again naga) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * set bad expectations, because naga does not support `enable` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Set bad expectations for, `Texture with '' label has been destroyed` also fails in firefox with same reason Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * one bad expectation also on firefox Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * expect that also matches firefox Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * more expect Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Use only 1 proc for _webgpu Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * better doc comment Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
f45c98496e
commit
94ff89a5e4
11 changed files with 910 additions and 4947 deletions
|
@ -110,10 +110,10 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
// Step 2
|
||||
let promise = Promise::new_in_current_realm(comp);
|
||||
let sender = response_async(&promise, self);
|
||||
let mut features = wgt::Features::empty();
|
||||
let mut required_features = wgt::Features::empty();
|
||||
for &ext in descriptor.requiredFeatures.iter() {
|
||||
if let Some(feature) = gpu_to_wgt_feature(ext) {
|
||||
features.insert(feature);
|
||||
required_features.insert(feature);
|
||||
} else {
|
||||
promise.reject_error(Error::Type(format!(
|
||||
"{} is not supported feature",
|
||||
|
@ -123,21 +123,23 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
let mut desc = wgt::DeviceDescriptor {
|
||||
required_features: features,
|
||||
required_limits: wgt::Limits::default(),
|
||||
label: None,
|
||||
memory_hints: MemoryHints::MemoryUsage,
|
||||
};
|
||||
let mut required_limits = wgt::Limits::default();
|
||||
if let Some(limits) = &descriptor.requiredLimits {
|
||||
for (limit, value) in (*limits).iter() {
|
||||
if !set_limit(&mut desc.required_limits, limit.as_ref(), *value) {
|
||||
if !set_limit(&mut required_limits, limit.as_ref(), *value) {
|
||||
warn!("Unknown GPUDevice limit: {limit}");
|
||||
promise.reject_error(Error::Operation);
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let desc = wgt::DeviceDescriptor {
|
||||
required_features,
|
||||
required_limits,
|
||||
label: Some(descriptor.parent.label.to_string()),
|
||||
memory_hints: MemoryHints::MemoryUsage,
|
||||
};
|
||||
let device_id = self
|
||||
.global()
|
||||
.wgpu_id_hub()
|
||||
|
|
|
@ -20,6 +20,7 @@ use super::bindings::codegen::Bindings::WebGPUBinding::GPUTextureUsageConstants;
|
|||
use super::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
|
||||
use super::bindings::error::{Error, Fallible};
|
||||
use super::bindings::root::MutNullableDom;
|
||||
use super::bindings::str::USVString;
|
||||
use super::gputexture::GPUTexture;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElement_Binding::HTMLCanvasElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||
|
@ -207,7 +208,9 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
fn Configure(&self, descriptor: &GPUCanvasConfiguration) -> Fallible<()> {
|
||||
// Step 1 is let
|
||||
// Step 2
|
||||
// TODO: device features
|
||||
descriptor
|
||||
.device
|
||||
.validate_texture_format_required_features(&descriptor.format)?;
|
||||
let format = match descriptor.format {
|
||||
GPUTextureFormat::Rgba8unorm | GPUTextureFormat::Rgba8unorm_srgb => ImageFormat::RGBA8,
|
||||
GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Bgra8unorm_srgb => ImageFormat::BGRA8,
|
||||
|
@ -220,7 +223,11 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
};
|
||||
|
||||
// Step 3
|
||||
// TODO: device features
|
||||
for view_format in &descriptor.viewFormats {
|
||||
descriptor
|
||||
.device
|
||||
.validate_texture_format_required_features(view_format)?;
|
||||
}
|
||||
|
||||
// Step 4
|
||||
let size = self.size();
|
||||
|
@ -236,7 +243,9 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
}),
|
||||
viewFormats: descriptor.viewFormats.clone(),
|
||||
// other members to default
|
||||
parent: GPUObjectDescriptorBase { label: None },
|
||||
parent: GPUObjectDescriptorBase {
|
||||
label: USVString::default(),
|
||||
},
|
||||
dimension: GPUTextureDimension::_2d,
|
||||
};
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
self,
|
||||
WebGPUComputePass(compute_pass_id),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
WebGPURenderPass(render_pass_id),
|
||||
self,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
buffer,
|
||||
self.buffers.borrow_mut().drain().collect(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use webgpu::wgc::command as wgpu_com;
|
||||
use webgpu::wgt;
|
||||
use webgpu::wgt::{self, AstcBlock, AstcChannel};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||
GPUAddressMode, GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUCompareFunction,
|
||||
|
@ -67,8 +67,135 @@ pub fn convert_texture_format(format: GPUTextureFormat) -> wgt::TextureFormat {
|
|||
GPUTextureFormat::Bc6h_rgb_ufloat => wgt::TextureFormat::Bc6hRgbUfloat,
|
||||
GPUTextureFormat::Bc7_rgba_unorm => wgt::TextureFormat::Bc7RgbaUnorm,
|
||||
GPUTextureFormat::Bc7_rgba_unorm_srgb => wgt::TextureFormat::Bc7RgbaUnormSrgb,
|
||||
GPUTextureFormat::Rg11b10float => wgt::TextureFormat::Rg11b10Float,
|
||||
GPUTextureFormat::Bc6h_rgb_float => wgt::TextureFormat::Bc6hRgbFloat,
|
||||
GPUTextureFormat::Rgb9e5ufloat => wgt::TextureFormat::Rgb9e5Ufloat,
|
||||
GPUTextureFormat::Rgb10a2uint => wgt::TextureFormat::Rgb10a2Uint,
|
||||
GPUTextureFormat::Rg11b10ufloat => wgt::TextureFormat::Rg11b10Float,
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,5 +456,9 @@ pub fn convert_ic_texture(ic_texture: &GPUImageCopyTexture) -> wgpu_com::ImageCo
|
|||
}
|
||||
|
||||
pub fn convert_label(parent: &GPUObjectDescriptorBase) -> Option<Cow<'static, str>> {
|
||||
parent.label.as_ref().map(|s| Cow::Owned(s.to_string()))
|
||||
if parent.label.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Cow::Owned(parent.label.to_string()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,13 @@ use webgpu::wgc::pipeline::RenderPipelineDescriptor;
|
|||
use webgpu::wgc::{
|
||||
binding_model as wgpu_bind, command as wgpu_com, pipeline as wgpu_pipe, resource as wgpu_res,
|
||||
};
|
||||
use webgpu::wgt::TextureFormat;
|
||||
use webgpu::{
|
||||
self, wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest,
|
||||
WebGPUResponse,
|
||||
};
|
||||
|
||||
use super::bindings::codegen::Bindings::WebGPUBinding::GPUPipelineErrorReason;
|
||||
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUPipelineErrorReason, GPUTextureFormat};
|
||||
use super::bindings::codegen::UnionTypes::GPUPipelineLayoutOrGPUAutoLayoutMode;
|
||||
use super::bindings::error::Fallible;
|
||||
use super::gpu::AsyncWGPUListener;
|
||||
|
@ -190,6 +191,28 @@ impl GPUDevice {
|
|||
let _ = self.eventtarget.DispatchEvent(ev.event());
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-texture-format-required-features>
|
||||
///
|
||||
/// Validates that the device suppports required features,
|
||||
/// and if so returns an ok containing wgpu's `TextureFormat`
|
||||
pub fn validate_texture_format_required_features(
|
||||
&self,
|
||||
format: &GPUTextureFormat,
|
||||
) -> Fallible<TextureFormat> {
|
||||
let texture_format = convert_texture_format(*format);
|
||||
if self
|
||||
.features
|
||||
.wgpu_features()
|
||||
.contains(texture_format.required_features())
|
||||
{
|
||||
Ok(texture_format)
|
||||
} else {
|
||||
Err(Error::Type(format!(
|
||||
"{texture_format:?} is not supported by this GPUDevice"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_pipeline_layout_data(
|
||||
&self,
|
||||
layout: &GPUPipelineLayoutOrGPUAutoLayoutMode,
|
||||
|
@ -223,10 +246,10 @@ impl GPUDevice {
|
|||
fn parse_render_pipeline(
|
||||
&self,
|
||||
descriptor: &GPURenderPipelineDescriptor,
|
||||
) -> (
|
||||
) -> Fallible<(
|
||||
Option<(PipelineLayoutId, Vec<BindGroupLayoutId>)>,
|
||||
RenderPipelineDescriptor<'static>,
|
||||
) {
|
||||
)> {
|
||||
let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout);
|
||||
|
||||
let desc = wgpu_pipe::RenderPipelineDescriptor {
|
||||
|
@ -236,7 +259,12 @@ impl GPUDevice {
|
|||
vertex: wgpu_pipe::VertexState {
|
||||
stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||
module: descriptor.vertex.parent.module.id().0,
|
||||
entry_point: Some(Cow::Owned(descriptor.vertex.parent.entryPoint.to_string())),
|
||||
entry_point: descriptor
|
||||
.vertex
|
||||
.parent
|
||||
.entryPoint
|
||||
.as_ref()
|
||||
.map(|ep| Cow::Owned(ep.to_string())),
|
||||
constants: Cow::Owned(HashMap::new()),
|
||||
zero_initialize_workgroup_memory: true,
|
||||
},
|
||||
|
@ -269,59 +297,88 @@ impl GPUDevice {
|
|||
fragment: descriptor
|
||||
.fragment
|
||||
.as_ref()
|
||||
.map(|stage| wgpu_pipe::FragmentState {
|
||||
stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||
module: stage.parent.module.id().0,
|
||||
entry_point: Some(Cow::Owned(stage.parent.entryPoint.to_string())),
|
||||
constants: Cow::Owned(HashMap::new()),
|
||||
zero_initialize_workgroup_memory: true,
|
||||
},
|
||||
targets: Cow::Owned(
|
||||
stage
|
||||
.targets
|
||||
.iter()
|
||||
.map(|state| {
|
||||
Some(wgt::ColorTargetState {
|
||||
format: convert_texture_format(state.format),
|
||||
write_mask: wgt::ColorWrites::from_bits_retain(state.writeMask),
|
||||
blend: state.blend.as_ref().map(|blend| wgt::BlendState {
|
||||
color: convert_blend_component(&blend.color),
|
||||
alpha: convert_blend_component(&blend.alpha),
|
||||
}),
|
||||
.map(|stage| -> Fallible<wgpu_pipe::FragmentState> {
|
||||
Ok(wgpu_pipe::FragmentState {
|
||||
stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||
module: stage.parent.module.id().0,
|
||||
entry_point: stage
|
||||
.parent
|
||||
.entryPoint
|
||||
.as_ref()
|
||||
.map(|ep| Cow::Owned(ep.to_string())),
|
||||
constants: Cow::Owned(HashMap::new()),
|
||||
zero_initialize_workgroup_memory: true,
|
||||
},
|
||||
targets: Cow::Owned(
|
||||
stage
|
||||
.targets
|
||||
.iter()
|
||||
.map(|state| {
|
||||
self.validate_texture_format_required_features(&state.format)
|
||||
.map(|format| {
|
||||
Some(wgt::ColorTargetState {
|
||||
format,
|
||||
write_mask: wgt::ColorWrites::from_bits_retain(
|
||||
state.writeMask,
|
||||
),
|
||||
blend: state.blend.as_ref().map(|blend| {
|
||||
wgt::BlendState {
|
||||
color: convert_blend_component(
|
||||
&blend.color,
|
||||
),
|
||||
alpha: convert_blend_component(
|
||||
&blend.alpha,
|
||||
),
|
||||
}
|
||||
}),
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
}),
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
),
|
||||
})
|
||||
})
|
||||
.transpose()?,
|
||||
primitive: convert_primitive_state(&descriptor.primitive),
|
||||
depth_stencil: descriptor.depthStencil.as_ref().map(|dss_desc| {
|
||||
wgt::DepthStencilState {
|
||||
format: convert_texture_format(dss_desc.format),
|
||||
depth_write_enabled: dss_desc.depthWriteEnabled,
|
||||
depth_compare: convert_compare_function(dss_desc.depthCompare),
|
||||
stencil: wgt::StencilState {
|
||||
front: wgt::StencilFaceState {
|
||||
compare: convert_compare_function(dss_desc.stencilFront.compare),
|
||||
fail_op: convert_stencil_op(dss_desc.stencilFront.failOp),
|
||||
depth_fail_op: convert_stencil_op(dss_desc.stencilFront.depthFailOp),
|
||||
pass_op: convert_stencil_op(dss_desc.stencilFront.passOp),
|
||||
},
|
||||
back: wgt::StencilFaceState {
|
||||
compare: convert_compare_function(dss_desc.stencilBack.compare),
|
||||
fail_op: convert_stencil_op(dss_desc.stencilBack.failOp),
|
||||
depth_fail_op: convert_stencil_op(dss_desc.stencilBack.depthFailOp),
|
||||
pass_op: convert_stencil_op(dss_desc.stencilBack.passOp),
|
||||
},
|
||||
read_mask: dss_desc.stencilReadMask,
|
||||
write_mask: dss_desc.stencilWriteMask,
|
||||
},
|
||||
bias: wgt::DepthBiasState {
|
||||
constant: dss_desc.depthBias,
|
||||
slope_scale: *dss_desc.depthBiasSlopeScale,
|
||||
clamp: *dss_desc.depthBiasClamp,
|
||||
},
|
||||
}
|
||||
}),
|
||||
depth_stencil: descriptor
|
||||
.depthStencil
|
||||
.as_ref()
|
||||
.map(|dss_desc| {
|
||||
self.validate_texture_format_required_features(&dss_desc.format)
|
||||
.map(|format| wgt::DepthStencilState {
|
||||
format,
|
||||
depth_write_enabled: dss_desc.depthWriteEnabled,
|
||||
depth_compare: convert_compare_function(dss_desc.depthCompare),
|
||||
stencil: wgt::StencilState {
|
||||
front: wgt::StencilFaceState {
|
||||
compare: convert_compare_function(
|
||||
dss_desc.stencilFront.compare,
|
||||
),
|
||||
fail_op: convert_stencil_op(dss_desc.stencilFront.failOp),
|
||||
depth_fail_op: convert_stencil_op(
|
||||
dss_desc.stencilFront.depthFailOp,
|
||||
),
|
||||
pass_op: convert_stencil_op(dss_desc.stencilFront.passOp),
|
||||
},
|
||||
back: wgt::StencilFaceState {
|
||||
compare: convert_compare_function(dss_desc.stencilBack.compare),
|
||||
fail_op: convert_stencil_op(dss_desc.stencilBack.failOp),
|
||||
depth_fail_op: convert_stencil_op(
|
||||
dss_desc.stencilBack.depthFailOp,
|
||||
),
|
||||
pass_op: convert_stencil_op(dss_desc.stencilBack.passOp),
|
||||
},
|
||||
read_mask: dss_desc.stencilReadMask,
|
||||
write_mask: dss_desc.stencilWriteMask,
|
||||
},
|
||||
bias: wgt::DepthBiasState {
|
||||
constant: dss_desc.depthBias,
|
||||
slope_scale: *dss_desc.depthBiasSlopeScale,
|
||||
clamp: *dss_desc.depthBiasClamp,
|
||||
},
|
||||
})
|
||||
})
|
||||
.transpose()?,
|
||||
multisample: wgt::MultisampleState {
|
||||
count: descriptor.multisample.count,
|
||||
mask: descriptor.multisample.mask as u64,
|
||||
|
@ -329,7 +386,7 @@ impl GPUDevice {
|
|||
},
|
||||
multiview: None,
|
||||
};
|
||||
(implicit_ids, desc)
|
||||
Ok((implicit_ids, desc))
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#lose-the-device>
|
||||
|
@ -420,7 +477,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
state,
|
||||
descriptor.size,
|
||||
map_info,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -429,7 +486,8 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
fn CreateBindGroupLayout(
|
||||
&self,
|
||||
descriptor: &GPUBindGroupLayoutDescriptor,
|
||||
) -> DomRoot<GPUBindGroupLayout> {
|
||||
) -> Fallible<DomRoot<GPUBindGroupLayout>> {
|
||||
// TODO(sagudev): pass invalid bits to wgpu
|
||||
let mut valid = true;
|
||||
let entries = descriptor
|
||||
.entries
|
||||
|
@ -471,7 +529,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
wgt::StorageTextureAccess::WriteOnly
|
||||
},
|
||||
},
|
||||
format: convert_texture_format(storage.format),
|
||||
format: self.validate_texture_format_required_features(&storage.format)?,
|
||||
view_dimension: convert_view_dimension(storage.viewDimension),
|
||||
}
|
||||
} else if let Some(texture) = &bind.texture {
|
||||
|
@ -495,14 +553,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
todo!("Handle error");
|
||||
};
|
||||
|
||||
wgt::BindGroupLayoutEntry {
|
||||
Ok(wgt::BindGroupLayoutEntry {
|
||||
binding: bind.binding,
|
||||
visibility,
|
||||
ty,
|
||||
count: None,
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect::<Fallible<Vec<_>>>()?;
|
||||
|
||||
let desc = if valid {
|
||||
Some(wgpu_bind::BindGroupLayoutDescriptor {
|
||||
|
@ -531,12 +589,12 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id);
|
||||
|
||||
GPUBindGroupLayout::new(
|
||||
Ok(GPUBindGroupLayout::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
bgl,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
descriptor.parent.label.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
|
||||
|
@ -579,7 +637,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
&self.global(),
|
||||
self.channel.clone(),
|
||||
pipeline_layout,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
bgls,
|
||||
)
|
||||
}
|
||||
|
@ -636,7 +694,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
bind_group,
|
||||
self.device,
|
||||
&descriptor.layout,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -655,7 +713,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
&self.global(),
|
||||
self.channel.clone(),
|
||||
webgpu::WebGPUShaderModule(program_id),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
promise.clone(),
|
||||
);
|
||||
let sender = response_async(&promise, &*shader_module);
|
||||
|
@ -689,7 +747,11 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
layout,
|
||||
stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||
module: descriptor.compute.module.id().0,
|
||||
entry_point: Some(Cow::Owned(descriptor.compute.entryPoint.to_string())),
|
||||
entry_point: descriptor
|
||||
.compute
|
||||
.entryPoint
|
||||
.as_ref()
|
||||
.map(|ep| Cow::Owned(ep.to_string())),
|
||||
constants: Cow::Owned(HashMap::new()),
|
||||
zero_initialize_workgroup_memory: true,
|
||||
},
|
||||
|
@ -711,7 +773,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
GPUComputePipeline::new(
|
||||
&self.global(),
|
||||
compute_pipeline,
|
||||
descriptor.parent.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.parent.label.clone(),
|
||||
self,
|
||||
)
|
||||
}
|
||||
|
@ -736,7 +798,11 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
layout,
|
||||
stage: wgpu_pipe::ProgrammableStageDescriptor {
|
||||
module: descriptor.compute.module.id().0,
|
||||
entry_point: Some(Cow::Owned(descriptor.compute.entryPoint.to_string())),
|
||||
entry_point: descriptor
|
||||
.compute
|
||||
.entryPoint
|
||||
.as_ref()
|
||||
.map(|ep| Cow::Owned(ep.to_string())),
|
||||
constants: Cow::Owned(HashMap::new()),
|
||||
zero_initialize_workgroup_memory: true,
|
||||
},
|
||||
|
@ -781,33 +847,37 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
self.channel.clone(),
|
||||
self,
|
||||
encoder,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
|
||||
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> {
|
||||
// TODO(sagudev): This should be https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuextent3d-shape
|
||||
let size = convert_texture_size_to_dict(&descriptor.size);
|
||||
let desc = wgt::TextureUsages::from_bits(descriptor.usage).map(|usg| {
|
||||
wgpu_res::TextureDescriptor {
|
||||
label: convert_label(&descriptor.parent),
|
||||
size: convert_texture_size_to_wgt(&size),
|
||||
mip_level_count: descriptor.mipLevelCount,
|
||||
sample_count: descriptor.sampleCount,
|
||||
dimension: match descriptor.dimension {
|
||||
GPUTextureDimension::_1d => wgt::TextureDimension::D1,
|
||||
GPUTextureDimension::_2d => wgt::TextureDimension::D2,
|
||||
GPUTextureDimension::_3d => wgt::TextureDimension::D3,
|
||||
},
|
||||
format: convert_texture_format(descriptor.format),
|
||||
usage: usg,
|
||||
view_formats: descriptor
|
||||
.viewFormats
|
||||
.iter()
|
||||
.map(|tf| convert_texture_format(*tf))
|
||||
.collect(),
|
||||
}
|
||||
});
|
||||
// TODO(sagudev): We should pass invalid bits to wgpu
|
||||
let desc = wgt::TextureUsages::from_bits(descriptor.usage)
|
||||
.map(|usg| -> Fallible<_> {
|
||||
Ok(wgpu_res::TextureDescriptor {
|
||||
label: convert_label(&descriptor.parent),
|
||||
size: convert_texture_size_to_wgt(&size),
|
||||
mip_level_count: descriptor.mipLevelCount,
|
||||
sample_count: descriptor.sampleCount,
|
||||
dimension: match descriptor.dimension {
|
||||
GPUTextureDimension::_1d => wgt::TextureDimension::D1,
|
||||
GPUTextureDimension::_2d => wgt::TextureDimension::D2,
|
||||
GPUTextureDimension::_3d => wgt::TextureDimension::D3,
|
||||
},
|
||||
format: self.validate_texture_format_required_features(&descriptor.format)?,
|
||||
usage: usg,
|
||||
view_formats: descriptor
|
||||
.viewFormats
|
||||
.iter()
|
||||
.map(|tf| self.validate_texture_format_required_features(tf))
|
||||
.collect::<Fallible<_>>()?,
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let texture_id = self
|
||||
.global()
|
||||
|
@ -839,7 +909,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
descriptor.dimension,
|
||||
descriptor.format,
|
||||
descriptor.usage,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -884,7 +954,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
self.device,
|
||||
compare_enable,
|
||||
sampler,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -892,8 +962,8 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
fn CreateRenderPipeline(
|
||||
&self,
|
||||
descriptor: &GPURenderPipelineDescriptor,
|
||||
) -> DomRoot<GPURenderPipeline> {
|
||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor);
|
||||
) -> Fallible<DomRoot<GPURenderPipeline>> {
|
||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
||||
|
||||
let render_pipeline_id = self
|
||||
.global()
|
||||
|
@ -913,12 +983,12 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id);
|
||||
|
||||
GPURenderPipeline::new(
|
||||
Ok(GPURenderPipeline::new(
|
||||
&self.global(),
|
||||
render_pipeline,
|
||||
descriptor.parent.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.parent.label.clone(),
|
||||
self,
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipelineasync>
|
||||
|
@ -926,10 +996,10 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
&self,
|
||||
descriptor: &GPURenderPipelineDescriptor,
|
||||
comp: InRealm,
|
||||
) -> Rc<Promise> {
|
||||
let promise = Promise::new_in_current_realm(comp);
|
||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor);
|
||||
) -> Fallible<Rc<Promise>> {
|
||||
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
|
||||
|
||||
let promise = Promise::new_in_current_realm(comp);
|
||||
let sender = response_async(&promise, self);
|
||||
|
||||
let render_pipeline_id = self
|
||||
|
@ -948,14 +1018,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
})
|
||||
.expect("Failed to create WebGPU render pipeline");
|
||||
|
||||
promise
|
||||
Ok(promise)
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderbundleencoder>
|
||||
fn CreateRenderBundleEncoder(
|
||||
&self,
|
||||
descriptor: &GPURenderBundleEncoderDescriptor,
|
||||
) -> DomRoot<GPURenderBundleEncoder> {
|
||||
) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
|
||||
let desc = wgpu_com::RenderBundleEncoderDescriptor {
|
||||
label: convert_label(&descriptor.parent.parent),
|
||||
color_formats: Cow::Owned(
|
||||
|
@ -963,16 +1033,24 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
.parent
|
||||
.colorFormats
|
||||
.iter()
|
||||
.map(|f| Some(convert_texture_format(*f)))
|
||||
.collect::<Vec<_>>(),
|
||||
.map(|format| {
|
||||
self.validate_texture_format_required_features(format)
|
||||
.map(|f| Some(f))
|
||||
})
|
||||
.collect::<Fallible<Vec<_>>>()?,
|
||||
),
|
||||
depth_stencil: descriptor.parent.depthStencilFormat.map(|dsf| {
|
||||
wgt::RenderBundleDepthStencil {
|
||||
format: convert_texture_format(dsf),
|
||||
depth_read_only: descriptor.depthReadOnly,
|
||||
stencil_read_only: descriptor.stencilReadOnly,
|
||||
}
|
||||
}),
|
||||
depth_stencil: descriptor
|
||||
.parent
|
||||
.depthStencilFormat
|
||||
.map(|dsf| {
|
||||
self.validate_texture_format_required_features(&dsf)
|
||||
.map(|format| wgt::RenderBundleDepthStencil {
|
||||
format,
|
||||
depth_read_only: descriptor.depthReadOnly,
|
||||
stencil_read_only: descriptor.stencilReadOnly,
|
||||
})
|
||||
})
|
||||
.transpose()?,
|
||||
sample_count: descriptor.parent.sampleCount,
|
||||
multiview: None,
|
||||
};
|
||||
|
@ -981,13 +1059,13 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let render_bundle_encoder =
|
||||
wgpu_com::RenderBundleEncoder::new(&desc, self.device.0, None).unwrap();
|
||||
|
||||
GPURenderBundleEncoder::new(
|
||||
Ok(GPURenderBundleEncoder::new(
|
||||
&self.global(),
|
||||
render_bundle_encoder,
|
||||
self,
|
||||
self.channel.clone(),
|
||||
descriptor.parent.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
descriptor.parent.parent.label.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope>
|
||||
|
|
|
@ -222,7 +222,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
|||
render_bundle,
|
||||
self.device.id(),
|
||||
self.channel.clone(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
descriptor.parent.label.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::str::FromStr;
|
|||
use dom_struct::dom_struct;
|
||||
use indexmap::IndexSet;
|
||||
use js::rust::HandleObject;
|
||||
use webgpu::wgt;
|
||||
use webgpu::wgt::Features;
|
||||
|
||||
use super::bindings::like::Setlike;
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
|
@ -39,43 +39,66 @@ pub struct GPUSupportedFeatures {
|
|||
// internal storage for features
|
||||
#[custom_trace]
|
||||
internal: DomRefCell<IndexSet<GPUFeatureName>>,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-types"]
|
||||
#[no_trace]
|
||||
features: Features,
|
||||
}
|
||||
|
||||
impl GPUSupportedFeatures {
|
||||
fn new(
|
||||
global: &GlobalScope,
|
||||
proto: Option<HandleObject>,
|
||||
features: wgt::Features,
|
||||
features: Features,
|
||||
) -> DomRoot<GPUSupportedFeatures> {
|
||||
let mut set = IndexSet::new();
|
||||
if features.contains(wgt::Features::DEPTH_CLIP_CONTROL) {
|
||||
if features.contains(Features::DEPTH_CLIP_CONTROL) {
|
||||
set.insert(GPUFeatureName::Depth_clip_control);
|
||||
}
|
||||
if features.contains(wgt::Features::DEPTH32FLOAT_STENCIL8) {
|
||||
if features.contains(Features::DEPTH32FLOAT_STENCIL8) {
|
||||
set.insert(GPUFeatureName::Depth32float_stencil8);
|
||||
}
|
||||
if features.contains(wgt::Features::PIPELINE_STATISTICS_QUERY) {
|
||||
set.insert(GPUFeatureName::Pipeline_statistics_query);
|
||||
}
|
||||
if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) {
|
||||
if features.contains(Features::TEXTURE_COMPRESSION_BC) {
|
||||
set.insert(GPUFeatureName::Texture_compression_bc);
|
||||
}
|
||||
if features.contains(wgt::Features::TEXTURE_COMPRESSION_ETC2) {
|
||||
// TODO: texture-compression-bc-sliced-3d when wgpu supports it
|
||||
if features.contains(Features::TEXTURE_COMPRESSION_ETC2) {
|
||||
set.insert(GPUFeatureName::Texture_compression_etc2);
|
||||
}
|
||||
if features.contains(wgt::Features::TEXTURE_COMPRESSION_ASTC) {
|
||||
if features.contains(Features::TEXTURE_COMPRESSION_ASTC) {
|
||||
set.insert(GPUFeatureName::Texture_compression_astc);
|
||||
}
|
||||
if features.contains(wgt::Features::TIMESTAMP_QUERY) {
|
||||
if features.contains(Features::TIMESTAMP_QUERY) {
|
||||
set.insert(GPUFeatureName::Timestamp_query);
|
||||
}
|
||||
if features.contains(wgt::Features::INDIRECT_FIRST_INSTANCE) {
|
||||
if features.contains(Features::INDIRECT_FIRST_INSTANCE) {
|
||||
set.insert(GPUFeatureName::Indirect_first_instance);
|
||||
}
|
||||
// While this feature exists in wgpu, it's not supported by naga yet
|
||||
// https://github.com/gfx-rs/wgpu/issues/4384
|
||||
/*
|
||||
if features.contains(Features::SHADER_F16) {
|
||||
set.insert(GPUFeatureName::Shader_f16);
|
||||
}
|
||||
*/
|
||||
if features.contains(Features::RG11B10UFLOAT_RENDERABLE) {
|
||||
set.insert(GPUFeatureName::Rg11b10ufloat_renderable);
|
||||
}
|
||||
if features.contains(Features::BGRA8UNORM_STORAGE) {
|
||||
set.insert(GPUFeatureName::Bgra8unorm_storage);
|
||||
}
|
||||
if features.contains(Features::FLOAT32_FILTERABLE) {
|
||||
set.insert(GPUFeatureName::Float32_filterable);
|
||||
}
|
||||
// TODO: clip-distances when wgpu supports it
|
||||
if features.contains(Features::DUAL_SOURCE_BLENDING) {
|
||||
set.insert(GPUFeatureName::Dual_source_blending);
|
||||
}
|
||||
|
||||
reflect_dom_object_with_proto(
|
||||
Box::new(GPUSupportedFeatures {
|
||||
reflector: Reflector::new(),
|
||||
internal: DomRefCell::new(set),
|
||||
features,
|
||||
}),
|
||||
global,
|
||||
proto,
|
||||
|
@ -86,29 +109,42 @@ impl GPUSupportedFeatures {
|
|||
pub fn Constructor(
|
||||
global: &GlobalScope,
|
||||
proto: Option<HandleObject>,
|
||||
features: wgt::Features,
|
||||
features: Features,
|
||||
) -> Fallible<DomRoot<GPUSupportedFeatures>> {
|
||||
Ok(GPUSupportedFeatures::new(global, proto, features))
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUSupportedFeatures {
|
||||
pub fn wgpu_features(&self) -> Features {
|
||||
self.features
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUSupportedFeaturesMethods for GPUSupportedFeatures {
|
||||
fn Size(&self) -> u32 {
|
||||
self.internal.size()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gpu_to_wgt_feature(feature: GPUFeatureName) -> Option<wgt::Features> {
|
||||
pub fn gpu_to_wgt_feature(feature: GPUFeatureName) -> Option<Features> {
|
||||
match feature {
|
||||
GPUFeatureName::Depth_clip_control => Some(wgt::Features::DEPTH_CLIP_CONTROL),
|
||||
GPUFeatureName::Depth24unorm_stencil8 => None,
|
||||
GPUFeatureName::Depth32float_stencil8 => Some(wgt::Features::DEPTH32FLOAT_STENCIL8),
|
||||
GPUFeatureName::Pipeline_statistics_query => Some(wgt::Features::PIPELINE_STATISTICS_QUERY),
|
||||
GPUFeatureName::Texture_compression_bc => Some(wgt::Features::TEXTURE_COMPRESSION_BC),
|
||||
GPUFeatureName::Texture_compression_etc2 => Some(wgt::Features::TEXTURE_COMPRESSION_ETC2),
|
||||
GPUFeatureName::Texture_compression_astc => Some(wgt::Features::TEXTURE_COMPRESSION_ASTC),
|
||||
GPUFeatureName::Timestamp_query => Some(wgt::Features::TIMESTAMP_QUERY),
|
||||
GPUFeatureName::Indirect_first_instance => Some(wgt::Features::INDIRECT_FIRST_INSTANCE),
|
||||
GPUFeatureName::Depth_clip_control => Some(Features::DEPTH_CLIP_CONTROL),
|
||||
GPUFeatureName::Depth32float_stencil8 => Some(Features::DEPTH32FLOAT_STENCIL8),
|
||||
GPUFeatureName::Texture_compression_bc => Some(Features::TEXTURE_COMPRESSION_BC),
|
||||
GPUFeatureName::Texture_compression_etc2 => Some(Features::TEXTURE_COMPRESSION_ETC2),
|
||||
GPUFeatureName::Texture_compression_astc => Some(Features::TEXTURE_COMPRESSION_ASTC),
|
||||
GPUFeatureName::Timestamp_query => Some(Features::TIMESTAMP_QUERY),
|
||||
GPUFeatureName::Indirect_first_instance => Some(Features::INDIRECT_FIRST_INSTANCE),
|
||||
// While this feature exists in wgpu, it's not supported by naga yet
|
||||
// https://github.com/gfx-rs/wgpu/issues/4384
|
||||
GPUFeatureName::Shader_f16 => None,
|
||||
GPUFeatureName::Rg11b10ufloat_renderable => Some(Features::RG11B10UFLOAT_RENDERABLE),
|
||||
GPUFeatureName::Bgra8unorm_storage => Some(Features::BGRA8UNORM_STORAGE),
|
||||
GPUFeatureName::Float32_filterable => Some(Features::FLOAT32_FILTERABLE),
|
||||
GPUFeatureName::Dual_source_blending => Some(Features::DUAL_SOURCE_BLENDING),
|
||||
GPUFeatureName::Texture_compression_bc_sliced_3d => None,
|
||||
GPUFeatureName::Clip_distances => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use dom_struct::dom_struct;
|
|||
use webgpu::wgc::resource;
|
||||
use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView};
|
||||
|
||||
use super::bindings::error::Fallible;
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||
GPUExtent3DDict, GPUTextureAspect, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods,
|
||||
|
@ -18,9 +19,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
|||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpuconvert::{
|
||||
convert_label, convert_texture_format, convert_texture_view_dimension,
|
||||
};
|
||||
use crate::dom::gpuconvert::{convert_label, convert_texture_view_dimension};
|
||||
use crate::dom::gpudevice::GPUDevice;
|
||||
use crate::dom::gputextureview::GPUTextureView;
|
||||
|
||||
|
@ -142,13 +141,19 @@ impl GPUTextureMethods for GPUTexture {
|
|||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-createview>
|
||||
fn CreateView(&self, descriptor: &GPUTextureViewDescriptor) -> DomRoot<GPUTextureView> {
|
||||
fn CreateView(
|
||||
&self,
|
||||
descriptor: &GPUTextureViewDescriptor,
|
||||
) -> Fallible<DomRoot<GPUTextureView>> {
|
||||
let desc = if !matches!(descriptor.mipLevelCount, Some(0)) &&
|
||||
!matches!(descriptor.arrayLayerCount, Some(0))
|
||||
{
|
||||
Some(resource::TextureViewDescriptor {
|
||||
label: convert_label(&descriptor.parent),
|
||||
format: descriptor.format.map(convert_texture_format),
|
||||
format: descriptor
|
||||
.format
|
||||
.map(|f| self.device.validate_texture_format_required_features(&f))
|
||||
.transpose()?,
|
||||
dimension: descriptor.dimension.map(convert_texture_view_dimension),
|
||||
range: wgt::ImageSubresourceRange {
|
||||
aspect: match descriptor.aspect {
|
||||
|
@ -187,13 +192,13 @@ impl GPUTextureMethods for GPUTexture {
|
|||
|
||||
let texture_view = WebGPUTextureView(texture_view_id);
|
||||
|
||||
GPUTextureView::new(
|
||||
Ok(GPUTextureView::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
texture_view,
|
||||
self,
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
descriptor.parent.label.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-destroy>
|
||||
|
@ -212,4 +217,44 @@ impl GPUTextureMethods for GPUTexture {
|
|||
};
|
||||
self.destroyed.set(true);
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-width>
|
||||
fn Width(&self) -> u32 {
|
||||
self.texture_size.width
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-height>
|
||||
fn Height(&self) -> u32 {
|
||||
self.texture_size.height
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-depthorarraylayers>
|
||||
fn DepthOrArrayLayers(&self) -> u32 {
|
||||
self.texture_size.depthOrArrayLayers
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-miplevelcount>
|
||||
fn MipLevelCount(&self) -> u32 {
|
||||
self.mip_level_count
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-samplecount>
|
||||
fn SampleCount(&self) -> u32 {
|
||||
self.sample_count
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-dimension>
|
||||
fn Dimension(&self) -> GPUTextureDimension {
|
||||
self.dimension
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-format>
|
||||
fn Format(&self) -> GPUTextureFormat {
|
||||
self.format
|
||||
}
|
||||
|
||||
/// <https://gpuweb.github.io/gpuweb/#dom-gputexture-usage>
|
||||
fn Usage(&self) -> u32 {
|
||||
self.texture_usage
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ interface mixin GPUObjectBase {
|
|||
};
|
||||
|
||||
dictionary GPUObjectDescriptorBase {
|
||||
USVString label;
|
||||
USVString label = "";
|
||||
};
|
||||
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
|
@ -100,21 +100,26 @@ interface GPUAdapter {
|
|||
Promise<GPUAdapterInfo> requestAdapterInfo(optional sequence<DOMString> unmaskHints = []);
|
||||
};
|
||||
|
||||
dictionary GPUDeviceDescriptor {
|
||||
dictionary GPUDeviceDescriptor: GPUObjectDescriptorBase {
|
||||
sequence<GPUFeatureName> requiredFeatures = [];
|
||||
record<DOMString, GPUSize64> requiredLimits;
|
||||
record<DOMString, GPUSize64> requiredLimits;// = {};
|
||||
};
|
||||
|
||||
enum GPUFeatureName {
|
||||
"depth-clip-control",
|
||||
"depth24unorm-stencil8",
|
||||
"depth32float-stencil8",
|
||||
"pipeline-statistics-query",
|
||||
"texture-compression-bc",
|
||||
"texture-compression-bc-sliced-3d",
|
||||
"texture-compression-etc2",
|
||||
"texture-compression-astc",
|
||||
"timestamp-query",
|
||||
"indirect-first-instance",
|
||||
"shader-f16",
|
||||
"rg11b10ufloat-renderable",
|
||||
"bgra8unorm-storage",
|
||||
"float32-filterable",
|
||||
"clip-distances",
|
||||
"dual-source-blending",
|
||||
};
|
||||
|
||||
[Exposed=(Window, DedicatedWorker), /*Serializable,*/ Pref="dom.webgpu.enabled"]
|
||||
|
@ -134,22 +139,24 @@ interface GPUDevice: EventTarget {
|
|||
[NewObject]
|
||||
GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
|
||||
|
||||
[Throws]
|
||||
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
|
||||
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
|
||||
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);
|
||||
|
||||
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
|
||||
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
|
||||
[Throws]
|
||||
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
|
||||
|
||||
[NewObject]
|
||||
Promise<GPUComputePipeline> createComputePipelineAsync(GPUComputePipelineDescriptor descriptor);
|
||||
[NewObject]
|
||||
[Throws, NewObject]
|
||||
Promise<GPURenderPipeline> createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor);
|
||||
|
||||
[NewObject]
|
||||
GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {});
|
||||
[NewObject]
|
||||
[Throws, NewObject]
|
||||
GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor);
|
||||
//[NewObject]
|
||||
//GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor);
|
||||
|
@ -199,10 +206,19 @@ interface GPUMapMode {
|
|||
|
||||
[Exposed=(Window, DedicatedWorker), Serializable , Pref="dom.webgpu.enabled"]
|
||||
interface GPUTexture {
|
||||
[NewObject]
|
||||
[Throws, NewObject]
|
||||
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
|
||||
|
||||
undefined destroy();
|
||||
|
||||
readonly attribute GPUIntegerCoordinateOut width;
|
||||
readonly attribute GPUIntegerCoordinateOut height;
|
||||
readonly attribute GPUIntegerCoordinateOut depthOrArrayLayers;
|
||||
readonly attribute GPUIntegerCoordinateOut mipLevelCount;
|
||||
readonly attribute GPUSize32Out sampleCount;
|
||||
readonly attribute GPUTextureDimension dimension;
|
||||
readonly attribute GPUTextureFormat format;
|
||||
readonly attribute GPUFlagsConstant usage;
|
||||
};
|
||||
GPUTexture includes GPUObjectBase;
|
||||
|
||||
|
@ -293,8 +309,10 @@ enum GPUTextureFormat {
|
|||
"bgra8unorm",
|
||||
"bgra8unorm-srgb",
|
||||
// Packed 32-bit formats
|
||||
"rgb9e5ufloat",
|
||||
"rgb10a2uint",
|
||||
"rgb10a2unorm",
|
||||
"rg11b10float",
|
||||
"rg11b10ufloat",
|
||||
|
||||
// 64-bit formats
|
||||
"rg32uint",
|
||||
|
@ -309,13 +327,16 @@ enum GPUTextureFormat {
|
|||
"rgba32sint",
|
||||
"rgba32float",
|
||||
|
||||
// Depth and stencil formats
|
||||
//"stencil8", //TODO
|
||||
//"depth16unorm",
|
||||
// Depth/stencil formats
|
||||
"stencil8",
|
||||
"depth16unorm",
|
||||
"depth24plus",
|
||||
"depth24plus-stencil8",
|
||||
"depth32float",
|
||||
|
||||
// "depth32float-stencil8" feature
|
||||
"depth32float-stencil8",
|
||||
|
||||
// BC compressed formats usable if "texture-compression-bc" is both
|
||||
// supported by the device/user agent and enabled in requestDevice.
|
||||
"bc1-rgba-unorm",
|
||||
|
@ -333,11 +354,49 @@ enum GPUTextureFormat {
|
|||
"bc7-rgba-unorm",
|
||||
"bc7-rgba-unorm-srgb",
|
||||
|
||||
// "depth24unorm-stencil8" feature
|
||||
//"depth24unorm-stencil8",
|
||||
// ETC2 compressed formats usable if "texture-compression-etc2" is both
|
||||
// supported by the device/user agent and enabled in requestDevice.
|
||||
"etc2-rgb8unorm",
|
||||
"etc2-rgb8unorm-srgb",
|
||||
"etc2-rgb8a1unorm",
|
||||
"etc2-rgb8a1unorm-srgb",
|
||||
"etc2-rgba8unorm",
|
||||
"etc2-rgba8unorm-srgb",
|
||||
"eac-r11unorm",
|
||||
"eac-r11snorm",
|
||||
"eac-rg11unorm",
|
||||
"eac-rg11snorm",
|
||||
|
||||
// "depth32float-stencil8" feature
|
||||
//"depth32float-stencil8",
|
||||
// ASTC compressed formats usable if "texture-compression-astc" is both
|
||||
// supported by the device/user agent and enabled in requestDevice.
|
||||
"astc-4x4-unorm",
|
||||
"astc-4x4-unorm-srgb",
|
||||
"astc-5x4-unorm",
|
||||
"astc-5x4-unorm-srgb",
|
||||
"astc-5x5-unorm",
|
||||
"astc-5x5-unorm-srgb",
|
||||
"astc-6x5-unorm",
|
||||
"astc-6x5-unorm-srgb",
|
||||
"astc-6x6-unorm",
|
||||
"astc-6x6-unorm-srgb",
|
||||
"astc-8x5-unorm",
|
||||
"astc-8x5-unorm-srgb",
|
||||
"astc-8x6-unorm",
|
||||
"astc-8x6-unorm-srgb",
|
||||
"astc-8x8-unorm",
|
||||
"astc-8x8-unorm-srgb",
|
||||
"astc-10x5-unorm",
|
||||
"astc-10x5-unorm-srgb",
|
||||
"astc-10x6-unorm",
|
||||
"astc-10x6-unorm-srgb",
|
||||
"astc-10x8-unorm",
|
||||
"astc-10x8-unorm-srgb",
|
||||
"astc-10x10-unorm",
|
||||
"astc-10x10-unorm-srgb",
|
||||
"astc-12x10-unorm",
|
||||
"astc-12x10-unorm-srgb",
|
||||
"astc-12x12-unorm",
|
||||
"astc-12x12-unorm-srgb",
|
||||
};
|
||||
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
|
@ -547,7 +606,7 @@ interface mixin GPUPipelineBase {
|
|||
|
||||
dictionary GPUProgrammableStage {
|
||||
required GPUShaderModule module;
|
||||
required USVString entryPoint;
|
||||
USVString entryPoint;
|
||||
};
|
||||
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
|
@ -1160,6 +1219,12 @@ typedef [EnforceRange] unsigned long GPUIndex32;
|
|||
typedef [EnforceRange] unsigned long GPUSize32;
|
||||
typedef [EnforceRange] long GPUSignedOffset32;
|
||||
|
||||
typedef unsigned long long GPUSize64Out;
|
||||
typedef unsigned long GPUIntegerCoordinateOut;
|
||||
typedef unsigned long GPUSize32Out;
|
||||
|
||||
typedef unsigned long GPUFlagsConstant;
|
||||
|
||||
dictionary GPUColorDict {
|
||||
required double r;
|
||||
required double g;
|
||||
|
|
|
@ -101,7 +101,7 @@ def handle_preset(s: str) -> Optional[JobConfig]:
|
|||
elif s == "webgpu":
|
||||
return JobConfig("WebGPU CTS", Workflow.LINUX,
|
||||
wpt_layout=Layout.layout2020, # reftests are mode for new layout
|
||||
wpt_args="_webgpu", # run only webgpu cts
|
||||
wpt_args="--processes 1 _webgpu", # run only webgpu cts
|
||||
profile="production", # WebGPU works to slow with debug assert
|
||||
unit_tests=False) # production profile does not work with unit-tests
|
||||
else:
|
||||
|
|
5123
tests/wpt/webgpu/meta/webgpu/cts.https.html.ini
vendored
5123
tests/wpt/webgpu/meta/webgpu/cts.https.html.ini
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue