diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index 42fe0eeec90..ef6dee69c77 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -138,10 +138,14 @@ impl GPUAdapterMethods for GPUAdapter { } } } - let id = self + let device_id = self .global() .wgpu_id_hub() .create_device_id(self.adapter.0.backend()); + let queue_id = self + .global() + .wgpu_id_hub() + .create_queue_id(self.adapter.0.backend()); let pipeline_id = self.global().pipeline_id(); if self .channel @@ -150,7 +154,8 @@ impl GPUAdapterMethods for GPUAdapter { sender, adapter_id: self.adapter, descriptor: desc, - device_id: id, + device_id, + queue_id, pipeline_id, }) .is_err() diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index c0e502b40cf..08226de337c 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -272,6 +272,7 @@ impl GPUCanvasContextMethods for GPUCanvasContext { .0 .send(WebGPURequest::CreateSwapChain { device_id: descriptor.device.id().0, + queue_id: descriptor.device.GetQueue().id().0, buffer_ids, external_id: self.context_id.0, sender, diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index 93bd32879d4..f69cc278094 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -61,6 +61,10 @@ impl GPUQueue { pub fn set_device(&self, device: &GPUDevice) { *self.device.borrow_mut() = Some(Dom::from_ref(device)); } + + pub fn id(&self) -> WebGPUQueue { + self.queue + } } impl GPUQueueMethods for GPUQueue { @@ -95,6 +99,7 @@ impl GPUQueueMethods for GPUQueue { self.channel .0 .send(WebGPURequest::Submit { + device_id: self.device.borrow().as_ref().unwrap().id().0, queue_id: self.queue.0, command_buffers, }) @@ -133,6 +138,7 @@ impl GPUQueueMethods for GPUQueue { &bytes[data_offset as usize..(data_offset + content_size) as usize], ); if let Err(e) = self.channel.0.send(WebGPURequest::WriteBuffer { + device_id: self.device.borrow().as_ref().unwrap().id().0, queue_id: self.queue.0, buffer_id: buffer.id().0, buffer_offset, @@ -169,6 +175,7 @@ impl GPUQueueMethods for GPUQueue { let final_data = IpcSharedMemory::from_bytes(&bytes); if let Err(e) = self.channel.0.send(WebGPURequest::WriteTexture { + device_id: self.device.borrow().as_ref().unwrap().id().0, queue_id: self.queue.0, texture_cv, data_layout: texture_layout, @@ -197,6 +204,7 @@ impl GPUQueueMethods for GPUQueue { .send(WebGPURequest::QueueOnSubmittedWorkDone { sender, queue_id: self.queue.0, + device_id: self.device.borrow().as_ref().unwrap().id().0, }) { warn!("QueueOnSubmittedWorkDone failed with {e}") diff --git a/components/script/dom/identityhub.rs b/components/script/dom/identityhub.rs index 1ab8d84bb3d..63aca9935c9 100644 --- a/components/script/dom/identityhub.rs +++ b/components/script/dom/identityhub.rs @@ -6,12 +6,13 @@ use smallvec::SmallVec; use webgpu::identity::{ComputePass, ComputePassId, RenderPass, RenderPassId}; use webgpu::wgc::id::markers::{ Adapter, BindGroup, BindGroupLayout, Buffer, CommandEncoder, ComputePipeline, Device, - PipelineLayout, RenderBundle, RenderPipeline, Sampler, ShaderModule, Texture, TextureView, + PipelineLayout, Queue, RenderBundle, RenderPipeline, Sampler, ShaderModule, Texture, + TextureView, }; use webgpu::wgc::id::{ AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandEncoderId, ComputePipelineId, - DeviceId, PipelineLayoutId, RenderBundleId, RenderPipelineId, SamplerId, ShaderModuleId, - TextureId, TextureViewId, + DeviceId, PipelineLayoutId, QueueId, RenderBundleId, RenderPipelineId, SamplerId, + ShaderModuleId, TextureId, TextureViewId, }; use webgpu::wgc::identity::IdentityManager; use webgpu::wgt::Backend; @@ -20,6 +21,7 @@ use webgpu::wgt::Backend; pub struct IdentityHub { adapters: IdentityManager, devices: IdentityManager, + queues: IdentityManager, buffers: IdentityManager, bind_groups: IdentityManager, bind_group_layouts: IdentityManager, @@ -41,6 +43,7 @@ impl IdentityHub { IdentityHub { adapters: IdentityManager::new(), devices: IdentityManager::new(), + queues: IdentityManager::new(), buffers: IdentityManager::new(), bind_groups: IdentityManager::new(), bind_group_layouts: IdentityManager::new(), @@ -123,6 +126,14 @@ impl Identities { self.select(id.backend()).devices.free(id); } + pub fn create_queue_id(&self, backend: Backend) -> QueueId { + self.select(backend).queues.process(backend) + } + + pub fn free_queue_id(&self, id: QueueId) { + self.select(id.backend()).queues.free(id); + } + pub fn create_adapter_ids(&self) -> SmallVec<[AdapterId; 4]> { let mut ids = SmallVec::new(); for hubs in self.hubs() { diff --git a/components/webgpu/ipc_messages/recv.rs b/components/webgpu/ipc_messages/recv.rs index adf6a6efa48..2efbf62758c 100644 --- a/components/webgpu/ipc_messages/recv.rs +++ b/components/webgpu/ipc_messages/recv.rs @@ -130,6 +130,7 @@ pub enum WebGPURequest { }, CreateSwapChain { device_id: id::DeviceId, + queue_id: id::QueueId, buffer_ids: ArrayVec, external_id: u64, sender: IpcSender, @@ -191,6 +192,7 @@ pub enum WebGPURequest { adapter_id: WebGPUAdapter, descriptor: wgt::DeviceDescriptor>, device_id: id::DeviceId, + queue_id: id::QueueId, pipeline_id: PipelineId, }, // Compute Pass @@ -250,6 +252,7 @@ pub enum WebGPURequest { command_encoder_id: id::CommandEncoderId, }, Submit { + device_id: id::DeviceId, queue_id: id::QueueId, command_buffers: Vec, }, @@ -267,12 +270,14 @@ pub enum WebGPURequest { size: u64, }, WriteBuffer { + device_id: id::DeviceId, queue_id: id::QueueId, buffer_id: id::BufferId, buffer_offset: u64, data: IpcSharedMemory, }, WriteTexture { + device_id: id::DeviceId, queue_id: id::QueueId, texture_cv: ImageCopyTexture, data_layout: wgt::ImageDataLayout, @@ -282,6 +287,7 @@ pub enum WebGPURequest { QueueOnSubmittedWorkDone { sender: IpcSender, queue_id: id::QueueId, + device_id: id::DeviceId, }, PushErrorScope { device_id: id::DeviceId, diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index 5def9100d1e..cd73d60b718 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -143,21 +143,3 @@ pub struct PresentationData { image_desc: ImageDescriptor, image_data: ImageData, } - -pub trait Transmute { - fn transmute(self) -> id::Id; -} - -impl Transmute for id::Id { - fn transmute(self) -> id::Id { - // if this is removed next one should be removed too. - self.into_queue_id() - } -} - -impl Transmute for id::Id { - fn transmute(self) -> id::Id { - // SAFETY: This is safe because queue_id = device_id in wgpu - unsafe { id::Id::from_raw(self.into_raw()) } - } -} diff --git a/components/webgpu/wgpu_thread.rs b/components/webgpu/wgpu_thread.rs index d1f9744b32c..6d7acaa739c 100644 --- a/components/webgpu/wgpu_thread.rs +++ b/components/webgpu/wgpu_thread.rs @@ -38,8 +38,8 @@ use crate::gpu_error::ErrorScope; use crate::poll_thread::Poller; use crate::render_commands::apply_render_command; use crate::{ - Adapter, ComputePassId, Error, PopError, PresentationData, RenderPassId, Transmute, WebGPU, - WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse, + Adapter, ComputePassId, Error, PopError, PresentationData, RenderPassId, WebGPU, WebGPUAdapter, + WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse, }; pub const PRESENTATION_BUFFER_COUNT: usize = 10; @@ -491,6 +491,7 @@ impl WGPU { }, WebGPURequest::CreateSwapChain { device_id, + queue_id, buffer_ids, external_id, sender, @@ -510,7 +511,7 @@ impl WGPU { external_id, PresentationData { device_id, - queue_id: device_id.transmute(), + queue_id, data: vec![255; (buffer_stride * height as u32) as usize], size: Size2D::new(width, height), unassigned_buffer_ids: buffer_ids, @@ -704,6 +705,7 @@ impl WGPU { adapter_id, descriptor, device_id, + queue_id, pipeline_id, } => { let desc = DeviceDescriptor { @@ -718,7 +720,7 @@ impl WGPU { &desc, None, Some(device_id), - Some(device_id.transmute()), + Some(queue_id), )); let device = WebGPUDevice(device_id); let queue = WebGPUQueue(queue_id); @@ -991,6 +993,7 @@ impl WGPU { }; }, WebGPURequest::Submit { + device_id, queue_id, command_buffers, } => { @@ -1008,7 +1011,7 @@ impl WGPU { gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers)) .map_err(Error::from_error) }; - self.maybe_dispatch_error(queue_id.transmute(), result.err()); + self.maybe_dispatch_error(device_id, result.err()); }, WebGPURequest::SwapChainPresent { external_id, @@ -1195,6 +1198,7 @@ impl WGPU { self.maybe_dispatch_wgpu_error(device_id, result.err()); }, WebGPURequest::WriteBuffer { + device_id, queue_id, buffer_id, buffer_offset, @@ -1208,9 +1212,10 @@ impl WGPU { buffer_offset as wgt::BufferAddress, &data )); - self.maybe_dispatch_wgpu_error(queue_id.transmute(), result.err()); + self.maybe_dispatch_wgpu_error(device_id, result.err()); }, WebGPURequest::WriteTexture { + device_id, queue_id, texture_cv, data_layout, @@ -1228,9 +1233,13 @@ impl WGPU { &size )); drop(_guard); - self.maybe_dispatch_wgpu_error(queue_id.transmute(), result.err()); + self.maybe_dispatch_wgpu_error(device_id, result.err()); }, - WebGPURequest::QueueOnSubmittedWorkDone { sender, queue_id } => { + WebGPURequest::QueueOnSubmittedWorkDone { + sender, + queue_id, + device_id, + } => { let global = &self.global; let token = self.poller.token(); let callback = SubmittedWorkDoneClosure::from_rust(Box::from(move || { @@ -1241,7 +1250,7 @@ impl WGPU { })); let result = gfx_select!(queue_id => global.queue_on_submitted_work_done(queue_id, callback)); self.poller.wake(); - self.maybe_dispatch_wgpu_error(queue_id.transmute(), result.err()); + self.maybe_dispatch_wgpu_error(device_id, result.err()); }, WebGPURequest::DropTexture(id) => { let global = &self.global;