Auto merge of #27447 - kunalmohan:gpu-error, r=kvark

Refactor and improve GPUErrorScopes

- Remove use of equivalent BGLs
- Capture errors from more `Createxxx` operations
- Address crashes on macOS in #27402

Improved ErrorScope model attempts to-

1. Identify and report `OutOfMemoryError` separately.
1. Match `GPUErrorFilter` and pass on uncaptured errors to parent scope.

r?@kvark

<!-- Please describe your changes on the following line: -->

---
<!-- 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
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- 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:
bors-servo 2020-07-30 14:26:05 -04:00 committed by GitHub
commit f0ba895c68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 259 additions and 149 deletions

79
Cargo.lock generated
View file

@ -770,6 +770,21 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "cocoa-foundation"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
dependencies = [
"bitflags",
"block",
"core-foundation 0.9.0",
"core-graphics-types",
"foreign-types",
"libc",
"objc",
]
[[package]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.0.1" version = "1.0.1"
@ -920,6 +935,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core-foundation"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
dependencies = [
"core-foundation-sys 0.8.0",
"libc",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.6.2" version = "0.6.2"
@ -932,6 +957,12 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]]
name = "core-foundation-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
[[package]] [[package]]
name = "core-graphics" name = "core-graphics"
version = "0.17.3" version = "0.17.3"
@ -956,6 +987,18 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core-graphics-types"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e92f5d519093a4178296707dbaa3880eae85a5ef5386675f361a1cf25376e93c"
dependencies = [
"bitflags",
"core-foundation 0.9.0",
"foreign-types",
"libc",
]
[[package]] [[package]]
name = "core-text" name = "core-text"
version = "13.3.2" version = "13.3.2"
@ -1889,22 +1932,21 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-metal" name = "gfx-backend-metal"
version = "0.5.4" version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "412a1e0e53e9e325a7c2e0316f1a4e8a14cbe8d8bfb5f030bc3895692f8a8254" checksum = "92804d20b194de6c84cb4bec14ec6a6dcae9c51f0a9186817fb412a590131ae6"
dependencies = [ dependencies = [
"arrayvec 0.5.1", "arrayvec 0.5.1",
"bitflags", "bitflags",
"block", "block",
"cocoa 0.20.1", "cocoa-foundation",
"copyless", "copyless",
"core-graphics 0.19.0",
"foreign-types", "foreign-types",
"gfx-auxil", "gfx-auxil",
"gfx-hal", "gfx-hal",
"lazy_static", "lazy_static",
"log", "log",
"metal", "metal 0.20.0",
"objc", "objc",
"parking_lot 0.10.2", "parking_lot 0.10.2",
"range-alloc", "range-alloc",
@ -1916,14 +1958,14 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-vulkan" name = "gfx-backend-vulkan"
version = "0.5.9" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2e8bb53e5bea0bfec7035462a75717cd04d733963a225c816339a671ef108b" checksum = "aec9c919cfc236d2c36aaa38609c1906a92f2df99a3c7f53022b01936f98275a"
dependencies = [ dependencies = [
"arrayvec 0.5.1", "arrayvec 0.5.1",
"ash", "ash",
"byteorder", "byteorder",
"core-graphics 0.19.0", "core-graphics-types",
"gfx-hal", "gfx-hal",
"lazy_static", "lazy_static",
"log", "log",
@ -3433,6 +3475,20 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "metal"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf"
dependencies = [
"bitflags",
"block",
"cocoa-foundation",
"foreign-types",
"log",
"objc",
]
[[package]] [[package]]
name = "metrics" name = "metrics"
version = "0.0.1" version = "0.0.1"
@ -5776,7 +5832,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"mach", "mach",
"metal", "metal 0.18.0",
"objc", "objc",
"parking_lot 0.10.2", "parking_lot 0.10.2",
"wayland-sys 0.24.0", "wayland-sys 0.24.0",
@ -6855,7 +6911,7 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu#8a2ee26fffcdf02fc5e7f0a29771f4720522f7d8" source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4"
dependencies = [ dependencies = [
"arrayvec 0.5.1", "arrayvec 0.5.1",
"bitflags", "bitflags",
@ -6869,7 +6925,6 @@ dependencies = [
"gfx-descriptor", "gfx-descriptor",
"gfx-hal", "gfx-hal",
"gfx-memory", "gfx-memory",
"log",
"naga", "naga",
"parking_lot 0.10.2", "parking_lot 0.10.2",
"ron", "ron",
@ -6883,7 +6938,7 @@ dependencies = [
[[package]] [[package]]
name = "wgpu-types" name = "wgpu-types"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu#8a2ee26fffcdf02fc5e7f0a29771f4720522f7d8" source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"serde", "serde",

View file

@ -169,7 +169,6 @@ use time::{Duration, Timespec, Tm};
use uuid::Uuid; use uuid::Uuid;
use webgpu::{ use webgpu::{
wgpu::command::{ComputePass, RenderBundleEncoder, RenderPass}, wgpu::command::{ComputePass, RenderBundleEncoder, RenderPass},
wgt::BindGroupLayoutEntry,
WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer,
WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice,
WebGPUPipelineLayout, WebGPUQueue, WebGPURenderBundle, WebGPURenderPipeline, WebGPUSampler, WebGPUPipelineLayout, WebGPUQueue, WebGPURenderBundle, WebGPURenderPipeline, WebGPUSampler,
@ -629,7 +628,6 @@ unsafe_no_jsmanaged_fields!(WebGPUContextId);
unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer); unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer);
unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder); unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder);
unsafe_no_jsmanaged_fields!(WebGPUDevice); unsafe_no_jsmanaged_fields!(WebGPUDevice);
unsafe_no_jsmanaged_fields!(BindGroupLayoutEntry);
unsafe_no_jsmanaged_fields!(Option<RenderPass>); unsafe_no_jsmanaged_fields!(Option<RenderPass>);
unsafe_no_jsmanaged_fields!(Option<RenderBundleEncoder>); unsafe_no_jsmanaged_fields!(Option<RenderBundleEncoder>);
unsafe_no_jsmanaged_fields!(Option<ComputePass>); unsafe_no_jsmanaged_fields!(Option<ComputePass>);

View file

@ -5,7 +5,6 @@
use crate::dom::bindings::cell::{DomRefCell, RefMut}; use crate::dom::bindings::cell::{DomRefCell, RefMut};
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods; use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods; use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods;
use crate::dom::bindings::codegen::Bindings::GPUValidationErrorBinding::GPUError;
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{ use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource, ImageBitmapOptions, ImageBitmapSource,
}; };
@ -36,8 +35,6 @@ use crate::dom::eventsource::EventSource;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::file::File; use crate::dom::file::File;
use crate::dom::gpudevice::GPUDevice; use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpuoutofmemoryerror::GPUOutOfMemoryError;
use crate::dom::gpuvalidationerror::GPUValidationError;
use crate::dom::htmlscriptelement::{ScriptId, SourceCode}; use crate::dom::htmlscriptelement::{ScriptId, SourceCode};
use crate::dom::identityhub::Identities; use crate::dom::identityhub::Identities;
use crate::dom::imagebitmap::ImageBitmap; use crate::dom::imagebitmap::ImageBitmap;
@ -3023,18 +3020,12 @@ impl GlobalScope {
let _ = self.gpu_devices.borrow_mut().remove(&device); let _ = self.gpu_devices.borrow_mut().remove(&device);
} }
pub fn handle_wgpu_msg(&self, device: WebGPUDevice, scope: u64, result: WebGPUOpResult) { pub fn handle_wgpu_msg(
let result = match result { &self,
WebGPUOpResult::Success => Ok(()), device: WebGPUDevice,
WebGPUOpResult::ValidationError(m) => { scope: Option<u64>,
let val_err = GPUValidationError::new(&self, DOMString::from_string(m)); result: WebGPUOpResult,
Err(GPUError::GPUValidationError(val_err)) ) {
},
WebGPUOpResult::OutOfMemoryError => {
let oom_err = GPUOutOfMemoryError::new(&self);
Err(GPUError::GPUOutOfMemoryError(oom_err))
},
};
self.gpu_devices self.gpu_devices
.borrow() .borrow()
.get(&device) .get(&device)

View file

@ -16,20 +16,20 @@ use crate::dom::bindings::codegen::UnionTypes::{
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; 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::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubuffer::GPUBuffer; use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandbuffer::GPUCommandBuffer; use crate::dom::gpucommandbuffer::GPUCommandBuffer;
use crate::dom::gpucomputepassencoder::GPUComputePassEncoder; use crate::dom::gpucomputepassencoder::GPUComputePassEncoder;
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 crate::dom::gpurenderpassencoder::GPURenderPassEncoder; use crate::dom::gpurenderpassencoder::GPURenderPassEncoder;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashSet; use std::collections::HashSet;
use webgpu::wgpu::command as wgpu_com; use webgpu::wgpu::command as wgpu_com;
use webgpu::{self, wgt, WebGPU, WebGPUDevice, WebGPURequest}; use webgpu::{self, wgt, WebGPU, WebGPURequest};
// https://gpuweb.github.io/gpuweb/#enumdef-encoder-state // https://gpuweb.github.io/gpuweb/#enumdef-encoder-state
#[derive(MallocSizeOf, PartialEq)] #[derive(MallocSizeOf, PartialEq)]
@ -49,14 +49,14 @@ pub struct GPUCommandEncoder {
encoder: webgpu::WebGPUCommandEncoder, encoder: webgpu::WebGPUCommandEncoder,
buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>, buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>,
state: DomRefCell<GPUCommandEncoderState>, state: DomRefCell<GPUCommandEncoderState>,
device: WebGPUDevice, device: Dom<GPUDevice>,
valid: Cell<bool>, valid: Cell<bool>,
} }
impl GPUCommandEncoder { impl GPUCommandEncoder {
pub fn new_inherited( pub fn new_inherited(
channel: WebGPU, channel: WebGPU,
device: WebGPUDevice, device: &GPUDevice,
encoder: webgpu::WebGPUCommandEncoder, encoder: webgpu::WebGPUCommandEncoder,
valid: bool, valid: bool,
label: Option<USVString>, label: Option<USVString>,
@ -65,7 +65,7 @@ impl GPUCommandEncoder {
channel, channel,
reflector_: Reflector::new(), reflector_: Reflector::new(),
label: DomRefCell::new(label), label: DomRefCell::new(label),
device, device: Dom::from_ref(device),
encoder, encoder,
buffers: DomRefCell::new(HashSet::new()), buffers: DomRefCell::new(HashSet::new()),
state: DomRefCell::new(GPUCommandEncoderState::Open), state: DomRefCell::new(GPUCommandEncoderState::Open),
@ -76,7 +76,7 @@ impl GPUCommandEncoder {
pub fn new( pub fn new(
global: &GlobalScope, global: &GlobalScope,
channel: WebGPU, channel: WebGPU,
device: WebGPUDevice, device: &GPUDevice,
encoder: webgpu::WebGPUCommandEncoder, encoder: webgpu::WebGPUCommandEncoder,
valid: bool, valid: bool,
label: Option<USVString>, label: Option<USVString>,
@ -370,6 +370,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
.0 .0
.send(WebGPURequest::CommandEncoderFinish { .send(WebGPURequest::CommandEncoderFinish {
command_encoder_id: self.encoder.0, 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 // TODO(zakorgy): We should use `_descriptor` here after it's not empty
// and the underlying wgpu-core struct is serializable // and the underlying wgpu-core struct is serializable
}) })

View file

@ -39,7 +39,7 @@ use crate::dom::bindings::codegen::UnionTypes::Uint32ArrayOrString;
use crate::dom::bindings::error::Error; use crate::dom::bindings::error::Error;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
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::{DOMString, USVString};
use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
@ -49,6 +49,7 @@ use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferMapInfo, GPUBufferState}; use crate::dom::gpubuffer::{GPUBuffer, GPUBufferMapInfo, GPUBufferState};
use crate::dom::gpucommandencoder::GPUCommandEncoder; use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline; use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::gpuoutofmemoryerror::GPUOutOfMemoryError;
use crate::dom::gpupipelinelayout::GPUPipelineLayout; use crate::dom::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::gpuqueue::GPUQueue; use crate::dom::gpuqueue::GPUQueue;
use crate::dom::gpurenderbundleencoder::GPURenderBundleEncoder; use crate::dom::gpurenderbundleencoder::GPURenderBundleEncoder;
@ -56,6 +57,7 @@ use crate::dom::gpurenderpipeline::GPURenderPipeline;
use crate::dom::gpusampler::GPUSampler; use crate::dom::gpusampler::GPUSampler;
use crate::dom::gpushadermodule::GPUShaderModule; use crate::dom::gpushadermodule::GPUShaderModule;
use crate::dom::gputexture::GPUTexture; use crate::dom::gputexture::GPUTexture;
use crate::dom::gpuvalidationerror::GPUValidationError;
use crate::dom::promise::Promise; use crate::dom::promise::Promise;
use crate::realms::InRealm; use crate::realms::InRealm;
use crate::script_runtime::JSContext as SafeJSContext; use crate::script_runtime::JSContext as SafeJSContext;
@ -69,13 +71,12 @@ use std::rc::Rc;
use webgpu::wgpu::{ use webgpu::wgpu::{
binding_model as wgpu_bind, command::RenderBundleEncoder, pipeline as wgpu_pipe, binding_model as wgpu_bind, command::RenderBundleEncoder, pipeline as wgpu_pipe,
}; };
use webgpu::{self, wgt, WebGPU, WebGPURequest}; use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest};
type ErrorScopeId = u64; type ErrorScopeId = u64;
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct ErrorScopeInfo { struct ErrorScopeInfo {
filter: GPUErrorFilter,
op_count: u64, op_count: u64,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
error: Option<GPUError>, error: Option<GPUError>,
@ -86,7 +87,7 @@ struct ErrorScopeInfo {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct ScopeContext { struct ScopeContext {
error_scopes: HashMap<ErrorScopeId, ErrorScopeInfo>, error_scopes: HashMap<ErrorScopeId, ErrorScopeInfo>,
scope_stack: Vec<ErrorScopeId>, scope_stack: Vec<(ErrorScopeId, GPUErrorFilter)>,
next_scope_id: ErrorScopeId, next_scope_id: ErrorScopeId,
} }
@ -106,9 +107,6 @@ pub struct GPUDevice {
scope_context: DomRefCell<ScopeContext>, scope_context: DomRefCell<ScopeContext>,
#[ignore_malloc_size_of = "promises are hard"] #[ignore_malloc_size_of = "promises are hard"]
lost_promise: DomRefCell<Option<Rc<Promise>>>, lost_promise: DomRefCell<Option<Rc<Promise>>>,
#[ignore_malloc_size_of = "defined in webgpu"]
bind_group_layouts:
DomRefCell<HashMap<Vec<wgt::BindGroupLayoutEntry>, Dom<GPUBindGroupLayout>>>,
} }
impl GPUDevice { impl GPUDevice {
@ -136,7 +134,6 @@ impl GPUDevice {
next_scope_id: 0, next_scope_id: 0,
}), }),
lost_promise: DomRefCell::new(None), lost_promise: DomRefCell::new(None),
bind_group_layouts: DomRefCell::new(HashMap::new()),
} }
} }
@ -165,18 +162,62 @@ impl GPUDevice {
self.device self.device
} }
pub fn handle_server_msg(&self, scope: ErrorScopeId, result: Result<(), GPUError>) { pub fn handle_server_msg(&self, scope: Option<ErrorScopeId>, result: WebGPUOpResult) {
let result = match result {
WebGPUOpResult::Success => Ok(()),
WebGPUOpResult::ValidationError(m) => {
let val_err = GPUValidationError::new(&self.global(), DOMString::from_string(m));
Err((
GPUError::GPUValidationError(val_err),
GPUErrorFilter::Validation,
))
},
WebGPUOpResult::OutOfMemoryError => {
let oom_err = GPUOutOfMemoryError::new(&self.global());
Err((
GPUError::GPUOutOfMemoryError(oom_err),
GPUErrorFilter::Out_of_memory,
))
},
};
if let Some(s_id) = scope {
if let Err((err, filter)) = result {
let scop = self
.scope_context
.borrow()
.scope_stack
.iter()
.rev()
.find(|&&(id, fil)| id <= s_id && fil == filter)
.map(|(id, _)| *id);
if let Some(s) = scop {
self.handle_error(s, err);
} else {
// Fire UncapturedErrorEvent.
}
}
self.try_remove_scope(s_id);
} else {
// Fire UncapturedErrorEvent if result is Error
}
}
fn handle_error(&self, scope: ErrorScopeId, error: GPUError) {
let mut context = self.scope_context.borrow_mut();
if let Some(mut err_scope) = context.error_scopes.get_mut(&scope) {
if err_scope.error.is_none() {
err_scope.error = Some(error);
}
} else {
warn!("Could not find ErrorScope with Id({})", scope);
}
}
fn try_remove_scope(&self, scope: ErrorScopeId) {
let mut context = self.scope_context.borrow_mut(); let mut context = self.scope_context.borrow_mut();
let remove = if let Some(mut err_scope) = context.error_scopes.get_mut(&scope) { let remove = if let Some(mut err_scope) = context.error_scopes.get_mut(&scope) {
err_scope.op_count -= 1; err_scope.op_count -= 1;
match result {
Ok(()) => {},
Err(e) => {
if err_scope.error.is_none() {
err_scope.error = Some(e);
}
},
}
if let Some(ref promise) = err_scope.promise { if let Some(ref promise) = err_scope.promise {
if !promise.is_fulfilled() { if !promise.is_fulfilled() {
if let Some(ref e) = err_scope.error { if let Some(ref e) = err_scope.error {
@ -191,18 +232,19 @@ impl GPUDevice {
} }
err_scope.op_count == 0 && err_scope.promise.is_some() err_scope.op_count == 0 && err_scope.promise.is_some()
} else { } else {
warn!("Could not find ErrroScope with Id({})", scope); warn!("Could not find ErrorScope with Id({})", scope);
false false
}; };
if remove { if remove {
let _ = context.error_scopes.remove(&scope); let _ = context.error_scopes.remove(&scope);
context.scope_stack.retain(|(id, _)| *id != scope);
} }
} }
fn use_current_scope(&self) -> Option<ErrorScopeId> { pub fn use_current_scope(&self) -> Option<ErrorScopeId> {
let mut context = self.scope_context.borrow_mut(); let mut context = self.scope_context.borrow_mut();
let scope_id = context.scope_stack.last().cloned(); let scope_id = context.scope_stack.last().copied();
scope_id.and_then(|s_id| { scope_id.and_then(|(s_id, _)| {
context.error_scopes.get_mut(&s_id).map(|mut scope| { context.error_scopes.get_mut(&s_id).map(|mut scope| {
scope.op_count += 1; scope.op_count += 1;
s_id s_id
@ -265,10 +307,13 @@ impl GPUDeviceMethods for GPUDevice {
.wgpu_id_hub() .wgpu_id_hub()
.lock() .lock()
.create_buffer_id(self.device.0.backend()); .create_buffer_id(self.device.0.backend());
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateBuffer { .send(WebGPURequest::CreateBuffer {
device_id: self.device.0, device_id: self.device.0,
scope_id,
buffer_id: id, buffer_id: id,
descriptor: wgpu_descriptor, descriptor: wgpu_descriptor,
}) })
@ -388,28 +433,13 @@ impl GPUDeviceMethods for GPUDevice {
let scope_id = self.use_current_scope(); let scope_id = self.use_current_scope();
// Check for equivalent GPUBindGroupLayout
{
let layout = self
.bind_group_layouts
.borrow()
.get(&entries)
.map(|bgl| DomRoot::from_ref(&**bgl));
if let Some(l) = layout {
if let Some(i) = scope_id {
self.handle_server_msg(i, Ok(()));
}
return l;
}
}
let desc = wgt::BindGroupLayoutDescriptor { let desc = wgt::BindGroupLayoutDescriptor {
label: descriptor label: descriptor
.parent .parent
.label .label
.as_ref() .as_ref()
.map(|s| Cow::Owned(s.to_string())), .map(|s| Cow::Owned(s.to_string())),
entries: Cow::Owned(entries.clone()), entries: Cow::Owned(entries),
}; };
let bind_group_layout_id = self let bind_group_layout_id = self
@ -429,17 +459,11 @@ impl GPUDeviceMethods for GPUDevice {
let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id); let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id);
let layout = GPUBindGroupLayout::new( GPUBindGroupLayout::new(
&self.global(), &self.global(),
bgl, bgl,
descriptor.parent.label.as_ref().cloned(), descriptor.parent.label.as_ref().cloned(),
); )
self.bind_group_layouts
.borrow_mut()
.insert(entries, Dom::from_ref(&*layout));
layout
} }
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout
@ -562,10 +586,13 @@ impl GPUDeviceMethods for GPUDevice {
.wgpu_id_hub() .wgpu_id_hub()
.lock() .lock()
.create_shader_module_id(self.device.0.backend()); .create_shader_module_id(self.device.0.backend());
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateShaderModule { .send(WebGPURequest::CreateShaderModule {
device_id: self.device.0, device_id: self.device.0,
scope_id,
program_id, program_id,
program, program,
}) })
@ -628,10 +655,12 @@ impl GPUDeviceMethods for GPUDevice {
.wgpu_id_hub() .wgpu_id_hub()
.lock() .lock()
.create_command_encoder_id(self.device.0.backend()); .create_command_encoder_id(self.device.0.backend());
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateCommandEncoder { .send(WebGPURequest::CreateCommandEncoder {
device_id: self.device.0, device_id: self.device.0,
scope_id,
command_encoder_id, command_encoder_id,
label: descriptor.parent.label.as_ref().map(|s| s.to_string()), label: descriptor.parent.label.as_ref().map(|s| s.to_string()),
}) })
@ -642,7 +671,7 @@ impl GPUDeviceMethods for GPUDevice {
GPUCommandEncoder::new( GPUCommandEncoder::new(
&self.global(), &self.global(),
self.channel.clone(), self.channel.clone(),
self.device, &self,
encoder, encoder,
true, true,
descriptor.parent.label.as_ref().cloned(), descriptor.parent.label.as_ref().cloned(),
@ -675,12 +704,15 @@ impl GPUDeviceMethods for GPUDevice {
.lock() .lock()
.create_texture_id(self.device.0.backend()); .create_texture_id(self.device.0.backend());
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateTexture { .send(WebGPURequest::CreateTexture {
device_id: self.device.0, device_id: self.device.0,
texture_id, texture_id,
descriptor: desc, descriptor: desc,
scope_id,
}) })
.expect("Failed to create WebGPU Texture"); .expect("Failed to create WebGPU Texture");
@ -689,7 +721,7 @@ impl GPUDeviceMethods for GPUDevice {
GPUTexture::new( GPUTexture::new(
&self.global(), &self.global(),
texture, texture,
self.device, &self,
self.channel.clone(), self.channel.clone(),
size, size,
descriptor.mipLevelCount, descriptor.mipLevelCount,
@ -723,10 +755,13 @@ impl GPUDeviceMethods for GPUDevice {
anisotropy_clamp: None, anisotropy_clamp: None,
..Default::default() ..Default::default()
}; };
let scope_id = self.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateSampler { .send(WebGPURequest::CreateSampler {
device_id: self.device.0, device_id: self.device.0,
scope_id,
sampler_id, sampler_id,
descriptor: desc, descriptor: desc,
}) })
@ -914,7 +949,7 @@ impl GPUDeviceMethods for GPUDevice {
GPURenderBundleEncoder::new( GPURenderBundleEncoder::new(
&self.global(), &self.global(),
render_bundle_encoder, render_bundle_encoder,
self.device, &self,
self.channel.clone(), self.channel.clone(),
descriptor.parent.label.as_ref().cloned(), descriptor.parent.label.as_ref().cloned(),
) )
@ -926,13 +961,12 @@ impl GPUDeviceMethods for GPUDevice {
let scope_id = context.next_scope_id; let scope_id = context.next_scope_id;
context.next_scope_id += 1; context.next_scope_id += 1;
let err_scope = ErrorScopeInfo { let err_scope = ErrorScopeInfo {
filter,
op_count: 0, op_count: 0,
error: None, error: None,
promise: None, promise: None,
}; };
let res = context.error_scopes.insert(scope_id, err_scope); let res = context.error_scopes.insert(scope_id, err_scope);
context.scope_stack.push(scope_id); context.scope_stack.push((scope_id, filter));
assert!(res.is_none()); assert!(res.is_none());
} }
@ -940,8 +974,8 @@ impl GPUDeviceMethods for GPUDevice {
fn PopErrorScope(&self, comp: InRealm) -> Rc<Promise> { fn PopErrorScope(&self, comp: InRealm) -> Rc<Promise> {
let mut context = self.scope_context.borrow_mut(); let mut context = self.scope_context.borrow_mut();
let promise = Promise::new_in_current_realm(&self.global(), comp); let promise = Promise::new_in_current_realm(&self.global(), comp);
let scope_id = if let Some(e) = context.scope_stack.pop() { let scope_id = if let Some((e, _)) = context.scope_stack.last() {
e *e
} else { } else {
promise.reject_error(Error::Operation); promise.reject_error(Error::Operation);
return promise; return promise;
@ -963,6 +997,7 @@ impl GPUDeviceMethods for GPUDevice {
}; };
if remove { if remove {
let _ = context.error_scopes.remove(&scope_id); let _ = context.error_scopes.remove(&scope_id);
let _ = context.scope_stack.pop();
} }
promise promise
} }

View file

@ -6,17 +6,18 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::GPURenderBundleBinding::GPURenderBundleDescriptor; use crate::dom::bindings::codegen::Bindings::GPURenderBundleBinding::GPURenderBundleDescriptor;
use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderMethods; use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::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;
use crate::dom::gpubindgroup::GPUBindGroup; use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubuffer::GPUBuffer; use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpudevice::GPUDevice;
use crate::dom::gpurenderbundle::GPURenderBundle; use crate::dom::gpurenderbundle::GPURenderBundle;
use crate::dom::gpurenderpipeline::GPURenderPipeline; use crate::dom::gpurenderpipeline::GPURenderPipeline;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use webgpu::{ use webgpu::{
wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder}, wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder},
wgt, WebGPU, WebGPUDevice, WebGPURenderBundle, WebGPURequest, wgt, WebGPU, WebGPURenderBundle, WebGPURequest,
}; };
#[dom_struct] #[dom_struct]
@ -24,7 +25,7 @@ pub struct GPURenderBundleEncoder {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
channel: WebGPU, channel: WebGPU,
device: WebGPUDevice, device: Dom<GPUDevice>,
#[ignore_malloc_size_of = "defined in wgpu-core"] #[ignore_malloc_size_of = "defined in wgpu-core"]
render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>, render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
@ -33,14 +34,14 @@ pub struct GPURenderBundleEncoder {
impl GPURenderBundleEncoder { impl GPURenderBundleEncoder {
fn new_inherited( fn new_inherited(
render_bundle_encoder: RenderBundleEncoder, render_bundle_encoder: RenderBundleEncoder,
device: WebGPUDevice, device: &GPUDevice,
channel: WebGPU, channel: WebGPU,
label: Option<USVString>, label: Option<USVString>,
) -> Self { ) -> Self {
Self { Self {
reflector_: Reflector::new(), reflector_: Reflector::new(),
render_bundle_encoder: DomRefCell::new(Some(render_bundle_encoder)), render_bundle_encoder: DomRefCell::new(Some(render_bundle_encoder)),
device, device: Dom::from_ref(device),
channel, channel,
label: DomRefCell::new(label), label: DomRefCell::new(label),
} }
@ -49,7 +50,7 @@ impl GPURenderBundleEncoder {
pub fn new( pub fn new(
global: &GlobalScope, global: &GlobalScope,
render_bundle_encoder: RenderBundleEncoder, render_bundle_encoder: RenderBundleEncoder,
device: WebGPUDevice, device: &GPUDevice,
channel: WebGPU, channel: WebGPU,
label: Option<USVString>, label: Option<USVString>,
) -> DomRoot<Self> { ) -> DomRoot<Self> {
@ -190,7 +191,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
.global() .global()
.wgpu_id_hub() .wgpu_id_hub()
.lock() .lock()
.create_render_bundle_id(self.device.0.backend()); .create_render_bundle_id(self.device.id().0.backend());
self.channel self.channel
.0 .0
@ -198,6 +199,8 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
render_bundle_encoder: encoder, render_bundle_encoder: encoder,
descriptor: desc, descriptor: desc,
render_bundle_id, render_bundle_id,
device_id: self.device.id().0,
scope_id: self.device.use_current_scope(),
}) })
.expect("Failed to send RenderBundleEncoderFinish"); .expect("Failed to send RenderBundleEncoderFinish");
@ -205,7 +208,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
GPURenderBundle::new( GPURenderBundle::new(
&self.global(), &self.global(),
render_bundle, render_bundle,
self.device, self.device.id(),
self.channel.clone(), self.channel.clone(),
descriptor.parent.label.as_ref().cloned(), descriptor.parent.label.as_ref().cloned(),
) )

View file

@ -10,21 +10,21 @@ use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::{
GPUTextureAspect, GPUTextureViewDescriptor, GPUTextureViewDimension, GPUTextureAspect, GPUTextureViewDescriptor, GPUTextureViewDimension,
}; };
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::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;
use crate::dom::gpudevice::{convert_texture_format, convert_texture_view_dimension}; use crate::dom::gpudevice::{convert_texture_format, convert_texture_view_dimension, GPUDevice};
use crate::dom::gputextureview::GPUTextureView; use crate::dom::gputextureview::GPUTextureView;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::string::String; use std::string::String;
use webgpu::{wgt, WebGPU, WebGPUDevice, WebGPURequest, WebGPUTexture, WebGPUTextureView}; use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView};
#[dom_struct] #[dom_struct]
pub struct GPUTexture { pub struct GPUTexture {
reflector_: Reflector, reflector_: Reflector,
texture: WebGPUTexture, texture: WebGPUTexture,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
device: WebGPUDevice, device: Dom<GPUDevice>,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
channel: WebGPU, channel: WebGPU,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
@ -39,7 +39,7 @@ pub struct GPUTexture {
impl GPUTexture { impl GPUTexture {
fn new_inherited( fn new_inherited(
texture: WebGPUTexture, texture: WebGPUTexture,
device: WebGPUDevice, device: &GPUDevice,
channel: WebGPU, channel: WebGPU,
texture_size: GPUExtent3DDict, texture_size: GPUExtent3DDict,
mip_level_count: u32, mip_level_count: u32,
@ -53,7 +53,7 @@ impl GPUTexture {
reflector_: Reflector::new(), reflector_: Reflector::new(),
texture, texture,
label: DomRefCell::new(label), label: DomRefCell::new(label),
device, device: Dom::from_ref(device),
channel, channel,
texture_size, texture_size,
mip_level_count, mip_level_count,
@ -67,7 +67,7 @@ impl GPUTexture {
pub fn new( pub fn new(
global: &GlobalScope, global: &GlobalScope,
texture: WebGPUTexture, texture: WebGPUTexture,
device: WebGPUDevice, device: &GPUDevice,
channel: WebGPU, channel: WebGPU,
texture_size: GPUExtent3DDict, texture_size: GPUExtent3DDict,
mip_level_count: u32, mip_level_count: u32,
@ -126,7 +126,7 @@ impl GPUTextureMethods for GPUTexture {
match self.dimension { match self.dimension {
GPUTextureDimension::_1d => GPUTextureViewDimension::_1d, GPUTextureDimension::_1d => GPUTextureViewDimension::_1d,
GPUTextureDimension::_2d => { GPUTextureDimension::_2d => {
if self.texture_size.depth > 1 && descriptor.arrayLayerCount == 0 { if self.texture_size.depth > 1 && descriptor.arrayLayerCount.is_none() {
GPUTextureViewDimension::_2d_array GPUTextureViewDimension::_2d_array
} else { } else {
GPUTextureViewDimension::_2d GPUTextureViewDimension::_2d
@ -152,31 +152,27 @@ impl GPUTextureMethods for GPUTexture {
GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly, GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly,
}, },
base_mip_level: descriptor.baseMipLevel, base_mip_level: descriptor.baseMipLevel,
level_count: if descriptor.mipLevelCount == 0 { level_count: descriptor.mipLevelCount.as_ref().copied(),
self.mip_level_count - descriptor.baseMipLevel
} else {
descriptor.mipLevelCount
},
base_array_layer: descriptor.baseArrayLayer, base_array_layer: descriptor.baseArrayLayer,
array_layer_count: if descriptor.arrayLayerCount == 0 { array_layer_count: descriptor.arrayLayerCount.as_ref().copied(),
self.texture_size.depth - descriptor.baseArrayLayer
} else {
descriptor.arrayLayerCount
},
}; };
let texture_view_id = self let texture_view_id = self
.global() .global()
.wgpu_id_hub() .wgpu_id_hub()
.lock() .lock()
.create_texture_view_id(self.device.0.backend()); .create_texture_view_id(self.device.id().0.backend());
let scope_id = self.device.use_current_scope();
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateTextureView { .send(WebGPURequest::CreateTextureView {
texture_id: self.texture.0, texture_id: self.texture.0,
texture_view_id, texture_view_id,
device_id: self.device.id().0,
descriptor: desc, descriptor: desc,
scope_id,
}) })
.expect("Failed to create WebGPU texture view"); .expect("Failed to create WebGPU texture view");

View file

@ -13,9 +13,9 @@ dictionary GPUTextureViewDescriptor : GPUObjectDescriptorBase {
GPUTextureViewDimension dimension; GPUTextureViewDimension dimension;
GPUTextureAspect aspect = "all"; GPUTextureAspect aspect = "all";
GPUIntegerCoordinate baseMipLevel = 0; GPUIntegerCoordinate baseMipLevel = 0;
GPUIntegerCoordinate mipLevelCount = 0; GPUIntegerCoordinate mipLevelCount;
GPUIntegerCoordinate baseArrayLayer = 0; GPUIntegerCoordinate baseArrayLayer = 0;
GPUIntegerCoordinate arrayLayerCount = 0; GPUIntegerCoordinate arrayLayerCount;
}; };
enum GPUTextureViewDimension { enum GPUTextureViewDimension {

View file

@ -43,7 +43,7 @@ pub enum WebGPUMsg {
FreeRenderBundle(RenderBundleId), FreeRenderBundle(RenderBundleId),
WebGPUOpResult { WebGPUOpResult {
device: WebGPUDevice, device: WebGPUDevice,
scope_id: u64, scope_id: Option<u64>,
pipeline_id: PipelineId, pipeline_id: PipelineId,
result: WebGPUOpResult, result: WebGPUOpResult,
}, },

View file

@ -73,6 +73,8 @@ pub enum WebGPURequest {
BufferMapComplete(id::BufferId), BufferMapComplete(id::BufferId),
CommandEncoderFinish { CommandEncoderFinish {
command_encoder_id: id::CommandEncoderId, command_encoder_id: id::CommandEncoderId,
device_id: id::DeviceId,
scope_id: Option<u64>,
// TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core // TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core
// wgpu::command::CommandBufferDescriptor, // wgpu::command::CommandBufferDescriptor,
}, },
@ -117,11 +119,13 @@ pub enum WebGPURequest {
}, },
CreateBuffer { CreateBuffer {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>,
buffer_id: id::BufferId, buffer_id: id::BufferId,
descriptor: wgt::BufferDescriptor<Option<String>>, descriptor: wgt::BufferDescriptor<Option<String>>,
}, },
CreateCommandEncoder { CreateCommandEncoder {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>,
// TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core // TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core
// wgpu::command::CommandEncoderDescriptor, // wgpu::command::CommandEncoderDescriptor,
command_encoder_id: id::CommandEncoderId, command_encoder_id: id::CommandEncoderId,
@ -148,11 +152,13 @@ pub enum WebGPURequest {
}, },
CreateSampler { CreateSampler {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>,
sampler_id: id::SamplerId, sampler_id: id::SamplerId,
descriptor: wgt::SamplerDescriptor<Option<String>>, descriptor: wgt::SamplerDescriptor<Option<String>>,
}, },
CreateShaderModule { CreateShaderModule {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>,
program_id: id::ShaderModuleId, program_id: id::ShaderModuleId,
program: Vec<u32>, program: Vec<u32>,
}, },
@ -166,12 +172,15 @@ pub enum WebGPURequest {
}, },
CreateTexture { CreateTexture {
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: Option<u64>,
texture_id: id::TextureId, texture_id: id::TextureId,
descriptor: wgt::TextureDescriptor<Option<String>>, descriptor: wgt::TextureDescriptor<Option<String>>,
}, },
CreateTextureView { CreateTextureView {
texture_id: id::TextureId, texture_id: id::TextureId,
texture_view_id: id::TextureViewId, texture_view_id: id::TextureViewId,
device_id: id::DeviceId,
scope_id: Option<u64>,
descriptor: wgt::TextureViewDescriptor<Option<String>>, descriptor: wgt::TextureViewDescriptor<Option<String>>,
}, },
DestroyBuffer(id::BufferId), DestroyBuffer(id::BufferId),
@ -186,6 +195,8 @@ pub enum WebGPURequest {
render_bundle_encoder: RenderBundleEncoder, render_bundle_encoder: RenderBundleEncoder,
descriptor: wgt::RenderBundleDescriptor<Option<String>>, descriptor: wgt::RenderBundleDescriptor<Option<String>>,
render_bundle_id: id::RenderBundleId, render_bundle_id: id::RenderBundleId,
device_id: id::DeviceId,
scope_id: Option<u64>,
}, },
RequestAdapter { RequestAdapter {
sender: IpcSender<WebGPUResponseResult>, sender: IpcSender<WebGPUResponseResult>,
@ -430,12 +441,17 @@ impl<'a> WGPU<'a> {
WebGPURequest::BufferMapComplete(buffer_id) => { WebGPURequest::BufferMapComplete(buffer_id) => {
self.buffer_maps.remove(&buffer_id); self.buffer_maps.remove(&buffer_id);
}, },
WebGPURequest::CommandEncoderFinish { command_encoder_id } => { WebGPURequest::CommandEncoderFinish {
command_encoder_id,
device_id,
scope_id,
} => {
let global = &self.global; let global = &self.global;
let _ = gfx_select!(command_encoder_id => global.command_encoder_finish( let result = gfx_select!(command_encoder_id => global.command_encoder_finish(
command_encoder_id, command_encoder_id,
&wgt::CommandBufferDescriptor::default() &wgt::CommandBufferDescriptor::default()
)); ));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CopyBufferToBuffer { WebGPURequest::CopyBufferToBuffer {
command_encoder_id, command_encoder_id,
@ -506,9 +522,7 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(bind_group_id => let result = gfx_select!(bind_group_id =>
global.device_create_bind_group(device_id, &descriptor, bind_group_id)); global.device_create_bind_group(device_id, &descriptor, bind_group_id));
if let Some(s_id) = scope_id { self.send_result(device_id, scope_id, result);
self.send_result(device_id, s_id, result);
}
}, },
WebGPURequest::CreateBindGroupLayout { WebGPURequest::CreateBindGroupLayout {
device_id, device_id,
@ -519,12 +533,11 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(bind_group_layout_id => let result = gfx_select!(bind_group_layout_id =>
global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id)); global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id));
if let Some(s_id) = scope_id { self.send_result(device_id, scope_id, result);
self.send_result(device_id, s_id, result);
}
}, },
WebGPURequest::CreateBuffer { WebGPURequest::CreateBuffer {
device_id, device_id,
scope_id,
buffer_id, buffer_id,
descriptor, descriptor,
} => { } => {
@ -537,11 +550,13 @@ impl<'a> WGPU<'a> {
}, },
None => ptr::null(), None => ptr::null(),
}; };
let _ = gfx_select!(buffer_id => let result = gfx_select!(buffer_id =>
global.device_create_buffer(device_id, &descriptor.map_label(|_| label), buffer_id)); global.device_create_buffer(device_id, &descriptor.map_label(|_| label), buffer_id));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateCommandEncoder { WebGPURequest::CreateCommandEncoder {
device_id, device_id,
scope_id,
command_encoder_id, command_encoder_id,
label, label,
} => { } => {
@ -555,8 +570,9 @@ impl<'a> WGPU<'a> {
None => ptr::null(), None => ptr::null(),
}; };
let desc = wgt::CommandEncoderDescriptor { label }; let desc = wgt::CommandEncoderDescriptor { label };
let _ = gfx_select!(command_encoder_id => let result = gfx_select!(command_encoder_id =>
global.device_create_command_encoder(device_id, &desc, command_encoder_id)); global.device_create_command_encoder(device_id, &desc, command_encoder_id));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateComputePipeline { WebGPURequest::CreateComputePipeline {
device_id, device_id,
@ -567,9 +583,7 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(compute_pipeline_id => let result = gfx_select!(compute_pipeline_id =>
global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id)); global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id));
if let Some(s_id) = scope_id { self.send_result(device_id, scope_id, result);
self.send_result(device_id, s_id, result);
}
}, },
WebGPURequest::CreateContext(sender) => { WebGPURequest::CreateContext(sender) => {
let id = self let id = self
@ -590,9 +604,7 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(pipeline_layout_id => let result = gfx_select!(pipeline_layout_id =>
global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id)); global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id));
if let Some(s_id) = scope_id { self.send_result(device_id, scope_id, result);
self.send_result(device_id, s_id, result);
}
}, },
//TODO: consider https://github.com/gfx-rs/wgpu/issues/684 //TODO: consider https://github.com/gfx-rs/wgpu/issues/684
WebGPURequest::CreateRenderPipeline { WebGPURequest::CreateRenderPipeline {
@ -604,12 +616,11 @@ impl<'a> WGPU<'a> {
let global = &self.global; let global = &self.global;
let result = gfx_select!(render_pipeline_id => let result = gfx_select!(render_pipeline_id =>
global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id)); global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id));
if let Some(s_id) = scope_id { self.send_result(device_id, scope_id, result);
self.send_result(device_id, s_id, result);
}
}, },
WebGPURequest::CreateSampler { WebGPURequest::CreateSampler {
device_id, device_id,
scope_id,
sampler_id, sampler_id,
descriptor, descriptor,
} => { } => {
@ -622,22 +633,25 @@ impl<'a> WGPU<'a> {
}, },
None => ptr::null(), None => ptr::null(),
}; };
let _ = gfx_select!(sampler_id => global.device_create_sampler( let result = gfx_select!(sampler_id => global.device_create_sampler(
device_id, device_id,
&descriptor.map_label(|_| label), &descriptor.map_label(|_| label),
sampler_id sampler_id
)); ));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateShaderModule { WebGPURequest::CreateShaderModule {
device_id, device_id,
scope_id,
program_id, program_id,
program, program,
} => { } => {
let global = &self.global; let global = &self.global;
let source = let source =
wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program)); wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program));
let _ = gfx_select!(program_id => let result = gfx_select!(program_id =>
global.device_create_shader_module(device_id, source, program_id)); global.device_create_shader_module(device_id, source, program_id));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateSwapChain { WebGPURequest::CreateSwapChain {
device_id, device_id,
@ -683,6 +697,7 @@ impl<'a> WGPU<'a> {
}, },
WebGPURequest::CreateTexture { WebGPURequest::CreateTexture {
device_id, device_id,
scope_id,
texture_id, texture_id,
descriptor, descriptor,
} => { } => {
@ -695,15 +710,18 @@ impl<'a> WGPU<'a> {
}, },
None => ptr::null(), None => ptr::null(),
}; };
let _ = gfx_select!(texture_id => global.device_create_texture( let result = gfx_select!(texture_id => global.device_create_texture(
device_id, device_id,
&descriptor.map_label(|_| label), &descriptor.map_label(|_| label),
texture_id texture_id
)); ));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::CreateTextureView { WebGPURequest::CreateTextureView {
texture_id, texture_id,
texture_view_id, texture_view_id,
device_id,
scope_id,
descriptor, descriptor,
} => { } => {
let global = &self.global; let global = &self.global;
@ -715,15 +733,16 @@ impl<'a> WGPU<'a> {
}, },
None => ptr::null(), None => ptr::null(),
}; };
let _ = gfx_select!(texture_view_id => global.texture_create_view( let result = gfx_select!(texture_view_id => global.texture_create_view(
texture_id, texture_id,
Some(&descriptor.map_label(|_| label)), Some(&descriptor.map_label(|_| label)),
texture_view_id texture_view_id
)); ));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::DestroyBuffer(buffer) => { WebGPURequest::DestroyBuffer(buffer) => {
let global = &self.global; let global = &self.global;
gfx_select!(buffer => global.buffer_destroy(buffer)); gfx_select!(buffer => global.buffer_destroy(buffer, false));
}, },
WebGPURequest::DestroySwapChain { WebGPURequest::DestroySwapChain {
external_id, external_id,
@ -737,10 +756,10 @@ impl<'a> WGPU<'a> {
.unwrap(); .unwrap();
let global = &self.global; let global = &self.global;
for b_id in data.available_buffer_ids.iter() { for b_id in data.available_buffer_ids.iter() {
gfx_select!(b_id => global.buffer_destroy(*b_id)); gfx_select!(b_id => global.buffer_destroy(*b_id, false));
} }
for b_id in data.queued_buffer_ids.iter() { for b_id in data.queued_buffer_ids.iter() {
gfx_select!(b_id => global.buffer_destroy(*b_id)); gfx_select!(b_id => global.buffer_destroy(*b_id, false));
} }
for b_id in data.unassigned_buffer_ids.iter() { for b_id in data.unassigned_buffer_ids.iter() {
if let Err(e) = self.script_sender.send(WebGPUMsg::FreeBuffer(*b_id)) { if let Err(e) = self.script_sender.send(WebGPUMsg::FreeBuffer(*b_id)) {
@ -779,6 +798,8 @@ impl<'a> WGPU<'a> {
render_bundle_encoder, render_bundle_encoder,
descriptor, descriptor,
render_bundle_id, render_bundle_id,
device_id,
scope_id,
} => { } => {
let global = &self.global; let global = &self.global;
let st; let st;
@ -789,11 +810,12 @@ impl<'a> WGPU<'a> {
}, },
None => ptr::null(), None => ptr::null(),
}; };
let _ = gfx_select!(render_bundle_id => global.render_bundle_encoder_finish( let result = gfx_select!(render_bundle_id => global.render_bundle_encoder_finish(
render_bundle_encoder, render_bundle_encoder,
&descriptor.map_label(|_| label), &descriptor.map_label(|_| label),
render_bundle_id render_bundle_id
)); ));
self.send_result(device_id, scope_id, result);
}, },
WebGPURequest::RequestAdapter { WebGPURequest::RequestAdapter {
sender, sender,
@ -1088,7 +1110,8 @@ impl<'a> WGPU<'a> {
data, data,
} => { } => {
let global = &self.global; let global = &self.global;
gfx_select!(queue_id => global.queue_write_buffer( //TODO: Report result to content process
let _ = gfx_select!(queue_id => global.queue_write_buffer(
queue_id, queue_id,
buffer_id, buffer_id,
buffer_offset as wgt::BufferAddress, buffer_offset as wgt::BufferAddress,
@ -1103,7 +1126,8 @@ impl<'a> WGPU<'a> {
data, data,
} => { } => {
let global = &self.global; let global = &self.global;
gfx_select!(queue_id => global.queue_write_texture( //TODO: Report result to content process
let _ = gfx_select!(queue_id => global.queue_write_texture(
queue_id, queue_id,
&texture_cv, &texture_cv,
&data, &data,
@ -1119,7 +1143,7 @@ impl<'a> WGPU<'a> {
fn send_result<U: id::TypedId, T: std::fmt::Debug>( fn send_result<U: id::TypedId, T: std::fmt::Debug>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
scope_id: u64, scope_id: Option<u64>,
result: Result<U, T>, result: Result<U, T>,
) { ) {
let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap(); let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();
@ -1128,7 +1152,12 @@ impl<'a> WGPU<'a> {
scope_id, scope_id,
pipeline_id, pipeline_id,
result: if let Err(e) = result { result: if let Err(e) = result {
WebGPUOpResult::ValidationError(format!("{:?}", e)) let err = format!("{:?}", e);
if err.contains("OutOfMemory") {
WebGPUOpResult::OutOfMemoryError
} else {
WebGPUOpResult::ValidationError(err)
}
} else { } else {
WebGPUOpResult::Success WebGPUOpResult::Success
}, },

View file

@ -34,6 +34,7 @@ packages = [
"cocoa", "cocoa",
"gleam", "gleam",
"libloading", "libloading",
"metal",
"miniz_oxide", "miniz_oxide",
"parking_lot", "parking_lot",
"parking_lot_core", "parking_lot_core",