mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #27480 - kunalmohan:gpu-void-error, r=kvark
WebGPU-Report errors in Promise or void returning operations <!-- Please describe your changes on the following line: --> This also updates GPUBuffer mapping to match latest spec. r?@kvark --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
549179bbd6
22 changed files with 489 additions and 305 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -3701,7 +3701,7 @@ checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
|
|||
[[package]]
|
||||
name = "naga"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/gfx-rs/naga?rev=94802078c3bc5d138f497419ea3e7a869f10916d#94802078c3bc5d138f497419ea3e7a869f10916d"
|
||||
source = "git+https://github.com/gfx-rs/naga?rev=1eb637038dd15fc1dad770eca8e6943424dbc122#1eb637038dd15fc1dad770eca8e6943424dbc122"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fxhash",
|
||||
|
@ -6911,7 +6911,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#872a6c4c2bab5591838219c34e0cbf5fa9c2ec85"
|
||||
dependencies = [
|
||||
"arrayvec 0.5.1",
|
||||
"bitflags",
|
||||
|
@ -6938,7 +6938,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "wgpu-types"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#872a6c4c2bab5591838219c34e0cbf5fa9c2ec85"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"serde",
|
||||
|
|
|
@ -2169,7 +2169,7 @@ where
|
|||
options,
|
||||
ids,
|
||||
};
|
||||
if webgpu_chan.0.send(adapter_request).is_err() {
|
||||
if webgpu_chan.0.send((None, adapter_request)).is_err() {
|
||||
return warn!("Failed to send request adapter message on WebGPU channel");
|
||||
}
|
||||
},
|
||||
|
|
|
@ -831,6 +831,7 @@ malloc_size_of_is_0!(bool, char, str);
|
|||
malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize);
|
||||
malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize);
|
||||
malloc_size_of_is_0!(f32, f64);
|
||||
malloc_size_of_is_0!(std::num::NonZeroU64);
|
||||
|
||||
malloc_size_of_is_0!(std::sync::atomic::AtomicBool);
|
||||
malloc_size_of_is_0!(std::sync::atomic::AtomicIsize);
|
||||
|
|
|
@ -138,6 +138,7 @@ use std::cell::{Cell, RefCell, UnsafeCell};
|
|||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::mem;
|
||||
use std::num::NonZeroU64;
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
@ -524,6 +525,7 @@ unsafe_no_jsmanaged_fields!(ActiveUniformBlockInfo);
|
|||
unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uuid, char);
|
||||
unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64);
|
||||
unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64);
|
||||
unsafe_no_jsmanaged_fields!(NonZeroU64);
|
||||
unsafe_no_jsmanaged_fields!(Error);
|
||||
unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin);
|
||||
unsafe_no_jsmanaged_fields!(Image, ImageMetadata, dyn ImageCache, PendingImageId);
|
||||
|
|
|
@ -127,7 +127,7 @@ use std::sync::Arc;
|
|||
use std::thread::JoinHandle;
|
||||
use time::{get_time, Timespec};
|
||||
use uuid::Uuid;
|
||||
use webgpu::{identity::WebGPUOpResult, WebGPUDevice};
|
||||
use webgpu::{identity::WebGPUOpResult, ErrorScopeId, WebGPUDevice};
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
pub struct AutoCloseWorker {
|
||||
|
@ -3023,7 +3023,7 @@ impl GlobalScope {
|
|||
pub fn handle_wgpu_msg(
|
||||
&self,
|
||||
device: WebGPUDevice,
|
||||
scope: Option<u64>,
|
||||
scope: Option<ErrorScopeId>,
|
||||
result: WebGPUOpResult,
|
||||
) {
|
||||
self.gpu_devices
|
||||
|
|
|
@ -41,7 +41,7 @@ impl GPU {
|
|||
}
|
||||
|
||||
pub trait AsyncWGPUListener {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>);
|
||||
fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc<Promise>);
|
||||
}
|
||||
|
||||
struct WGPUResponse<T: AsyncWGPUListener + DomObject> {
|
||||
|
@ -53,13 +53,7 @@ impl<T: AsyncWGPUListener + DomObject> WGPUResponse<T> {
|
|||
#[allow(unrooted_must_root)]
|
||||
fn response(self, response: WebGPUResponseResult) {
|
||||
let promise = self.trusted.root();
|
||||
match response {
|
||||
Ok(response) => self.receiver.root().handle_response(response, &promise),
|
||||
Err(error) => promise.reject_error(Error::Type(format!(
|
||||
"Received error from WebGPU thread: {}",
|
||||
error
|
||||
))),
|
||||
}
|
||||
self.receiver.root().handle_response(response, &promise);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,13 +128,13 @@ impl GPUMethods for GPU {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPU {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc<Promise>) {
|
||||
match response {
|
||||
WebGPUResponse::RequestAdapter {
|
||||
Ok(WebGPUResponse::RequestAdapter {
|
||||
adapter_name,
|
||||
adapter_id,
|
||||
channel,
|
||||
} => {
|
||||
}) => {
|
||||
let adapter = GPUAdapter::new(
|
||||
&self.global(),
|
||||
channel,
|
||||
|
@ -150,7 +144,14 @@ impl AsyncWGPUListener for GPU {
|
|||
);
|
||||
promise.resolve_native(&adapter);
|
||||
},
|
||||
_ => promise.reject_error(Error::Operation),
|
||||
Err(e) => {
|
||||
warn!("Could not get GPUAdapter ({:?})", e);
|
||||
promise.resolve_native(&None::<GPUAdapter>);
|
||||
},
|
||||
_ => {
|
||||
warn!("GPU received wrong WebGPUResponse");
|
||||
promise.reject_error(Error::Operation);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use dom_struct::dom_struct;
|
|||
use js::jsapi::{Heap, JSObject};
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse};
|
||||
use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPUResponseResult};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUAdapter {
|
||||
|
@ -97,14 +97,17 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
if self
|
||||
.channel
|
||||
.0
|
||||
.send(WebGPURequest::RequestDevice {
|
||||
sender,
|
||||
adapter_id: self.adapter,
|
||||
descriptor: desc,
|
||||
device_id: id,
|
||||
pipeline_id,
|
||||
label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
|
||||
})
|
||||
.send((
|
||||
None,
|
||||
WebGPURequest::RequestDevice {
|
||||
sender,
|
||||
adapter_id: self.adapter,
|
||||
descriptor: desc,
|
||||
device_id: id,
|
||||
pipeline_id,
|
||||
label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
|
||||
},
|
||||
))
|
||||
.is_err()
|
||||
{
|
||||
promise.reject_error(Error::Operation);
|
||||
|
@ -114,14 +117,14 @@ impl GPUAdapterMethods for GPUAdapter {
|
|||
}
|
||||
|
||||
impl AsyncWGPUListener for GPUAdapter {
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc<Promise>) {
|
||||
match response {
|
||||
WebGPUResponse::RequestDevice {
|
||||
Ok(WebGPUResponse::RequestDevice {
|
||||
device_id,
|
||||
queue_id,
|
||||
_descriptor,
|
||||
label,
|
||||
} => {
|
||||
}) => {
|
||||
let device = GPUDevice::new(
|
||||
&self.global(),
|
||||
self.channel.clone(),
|
||||
|
@ -135,7 +138,14 @@ impl AsyncWGPUListener for GPUAdapter {
|
|||
self.global().add_gpu_device(&device);
|
||||
promise.resolve_native(&device);
|
||||
},
|
||||
_ => promise.reject_error(Error::Operation),
|
||||
Err(e) => {
|
||||
warn!("Could not get GPUDevice({:?})", e);
|
||||
promise.reject_error(Error::Operation);
|
||||
},
|
||||
_ => {
|
||||
warn!("GPUAdapter received wrong WebGPUResponse");
|
||||
promise.reject_error(Error::Operation);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ use crate::dom::bindings::codegen::Bindings::GPUMapModeBinding::GPUMapModeConsta
|
|||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpu::{response_async, AsyncWGPUListener};
|
||||
use crate::dom::gpudevice::GPUDevice;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::JSContext;
|
||||
|
@ -25,8 +26,10 @@ use std::ffi::c_void;
|
|||
use std::ops::Range;
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
use webgpu::{
|
||||
wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPUDevice, WebGPURequest, WebGPUResponse,
|
||||
identity::WebGPUOpResult, wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest,
|
||||
WebGPUResponse, WebGPUResponseResult,
|
||||
};
|
||||
|
||||
const RANGE_OFFSET_ALIGN_MASK: u64 = 8;
|
||||
|
@ -61,7 +64,7 @@ pub struct GPUBuffer {
|
|||
label: DomRefCell<Option<USVString>>,
|
||||
state: Cell<GPUBufferState>,
|
||||
buffer: WebGPUBuffer,
|
||||
device: WebGPUDevice,
|
||||
device: Dom<GPUDevice>,
|
||||
size: GPUSize64,
|
||||
#[ignore_malloc_size_of = "promises are hard"]
|
||||
map_promise: DomRefCell<Option<Rc<Promise>>>,
|
||||
|
@ -72,7 +75,7 @@ impl GPUBuffer {
|
|||
fn new_inherited(
|
||||
channel: WebGPU,
|
||||
buffer: WebGPUBuffer,
|
||||
device: WebGPUDevice,
|
||||
device: &GPUDevice,
|
||||
state: GPUBufferState,
|
||||
size: GPUSize64,
|
||||
map_info: DomRefCell<Option<GPUBufferMapInfo>>,
|
||||
|
@ -83,7 +86,7 @@ impl GPUBuffer {
|
|||
channel,
|
||||
label: DomRefCell::new(label),
|
||||
state: Cell::new(state),
|
||||
device,
|
||||
device: Dom::from_ref(device),
|
||||
buffer,
|
||||
map_promise: DomRefCell::new(None),
|
||||
size,
|
||||
|
@ -96,7 +99,7 @@ impl GPUBuffer {
|
|||
global: &GlobalScope,
|
||||
channel: WebGPU,
|
||||
buffer: WebGPUBuffer,
|
||||
device: WebGPUDevice,
|
||||
device: &GPUDevice,
|
||||
state: GPUBufferState,
|
||||
size: GPUSize64,
|
||||
map_info: DomRefCell<Option<GPUBufferMapInfo>>,
|
||||
|
@ -143,13 +146,19 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
let mut info = self.map_info.borrow_mut();
|
||||
let m_info = info.as_mut().unwrap();
|
||||
let m_range = m_info.mapping_range.clone();
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::UnmapBuffer {
|
||||
buffer_id: self.id().0,
|
||||
array_buffer: IpcSharedMemory::from_bytes(m_info.mapping.borrow().as_slice()),
|
||||
is_map_read: m_info.map_mode == Some(GPUMapModeConstants::READ),
|
||||
offset: m_range.start,
|
||||
size: m_range.end - m_range.start,
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
self.device.use_current_scope(),
|
||||
WebGPURequest::UnmapBuffer {
|
||||
buffer_id: self.id().0,
|
||||
device_id: self.device.id().0,
|
||||
array_buffer: IpcSharedMemory::from_bytes(
|
||||
m_info.mapping.borrow().as_slice(),
|
||||
),
|
||||
is_map_read: m_info.map_mode == Some(GPUMapModeConstants::READ),
|
||||
offset: m_range.start,
|
||||
size: m_range.end - m_range.start,
|
||||
},
|
||||
)) {
|
||||
warn!("Failed to send Buffer unmap ({:?}) ({})", self.buffer.0, e);
|
||||
}
|
||||
// Step 3.3
|
||||
|
@ -180,7 +189,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
if let Err(e) = self
|
||||
.channel
|
||||
.0
|
||||
.send(WebGPURequest::DestroyBuffer(self.buffer.0))
|
||||
.send((None, WebGPURequest::DestroyBuffer(self.buffer.0)))
|
||||
{
|
||||
warn!(
|
||||
"Failed to send WebGPURequest::DestroyBuffer({:?}) ({})",
|
||||
|
@ -196,40 +205,53 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
&self,
|
||||
mode: u32,
|
||||
offset: GPUSize64,
|
||||
size: GPUSize64,
|
||||
size: Option<GPUSize64>,
|
||||
comp: InRealm,
|
||||
) -> Rc<Promise> {
|
||||
let promise = Promise::new_in_current_realm(&self.global(), comp);
|
||||
let map_range = if size == 0 {
|
||||
offset..self.size
|
||||
let range_size = if let Some(s) = size {
|
||||
s
|
||||
} else if offset >= self.size {
|
||||
promise.reject_error(Error::Operation);
|
||||
return promise;
|
||||
} else {
|
||||
if offset + size > self.size {
|
||||
warn!("Requested mapping size is greated than buffer size");
|
||||
promise.reject_error(Error::Abort);
|
||||
return promise;
|
||||
}
|
||||
offset..offset + size
|
||||
self.size - offset
|
||||
};
|
||||
let scope_id = self.device.use_current_scope();
|
||||
if self.state.get() != GPUBufferState::Unmapped {
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from("Buffer is not Unmapped")),
|
||||
);
|
||||
promise.reject_error(Error::Abort);
|
||||
return promise;
|
||||
}
|
||||
let host_map = match mode {
|
||||
GPUMapModeConstants::READ => HostMap::Read,
|
||||
GPUMapModeConstants::WRITE => HostMap::Write,
|
||||
_ => {
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from("Invalid MapModeFlags")),
|
||||
);
|
||||
promise.reject_error(Error::Abort);
|
||||
return promise;
|
||||
},
|
||||
};
|
||||
if self.state.get() != GPUBufferState::Unmapped {
|
||||
promise.reject_error(Error::Abort);
|
||||
return promise;
|
||||
}
|
||||
|
||||
let map_range = offset..offset + range_size;
|
||||
|
||||
let sender = response_async(&promise, self);
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync {
|
||||
sender,
|
||||
buffer_id: self.buffer.0,
|
||||
host_map,
|
||||
map_range: map_range.clone(),
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
scope_id,
|
||||
WebGPURequest::BufferMapAsync {
|
||||
sender,
|
||||
buffer_id: self.buffer.0,
|
||||
device_id: self.device.id().0,
|
||||
host_map,
|
||||
map_range: map_range.clone(),
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send BufferMapAsync ({:?}) ({})",
|
||||
self.buffer.0, e
|
||||
|
@ -256,9 +278,16 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
&self,
|
||||
cx: JSContext,
|
||||
offset: GPUSize64,
|
||||
size: GPUSize64,
|
||||
size: Option<GPUSize64>,
|
||||
) -> Fallible<NonNull<JSObject>> {
|
||||
let m_end = if size == 0 { self.size } else { offset + size };
|
||||
let range_size = if let Some(s) = size {
|
||||
s
|
||||
} else if offset >= self.size {
|
||||
return Err(Error::Operation);
|
||||
} else {
|
||||
self.size - offset
|
||||
};
|
||||
let m_end = offset + range_size;
|
||||
let mut info = self.map_info.borrow_mut();
|
||||
let m_info = info.as_mut().unwrap();
|
||||
|
||||
|
@ -267,7 +296,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
_ => false,
|
||||
};
|
||||
valid &= offset % RANGE_OFFSET_ALIGN_MASK == 0 &&
|
||||
(m_end - offset) % RANGE_SIZE_ALIGN_MASK == 0 &&
|
||||
range_size % RANGE_SIZE_ALIGN_MASK == 0 &&
|
||||
offset >= m_info.mapping_range.start &&
|
||||
m_end <= m_info.mapping_range.end;
|
||||
valid &= m_info
|
||||
|
@ -285,7 +314,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
let array_buffer = unsafe {
|
||||
NewExternalArrayBuffer(
|
||||
*cx,
|
||||
(m_end - offset) as usize,
|
||||
range_size as usize,
|
||||
m_info.mapping.borrow_mut()[offset as usize..m_end as usize].as_mut_ptr() as _,
|
||||
Some(free_func),
|
||||
Rc::into_raw(m_info.mapping.clone()) as _,
|
||||
|
@ -311,9 +340,9 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
|
||||
impl AsyncWGPUListener for GPUBuffer {
|
||||
#[allow(unsafe_code)]
|
||||
fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) {
|
||||
fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc<Promise>) {
|
||||
match response {
|
||||
WebGPUResponse::BufferMapAsync(bytes) => {
|
||||
Ok(WebGPUResponse::BufferMapAsync(bytes)) => {
|
||||
*self
|
||||
.map_info
|
||||
.borrow_mut()
|
||||
|
@ -324,8 +353,12 @@ impl AsyncWGPUListener for GPUBuffer {
|
|||
promise.resolve_native(&());
|
||||
self.state.set(GPUBufferState::Mapped);
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Could not map buffer({:?})", e);
|
||||
promise.reject_error(Error::Abort);
|
||||
},
|
||||
_ => {
|
||||
warn!("Wrong WebGPUResponse received");
|
||||
warn!("GPUBuffer received wrong WebGPUResponse");
|
||||
promise.reject_error(Error::Operation);
|
||||
},
|
||||
}
|
||||
|
@ -333,7 +366,7 @@ impl AsyncWGPUListener for GPUBuffer {
|
|||
if let Err(e) = self
|
||||
.channel
|
||||
.0
|
||||
.send(WebGPURequest::BufferMapComplete(self.buffer.0))
|
||||
.send((None, WebGPURequest::BufferMapComplete(self.buffer.0)))
|
||||
{
|
||||
warn!(
|
||||
"Failed to send BufferMapComplete({:?}) ({})",
|
||||
|
|
|
@ -45,7 +45,9 @@ pub struct GPUCanvasContext {
|
|||
impl GPUCanvasContext {
|
||||
fn new_inherited(canvas: &HTMLCanvasElement, size: Size2D<u32>, channel: WebGPU) -> Self {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let _ = channel.0.send(WebGPURequest::CreateContext(sender));
|
||||
if let Err(e) = channel.0.send((None, WebGPURequest::CreateContext(sender))) {
|
||||
warn!("Failed to send CreateContext ({:?})", e);
|
||||
}
|
||||
let external_id = receiver.recv().unwrap();
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -88,11 +90,14 @@ impl GPUCanvasContext {
|
|||
.wgpu_id_hub()
|
||||
.lock()
|
||||
.create_command_encoder_id(texture_id.backend());
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::SwapChainPresent {
|
||||
external_id: self.context_id.0,
|
||||
texture_id,
|
||||
encoder_id,
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
None,
|
||||
WebGPURequest::SwapChainPresent {
|
||||
external_id: self.context_id.0,
|
||||
texture_id,
|
||||
encoder_id,
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send UpdateWebrenderData({:?}) ({})",
|
||||
self.context_id, e
|
||||
|
@ -168,14 +173,17 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateSwapChain {
|
||||
device_id: descriptor.device.id().0,
|
||||
buffer_ids,
|
||||
external_id: self.context_id.0,
|
||||
sender,
|
||||
image_desc,
|
||||
image_data,
|
||||
})
|
||||
.send((
|
||||
None,
|
||||
WebGPURequest::CreateSwapChain {
|
||||
device_id: descriptor.device.id().0,
|
||||
buffer_ids,
|
||||
external_id: self.context_id.0,
|
||||
sender,
|
||||
image_desc,
|
||||
image_data,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU SwapChain");
|
||||
|
||||
let usage = if descriptor.usage % 2 == 0 {
|
||||
|
|
|
@ -29,7 +29,7 @@ use std::borrow::Cow;
|
|||
use std::cell::Cell;
|
||||
use std::collections::HashSet;
|
||||
use webgpu::wgpu::command as wgpu_com;
|
||||
use webgpu::{self, wgt, WebGPU, WebGPURequest};
|
||||
use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest};
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#enumdef-encoder-state
|
||||
#[derive(MallocSizeOf, PartialEq)]
|
||||
|
@ -103,6 +103,10 @@ impl GPUCommandEncoder {
|
|||
*self.state.borrow_mut() = GPUCommandEncoderState::Closed;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device(&self) -> &GPUDevice {
|
||||
&*self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
||||
|
@ -254,9 +258,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
size: GPUSize64,
|
||||
) {
|
||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
||||
let scope_id = self.device.use_current_scope();
|
||||
|
||||
if !valid {
|
||||
// TODO: Record an error in the current scope.
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from(
|
||||
"CommandEncoder is not in Open State",
|
||||
)),
|
||||
);
|
||||
self.valid.set(false);
|
||||
return;
|
||||
}
|
||||
|
@ -267,14 +277,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
.insert(DomRoot::from_ref(destination));
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CopyBufferToBuffer {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source_id: source.id().0,
|
||||
source_offset,
|
||||
destination_id: destination.id().0,
|
||||
destination_offset,
|
||||
size,
|
||||
})
|
||||
.send((
|
||||
scope_id,
|
||||
WebGPURequest::CopyBufferToBuffer {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
source_id: source.id().0,
|
||||
source_offset,
|
||||
destination_id: destination.id().0,
|
||||
destination_offset,
|
||||
size,
|
||||
},
|
||||
))
|
||||
.expect("Failed to send CopyBufferToBuffer");
|
||||
}
|
||||
|
||||
|
@ -286,9 +300,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
||||
let scope_id = self.device.use_current_scope();
|
||||
|
||||
if !valid {
|
||||
// TODO: Record an error in the current scope.
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from(
|
||||
"CommandEncoder is not in Open State",
|
||||
)),
|
||||
);
|
||||
self.valid.set(false);
|
||||
return;
|
||||
}
|
||||
|
@ -299,12 +319,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CopyBufferToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_buffer_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)),
|
||||
})
|
||||
.send((
|
||||
scope_id,
|
||||
WebGPURequest::CopyBufferToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
source: convert_buffer_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
},
|
||||
))
|
||||
.expect("Failed to send CopyBufferToTexture");
|
||||
}
|
||||
|
||||
|
@ -316,9 +342,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
||||
let scope_id = self.device.use_current_scope();
|
||||
|
||||
if !valid {
|
||||
// TODO: Record an error in the current scope.
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from(
|
||||
"CommandEncoder is not in Open State",
|
||||
)),
|
||||
);
|
||||
self.valid.set(false);
|
||||
return;
|
||||
}
|
||||
|
@ -329,12 +361,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CopyTextureToBuffer {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_buffer_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)),
|
||||
})
|
||||
.send((
|
||||
scope_id,
|
||||
WebGPURequest::CopyTextureToBuffer {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_buffer_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
},
|
||||
))
|
||||
.expect("Failed to send CopyTextureToBuffer");
|
||||
}
|
||||
|
||||
|
@ -346,21 +384,33 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
copy_size: GPUExtent3D,
|
||||
) {
|
||||
let valid = *self.state.borrow() == GPUCommandEncoderState::Open;
|
||||
let scope_id = self.device.use_current_scope();
|
||||
|
||||
if !valid {
|
||||
// TODO: Record an error in the current scope.
|
||||
self.device.handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from(
|
||||
"CommandEncoder is not in Open State",
|
||||
)),
|
||||
);
|
||||
self.valid.set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CopyTextureToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)),
|
||||
})
|
||||
.send((
|
||||
scope_id,
|
||||
WebGPURequest::CopyTextureToTexture {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
source: convert_texture_cv(source),
|
||||
destination: convert_texture_cv(destination),
|
||||
copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(
|
||||
©_size,
|
||||
)),
|
||||
},
|
||||
))
|
||||
.expect("Failed to send CopyTextureToTexture");
|
||||
}
|
||||
|
||||
|
@ -368,13 +418,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
|
|||
fn Finish(&self, descriptor: &GPUCommandBufferDescriptor) -> DomRoot<GPUCommandBuffer> {
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CommandEncoderFinish {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
scope_id: self.device.use_current_scope(),
|
||||
// TODO(zakorgy): We should use `_descriptor` here after it's not empty
|
||||
// and the underlying wgpu-core struct is serializable
|
||||
})
|
||||
.send((
|
||||
self.device.use_current_scope(),
|
||||
WebGPURequest::CommandEncoderFinish {
|
||||
command_encoder_id: self.encoder.0,
|
||||
device_id: self.device.id().0,
|
||||
// TODO(zakorgy): We should use `_descriptor` here after it's not empty
|
||||
// and the underlying wgpu-core struct is serializable
|
||||
},
|
||||
))
|
||||
.expect("Failed to send Finish");
|
||||
|
||||
*self.state.borrow_mut() = GPUCommandEncoderState::Closed;
|
||||
|
|
|
@ -91,10 +91,14 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
|
|||
if let Some(compute_pass) = self.compute_pass.borrow_mut().take() {
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::RunComputePass {
|
||||
command_encoder_id: self.command_encoder.id().0,
|
||||
compute_pass,
|
||||
})
|
||||
.send((
|
||||
self.command_encoder.device().use_current_scope(),
|
||||
WebGPURequest::RunComputePass {
|
||||
command_encoder_id: self.command_encoder.id().0,
|
||||
device_id: self.command_encoder.device().id().0,
|
||||
compute_pass,
|
||||
},
|
||||
))
|
||||
.expect("Failed to send RunComputePass");
|
||||
|
||||
self.command_encoder.set_state(
|
||||
|
|
|
@ -71,9 +71,7 @@ use std::rc::Rc;
|
|||
use webgpu::wgpu::{
|
||||
binding_model as wgpu_bind, command::RenderBundleEncoder, pipeline as wgpu_pipe,
|
||||
};
|
||||
use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest};
|
||||
|
||||
type ErrorScopeId = u64;
|
||||
use webgpu::{self, identity::WebGPUOpResult, wgt, ErrorScopeId, WebGPU, WebGPURequest};
|
||||
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
struct ErrorScopeInfo {
|
||||
|
@ -131,7 +129,7 @@ impl GPUDevice {
|
|||
scope_context: DomRefCell::new(ScopeContext {
|
||||
error_scopes: HashMap::new(),
|
||||
scope_stack: Vec::new(),
|
||||
next_scope_id: 0,
|
||||
next_scope_id: ErrorScopeId::new(1).unwrap(),
|
||||
}),
|
||||
lost_promise: DomRefCell::new(None),
|
||||
}
|
||||
|
@ -148,12 +146,14 @@ impl GPUDevice {
|
|||
label: Option<String>,
|
||||
) -> DomRoot<Self> {
|
||||
let queue = GPUQueue::new(global, channel.clone(), queue);
|
||||
reflect_dom_object(
|
||||
let device = reflect_dom_object(
|
||||
Box::new(GPUDevice::new_inherited(
|
||||
channel, adapter, extensions, limits, device, &queue, label,
|
||||
)),
|
||||
global,
|
||||
)
|
||||
);
|
||||
queue.set_device(&*device);
|
||||
device
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,12 +311,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let scope_id = self.use_current_scope();
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateBuffer {
|
||||
device_id: self.device.0,
|
||||
.send((
|
||||
scope_id,
|
||||
buffer_id: id,
|
||||
descriptor: wgpu_descriptor,
|
||||
})
|
||||
WebGPURequest::CreateBuffer {
|
||||
device_id: self.device.0,
|
||||
buffer_id: id,
|
||||
descriptor: wgpu_descriptor,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU buffer");
|
||||
|
||||
let buffer = webgpu::WebGPUBuffer(id);
|
||||
|
@ -341,7 +343,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
&self.global(),
|
||||
self.channel.clone(),
|
||||
buffer,
|
||||
self.device,
|
||||
&self,
|
||||
state,
|
||||
descriptor.size,
|
||||
map_info,
|
||||
|
@ -449,12 +451,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
.create_bind_group_layout_id(self.device.0.backend());
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateBindGroupLayout {
|
||||
device_id: self.device.0,
|
||||
bind_group_layout_id,
|
||||
.send((
|
||||
scope_id,
|
||||
descriptor: desc,
|
||||
})
|
||||
WebGPURequest::CreateBindGroupLayout {
|
||||
device_id: self.device.0,
|
||||
bind_group_layout_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU BindGroupLayout");
|
||||
|
||||
let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id);
|
||||
|
@ -491,12 +495,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
.create_pipeline_layout_id(self.device.0.backend());
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreatePipelineLayout {
|
||||
device_id: self.device.0,
|
||||
pipeline_layout_id,
|
||||
descriptor: desc,
|
||||
.send((
|
||||
scope_id,
|
||||
})
|
||||
WebGPURequest::CreatePipelineLayout {
|
||||
device_id: self.device.0,
|
||||
pipeline_layout_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU PipelineLayout");
|
||||
|
||||
let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id);
|
||||
|
@ -551,12 +557,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
.create_bind_group_id(self.device.0.backend());
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateBindGroup {
|
||||
device_id: self.device.0,
|
||||
bind_group_id,
|
||||
descriptor: desc,
|
||||
.send((
|
||||
scope_id,
|
||||
})
|
||||
WebGPURequest::CreateBindGroup {
|
||||
device_id: self.device.0,
|
||||
bind_group_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU BindGroup");
|
||||
|
||||
let bind_group = webgpu::WebGPUBindGroup(bind_group_id);
|
||||
|
@ -590,12 +598,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let scope_id = self.use_current_scope();
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateShaderModule {
|
||||
device_id: self.device.0,
|
||||
.send((
|
||||
scope_id,
|
||||
program_id,
|
||||
program,
|
||||
})
|
||||
WebGPURequest::CreateShaderModule {
|
||||
device_id: self.device.0,
|
||||
program_id,
|
||||
program,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU ShaderModule");
|
||||
|
||||
let shader_module = webgpu::WebGPUShaderModule(program_id);
|
||||
|
@ -629,12 +639,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateComputePipeline {
|
||||
device_id: self.device.0,
|
||||
.send((
|
||||
scope_id,
|
||||
compute_pipeline_id,
|
||||
descriptor: desc,
|
||||
})
|
||||
WebGPURequest::CreateComputePipeline {
|
||||
device_id: self.device.0,
|
||||
compute_pipeline_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU ComputePipeline");
|
||||
|
||||
let compute_pipeline = webgpu::WebGPUComputePipeline(compute_pipeline_id);
|
||||
|
@ -658,12 +670,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let scope_id = self.use_current_scope();
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateCommandEncoder {
|
||||
device_id: self.device.0,
|
||||
.send((
|
||||
scope_id,
|
||||
command_encoder_id,
|
||||
label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
|
||||
})
|
||||
WebGPURequest::CreateCommandEncoder {
|
||||
device_id: self.device.0,
|
||||
command_encoder_id,
|
||||
label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU command encoder");
|
||||
|
||||
let encoder = webgpu::WebGPUCommandEncoder(command_encoder_id);
|
||||
|
@ -708,12 +722,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateTexture {
|
||||
device_id: self.device.0,
|
||||
texture_id,
|
||||
descriptor: desc,
|
||||
.send((
|
||||
scope_id,
|
||||
})
|
||||
WebGPURequest::CreateTexture {
|
||||
device_id: self.device.0,
|
||||
texture_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU Texture");
|
||||
|
||||
let texture = webgpu::WebGPUTexture(texture_id);
|
||||
|
@ -759,12 +775,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
let scope_id = self.use_current_scope();
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateSampler {
|
||||
device_id: self.device.0,
|
||||
.send((
|
||||
scope_id,
|
||||
sampler_id,
|
||||
descriptor: desc,
|
||||
})
|
||||
WebGPURequest::CreateSampler {
|
||||
device_id: self.device.0,
|
||||
sampler_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU sampler");
|
||||
|
||||
let sampler = webgpu::WebGPUSampler(sampler_id);
|
||||
|
@ -901,12 +919,14 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateRenderPipeline {
|
||||
device_id: self.device.0,
|
||||
render_pipeline_id,
|
||||
.send((
|
||||
scope_id,
|
||||
descriptor: desc,
|
||||
})
|
||||
WebGPURequest::CreateRenderPipeline {
|
||||
device_id: self.device.0,
|
||||
render_pipeline_id,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU render pipeline");
|
||||
|
||||
let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id);
|
||||
|
@ -959,7 +979,7 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
fn PushErrorScope(&self, filter: GPUErrorFilter) {
|
||||
let mut context = self.scope_context.borrow_mut();
|
||||
let scope_id = context.next_scope_id;
|
||||
context.next_scope_id += 1;
|
||||
context.next_scope_id = ErrorScopeId::new(scope_id.get() + 1).unwrap();
|
||||
let err_scope = ErrorScopeInfo {
|
||||
op_count: 0,
|
||||
error: None,
|
||||
|
|
|
@ -11,24 +11,25 @@ use crate::dom::bindings::codegen::Bindings::GPUQueueBinding::GPUQueueMethods;
|
|||
use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::GPUExtent3D;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState};
|
||||
use crate::dom::gpucommandbuffer::GPUCommandBuffer;
|
||||
use crate::dom::gpucommandencoder::{convert_texture_cv, convert_texture_data_layout};
|
||||
use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt};
|
||||
use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt, GPUDevice};
|
||||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use js::rust::CustomAutoRooterGuard;
|
||||
use js::typedarray::ArrayBuffer;
|
||||
use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest};
|
||||
use webgpu::{identity::WebGPUOpResult, wgt, WebGPU, WebGPUQueue, WebGPURequest};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUQueue {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
channel: WebGPU,
|
||||
device: DomRefCell<Option<Dom<GPUDevice>>>,
|
||||
label: DomRefCell<Option<USVString>>,
|
||||
queue: WebGPUQueue,
|
||||
}
|
||||
|
@ -38,6 +39,7 @@ impl GPUQueue {
|
|||
GPUQueue {
|
||||
channel,
|
||||
reflector_: Reflector::new(),
|
||||
device: DomRefCell::new(None),
|
||||
label: DomRefCell::new(None),
|
||||
queue,
|
||||
}
|
||||
|
@ -48,6 +50,12 @@ impl GPUQueue {
|
|||
}
|
||||
}
|
||||
|
||||
impl GPUQueue {
|
||||
pub fn set_device(&self, device: &GPUDevice) {
|
||||
*self.device.borrow_mut() = Some(Dom::from_ref(device));
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUQueueMethods for GPUQueue {
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
|
||||
fn GetLabel(&self) -> Option<USVString> {
|
||||
|
@ -67,17 +75,26 @@ impl GPUQueueMethods for GPUQueue {
|
|||
_ => false,
|
||||
})
|
||||
});
|
||||
let scope_id = self.device.borrow().as_ref().unwrap().use_current_scope();
|
||||
if !valid {
|
||||
// TODO: Generate error to the ErrorScope
|
||||
self.device.borrow().as_ref().unwrap().handle_server_msg(
|
||||
scope_id,
|
||||
WebGPUOpResult::ValidationError(String::from(
|
||||
"Referenced GPUBuffer(s) are not Unmapped",
|
||||
)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
let command_buffers = command_buffers.iter().map(|cb| cb.id().0).collect();
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::Submit {
|
||||
queue_id: self.queue.0,
|
||||
command_buffers,
|
||||
})
|
||||
.send((
|
||||
scope_id,
|
||||
WebGPURequest::Submit {
|
||||
queue_id: self.queue.0,
|
||||
command_buffers,
|
||||
},
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
@ -109,12 +126,15 @@ impl GPUQueueMethods for GPUQueue {
|
|||
let final_data = IpcSharedMemory::from_bytes(
|
||||
&bytes[data_offset as usize..(data_offset + content_size) as usize],
|
||||
);
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::WriteBuffer {
|
||||
queue_id: self.queue.0,
|
||||
buffer_id: buffer.id().0,
|
||||
buffer_offset,
|
||||
data: final_data,
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
self.device.borrow().as_ref().unwrap().use_current_scope(),
|
||||
WebGPURequest::WriteBuffer {
|
||||
queue_id: self.queue.0,
|
||||
buffer_id: buffer.id().0,
|
||||
buffer_offset,
|
||||
data: final_data,
|
||||
},
|
||||
)) {
|
||||
warn!("Failed to send WriteBuffer({:?}) ({})", buffer.id(), e);
|
||||
return Err(Error::Operation);
|
||||
}
|
||||
|
@ -142,13 +162,16 @@ impl GPUQueueMethods for GPUQueue {
|
|||
let write_size = convert_texture_size_to_wgt(&convert_texture_size_to_dict(&size));
|
||||
let final_data = IpcSharedMemory::from_bytes(&bytes);
|
||||
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::WriteTexture {
|
||||
queue_id: self.queue.0,
|
||||
texture_cv,
|
||||
data_layout: texture_layout,
|
||||
size: write_size,
|
||||
data: final_data,
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
self.device.borrow().as_ref().unwrap().use_current_scope(),
|
||||
WebGPURequest::WriteTexture {
|
||||
queue_id: self.queue.0,
|
||||
texture_cv,
|
||||
data_layout: texture_layout,
|
||||
size: write_size,
|
||||
data: final_data,
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send WriteTexture({:?}) ({})",
|
||||
destination.texture.id().0,
|
||||
|
|
|
@ -195,13 +195,15 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::RenderBundleEncoderFinish {
|
||||
render_bundle_encoder: encoder,
|
||||
descriptor: desc,
|
||||
render_bundle_id,
|
||||
device_id: self.device.id().0,
|
||||
scope_id: self.device.use_current_scope(),
|
||||
})
|
||||
.send((
|
||||
self.device.use_current_scope(),
|
||||
WebGPURequest::RenderBundleEncoderFinish {
|
||||
render_bundle_encoder: encoder,
|
||||
descriptor: desc,
|
||||
render_bundle_id,
|
||||
device_id: self.device.id().0,
|
||||
},
|
||||
))
|
||||
.expect("Failed to send RenderBundleEncoderFinish");
|
||||
|
||||
let render_bundle = WebGPURenderBundle(render_bundle_id);
|
||||
|
|
|
@ -163,10 +163,14 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
|
|||
if let Some(render_pass) = self.render_pass.borrow_mut().take() {
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::RunRenderPass {
|
||||
command_encoder_id: self.command_encoder.id().0,
|
||||
render_pass,
|
||||
})
|
||||
.send((
|
||||
self.command_encoder.device().use_current_scope(),
|
||||
WebGPURequest::RunRenderPass {
|
||||
command_encoder_id: self.command_encoder.id().0,
|
||||
device_id: self.command_encoder.device().id().0,
|
||||
render_pass,
|
||||
},
|
||||
))
|
||||
.expect("Failed to send RunRenderPass");
|
||||
|
||||
self.command_encoder.set_state(
|
||||
|
|
|
@ -57,10 +57,13 @@ impl GPUSwapChain {
|
|||
|
||||
impl GPUSwapChain {
|
||||
pub fn destroy(&self, external_id: u64, image_key: webrender_api::ImageKey) {
|
||||
if let Err(e) = self.channel.0.send(WebGPURequest::DestroySwapChain {
|
||||
external_id,
|
||||
image_key,
|
||||
}) {
|
||||
if let Err(e) = self.channel.0.send((
|
||||
None,
|
||||
WebGPURequest::DestroySwapChain {
|
||||
external_id,
|
||||
image_key,
|
||||
},
|
||||
)) {
|
||||
warn!(
|
||||
"Failed to send DestroySwapChain-ImageKey({:?}) ({})",
|
||||
image_key, e
|
||||
|
|
|
@ -167,13 +167,15 @@ impl GPUTextureMethods for GPUTexture {
|
|||
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateTextureView {
|
||||
texture_id: self.texture.0,
|
||||
texture_view_id,
|
||||
device_id: self.device.id().0,
|
||||
descriptor: desc,
|
||||
.send((
|
||||
scope_id,
|
||||
})
|
||||
WebGPURequest::CreateTextureView {
|
||||
texture_id: self.texture.0,
|
||||
texture_view_id,
|
||||
device_id: self.device.id().0,
|
||||
descriptor: desc,
|
||||
},
|
||||
))
|
||||
.expect("Failed to create WebGPU texture view");
|
||||
|
||||
let texture_view = WebGPUTextureView(texture_view_id);
|
||||
|
@ -191,7 +193,7 @@ impl GPUTextureMethods for GPUTexture {
|
|||
if let Err(e) = self
|
||||
.channel
|
||||
.0
|
||||
.send(WebGPURequest::DestroyTexture(self.texture.0))
|
||||
.send((None, WebGPURequest::DestroyTexture(self.texture.0)))
|
||||
{
|
||||
warn!(
|
||||
"Failed to send WebGPURequest::DestroyTexture({:?}) ({})",
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpu-interface
|
||||
[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
|
||||
interface GPU {
|
||||
// May reject with DOMException // TODO: DOMException("OperationError")?
|
||||
Promise<GPUAdapter> requestAdapter(optional GPURequestAdapterOptions options = {});
|
||||
Promise<GPUAdapter?> requestAdapter(optional GPURequestAdapterOptions options = {});
|
||||
};
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions
|
||||
|
|
|
@ -9,8 +9,7 @@ interface GPUAdapter {
|
|||
readonly attribute object extensions;
|
||||
//readonly attribute GPULimits limits; Don’t expose higher limits for now.
|
||||
|
||||
// May reject with DOMException // TODO: DOMException("OperationError")?
|
||||
Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {});
|
||||
Promise<GPUDevice?> requestDevice(optional GPUDeviceDescriptor descriptor = {});
|
||||
};
|
||||
|
||||
dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
// https://gpuweb.github.io/gpuweb/#gpubuffer
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUBuffer {
|
||||
Promise<void> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size = 0);
|
||||
[Throws] ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size = 0);
|
||||
Promise<void> mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size);
|
||||
[Throws] ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size);
|
||||
void unmap();
|
||||
|
||||
void destroy();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 crate::{WebGPUDevice, WebGPURequest};
|
||||
use crate::{ErrorScopeId, WebGPUDevice, WebGPURequest};
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -43,7 +43,7 @@ pub enum WebGPUMsg {
|
|||
FreeRenderBundle(RenderBundleId),
|
||||
WebGPUOpResult {
|
||||
device: WebGPUDevice,
|
||||
scope_id: Option<u64>,
|
||||
scope_id: Option<ErrorScopeId>,
|
||||
pipeline_id: PipelineId,
|
||||
result: WebGPUOpResult,
|
||||
},
|
||||
|
@ -57,12 +57,12 @@ pub enum WebGPUMsg {
|
|||
#[derive(Debug)]
|
||||
pub struct IdentityRecycler {
|
||||
sender: IpcSender<WebGPUMsg>,
|
||||
self_sender: IpcSender<WebGPURequest>,
|
||||
self_sender: IpcSender<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
}
|
||||
|
||||
pub struct IdentityRecyclerFactory {
|
||||
pub sender: IpcSender<WebGPUMsg>,
|
||||
pub self_sender: IpcSender<WebGPURequest>,
|
||||
pub self_sender: IpcSender<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
}
|
||||
|
||||
macro_rules! impl_identity_handler {
|
||||
|
@ -130,12 +130,14 @@ impl IdentityHandler<DeviceId> for IdentityRecycler {
|
|||
}
|
||||
fn free(&self, id: DeviceId) {
|
||||
log::debug!("free device {:?}", id);
|
||||
let msg = WebGPUMsg::FreeDevice(id);
|
||||
if self.sender.send(msg).is_err() {
|
||||
if self.sender.send(WebGPUMsg::FreeDevice(id)).is_err() {
|
||||
log::error!("Failed to send FreeDevice({:?}) to script", id);
|
||||
}
|
||||
let msg_to_self = WebGPURequest::FreeDevice(id);
|
||||
if self.self_sender.send(msg_to_self).is_err() {
|
||||
if self
|
||||
.self_sender
|
||||
.send((None, WebGPURequest::FreeDevice(id)))
|
||||
.is_err()
|
||||
{
|
||||
log::error!("Failed to send FreeDevice({:?}) to server", id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use smallvec::SmallVec;
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
use std::num::NonZeroU64;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
|
@ -41,6 +42,7 @@ use wgpu::{
|
|||
resource::{BufferMapAsyncStatus, BufferMapOperation},
|
||||
};
|
||||
|
||||
pub type ErrorScopeId = NonZeroU64;
|
||||
const DEVICE_POLL_INTERVAL: u64 = 100;
|
||||
pub const PRESENTATION_BUFFER_COUNT: usize = 10;
|
||||
|
||||
|
@ -67,6 +69,7 @@ pub enum WebGPURequest {
|
|||
BufferMapAsync {
|
||||
sender: IpcSender<WebGPUResponseResult>,
|
||||
buffer_id: id::BufferId,
|
||||
device_id: id::DeviceId,
|
||||
host_map: HostMap,
|
||||
map_range: std::ops::Range<u64>,
|
||||
},
|
||||
|
@ -74,12 +77,12 @@ pub enum WebGPURequest {
|
|||
CommandEncoderFinish {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
// TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core
|
||||
// wgpu::command::CommandBufferDescriptor,
|
||||
},
|
||||
CopyBufferToBuffer {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
source_id: id::BufferId,
|
||||
source_offset: wgt::BufferAddress,
|
||||
destination_id: id::BufferId,
|
||||
|
@ -88,44 +91,42 @@ pub enum WebGPURequest {
|
|||
},
|
||||
CopyBufferToTexture {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
source: BufferCopyView,
|
||||
destination: TextureCopyView,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToBuffer {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
source: TextureCopyView,
|
||||
destination: BufferCopyView,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToTexture {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
source: TextureCopyView,
|
||||
destination: TextureCopyView,
|
||||
copy_size: wgt::Extent3d,
|
||||
},
|
||||
CreateBindGroup {
|
||||
device_id: id::DeviceId,
|
||||
// TODO: Consider using NonZeroU64 to reduce enum size
|
||||
scope_id: Option<u64>,
|
||||
bind_group_id: id::BindGroupId,
|
||||
descriptor: BindGroupDescriptor<'static>,
|
||||
},
|
||||
CreateBindGroupLayout {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
bind_group_layout_id: id::BindGroupLayoutId,
|
||||
descriptor: wgt::BindGroupLayoutDescriptor<'static>,
|
||||
},
|
||||
CreateBuffer {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
buffer_id: id::BufferId,
|
||||
descriptor: wgt::BufferDescriptor<Option<String>>,
|
||||
},
|
||||
CreateCommandEncoder {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
// TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core
|
||||
// wgpu::command::CommandEncoderDescriptor,
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
|
@ -133,32 +134,27 @@ pub enum WebGPURequest {
|
|||
},
|
||||
CreateComputePipeline {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
compute_pipeline_id: id::ComputePipelineId,
|
||||
descriptor: ComputePipelineDescriptor<'static>,
|
||||
},
|
||||
CreateContext(IpcSender<webrender_api::ExternalImageId>),
|
||||
CreatePipelineLayout {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
pipeline_layout_id: id::PipelineLayoutId,
|
||||
descriptor: wgt::PipelineLayoutDescriptor<'static, id::BindGroupLayoutId>,
|
||||
},
|
||||
CreateRenderPipeline {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
render_pipeline_id: id::RenderPipelineId,
|
||||
descriptor: RenderPipelineDescriptor<'static>,
|
||||
},
|
||||
CreateSampler {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
sampler_id: id::SamplerId,
|
||||
descriptor: wgt::SamplerDescriptor<Option<String>>,
|
||||
},
|
||||
CreateShaderModule {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
program_id: id::ShaderModuleId,
|
||||
program: Vec<u32>,
|
||||
},
|
||||
|
@ -172,7 +168,6 @@ pub enum WebGPURequest {
|
|||
},
|
||||
CreateTexture {
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
texture_id: id::TextureId,
|
||||
descriptor: wgt::TextureDescriptor<Option<String>>,
|
||||
},
|
||||
|
@ -180,7 +175,6 @@ pub enum WebGPURequest {
|
|||
texture_id: id::TextureId,
|
||||
texture_view_id: id::TextureViewId,
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
descriptor: wgt::TextureViewDescriptor<Option<String>>,
|
||||
},
|
||||
DestroyBuffer(id::BufferId),
|
||||
|
@ -196,7 +190,6 @@ pub enum WebGPURequest {
|
|||
descriptor: wgt::RenderBundleDescriptor<Option<String>>,
|
||||
render_bundle_id: id::RenderBundleId,
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
},
|
||||
RequestAdapter {
|
||||
sender: IpcSender<WebGPUResponseResult>,
|
||||
|
@ -213,10 +206,12 @@ pub enum WebGPURequest {
|
|||
},
|
||||
RunComputePass {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
compute_pass: ComputePass,
|
||||
},
|
||||
RunRenderPass {
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
device_id: id::DeviceId,
|
||||
render_pass: RenderPass,
|
||||
},
|
||||
Submit {
|
||||
|
@ -230,6 +225,7 @@ pub enum WebGPURequest {
|
|||
},
|
||||
UnmapBuffer {
|
||||
buffer_id: id::BufferId,
|
||||
device_id: id::DeviceId,
|
||||
array_buffer: IpcSharedMemory,
|
||||
is_map_read: bool,
|
||||
offset: u64,
|
||||
|
@ -264,7 +260,7 @@ struct BufferMapInfo<'a, T> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct WebGPU(pub IpcSender<WebGPURequest>);
|
||||
pub struct WebGPU(pub IpcSender<(Option<ErrorScopeId>, WebGPURequest)>);
|
||||
|
||||
impl WebGPU {
|
||||
pub fn new(
|
||||
|
@ -322,14 +318,14 @@ impl WebGPU {
|
|||
|
||||
pub fn exit(&self, sender: IpcSender<()>) -> Result<(), &'static str> {
|
||||
self.0
|
||||
.send(WebGPURequest::Exit(sender))
|
||||
.send((None, WebGPURequest::Exit(sender)))
|
||||
.map_err(|_| "Failed to send Exit message")
|
||||
}
|
||||
}
|
||||
|
||||
struct WGPU<'a> {
|
||||
receiver: IpcReceiver<WebGPURequest>,
|
||||
sender: IpcSender<WebGPURequest>,
|
||||
receiver: IpcReceiver<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
sender: IpcSender<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
script_sender: IpcSender<WebGPUMsg>,
|
||||
global: wgpu::hub::Global<IdentityRecyclerFactory>,
|
||||
adapters: Vec<WebGPUAdapter>,
|
||||
|
@ -339,7 +335,8 @@ struct WGPU<'a> {
|
|||
// Buffers with pending mapping
|
||||
buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPUResponseResult>>>,
|
||||
// Presentation Buffers with pending mapping
|
||||
present_buffer_maps: HashMap<id::BufferId, Rc<BufferMapInfo<'a, WebGPURequest>>>,
|
||||
present_buffer_maps:
|
||||
HashMap<id::BufferId, Rc<BufferMapInfo<'a, (Option<ErrorScopeId>, WebGPURequest)>>>,
|
||||
webrender_api: webrender_api::RenderApi,
|
||||
webrender_document: webrender_api::DocumentId,
|
||||
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
|
||||
|
@ -349,8 +346,8 @@ struct WGPU<'a> {
|
|||
|
||||
impl<'a> WGPU<'a> {
|
||||
fn new(
|
||||
receiver: IpcReceiver<WebGPURequest>,
|
||||
sender: IpcSender<WebGPURequest>,
|
||||
receiver: IpcReceiver<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
sender: IpcSender<(Option<ErrorScopeId>, WebGPURequest)>,
|
||||
script_sender: IpcSender<WebGPUMsg>,
|
||||
webrender_api_sender: webrender_api::RenderApiSender,
|
||||
webrender_document: webrender_api::DocumentId,
|
||||
|
@ -385,17 +382,18 @@ impl<'a> WGPU<'a> {
|
|||
let _ = self.global.poll_all_devices(false);
|
||||
self.last_poll = Instant::now();
|
||||
}
|
||||
if let Ok(msg) = self.receiver.try_recv() {
|
||||
if let Ok((scope_id, msg)) = self.receiver.try_recv() {
|
||||
match msg {
|
||||
WebGPURequest::BufferMapAsync {
|
||||
sender,
|
||||
buffer_id,
|
||||
device_id,
|
||||
host_map,
|
||||
map_range,
|
||||
} => {
|
||||
let map_info = BufferMapInfo {
|
||||
buffer_id,
|
||||
sender,
|
||||
sender: sender.clone(),
|
||||
global: &self.global,
|
||||
size: (map_range.end - map_range.start) as usize,
|
||||
external_id: None,
|
||||
|
@ -409,22 +407,24 @@ impl<'a> WGPU<'a> {
|
|||
let info = Rc::from_raw(
|
||||
userdata as *const BufferMapInfo<WebGPUResponseResult>,
|
||||
);
|
||||
match status {
|
||||
let msg = match status {
|
||||
BufferMapAsyncStatus::Success => {
|
||||
let global = &info.global;
|
||||
let data_pt = gfx_select!(info.buffer_id =>
|
||||
global.buffer_get_mapped_range(info.buffer_id, 0, None))
|
||||
.unwrap();
|
||||
let data = slice::from_raw_parts(data_pt, info.size);
|
||||
if let Err(e) =
|
||||
info.sender.send(Ok(WebGPUResponse::BufferMapAsync(
|
||||
IpcSharedMemory::from_bytes(data),
|
||||
)))
|
||||
{
|
||||
warn!("Could not send BufferMapAsync Response ({})", e);
|
||||
}
|
||||
Ok(WebGPUResponse::BufferMapAsync(IpcSharedMemory::from_bytes(
|
||||
data,
|
||||
)))
|
||||
},
|
||||
_ => error!("Could not map buffer({:?})", info.buffer_id),
|
||||
_ => {
|
||||
warn!("Could not map buffer({:?})", info.buffer_id);
|
||||
Err(String::from("Failed to map Buffer"))
|
||||
},
|
||||
};
|
||||
if let Err(e) = info.sender.send(msg) {
|
||||
warn!("Could not send BufferMapAsync Response ({})", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,7 +436,13 @@ impl<'a> WGPU<'a> {
|
|||
),
|
||||
};
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation));
|
||||
let result = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation));
|
||||
if let Err(ref e) = result {
|
||||
if let Err(w) = sender.send(Err(format!("{:?}", e))) {
|
||||
warn!("Failed to send BufferMapAsync Response ({:?})", w);
|
||||
}
|
||||
}
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::BufferMapComplete(buffer_id) => {
|
||||
self.buffer_maps.remove(&buffer_id);
|
||||
|
@ -444,7 +450,6 @@ impl<'a> WGPU<'a> {
|
|||
WebGPURequest::CommandEncoderFinish {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
scope_id,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_finish(
|
||||
|
@ -455,6 +460,7 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CopyBufferToBuffer {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
source_id,
|
||||
source_offset,
|
||||
destination_id,
|
||||
|
@ -462,7 +468,7 @@ impl<'a> WGPU<'a> {
|
|||
size,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_buffer(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_buffer(
|
||||
command_encoder_id,
|
||||
source_id,
|
||||
source_offset,
|
||||
|
@ -470,52 +476,58 @@ impl<'a> WGPU<'a> {
|
|||
destination_offset,
|
||||
size
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CopyBufferToTexture {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
source,
|
||||
destination,
|
||||
copy_size,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_texture(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_texture(
|
||||
command_encoder_id,
|
||||
&source,
|
||||
&destination,
|
||||
©_size
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CopyTextureToBuffer {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
source,
|
||||
destination,
|
||||
copy_size,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_buffer(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_buffer(
|
||||
command_encoder_id,
|
||||
&source,
|
||||
&destination,
|
||||
©_size
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CopyTextureToTexture {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
source,
|
||||
destination,
|
||||
copy_size,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_texture(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_texture(
|
||||
command_encoder_id,
|
||||
&source,
|
||||
&destination,
|
||||
©_size
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::CreateBindGroup {
|
||||
device_id,
|
||||
scope_id,
|
||||
bind_group_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -526,7 +538,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateBindGroupLayout {
|
||||
device_id,
|
||||
scope_id,
|
||||
bind_group_layout_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -537,7 +548,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateBuffer {
|
||||
device_id,
|
||||
scope_id,
|
||||
buffer_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -556,7 +566,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateCommandEncoder {
|
||||
device_id,
|
||||
scope_id,
|
||||
command_encoder_id,
|
||||
label,
|
||||
} => {
|
||||
|
@ -576,7 +585,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateComputePipeline {
|
||||
device_id,
|
||||
scope_id,
|
||||
compute_pipeline_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -597,7 +605,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreatePipelineLayout {
|
||||
device_id,
|
||||
scope_id,
|
||||
pipeline_layout_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -609,7 +616,6 @@ impl<'a> WGPU<'a> {
|
|||
//TODO: consider https://github.com/gfx-rs/wgpu/issues/684
|
||||
WebGPURequest::CreateRenderPipeline {
|
||||
device_id,
|
||||
scope_id,
|
||||
render_pipeline_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -620,7 +626,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateSampler {
|
||||
device_id,
|
||||
scope_id,
|
||||
sampler_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -642,7 +647,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateShaderModule {
|
||||
device_id,
|
||||
scope_id,
|
||||
program_id,
|
||||
program,
|
||||
} => {
|
||||
|
@ -697,7 +701,6 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::CreateTexture {
|
||||
device_id,
|
||||
scope_id,
|
||||
texture_id,
|
||||
descriptor,
|
||||
} => {
|
||||
|
@ -721,7 +724,6 @@ impl<'a> WGPU<'a> {
|
|||
texture_id,
|
||||
texture_view_id,
|
||||
device_id,
|
||||
scope_id,
|
||||
descriptor,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
|
@ -799,7 +801,6 @@ impl<'a> WGPU<'a> {
|
|||
descriptor,
|
||||
render_bundle_id,
|
||||
device_id,
|
||||
scope_id,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let st;
|
||||
|
@ -863,14 +864,23 @@ impl<'a> WGPU<'a> {
|
|||
label,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let result = gfx_select!(device_id => global.adapter_request_device(
|
||||
let id = match gfx_select!(device_id => global.adapter_request_device(
|
||||
adapter_id.0,
|
||||
&descriptor,
|
||||
None,
|
||||
device_id
|
||||
));
|
||||
// TODO: Handle error gracefully acc. to spec.
|
||||
let id = result.unwrap();
|
||||
)) {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
if let Err(w) = sender.send(Err(format!("{:?}", e))) {
|
||||
warn!(
|
||||
"Failed to send response to WebGPURequest::RequestDevice ({})",
|
||||
w
|
||||
)
|
||||
}
|
||||
return;
|
||||
},
|
||||
};
|
||||
let device = WebGPUDevice(id);
|
||||
// Note: (zakorgy) Note sure if sending the queue is needed at all,
|
||||
// since wgpu-core uses the same id for the device and the queue
|
||||
|
@ -890,30 +900,35 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::RunComputePass {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
compute_pass,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass(
|
||||
command_encoder_id,
|
||||
&compute_pass
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::RunRenderPass {
|
||||
command_encoder_id,
|
||||
device_id,
|
||||
render_pass,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(command_encoder_id => global.command_encoder_run_render_pass(
|
||||
let result = gfx_select!(command_encoder_id => global.command_encoder_run_render_pass(
|
||||
command_encoder_id,
|
||||
&render_pass
|
||||
));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::Submit {
|
||||
queue_id,
|
||||
command_buffers,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
let _ = gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers));
|
||||
let result = gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers));
|
||||
self.send_result(queue_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::SwapChainPresent {
|
||||
external_id,
|
||||
|
@ -1052,6 +1067,7 @@ impl<'a> WGPU<'a> {
|
|||
},
|
||||
WebGPURequest::UnmapBuffer {
|
||||
buffer_id,
|
||||
device_id,
|
||||
array_buffer,
|
||||
is_map_read,
|
||||
offset,
|
||||
|
@ -1068,7 +1084,8 @@ impl<'a> WGPU<'a> {
|
|||
unsafe { slice::from_raw_parts_mut(map_ptr, size as usize) }
|
||||
.copy_from_slice(&array_buffer);
|
||||
}
|
||||
let _ = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
|
||||
let result = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
|
||||
self.send_result(device_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::UpdateWebRenderData {
|
||||
buffer_id,
|
||||
|
@ -1111,12 +1128,13 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
//TODO: Report result to content process
|
||||
let _ = gfx_select!(queue_id => global.queue_write_buffer(
|
||||
let result = gfx_select!(queue_id => global.queue_write_buffer(
|
||||
queue_id,
|
||||
buffer_id,
|
||||
buffer_offset as wgt::BufferAddress,
|
||||
&data
|
||||
));
|
||||
self.send_result(queue_id, scope_id, result);
|
||||
},
|
||||
WebGPURequest::WriteTexture {
|
||||
queue_id,
|
||||
|
@ -1127,23 +1145,24 @@ impl<'a> WGPU<'a> {
|
|||
} => {
|
||||
let global = &self.global;
|
||||
//TODO: Report result to content process
|
||||
let _ = gfx_select!(queue_id => global.queue_write_texture(
|
||||
let result = gfx_select!(queue_id => global.queue_write_texture(
|
||||
queue_id,
|
||||
&texture_cv,
|
||||
&data,
|
||||
&data_layout,
|
||||
&size
|
||||
));
|
||||
self.send_result(queue_id, scope_id, result);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_result<U: id::TypedId, T: std::fmt::Debug>(
|
||||
fn send_result<U, T: std::fmt::Debug>(
|
||||
&self,
|
||||
device_id: id::DeviceId,
|
||||
scope_id: Option<u64>,
|
||||
scope_id: Option<ErrorScopeId>,
|
||||
result: Result<U, T>,
|
||||
) {
|
||||
let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue