mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Upgrade whole webgpu stack (#29795)
* Allow noidl files in script/dom/webidls * Upgrade wgpu to 0.16 and refresh whole webgpu implementation * Update WebGPU test expectations * misc * MutNullableDom -> DomRefCell<Option<Dom for GPUTexture * Direct use of GPUTextureDescriptor * Remove config from GPUCanvasContext * misc * finally blue color * gpubuffer "handle" error * GPU object have non-null label * gpu limits and info * use buffer_size * fix warnings * Cleanup * device destroy * fallback adapter * mach update-webgpu write webgpu commit hash in file * Mising deps in CI for webgpu tests * Updated expectations * Fixups * early reject * DomRefCell<Option<Dom -> MutNullableDom for GPUTexture
This commit is contained in:
parent
fed3491f23
commit
71e0372ac1
96 changed files with 15612 additions and 4023 deletions
2
.github/workflows/linux-wpt.yml
vendored
2
.github/workflows/linux-wpt.yml
vendored
|
@ -55,7 +55,7 @@ jobs:
|
|||
run: |
|
||||
python3 -m pip install --upgrade pip virtualenv
|
||||
sudo apt update
|
||||
sudo apt install -qy --no-install-recommends libgl1 libssl1.1 libdbus-1-3 libxcb-xfixes0-dev libxcb-shape0-dev libunwind8 libegl1-mesa
|
||||
sudo apt install -qy --no-install-recommends libgl1 libssl1.1 libdbus-1-3 libxcb-xfixes0-dev libxcb-shape0-dev libunwind8 libgl1-mesa-dri mesa-vulkan-drivers libegl1-mesa
|
||||
sudo apt install ./libffi6_3.2.1-8_amd64.deb
|
||||
python3 ./mach bootstrap-gstreamer
|
||||
- name: Sync from upstream WPT
|
||||
|
|
635
Cargo.lock
generated
635
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -153,7 +153,7 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'GPUAdapter': {
|
||||
'inRealms': ['RequestDevice'],
|
||||
'inRealms': ['RequestDevice', 'RequestAdapterInfo'],
|
||||
},
|
||||
|
||||
'GPUBuffer': {
|
||||
|
@ -161,7 +161,7 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'GPUDevice': {
|
||||
'inRealms': ['PopErrorScope', 'Lost'],
|
||||
'inRealms': ['PopErrorScope', 'GetLost'],
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ use std::rc::Rc;
|
|||
use webgpu::wgt::PowerPreference;
|
||||
use webgpu::{wgpu, WebGPUResponse, WebGPUResponseResult};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUTextureBinding::GPUTextureFormat;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPU {
|
||||
reflector_: Reflector,
|
||||
|
@ -105,7 +107,7 @@ impl GPUMethods for GPU {
|
|||
let power_preference = match options.powerPreference {
|
||||
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,
|
||||
Some(GPUPowerPreference::High_performance) => PowerPreference::HighPerformance,
|
||||
None => PowerPreference::Default,
|
||||
None => PowerPreference::default(),
|
||||
};
|
||||
let ids = global.wgpu_id_hub().lock().create_adapter_ids();
|
||||
|
||||
|
@ -116,6 +118,7 @@ impl GPUMethods for GPU {
|
|||
wgpu::instance::RequestAdapterOptions {
|
||||
power_preference,
|
||||
compatible_surface: None,
|
||||
force_fallback_adapter: options.forceFallbackAdapter,
|
||||
},
|
||||
ids,
|
||||
))
|
||||
|
@ -125,21 +128,34 @@ impl GPUMethods for GPU {
|
|||
}
|
||||
promise
|
||||
}
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#dom-gpu-getpreferredcanvasformat
|
||||
fn GetPreferredCanvasFormat(&self) -> GPUTextureFormat {
|
||||
// TODO: real implementation
|
||||
GPUTextureFormat::Rgba8unorm
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWGPUListener for GPU {
|
||||
fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc<Promise>) {
|
||||
match response {
|
||||
Ok(WebGPUResponse::RequestAdapter {
|
||||
adapter_name,
|
||||
adapter_info,
|
||||
adapter_id,
|
||||
limits,
|
||||
channel,
|
||||
}) => {
|
||||
let adapter = GPUAdapter::new(
|
||||
&self.global(),
|
||||
channel,
|
||||
DOMString::from(format!("{} ({:?})", adapter_name, adapter_id.0.backend())),
|
||||
DOMString::from(format!(
|
||||
"{} ({:?})",
|
||||
adapter_info.name,
|
||||
adapter_id.0.backend()
|
||||
)),
|
||||
Heap::default(),
|
||||
limits,
|
||||
adapter_info,
|
||||
adapter_id,
|
||||
);
|
||||
promise.resolve_native(&adapter);
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::{
|
||||
GPUAdapterMethods, GPUDeviceDescriptor, GPUExtensionName, GPULimits,
|
||||
GPUAdapterMethods, GPUDeviceDescriptor, GPUFeatureName,
|
||||
};
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpu::response_async;
|
||||
|
@ -15,13 +15,14 @@ use crate::dom::gpu::AsyncWGPUListener;
|
|||
use crate::dom::gpudevice::GPUDevice;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use std::ptr::NonNull;
|
||||
use std::convert::TryFrom;
|
||||
use std::rc::Rc;
|
||||
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPUResponseResult};
|
||||
|
||||
use super::types::{GPUAdapterInfo, GPUSupportedLimits};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUAdapter {
|
||||
reflector_: Reflector,
|
||||
|
@ -31,6 +32,8 @@ pub struct GPUAdapter {
|
|||
name: DOMString,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
extensions: Heap<*mut JSObject>,
|
||||
limits: Dom<GPUSupportedLimits>,
|
||||
info: Dom<GPUAdapterInfo>,
|
||||
#[no_trace]
|
||||
adapter: WebGPUAdapter,
|
||||
}
|
||||
|
@ -40,6 +43,8 @@ impl GPUAdapter {
|
|||
channel: WebGPU,
|
||||
name: DOMString,
|
||||
extensions: Heap<*mut JSObject>,
|
||||
limits: &GPUSupportedLimits,
|
||||
info: &GPUAdapterInfo,
|
||||
adapter: WebGPUAdapter,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -47,6 +52,8 @@ impl GPUAdapter {
|
|||
channel,
|
||||
name,
|
||||
extensions,
|
||||
limits: Dom::from_ref(limits),
|
||||
info: Dom::from_ref(info),
|
||||
adapter,
|
||||
}
|
||||
}
|
||||
|
@ -56,11 +63,15 @@ impl GPUAdapter {
|
|||
channel: WebGPU,
|
||||
name: DOMString,
|
||||
extensions: Heap<*mut JSObject>,
|
||||
limits: wgt::Limits,
|
||||
info: wgt::AdapterInfo,
|
||||
adapter: WebGPUAdapter,
|
||||
) -> DomRoot<Self> {
|
||||
let limits = GPUSupportedLimits::new(global, limits);
|
||||
let info = GPUAdapterInfo::new(global, info);
|
||||
reflect_dom_object(
|
||||
Box::new(GPUAdapter::new_inherited(
|
||||
channel, name, extensions, adapter,
|
||||
channel, name, extensions, &limits, &info, adapter,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
|
@ -68,57 +79,116 @@ impl GPUAdapter {
|
|||
}
|
||||
|
||||
impl GPUAdapterMethods for GPUAdapter {
|
||||
// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-name
|
||||
fn Name(&self) -> DOMString {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-extensions
|
||||
fn Extensions(&self, _cx: SafeJSContext) -> NonNull<JSObject> {
|
||||
NonNull::new(self.extensions.get()).unwrap()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice
|
||||
fn RequestDevice(&self, descriptor: &GPUDeviceDescriptor, comp: InRealm) -> Rc<Promise> {
|
||||
// Step 2
|
||||
let promise = Promise::new_in_current_realm(comp);
|
||||
let sender = response_async(&promise, self);
|
||||
let mut features = wgt::Features::empty();
|
||||
for &ext in descriptor.extensions.iter() {
|
||||
if ext == GPUExtensionName::Depth_clamping {
|
||||
features.insert(wgt::Features::DEPTH_CLAMPING);
|
||||
} else if ext == GPUExtensionName::Texture_compression_bc {
|
||||
features.insert(wgt::Features::TEXTURE_COMPRESSION_BC)
|
||||
for &ext in descriptor.requiredFeatures.iter() {
|
||||
match ext {
|
||||
GPUFeatureName::Depth_clip_control => {
|
||||
features.insert(wgt::Features::DEPTH_CLIP_CONTROL)
|
||||
},
|
||||
GPUFeatureName::Depth24unorm_stencil8 => {
|
||||
promise.reject_error(Error::Type(String::from(
|
||||
"depth24unorm_stencil8 is not supported by wgpu",
|
||||
)));
|
||||
return promise;
|
||||
},
|
||||
GPUFeatureName::Depth32float_stencil8 => {
|
||||
features.insert(wgt::Features::DEPTH32FLOAT_STENCIL8)
|
||||
},
|
||||
GPUFeatureName::Pipeline_statistics_query => {
|
||||
features.insert(wgt::Features::PIPELINE_STATISTICS_QUERY)
|
||||
},
|
||||
GPUFeatureName::Texture_compression_bc => {
|
||||
features.insert(wgt::Features::TEXTURE_COMPRESSION_BC)
|
||||
},
|
||||
GPUFeatureName::Texture_compression_etc2 => {
|
||||
features.insert(wgt::Features::TEXTURE_COMPRESSION_ETC2)
|
||||
},
|
||||
GPUFeatureName::Texture_compression_astc => {
|
||||
features.insert(wgt::Features::TEXTURE_COMPRESSION_ASTC)
|
||||
},
|
||||
GPUFeatureName::Timestamp_query => features.insert(wgt::Features::TIMESTAMP_QUERY),
|
||||
GPUFeatureName::Indirect_first_instance => {
|
||||
features.insert(wgt::Features::INDIRECT_FIRST_INSTANCE)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let desc = wgt::DeviceDescriptor {
|
||||
let mut desc = wgt::DeviceDescriptor {
|
||||
features,
|
||||
limits: wgt::Limits {
|
||||
max_bind_groups: descriptor.limits.maxBindGroups,
|
||||
max_dynamic_uniform_buffers_per_pipeline_layout: descriptor
|
||||
.limits
|
||||
.maxDynamicUniformBuffersPerPipelineLayout,
|
||||
max_dynamic_storage_buffers_per_pipeline_layout: descriptor
|
||||
.limits
|
||||
.maxDynamicStorageBuffersPerPipelineLayout,
|
||||
max_sampled_textures_per_shader_stage: descriptor
|
||||
.limits
|
||||
.maxSampledTexturesPerShaderStage,
|
||||
max_samplers_per_shader_stage: descriptor.limits.maxSamplersPerShaderStage,
|
||||
max_storage_buffers_per_shader_stage: descriptor
|
||||
.limits
|
||||
.maxStorageBuffersPerShaderStage,
|
||||
max_storage_textures_per_shader_stage: descriptor
|
||||
.limits
|
||||
.maxStorageTexturesPerShaderStage,
|
||||
max_uniform_buffers_per_shader_stage: descriptor
|
||||
.limits
|
||||
.maxUniformBuffersPerShaderStage,
|
||||
max_uniform_buffer_binding_size: descriptor.limits.maxUniformBufferBindingSize,
|
||||
..Default::default()
|
||||
},
|
||||
shader_validation: true,
|
||||
limits: wgt::Limits::default(),
|
||||
label: None,
|
||||
};
|
||||
if let Some(lim) = &descriptor.requiredLimits {
|
||||
for (k, v) in (*lim).iter() {
|
||||
let v = u32::try_from(*v).unwrap_or(u32::MAX);
|
||||
match k.as_ref() {
|
||||
"maxTextureDimension1D" => desc.limits.max_texture_dimension_1d = v,
|
||||
"maxTextureDimension2D" => desc.limits.max_texture_dimension_2d = v,
|
||||
"maxTextureDimension3D" => desc.limits.max_texture_dimension_3d = v,
|
||||
"maxTextureArrayLayers" => desc.limits.max_texture_array_layers = v,
|
||||
"maxBindGroups" => desc.limits.max_bind_groups = v,
|
||||
"maxDynamicUniformBuffersPerPipelineLayout" => {
|
||||
desc.limits.max_dynamic_uniform_buffers_per_pipeline_layout = v
|
||||
},
|
||||
"maxDynamicStorageBuffersPerPipelineLayout" => {
|
||||
desc.limits.max_dynamic_storage_buffers_per_pipeline_layout = v
|
||||
},
|
||||
"maxSampledTexturesPerShaderStage" => {
|
||||
desc.limits.max_sampled_textures_per_shader_stage = v
|
||||
},
|
||||
"maxSamplersPerShaderStage" => desc.limits.max_samplers_per_shader_stage = v,
|
||||
"maxStorageBuffersPerShaderStage" => {
|
||||
desc.limits.max_storage_buffers_per_shader_stage = v
|
||||
},
|
||||
"maxStorageTexturesPerShaderStage" => {
|
||||
desc.limits.max_storage_textures_per_shader_stage = v
|
||||
},
|
||||
"maxUniformBuffersPerShaderStage" => {
|
||||
desc.limits.max_uniform_buffers_per_shader_stage = v
|
||||
},
|
||||
"maxUniformBufferBindingSize" => {
|
||||
desc.limits.max_uniform_buffer_binding_size = v
|
||||
},
|
||||
"maxStorageBufferBindingSize" => {
|
||||
desc.limits.max_storage_buffer_binding_size = v
|
||||
},
|
||||
"minUniformBufferOffsetAlignment" => {
|
||||
desc.limits.min_uniform_buffer_offset_alignment = v
|
||||
},
|
||||
"minStorageBufferOffsetAlignment" => {
|
||||
desc.limits.min_storage_buffer_offset_alignment = v
|
||||
},
|
||||
"maxVertexBuffers" => desc.limits.max_vertex_buffers = v,
|
||||
"maxVertexAttributes" => desc.limits.max_vertex_attributes = v,
|
||||
"maxVertexBufferArrayStride" => desc.limits.max_vertex_buffer_array_stride = v,
|
||||
"maxInterStageShaderComponents" => {
|
||||
desc.limits.max_inter_stage_shader_components = v
|
||||
},
|
||||
"maxComputeWorkgroupStorageSize" => {
|
||||
desc.limits.max_compute_workgroup_storage_size = v
|
||||
},
|
||||
"maxComputeInvocationsPerWorkgroup" => {
|
||||
desc.limits.max_compute_invocations_per_workgroup = v
|
||||
},
|
||||
"maxComputeWorkgroupSizeX" => desc.limits.max_compute_workgroup_size_x = v,
|
||||
"maxComputeWorkgroupSizeY" => desc.limits.max_compute_workgroup_size_y = v,
|
||||
"maxComputeWorkgroupSizeZ" => desc.limits.max_compute_workgroup_size_z = v,
|
||||
"maxComputeWorkgroupsPerDimension" => {
|
||||
desc.limits.max_compute_workgroups_per_dimension = v
|
||||
},
|
||||
_ => {
|
||||
error!("Unknown required limit: {k} with value {v}");
|
||||
promise.reject_error(Error::Operation);
|
||||
return promise;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
let id = self
|
||||
.global()
|
||||
.wgpu_id_hub()
|
||||
|
@ -136,15 +206,40 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
descriptor: desc,
|
||||
device_id: id,
|
||||
pipeline_id,
|
||||
label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
|
||||
},
|
||||
))
|
||||
.is_err()
|
||||
{
|
||||
promise.reject_error(Error::Operation);
|
||||
}
|
||||
// Step 5
|
||||
promise
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-isfallbackadapter
|
||||
fn IsFallbackAdapter(&self) -> bool {
|
||||
//TODO
|
||||
false
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestadapterinfo
|
||||
fn RequestAdapterInfo(&self, unmask_hints: Vec<DOMString>, comp: InRealm) -> Rc<Promise> {
|
||||
// XXX: Adapter info should be generated here ...
|
||||
// Step 1
|
||||
let promise = Promise::new_in_current_realm(comp);
|
||||
// Step 4
|
||||
if !unmask_hints.is_empty() {
|
||||
todo!("unmaskHints on RequestAdapterInfo");
|
||||
}
|
||||
promise.resolve_native(&*self.info);
|
||||
// Step 5
|
||||
promise
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-limits
|
||||
fn Limits(&self) -> DomRoot<GPUSupportedLimits> {
|
||||
DomRoot::from_ref(&self.limits)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUAdapter {
|
||||
|
@ -154,40 +249,16 @@ impl AsyncWGPUListener for GPUAdapter {
|
|||
device_id,
|
||||
queue_id,
|
||||
descriptor,
|
||||
label,
|
||||
}) => {
|
||||
let limits = GPULimits {
|
||||
maxBindGroups: descriptor.limits.max_bind_groups,
|
||||
maxDynamicStorageBuffersPerPipelineLayout: descriptor
|
||||
.limits
|
||||
.max_dynamic_storage_buffers_per_pipeline_layout,
|
||||
maxDynamicUniformBuffersPerPipelineLayout: descriptor
|
||||
.limits
|
||||
.max_dynamic_uniform_buffers_per_pipeline_layout,
|
||||
maxSampledTexturesPerShaderStage: descriptor
|
||||
.limits
|
||||
.max_sampled_textures_per_shader_stage,
|
||||
maxSamplersPerShaderStage: descriptor.limits.max_samplers_per_shader_stage,
|
||||
maxStorageBuffersPerShaderStage: descriptor
|
||||
.limits
|
||||
.max_storage_buffers_per_shader_stage,
|
||||
maxStorageTexturesPerShaderStage: descriptor
|
||||
.limits
|
||||
.max_storage_textures_per_shader_stage,
|
||||
maxUniformBufferBindingSize: descriptor.limits.max_uniform_buffer_binding_size,
|
||||
maxUniformBuffersPerShaderStage: descriptor
|
||||
.limits
|
||||
.max_uniform_buffers_per_shader_stage,
|
||||
};
|
||||
let device = GPUDevice::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
&self,
|
||||
Heap::default(),
|
||||
limits,
|
||||
descriptor.limits,
|
||||
device_id,
|
||||
queue_id,
|
||||
label,
|
||||
descriptor.label.unwrap_or_default(),
|
||||
);
|
||||
self.global().add_gpu_device(&device);
|
||||
promise.resolve_native(&device);
|
||||
|
|
56
components/script/dom/gpuadapterinfo.rs
Normal file
56
components/script/dom/gpuadapterinfo.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* 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 super::bindings::codegen::Bindings::GPUAdapterInfoBinding::GPUAdapterInfoMethods;
|
||||
use super::bindings::reflector::reflect_dom_object;
|
||||
use super::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::reflector::Reflector;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::test::DOMString;
|
||||
use dom_struct::dom_struct;
|
||||
use webgpu::wgt::AdapterInfo;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUAdapterInfo {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-types"]
|
||||
#[no_trace]
|
||||
info: AdapterInfo,
|
||||
}
|
||||
|
||||
impl GPUAdapterInfo {
|
||||
fn new_inherited(info: AdapterInfo) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
info,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: &GlobalScope, info: AdapterInfo) -> DomRoot<Self> {
|
||||
reflect_dom_object(Box::new(Self::new_inherited(info)), global)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: wgpu does not expose right fields right now
|
||||
impl GPUAdapterInfoMethods for GPUAdapterInfo {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapterinfo-vendor
|
||||
fn Vendor(&self) -> DOMString {
|
||||
DOMString::new()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapterinfo-architecture
|
||||
fn Architecture(&self) -> DOMString {
|
||||
DOMString::new()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapterinfo-device
|
||||
fn Device(&self) -> DOMString {
|
||||
DOMString::new()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapterinfo-description
|
||||
fn Description(&self) -> DOMString {
|
||||
DOMString::from_string(self.info.driver_info.clone())
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ use webgpu::{WebGPUBindGroup, WebGPUDevice};
|
|||
#[dom_struct]
|
||||
pub struct GPUBindGroup {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
bind_group: WebGPUBindGroup,
|
||||
#[no_trace]
|
||||
|
@ -28,7 +28,7 @@ impl GPUBindGroup {
|
|||
bind_group: WebGPUBindGroup,
|
||||
device: WebGPUDevice,
|
||||
layout: &GPUBindGroupLayout,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -44,7 +44,7 @@ impl GPUBindGroup {
|
|||
bind_group: WebGPUBindGroup,
|
||||
device: WebGPUDevice,
|
||||
layout: &GPUBindGroupLayout,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUBindGroup::new_inherited(
|
||||
|
@ -63,12 +63,12 @@ impl GPUBindGroup {
|
|||
|
||||
impl GPUBindGroupMethods for GPUBindGroup {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@ use webgpu::WebGPUBindGroupLayout;
|
|||
#[dom_struct]
|
||||
pub struct GPUBindGroupLayout {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
bind_group_layout: WebGPUBindGroupLayout,
|
||||
}
|
||||
|
||||
impl GPUBindGroupLayout {
|
||||
fn new_inherited(bind_group_layout: WebGPUBindGroupLayout, label: Option<USVString>) -> Self {
|
||||
fn new_inherited(bind_group_layout: WebGPUBindGroupLayout, label: USVString) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
label: DomRefCell::new(label),
|
||||
|
@ -31,7 +31,7 @@ impl GPUBindGroupLayout {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
bind_group_layout: WebGPUBindGroupLayout,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUBindGroupLayout::new_inherited(bind_group_layout, label)),
|
||||
|
@ -48,12 +48,12 @@ impl GPUBindGroupLayout {
|
|||
|
||||
impl GPUBindGroupLayoutMethods for GPUBindGroupLayout {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ pub struct GPUBuffer {
|
|||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
state: Cell<GPUBufferState>,
|
||||
#[no_trace]
|
||||
buffer: WebGPUBuffer,
|
||||
|
@ -80,7 +80,7 @@ impl GPUBuffer {
|
|||
state: GPUBufferState,
|
||||
size: GPUSize64,
|
||||
map_info: DomRefCell<Option<GPUBufferMapInfo>>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -104,7 +104,7 @@ impl GPUBuffer {
|
|||
state: GPUBufferState,
|
||||
size: GPUSize64,
|
||||
map_info: DomRefCell<Option<GPUBufferMapInfo>>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUBuffer::new_inherited(
|
||||
|
@ -127,20 +127,22 @@ impl GPUBuffer {
|
|||
|
||||
impl Drop for GPUBuffer {
|
||||
fn drop(&mut self) {
|
||||
self.Destroy()
|
||||
if let Err(e) = self.Destroy() {
|
||||
error!("GPUBuffer destruction failed with {e:?}!"); // TODO: should we allow panic here?
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUBufferMethods for GPUBuffer {
|
||||
#[allow(unsafe_code)]
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpubuffer-unmap
|
||||
fn Unmap(&self) {
|
||||
fn Unmap(&self) -> Fallible<()> {
|
||||
let cx = GlobalScope::get_cx();
|
||||
// Step 1
|
||||
match self.state.get() {
|
||||
GPUBufferState::Unmapped | GPUBufferState::Destroyed => {
|
||||
// TODO: Record validation error on the current scope
|
||||
return;
|
||||
return Ok(());
|
||||
},
|
||||
// Step 3
|
||||
GPUBufferState::Mapped | GPUBufferState::MappedAtCreation => {
|
||||
|
@ -176,16 +178,17 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
// Step 4
|
||||
self.state.set(GPUBufferState::Unmapped);
|
||||
*self.map_info.borrow_mut() = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpubuffer-destroy
|
||||
fn Destroy(&self) {
|
||||
fn Destroy(&self) -> Fallible<()> {
|
||||
let state = self.state.get();
|
||||
match state {
|
||||
GPUBufferState::Mapped | GPUBufferState::MappedAtCreation => {
|
||||
self.Unmap();
|
||||
self.Unmap()?;
|
||||
},
|
||||
GPUBufferState::Destroyed => return,
|
||||
GPUBufferState::Destroyed => return Ok(()),
|
||||
_ => {},
|
||||
};
|
||||
if let Err(e) = self
|
||||
|
@ -199,6 +202,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
);
|
||||
};
|
||||
self.state.set(GPUBufferState::Destroyed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -330,12 +334,12 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,19 @@
|
|||
* 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 crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUCanvasContextBinding::{
|
||||
GPUCanvasContextMethods, GPUSwapChainDescriptor,
|
||||
GPUCanvasConfiguration, GPUCanvasContextMethods,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::GPUDeviceBinding::GPUDeviceMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUObjectBaseBinding::GPUObjectDescriptorBase;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::{
|
||||
GPUExtent3D, GPUExtent3DDict, GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom};
|
||||
use crate::dom::bindings::root::{DomRoot, LayoutDom};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpuswapchain::GPUSwapChain;
|
||||
use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutCanvasRenderingContextHelpers};
|
||||
use crate::dom::node::{document_from_node, Node, NodeDamage};
|
||||
use arrayvec::ArrayVec;
|
||||
|
@ -24,33 +23,98 @@ use euclid::default::Size2D;
|
|||
use ipc_channel::ipc;
|
||||
use script_layout_interface::HTMLCanvasDataSource;
|
||||
use std::cell::Cell;
|
||||
use webgpu::WebGPUTexture;
|
||||
use webgpu::{wgpu::id, wgt, WebGPU, WebGPURequest, PRESENTATION_BUFFER_COUNT};
|
||||
use webrender_api::{
|
||||
units, ExternalImageData, ExternalImageId, ExternalImageType, ImageData, ImageDescriptor,
|
||||
ImageDescriptorFlags, ImageFormat, ImageKey,
|
||||
};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUTextureUsageBinding::GPUTextureUsageConstants;
|
||||
use super::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
|
||||
use super::bindings::error::{Error, Fallible};
|
||||
use super::bindings::root::MutNullableDom;
|
||||
use super::gputexture::GPUTexture;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd)]
|
||||
pub struct WebGPUContextId(pub u64);
|
||||
|
||||
// TODO: make all this derivables available via new Bindings.conf option
|
||||
impl Clone for GPUCanvasConfiguration {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
alphaMode: self.alphaMode.clone(),
|
||||
device: self.device.clone(),
|
||||
format: self.format.clone(),
|
||||
usage: self.usage.clone(),
|
||||
viewFormats: self.viewFormats.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for HTMLCanvasElementOrOffscreenCanvas {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::HTMLCanvasElement(arg0) => Self::HTMLCanvasElement(arg0.clone()),
|
||||
Self::OffscreenCanvas(arg0) => Self::OffscreenCanvas(arg0.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl malloc_size_of::MallocSizeOf for GPUTextureDescriptor {
|
||||
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||
match self {
|
||||
Self {
|
||||
parent,
|
||||
dimension,
|
||||
format,
|
||||
mipLevelCount,
|
||||
sampleCount,
|
||||
size,
|
||||
usage,
|
||||
viewFormats,
|
||||
} => {
|
||||
parent.size_of(ops) +
|
||||
dimension.size_of(ops) +
|
||||
format.size_of(ops) +
|
||||
mipLevelCount.size_of(ops) +
|
||||
sampleCount.size_of(ops) +
|
||||
size.size_of(ops) +
|
||||
usage.size_of(ops) +
|
||||
viewFormats.size_of(ops)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl malloc_size_of::MallocSizeOf for HTMLCanvasElementOrOffscreenCanvas {
|
||||
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||
match self {
|
||||
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => canvas.size_of(ops),
|
||||
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => canvas.size_of(ops),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUCanvasContext {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
canvas: Dom<HTMLCanvasElement>,
|
||||
#[no_trace]
|
||||
size: Cell<Size2D<u32>>,
|
||||
swap_chain: DomRefCell<Option<Dom<GPUSwapChain>>>,
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-canvas
|
||||
canvas: HTMLCanvasElementOrOffscreenCanvas,
|
||||
// TODO: can we have wgpu surface that is hw accelerated inside wr ...
|
||||
#[ignore_malloc_size_of = "Defined in webrender"]
|
||||
#[no_trace]
|
||||
webrender_image: Cell<Option<webrender_api::ImageKey>>,
|
||||
context_id: WebGPUContextId,
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-currenttexture-slot
|
||||
texture: MutNullableDom<GPUTexture>,
|
||||
}
|
||||
|
||||
impl GPUCanvasContext {
|
||||
fn new_inherited(canvas: &HTMLCanvasElement, size: Size2D<u32>, channel: WebGPU) -> Self {
|
||||
fn new_inherited(canvas: HTMLCanvasElementOrOffscreenCanvas, channel: WebGPU) -> Self {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
if let Err(e) = channel.0.send((None, WebGPURequest::CreateContext(sender))) {
|
||||
warn!("Failed to send CreateContext ({:?})", e);
|
||||
|
@ -59,22 +123,19 @@ impl GPUCanvasContext {
|
|||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
channel,
|
||||
canvas: Dom::from_ref(canvas),
|
||||
size: Cell::new(size),
|
||||
swap_chain: DomRefCell::new(None),
|
||||
canvas,
|
||||
webrender_image: Cell::new(None),
|
||||
context_id: WebGPUContextId(external_id.0),
|
||||
texture: MutNullableDom::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
canvas: &HTMLCanvasElement,
|
||||
size: Size2D<u32>,
|
||||
channel: WebGPU,
|
||||
) -> DomRoot<Self> {
|
||||
pub fn new(global: &GlobalScope, canvas: &HTMLCanvasElement, channel: WebGPU) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUCanvasContext::new_inherited(canvas, size, channel)),
|
||||
Box::new(GPUCanvasContext::new_inherited(
|
||||
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(canvas)),
|
||||
channel,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
}
|
||||
|
@ -91,7 +152,7 @@ impl GPUCanvasContext {
|
|||
}
|
||||
|
||||
pub fn send_swap_chain_present(&self) {
|
||||
let texture_id = self.swap_chain.borrow().as_ref().unwrap().texture_id().0;
|
||||
let texture_id = self.texture_id().unwrap().0;
|
||||
let encoder_id = self
|
||||
.global()
|
||||
.wgpu_id_hub()
|
||||
|
@ -116,13 +177,26 @@ impl GPUCanvasContext {
|
|||
self.context_id
|
||||
}
|
||||
|
||||
pub fn mark_as_dirty(&self) {
|
||||
self.canvas
|
||||
.upcast::<Node>()
|
||||
.dirty(NodeDamage::OtherNodeDamage);
|
||||
pub fn texture_id(&self) -> Option<WebGPUTexture> {
|
||||
self.texture.get().map(|t| t.id())
|
||||
}
|
||||
|
||||
let document = document_from_node(&*self.canvas);
|
||||
document.add_dirty_webgpu_canvas(self);
|
||||
pub fn mark_as_dirty(&self) {
|
||||
if let HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) = &self.canvas {
|
||||
canvas.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||
let document = document_from_node(&**canvas);
|
||||
document.add_dirty_webgpu_canvas(self);
|
||||
}
|
||||
// TODO(sagudev): offscreen canvas also dirty?
|
||||
}
|
||||
|
||||
fn size(&self) -> Size2D<u64> {
|
||||
match &self.canvas {
|
||||
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => {
|
||||
Size2D::new(canvas.Width() as u64, canvas.Height() as u64)
|
||||
},
|
||||
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => canvas.get_size(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,37 +208,49 @@ impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, GPUCanvasContext> {
|
|||
}
|
||||
|
||||
impl GPUCanvasContextMethods for GPUCanvasContext {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-configureswapchain
|
||||
fn ConfigureSwapChain(&self, descriptor: &GPUSwapChainDescriptor) -> DomRoot<GPUSwapChain> {
|
||||
if let Some(chain) = &*self.swap_chain.borrow() {
|
||||
chain.destroy(self.context_id.0, self.webrender_image.get().unwrap());
|
||||
self.webrender_image.set(None);
|
||||
}
|
||||
*self.swap_chain.borrow_mut() = None;
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-canvas
|
||||
fn Canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas {
|
||||
self.canvas.clone()
|
||||
}
|
||||
|
||||
let mut buffer_ids = ArrayVec::<id::BufferId, PRESENTATION_BUFFER_COUNT>::new();
|
||||
for _ in 0..PRESENTATION_BUFFER_COUNT {
|
||||
buffer_ids.push(
|
||||
self.global()
|
||||
.wgpu_id_hub()
|
||||
.lock()
|
||||
.create_buffer_id(descriptor.device.id().0.backend()),
|
||||
);
|
||||
}
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-configure
|
||||
fn Configure(&self, descriptor: &GPUCanvasConfiguration) {
|
||||
// Step 1 is let
|
||||
// Step 2
|
||||
// TODO: device features
|
||||
let format = match descriptor.format {
|
||||
GPUTextureFormat::Rgba8unorm | GPUTextureFormat::Rgba8unorm_srgb => ImageFormat::RGBA8,
|
||||
GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Bgra8unorm_srgb => ImageFormat::BGRA8,
|
||||
_ => panic!("SwapChain format({:?}) not supported", descriptor.format), // TODO: Better handling
|
||||
};
|
||||
|
||||
// Step 3
|
||||
// TODO: device features
|
||||
|
||||
// Step 4
|
||||
let size = self.size();
|
||||
let text_desc = GPUTextureDescriptor {
|
||||
format: descriptor.format,
|
||||
mipLevelCount: 1,
|
||||
sampleCount: 1,
|
||||
usage: descriptor.usage | GPUTextureUsageConstants::COPY_SRC, // TODO: specs
|
||||
size: GPUExtent3D::GPUExtent3DDict(GPUExtent3DDict {
|
||||
width: size.width as u32,
|
||||
height: size.height as u32,
|
||||
depthOrArrayLayers: 1,
|
||||
}),
|
||||
viewFormats: descriptor.viewFormats.clone(),
|
||||
// other members to default
|
||||
parent: GPUObjectDescriptorBase { label: None },
|
||||
dimension: GPUTextureDimension::_2d,
|
||||
};
|
||||
|
||||
// Step 8
|
||||
let image_desc = ImageDescriptor {
|
||||
format: match descriptor.format {
|
||||
GPUTextureFormat::Rgba8unorm => ImageFormat::RGBA8,
|
||||
GPUTextureFormat::Bgra8unorm => ImageFormat::BGRA8,
|
||||
_ => panic!("SwapChain format({:?}) not supported", descriptor.format),
|
||||
},
|
||||
size: units::DeviceIntSize::new(
|
||||
self.size.get().width as i32,
|
||||
self.size.get().height as i32,
|
||||
),
|
||||
format,
|
||||
size: units::DeviceIntSize::new(size.width as i32, size.height as i32),
|
||||
stride: Some(
|
||||
(((self.size.get().width * 4) | (wgt::COPY_BYTES_PER_ROW_ALIGNMENT - 1)) + 1)
|
||||
as i32,
|
||||
(((size.width as u32 * 4) | (wgt::COPY_BYTES_PER_ROW_ALIGNMENT - 1)) + 1) as i32,
|
||||
),
|
||||
offset: 0,
|
||||
flags: ImageDescriptorFlags::from_bits(1).unwrap(),
|
||||
|
@ -178,6 +264,16 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
|
||||
let mut buffer_ids = ArrayVec::<id::BufferId, PRESENTATION_BUFFER_COUNT>::new();
|
||||
for _ in 0..PRESENTATION_BUFFER_COUNT {
|
||||
buffer_ids.push(
|
||||
self.global()
|
||||
.wgpu_id_hub()
|
||||
.lock()
|
||||
.create_buffer_id(descriptor.device.id().0.backend()),
|
||||
);
|
||||
}
|
||||
|
||||
self.channel
|
||||
.0
|
||||
.send((
|
||||
|
@ -193,37 +289,42 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
))
|
||||
.expect("Failed to create WebGPU SwapChain");
|
||||
|
||||
let usage = if descriptor.usage % 2 == 0 {
|
||||
descriptor.usage + 1
|
||||
} else {
|
||||
descriptor.usage
|
||||
};
|
||||
let text_desc = GPUTextureDescriptor {
|
||||
parent: GPUObjectDescriptorBase { label: None },
|
||||
dimension: GPUTextureDimension::_2d,
|
||||
format: descriptor.format,
|
||||
mipLevelCount: 1,
|
||||
sampleCount: 1,
|
||||
usage,
|
||||
size: GPUExtent3D::GPUExtent3DDict(GPUExtent3DDict {
|
||||
width: self.size.get().width,
|
||||
height: self.size.get().height,
|
||||
depth: 1,
|
||||
}),
|
||||
};
|
||||
|
||||
let texture = descriptor.device.CreateTexture(&text_desc);
|
||||
self.texture
|
||||
.set(Some(&descriptor.device.CreateTexture(&text_desc)));
|
||||
|
||||
self.webrender_image.set(Some(receiver.recv().unwrap()));
|
||||
}
|
||||
|
||||
let swap_chain = GPUSwapChain::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
&self,
|
||||
&*texture,
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
);
|
||||
*self.swap_chain.borrow_mut() = Some(Dom::from_ref(&*swap_chain));
|
||||
swap_chain
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-unconfigure
|
||||
fn Unconfigure(&self) {
|
||||
if let Some(image_key) = self.webrender_image.take() {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
None,
|
||||
WebGPURequest::DestroySwapChain {
|
||||
external_id: self.context_id.0,
|
||||
image_key,
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send DestroySwapChain-ImageKey({:?}) ({})",
|
||||
image_key, e
|
||||
);
|
||||
}
|
||||
}
|
||||
self.texture.take();
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-getcurrenttexture
|
||||
fn GetCurrentTexture(&self) -> Fallible<DomRoot<GPUTexture>> {
|
||||
// Step 5.
|
||||
self.mark_as_dirty();
|
||||
// Step 6.
|
||||
self.texture.get().ok_or(Error::InvalidState)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GPUCanvasContext {
|
||||
fn drop(&mut self) {
|
||||
self.Unconfigure()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ pub struct GPUCommandBuffer {
|
|||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
command_buffer: WebGPUCommandBuffer,
|
||||
buffers: DomRefCell<HashSet<Dom<GPUBuffer>>>,
|
||||
|
@ -39,7 +39,7 @@ impl GPUCommandBuffer {
|
|||
channel: WebGPU,
|
||||
command_buffer: WebGPUCommandBuffer,
|
||||
buffers: HashSet<DomRoot<GPUBuffer>>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
|
@ -55,7 +55,7 @@ impl GPUCommandBuffer {
|
|||
channel: WebGPU,
|
||||
command_buffer: WebGPUCommandBuffer,
|
||||
buffers: HashSet<DomRoot<GPUBuffer>>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUCommandBuffer::new_inherited(
|
||||
|
@ -95,12 +95,12 @@ impl GPUCommandBuffer {
|
|||
|
||||
impl GPUCommandBufferMethods for GPUCommandBuffer {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,10 @@
|
|||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUSize64;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUCommandEncoderBinding::{
|
||||
GPUBufferCopyView, GPUCommandBufferDescriptor, GPUCommandEncoderMethods,
|
||||
GPUComputePassDescriptor, GPUOrigin3D, GPURenderPassDescriptor, GPUStencilLoadValue,
|
||||
GPUStoreOp, GPUTextureCopyView, GPUTextureDataLayout,
|
||||
GPUCommandEncoderMethods, GPUComputePassDescriptor, GPUOrigin3D, GPURenderPassDescriptor,
|
||||
GPUStoreOp,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::GPUExtent3D;
|
||||
use crate::dom::bindings::codegen::UnionTypes::{
|
||||
GPULoadOpOrDoubleSequenceOrGPUColorDict as GPUColorLoad, GPULoadOpOrFloat,
|
||||
};
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
|
@ -31,6 +27,14 @@ use std::collections::HashSet;
|
|||
use webgpu::wgpu::command as wgpu_com;
|
||||
use webgpu::{self, wgt, WebGPU, WebGPURequest};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUCommandBufferBinding::GPUCommandBufferDescriptor;
|
||||
use super::bindings::codegen::Bindings::GPUCommandEncoderBinding::{
|
||||
GPUImageCopyBuffer, GPUImageCopyTexture, GPUImageDataLayout, GPULoadOp,
|
||||
};
|
||||
use super::bindings::codegen::Bindings::GPUTextureViewBinding::GPUTextureAspect;
|
||||
use super::bindings::codegen::UnionTypes::DoubleSequenceOrGPUColorDict;
|
||||
|
||||
// TODO(sagudev): this is different now
|
||||
// https://gpuweb.github.io/gpuweb/#enumdef-encoder-state
|
||||
#[derive(MallocSizeOf, PartialEq)]
|
||||
pub enum GPUCommandEncoderState {
|
||||
|
@ -46,7 +50,7 @@ pub struct GPUCommandEncoder {
|
|||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
encoder: webgpu::WebGPUCommandEncoder,
|
||||
buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>,
|
||||
|
@ -60,7 +64,7 @@ impl GPUCommandEncoder {
|
|||
channel: WebGPU,
|
||||
device: &GPUDevice,
|
||||
encoder: webgpu::WebGPUCommandEncoder,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
|
@ -79,7 +83,7 @@ impl GPUCommandEncoder {
|
|||
channel: WebGPU,
|
||||
device: &GPUDevice,
|
||||
encoder: webgpu::WebGPUCommandEncoder,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUCommandEncoder::new_inherited(
|
||||
|
@ -107,12 +111,12 @@ impl GPUCommandEncoder {
|
|||
|
||||
impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -129,7 +133,16 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
let compute_pass = if !self.valid.get() {
|
||||
None
|
||||
} else {
|
||||
Some(wgpu_com::ComputePass::new(self.encoder.0))
|
||||
Some(wgpu_com::ComputePass::new(
|
||||
self.encoder.0,
|
||||
&wgpu_com::ComputePassDescriptor {
|
||||
label: descriptor
|
||||
.parent
|
||||
.label
|
||||
.as_ref()
|
||||
.map(|l| Cow::Borrowed(&**l)),
|
||||
},
|
||||
))
|
||||
};
|
||||
|
||||
GPUComputePassEncoder::new(
|
||||
|
@ -137,7 +150,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
&self,
|
||||
compute_pass,
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -155,38 +168,20 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
None
|
||||
} else {
|
||||
let depth_stencil = descriptor.depthStencilAttachment.as_ref().map(|depth| {
|
||||
let (depth_load_op, clear_depth) = match depth.depthLoadValue {
|
||||
GPULoadOpOrFloat::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0.0f32),
|
||||
GPULoadOpOrFloat::Float(f) => (wgpu_com::LoadOp::Clear, *f),
|
||||
};
|
||||
let (stencil_load_op, clear_stencil) = match depth.stencilLoadValue {
|
||||
GPUStencilLoadValue::GPULoadOp(_) => (wgpu_com::LoadOp::Load, 0u32),
|
||||
GPUStencilLoadValue::RangeEnforcedUnsignedLong(l) => {
|
||||
(wgpu_com::LoadOp::Clear, l)
|
||||
wgpu_com::RenderPassDepthStencilAttachment {
|
||||
depth: wgpu_com::PassChannel {
|
||||
load_op: convert_load_op(depth.depthLoadOp),
|
||||
store_op: convert_store_op(depth.depthStoreOp),
|
||||
clear_value: *depth.depthClearValue.unwrap_or_default(),
|
||||
read_only: depth.depthReadOnly,
|
||||
},
|
||||
};
|
||||
let depth_channel = wgpu_com::PassChannel {
|
||||
load_op: depth_load_op,
|
||||
store_op: match depth.depthStoreOp {
|
||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||
stencil: wgpu_com::PassChannel {
|
||||
load_op: convert_load_op(depth.stencilLoadOp),
|
||||
store_op: convert_store_op(depth.stencilStoreOp),
|
||||
clear_value: depth.stencilClearValue,
|
||||
read_only: depth.stencilReadOnly,
|
||||
},
|
||||
clear_value: clear_depth,
|
||||
read_only: depth.depthReadOnly,
|
||||
};
|
||||
let stencil_channel = wgpu_com::PassChannel {
|
||||
load_op: stencil_load_op,
|
||||
store_op: match depth.stencilStoreOp {
|
||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||
},
|
||||
clear_value: clear_stencil,
|
||||
read_only: depth.stencilReadOnly,
|
||||
};
|
||||
wgpu_com::DepthStencilAttachmentDescriptor {
|
||||
attachment: depth.attachment.id().0,
|
||||
depth: depth_channel,
|
||||
stencil: stencil_channel,
|
||||
view: depth.view.id().0,
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -196,56 +191,54 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
.colorAttachments
|
||||
.iter()
|
||||
.map(|color| {
|
||||
let (load_op, clear_value) = match color.loadValue {
|
||||
GPUColorLoad::GPULoadOp(_) => {
|
||||
(wgpu_com::LoadOp::Load, wgt::Color::TRANSPARENT)
|
||||
},
|
||||
GPUColorLoad::DoubleSequence(ref s) => {
|
||||
let mut w = s.clone();
|
||||
if w.len() < 3 {
|
||||
w.resize(3, Finite::wrap(0.0f64));
|
||||
}
|
||||
w.resize(4, Finite::wrap(1.0f64));
|
||||
(
|
||||
wgpu_com::LoadOp::Clear,
|
||||
wgt::Color {
|
||||
r: *w[0],
|
||||
g: *w[1],
|
||||
b: *w[2],
|
||||
a: *w[3],
|
||||
},
|
||||
)
|
||||
},
|
||||
GPUColorLoad::GPUColorDict(ref d) => (
|
||||
wgpu_com::LoadOp::Clear,
|
||||
wgt::Color {
|
||||
r: *d.r,
|
||||
g: *d.g,
|
||||
b: *d.b,
|
||||
a: *d.a,
|
||||
},
|
||||
),
|
||||
};
|
||||
let channel = wgpu_com::PassChannel {
|
||||
load_op,
|
||||
store_op: match color.storeOp {
|
||||
GPUStoreOp::Store => wgpu_com::StoreOp::Store,
|
||||
GPUStoreOp::Clear => wgpu_com::StoreOp::Clear,
|
||||
load_op: convert_load_op(Some(color.loadOp)),
|
||||
store_op: convert_store_op(Some(color.storeOp)),
|
||||
clear_value: if let Some(clear_val) = &color.clearValue {
|
||||
match clear_val {
|
||||
DoubleSequenceOrGPUColorDict::DoubleSequence(s) => {
|
||||
let mut w = s.clone();
|
||||
if w.len() < 3 {
|
||||
w.resize(3, Finite::wrap(0.0f64));
|
||||
}
|
||||
w.resize(4, Finite::wrap(1.0f64));
|
||||
wgt::Color {
|
||||
r: *w[0],
|
||||
g: *w[1],
|
||||
b: *w[2],
|
||||
a: *w[3],
|
||||
}
|
||||
},
|
||||
DoubleSequenceOrGPUColorDict::GPUColorDict(d) => {
|
||||
wgt::Color {
|
||||
r: *d.r,
|
||||
g: *d.g,
|
||||
b: *d.b,
|
||||
a: *d.a,
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
wgt::Color::TRANSPARENT
|
||||
},
|
||||
clear_value,
|
||||
read_only: false,
|
||||
};
|
||||
wgpu_com::ColorAttachmentDescriptor {
|
||||
attachment: color.attachment.id().0,
|
||||
Some(wgpu_com::RenderPassColorAttachment {
|
||||
resolve_target: color.resolveTarget.as_ref().map(|t| t.id().0),
|
||||
channel,
|
||||
}
|
||||
view: color.view.id().0,
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
depth_stencil_attachment: depth_stencil.as_ref(),
|
||||
label: descriptor
|
||||
.parent
|
||||
.label
|
||||
.as_ref()
|
||||
.map(|l| Cow::Borrowed(&**l)),
|
||||
};
|
||||
Some(wgpu_com::RenderPass::new(self.encoder.0, desc))
|
||||
Some(wgpu_com::RenderPass::new(self.encoder.0, &desc))
|
||||
};
|
||||
|
||||
GPURenderPassEncoder::new(
|
||||
|
@ -253,7 +246,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
render_pass,
|
||||
&self,
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -294,8 +287,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
/// https://gpuweb.github.io/gpuweb/#dom-gpucommandencoder-copybuffertotexture
|
||||
fn CopyBufferToTexture(
|
||||
&self,
|
||||
source: &GPUBufferCopyView,
|
||||
destination: &GPUTextureCopyView,
|
||||
source: &GPUImageCopyBuffer,
|
||||
destination: &GPUImageCopyTexture,
|
||||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||
|
@ -313,8 +306,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
None,
|
||||
WebGPURequest::CopyBufferToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_buffer_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
source: convert_ic_buffer(source),
|
||||
destination: convert_ic_texture(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
|
@ -323,11 +316,11 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
.expect("Failed to send CopyBufferToTexture");
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#GPUCommandEncoder-copyTextureToBuffer
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucommandencoder-copybuffertotexture
|
||||
fn CopyTextureToBuffer(
|
||||
&self,
|
||||
source: &GPUTextureCopyView,
|
||||
destination: &GPUBufferCopyView,
|
||||
source: &GPUImageCopyTexture,
|
||||
destination: &GPUImageCopyBuffer,
|
||||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||
|
@ -345,8 +338,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
None,
|
||||
WebGPURequest::CopyTextureToBuffer {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_buffer_cv(destination),
|
||||
source: convert_ic_texture(source),
|
||||
destination: convert_ic_buffer(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
|
@ -358,8 +351,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
/// https://gpuweb.github.io/gpuweb/#GPUCommandEncoder-copyTextureToTexture
|
||||
fn CopyTextureToTexture(
|
||||
&self,
|
||||
source: &GPUTextureCopyView,
|
||||
destination: &GPUTextureCopyView,
|
||||
source: &GPUImageCopyTexture,
|
||||
destination: &GPUImageCopyTexture,
|
||||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
if !(*self.state.borrow() == GPUCommandEncoderState::Open) {
|
||||
|
@ -373,8 +366,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
None,
|
||||
WebGPURequest::CopyTextureToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
source: convert_ic_texture(source),
|
||||
destination: convert_ic_texture(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
|
@ -406,24 +399,40 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
self.channel.clone(),
|
||||
buffer,
|
||||
self.buffers.borrow_mut().drain().collect(),
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_buffer_cv(buffer_cv: &GPUBufferCopyView) -> wgpu_com::BufferCopyView {
|
||||
wgpu_com::BufferCopyView {
|
||||
buffer: buffer_cv.buffer.id().0,
|
||||
layout: convert_texture_data_layout(&buffer_cv.parent),
|
||||
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_texture_cv(texture_cv: &GPUTextureCopyView) -> wgpu_com::TextureCopyView {
|
||||
wgpu_com::TextureCopyView {
|
||||
texture: texture_cv.texture.id().0,
|
||||
mip_level: texture_cv.mipLevel,
|
||||
origin: match texture_cv.origin {
|
||||
GPUOrigin3D::RangeEnforcedUnsignedLongSequence(ref v) => {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_ic_buffer(ic_buffer: &GPUImageCopyBuffer) -> wgpu_com::ImageCopyBuffer {
|
||||
wgpu_com::ImageCopyBuffer {
|
||||
buffer: ic_buffer.buffer.id().0,
|
||||
layout: convert_image_data_layout(&ic_buffer.parent),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_ic_texture(ic_texture: &GPUImageCopyTexture) -> wgpu_com::ImageCopyTexture {
|
||||
wgpu_com::ImageCopyTexture {
|
||||
texture: ic_texture.texture.id().0,
|
||||
mip_level: ic_texture.mipLevel,
|
||||
origin: match ic_texture.origin {
|
||||
Some(GPUOrigin3D::RangeEnforcedUnsignedLongSequence(ref v)) => {
|
||||
let mut w = v.clone();
|
||||
w.resize(3, 0);
|
||||
wgt::Origin3d {
|
||||
|
@ -432,17 +441,23 @@ pub fn convert_texture_cv(texture_cv: &GPUTextureCopyView) -> wgpu_com::TextureC
|
|||
z: w[2],
|
||||
}
|
||||
},
|
||||
GPUOrigin3D::GPUOrigin3DDict(ref d) => wgt::Origin3d {
|
||||
Some(GPUOrigin3D::GPUOrigin3DDict(ref d)) => wgt::Origin3d {
|
||||
x: d.x,
|
||||
y: d.y,
|
||||
z: d.z,
|
||||
},
|
||||
None => wgt::Origin3d::default(),
|
||||
},
|
||||
aspect: match ic_texture.aspect {
|
||||
GPUTextureAspect::All => wgt::TextureAspect::All,
|
||||
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
|
||||
GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_texture_data_layout(data_layout: &GPUTextureDataLayout) -> wgt::TextureDataLayout {
|
||||
wgt::TextureDataLayout {
|
||||
pub fn convert_image_data_layout(data_layout: &GPUImageDataLayout) -> wgt::ImageDataLayout {
|
||||
wgt::ImageDataLayout {
|
||||
offset: data_layout.offset as wgt::BufferAddress,
|
||||
bytes_per_row: data_layout.bytesPerRow,
|
||||
rows_per_image: data_layout.rowsPerImage,
|
||||
|
|
27
components/script/dom/gpucompilationinfo.rs
Normal file
27
components/script/dom/gpucompilationinfo.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* 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 crate::dom::bindings::reflector::Reflector;
|
||||
use crate::script_runtime::JSContext;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use js::jsval::JSVal;
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUCompilationInfoBinding::GPUCompilationInfoMethods;
|
||||
use super::bindings::root::Dom;
|
||||
use super::types::GPUCompilationMessage;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUCompilationInfo {
|
||||
reflector_: Reflector,
|
||||
msg: Dom<GPUCompilationMessage>,
|
||||
}
|
||||
|
||||
// TODO: wgpu does not expose right fields right now
|
||||
impl GPUCompilationInfoMethods for GPUCompilationInfo {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationinfo-messages
|
||||
fn Messages(&self, _cx: JSContext) -> JSVal {
|
||||
todo!()
|
||||
}
|
||||
}
|
98
components/script/dom/gpucompilationmessage.rs
Normal file
98
components/script/dom/gpucompilationmessage.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* 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/. */
|
||||
|
||||
#![allow(dead_code)] // this file is stub as wgpu does not provide info
|
||||
|
||||
use crate::dom::bindings::reflector::Reflector;
|
||||
use crate::test::DOMString;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUCompilationMessageBinding::{
|
||||
GPUCompilationMessageMethods, GPUCompilationMessageType,
|
||||
};
|
||||
use super::bindings::root::DomRoot;
|
||||
use super::types::GlobalScope;
|
||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUCompilationMessage {
|
||||
reflector_: Reflector,
|
||||
// #[ignore_malloc_size_of = "defined in wgpu-types"]
|
||||
message: DOMString,
|
||||
mtype: GPUCompilationMessageType,
|
||||
line_num: u64,
|
||||
line_pos: u64,
|
||||
offset: u64,
|
||||
length: u64,
|
||||
}
|
||||
|
||||
impl GPUCompilationMessage {
|
||||
fn new_inherited(
|
||||
message: DOMString,
|
||||
mtype: GPUCompilationMessageType,
|
||||
line_num: u64,
|
||||
line_pos: u64,
|
||||
offset: u64,
|
||||
length: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
message,
|
||||
mtype,
|
||||
line_num,
|
||||
line_pos,
|
||||
offset,
|
||||
length,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
message: DOMString,
|
||||
mtype: GPUCompilationMessageType,
|
||||
line_num: u64,
|
||||
line_pos: u64,
|
||||
offset: u64,
|
||||
length: u64,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(Self::new_inherited(
|
||||
message, mtype, line_num, line_pos, offset, length,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUCompilationMessageMethods for GPUCompilationMessage {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-message
|
||||
fn Message(&self) -> DOMString {
|
||||
self.message.to_owned()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-type
|
||||
fn Type(&self) -> GPUCompilationMessageType {
|
||||
self.mtype
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-linenum
|
||||
fn LineNum(&self) -> u64 {
|
||||
self.line_num
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-linepos
|
||||
fn LinePos(&self) -> u64 {
|
||||
self.line_pos
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-offset
|
||||
fn Offset(&self) -> u64 {
|
||||
self.offset
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-length
|
||||
fn Length(&self) -> u64 {
|
||||
self.length
|
||||
}
|
||||
}
|
|
@ -18,13 +18,15 @@ use webgpu::{
|
|||
WebGPU, WebGPURequest,
|
||||
};
|
||||
|
||||
use super::bindings::error::Fallible;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUComputePassEncoder {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-core"]
|
||||
#[no_trace]
|
||||
compute_pass: DomRefCell<Option<ComputePass>>,
|
||||
|
@ -36,7 +38,7 @@ impl GPUComputePassEncoder {
|
|||
channel: WebGPU,
|
||||
parent: &GPUCommandEncoder,
|
||||
compute_pass: Option<ComputePass>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
|
@ -52,7 +54,7 @@ impl GPUComputePassEncoder {
|
|||
channel: WebGPU,
|
||||
parent: &GPUCommandEncoder,
|
||||
compute_pass: Option<ComputePass>,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUComputePassEncoder::new_inherited(
|
||||
|
@ -68,26 +70,26 @@ impl GPUComputePassEncoder {
|
|||
|
||||
impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatch
|
||||
fn Dispatch(&self, x: u32, y: u32, z: u32) {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatchworkgroups
|
||||
fn DispatchWorkgroups(&self, x: u32, y: u32, z: u32) {
|
||||
if let Some(compute_pass) = self.compute_pass.borrow_mut().as_mut() {
|
||||
wgpu_comp::wgpu_compute_pass_dispatch(compute_pass, x, y, z);
|
||||
wgpu_comp::wgpu_compute_pass_dispatch_workgroups(compute_pass, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatchindirect
|
||||
fn DispatchIndirect(&self, indirect_buffer: &GPUBuffer, indirect_offset: u64) {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatchworkgroupsindirect
|
||||
fn DispatchWorkgroupsIndirect(&self, indirect_buffer: &GPUBuffer, indirect_offset: u64) {
|
||||
if let Some(compute_pass) = self.compute_pass.borrow_mut().as_mut() {
|
||||
wgpu_comp::wgpu_compute_pass_dispatch_indirect(
|
||||
wgpu_comp::wgpu_compute_pass_dispatch_workgroups_indirect(
|
||||
compute_pass,
|
||||
indirect_buffer.id().0,
|
||||
indirect_offset,
|
||||
|
@ -96,7 +98,7 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
|
|||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
||||
fn EndPass(&self) {
|
||||
fn End(&self) -> Fallible<()> {
|
||||
let compute_pass = self.compute_pass.borrow_mut().take();
|
||||
self.channel
|
||||
.0
|
||||
|
@ -107,12 +109,13 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
|
|||
compute_pass,
|
||||
},
|
||||
))
|
||||
.expect("Failed to send RunComputePass");
|
||||
.expect("Failed to send RunComputePass"); //TODO: handle error
|
||||
|
||||
self.command_encoder.set_state(
|
||||
GPUCommandEncoderState::Open,
|
||||
GPUCommandEncoderState::EncodingComputePass,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuprogrammablepassencoder-setbindgroup
|
||||
|
|
|
@ -18,7 +18,7 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUComputePipeline};
|
|||
#[dom_struct]
|
||||
pub struct GPUComputePipeline {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
compute_pipeline: WebGPUComputePipeline,
|
||||
#[no_trace]
|
||||
|
@ -29,7 +29,7 @@ pub struct GPUComputePipeline {
|
|||
impl GPUComputePipeline {
|
||||
fn new_inherited(
|
||||
compute_pipeline: WebGPUComputePipeline,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
device: &GPUDevice,
|
||||
) -> Self {
|
||||
|
@ -45,7 +45,7 @@ impl GPUComputePipeline {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
compute_pipeline: WebGPUComputePipeline,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
device: &GPUDevice,
|
||||
) -> DomRoot<Self> {
|
||||
|
@ -69,12 +69,12 @@ impl GPUComputePipeline {
|
|||
|
||||
impl GPUComputePipelineMethods for GPUComputePipeline {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ impl GPUComputePipelineMethods for GPUComputePipeline {
|
|||
Ok(GPUBindGroupLayout::new(
|
||||
&self.global(),
|
||||
self.bind_group_layouts[index as usize],
|
||||
None,
|
||||
USVString::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,22 +11,33 @@ use crate::dom::bindings::str::DOMString;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUDeviceLostInfoBinding::GPUDeviceLostReason;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUDeviceLostInfo {
|
||||
reflector_: Reflector,
|
||||
message: DOMString,
|
||||
reason: GPUDeviceLostReason,
|
||||
}
|
||||
|
||||
impl GPUDeviceLostInfo {
|
||||
fn new_inherited(message: DOMString) -> Self {
|
||||
fn new_inherited(message: DOMString, reason: GPUDeviceLostReason) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
message,
|
||||
reason,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: &GlobalScope, message: DOMString) -> DomRoot<Self> {
|
||||
reflect_dom_object(Box::new(GPUDeviceLostInfo::new_inherited(message)), global)
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
message: DOMString,
|
||||
reason: GPUDeviceLostReason,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUDeviceLostInfo::new_inherited(message, reason)),
|
||||
global,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,4 +46,9 @@ impl GPUDeviceLostInfoMethods for GPUDeviceLostInfo {
|
|||
fn Message(&self) -> DOMString {
|
||||
self.message.clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpudevicelostinfo-reason
|
||||
fn Reason(&self) -> GPUDeviceLostReason {
|
||||
self.reason
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUPipelineLayout};
|
|||
#[dom_struct]
|
||||
pub struct GPUPipelineLayout {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
pipeline_layout: WebGPUPipelineLayout,
|
||||
#[no_trace]
|
||||
|
@ -24,7 +24,7 @@ pub struct GPUPipelineLayout {
|
|||
impl GPUPipelineLayout {
|
||||
fn new_inherited(
|
||||
pipeline_layout: WebGPUPipelineLayout,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -38,7 +38,7 @@ impl GPUPipelineLayout {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
pipeline_layout: WebGPUPipelineLayout,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
|
@ -64,12 +64,12 @@ impl GPUPipelineLayout {
|
|||
|
||||
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
35
components/script/dom/gpuqueryset.rs
Normal file
35
components/script/dom/gpuqueryset.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* 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/. */
|
||||
|
||||
#![allow(dead_code)] // this file is stub
|
||||
|
||||
use crate::dom::bindings::reflector::Reflector;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUQuerySetBinding::GPUQuerySetMethods;
|
||||
use super::bindings::str::USVString;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUQuerySet {
|
||||
reflector_: Reflector,
|
||||
// #[ignore_malloc_size_of = "defined in wgpu-types"]
|
||||
}
|
||||
|
||||
// TODO: wgpu does not expose right fields right now
|
||||
impl GPUQuerySetMethods for GPUQuerySet {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuqueryset-destroy
|
||||
fn Destroy(&self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn Label(&self) -> USVString {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, _value: USVString) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -4,9 +4,6 @@
|
|||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUSize64;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUCommandEncoderBinding::{
|
||||
GPUTextureCopyView, GPUTextureDataLayout,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUQueueBinding::GPUQueueMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::GPUExtent3D;
|
||||
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer as BufferSource;
|
||||
|
@ -17,12 +14,16 @@ use crate::dom::bindings::str::USVString;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState};
|
||||
use crate::dom::gpucommandbuffer::GPUCommandBuffer;
|
||||
use crate::dom::gpucommandencoder::{convert_texture_cv, convert_texture_data_layout};
|
||||
use crate::dom::gpucommandencoder::{convert_ic_texture, convert_image_data_layout};
|
||||
use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt, GPUDevice};
|
||||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use webgpu::{identity::WebGPUOpResult, wgt, WebGPU, WebGPUQueue, WebGPURequest};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPUCommandEncoderBinding::{
|
||||
GPUImageCopyTexture, GPUImageDataLayout,
|
||||
};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUQueue {
|
||||
reflector_: Reflector,
|
||||
|
@ -30,7 +31,7 @@ pub struct GPUQueue {
|
|||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
device: DomRefCell<Option<Dom<GPUDevice>>>,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
queue: WebGPUQueue,
|
||||
}
|
||||
|
@ -41,7 +42,7 @@ impl GPUQueue {
|
|||
channel,
|
||||
reflector_: Reflector::new(),
|
||||
device: DomRefCell::new(None),
|
||||
label: DomRefCell::new(None),
|
||||
label: DomRefCell::new(USVString::default()),
|
||||
queue,
|
||||
}
|
||||
}
|
||||
|
@ -59,12 +60,12 @@ impl GPUQueue {
|
|||
|
||||
impl GPUQueueMethods for GPUQueue {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -149,9 +150,9 @@ impl GPUQueueMethods for GPUQueue {
|
|||
/// https://gpuweb.github.io/gpuweb/#dom-gpuqueue-writetexture
|
||||
fn WriteTexture(
|
||||
&self,
|
||||
destination: &GPUTextureCopyView,
|
||||
destination: &GPUImageCopyTexture,
|
||||
data: BufferSource,
|
||||
data_layout: &GPUTextureDataLayout,
|
||||
data_layout: &GPUImageDataLayout,
|
||||
size: GPUExtent3D,
|
||||
) -> Fallible<()> {
|
||||
let (bytes, len) = match data {
|
||||
|
@ -164,8 +165,8 @@ impl GPUQueueMethods for GPUQueue {
|
|||
return Err(Error::Operation);
|
||||
}
|
||||
|
||||
let texture_cv = convert_texture_cv(destination);
|
||||
let texture_layout = convert_texture_data_layout(data_layout);
|
||||
let texture_cv = convert_ic_texture(destination);
|
||||
let texture_layout = convert_image_data_layout(data_layout);
|
||||
let write_size = convert_texture_size_to_wgt(&convert_texture_size_to_dict(&size));
|
||||
let final_data = IpcSharedMemory::from_bytes(&bytes);
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ pub struct GPURenderBundle {
|
|||
device: WebGPUDevice,
|
||||
#[no_trace]
|
||||
render_bundle: WebGPURenderBundle,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
}
|
||||
|
||||
impl GPURenderBundle {
|
||||
|
@ -29,7 +29,7 @@ impl GPURenderBundle {
|
|||
render_bundle: WebGPURenderBundle,
|
||||
device: WebGPUDevice,
|
||||
channel: WebGPU,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -45,7 +45,7 @@ impl GPURenderBundle {
|
|||
render_bundle: WebGPURenderBundle,
|
||||
device: WebGPUDevice,
|
||||
channel: WebGPU,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPURenderBundle::new_inherited(
|
||||
|
@ -67,12 +67,12 @@ impl GPURenderBundle {
|
|||
|
||||
impl GPURenderBundleMethods for GPURenderBundle {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ use webgpu::{
|
|||
wgt, WebGPU, WebGPURenderBundle, WebGPURequest,
|
||||
};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPURenderPipelineBinding::GPUIndexFormat;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPURenderBundleEncoder {
|
||||
reflector_: Reflector,
|
||||
|
@ -30,7 +32,7 @@ pub struct GPURenderBundleEncoder {
|
|||
#[ignore_malloc_size_of = "defined in wgpu-core"]
|
||||
#[no_trace]
|
||||
render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
}
|
||||
|
||||
impl GPURenderBundleEncoder {
|
||||
|
@ -38,7 +40,7 @@ impl GPURenderBundleEncoder {
|
|||
render_bundle_encoder: RenderBundleEncoder,
|
||||
device: &GPUDevice,
|
||||
channel: WebGPU,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -54,7 +56,7 @@ impl GPURenderBundleEncoder {
|
|||
render_bundle_encoder: RenderBundleEncoder,
|
||||
device: &GPUDevice,
|
||||
channel: WebGPU,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPURenderBundleEncoder::new_inherited(
|
||||
|
@ -70,12 +72,12 @@ impl GPURenderBundleEncoder {
|
|||
|
||||
impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -103,11 +105,21 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
|||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-setindexbuffer
|
||||
fn SetIndexBuffer(&self, buffer: &GPUBuffer, offset: u64, size: u64) {
|
||||
fn SetIndexBuffer(
|
||||
&self,
|
||||
buffer: &GPUBuffer,
|
||||
index_format: GPUIndexFormat,
|
||||
offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
if let Some(encoder) = self.render_bundle_encoder.borrow_mut().as_mut() {
|
||||
wgpu_bundle::wgpu_render_bundle_set_index_buffer(
|
||||
encoder,
|
||||
buffer.id().0,
|
||||
match index_format {
|
||||
GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
|
||||
GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
|
||||
},
|
||||
offset,
|
||||
wgt::BufferSize::new(size),
|
||||
);
|
||||
|
@ -175,7 +187,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
|||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-drawindexedindirect
|
||||
fn DrawIndexedIndirect(&self, indirect_buffer: &GPUBuffer, indirect_offset: u64) {
|
||||
if let Some(encoder) = self.render_bundle_encoder.borrow_mut().as_mut() {
|
||||
wgpu_bundle::wgpu_render_pass_bundle_indexed_indirect(
|
||||
wgpu_bundle::wgpu_render_bundle_draw_indexed_indirect(
|
||||
encoder,
|
||||
indirect_buffer.id().0,
|
||||
indirect_offset,
|
||||
|
@ -214,7 +226,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
|||
render_bundle,
|
||||
self.device.id(),
|
||||
self.channel.clone(),
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,16 @@ use webgpu::{
|
|||
wgt, WebGPU, WebGPURequest,
|
||||
};
|
||||
|
||||
use super::bindings::codegen::Bindings::GPURenderPipelineBinding::GPUIndexFormat;
|
||||
use super::bindings::error::Fallible;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPURenderPassEncoder {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-core"]
|
||||
#[no_trace]
|
||||
render_pass: DomRefCell<Option<RenderPass>>,
|
||||
|
@ -39,7 +42,7 @@ impl GPURenderPassEncoder {
|
|||
channel: WebGPU,
|
||||
render_pass: Option<RenderPass>,
|
||||
parent: &GPUCommandEncoder,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
|
@ -55,7 +58,7 @@ impl GPURenderPassEncoder {
|
|||
channel: WebGPU,
|
||||
render_pass: Option<RenderPass>,
|
||||
parent: &GPUCommandEncoder,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPURenderPassEncoder::new_inherited(
|
||||
|
@ -71,12 +74,12 @@ impl GPURenderPassEncoder {
|
|||
|
||||
impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -127,7 +130,7 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-setblendcolor
|
||||
fn SetBlendColor(&self, color: GPUColor) {
|
||||
fn SetBlendConstant(&self, color: GPUColor) {
|
||||
if let Some(render_pass) = self.render_pass.borrow_mut().as_mut() {
|
||||
let colors = match color {
|
||||
GPUColor::GPUColorDict(d) => wgt::Color {
|
||||
|
@ -149,7 +152,7 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
}
|
||||
},
|
||||
};
|
||||
wgpu_render::wgpu_render_pass_set_blend_color(render_pass, &colors);
|
||||
wgpu_render::wgpu_render_pass_set_blend_constant(render_pass, &colors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,8 +163,8 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass
|
||||
fn EndPass(&self) {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-end
|
||||
fn End(&self) -> Fallible<()> {
|
||||
let render_pass = self.render_pass.borrow_mut().take();
|
||||
self.channel
|
||||
.0
|
||||
|
@ -178,6 +181,7 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
GPUCommandEncoderState::Open,
|
||||
GPUCommandEncoderState::EncodingRenderPass,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-setpipeline
|
||||
|
@ -187,12 +191,22 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurenderencoderbase-setindexbuffer
|
||||
fn SetIndexBuffer(&self, buffer: &GPUBuffer, offset: u64, size: u64) {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-setindexbuffer
|
||||
fn SetIndexBuffer(
|
||||
&self,
|
||||
buffer: &GPUBuffer,
|
||||
index_format: GPUIndexFormat,
|
||||
offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
if let Some(render_pass) = self.render_pass.borrow_mut().as_mut() {
|
||||
wgpu_render::wgpu_render_pass_set_index_buffer(
|
||||
render_pass,
|
||||
buffer.id().0,
|
||||
match index_format {
|
||||
GPUIndexFormat::Uint16 => wgt::IndexFormat::Uint16,
|
||||
GPUIndexFormat::Uint32 => wgt::IndexFormat::Uint32,
|
||||
},
|
||||
offset,
|
||||
wgt::BufferSize::new(size),
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ use webgpu::{WebGPUBindGroupLayout, WebGPURenderPipeline};
|
|||
#[dom_struct]
|
||||
pub struct GPURenderPipeline {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
render_pipeline: WebGPURenderPipeline,
|
||||
#[no_trace]
|
||||
|
@ -29,7 +29,7 @@ pub struct GPURenderPipeline {
|
|||
impl GPURenderPipeline {
|
||||
fn new_inherited(
|
||||
render_pipeline: WebGPURenderPipeline,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
device: &GPUDevice,
|
||||
) -> Self {
|
||||
|
@ -45,7 +45,7 @@ impl GPURenderPipeline {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
render_pipeline: WebGPURenderPipeline,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
bgls: Vec<WebGPUBindGroupLayout>,
|
||||
device: &GPUDevice,
|
||||
) -> DomRoot<Self> {
|
||||
|
@ -69,12 +69,12 @@ impl GPURenderPipeline {
|
|||
|
||||
impl GPURenderPipelineMethods for GPURenderPipeline {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ impl GPURenderPipelineMethods for GPURenderPipeline {
|
|||
Ok(GPUBindGroupLayout::new(
|
||||
&self.global(),
|
||||
self.bind_group_layouts[index as usize],
|
||||
None,
|
||||
USVString::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use webgpu::{WebGPUDevice, WebGPUSampler};
|
|||
#[dom_struct]
|
||||
pub struct GPUSampler {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
|
@ -27,7 +27,7 @@ impl GPUSampler {
|
|||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
sampler: WebGPUSampler,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -43,7 +43,7 @@ impl GPUSampler {
|
|||
device: WebGPUDevice,
|
||||
compare_enable: bool,
|
||||
sampler: WebGPUSampler,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUSampler::new_inherited(
|
||||
|
@ -65,12 +65,12 @@ impl GPUSampler {
|
|||
|
||||
impl GPUSamplerMethods for GPUSampler {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* 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::rc::Rc;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUShaderModuleBinding::GPUShaderModuleMethods;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
|
@ -11,16 +13,19 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use dom_struct::dom_struct;
|
||||
use webgpu::WebGPUShaderModule;
|
||||
|
||||
use super::bindings::error::Fallible;
|
||||
use super::promise::Promise;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUShaderModule {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
shader_module: WebGPUShaderModule,
|
||||
}
|
||||
|
||||
impl GPUShaderModule {
|
||||
fn new_inherited(shader_module: WebGPUShaderModule, label: Option<USVString>) -> Self {
|
||||
fn new_inherited(shader_module: WebGPUShaderModule, label: USVString) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
label: DomRefCell::new(label),
|
||||
|
@ -31,7 +36,7 @@ impl GPUShaderModule {
|
|||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
shader_module: WebGPUShaderModule,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUShaderModule::new_inherited(shader_module, label)),
|
||||
|
@ -48,12 +53,17 @@ impl GPUShaderModule {
|
|||
|
||||
impl GPUShaderModuleMethods for GPUShaderModule {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpushadermodule-getcompilationinfo
|
||||
fn CompilationInfo(&self) -> Fallible<Rc<Promise>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
165
components/script/dom/gpusupportedlimits.rs
Normal file
165
components/script/dom/gpusupportedlimits.rs
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* 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 super::bindings::codegen::Bindings::GPUSupportedLimitsBinding::GPUSupportedLimitsBinding;
|
||||
use super::bindings::reflector::reflect_dom_object;
|
||||
use super::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::reflector::Reflector;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use dom_struct::dom_struct;
|
||||
use webgpu::wgt::Limits;
|
||||
use GPUSupportedLimitsBinding::GPUSupportedLimitsMethods;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUSupportedLimits {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "defined in wgpu-types"]
|
||||
#[no_trace]
|
||||
limits: Limits,
|
||||
}
|
||||
|
||||
impl GPUSupportedLimits {
|
||||
fn new_inherited(limits: Limits) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
limits,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: &GlobalScope, limits: Limits) -> DomRoot<Self> {
|
||||
reflect_dom_object(Box::new(Self::new_inherited(limits)), global)
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUSupportedLimitsMethods for GPUSupportedLimits {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxtexturedimension1d
|
||||
fn MaxTextureDimension1D(&self) -> u32 {
|
||||
self.limits.max_texture_dimension_1d
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxtexturedimension2d
|
||||
fn MaxTextureDimension2D(&self) -> u32 {
|
||||
self.limits.max_texture_dimension_2d
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxtexturedimension3d
|
||||
fn MaxTextureDimension3D(&self) -> u32 {
|
||||
self.limits.max_texture_dimension_3d
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxtexturearraylayers
|
||||
fn MaxTextureArrayLayers(&self) -> u32 {
|
||||
self.limits.max_texture_array_layers
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxbindgroups
|
||||
fn MaxBindGroups(&self) -> u32 {
|
||||
self.limits.max_bind_groups
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxdynamicuniformbuffersperpipelinelayout
|
||||
fn MaxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 {
|
||||
self.limits.max_dynamic_uniform_buffers_per_pipeline_layout
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxdynamicstoragebuffersperpipelinelayout
|
||||
fn MaxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 {
|
||||
self.limits.max_dynamic_storage_buffers_per_pipeline_layout
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxsampledtexturespershaderstage
|
||||
fn MaxSampledTexturesPerShaderStage(&self) -> u32 {
|
||||
self.limits.max_sampled_textures_per_shader_stage
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxsamplerspershaderstage
|
||||
fn MaxSamplersPerShaderStage(&self) -> u32 {
|
||||
self.limits.max_samplers_per_shader_stage
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxstoragebufferspershaderstage
|
||||
fn MaxStorageBuffersPerShaderStage(&self) -> u32 {
|
||||
self.limits.max_storage_buffers_per_shader_stage
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxstoragetexturespershaderstage
|
||||
fn MaxStorageTexturesPerShaderStage(&self) -> u32 {
|
||||
self.limits.max_storage_textures_per_shader_stage
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxuniformbufferspershaderstage
|
||||
fn MaxUniformBuffersPerShaderStage(&self) -> u32 {
|
||||
self.limits.max_uniform_buffers_per_shader_stage
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxuniformbufferbindingsize
|
||||
fn MaxUniformBufferBindingSize(&self) -> u32 {
|
||||
self.limits.max_uniform_buffer_binding_size
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxstoragebufferbindingsize
|
||||
fn MaxStorageBufferBindingSize(&self) -> u32 {
|
||||
self.limits.max_storage_buffer_binding_size
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-minuniformbufferoffsetalignment
|
||||
fn MinUniformBufferOffsetAlignment(&self) -> u32 {
|
||||
self.limits.min_uniform_buffer_offset_alignment
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-minstoragebufferoffsetalignment
|
||||
fn MinStorageBufferOffsetAlignment(&self) -> u32 {
|
||||
self.limits.min_storage_buffer_offset_alignment
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxvertexbuffers
|
||||
fn MaxVertexBuffers(&self) -> u32 {
|
||||
self.limits.max_vertex_buffers
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxvertexattributes
|
||||
fn MaxVertexAttributes(&self) -> u32 {
|
||||
self.limits.max_vertex_attributes
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxvertexbufferarraystride
|
||||
fn MaxVertexBufferArrayStride(&self) -> u32 {
|
||||
self.limits.max_vertex_buffer_array_stride
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxinterstageshadercomponents
|
||||
fn MaxInterStageShaderComponents(&self) -> u32 {
|
||||
self.limits.max_inter_stage_shader_components
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeworkgroupstoragesize
|
||||
fn MaxComputeWorkgroupStorageSize(&self) -> u32 {
|
||||
self.limits.max_compute_workgroup_storage_size
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeinvocationsperworkgroup
|
||||
fn MaxComputeInvocationsPerWorkgroup(&self) -> u32 {
|
||||
self.limits.max_compute_invocations_per_workgroup
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeworkgroupsizex
|
||||
fn MaxComputeWorkgroupSizeX(&self) -> u32 {
|
||||
self.limits.max_compute_workgroup_size_x
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeworkgroupsizey
|
||||
fn MaxComputeWorkgroupSizeY(&self) -> u32 {
|
||||
self.limits.max_compute_workgroup_size_y
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeworkgroupsizez
|
||||
fn MaxComputeWorkgroupSizeZ(&self) -> u32 {
|
||||
self.limits.max_compute_workgroup_size_z
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcomputeworkgroupsperdimension
|
||||
fn MaxComputeWorkgroupsPerDimension(&self) -> u32 {
|
||||
self.limits.max_compute_workgroups_per_dimension
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/* 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 crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUSwapChainBinding::GPUSwapChainMethods;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpucanvascontext::GPUCanvasContext;
|
||||
use crate::dom::gputexture::GPUTexture;
|
||||
use dom_struct::dom_struct;
|
||||
use webgpu::{WebGPU, WebGPURequest, WebGPUTexture};
|
||||
use webrender_api::ImageKey;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUSwapChain {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
#[no_trace]
|
||||
channel: WebGPU,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
context: Dom<GPUCanvasContext>,
|
||||
texture: Dom<GPUTexture>,
|
||||
}
|
||||
|
||||
impl GPUSwapChain {
|
||||
fn new_inherited(
|
||||
channel: WebGPU,
|
||||
context: &GPUCanvasContext,
|
||||
texture: &GPUTexture,
|
||||
label: Option<USVString>,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
channel,
|
||||
context: Dom::from_ref(context),
|
||||
texture: Dom::from_ref(texture),
|
||||
label: DomRefCell::new(label),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
channel: WebGPU,
|
||||
context: &GPUCanvasContext,
|
||||
texture: &GPUTexture,
|
||||
label: Option<USVString>,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUSwapChain::new_inherited(
|
||||
channel, context, texture, label,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUSwapChain {
|
||||
pub fn destroy(&self, external_id: u64, image_key: ImageKey) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
None,
|
||||
WebGPURequest::DestroySwapChain {
|
||||
external_id,
|
||||
image_key,
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send DestroySwapChain-ImageKey({:?}) ({})",
|
||||
image_key, e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn texture_id(&self) -> WebGPUTexture {
|
||||
self.texture.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUSwapChainMethods for GPUSwapChain {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuswapchain-getcurrenttexture
|
||||
fn GetCurrentTexture(&self) -> DomRoot<GPUTexture> {
|
||||
self.context.mark_as_dirty();
|
||||
DomRoot::from_ref(&*self.texture)
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ use crate::dom::gpudevice::{
|
|||
use crate::dom::gputextureview::GPUTextureView;
|
||||
use dom_struct::dom_struct;
|
||||
use std::cell::Cell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::string::String;
|
||||
use webgpu::{
|
||||
identity::WebGPUOpResult, wgpu::resource, wgt, WebGPU, WebGPURequest, WebGPUTexture,
|
||||
|
@ -31,7 +30,7 @@ pub struct GPUTexture {
|
|||
reflector_: Reflector,
|
||||
#[no_trace]
|
||||
texture: WebGPUTexture,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
device: Dom<GPUDevice>,
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
#[no_trace]
|
||||
|
@ -57,7 +56,7 @@ impl GPUTexture {
|
|||
dimension: GPUTextureDimension,
|
||||
format: GPUTextureFormat,
|
||||
texture_usage: u32,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> Self {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -86,7 +85,7 @@ impl GPUTexture {
|
|||
dimension: GPUTextureDimension,
|
||||
format: GPUTextureFormat,
|
||||
texture_usage: u32,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUTexture::new_inherited(
|
||||
|
@ -120,46 +119,37 @@ impl GPUTexture {
|
|||
|
||||
impl GPUTextureMethods for GPUTexture {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gputexture-createview
|
||||
fn CreateView(&self, descriptor: &GPUTextureViewDescriptor) -> DomRoot<GPUTextureView> {
|
||||
let scope_id = self.device.use_current_scope();
|
||||
let mut valid = true;
|
||||
let level_count = descriptor.mipLevelCount.and_then(|count| {
|
||||
if count == 0 {
|
||||
valid = false;
|
||||
}
|
||||
NonZeroU32::new(count)
|
||||
});
|
||||
let array_layer_count = descriptor.arrayLayerCount.and_then(|count| {
|
||||
if count == 0 {
|
||||
valid = false;
|
||||
}
|
||||
NonZeroU32::new(count)
|
||||
});
|
||||
|
||||
let desc = if valid {
|
||||
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),
|
||||
dimension: descriptor.dimension.map(convert_texture_view_dimension),
|
||||
aspect: match descriptor.aspect {
|
||||
GPUTextureAspect::All => wgt::TextureAspect::All,
|
||||
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
|
||||
GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
|
||||
range: wgt::ImageSubresourceRange {
|
||||
aspect: match descriptor.aspect {
|
||||
GPUTextureAspect::All => wgt::TextureAspect::All,
|
||||
GPUTextureAspect::Stencil_only => wgt::TextureAspect::StencilOnly,
|
||||
GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
|
||||
},
|
||||
base_mip_level: descriptor.baseMipLevel,
|
||||
mip_level_count: descriptor.mipLevelCount,
|
||||
base_array_layer: descriptor.baseArrayLayer,
|
||||
array_layer_count: descriptor.arrayLayerCount,
|
||||
},
|
||||
base_mip_level: descriptor.baseMipLevel,
|
||||
level_count,
|
||||
base_array_layer: descriptor.baseArrayLayer,
|
||||
array_layer_count,
|
||||
})
|
||||
} else {
|
||||
self.device.handle_server_msg(
|
||||
|
@ -196,7 +186,7 @@ impl GPUTextureMethods for GPUTexture {
|
|||
&self.global(),
|
||||
texture_view,
|
||||
&self,
|
||||
descriptor.parent.label.as_ref().cloned(),
|
||||
descriptor.parent.label.clone().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use webgpu::WebGPUTextureView;
|
|||
#[dom_struct]
|
||||
pub struct GPUTextureView {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
label: DomRefCell<USVString>,
|
||||
#[no_trace]
|
||||
texture_view: WebGPUTextureView,
|
||||
texture: Dom<GPUTexture>,
|
||||
|
@ -25,7 +25,7 @@ impl GPUTextureView {
|
|||
fn new_inherited(
|
||||
texture_view: WebGPUTextureView,
|
||||
texture: &GPUTexture,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> GPUTextureView {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -39,7 +39,7 @@ impl GPUTextureView {
|
|||
global: &GlobalScope,
|
||||
texture_view: WebGPUTextureView,
|
||||
texture: &GPUTexture,
|
||||
label: Option<USVString>,
|
||||
label: USVString,
|
||||
) -> DomRoot<GPUTextureView> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUTextureView::new_inherited(texture_view, texture, label)),
|
||||
|
@ -56,12 +56,12 @@ impl GPUTextureView {
|
|||
|
||||
impl GPUTextureViewMethods for GPUTextureView {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
fn Label(&self) -> USVString {
|
||||
self.label.borrow().clone()
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn SetLabel(&self, value: Option<USVString>) {
|
||||
fn SetLabel(&self, value: USVString) {
|
||||
*self.label.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use dom_struct::dom_struct;
|
||||
use js::rust::HandleObject;
|
||||
|
||||
use super::bindings::error::Fallible;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUValidationError {
|
||||
reflector_: Reflector,
|
||||
|
@ -46,8 +48,8 @@ impl GPUValidationError {
|
|||
global: &GlobalScope,
|
||||
proto: Option<HandleObject>,
|
||||
message: DOMString,
|
||||
) -> DomRoot<Self> {
|
||||
GPUValidationError::new_with_proto(global, proto, message)
|
||||
) -> Fallible<DomRoot<Self>> {
|
||||
Ok(GPUValidationError::new_with_proto(global, proto, message))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -269,9 +269,8 @@ impl HTMLCanvasElement {
|
|||
.script_to_constellation_chan()
|
||||
.send(ScriptMsg::GetWebGPUChan(sender));
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let channel = receiver.recv().expect("Failed to get WebGPU channel");
|
||||
let context = GPUCanvasContext::new(window.upcast::<GlobalScope>(), self, size, channel);
|
||||
let context = GPUCanvasContext::new(window.upcast::<GlobalScope>(), self, channel);
|
||||
*self.context.borrow_mut() = Some(CanvasContext::WebGPU(Dom::from_ref(&*context)));
|
||||
Some(context)
|
||||
}
|
||||
|
@ -374,7 +373,7 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
|||
"webgl2" | "experimental-webgl2" => self
|
||||
.get_or_init_webgl2_context(cx, options)
|
||||
.map(RenderingContext::WebGL2RenderingContext),
|
||||
"gpupresent" => self
|
||||
"webgpu" => self
|
||||
.get_or_init_webgpu_context()
|
||||
.map(RenderingContext::GPUCanvasContext),
|
||||
_ => None,
|
||||
|
|
|
@ -321,6 +321,7 @@ pub mod gamepadpose;
|
|||
pub mod globalscope;
|
||||
pub mod gpu;
|
||||
pub mod gpuadapter;
|
||||
pub mod gpuadapterinfo;
|
||||
pub mod gpubindgroup;
|
||||
pub mod gpubindgrouplayout;
|
||||
pub mod gpubuffer;
|
||||
|
@ -329,6 +330,8 @@ pub mod gpucanvascontext;
|
|||
pub mod gpucolorwrite;
|
||||
pub mod gpucommandbuffer;
|
||||
pub mod gpucommandencoder;
|
||||
pub mod gpucompilationinfo;
|
||||
pub mod gpucompilationmessage;
|
||||
pub mod gpucomputepassencoder;
|
||||
pub mod gpucomputepipeline;
|
||||
pub mod gpudevice;
|
||||
|
@ -336,6 +339,7 @@ pub mod gpudevicelostinfo;
|
|||
pub mod gpumapmode;
|
||||
pub mod gpuoutofmemoryerror;
|
||||
pub mod gpupipelinelayout;
|
||||
pub mod gpuqueryset;
|
||||
pub mod gpuqueue;
|
||||
pub mod gpurenderbundle;
|
||||
pub mod gpurenderbundleencoder;
|
||||
|
@ -344,7 +348,7 @@ pub mod gpurenderpipeline;
|
|||
pub mod gpusampler;
|
||||
pub mod gpushadermodule;
|
||||
pub mod gpushaderstage;
|
||||
pub mod gpuswapchain;
|
||||
pub mod gpusupportedlimits;
|
||||
pub mod gputexture;
|
||||
pub mod gputextureusage;
|
||||
pub mod gputextureview;
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpu-interface
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPU {
|
||||
[NewObject]
|
||||
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
|
||||
GPUTextureFormat getPreferredCanvasFormat();
|
||||
};
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions
|
||||
dictionary GPURequestAdapterOptions {
|
||||
GPUPowerPreference powerPreference;
|
||||
boolean forceFallbackAdapter = false;
|
||||
};
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference
|
||||
enum GPUPowerPreference {
|
||||
"low-power",
|
||||
"high-performance"
|
||||
|
|
|
@ -5,35 +5,29 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpuadapter
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUAdapter {
|
||||
readonly attribute DOMString name;
|
||||
readonly attribute object extensions;
|
||||
//readonly attribute GPULimits limits; Don’t expose higher limits for now.
|
||||
//[SameObject] readonly attribute GPUSupportedFeatures features;
|
||||
[SameObject] readonly attribute GPUSupportedLimits limits;
|
||||
readonly attribute boolean isFallbackAdapter;
|
||||
|
||||
Promise<GPUDevice?> requestDevice(optional GPUDeviceDescriptor descriptor = {});
|
||||
[NewObject]
|
||||
Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {});
|
||||
[NewObject]
|
||||
Promise<GPUAdapterInfo> requestAdapterInfo(optional sequence<DOMString> unmaskHints = []);
|
||||
};
|
||||
|
||||
dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
|
||||
sequence<GPUExtensionName> extensions = [];
|
||||
GPULimits limits = {};
|
||||
dictionary GPUDeviceDescriptor {
|
||||
sequence<GPUFeatureName> requiredFeatures = [];
|
||||
record<DOMString, GPUSize64> requiredLimits;
|
||||
};
|
||||
|
||||
enum GPUExtensionName {
|
||||
"depth-clamping",
|
||||
enum GPUFeatureName {
|
||||
"depth-clip-control",
|
||||
"depth24unorm-stencil8",
|
||||
"depth32float-stencil8",
|
||||
"pipeline-statistics-query",
|
||||
"texture-compression-bc",
|
||||
"texture-compression-etc2",
|
||||
"texture-compression-astc",
|
||||
"timestamp-query",
|
||||
};
|
||||
|
||||
dictionary GPULimits {
|
||||
GPUSize32 maxBindGroups = 4;
|
||||
GPUSize32 maxDynamicUniformBuffersPerPipelineLayout = 8;
|
||||
GPUSize32 maxDynamicStorageBuffersPerPipelineLayout = 4;
|
||||
GPUSize32 maxSampledTexturesPerShaderStage = 16;
|
||||
GPUSize32 maxSamplersPerShaderStage = 16;
|
||||
GPUSize32 maxStorageBuffersPerShaderStage = 4;
|
||||
GPUSize32 maxStorageTexturesPerShaderStage = 4;
|
||||
GPUSize32 maxUniformBuffersPerShaderStage = 12;
|
||||
GPUSize32 maxUniformBufferBindingSize = 16384;
|
||||
"indirect-first-instance",
|
||||
};
|
||||
|
|
12
components/script/dom/webidls/GPUAdapterInfo.webidl
Normal file
12
components/script/dom/webidls/GPUAdapterInfo.webidl
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpuadapterinfo
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUAdapterInfo {
|
||||
readonly attribute DOMString vendor;
|
||||
readonly attribute DOMString architecture;
|
||||
readonly attribute DOMString device;
|
||||
readonly attribute DOMString description;
|
||||
};
|
|
@ -13,16 +13,14 @@ dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase {
|
|||
required sequence<GPUBindGroupEntry> entries;
|
||||
};
|
||||
|
||||
typedef (GPUSampler or GPUTextureView or GPUBufferBindings) GPUBindingResource;
|
||||
typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource;
|
||||
|
||||
dictionary GPUBindGroupEntry {
|
||||
required GPUIndex32 binding;
|
||||
required GPUBindingResource resource;
|
||||
};
|
||||
|
||||
// Note: Servo codegen doesn't like the name `GPUBufferBinding` because it's already occupied
|
||||
// dictionary GPUBufferBinding {
|
||||
dictionary GPUBufferBindings {
|
||||
dictionary GPUBufferBinding {
|
||||
required GPUBuffer buffer;
|
||||
GPUSize64 offset = 0;
|
||||
GPUSize64 size;
|
||||
|
|
|
@ -15,22 +15,54 @@ dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase {
|
|||
dictionary GPUBindGroupLayoutEntry {
|
||||
required GPUIndex32 binding;
|
||||
required GPUShaderStageFlags visibility;
|
||||
required GPUBindingType type;
|
||||
boolean hasDynamicOffset;
|
||||
GPUSize64 minBufferBindingSize;
|
||||
GPUTextureViewDimension viewDimension;
|
||||
GPUTextureComponentType textureComponentType;
|
||||
GPUTextureFormat storageTextureFormat;
|
||||
GPUBufferBindingLayout buffer;
|
||||
GPUSamplerBindingLayout sampler;
|
||||
GPUTextureBindingLayout texture;
|
||||
GPUStorageTextureBindingLayout storageTexture;
|
||||
};
|
||||
|
||||
enum GPUBindingType {
|
||||
"uniform-buffer",
|
||||
"storage-buffer",
|
||||
"readonly-storage-buffer",
|
||||
"sampler",
|
||||
"comparison-sampler",
|
||||
"sampled-texture",
|
||||
"multisampled-texture",
|
||||
"readonly-storage-texture",
|
||||
"writeonly-storage-texture"
|
||||
enum GPUBufferBindingType {
|
||||
"uniform",
|
||||
"storage",
|
||||
"read-only-storage",
|
||||
};
|
||||
|
||||
dictionary GPUBufferBindingLayout {
|
||||
GPUBufferBindingType type = "uniform";
|
||||
boolean hasDynamicOffset = false;
|
||||
GPUSize64 minBindingSize = 0;
|
||||
};
|
||||
|
||||
enum GPUSamplerBindingType {
|
||||
"filtering",
|
||||
"non-filtering",
|
||||
"comparison",
|
||||
};
|
||||
|
||||
dictionary GPUSamplerBindingLayout {
|
||||
GPUSamplerBindingType type = "filtering";
|
||||
};
|
||||
|
||||
enum GPUTextureSampleType {
|
||||
"float",
|
||||
"unfilterable-float",
|
||||
"depth",
|
||||
"sint",
|
||||
"uint",
|
||||
};
|
||||
|
||||
dictionary GPUTextureBindingLayout {
|
||||
GPUTextureSampleType sampleType = "float";
|
||||
GPUTextureViewDimension viewDimension = "2d";
|
||||
boolean multisampled = false;
|
||||
};
|
||||
|
||||
enum GPUStorageTextureAccess {
|
||||
"write-only",
|
||||
};
|
||||
|
||||
dictionary GPUStorageTextureBindingLayout {
|
||||
GPUStorageTextureAccess access = "write-only";
|
||||
required GPUTextureFormat format;
|
||||
GPUTextureViewDimension viewDimension = "2d";
|
||||
};
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpubuffer
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUBuffer {
|
||||
[NewObject]
|
||||
Promise<undefined> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
|
||||
[Throws] ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
|
||||
[NewObject, Throws]
|
||||
ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
|
||||
[Throws]
|
||||
undefined unmap();
|
||||
|
||||
[Throws]
|
||||
undefined destroy();
|
||||
};
|
||||
GPUBuffer includes GPUObjectBase;
|
||||
|
@ -19,4 +22,4 @@ dictionary GPUBufferDescriptor : GPUObjectDescriptorBase {
|
|||
boolean mappedAtCreation = false;
|
||||
};
|
||||
|
||||
typedef unsigned long long GPUSize64;
|
||||
typedef [EnforceRange] unsigned long long GPUSize64;
|
||||
|
|
|
@ -16,5 +16,4 @@ interface GPUBufferUsage {
|
|||
const GPUBufferUsageFlags INDIRECT = 0x0100;
|
||||
const GPUBufferUsageFlags QUERY_RESOLVE = 0x0200;
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUBufferUsageFlags;
|
||||
|
|
|
@ -5,13 +5,27 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpucanvascontext
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUCanvasContext {
|
||||
GPUSwapChain configureSwapChain(GPUSwapChainDescriptor descriptor);
|
||||
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
|
||||
|
||||
//Promise<GPUTextureFormat> getSwapChainPreferredFormat(GPUDevice device);
|
||||
// Calling configure() a second time invalidates the previous one,
|
||||
// and all of the textures it's produced.
|
||||
undefined configure(GPUCanvasConfiguration descriptor);
|
||||
undefined unconfigure();
|
||||
|
||||
[Throws]
|
||||
GPUTexture getCurrentTexture();
|
||||
};
|
||||
|
||||
dictionary GPUSwapChainDescriptor : GPUObjectDescriptorBase {
|
||||
enum GPUCanvasAlphaMode {
|
||||
"opaque",
|
||||
"premultiplied",
|
||||
};
|
||||
|
||||
dictionary GPUCanvasConfiguration {
|
||||
required GPUDevice device;
|
||||
required GPUTextureFormat format;
|
||||
GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.OUTPUT_ATTACHMENT
|
||||
GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.RENDER_ATTACHMENT
|
||||
sequence<GPUTextureFormat> viewFormats = [];
|
||||
// PredefinedColorSpace colorSpace = "srgb"; // TODO
|
||||
GPUCanvasAlphaMode alphaMode = "opaque";
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpucolorwrite
|
||||
// https://gpuweb.github.io/gpuweb/#namespacedef-gpucolorwrite
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUColorWrite {
|
||||
const GPUColorWriteFlags RED = 0x1;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpucommandbuffer
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUCommandBuffer {
|
||||
//readonly attribute Promise<double> executionTime;
|
||||
};
|
||||
GPUCommandBuffer includes GPUObjectBase;
|
||||
|
||||
dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
|
||||
};
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpucommandencoder
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUCommandEncoder {
|
||||
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
|
||||
[NewObject]
|
||||
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
|
||||
[NewObject]
|
||||
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
|
||||
|
||||
undefined copyBufferToBuffer(
|
||||
GPUBuffer source,
|
||||
|
@ -16,78 +18,117 @@ interface GPUCommandEncoder {
|
|||
GPUSize64 size);
|
||||
|
||||
undefined copyBufferToTexture(
|
||||
GPUBufferCopyView source,
|
||||
GPUTextureCopyView destination,
|
||||
GPUImageCopyBuffer source,
|
||||
GPUImageCopyTexture destination,
|
||||
GPUExtent3D copySize);
|
||||
|
||||
undefined copyTextureToBuffer(
|
||||
GPUTextureCopyView source,
|
||||
GPUBufferCopyView destination,
|
||||
GPUImageCopyTexture source,
|
||||
GPUImageCopyBuffer destination,
|
||||
GPUExtent3D copySize);
|
||||
|
||||
undefined copyTextureToTexture(
|
||||
GPUTextureCopyView source,
|
||||
GPUTextureCopyView destination,
|
||||
GPUImageCopyTexture source,
|
||||
GPUImageCopyTexture destination,
|
||||
GPUExtent3D copySize);
|
||||
|
||||
//void pushDebugGroup(USVString groupLabel);
|
||||
//void popDebugGroup();
|
||||
//void insertDebugMarker(USVString markerLabel);
|
||||
/*
|
||||
undefined copyImageBitmapToTexture(
|
||||
GPUImageBitmapCopyView source,
|
||||
GPUImageCopyTexture destination,
|
||||
GPUExtent3D copySize);
|
||||
*/
|
||||
|
||||
//void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
|
||||
//void resolveQuerySet(
|
||||
// GPUQuerySet querySet,
|
||||
// GPUSize32 firstQuery,
|
||||
// GPUSize32 queryCount,
|
||||
// GPUBuffer destination,
|
||||
// GPUSize64 destinationOffset);
|
||||
//undefined pushDebugGroup(USVString groupLabel);
|
||||
//undefined popDebugGroup();
|
||||
//undefined insertDebugMarker(USVString markerLabel);
|
||||
|
||||
[NewObject]
|
||||
GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {});
|
||||
};
|
||||
GPUCommandEncoder includes GPUObjectBase;
|
||||
|
||||
dictionary GPUImageDataLayout {
|
||||
GPUSize64 offset = 0;
|
||||
GPUSize32 bytesPerRow;
|
||||
GPUSize32 rowsPerImage;
|
||||
};
|
||||
|
||||
dictionary GPUImageCopyBuffer : GPUImageDataLayout {
|
||||
required GPUBuffer buffer;
|
||||
};
|
||||
|
||||
dictionary GPUImageCopyExternalImage {
|
||||
required (ImageBitmap or HTMLCanvasElement or OffscreenCanvas) source;
|
||||
GPUOrigin2D origin = {};
|
||||
boolean flipY = false;
|
||||
};
|
||||
|
||||
dictionary GPUImageCopyTexture {
|
||||
required GPUTexture texture;
|
||||
GPUIntegerCoordinate mipLevel = 0;
|
||||
GPUOrigin3D origin;
|
||||
GPUTextureAspect aspect = "all";
|
||||
};
|
||||
|
||||
dictionary GPUImageCopyTextureTagged : GPUImageCopyTexture {
|
||||
//GPUPredefinedColorSpace colorSpace = "srgb"; //TODO
|
||||
boolean premultipliedAlpha = false;
|
||||
};
|
||||
|
||||
dictionary GPUImageBitmapCopyView {
|
||||
//required ImageBitmap imageBitmap; //TODO
|
||||
GPUOrigin2D origin;
|
||||
};
|
||||
|
||||
dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase {
|
||||
};
|
||||
|
||||
dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase {
|
||||
};
|
||||
|
||||
//
|
||||
dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase {
|
||||
required sequence<GPURenderPassColorAttachmentDescriptor> colorAttachments;
|
||||
GPURenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
|
||||
//GPUQuerySet occlusionQuerySet;
|
||||
required sequence<GPURenderPassColorAttachment> colorAttachments;
|
||||
GPURenderPassDepthStencilAttachment depthStencilAttachment;
|
||||
GPUQuerySet occlusionQuerySet;
|
||||
};
|
||||
|
||||
dictionary GPURenderPassColorAttachmentDescriptor {
|
||||
required GPUTextureView attachment;
|
||||
dictionary GPURenderPassColorAttachment {
|
||||
required GPUTextureView view;
|
||||
GPUTextureView resolveTarget;
|
||||
|
||||
required (GPULoadOp or GPUColor) loadValue;
|
||||
GPUStoreOp storeOp = "store";
|
||||
GPUColor clearValue;
|
||||
required GPULoadOp loadOp;
|
||||
required GPUStoreOp storeOp;
|
||||
};
|
||||
|
||||
dictionary GPURenderPassDepthStencilAttachmentDescriptor {
|
||||
required GPUTextureView attachment;
|
||||
dictionary GPURenderPassDepthStencilAttachment {
|
||||
required GPUTextureView view;
|
||||
|
||||
required (GPULoadOp or float) depthLoadValue;
|
||||
required GPUStoreOp depthStoreOp;
|
||||
float depthClearValue;
|
||||
GPULoadOp depthLoadOp;
|
||||
GPUStoreOp depthStoreOp;
|
||||
boolean depthReadOnly = false;
|
||||
|
||||
required GPUStencilLoadValue stencilLoadValue;
|
||||
required GPUStoreOp stencilStoreOp;
|
||||
GPUStencilValue stencilClearValue = 0;
|
||||
GPULoadOp stencilLoadOp;
|
||||
GPUStoreOp stencilStoreOp;
|
||||
boolean stencilReadOnly = false;
|
||||
};
|
||||
|
||||
typedef (GPULoadOp or GPUStencilValue) GPUStencilLoadValue;
|
||||
|
||||
enum GPULoadOp {
|
||||
"load"
|
||||
"load",
|
||||
"clear"
|
||||
};
|
||||
|
||||
enum GPUStoreOp {
|
||||
"store",
|
||||
"clear"
|
||||
"discard"
|
||||
};
|
||||
|
||||
dictionary GPURenderPassLayout: GPUObjectDescriptorBase {
|
||||
// TODO: We don't support nullable enumerated arguments yet
|
||||
required sequence<GPUTextureFormat> colorFormats;
|
||||
GPUTextureFormat depthStencilFormat;
|
||||
GPUSize32 sampleCount = 1;
|
||||
};
|
||||
|
||||
dictionary GPUColorDict {
|
||||
|
@ -98,21 +139,11 @@ dictionary GPUColorDict {
|
|||
};
|
||||
typedef (sequence<double> or GPUColorDict) GPUColor;
|
||||
|
||||
dictionary GPUTextureDataLayout {
|
||||
GPUSize64 offset = 0;
|
||||
required GPUSize32 bytesPerRow;
|
||||
GPUSize32 rowsPerImage = 0;
|
||||
};
|
||||
|
||||
dictionary GPUBufferCopyView : GPUTextureDataLayout {
|
||||
required GPUBuffer buffer;
|
||||
};
|
||||
|
||||
dictionary GPUTextureCopyView {
|
||||
required GPUTexture texture;
|
||||
GPUIntegerCoordinate mipLevel = 0;
|
||||
GPUOrigin3D origin = {};
|
||||
dictionary GPUOrigin2DDict {
|
||||
GPUIntegerCoordinate x = 0;
|
||||
GPUIntegerCoordinate y = 0;
|
||||
};
|
||||
typedef (sequence<GPUIntegerCoordinate> or GPUOrigin2DDict) GPUOrigin2D;
|
||||
|
||||
dictionary GPUOrigin3DDict {
|
||||
GPUIntegerCoordinate x = 0;
|
||||
|
|
11
components/script/dom/webidls/GPUCompilationInfo.webidl
Normal file
11
components/script/dom/webidls/GPUCompilationInfo.webidl
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpucompilationinfo
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUCompilationInfo {
|
||||
// codegen hates it
|
||||
//[Cached, Frozen, Pure]
|
||||
readonly attribute /*sequence<GPUCompilationMessage>*/ any messages;
|
||||
};
|
20
components/script/dom/webidls/GPUCompilationMessage.webidl
Normal file
20
components/script/dom/webidls/GPUCompilationMessage.webidl
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpucompilationmessage
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUCompilationMessage {
|
||||
readonly attribute DOMString message;
|
||||
readonly attribute GPUCompilationMessageType type;
|
||||
readonly attribute unsigned long long lineNum;
|
||||
readonly attribute unsigned long long linePos;
|
||||
readonly attribute unsigned long long offset;
|
||||
readonly attribute unsigned long long length;
|
||||
};
|
||||
|
||||
enum GPUCompilationMessageType {
|
||||
"error",
|
||||
"warning",
|
||||
"info"
|
||||
};
|
|
@ -6,15 +6,12 @@
|
|||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUComputePassEncoder {
|
||||
undefined setPipeline(GPUComputePipeline pipeline);
|
||||
undefined dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1);
|
||||
undefined dispatchIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
|
||||
undefined dispatchWorkgroups(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1);
|
||||
//[Pref="dom.webgpu.indirect-dispatch.enabled"]
|
||||
undefined dispatchWorkgroupsIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
|
||||
|
||||
//void beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
//void endPipelineStatisticsQuery();
|
||||
|
||||
//void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
|
||||
undefined endPass();
|
||||
[Throws]
|
||||
undefined end();
|
||||
};
|
||||
GPUComputePassEncoder includes GPUObjectBase;
|
||||
GPUComputePassEncoder includes GPUProgrammablePassEncoder;
|
||||
|
|
|
@ -9,19 +9,23 @@ interface GPUComputePipeline {
|
|||
GPUComputePipeline includes GPUObjectBase;
|
||||
GPUComputePipeline includes GPUPipelineBase;
|
||||
|
||||
dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase {
|
||||
GPUPipelineLayout layout;
|
||||
enum GPUAutoLayoutMode {
|
||||
"auto"
|
||||
};
|
||||
|
||||
dictionary GPUProgrammableStageDescriptor {
|
||||
required GPUShaderModule module;
|
||||
required DOMString entryPoint;
|
||||
dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase {
|
||||
required (GPUPipelineLayout or GPUAutoLayoutMode) layout;
|
||||
};
|
||||
|
||||
dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
|
||||
required GPUProgrammableStageDescriptor computeStage;
|
||||
required GPUProgrammableStage compute;
|
||||
};
|
||||
|
||||
interface mixin GPUPipelineBase {
|
||||
[Throws] GPUBindGroupLayout getBindGroupLayout(unsigned long index);
|
||||
};
|
||||
|
||||
dictionary GPUProgrammableStage {
|
||||
required GPUShaderModule module;
|
||||
required USVString entryPoint;
|
||||
};
|
||||
|
|
|
@ -4,15 +4,20 @@
|
|||
|
||||
// https://gpuweb.github.io/gpuweb/#gpudevice
|
||||
[Exposed=(Window, DedicatedWorker), /*Serializable,*/ Pref="dom.webgpu.enabled"]
|
||||
interface GPUDevice : EventTarget {
|
||||
[SameObject] readonly attribute GPUAdapter adapter;
|
||||
readonly attribute object extensions;
|
||||
readonly attribute object limits;
|
||||
interface GPUDevice: EventTarget {
|
||||
//[SameObject] readonly attribute GPUSupportedFeatures features;
|
||||
[SameObject] readonly attribute GPUSupportedLimits limits;
|
||||
|
||||
[SameObject] readonly attribute GPUQueue defaultQueue;
|
||||
// Overriding the name to avoid collision with `class Queue` in gcc
|
||||
[SameObject, BinaryName="getQueue"] readonly attribute GPUQueue queue;
|
||||
|
||||
undefined destroy();
|
||||
|
||||
[NewObject, Throws]
|
||||
GPUBuffer createBuffer(GPUBufferDescriptor descriptor);
|
||||
[NewObject]
|
||||
GPUTexture createTexture(GPUTextureDescriptor descriptor);
|
||||
[NewObject]
|
||||
GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
|
||||
|
||||
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
|
||||
|
@ -22,16 +27,22 @@ interface GPUDevice : EventTarget {
|
|||
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
|
||||
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
|
||||
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
|
||||
//Promise<GPUComputePipeline> createReadyComputePipeline(GPUComputePipelineDescriptor descriptor);
|
||||
//Promise<GPURenderPipeline> createReadyRenderPipeline(GPURenderPipelineDescriptor descriptor);
|
||||
|
||||
[NewObject]
|
||||
Promise<GPUComputePipeline> createComputePipelineAsync(GPUComputePipelineDescriptor descriptor);
|
||||
[NewObject]
|
||||
Promise<GPURenderPipeline> createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor);
|
||||
|
||||
[NewObject]
|
||||
GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {});
|
||||
[NewObject]
|
||||
GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor);
|
||||
|
||||
//[NewObject]
|
||||
//GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor);
|
||||
};
|
||||
GPUDevice includes GPUObjectBase;
|
||||
|
||||
//TODO
|
||||
dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase {
|
||||
boolean measureExecutionTime = false;
|
||||
};
|
||||
|
|
|
@ -5,9 +5,16 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpudevicelostinfo
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUDeviceLostInfo {
|
||||
readonly attribute GPUDeviceLostReason reason;
|
||||
readonly attribute DOMString message;
|
||||
};
|
||||
|
||||
enum GPUDeviceLostReason {
|
||||
"unknown",
|
||||
"destroyed",
|
||||
};
|
||||
|
||||
partial interface GPUDevice {
|
||||
[Throws]
|
||||
readonly attribute Promise<GPUDeviceLostInfo> lost;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpumapmode
|
||||
// https://gpuweb.github.io/gpuweb/#namespacedef-gpumapmode
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUMapMode {
|
||||
const GPUMapModeFlags READ = 0x0001;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpuobjectbase
|
||||
[Exposed=(Window)]
|
||||
interface mixin GPUObjectBase {
|
||||
attribute USVString? label;
|
||||
attribute USVString label;
|
||||
};
|
||||
|
||||
dictionary GPUObjectDescriptorBase {
|
||||
|
|
|
@ -6,16 +6,11 @@
|
|||
[Exposed=(Window, DedicatedWorker)]
|
||||
interface mixin GPUProgrammablePassEncoder {
|
||||
undefined setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup,
|
||||
optional sequence<GPUBufferDynamicOffset> dynamicOffsets = []);
|
||||
optional sequence<GPUBufferDynamicOffset> dynamicOffsets = []);
|
||||
|
||||
// void setBindGroup(GPUIndex32 index, GPUBindGroup bindGroup,
|
||||
// Uint32Array dynamicOffsetsData,
|
||||
// GPUSize64 dynamicOffsetsDataStart,
|
||||
// GPUSize64 dynamicOffsetsDataLength);
|
||||
|
||||
// void pushDebugGroup(DOMString groupLabel);
|
||||
// void popDebugGroup();
|
||||
// void insertDebugMarker(DOMString markerLabel);
|
||||
//undefined pushDebugGroup(USVString groupLabel);
|
||||
//undefined popDebugGroup();
|
||||
//undefined insertDebugMarker(USVString markerLabel);
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUBufferDynamicOffset;
|
||||
|
|
30
components/script/dom/webidls/GPUQuerySet.webidl
Normal file
30
components/script/dom/webidls/GPUQuerySet.webidl
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpuqueryset
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUQuerySet {
|
||||
undefined destroy();
|
||||
};
|
||||
GPUQuerySet includes GPUObjectBase;
|
||||
|
||||
dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
|
||||
required GPUQueryType type;
|
||||
required GPUSize32 count;
|
||||
sequence<GPUPipelineStatisticName> pipelineStatistics = [];
|
||||
};
|
||||
|
||||
enum GPUPipelineStatisticName {
|
||||
"vertex-shader-invocations",
|
||||
"clipper-invocations",
|
||||
"clipper-primitives-out",
|
||||
"fragment-shader-invocations",
|
||||
"compute-shader-invocations"
|
||||
};
|
||||
|
||||
enum GPUQueryType {
|
||||
"occlusion",
|
||||
"pipeline-statistics",
|
||||
"timestamp"
|
||||
};
|
|
@ -5,27 +5,30 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpuqueue
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUQueue {
|
||||
undefined submit(sequence<GPUCommandBuffer> commandBuffers);
|
||||
undefined submit(sequence<GPUCommandBuffer> buffers);
|
||||
|
||||
//GPUFence createFence(optional GPUFenceDescriptor descriptor = {});
|
||||
//void signal(GPUFence fence, GPUFenceValue signalValue);
|
||||
//TODO:
|
||||
//Promise<undefined> onSubmittedWorkDone();
|
||||
|
||||
[Throws] undefined writeBuffer(
|
||||
[Throws]
|
||||
undefined writeBuffer(
|
||||
GPUBuffer buffer,
|
||||
GPUSize64 bufferOffset,
|
||||
/*[AllowShared]*/ BufferSource data,
|
||||
BufferSource data,
|
||||
optional GPUSize64 dataOffset = 0,
|
||||
optional GPUSize64 size);
|
||||
|
||||
[Throws] undefined writeTexture(
|
||||
GPUTextureCopyView destination,
|
||||
/*[AllowShared]*/ BufferSource data,
|
||||
GPUTextureDataLayout dataLayout,
|
||||
[Throws]
|
||||
undefined writeTexture(
|
||||
GPUImageCopyTexture destination,
|
||||
BufferSource data,
|
||||
GPUImageDataLayout dataLayout,
|
||||
GPUExtent3D size);
|
||||
|
||||
//void copyImageBitmapToTexture(
|
||||
// GPUImageBitmapCopyView source,
|
||||
// GPUTextureCopyView destination,
|
||||
// GPUExtent3D copySize);
|
||||
//[Throws]
|
||||
//undefined copyExternalImageToTexture(
|
||||
// GPUImageCopyExternalImage source,
|
||||
// GPUImageCopyTextureTagged destination,
|
||||
// GPUExtent3D copySize);
|
||||
};
|
||||
GPUQueue includes GPUObjectBase;
|
||||
|
|
|
@ -11,8 +11,7 @@ GPURenderBundleEncoder includes GPUObjectBase;
|
|||
GPURenderBundleEncoder includes GPUProgrammablePassEncoder;
|
||||
GPURenderBundleEncoder includes GPURenderEncoderBase;
|
||||
|
||||
dictionary GPURenderBundleEncoderDescriptor : GPUObjectDescriptorBase {
|
||||
required sequence<GPUTextureFormat> colorFormats;
|
||||
GPUTextureFormat depthStencilFormat;
|
||||
GPUSize32 sampleCount = 1;
|
||||
dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout {
|
||||
boolean depthReadOnly = false;
|
||||
boolean stencilReadOnly = false;
|
||||
};
|
||||
|
|
|
@ -2,27 +2,33 @@
|
|||
* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpurenderencoderbase
|
||||
// https://gpuweb.github.io/gpuweb/#gpurendercommandsmixin
|
||||
[Exposed=(Window, DedicatedWorker)]
|
||||
interface mixin GPURenderEncoderBase {
|
||||
undefined setPipeline(GPURenderPipeline pipeline);
|
||||
|
||||
undefined setIndexBuffer(GPUBuffer buffer, optional GPUSize64 offset = 0, optional GPUSize64 size = 0);
|
||||
undefined setVertexBuffer(
|
||||
GPUIndex32 slot,
|
||||
GPUBuffer buffer,
|
||||
optional GPUSize64 offset = 0,
|
||||
optional GPUSize64 size = 0
|
||||
);
|
||||
undefined setIndexBuffer(GPUBuffer buffer,
|
||||
GPUIndexFormat indexFormat,
|
||||
optional GPUSize64 offset = 0,
|
||||
optional GPUSize64 size = 0);
|
||||
undefined setVertexBuffer(GPUIndex32 slot,
|
||||
GPUBuffer buffer,
|
||||
optional GPUSize64 offset = 0,
|
||||
optional GPUSize64 size = 0);
|
||||
|
||||
undefined draw(GPUSize32 vertexCount, optional GPUSize32 instanceCount = 1,
|
||||
optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0);
|
||||
undefined drawIndexed(GPUSize32 indexCount, optional GPUSize32 instanceCount = 1,
|
||||
optional GPUSize32 firstIndex = 0,
|
||||
optional GPUSignedOffset32 baseVertex = 0,
|
||||
optional GPUSize32 firstInstance = 0);
|
||||
undefined draw(GPUSize32 vertexCount,
|
||||
optional GPUSize32 instanceCount = 1,
|
||||
optional GPUSize32 firstVertex = 0,
|
||||
optional GPUSize32 firstInstance = 0);
|
||||
undefined drawIndexed(GPUSize32 indexCount,
|
||||
optional GPUSize32 instanceCount = 1,
|
||||
optional GPUSize32 firstIndex = 0,
|
||||
optional GPUSignedOffset32 baseVertex = 0,
|
||||
optional GPUSize32 firstInstance = 0);
|
||||
|
||||
//[Pref="dom.webgpu.indirect-dispatch.enabled"]
|
||||
undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
|
||||
//[Pref="dom.webgpu.indirect-dispatch.enabled"]
|
||||
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,25 +6,27 @@
|
|||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPURenderPassEncoder {
|
||||
undefined setViewport(float x, float y,
|
||||
float width, float height,
|
||||
float minDepth, float maxDepth);
|
||||
float width, float height,
|
||||
float minDepth, float maxDepth);
|
||||
|
||||
undefined setScissorRect(GPUIntegerCoordinate x, GPUIntegerCoordinate y,
|
||||
GPUIntegerCoordinate width, GPUIntegerCoordinate height);
|
||||
GPUIntegerCoordinate width, GPUIntegerCoordinate height);
|
||||
|
||||
undefined setBlendColor(GPUColor color);
|
||||
undefined setBlendConstant(GPUColor color);
|
||||
undefined setStencilReference(GPUStencilValue reference);
|
||||
|
||||
//void beginOcclusionQuery(GPUSize32 queryIndex);
|
||||
//void endOcclusionQuery();
|
||||
//undefined beginOcclusionQuery(GPUSize32 queryIndex);
|
||||
//undefined endOcclusionQuery();
|
||||
|
||||
//void beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
//void endPipelineStatisticsQuery();
|
||||
//undefined beginPipelineStatisticsQuery(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
//undefined endPipelineStatisticsQuery();
|
||||
|
||||
//void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
//undefined writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
|
||||
|
||||
undefined executeBundles(sequence<GPURenderBundle> bundles);
|
||||
undefined endPass();
|
||||
|
||||
[Throws]
|
||||
undefined end();
|
||||
};
|
||||
GPURenderPassEncoder includes GPUObjectBase;
|
||||
GPURenderPassEncoder includes GPUProgrammablePassEncoder;
|
||||
|
|
|
@ -10,21 +10,21 @@ GPURenderPipeline includes GPUObjectBase;
|
|||
GPURenderPipeline includes GPUPipelineBase;
|
||||
|
||||
dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase {
|
||||
required GPUProgrammableStageDescriptor vertexStage;
|
||||
GPUProgrammableStageDescriptor fragmentStage;
|
||||
|
||||
required GPUPrimitiveTopology primitiveTopology;
|
||||
GPURasterizationStateDescriptor rasterizationState = {};
|
||||
required sequence<GPUColorStateDescriptor> colorStates;
|
||||
GPUDepthStencilStateDescriptor depthStencilState;
|
||||
GPUVertexStateDescriptor vertexState = {};
|
||||
|
||||
GPUSize32 sampleCount = 1;
|
||||
GPUSampleMask sampleMask = 0xFFFFFFFF;
|
||||
boolean alphaToCoverageEnabled = false;
|
||||
required GPUVertexState vertex;
|
||||
GPUPrimitiveState primitive = {};
|
||||
GPUDepthStencilState depthStencil;
|
||||
GPUMultisampleState multisample = {};
|
||||
GPUFragmentState fragment;
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUSampleMask;
|
||||
dictionary GPUPrimitiveState {
|
||||
GPUPrimitiveTopology topology = "triangle-list";
|
||||
GPUIndexFormat stripIndexFormat;
|
||||
GPUFrontFace frontFace = "ccw";
|
||||
GPUCullMode cullMode = "none";
|
||||
// Enable depth clamping (requires "depth-clamping" feature)
|
||||
boolean clampDepth = false;
|
||||
};
|
||||
|
||||
enum GPUPrimitiveTopology {
|
||||
"point-list",
|
||||
|
@ -34,19 +34,6 @@ enum GPUPrimitiveTopology {
|
|||
"triangle-strip"
|
||||
};
|
||||
|
||||
typedef [EnforceRange] long GPUDepthBias;
|
||||
|
||||
dictionary GPURasterizationStateDescriptor {
|
||||
GPUFrontFace frontFace = "ccw";
|
||||
GPUCullMode cullMode = "none";
|
||||
// Enable depth clamping (requires "depth-clamping" extension)
|
||||
boolean clampDepth = false;
|
||||
|
||||
GPUDepthBias depthBias = 0;
|
||||
float depthBiasSlopeScale = 0;
|
||||
float depthBiasClamp = 0;
|
||||
};
|
||||
|
||||
enum GPUFrontFace {
|
||||
"ccw",
|
||||
"cw"
|
||||
|
@ -58,15 +45,31 @@ enum GPUCullMode {
|
|||
"back"
|
||||
};
|
||||
|
||||
dictionary GPUColorStateDescriptor {
|
||||
required GPUTextureFormat format;
|
||||
dictionary GPUMultisampleState {
|
||||
GPUSize32 count = 1;
|
||||
GPUSampleMask mask = 0xFFFFFFFF;
|
||||
boolean alphaToCoverageEnabled = false;
|
||||
};
|
||||
|
||||
GPUBlendDescriptor alphaBlend = {};
|
||||
GPUBlendDescriptor colorBlend = {};
|
||||
dictionary GPUFragmentState: GPUProgrammableStage {
|
||||
required sequence<GPUColorTargetState> targets;
|
||||
};
|
||||
|
||||
dictionary GPUColorTargetState {
|
||||
required GPUTextureFormat format;
|
||||
GPUBlendState blend;
|
||||
GPUColorWriteFlags writeMask = 0xF; // GPUColorWrite.ALL
|
||||
};
|
||||
|
||||
dictionary GPUBlendDescriptor {
|
||||
dictionary GPUBlendState {
|
||||
required GPUBlendComponent color;
|
||||
required GPUBlendComponent alpha;
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUSampleMask;
|
||||
typedef [EnforceRange] long GPUDepthBias;
|
||||
|
||||
dictionary GPUBlendComponent {
|
||||
GPUBlendFactor srcFactor = "one";
|
||||
GPUBlendFactor dstFactor = "zero";
|
||||
GPUBlendOperation operation = "add";
|
||||
|
@ -75,17 +78,17 @@ dictionary GPUBlendDescriptor {
|
|||
enum GPUBlendFactor {
|
||||
"zero",
|
||||
"one",
|
||||
"src-color",
|
||||
"one-minus-src-color",
|
||||
"src",
|
||||
"one-minus-src",
|
||||
"src-alpha",
|
||||
"one-minus-src-alpha",
|
||||
"dst-color",
|
||||
"one-minus-dst-color",
|
||||
"dst",
|
||||
"one-minus-dst",
|
||||
"dst-alpha",
|
||||
"one-minus-dst-alpha",
|
||||
"src-alpha-saturated",
|
||||
"blend-color",
|
||||
"one-minus-blend-color"
|
||||
"constant",
|
||||
"one-minus-constant",
|
||||
};
|
||||
|
||||
enum GPUBlendOperation {
|
||||
|
@ -96,6 +99,30 @@ enum GPUBlendOperation {
|
|||
"max"
|
||||
};
|
||||
|
||||
dictionary GPUDepthStencilState {
|
||||
required GPUTextureFormat format;
|
||||
|
||||
boolean depthWriteEnabled = false;
|
||||
GPUCompareFunction depthCompare = "always";
|
||||
|
||||
GPUStencilFaceState stencilFront = {};
|
||||
GPUStencilFaceState stencilBack = {};
|
||||
|
||||
GPUStencilValue stencilReadMask = 0xFFFFFFFF;
|
||||
GPUStencilValue stencilWriteMask = 0xFFFFFFFF;
|
||||
|
||||
GPUDepthBias depthBias = 0;
|
||||
float depthBiasSlopeScale = 0;
|
||||
float depthBiasClamp = 0;
|
||||
};
|
||||
|
||||
dictionary GPUStencilFaceState {
|
||||
GPUCompareFunction compare = "always";
|
||||
GPUStencilOperation failOp = "keep";
|
||||
GPUStencilOperation depthFailOp = "keep";
|
||||
GPUStencilOperation passOp = "keep";
|
||||
};
|
||||
|
||||
enum GPUStencilOperation {
|
||||
"keep",
|
||||
"zero",
|
||||
|
@ -107,85 +134,63 @@ enum GPUStencilOperation {
|
|||
"decrement-wrap"
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUStencilValue;
|
||||
|
||||
dictionary GPUDepthStencilStateDescriptor {
|
||||
required GPUTextureFormat format;
|
||||
|
||||
boolean depthWriteEnabled = false;
|
||||
GPUCompareFunction depthCompare = "always";
|
||||
|
||||
GPUStencilStateFaceDescriptor stencilFront = {};
|
||||
GPUStencilStateFaceDescriptor stencilBack = {};
|
||||
|
||||
GPUStencilValue stencilReadMask = 0xFFFFFFFF;
|
||||
GPUStencilValue stencilWriteMask = 0xFFFFFFFF;
|
||||
};
|
||||
|
||||
dictionary GPUStencilStateFaceDescriptor {
|
||||
GPUCompareFunction compare = "always";
|
||||
GPUStencilOperation failOp = "keep";
|
||||
GPUStencilOperation depthFailOp = "keep";
|
||||
GPUStencilOperation passOp = "keep";
|
||||
};
|
||||
|
||||
enum GPUIndexFormat {
|
||||
"uint16",
|
||||
"uint32"
|
||||
"uint32",
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUStencilValue;
|
||||
|
||||
enum GPUVertexFormat {
|
||||
"uchar2",
|
||||
"uchar4",
|
||||
"char2",
|
||||
"char4",
|
||||
"uchar2norm",
|
||||
"uchar4norm",
|
||||
"char2norm",
|
||||
"char4norm",
|
||||
"ushort2",
|
||||
"ushort4",
|
||||
"short2",
|
||||
"short4",
|
||||
"ushort2norm",
|
||||
"ushort4norm",
|
||||
"short2norm",
|
||||
"short4norm",
|
||||
"half2",
|
||||
"half4",
|
||||
"float",
|
||||
"float2",
|
||||
"float3",
|
||||
"float4",
|
||||
"uint",
|
||||
"uint2",
|
||||
"uint3",
|
||||
"uint4",
|
||||
"int",
|
||||
"int2",
|
||||
"int3",
|
||||
"int4"
|
||||
"uint8x2",
|
||||
"uint8x4",
|
||||
"sint8x2",
|
||||
"sint8x4",
|
||||
"unorm8x2",
|
||||
"unorm8x4",
|
||||
"snorm8x2",
|
||||
"snorm8x4",
|
||||
"uint16x2",
|
||||
"uint16x4",
|
||||
"sint16x2",
|
||||
"sint16x4",
|
||||
"unorm16x2",
|
||||
"unorm16x4",
|
||||
"snorm16x2",
|
||||
"snorm16x4",
|
||||
"float16x2",
|
||||
"float16x4",
|
||||
"float32",
|
||||
"float32x2",
|
||||
"float32x3",
|
||||
"float32x4",
|
||||
"uint32",
|
||||
"uint32x2",
|
||||
"uint32x3",
|
||||
"uint32x4",
|
||||
"sint32",
|
||||
"sint32x2",
|
||||
"sint32x3",
|
||||
"sint32x4",
|
||||
};
|
||||
|
||||
enum GPUInputStepMode {
|
||||
enum GPUVertexStepMode {
|
||||
"vertex",
|
||||
"instance"
|
||||
"instance",
|
||||
};
|
||||
|
||||
dictionary GPUVertexStateDescriptor {
|
||||
GPUIndexFormat indexFormat = "uint32";
|
||||
sequence<GPUVertexBufferLayoutDescriptor?> vertexBuffers = [];
|
||||
dictionary GPUVertexState: GPUProgrammableStage {
|
||||
sequence<GPUVertexBufferLayout?> buffers = [];
|
||||
};
|
||||
|
||||
dictionary GPUVertexBufferLayoutDescriptor {
|
||||
dictionary GPUVertexBufferLayout {
|
||||
required GPUSize64 arrayStride;
|
||||
GPUInputStepMode stepMode = "vertex";
|
||||
required sequence<GPUVertexAttributeDescriptor> attributes;
|
||||
GPUVertexStepMode stepMode = "vertex";
|
||||
required sequence<GPUVertexAttribute> attributes;
|
||||
};
|
||||
|
||||
dictionary GPUVertexAttributeDescriptor {
|
||||
dictionary GPUVertexAttribute {
|
||||
required GPUVertexFormat format;
|
||||
required GPUSize64 offset;
|
||||
|
||||
required GPUIndex32 shaderLocation;
|
||||
};
|
||||
|
|
|
@ -16,9 +16,9 @@ dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
|
|||
GPUFilterMode minFilter = "nearest";
|
||||
GPUFilterMode mipmapFilter = "nearest";
|
||||
float lodMinClamp = 0;
|
||||
float lodMaxClamp = 0xfffff; // TODO: What should this be? Was Number.MAX_VALUE.
|
||||
float lodMaxClamp = 1000.0; // TODO: What should this be?
|
||||
GPUCompareFunction compare;
|
||||
unsigned short maxAnisotropy = 1;
|
||||
[Clamp] unsigned short maxAnisotropy = 1;
|
||||
};
|
||||
|
||||
enum GPUAddressMode {
|
||||
|
@ -29,7 +29,7 @@ enum GPUAddressMode {
|
|||
|
||||
enum GPUFilterMode {
|
||||
"nearest",
|
||||
"linear"
|
||||
"linear",
|
||||
};
|
||||
|
||||
enum GPUCompareFunction {
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpushadermodule
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUShaderModule {
|
||||
[Throws]
|
||||
Promise<GPUCompilationInfo> compilationInfo();
|
||||
};
|
||||
GPUShaderModule includes GPUObjectBase;
|
||||
|
||||
typedef (Uint32Array or DOMString) GPUShaderCode;
|
||||
|
||||
dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
|
||||
required GPUShaderCode code;
|
||||
// UTF8String is not observably different from USVString
|
||||
required USVString code;
|
||||
object sourceMap;
|
||||
};
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// https://gpuweb.github.io/gpuweb/#typedefdef-gpushaderstageflags
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUShaderStage {
|
||||
const GPUShaderStageFlags VERTEX = 0x1;
|
||||
const GPUShaderStageFlags FRAGMENT = 0x2;
|
||||
const GPUShaderStageFlags COMPUTE = 0x4;
|
||||
const GPUShaderStageFlags VERTEX = 1;
|
||||
const GPUShaderStageFlags FRAGMENT = 2;
|
||||
const GPUShaderStageFlags COMPUTE = 4;
|
||||
};
|
||||
|
||||
typedef unsigned long GPUShaderStageFlags;
|
||||
typedef [EnforceRange] unsigned long GPUShaderStageFlags;
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpuswapchain
|
||||
// https://gpuweb.github.io/gpuweb/#gpusupportedfeatures
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUSwapChain {
|
||||
GPUTexture getCurrentTexture();
|
||||
interface GPUSupportedFeatures {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
GPUSwapChain includes GPUObjectBase;
|
34
components/script/dom/webidls/GPUSupportedLimits.webidl
Normal file
34
components/script/dom/webidls/GPUSupportedLimits.webidl
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gpusupportedlimits
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUSupportedLimits {
|
||||
readonly attribute unsigned long maxTextureDimension1D;
|
||||
readonly attribute unsigned long maxTextureDimension2D;
|
||||
readonly attribute unsigned long maxTextureDimension3D;
|
||||
readonly attribute unsigned long maxTextureArrayLayers;
|
||||
readonly attribute unsigned long maxBindGroups;
|
||||
readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout;
|
||||
readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout;
|
||||
readonly attribute unsigned long maxSampledTexturesPerShaderStage;
|
||||
readonly attribute unsigned long maxSamplersPerShaderStage;
|
||||
readonly attribute unsigned long maxStorageBuffersPerShaderStage;
|
||||
readonly attribute unsigned long maxStorageTexturesPerShaderStage;
|
||||
readonly attribute unsigned long maxUniformBuffersPerShaderStage;
|
||||
readonly attribute unsigned long maxUniformBufferBindingSize;
|
||||
readonly attribute unsigned long maxStorageBufferBindingSize;
|
||||
readonly attribute unsigned long minUniformBufferOffsetAlignment;
|
||||
readonly attribute unsigned long minStorageBufferOffsetAlignment;
|
||||
readonly attribute unsigned long maxVertexBuffers;
|
||||
readonly attribute unsigned long maxVertexAttributes;
|
||||
readonly attribute unsigned long maxVertexBufferArrayStride;
|
||||
readonly attribute unsigned long maxInterStageShaderComponents;
|
||||
readonly attribute unsigned long maxComputeWorkgroupStorageSize;
|
||||
readonly attribute unsigned long maxComputeInvocationsPerWorkgroup;
|
||||
readonly attribute unsigned long maxComputeWorkgroupSizeX;
|
||||
readonly attribute unsigned long maxComputeWorkgroupSizeY;
|
||||
readonly attribute unsigned long maxComputeWorkgroupSizeZ;
|
||||
readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
|
||||
};
|
|
@ -5,6 +5,7 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gputexture
|
||||
[Exposed=(Window, DedicatedWorker), Serializable , Pref="dom.webgpu.enabled"]
|
||||
interface GPUTexture {
|
||||
[NewObject]
|
||||
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
|
||||
|
||||
undefined destroy();
|
||||
|
@ -18,12 +19,13 @@ dictionary GPUTextureDescriptor : GPUObjectDescriptorBase {
|
|||
GPUTextureDimension dimension = "2d";
|
||||
required GPUTextureFormat format;
|
||||
required GPUTextureUsageFlags usage;
|
||||
sequence<GPUTextureFormat> viewFormats = [];
|
||||
};
|
||||
|
||||
enum GPUTextureDimension {
|
||||
"1d",
|
||||
"2d",
|
||||
"3d"
|
||||
"3d",
|
||||
};
|
||||
|
||||
enum GPUTextureFormat {
|
||||
|
@ -57,9 +59,8 @@ enum GPUTextureFormat {
|
|||
"bgra8unorm",
|
||||
"bgra8unorm-srgb",
|
||||
// Packed 32-bit formats
|
||||
//"rgb9e5ufloat",
|
||||
"rgb10a2unorm",
|
||||
//"rg11b10ufloat",
|
||||
"rg11b10float",
|
||||
|
||||
// 64-bit formats
|
||||
"rg32uint",
|
||||
|
@ -75,7 +76,7 @@ enum GPUTextureFormat {
|
|||
"rgba32float",
|
||||
|
||||
// Depth and stencil formats
|
||||
//"stencil8",
|
||||
//"stencil8", //TODO
|
||||
//"depth16unorm",
|
||||
"depth24plus",
|
||||
"depth24plus-stencil8",
|
||||
|
@ -94,29 +95,22 @@ enum GPUTextureFormat {
|
|||
"bc5-rg-unorm",
|
||||
"bc5-rg-snorm",
|
||||
"bc6h-rgb-ufloat",
|
||||
//"bc6h-rgb-float",
|
||||
"bc6h-rgb-float",
|
||||
"bc7-rgba-unorm",
|
||||
"bc7-rgba-unorm-srgb",
|
||||
|
||||
// "depth24unorm-stencil8" extension
|
||||
// "depth24unorm-stencil8" feature
|
||||
//"depth24unorm-stencil8",
|
||||
|
||||
// "depth32float-stencil8" extension
|
||||
// "depth32float-stencil8" feature
|
||||
//"depth32float-stencil8",
|
||||
};
|
||||
|
||||
enum GPUTextureComponentType {
|
||||
"float",
|
||||
"sint",
|
||||
"uint",
|
||||
// Texture is used with comparison sampling only.
|
||||
"depth-comparison"
|
||||
};
|
||||
typedef [EnforceRange] unsigned long GPUIntegerCoordinate;
|
||||
|
||||
dictionary GPUExtent3DDict {
|
||||
required GPUIntegerCoordinate width;
|
||||
required GPUIntegerCoordinate height;
|
||||
required GPUIntegerCoordinate depth;
|
||||
GPUIntegerCoordinate height = 1;
|
||||
GPUIntegerCoordinate depthOrArrayLayers = 1;
|
||||
};
|
||||
typedef [EnforceRange] unsigned long GPUIntegerCoordinate;
|
||||
typedef (sequence<GPUIntegerCoordinate> or GPUExtent3DDict) GPUExtent3D;
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
* 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/. */
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#gputextureusage
|
||||
// https://gpuweb.github.io/gpuweb/#typedefdef-gputextureusageflags
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUTextureUsage {
|
||||
const GPUTextureUsageFlags COPY_SRC = 0x01;
|
||||
const GPUTextureUsageFlags COPY_DST = 0x02;
|
||||
const GPUTextureUsageFlags SAMPLED = 0x04;
|
||||
const GPUTextureUsageFlags STORAGE = 0x08;
|
||||
const GPUTextureUsageFlags OUTPUT_ATTACHMENT = 0x10;
|
||||
const GPUTextureUsageFlags TEXTURE_BINDING = 0x04;
|
||||
const GPUTextureUsageFlags STORAGE_BINDING = 0x08;
|
||||
const GPUTextureUsageFlags RENDER_ATTACHMENT = 0x10;
|
||||
};
|
||||
|
||||
typedef [EnforceRange] unsigned long GPUTextureUsageFlags;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpuvalidationerror
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPUValidationError {
|
||||
[Throws]
|
||||
constructor(DOMString message);
|
||||
readonly attribute DOMString message;
|
||||
};
|
||||
|
@ -18,5 +19,6 @@ enum GPUErrorFilter {
|
|||
|
||||
partial interface GPUDevice {
|
||||
undefined pushErrorScope(GPUErrorFilter filter);
|
||||
[NewObject]
|
||||
Promise<GPUError?> popErrorScope();
|
||||
};
|
||||
|
|
|
@ -22,5 +22,17 @@ servo_config = { path = "../config" }
|
|||
smallvec = { workspace = true, features = ["serde"] }
|
||||
webrender_api = { workspace = true }
|
||||
webrender_traits = { path = "../webrender_traits" }
|
||||
wgpu-core = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace", "serial-pass"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
||||
wgpu-types = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
||||
wgpu-core = { version = "0.16", features = ["replay", "trace", "serial-pass", "wgsl"] }
|
||||
wgpu-types = { version = "0.16" }
|
||||
|
||||
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies.wgpu-core]
|
||||
version = "0.16"
|
||||
features = ["replay", "trace", "serial-pass", "metal"]
|
||||
|
||||
[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies.wgpu-core]
|
||||
version = "0.16"
|
||||
features = ["replay", "trace", "serial-pass", "vulkan"]
|
||||
|
||||
[target.'cfg(windows)'.dependencies.wgpu-core]
|
||||
version = "0.16"
|
||||
features = ["replay", "trace", "serial-pass", "dx11", "dx12", "vulkan"]
|
||||
|
|
|
@ -10,8 +10,8 @@ use wgpu::{
|
|||
hub::{GlobalIdentityHandlerFactory, IdentityHandler, IdentityHandlerFactory},
|
||||
id::{
|
||||
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandBufferId, ComputePipelineId,
|
||||
DeviceId, PipelineLayoutId, RenderBundleId, RenderPipelineId, SamplerId, ShaderModuleId,
|
||||
SurfaceId, SwapChainId, TextureId, TextureViewId, TypedId,
|
||||
DeviceId, PipelineLayoutId, QuerySetId, RenderBundleId, RenderPipelineId, SamplerId,
|
||||
ShaderModuleId, StagingBufferId, SurfaceId, TextureId, TextureViewId, TypedId,
|
||||
},
|
||||
};
|
||||
use wgt::Backend;
|
||||
|
@ -28,7 +28,6 @@ pub enum WebGPUMsg {
|
|||
FreeAdapter(AdapterId),
|
||||
FreeDevice(DeviceId),
|
||||
FreeBuffer(BufferId),
|
||||
FreeSwapChain(SwapChainId),
|
||||
FreePipelineLayout(PipelineLayoutId),
|
||||
FreeComputePipeline(ComputePipelineId),
|
||||
FreeRenderPipeline(RenderPipelineId),
|
||||
|
@ -41,6 +40,8 @@ pub enum WebGPUMsg {
|
|||
FreeSurface(SurfaceId),
|
||||
FreeShaderModule(ShaderModuleId),
|
||||
FreeRenderBundle(RenderBundleId),
|
||||
FreeStagingBuffer(StagingBufferId),
|
||||
FreeQuerySet(QuerySetId),
|
||||
WebGPUOpResult {
|
||||
device: WebGPUDevice,
|
||||
scope_id: Option<ErrorScopeId>,
|
||||
|
@ -92,9 +93,14 @@ impl_identity_handler!(TextureId, "texture", WebGPUMsg::FreeTexture);
|
|||
impl_identity_handler!(TextureViewId, "texture_view", WebGPUMsg::FreeTextureView);
|
||||
impl_identity_handler!(BufferId, "buffer", WebGPUMsg::FreeBuffer);
|
||||
impl_identity_handler!(BindGroupId, "bind_group", WebGPUMsg::FreeBindGroup);
|
||||
impl_identity_handler!(SwapChainId, "swap_chain", WebGPUMsg::FreeSwapChain);
|
||||
impl_identity_handler!(ShaderModuleId, "shader_module", WebGPUMsg::FreeShaderModule);
|
||||
impl_identity_handler!(RenderBundleId, "render_bundle", WebGPUMsg::FreeRenderBundle);
|
||||
impl_identity_handler!(
|
||||
StagingBufferId,
|
||||
"staging_buffer",
|
||||
WebGPUMsg::FreeStagingBuffer
|
||||
);
|
||||
impl_identity_handler!(QuerySetId, "quary_set", WebGPUMsg::FreeQuerySet);
|
||||
impl_identity_handler!(
|
||||
RenderPipelineId,
|
||||
"render_pipeline",
|
||||
|
@ -149,7 +155,7 @@ where
|
|||
IdentityRecycler: IdentityHandler<I>,
|
||||
{
|
||||
type Filter = IdentityRecycler;
|
||||
fn spawn(&self, _min_index: u32) -> Self::Filter {
|
||||
fn spawn(&self) -> Self::Filter {
|
||||
IdentityRecycler {
|
||||
sender: self.sender.clone(),
|
||||
self_sender: self.self_sender.clone(),
|
||||
|
|
|
@ -35,11 +35,14 @@ use webrender_traits::{
|
|||
WebrenderExternalImageApi, WebrenderExternalImageRegistry, WebrenderImageHandlerType,
|
||||
WebrenderImageSource,
|
||||
};
|
||||
use wgpu::device::DeviceDescriptor;
|
||||
use wgpu::pipeline::ShaderModuleDescriptor;
|
||||
use wgpu::resource::{BufferMapCallback, BufferMapCallbackC};
|
||||
use wgpu::{
|
||||
binding_model::{BindGroupDescriptor, BindGroupLayoutDescriptor, PipelineLayoutDescriptor},
|
||||
command::{
|
||||
BufferCopyView, ComputePass, RenderBundleDescriptor, RenderBundleEncoder, RenderPass,
|
||||
TextureCopyView,
|
||||
ComputePass, ImageCopyBuffer, ImageCopyTexture, RenderBundleDescriptor,
|
||||
RenderBundleEncoder, RenderPass,
|
||||
},
|
||||
device::{HostMap, ImplicitPipelineIds},
|
||||
id,
|
||||
|
@ -50,6 +53,7 @@ use wgpu::{
|
|||
TextureDescriptor, TextureViewDescriptor,
|
||||
},
|
||||
};
|
||||
use wgt::{Dx12Compiler, InstanceDescriptor};
|
||||
|
||||
pub type ErrorScopeId = NonZeroU64;
|
||||
const DEVICE_POLL_INTERVAL: u64 = 100;
|
||||
|
@ -58,15 +62,15 @@ pub const PRESENTATION_BUFFER_COUNT: usize = 10;
|
|||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub enum WebGPUResponse {
|
||||
RequestAdapter {
|
||||
adapter_name: String,
|
||||
adapter_info: wgt::AdapterInfo,
|
||||
adapter_id: WebGPUAdapter,
|
||||
limits: wgt::Limits,
|
||||
channel: WebGPU,
|
||||
},
|
||||
RequestDevice {
|
||||
device_id: WebGPUDevice,
|
||||
queue_id: WebGPUQueue,
|
||||
descriptor: wgt::DeviceDescriptor,
|
||||
label: Option<String>,
|
||||
descriptor: wgt::DeviceDescriptor<Option<String>>,
|
||||
},
|
||||
BufferMapAsync(IpcSharedMemory),
|
||||
}
|
||||
|
@ -100,20 +104,20 @@ pub enum WebGPURequest {
|
|||
},
|
||||
CopyBufferToTexture {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
source: BufferCopyView,
|
||||
destination: TextureCopyView,
|
||||
source: ImageCopyBuffer,
|
||||
destination: ImageCopyTexture,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToBuffer {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
source: TextureCopyView,
|
||||
destination: BufferCopyView,
|
||||
source: ImageCopyTexture,
|
||||
destination: ImageCopyBuffer,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToTexture {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
source: TextureCopyView,
|
||||
destination: TextureCopyView,
|
||||
source: ImageCopyTexture,
|
||||
destination: ImageCopyTexture,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CreateBindGroup {
|
||||
|
@ -164,7 +168,8 @@ pub enum WebGPURequest {
|
|||
CreateShaderModule {
|
||||
device_id: id::DeviceId,
|
||||
program_id: id::ShaderModuleId,
|
||||
program: Vec<u32>,
|
||||
program: String,
|
||||
label: Option<String>,
|
||||
},
|
||||
CreateSwapChain {
|
||||
device_id: id::DeviceId,
|
||||
|
@ -186,6 +191,7 @@ pub enum WebGPURequest {
|
|||
descriptor: Option<TextureViewDescriptor<'static>>,
|
||||
},
|
||||
DestroyBuffer(id::BufferId),
|
||||
DestroyDevice(id::DeviceId),
|
||||
DestroySwapChain {
|
||||
external_id: u64,
|
||||
image_key: ImageKey,
|
||||
|
@ -208,10 +214,9 @@ pub enum WebGPURequest {
|
|||
RequestDevice {
|
||||
sender: IpcSender<WebGPUResponseResult>,
|
||||
adapter_id: WebGPUAdapter,
|
||||
descriptor: wgt::DeviceDescriptor,
|
||||
descriptor: wgt::DeviceDescriptor<Option<String>>,
|
||||
device_id: id::DeviceId,
|
||||
pipeline_id: PipelineId,
|
||||
label: Option<String>,
|
||||
},
|
||||
RunComputePass {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
|
@ -251,8 +256,8 @@ pub enum WebGPURequest {
|
|||
},
|
||||
WriteTexture {
|
||||
queue_id: id::QueueId,
|
||||
texture_cv: TextureCopyView,
|
||||
data_layout: wgt::TextureDataLayout,
|
||||
texture_cv: ImageCopyTexture,
|
||||
data_layout: wgt::ImageDataLayout,
|
||||
size: wgt::Extent3d,
|
||||
data: IpcSharedMemory,
|
||||
},
|
||||
|
@ -371,7 +376,14 @@ impl<'a> WGPU<'a> {
|
|||
receiver,
|
||||
sender,
|
||||
script_sender,
|
||||
global: wgpu::hub::Global::new("wgpu-core", factory, wgt::BackendBit::PRIMARY),
|
||||
global: wgpu::hub::Global::new(
|
||||
"wgpu-core",
|
||||
factory,
|
||||
InstanceDescriptor {
|
||||
backends: wgt::Backends::PRIMARY,
|
||||
dx12_shader_compiler: Dx12Compiler::default(),
|
||||
},
|
||||
),
|
||||
adapters: Vec::new(),
|
||||
devices: HashMap::new(),
|
||||
_invalid_adapters: Vec::new(),
|
||||
|
@ -409,7 +421,7 @@ impl<'a> WGPU<'a> {
|
|||
external_id: None,
|
||||
};
|
||||
self.buffer_maps.insert(buffer_id, Rc::new(map_info));
|
||||
|
||||
// TODO(sagudev): replace with safe callback
|
||||
unsafe extern "C" fn callback(
|
||||
status: BufferMapAsyncStatus,
|
||||
userdata: *mut u8,
|
||||
|
@ -420,10 +432,11 @@ impl<'a> WGPU<'a> {
|
|||
let msg = match status {
|
||||
BufferMapAsyncStatus::Success => {
|
||||
let global = &info.global;
|
||||
let data_pt = gfx_select!(info.buffer_id =>
|
||||
let (slice_pointer, range_size) = gfx_select!(info.buffer_id =>
|
||||
global.buffer_get_mapped_range(info.buffer_id, 0, None))
|
||||
.unwrap();
|
||||
let data = slice::from_raw_parts(data_pt, info.size);
|
||||
let data =
|
||||
slice::from_raw_parts(slice_pointer, range_size as usize);
|
||||
Ok(WebGPUResponse::BufferMapAsync(IpcSharedMemory::from_bytes(
|
||||
data,
|
||||
)))
|
||||
|
@ -440,10 +453,14 @@ impl<'a> WGPU<'a> {
|
|||
|
||||
let operation = BufferMapOperation {
|
||||
host: host_map,
|
||||
callback,
|
||||
user_data: convert_to_pointer(
|
||||
self.buffer_maps.get(&buffer_id).unwrap().clone(),
|
||||
),
|
||||
callback: unsafe {
|
||||
BufferMapCallback::from_c(BufferMapCallbackC {
|
||||
callback,
|
||||
user_data: convert_to_pointer(
|
||||
self.buffer_maps.get(&buffer_id).unwrap().clone(),
|
||||
),
|
||||
})
|
||||
},
|
||||
};
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation));
|
||||
|
@ -472,10 +489,12 @@ impl<'a> WGPU<'a> {
|
|||
{
|
||||
Err(err.clone())
|
||||
} else {
|
||||
gfx_select!(command_encoder_id => global.command_encoder_finish(
|
||||
command_encoder_id,
|
||||
&wgt::CommandBufferDescriptor::default()
|
||||
))
|
||||
tuple_to_result(
|
||||
gfx_select!(command_encoder_id => global.command_encoder_finish(
|
||||
command_encoder_id,
|
||||
&wgt::CommandBufferDescriptor::default()
|
||||
)),
|
||||
)
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
};
|
||||
self.encoder_record_error(command_encoder_id, &result);
|
||||
|
@ -551,11 +570,8 @@ impl<'a> WGPU<'a> {
|
|||
descriptor,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(bind_group_id =>
|
||||
global.device_create_bind_group(device_id, &descriptor, bind_group_id));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(bind_group_id => global.bind_group_error(bind_group_id));
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(bind_group_id =>
|
||||
global.device_create_bind_group(device_id, &descriptor, bind_group_id)));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateBindGroupLayout {
|
||||
|
@ -565,16 +581,10 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
if let Some(desc) = descriptor {
|
||||
let result = gfx_select!(bind_group_layout_id =>
|
||||
global.device_create_bind_group_layout(device_id, &desc, bind_group_layout_id));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(bind_group_layout_id =>
|
||||
global.bind_group_layout_error(bind_group_layout_id));
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(bind_group_layout_id =>
|
||||
global.device_create_bind_group_layout(device_id, &desc, bind_group_layout_id)));
|
||||
|
||||
self.send_result(device_id, scope_id, result);
|
||||
} else {
|
||||
let _ = gfx_select!(bind_group_layout_id =>
|
||||
global.bind_group_layout_error(bind_group_layout_id));
|
||||
}
|
||||
},
|
||||
WebGPURequest::CreateBuffer {
|
||||
|
@ -584,14 +594,10 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
if let Some(desc) = descriptor {
|
||||
let result = gfx_select!(buffer_id =>
|
||||
global.device_create_buffer(device_id, &desc, buffer_id));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(buffer_id => global.buffer_error(buffer_id));
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(buffer_id =>
|
||||
global.device_create_buffer(device_id, &desc, buffer_id)));
|
||||
|
||||
self.send_result(device_id, scope_id, result);
|
||||
} else {
|
||||
let _ = gfx_select!(buffer_id => global.buffer_error(buffer_id));
|
||||
}
|
||||
},
|
||||
WebGPURequest::CreateCommandEncoder {
|
||||
|
@ -601,11 +607,9 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
let desc = wgt::CommandEncoderDescriptor { label };
|
||||
let result = gfx_select!(command_encoder_id =>
|
||||
global.device_create_command_encoder(device_id, &desc, command_encoder_id));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_error(command_encoder_id));
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(command_encoder_id =>
|
||||
global.device_create_command_encoder(device_id, &desc, command_encoder_id)));
|
||||
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateComputePipeline {
|
||||
|
@ -625,22 +629,14 @@ impl<'a> WGPU<'a> {
|
|||
root_id: *layout,
|
||||
group_ids: bgls.as_slice(),
|
||||
});
|
||||
let result = gfx_select!(compute_pipeline_id => global.device_create_compute_pipeline(
|
||||
device_id,
|
||||
&descriptor,
|
||||
compute_pipeline_id,
|
||||
implicit
|
||||
));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(compute_pipeline_id =>
|
||||
global.compute_pipeline_error(compute_pipeline_id));
|
||||
if let Some((layout, bgls)) = implicit_ids {
|
||||
let _ = gfx_select!(layout => global.pipeline_layout_error(layout));
|
||||
bgls.iter().for_each(|&bgl| {
|
||||
let _ = gfx_select!(bgl => global.bind_group_layout_error(bgl));
|
||||
});
|
||||
}
|
||||
}
|
||||
let result = tuple_to_result(
|
||||
gfx_select!(compute_pipeline_id => global.device_create_compute_pipeline(
|
||||
device_id,
|
||||
&descriptor,
|
||||
compute_pipeline_id,
|
||||
implicit
|
||||
)),
|
||||
);
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateContext(sender) => {
|
||||
|
@ -659,11 +655,8 @@ impl<'a> WGPU<'a> {
|
|||
descriptor,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(pipeline_layout_id =>
|
||||
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(pipeline_layout_id => global.pipeline_layout_error(pipeline_layout_id));
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(pipeline_layout_id =>
|
||||
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id)));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateRenderPipeline {
|
||||
|
@ -684,22 +677,9 @@ impl<'a> WGPU<'a> {
|
|||
group_ids: bgls.as_slice(),
|
||||
});
|
||||
if let Some(desc) = descriptor {
|
||||
let result = gfx_select!(render_pipeline_id =>
|
||||
global.device_create_render_pipeline(device_id, &desc, render_pipeline_id, implicit));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(render_pipeline_id =>
|
||||
global.render_pipeline_error(render_pipeline_id));
|
||||
if let Some((layout, bgls)) = implicit_ids {
|
||||
let _ =
|
||||
gfx_select!(layout => global.pipeline_layout_error(layout));
|
||||
bgls.iter().for_each(|&bgl| {
|
||||
let _ = gfx_select!(bgl => global.bind_group_layout_error(bgl));
|
||||
});
|
||||
}
|
||||
}
|
||||
let result = tuple_to_result(gfx_select!(render_pipeline_id =>
|
||||
global.device_create_render_pipeline(device_id, &desc, render_pipeline_id, implicit)));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
} else {
|
||||
let _ = gfx_select!(render_pipeline_id => global.render_pipeline_error(render_pipeline_id));
|
||||
}
|
||||
},
|
||||
WebGPURequest::CreateSampler {
|
||||
|
@ -708,30 +688,31 @@ impl<'a> WGPU<'a> {
|
|||
descriptor,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(sampler_id => global.device_create_sampler(
|
||||
device_id,
|
||||
&descriptor,
|
||||
sampler_id
|
||||
));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(sampler_id => global.sampler_error(sampler_id));
|
||||
}
|
||||
let result = tuple_to_result(
|
||||
gfx_select!(sampler_id => global.device_create_sampler(
|
||||
device_id,
|
||||
&descriptor,
|
||||
sampler_id
|
||||
)),
|
||||
);
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateShaderModule {
|
||||
device_id,
|
||||
program_id,
|
||||
program,
|
||||
label,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let source =
|
||||
wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program));
|
||||
let result = gfx_select!(program_id =>
|
||||
global.device_create_shader_module(device_id, source, program_id));
|
||||
if result.is_err() {
|
||||
let _ =
|
||||
gfx_select!(program_id => global.shader_module_error(program_id));
|
||||
}
|
||||
let source = wgpu_core::pipeline::ShaderModuleSource::Wgsl(
|
||||
crate::Cow::Owned(program),
|
||||
);
|
||||
let desc = ShaderModuleDescriptor {
|
||||
label: label.map(|s| s.into()),
|
||||
shader_bound_checks: wgt::ShaderBoundChecks::default(),
|
||||
};
|
||||
let result = tuple_to_result(gfx_select!(program_id =>
|
||||
global.device_create_shader_module(device_id, &desc, source, program_id)));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateSwapChain {
|
||||
|
@ -785,17 +766,14 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
if let Some(desc) = descriptor {
|
||||
let result = gfx_select!(texture_id => global.device_create_texture(
|
||||
device_id,
|
||||
&desc,
|
||||
texture_id
|
||||
));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(texture_id => global.texture_error(texture_id));
|
||||
}
|
||||
let result = tuple_to_result(
|
||||
gfx_select!(texture_id => global.device_create_texture(
|
||||
device_id,
|
||||
&desc,
|
||||
texture_id
|
||||
)),
|
||||
);
|
||||
self.send_result(device_id, scope_id, result);
|
||||
} else {
|
||||
let _ = gfx_select!(texture_id => global.texture_error(texture_id));
|
||||
}
|
||||
},
|
||||
WebGPURequest::CreateTextureView {
|
||||
|
@ -806,23 +784,25 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
if let Some(desc) = descriptor {
|
||||
let result = gfx_select!(texture_view_id => global.texture_create_view(
|
||||
texture_id,
|
||||
&desc,
|
||||
texture_view_id
|
||||
));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(texture_view_id => global.texture_view_error(texture_view_id));
|
||||
}
|
||||
let result = tuple_to_result(
|
||||
gfx_select!(texture_view_id => global.texture_create_view(
|
||||
texture_id,
|
||||
&desc,
|
||||
texture_view_id
|
||||
)),
|
||||
);
|
||||
|
||||
self.send_result(device_id, scope_id, result);
|
||||
} else {
|
||||
let _ = gfx_select!(texture_view_id => global.texture_view_error(texture_view_id));
|
||||
}
|
||||
},
|
||||
WebGPURequest::DestroyBuffer(buffer) => {
|
||||
let global = &self.global;
|
||||
gfx_select!(buffer => global.buffer_drop(buffer, false));
|
||||
},
|
||||
WebGPURequest::DestroyDevice(device) => {
|
||||
let global = &self.global;
|
||||
gfx_select!(device => global.device_drop(device));
|
||||
},
|
||||
WebGPURequest::DestroySwapChain {
|
||||
external_id,
|
||||
image_key,
|
||||
|
@ -852,7 +832,7 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::DestroyTexture(texture) => {
|
||||
let global = &self.global;
|
||||
gfx_select!(texture => global.texture_drop(texture));
|
||||
gfx_select!(texture => global.texture_drop(texture, true));
|
||||
},
|
||||
WebGPURequest::Exit(sender) => {
|
||||
if let Err(e) = self.script_sender.send(WebGPUMsg::Exit) {
|
||||
|
@ -885,14 +865,14 @@ impl<'a> WGPU<'a> {
|
|||
device_id,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(render_bundle_id => global.render_bundle_encoder_finish(
|
||||
render_bundle_encoder,
|
||||
&descriptor,
|
||||
render_bundle_id
|
||||
));
|
||||
if result.is_err() {
|
||||
let _ = gfx_select!(render_bundle_id => global.render_bundle_error(render_bundle_id));
|
||||
}
|
||||
let result = tuple_to_result(
|
||||
gfx_select!(render_bundle_id => global.render_bundle_encoder_finish(
|
||||
render_bundle_encoder,
|
||||
&descriptor,
|
||||
render_bundle_id
|
||||
)),
|
||||
);
|
||||
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::RequestAdapter {
|
||||
|
@ -920,9 +900,12 @@ impl<'a> WGPU<'a> {
|
|||
let global = &self.global;
|
||||
let info =
|
||||
gfx_select!(adapter_id => global.adapter_get_info(adapter_id)).unwrap();
|
||||
let limits =
|
||||
gfx_select!(adapter_id => global.adapter_limits(adapter_id)).unwrap();
|
||||
if let Err(e) = sender.send(Ok(WebGPUResponse::RequestAdapter {
|
||||
adapter_name: info.name,
|
||||
adapter_info: info,
|
||||
adapter_id: adapter,
|
||||
limits,
|
||||
channel: WebGPU(self.sender.clone()),
|
||||
})) {
|
||||
warn!(
|
||||
|
@ -937,18 +920,23 @@ impl<'a> WGPU<'a> {
|
|||
descriptor,
|
||||
device_id,
|
||||
pipeline_id,
|
||||
label,
|
||||
} => {
|
||||
let desc = DeviceDescriptor {
|
||||
label: descriptor.label.as_ref().map(|l| crate::Cow::from(l)),
|
||||
features: descriptor.features.clone(),
|
||||
limits: descriptor.limits.clone(),
|
||||
};
|
||||
let global = &self.global;
|
||||
let id = match gfx_select!(device_id => global.adapter_request_device(
|
||||
adapter_id.0,
|
||||
&descriptor,
|
||||
None,
|
||||
device_id
|
||||
)) {
|
||||
let id = match tuple_to_result(
|
||||
gfx_select!(device_id => global.adapter_request_device(
|
||||
adapter_id.0,
|
||||
&desc,
|
||||
None,
|
||||
device_id
|
||||
)),
|
||||
) {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
let _ = gfx_select!(device_id => global.device_error(device_id));
|
||||
if let Err(w) = sender.send(Err(format!("{:?}", e))) {
|
||||
warn!(
|
||||
"Failed to send response to WebGPURequest::RequestDevice ({})",
|
||||
|
@ -967,7 +955,6 @@ impl<'a> WGPU<'a> {
|
|||
device_id: device,
|
||||
queue_id: queue,
|
||||
descriptor,
|
||||
label,
|
||||
})) {
|
||||
warn!(
|
||||
"Failed to send response to WebGPURequest::RequestDevice ({})",
|
||||
|
@ -1051,8 +1038,8 @@ impl<'a> WGPU<'a> {
|
|||
let buffer_desc = wgt::BufferDescriptor {
|
||||
label: None,
|
||||
size: buffer_size,
|
||||
usage: wgt::BufferUsage::MAP_READ |
|
||||
wgt::BufferUsage::COPY_DST,
|
||||
usage: wgt::BufferUsages::MAP_READ |
|
||||
wgt::BufferUsages::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
};
|
||||
let _ = gfx_select!(b_id => global.device_create_buffer(
|
||||
|
@ -1084,23 +1071,24 @@ impl<'a> WGPU<'a> {
|
|||
encoder_id
|
||||
));
|
||||
|
||||
let buffer_cv = BufferCopyView {
|
||||
let buffer_cv = ImageCopyBuffer {
|
||||
buffer: buffer_id,
|
||||
layout: wgt::TextureDataLayout {
|
||||
layout: wgt::ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: buffer_stride,
|
||||
rows_per_image: 0,
|
||||
bytes_per_row: Some(buffer_stride),
|
||||
rows_per_image: None,
|
||||
},
|
||||
};
|
||||
let texture_cv = TextureCopyView {
|
||||
let texture_cv = ImageCopyTexture {
|
||||
texture: texture_id,
|
||||
mip_level: 0,
|
||||
origin: wgt::Origin3d::ZERO,
|
||||
aspect: wgt::TextureAspect::All,
|
||||
};
|
||||
let copy_size = wgt::Extent3d {
|
||||
width: size.width as u32,
|
||||
height: size.height as u32,
|
||||
depth: 1,
|
||||
depth_or_array_layers: 1,
|
||||
};
|
||||
let _ = gfx_select!(encoder_id => global.command_encoder_copy_texture_to_buffer(
|
||||
encoder_id,
|
||||
|
@ -1126,6 +1114,7 @@ impl<'a> WGPU<'a> {
|
|||
};
|
||||
self.present_buffer_maps
|
||||
.insert(buffer_id, Rc::new(map_info));
|
||||
// TODO(sagudev): replace with safe callback
|
||||
unsafe extern "C" fn callback(
|
||||
status: BufferMapAsyncStatus,
|
||||
userdata: *mut u8,
|
||||
|
@ -1152,10 +1141,14 @@ impl<'a> WGPU<'a> {
|
|||
}
|
||||
let map_op = BufferMapOperation {
|
||||
host: HostMap::Read,
|
||||
callback,
|
||||
user_data: convert_to_pointer(
|
||||
self.present_buffer_maps.get(&buffer_id).unwrap().clone(),
|
||||
),
|
||||
callback: unsafe {
|
||||
BufferMapCallback::from_c(BufferMapCallbackC {
|
||||
callback,
|
||||
user_data: convert_to_pointer(
|
||||
self.present_buffer_maps.get(&buffer_id).unwrap().clone(),
|
||||
),
|
||||
})
|
||||
},
|
||||
};
|
||||
let _ = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, 0..buffer_size, map_op));
|
||||
},
|
||||
|
@ -1169,14 +1162,17 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
if !is_map_read {
|
||||
let map_ptr = gfx_select!(buffer_id => global.buffer_get_mapped_range(
|
||||
buffer_id,
|
||||
offset,
|
||||
wgt::BufferSize::new(size)
|
||||
))
|
||||
.unwrap();
|
||||
unsafe { slice::from_raw_parts_mut(map_ptr, size as usize) }
|
||||
.copy_from_slice(&array_buffer);
|
||||
let (slice_pointer, range_size) =
|
||||
gfx_select!(buffer_id => global.buffer_get_mapped_range(
|
||||
buffer_id,
|
||||
offset,
|
||||
Some(size)
|
||||
))
|
||||
.unwrap();
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(slice_pointer, range_size as usize)
|
||||
}
|
||||
.copy_from_slice(&array_buffer);
|
||||
}
|
||||
let result = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
|
@ -1187,10 +1183,12 @@ impl<'a> WGPU<'a> {
|
|||
external_id,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let data_pt = gfx_select!(buffer_id =>
|
||||
global.buffer_get_mapped_range(buffer_id, 0, None))
|
||||
let (slice_pointer, range_size) = gfx_select!(buffer_id =>
|
||||
global.buffer_get_mapped_range(buffer_id, 0, Some(buffer_size as u64)))
|
||||
.unwrap();
|
||||
let data = unsafe { slice::from_raw_parts(data_pt, buffer_size) }.to_vec();
|
||||
let data =
|
||||
unsafe { slice::from_raw_parts(slice_pointer, range_size as usize) }
|
||||
.to_vec();
|
||||
if let Some(present_data) =
|
||||
self.wgpu_image_map.lock().unwrap().get_mut(&external_id)
|
||||
{
|
||||
|
@ -1297,6 +1295,14 @@ fn convert_to_pointer<T: Sized>(obj: Rc<T>) -> *mut u8 {
|
|||
Rc::into_raw(obj) as *mut u8
|
||||
}
|
||||
|
||||
fn tuple_to_result<T, E>(res: (T, Option<E>)) -> Result<T, E> {
|
||||
if let Some(err) = res.1 {
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(res.0)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! webgpu_resource {
|
||||
($name:ident, $id:ty) => {
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Hash, PartialEq, Serialize)]
|
||||
|
@ -1326,7 +1332,7 @@ webgpu_resource!(WebGPURenderBundle, id::RenderBundleId);
|
|||
webgpu_resource!(WebGPURenderPipeline, id::RenderPipelineId);
|
||||
webgpu_resource!(WebGPUSampler, id::SamplerId);
|
||||
webgpu_resource!(WebGPUShaderModule, id::ShaderModuleId);
|
||||
webgpu_resource!(WebGPUSwapChain, id::SwapChainId);
|
||||
webgpu_resource!(WebGPUSurface, id::SurfaceId);
|
||||
webgpu_resource!(WebGPUTexture, id::TextureId);
|
||||
webgpu_resource!(WebGPUTextureView, id::TextureViewId);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ libc = { workspace = true }
|
|||
winapi = { workspace = true, features = ["wingdi", "winuser", "winnt", "winbase", "processenv", "namedpipeapi", "ntdef", "minwindef", "handleapi", "debugapi"] }
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.20"
|
||||
cbindgen = "0.24"
|
||||
|
||||
[features]
|
||||
debugmozjs = ["simpleservo/debugmozjs"]
|
||||
|
|
|
@ -775,7 +775,7 @@ tests/wpt/mozilla/tests for Servo-only tests""" % reference_path)
|
|||
delete(path.join(tdir, "webgpu"))
|
||||
copy_tree(path.join(clone_dir, "out-wpt"), path.join(tdir, "webgpu"))
|
||||
# update commit
|
||||
commit = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode()
|
||||
commit = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=clone_dir).decode()
|
||||
with open(path.join(tdir, "checkout_commit.txt"), 'w') as file:
|
||||
file.write(commit)
|
||||
# clean up
|
||||
|
|
|
@ -25,17 +25,14 @@ packages = [
|
|||
"base64",
|
||||
"cfg-if",
|
||||
"cookie",
|
||||
"fixedbitset",
|
||||
"getrandom",
|
||||
"image",
|
||||
"itoa",
|
||||
"libloading",
|
||||
"metal",
|
||||
"miniz_oxide",
|
||||
"num-rational",
|
||||
"parking_lot",
|
||||
"parking_lot_core",
|
||||
"petgraph",
|
||||
"png",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
|
@ -74,14 +71,24 @@ packages = [
|
|||
"digest",
|
||||
"generic-array",
|
||||
|
||||
# Duplicated by winit/surfman update.
|
||||
"raw-window-handle",
|
||||
# Duplicated by surfman/wgpu update.
|
||||
"bitflags",
|
||||
"windows-sys",
|
||||
"windows-targets",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_x86_64_gnullvm",
|
||||
|
||||
# Temporarily duplicated until gleam can be upgrded.
|
||||
"uuid",
|
||||
|
||||
# winit port minibrowser (servo/servo#30049)
|
||||
"clipboard-win",
|
||||
"ahash",
|
||||
]
|
||||
# Files that are ignored for all tidy and lint checks.
|
||||
files = [
|
||||
|
@ -132,4 +139,4 @@ directories = [
|
|||
# Directories that are checked for correct file extension
|
||||
[check_ext]
|
||||
# directory, list of expected file extensions
|
||||
"./components/script/dom/webidls" = [".webidl"]
|
||||
"./components/script/dom/webidls" = [".webidl", "noidl"]
|
||||
|
|
|
@ -470,7 +470,7 @@
|
|||
[]
|
||||
],
|
||||
"checkout_commit.txt": [
|
||||
"5db12b3c0c240f6567fa294f3fa56dfd75b6e891",
|
||||
"ede5c184cdc42d0374d6e712f49f86313747cfea",
|
||||
[]
|
||||
],
|
||||
"webgpu": {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,2 +1,2 @@
|
|||
[canvas_clear.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_colorspace_rgba16float.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_complex_rgba16float_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_complex_rgba16float_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_complex_rgba16float_store.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_complex_rgba8unorm_store.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_bgra8unorm_opaque_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: [PASS, FAIL]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_bgra8unorm_opaque_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: [PASS, FAIL]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_bgra8unorm_premultiplied_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_bgra8unorm_premultiplied_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba16float_opaque_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba16float_opaque_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba16float_premultiplied_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba16float_premultiplied_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba8unorm_opaque_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: [PASS, FAIL]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba8unorm_opaque_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: [PASS, FAIL]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba8unorm_premultiplied_copy.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_composite_alpha_rgba8unorm_premultiplied_draw.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[canvas_image_rendering.https.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
|
|
|
@ -1 +1 @@
|
|||
9ab2eade6a818ed58ac1a7b36b706858f3ba5eb3
|
||||
480edec387e8cd5bf5934680050c59a3f7a01438
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue