Skip to content

Commit

Permalink
Add GPUSupportedFeatures and update GPUSupportedLimits (#30359)
Browse files Browse the repository at this point in the history
* GPUSupportedFeatures

* New supported limits

* Update expectations
  • Loading branch information
sagudev committed Sep 14, 2023
1 parent 6ea394a commit d22d97f
Show file tree
Hide file tree
Showing 12 changed files with 833 additions and 17,648 deletions.
2 changes: 2 additions & 0 deletions components/script/dom/gpu.rs
Expand Up @@ -144,6 +144,7 @@ impl AsyncWGPUListener for GPU {
Ok(WebGPUResponse::RequestAdapter {
adapter_info,
adapter_id,
features,
limits,
channel,
}) => {
Expand All @@ -156,6 +157,7 @@ impl AsyncWGPUListener for GPU {
adapter_id.0.backend()
)),
Heap::default(),
features,
limits,
adapter_info,
adapter_id,
Expand Down
73 changes: 34 additions & 39 deletions components/script/dom/gpuadapter.rs
Expand Up @@ -9,9 +9,10 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject};
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPUResponseResult};

use super::gpusupportedfeatures::GPUSupportedFeatures;
use super::types::{GPUAdapterInfo, GPUSupportedLimits};
use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::{
GPUAdapterMethods, GPUDeviceDescriptor, GPUFeatureName,
GPUAdapterMethods, GPUDeviceDescriptor,
};
use crate::dom::bindings::error::Error;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
Expand All @@ -20,6 +21,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpu::{response_async, AsyncWGPUListener};
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpusupportedfeatures::gpu_to_wgt_feature;
use crate::dom::promise::Promise;
use crate::realms::InRealm;

Expand All @@ -32,6 +34,7 @@ pub struct GPUAdapter {
name: DOMString,
#[ignore_malloc_size_of = "mozjs"]
extensions: Heap<*mut JSObject>,
features: Dom<GPUSupportedFeatures>,
limits: Dom<GPUSupportedLimits>,
info: Dom<GPUAdapterInfo>,
#[no_trace]
Expand All @@ -43,6 +46,7 @@ impl GPUAdapter {
channel: WebGPU,
name: DOMString,
extensions: Heap<*mut JSObject>,
features: &GPUSupportedFeatures,
limits: &GPUSupportedLimits,
info: &GPUAdapterInfo,
adapter: WebGPUAdapter,
Expand All @@ -52,6 +56,7 @@ impl GPUAdapter {
channel,
name,
extensions,
features: Dom::from_ref(features),
limits: Dom::from_ref(limits),
info: Dom::from_ref(info),
adapter,
Expand All @@ -63,15 +68,17 @@ impl GPUAdapter {
channel: WebGPU,
name: DOMString,
extensions: Heap<*mut JSObject>,
features: wgt::Features,
limits: wgt::Limits,
info: wgt::AdapterInfo,
adapter: WebGPUAdapter,
) -> DomRoot<Self> {
let features = GPUSupportedFeatures::Constructor(global, None, features).unwrap();
let limits = GPUSupportedLimits::new(global, limits);
let info = GPUAdapterInfo::new(global, info);
reflect_dom_object(
Box::new(GPUAdapter::new_inherited(
channel, name, extensions, &limits, &info, adapter,
channel, name, extensions, &features, &limits, &info, adapter,
)),
global,
)
Expand All @@ -86,35 +93,14 @@ impl GPUAdapterMethods for GPUAdapter {
let sender = response_async(&promise, self);
let mut features = wgt::Features::empty();
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)
},
if let Some(feature) = gpu_to_wgt_feature(ext) {
features.insert(feature);
} else {
promise.reject_error(Error::Type(format!(
"{} is not supported feature",
ext.as_str()
)));
return promise;
}
}

Expand All @@ -123,15 +109,16 @@ impl GPUAdapterMethods for GPUAdapter {
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() {
if let Some(limits) = &descriptor.requiredLimits {
for (limit, value) in (*limits).iter() {
let v = u32::try_from(*value).unwrap_or(u32::MAX);
match limit.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,
"maxBindingsPerBindGroup" => desc.limits.max_bindings_per_bind_group = v,
"maxDynamicUniformBuffersPerPipelineLayout" => {
desc.limits.max_dynamic_uniform_buffers_per_pipeline_layout = v
},
Expand Down Expand Up @@ -164,6 +151,7 @@ impl GPUAdapterMethods for GPUAdapter {
desc.limits.min_storage_buffer_offset_alignment = v
},
"maxVertexBuffers" => desc.limits.max_vertex_buffers = v,
"maxBufferSize" => desc.limits.max_buffer_size = *value,
"maxVertexAttributes" => desc.limits.max_vertex_attributes = v,
"maxVertexBufferArrayStride" => desc.limits.max_vertex_buffer_array_stride = v,
"maxInterStageShaderComponents" => {
Expand All @@ -182,9 +170,10 @@ impl GPUAdapterMethods for GPUAdapter {
desc.limits.max_compute_workgroups_per_dimension = v
},
_ => {
error!("Unknown required limit: {k} with value {v}");
promise.reject_error(Error::Operation);
return promise;
error!("Unknown required limit: {limit} with value {value}");
// we should reject but spec is still evolving
// promise.reject_error(Error::Operation);
// return promise;
},
}
}
Expand Down Expand Up @@ -236,7 +225,12 @@ impl GPUAdapterMethods for GPUAdapter {
promise
}

/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-limits
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-features
fn Features(&self) -> DomRoot<GPUSupportedFeatures> {
DomRoot::from_ref(&self.features)
}

/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-limits
fn Limits(&self) -> DomRoot<GPUSupportedLimits> {
DomRoot::from_ref(&self.limits)
}
Expand All @@ -255,6 +249,7 @@ impl AsyncWGPUListener for GPUAdapter {
self.channel.clone(),
&self,
Heap::default(),
descriptor.features,
descriptor.limits,
device_id,
queue_id,
Expand Down
13 changes: 12 additions & 1 deletion components/script/dom/gpudevice.rs
Expand Up @@ -82,6 +82,7 @@ use crate::dom::gpurenderbundleencoder::GPURenderBundleEncoder;
use crate::dom::gpurenderpipeline::GPURenderPipeline;
use crate::dom::gpusampler::GPUSampler;
use crate::dom::gpushadermodule::GPUShaderModule;
use crate::dom::gpusupportedfeatures::GPUSupportedFeatures;
use crate::dom::gputexture::GPUTexture;
use crate::dom::gpuuncapturederrorevent::GPUUncapturedErrorEvent;
use crate::dom::gpuvalidationerror::GPUValidationError;
Expand Down Expand Up @@ -120,6 +121,7 @@ pub struct GPUDevice {
adapter: Dom<GPUAdapter>,
#[ignore_malloc_size_of = "mozjs"]
extensions: Heap<*mut JSObject>,
features: Dom<GPUSupportedFeatures>,
limits: Dom<GPUSupportedLimits>,
label: DomRefCell<USVString>,
#[no_trace]
Expand All @@ -136,6 +138,7 @@ impl GPUDevice {
channel: WebGPU,
adapter: &GPUAdapter,
extensions: Heap<*mut JSObject>,
features: &GPUSupportedFeatures,
limits: &GPUSupportedLimits,
device: webgpu::WebGPUDevice,
queue: &GPUQueue,
Expand All @@ -146,6 +149,7 @@ impl GPUDevice {
channel,
adapter: Dom::from_ref(adapter),
extensions,
features: Dom::from_ref(features),
limits: Dom::from_ref(limits),
label: DomRefCell::new(USVString::from(label)),
device,
Expand All @@ -165,16 +169,18 @@ impl GPUDevice {
channel: WebGPU,
adapter: &GPUAdapter,
extensions: Heap<*mut JSObject>,
features: wgt::Features,
limits: wgt::Limits,
device: webgpu::WebGPUDevice,
queue: webgpu::WebGPUQueue,
label: String,
) -> DomRoot<Self> {
let queue = GPUQueue::new(global, channel.clone(), queue);
let limits = GPUSupportedLimits::new(global, limits);
let features = GPUSupportedFeatures::Constructor(global, None, features).unwrap();
let device = reflect_dom_object(
Box::new(GPUDevice::new_inherited(
channel, adapter, extensions, &limits, device, &queue, label,
channel, adapter, extensions, &features, &limits, device, &queue, label,
)),
global,
);
Expand Down Expand Up @@ -343,6 +349,11 @@ impl GPUDevice {
}

impl GPUDeviceMethods for GPUDevice {
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-features
fn Features(&self) -> DomRoot<GPUSupportedFeatures> {
DomRoot::from_ref(&self.features)
}

/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-limits
fn Limits(&self) -> DomRoot<GPUSupportedLimits> {
DomRoot::from_ref(&self.limits)
Expand Down

0 comments on commit d22d97f

Please sign in to comment.