Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions cts_runner/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_d
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float"
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float-stencil8"
webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="stencil8"
// Fails with OOM in CI.
fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:*
webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="1d"
webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="2d"
Expand Down Expand Up @@ -54,12 +53,11 @@ webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribu

webgpu:api,validation,buffer,create:*
webgpu:api,validation,buffer,destroy:*
// Limit tests fail with OOM in CI.
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,*
webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,*
//FAIL: other `maxInterStageShaderVariables` cases w/ limitTest ∈ [underDefault, overMaximum]
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="atDefault";*
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="atMaximum";*
fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="betweenDefaultAndMaximum";*
webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="atDefault";*
webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="atMaximum";*
webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="betweenDefaultAndMaximum";*
Comment on lines +58 to +60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Is it feasible to simplify to …:createRenderPipeline,at_over:*?

webgpu:api,validation,createBindGroup:binding_must_contain_resource_defined_in_layout:*
webgpu:api,validation,createBindGroup:buffer_offset_and_size_for_bind_groups_match:*
webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*
Expand Down Expand Up @@ -150,8 +148,7 @@ fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and
webgpu:api,validation,image_copy,buffer_texture_copies:sample_count:*
webgpu:api,validation,image_copy,buffer_texture_copies:texture_buffer_usages:*
webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:*
// Fails with OOM in CI.
fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:*
webgpu:api,validation,image_copy,layout_related:offset_alignment:*
webgpu:api,validation,image_copy,texture_related:*
webgpu:api,validation,queue,buffer_mapped:copyBufferToBuffer:*
webgpu:api,validation,queue,buffer_mapped:copyBufferToTexture:*
Expand Down
57 changes: 46 additions & 11 deletions deno_webgpu/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use deno_core::V8TaskSpawner;
use deno_core::WebIDL;

use super::device::GPUDevice;
use super::device::DEVICE_EXTERNAL_MEMORY_SIZE;
use super::queue::GPUQueue;
use crate::error::GPUGenericError;
use crate::webidl::features_to_feature_names;
use crate::webidl::GPUFeatureName;
Expand Down Expand Up @@ -160,24 +162,46 @@ impl GPUAdapter {
None,
)?;

// Associate external memory with the device to encourage V8 to garbage
// collect devices promptly.
scope
.adjust_amount_of_external_allocated_memory(DEVICE_EXTERNAL_MEMORY_SIZE);
Comment on lines +165 to +168
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I wonder if we could do that in servo too.


let spawner = state.borrow::<V8TaskSpawner>().clone();
let lost_resolver = v8::PromiseResolver::new(scope).unwrap();
let lost_promise = lost_resolver.get_promise(scope);
let error_handler = Rc::new(super::error::DeviceErrorHandler::new(
v8::Global::new(scope, lost_resolver),
spawner,
));

// Create the queue object eagerly so that the wgpu-core queue resource
// gets cleaned up when the device is garbage collected, even if JS code
// never accesses the queue property.
let queue_obj = deno_core::cppgc::make_cppgc_object(
scope,
GPUQueue {
instance: self.instance.clone(),
error_handler: error_handler.clone(),
label: descriptor.label.clone(),
id: queue,
device,
},
);
let queue_obj = v8::Global::new(scope, queue_obj);

let device = GPUDevice {
instance: self.instance.clone(),
id: device,
queue,
label: descriptor.label,
queue_obj: SameObject::new(),
queue_obj,
adapter_info: self.info.clone(),
error_handler: Rc::new(super::error::DeviceErrorHandler::new(
v8::Global::new(scope, lost_resolver),
spawner,
)),
error_handler,
adapter: self.id,
lost_promise: v8::Global::new(scope, lost_promise),
limits: SameObject::new(),
features: SameObject::new(),
weak: std::sync::OnceLock::new(),
};
let device = deno_core::cppgc::make_cppgc_object(scope, device);
let weak_device = v8::Weak::new(scope, device);
Expand All @@ -190,13 +214,24 @@ impl GPUAdapter {
let null = v8::null(scope);
set_event_target_data.call(scope, null.into(), &[device.into()]);

let finalizer = v8::Weak::with_finalizer(
scope,
device,
Box::new(move |isolate| {
isolate.adjust_amount_of_external_allocated_memory(
-DEVICE_EXTERNAL_MEMORY_SIZE,
);
}),
);

// Now that the device is fully constructed, give the error handler a
// weak reference to it.
// weak reference to it, and store the finalizer weak reference.
let device = device.cast::<v8::Value>();
deno_core::cppgc::try_unwrap_cppgc_object::<GPUDevice>(scope, device)
.unwrap()
.error_handler
.set_device(weak_device);
let device_ref =
deno_core::cppgc::try_unwrap_cppgc_object::<GPUDevice>(scope, device)
.unwrap();
device_ref.error_handler.set_device(weak_device);
device_ref.weak.set(finalizer).unwrap();

Ok(v8::Global::new(scope, device))
}
Expand Down
22 changes: 11 additions & 11 deletions deno_webgpu/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use super::bind_group_layout::GPUBindGroupLayout;
use super::buffer::GPUBuffer;
use super::compute_pipeline::GPUComputePipeline;
use super::pipeline_layout::GPUPipelineLayout;
use super::queue::GPUQueue;
use super::sampler::GPUSampler;
use super::shader::GPUShaderModule;
use super::texture::GPUTexture;
Expand All @@ -38,22 +37,29 @@ use crate::shader::GPUCompilationInfo;
use crate::webidl::features_to_feature_names;
use crate::Instance;

/// External memory associated with device and queue, to encourage V8 to garbage
/// collect devices promptly. This seems to be particularly important on DX12
/// in CI, where any smaller power of two results in OOM errors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: This is a crate sync'd between here and Deno upstream, so clarifying whose CI is failing here might be important.

pub(crate) const DEVICE_EXTERNAL_MEMORY_SIZE: i64 = 1 << 24; // 16 MB

pub struct GPUDevice {
pub instance: Instance,
pub id: wgpu_core::id::DeviceId,
pub adapter: wgpu_core::id::AdapterId,
pub queue: wgpu_core::id::QueueId,

pub label: String,

pub features: SameObject<GPUSupportedFeatures>,
pub limits: SameObject<GPUSupportedLimits>,
pub adapter_info: Rc<SameObject<GPUAdapterInfo>>,

pub queue_obj: SameObject<GPUQueue>,
pub queue_obj: v8::Global<v8::Object>,

pub error_handler: super::error::ErrorHandler,
pub lost_promise: v8::Global<v8::Promise>,

// Weak reference to the JS object so we can attach a finalizer.
pub(crate) weak: std::sync::OnceLock<v8::Weak<v8::Object>>,
}

impl Drop for GPUDevice {
Expand Down Expand Up @@ -126,14 +132,8 @@ impl GPUDevice {

#[getter]
#[global]
fn queue(&self, scope: &mut v8::HandleScope) -> v8::Global<v8::Object> {
self.queue_obj.get(scope, |_| GPUQueue {
id: self.queue,
device: self.id,
error_handler: self.error_handler.clone(),
instance: self.instance.clone(),
label: self.label.clone(),
})
fn queue(&self) -> v8::Global<v8::Object> {
self.queue_obj.clone()
}

#[fast]
Expand Down