mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add GPUSupportedFeatures and update GPUSupportedLimits (#30359)
* GPUSupportedFeatures * New supported limits * Update expectations
This commit is contained in:
parent
6ea394a701
commit
d22d97f8c8
12 changed files with 243 additions and 17058 deletions
|
@ -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};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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]
|
||||
|
@ -43,6 +46,7 @@ impl GPUAdapter {
|
|||
channel: WebGPU,
|
||||
name: DOMString,
|
||||
extensions: Heap<*mut JSObject>,
|
||||
features: &GPUSupportedFeatures,
|
||||
limits: &GPUSupportedLimits,
|
||||
info: &GPUAdapterInfo,
|
||||
adapter: WebGPUAdapter,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
},
|
||||
|
@ -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" => {
|
||||
|
@ -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;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -255,6 +249,7 @@ impl AsyncWGPUListener for GPUAdapter {
|
|||
self.channel.clone(),
|
||||
&self,
|
||||
Heap::default(),
|
||||
descriptor.features,
|
||||
descriptor.limits,
|
||||
device_id,
|
||||
queue_id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue