webgpu: Use wgpu's instead of string errors and update limits handling (#32925)

* Use wgpu specific errors

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* fixup expect

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* WIP

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Fix records erasing enforcerange

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* page can already be destroyed

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Support more limits

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Set good results

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Set OK (not PASS) expect CRASH

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* fixup expectation

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* bad expectations

https://github.com/gfx-rs/wgpu/issues/6075
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* set bad expectation

render bundleencoder needs to be rewritten

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
Samson 2024-08-04 19:19:46 +02:00 committed by GitHub
parent b366a02318
commit 5e59988c87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 496 additions and 871 deletions

View file

@ -2,15 +2,17 @@
* 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::convert::TryFrom;
use std::rc::Rc;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject};
use webgpu::wgc::instance::RequestDeviceError;
use webgpu::wgt::MemoryHints;
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse};
use super::bindings::codegen::Bindings::WebGPUBinding::GPUDeviceLostReason;
use super::gpusupportedfeatures::GPUSupportedFeatures;
use super::gpusupportedlimits::set_limit;
use super::types::{GPUAdapterInfo, GPUSupportedLimits};
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
GPUAdapterMethods, GPUDeviceDescriptor,
@ -129,84 +131,10 @@ impl GPUAdapterMethods for GPUAdapter {
};
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.required_limits.max_texture_dimension_1d = v,
"maxTextureDimension2D" => desc.required_limits.max_texture_dimension_2d = v,
"maxTextureDimension3D" => desc.required_limits.max_texture_dimension_3d = v,
"maxTextureArrayLayers" => desc.required_limits.max_texture_array_layers = v,
"maxBindGroups" => desc.required_limits.max_bind_groups = v,
"maxBindingsPerBindGroup" => {
desc.required_limits.max_bindings_per_bind_group = v
},
"maxDynamicUniformBuffersPerPipelineLayout" => {
desc.required_limits
.max_dynamic_uniform_buffers_per_pipeline_layout = v
},
"maxDynamicStorageBuffersPerPipelineLayout" => {
desc.required_limits
.max_dynamic_storage_buffers_per_pipeline_layout = v
},
"maxSampledTexturesPerShaderStage" => {
desc.required_limits.max_sampled_textures_per_shader_stage = v
},
"maxSamplersPerShaderStage" => {
desc.required_limits.max_samplers_per_shader_stage = v
},
"maxStorageBuffersPerShaderStage" => {
desc.required_limits.max_storage_buffers_per_shader_stage = v
},
"maxStorageTexturesPerShaderStage" => {
desc.required_limits.max_storage_textures_per_shader_stage = v
},
"maxUniformBuffersPerShaderStage" => {
desc.required_limits.max_uniform_buffers_per_shader_stage = v
},
"maxUniformBufferBindingSize" => {
desc.required_limits.max_uniform_buffer_binding_size = v
},
"maxStorageBufferBindingSize" => {
desc.required_limits.max_storage_buffer_binding_size = v
},
"minUniformBufferOffsetAlignment" => {
desc.required_limits.min_uniform_buffer_offset_alignment = v
},
"minStorageBufferOffsetAlignment" => {
desc.required_limits.min_storage_buffer_offset_alignment = v
},
"maxVertexBuffers" => desc.required_limits.max_vertex_buffers = v,
"maxBufferSize" => desc.required_limits.max_buffer_size = *value,
"maxVertexAttributes" => desc.required_limits.max_vertex_attributes = v,
"maxVertexBufferArrayStride" => {
desc.required_limits.max_vertex_buffer_array_stride = v
},
"maxInterStageShaderComponents" => {
desc.required_limits.max_inter_stage_shader_components = v
},
"maxComputeWorkgroupStorageSize" => {
desc.required_limits.max_compute_workgroup_storage_size = v
},
"maxComputeInvocationsPerWorkgroup" => {
desc.required_limits.max_compute_invocations_per_workgroup = v
},
"maxComputeWorkgroupSizeX" => {
desc.required_limits.max_compute_workgroup_size_x = v
},
"maxComputeWorkgroupSizeY" => {
desc.required_limits.max_compute_workgroup_size_y = v
},
"maxComputeWorkgroupSizeZ" => {
desc.required_limits.max_compute_workgroup_size_z = v
},
"maxComputeWorkgroupsPerDimension" => {
desc.required_limits.max_compute_workgroups_per_dimension = v
},
_ => {
error!("Unknown required limit: {limit} with value {value}");
// we should reject but spec is still evolving
// promise.reject_error(Error::Operation);
// return promise;
},
if !set_limit(&mut desc.required_limits, limit.as_ref(), *value) {
warn!("Unknown GPUDevice limit: {limit}");
promise.reject_error(Error::Operation);
return promise;
}
}
}
@ -267,8 +195,7 @@ impl GPUAdapterMethods for GPUAdapter {
impl AsyncWGPUListener for GPUAdapter {
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
match response {
WebGPUResponse::Device(Ok(device)) => {
let descriptor = device.descriptor;
WebGPUResponse::Device((device_id, queue_id, Ok(descriptor))) => {
let device = GPUDevice::new(
&self.global(),
self.channel.clone(),
@ -276,16 +203,37 @@ impl AsyncWGPUListener for GPUAdapter {
Heap::default(),
descriptor.required_features,
descriptor.required_limits,
device.device_id,
device.queue_id,
device_id,
queue_id,
descriptor.label.unwrap_or_default(),
);
self.global().add_gpu_device(&device);
promise.resolve_native(&device);
},
WebGPUResponse::Device(Err(e)) => {
warn!("Could not get GPUDevice({:?})", e);
promise.reject_error(Error::Operation);
WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => {
promise.reject_error(Error::Type(
RequestDeviceError::UnsupportedFeature(f).to_string(),
))
},
WebGPUResponse::Device((
_,
_,
Err(RequestDeviceError::LimitsExceeded(_) | RequestDeviceError::InvalidAdapter),
)) => promise.reject_error(Error::Operation),
WebGPUResponse::Device((device_id, queue_id, Err(e))) => {
let device = GPUDevice::new(
&self.global(),
self.channel.clone(),
self,
Heap::default(),
wgt::Features::default(),
wgt::Limits::default(),
device_id,
queue_id,
String::new(),
);
device.lose(GPUDeviceLostReason::Unknown, e.to_string());
promise.resolve_native(&device);
},
WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"),
_ => unreachable!("GPUAdapter received wrong WebGPUResponse"),