webgpu: Implement onSubmittedWorkDone (#31772)

* Implement onSubmittedWorkDone

* Use rust closures for callback & actually remove entries from hashmap.

* Remove hashmap

* Fix warnings

* Update expectations

* clean flaky crashes

* re

* Update components/script/dom/gpuqueue.rs

Co-authored-by: Martin Robinson <mrobinson@igalia.com>

---------

Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Samson 2024-04-04 10:12:40 +02:00 committed by GitHub
parent 08ef158d4e
commit 62a916ce5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 1442 additions and 3109 deletions

View file

@ -2,19 +2,22 @@
* 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::rc::Rc;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSharedMemory; use ipc_channel::ipc::IpcSharedMemory;
use webgpu::identity::WebGPUOpResult; use webgpu::identity::WebGPUOpResult;
use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest}; use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest, WebGPUResponse};
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUImageCopyTexture, GPUImageDataLayout}; use super::bindings::codegen::Bindings::WebGPUBinding::{GPUImageCopyTexture, GPUImageDataLayout};
use super::gpu::{response_async, AsyncWGPUListener};
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
GPUExtent3D, GPUQueueMethods, GPUSize64, GPUExtent3D, GPUQueueMethods, GPUSize64,
}; };
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer as BufferSource; use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer as BufferSource;
use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString; use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
@ -25,6 +28,7 @@ use crate::dom::gpuconvert::{
convert_texture_size_to_wgt, convert_texture_size_to_wgt,
}; };
use crate::dom::gpudevice::GPUDevice; use crate::dom::gpudevice::GPUDevice;
use crate::dom::promise::Promise;
#[dom_struct] #[dom_struct]
pub struct GPUQueue { pub struct GPUQueue {
@ -191,4 +195,39 @@ impl GPUQueueMethods for GPUQueue {
Ok(()) Ok(())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpuqueue-onsubmittedworkdone>
fn OnSubmittedWorkDone(&self) -> Rc<Promise> {
let global = self.global();
let promise = Promise::new(&global);
let sender = response_async(&promise, self);
if let Err(e) = self.channel.0.send((
self.device.borrow().as_ref().unwrap().use_current_scope(),
WebGPURequest::QueueOnSubmittedWorkDone {
sender,
queue_id: self.queue.0,
},
)) {
warn!("QueueOnSubmittedWorkDone failed with {e}")
}
promise
}
}
impl AsyncWGPUListener for GPUQueue {
fn handle_response(
&self,
response: Option<Result<webgpu::WebGPUResponse, String>>,
promise: &Rc<Promise>,
) {
match response {
Some(Ok(WebGPUResponse::SubmittedWorkDone)) => {
promise.resolve_native(&());
},
_ => {
warn!("GPUQueue received wrong WebGPUResponse");
promise.reject_error(Error::Operation);
},
}
}
} }

View file

@ -991,8 +991,7 @@ dictionary GPURenderBundleEncoderDescriptor : GPURenderPassLayout {
interface GPUQueue { interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> buffers); undefined submit(sequence<GPUCommandBuffer> buffers);
//TODO: Promise<undefined> onSubmittedWorkDone();
//Promise<undefined> onSubmittedWorkDone();
[Throws] [Throws]
undefined writeBuffer( undefined writeBuffer(

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 log::{error, warn}; use log::{error, warn};
use wgpu::device::queue::SubmittedWorkDoneClosure;
use wgpu::gfx_select; use wgpu::gfx_select;
pub use {wgpu_core as wgpu, wgpu_types as wgt}; pub use {wgpu_core as wgpu, wgpu_types as wgt};
@ -69,6 +70,7 @@ pub enum WebGPUResponse {
descriptor: wgt::DeviceDescriptor<Option<String>>, descriptor: wgt::DeviceDescriptor<Option<String>>,
}, },
BufferMapAsync(IpcSharedMemory), BufferMapAsync(IpcSharedMemory),
SubmittedWorkDone,
} }
pub type WebGPUResponseResult = Result<WebGPUResponse, String>; pub type WebGPUResponseResult = Result<WebGPUResponse, String>;
@ -257,6 +259,10 @@ pub enum WebGPURequest {
size: wgt::Extent3d, size: wgt::Extent3d,
data: IpcSharedMemory, data: IpcSharedMemory,
}, },
QueueOnSubmittedWorkDone {
sender: IpcSender<Option<WebGPUResponseResult>>,
queue_id: id::QueueId,
},
} }
struct BufferMapInfo<'a, T> { struct BufferMapInfo<'a, T> {
@ -1249,6 +1255,18 @@ impl<'a> WGPU<'a> {
)); ));
self.send_result(queue_id, scope_id, result); self.send_result(queue_id, scope_id, result);
}, },
WebGPURequest::QueueOnSubmittedWorkDone { sender, queue_id } => {
let global = &self.global;
let callback = SubmittedWorkDoneClosure::from_rust(Box::from(move || {
if let Err(e) = sender.send(Some(Ok(WebGPUResponse::SubmittedWorkDone)))
{
warn!("Could not send SubmittedWorkDone Response ({})", e);
}
}));
let result = gfx_select!(queue_id => global.queue_on_submitted_work_done(queue_id, callback));
self.send_result(queue_id, scope_id, result);
},
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
[canvas_composite_alpha_rgba8unorm_opaque_copy.https.html] [canvas_composite_alpha_rgba8unorm_opaque_copy.https.html]
expected: expected:
if os == "linux" and not debug: [CRASH, PASS] if os == "linux" and not debug: [CRASH, PASS, FAIL]

View file

@ -1,3 +1,3 @@
[canvas_composite_alpha_rgba8unorm_opaque_draw.https.html] [canvas_composite_alpha_rgba8unorm_opaque_draw.https.html]
expected: expected:
if os == "linux" and not debug: PASS if os == "linux" and not debug: [PASS, FAIL]