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

@ -718,7 +718,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
isMember="Sequence", isMember="Sequence",
isAutoRooted=isAutoRooted) isAutoRooted=isAutoRooted)
declType = wrapInNativeContainerType(type, innerInfo.declType) declType = wrapInNativeContainerType(type, innerInfo.declType)
config = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) config = getConversionConfigForType(type, innerContainerType(type).hasEnforceRange(), isClamp, treatNullAs)
if type.nullable(): if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=" >") declType = CGWrapper(declType, pre="Option<", post=" >")

View file

@ -2,15 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::convert::TryFrom;
use std::rc::Rc; use std::rc::Rc;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject}; use js::jsapi::{Heap, JSObject};
use webgpu::wgc::instance::RequestDeviceError;
use webgpu::wgt::MemoryHints; use webgpu::wgt::MemoryHints;
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse}; use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse};
use super::bindings::codegen::Bindings::WebGPUBinding::GPUDeviceLostReason;
use super::gpusupportedfeatures::GPUSupportedFeatures; use super::gpusupportedfeatures::GPUSupportedFeatures;
use super::gpusupportedlimits::set_limit;
use super::types::{GPUAdapterInfo, GPUSupportedLimits}; use super::types::{GPUAdapterInfo, GPUSupportedLimits};
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
GPUAdapterMethods, GPUDeviceDescriptor, GPUAdapterMethods, GPUDeviceDescriptor,
@ -129,84 +131,10 @@ impl GPUAdapterMethods for GPUAdapter {
}; };
if let Some(limits) = &descriptor.requiredLimits { if let Some(limits) = &descriptor.requiredLimits {
for (limit, value) in (*limits).iter() { for (limit, value) in (*limits).iter() {
let v = u32::try_from(*value).unwrap_or(u32::MAX); if !set_limit(&mut desc.required_limits, limit.as_ref(), *value) {
match limit.as_ref() { warn!("Unknown GPUDevice limit: {limit}");
"maxTextureDimension1D" => desc.required_limits.max_texture_dimension_1d = v, promise.reject_error(Error::Operation);
"maxTextureDimension2D" => desc.required_limits.max_texture_dimension_2d = v, return promise;
"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;
},
} }
} }
} }
@ -267,8 +195,7 @@ impl GPUAdapterMethods for GPUAdapter {
impl AsyncWGPUListener for GPUAdapter { impl AsyncWGPUListener for GPUAdapter {
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
match response { match response {
WebGPUResponse::Device(Ok(device)) => { WebGPUResponse::Device((device_id, queue_id, Ok(descriptor))) => {
let descriptor = device.descriptor;
let device = GPUDevice::new( let device = GPUDevice::new(
&self.global(), &self.global(),
self.channel.clone(), self.channel.clone(),
@ -276,16 +203,37 @@ impl AsyncWGPUListener for GPUAdapter {
Heap::default(), Heap::default(),
descriptor.required_features, descriptor.required_features,
descriptor.required_limits, descriptor.required_limits,
device.device_id, device_id,
device.queue_id, queue_id,
descriptor.label.unwrap_or_default(), descriptor.label.unwrap_or_default(),
); );
self.global().add_gpu_device(&device); self.global().add_gpu_device(&device);
promise.resolve_native(&device); promise.resolve_native(&device);
}, },
WebGPUResponse::Device(Err(e)) => { WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => {
warn!("Could not get GPUDevice({:?})", e); promise.reject_error(Error::Type(
promise.reject_error(Error::Operation); 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"), WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"),
_ => unreachable!("GPUAdapter received wrong WebGPUResponse"), _ => unreachable!("GPUAdapter received wrong WebGPUResponse"),

View file

@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct; use dom_struct::dom_struct;
use num_traits::bounds::UpperBounded;
use webgpu::wgt::Limits; use webgpu::wgt::Limits;
use GPUSupportedLimits_Binding::GPUSupportedLimitsMethods; use GPUSupportedLimits_Binding::GPUSupportedLimitsMethods;
@ -173,4 +174,144 @@ impl GPUSupportedLimitsMethods for GPUSupportedLimits {
fn MaxComputeWorkgroupsPerDimension(&self) -> u32 { fn MaxComputeWorkgroupsPerDimension(&self) -> u32 {
self.limits.max_compute_workgroups_per_dimension self.limits.max_compute_workgroups_per_dimension
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxbindgroupsplusvertexbuffers>
fn MaxBindGroupsPlusVertexBuffers(&self) -> u32 {
// Not on wgpu yet, so we craft it manually
self.limits.max_bind_groups + self.limits.max_vertex_buffers
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxinterstageshadervariables>
fn MaxInterStageShaderVariables(&self) -> u32 {
// Not in wgpu yet, so we use default value from spec
16
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcolorattachments>
fn MaxColorAttachments(&self) -> u32 {
self.limits.max_color_attachments
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxcolorattachmentbytespersample>
fn MaxColorAttachmentBytesPerSample(&self) -> u32 {
self.limits.max_color_attachment_bytes_per_sample
}
}
/// Returns false if unknown limit or other value error
pub fn set_limit(limits: &mut Limits, limit: &str, value: u64) -> bool {
/// per spec defaults are lower bounds for values
///
/// https://www.w3.org/TR/webgpu/#limit-class-maximum
fn set_maximum<T>(limit: &mut T, value: u64) -> bool
where
T: Ord + Copy + TryFrom<u64> + UpperBounded,
{
if let Ok(value) = T::try_from(value) {
*limit = value.max(*limit);
true
} else {
false
}
}
/// per spec defaults are higher bounds for values
///
/// <https://www.w3.org/TR/webgpu/#limit-class-alignment>
fn set_alignment<T>(limit: &mut T, value: u64) -> bool
where
T: Ord + Copy + TryFrom<u64> + UpperBounded,
{
if !value.is_power_of_two() {
return false;
}
if let Ok(value) = T::try_from(value) {
*limit = value.min(*limit);
true
} else {
false
}
}
match limit {
"maxTextureDimension1D" => set_maximum(&mut limits.max_texture_dimension_1d, value),
"maxTextureDimension2D" => set_maximum(&mut limits.max_texture_dimension_2d, value),
"maxTextureDimension3D" => set_maximum(&mut limits.max_texture_dimension_3d, value),
"maxTextureArrayLayers" => set_maximum(&mut limits.max_texture_array_layers, value),
"maxBindGroups" => set_maximum(&mut limits.max_bind_groups, value),
"maxBindGroupsPlusVertexBuffers" => {
// not in wgpu but we're allowed to give back better limits than requested.
// we use dummy value to still produce value verification
let mut v: u32 = 0;
set_maximum(&mut v, value)
},
"maxBindingsPerBindGroup" => set_maximum(&mut limits.max_bindings_per_bind_group, value),
"maxDynamicUniformBuffersPerPipelineLayout" => set_maximum(
&mut limits.max_dynamic_uniform_buffers_per_pipeline_layout,
value,
),
"maxDynamicStorageBuffersPerPipelineLayout" => set_maximum(
&mut limits.max_dynamic_storage_buffers_per_pipeline_layout,
value,
),
"maxSampledTexturesPerShaderStage" => {
set_maximum(&mut limits.max_sampled_textures_per_shader_stage, value)
},
"maxSamplersPerShaderStage" => {
set_maximum(&mut limits.max_samplers_per_shader_stage, value)
},
"maxStorageBuffersPerShaderStage" => {
set_maximum(&mut limits.max_storage_buffers_per_shader_stage, value)
},
"maxStorageTexturesPerShaderStage" => {
set_maximum(&mut limits.max_storage_textures_per_shader_stage, value)
},
"maxUniformBuffersPerShaderStage" => {
set_maximum(&mut limits.max_uniform_buffers_per_shader_stage, value)
},
"maxUniformBufferBindingSize" => {
set_maximum(&mut limits.max_uniform_buffer_binding_size, value)
},
"maxStorageBufferBindingSize" => {
set_maximum(&mut limits.max_storage_buffer_binding_size, value)
},
"minUniformBufferOffsetAlignment" => {
set_alignment(&mut limits.min_uniform_buffer_offset_alignment, value)
},
"minStorageBufferOffsetAlignment" => {
set_alignment(&mut limits.min_storage_buffer_offset_alignment, value)
},
"maxVertexBuffers" => set_maximum(&mut limits.max_vertex_buffers, value),
"maxBufferSize" => set_maximum(&mut limits.max_buffer_size, value),
"maxVertexAttributes" => set_maximum(&mut limits.max_vertex_attributes, value),
"maxVertexBufferArrayStride" => {
set_maximum(&mut limits.max_vertex_buffer_array_stride, value)
},
"maxInterStageShaderComponents" => {
set_maximum(&mut limits.max_inter_stage_shader_components, value)
},
"maxInterStageShaderVariables" => {
// not in wgpu but we're allowed to give back better limits than requested.
// we use dummy value to still produce value verification
let mut v: u32 = 0;
set_maximum(&mut v, value)
},
"maxColorAttachments" => set_maximum(&mut limits.max_color_attachments, value),
"maxColorAttachmentBytesPerSample" => {
set_maximum(&mut limits.max_color_attachment_bytes_per_sample, value)
},
"maxComputeWorkgroupStorageSize" => {
set_maximum(&mut limits.max_compute_workgroup_storage_size, value)
},
"maxComputeInvocationsPerWorkgroup" => {
set_maximum(&mut limits.max_compute_invocations_per_workgroup, value)
},
"maxComputeWorkgroupSizeX" => set_maximum(&mut limits.max_compute_workgroup_size_x, value),
"maxComputeWorkgroupSizeY" => set_maximum(&mut limits.max_compute_workgroup_size_y, value),
"maxComputeWorkgroupSizeZ" => set_maximum(&mut limits.max_compute_workgroup_size_z, value),
"maxComputeWorkgroupsPerDimension" => {
set_maximum(&mut limits.max_compute_workgroups_per_dimension, value)
},
_ => false,
}
} }

View file

@ -21,7 +21,7 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension3D; readonly attribute unsigned long maxTextureDimension3D;
readonly attribute unsigned long maxTextureArrayLayers; readonly attribute unsigned long maxTextureArrayLayers;
readonly attribute unsigned long maxBindGroups; readonly attribute unsigned long maxBindGroups;
//readonly attribute unsigned long maxBindGroupsPlusVertexBuffers; readonly attribute unsigned long maxBindGroupsPlusVertexBuffers;
readonly attribute unsigned long maxBindingsPerBindGroup; readonly attribute unsigned long maxBindingsPerBindGroup;
readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout; readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout;
readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout; readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout;
@ -39,9 +39,9 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxVertexAttributes; readonly attribute unsigned long maxVertexAttributes;
readonly attribute unsigned long maxVertexBufferArrayStride; readonly attribute unsigned long maxVertexBufferArrayStride;
readonly attribute unsigned long maxInterStageShaderComponents; readonly attribute unsigned long maxInterStageShaderComponents;
//readonly attribute unsigned long maxInterStageShaderVariables; readonly attribute unsigned long maxInterStageShaderVariables;
//readonly attribute unsigned long maxColorAttachments; readonly attribute unsigned long maxColorAttachments;
//readonly attribute unsigned long maxColorAttachmentBytesPerSample; readonly attribute unsigned long maxColorAttachmentBytesPerSample;
readonly attribute unsigned long maxComputeWorkgroupStorageSize; readonly attribute unsigned long maxComputeWorkgroupStorageSize;
readonly attribute unsigned long maxComputeInvocationsPerWorkgroup; readonly attribute unsigned long maxComputeInvocationsPerWorkgroup;
readonly attribute unsigned long maxComputeWorkgroupSizeX; readonly attribute unsigned long maxComputeWorkgroupSizeX;

View file

@ -2427,8 +2427,9 @@ impl ScriptThread {
pipeline_id, pipeline_id,
} => { } => {
self.gpu_id_hub.free_device_id(device_id); self.gpu_id_hub.free_device_id(device_id);
let global = self.documents.borrow().find_global(pipeline_id).unwrap(); if let Some(global) = self.documents.borrow().find_global(pipeline_id) {
global.remove_gpu_device(WebGPUDevice(device_id)); global.remove_gpu_device(WebGPUDevice(device_id));
} // page can already be destroyed
}, },
WebGPUMsg::FreeBuffer(id) => self.gpu_id_hub.free_buffer_id(id), WebGPUMsg::FreeBuffer(id) => self.gpu_id_hub.free_buffer_id(id),
WebGPUMsg::FreePipelineLayout(id) => self.gpu_id_hub.free_pipeline_layout_id(id), WebGPUMsg::FreePipelineLayout(id) => self.gpu_id_hub.free_pipeline_layout_id(id),

View file

@ -7,6 +7,8 @@
use ipc_channel::ipc::IpcSharedMemory; use ipc_channel::ipc::IpcSharedMemory;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use wgc::pipeline::CreateShaderModuleError; use wgc::pipeline::CreateShaderModuleError;
use wgpu_core::instance::{RequestAdapterError, RequestDeviceError};
use wgpu_core::resource::BufferAccessError;
pub use {wgpu_core as wgc, wgpu_types as wgt}; pub use {wgpu_core as wgc, wgpu_types as wgt};
use crate::identity::*; use crate::identity::*;
@ -63,22 +65,20 @@ pub struct Adapter {
pub channel: WebGPU, pub channel: WebGPU,
} }
#[derive(Debug, Deserialize, Serialize)]
pub struct Device {
pub device_id: WebGPUDevice,
pub queue_id: WebGPUQueue,
pub descriptor: wgt::DeviceDescriptor<Option<String>>,
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub enum WebGPUResponse { pub enum WebGPUResponse {
/// WebGPU is disabled /// WebGPU is disabled
None, None,
// TODO: use wgpu errors Adapter(Result<Adapter, RequestAdapterError>),
Adapter(Result<Adapter, String>), Device(
Device(Result<Device, String>), (
BufferMapAsync(Result<IpcSharedMemory, String>), WebGPUDevice,
WebGPUQueue,
Result<wgt::DeviceDescriptor<Option<String>>, RequestDeviceError>,
),
),
BufferMapAsync(Result<IpcSharedMemory, BufferAccessError>),
SubmittedWorkDone, SubmittedWorkDone,
PoppedErrorScope(Result<Option<Error>, PopError>), PoppedErrorScope(Result<Option<Error>, PopError>),
CompilationInfo(Option<ShaderCompilationInfo>), CompilationInfo(Option<ShaderCompilationInfo>),

View file

@ -38,8 +38,8 @@ use crate::gpu_error::ErrorScope;
use crate::poll_thread::Poller; use crate::poll_thread::Poller;
use crate::render_commands::apply_render_command; use crate::render_commands::apply_render_command;
use crate::{ use crate::{
Adapter, ComputePassId, Device, Error, PopError, PresentationData, RenderPassId, Transmute, Adapter, ComputePassId, Error, PopError, PresentationData, RenderPassId, Transmute, WebGPU,
WebGPU, WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse, WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse,
}; };
pub const PRESENTATION_BUFFER_COUNT: usize = 10; pub const PRESENTATION_BUFFER_COUNT: usize = 10;
@ -189,23 +189,21 @@ impl WGPU {
let callback = BufferMapCallback::from_rust(Box::from( let callback = BufferMapCallback::from_rust(Box::from(
move |result: BufferAccessResult| { move |result: BufferAccessResult| {
drop(token); drop(token);
let response = result let response = result.map(|_| {
.map(|_| { let global = &glob;
let global = &glob; let (slice_pointer, range_size) = gfx_select!(buffer_id =>
let (slice_pointer, range_size) = gfx_select!(buffer_id =>
global.buffer_get_mapped_range(buffer_id, 0, None)) global.buffer_get_mapped_range(buffer_id, 0, None))
.unwrap(); .unwrap();
// SAFETY: guarantee to be safe from wgpu // SAFETY: guarantee to be safe from wgpu
let data = unsafe { let data = unsafe {
slice::from_raw_parts( slice::from_raw_parts(
slice_pointer.as_ptr(), slice_pointer.as_ptr(),
range_size as usize, range_size as usize,
) )
}; };
IpcSharedMemory::from_bytes(data) IpcSharedMemory::from_bytes(data)
}) });
.map_err(|e| e.to_string());
if let Err(e) = if let Err(e) =
resp_sender.send(WebGPUResponse::BufferMapAsync(response)) resp_sender.send(WebGPUResponse::BufferMapAsync(response))
{ {
@ -226,13 +224,14 @@ impl WGPU {
operation operation
)); ));
self.poller.wake(); self.poller.wake();
if let Err(ref e) = result { if let Err(e) = &result {
if let Err(w) = if let Err(w) =
sender.send(WebGPUResponse::BufferMapAsync(Err(e.to_string()))) sender.send(WebGPUResponse::BufferMapAsync(Err(e.to_owned())))
{ {
warn!("Failed to send BufferMapAsync Response ({:?})", w); warn!("Failed to send BufferMapAsync Response ({:?})", w);
} }
} }
// Per spec we also need to raise validation error here
self.maybe_dispatch_wgpu_error(device_id, result.err()); self.maybe_dispatch_wgpu_error(device_id, result.err());
}, },
WebGPURequest::CommandEncoderFinish { WebGPURequest::CommandEncoderFinish {
@ -691,8 +690,7 @@ impl WGPU {
limits, limits,
channel: WebGPU(self.sender.clone()), channel: WebGPU(self.sender.clone()),
} }
}) });
.map_err(|e| e.to_string());
if let Err(e) = sender.send(WebGPUResponse::Adapter(response)) { if let Err(e) = sender.send(WebGPUResponse::Adapter(response)) {
warn!( warn!(
@ -722,8 +720,11 @@ impl WGPU {
Some(device_id), Some(device_id),
Some(device_id.transmute()), Some(device_id.transmute()),
)); ));
let device = WebGPUDevice(device_id);
let queue = WebGPUQueue(queue_id);
if let Some(e) = error { if let Some(e) = error {
if let Err(e) = sender.send(WebGPUResponse::Device(Err(e.to_string()))) if let Err(e) =
sender.send(WebGPUResponse::Device((device, queue, Err(e))))
{ {
warn!( warn!(
"Failed to send response to WebGPURequest::RequestDevice ({})", "Failed to send response to WebGPURequest::RequestDevice ({})",
@ -732,8 +733,6 @@ impl WGPU {
} }
continue; continue;
} }
let device = WebGPUDevice(device_id);
let queue = WebGPUQueue(queue_id);
{ {
self.devices self.devices
.lock() .lock()
@ -777,11 +776,9 @@ impl WGPU {
} }
})); }));
gfx_select!(device_id => global.device_set_device_lost_closure(device_id, callback)); gfx_select!(device_id => global.device_set_device_lost_closure(device_id, callback));
if let Err(e) = sender.send(WebGPUResponse::Device(Ok(Device { if let Err(e) =
device_id: device, sender.send(WebGPUResponse::Device((device, queue, Ok(descriptor))))
queue_id: queue, {
descriptor,
}))) {
warn!( warn!(
"Failed to send response to WebGPURequest::RequestDevice ({})", "Failed to send response to WebGPURequest::RequestDevice ({})",
e e

File diff suppressed because it is too large Load diff