fix(deno): cleanup resources when closed (#3530)

This commit is contained in:
Leo Kettmeir 2023-03-03 13:18:01 -04:00 committed by GitHub
parent ac689cbe1f
commit 710fc553d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 297 additions and 131 deletions

View File

@ -7,21 +7,38 @@ use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult;
pub(crate) struct WebGpuBindGroupLayout(pub(crate) wgpu_core::id::BindGroupLayoutId);
pub(crate) struct WebGpuBindGroupLayout(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::BindGroupLayoutId,
);
impl Resource for WebGpuBindGroupLayout {
fn name(&self) -> Cow<str> {
"webGPUBindGroupLayout".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.bind_group_layout_drop(self.1));
}
}
pub(crate) struct WebGpuBindGroup(pub(crate) wgpu_core::id::BindGroupId);
pub(crate) struct WebGpuBindGroup(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::BindGroupId,
);
impl Resource for WebGpuBindGroup {
fn name(&self) -> Cow<str> {
"webGPUBindGroup".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.bind_group_drop(self.1));
}
}
#[derive(Deserialize)]
@ -170,7 +187,7 @@ pub fn op_webgpu_create_bind_group_layout(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let entries = entries
.into_iter()
@ -207,13 +224,13 @@ pub fn op_webgpu_create_pipeline_layout(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let bind_group_layouts = bind_group_layouts
.into_iter()
.map(|rid| {
let bind_group_layout = state.resource_table.get::<WebGpuBindGroupLayout>(rid)?;
Ok(bind_group_layout.0)
Ok(bind_group_layout.1)
})
.collect::<Result<Vec<_>, AnyError>>()?;
@ -252,7 +269,7 @@ pub fn op_webgpu_create_bind_group(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let entries = entries
.into_iter()
@ -264,7 +281,7 @@ pub fn op_webgpu_create_bind_group(
let sampler_resource = state
.resource_table
.get::<super::sampler::WebGpuSampler>(entry.resource)?;
wgpu_core::binding_model::BindingResource::Sampler(sampler_resource.0)
wgpu_core::binding_model::BindingResource::Sampler(sampler_resource.1)
}
"GPUTextureView" => {
let texture_view_resource =
@ -272,7 +289,7 @@ pub fn op_webgpu_create_bind_group(
.resource_table
.get::<super::texture::WebGpuTextureView>(entry.resource)?;
wgpu_core::binding_model::BindingResource::TextureView(
texture_view_resource.0,
texture_view_resource.1,
)
}
"GPUBufferBinding" => {
@ -281,7 +298,7 @@ pub fn op_webgpu_create_bind_group(
.get::<super::buffer::WebGpuBuffer>(entry.resource)?;
wgpu_core::binding_model::BindingResource::Buffer(
wgpu_core::binding_model::BufferBinding {
buffer_id: buffer_resource.0,
buffer_id: buffer_resource.1,
offset: entry.offset.unwrap_or(0),
size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)),
},
@ -297,7 +314,7 @@ pub fn op_webgpu_create_bind_group(
let descriptor = wgpu_core::binding_model::BindGroupDescriptor {
label: label.map(Cow::from),
layout: bind_group_layout.0,
layout: bind_group_layout.1,
entries: Cow::from(entries),
};

View File

@ -18,11 +18,19 @@ use wgpu_core::resource::BufferAccessResult;
use super::error::DomExceptionOperationError;
use super::error::WebGpuResult;
pub(crate) struct WebGpuBuffer(pub(crate) wgpu_core::id::BufferId);
pub(crate) struct WebGpuBuffer(
pub(crate) super::Instance,
pub(crate) wgpu_core::id::BufferId,
);
impl Resource for WebGpuBuffer {
fn name(&self) -> Cow<str> {
"webGPUBuffer".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.buffer_drop(self.1, true));
}
}
struct WebGpuBufferMapped(*mut u8, usize);
@ -45,7 +53,7 @@ pub fn op_webgpu_create_buffer(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let descriptor = wgpu_core::resource::BufferDescriptor {
label: label.map(Cow::from),
@ -78,11 +86,11 @@ pub async fn op_webgpu_buffer_get_map_async(
let state_ = state.borrow();
let instance = state_.borrow::<super::Instance>();
let buffer_resource = state_.resource_table.get::<WebGpuBuffer>(buffer_rid)?;
let buffer = buffer_resource.0;
let buffer = buffer_resource.1;
let device_resource = state_
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
device = device_resource.0;
device = device_resource.1;
let callback = Box::new(move |status| {
sender.send(status).unwrap();
@ -145,7 +153,7 @@ pub fn op_webgpu_buffer_get_mapped_range(
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let buffer_resource = state.resource_table.get::<WebGpuBuffer>(buffer_rid)?;
let buffer = buffer_resource.0;
let buffer = buffer_resource.1;
let (slice_pointer, range_size) = gfx_select!(buffer => instance.buffer_get_mapped_range(
buffer,
@ -176,7 +184,7 @@ pub fn op_webgpu_buffer_unmap(
.take::<WebGpuBufferMapped>(mapped_rid)?;
let instance = state.borrow::<super::Instance>();
let buffer_resource = state.resource_table.get::<WebGpuBuffer>(buffer_rid)?;
let buffer = buffer_resource.0;
let buffer = buffer_resource.1;
if let Some(buf) = buf {
let slice = unsafe { std::slice::from_raw_parts_mut(mapped_resource.0, mapped_resource.1) };

View File

@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::error::{type_error, AnyError};
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op;
use deno_core::OpState;
use deno_core::Resource;
@ -20,11 +21,19 @@ impl Resource for WebGpuRenderBundleEncoder {
}
}
pub(crate) struct WebGpuRenderBundle(pub(crate) wgpu_core::id::RenderBundleId);
pub(crate) struct WebGpuRenderBundle(
pub(crate) super::Instance,
pub(crate) wgpu_core::id::RenderBundleId,
);
impl Resource for WebGpuRenderBundle {
fn name(&self) -> Cow<str> {
"webGPURenderBundle".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.render_bundle_drop(self.1));
}
}
#[derive(Deserialize)]
@ -47,7 +56,7 @@ pub fn op_webgpu_create_render_bundle_encoder(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let depth_stencil =
args.depth_stencil_format
@ -148,7 +157,7 @@ pub fn op_webgpu_render_bundle_encoder_set_bind_group(
wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group(
&mut render_bundle_encoder_resource.0.borrow_mut(),
index,
bind_group_resource.0,
bind_group_resource.1,
dynamic_offsets_data.as_ptr(),
dynamic_offsets_data.len(),
);
@ -234,7 +243,7 @@ pub fn op_webgpu_render_bundle_encoder_set_pipeline(
wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline(
&mut render_bundle_encoder_resource.0.borrow_mut(),
render_pipeline_resource.0,
render_pipeline_resource.1,
);
Ok(WebGpuResult::empty())
@ -262,7 +271,7 @@ pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
render_bundle_encoder_resource
.0
.borrow_mut()
.set_index_buffer(buffer_resource.0, index_format, offset, size);
.set_index_buffer(buffer_resource.1, index_format, offset, size);
Ok(WebGpuResult::empty())
}
@ -294,7 +303,7 @@ pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer(
wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer(
&mut render_bundle_encoder_resource.0.borrow_mut(),
slot,
buffer_resource.0,
buffer_resource.1,
offset,
size,
);
@ -368,7 +377,7 @@ pub fn op_webgpu_render_bundle_encoder_draw_indirect(
wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect(
&mut render_bundle_encoder_resource.0.borrow_mut(),
buffer_resource.0,
buffer_resource.1,
indirect_offset,
);

View File

@ -9,21 +9,40 @@ use serde::Deserialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::num::NonZeroU32;
use std::rc::Rc;
use super::error::WebGpuResult;
pub(crate) struct WebGpuCommandEncoder(pub(crate) wgpu_core::id::CommandEncoderId);
pub(crate) struct WebGpuCommandEncoder(
pub(crate) super::Instance,
pub(crate) wgpu_core::id::CommandEncoderId, // TODO: should maybe be option?
);
impl Resource for WebGpuCommandEncoder {
fn name(&self) -> Cow<str> {
"webGPUCommandEncoder".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.command_encoder_drop(self.1));
}
}
pub(crate) struct WebGpuCommandBuffer(pub(crate) wgpu_core::id::CommandBufferId);
pub(crate) struct WebGpuCommandBuffer(
pub(crate) super::Instance,
pub(crate) RefCell<Option<wgpu_core::id::CommandBufferId>>,
);
impl Resource for WebGpuCommandBuffer {
fn name(&self) -> Cow<str> {
"webGPUCommandBuffer".into()
}
fn close(self: Rc<Self>) {
if let Some(id) = *self.1.borrow() {
let instance = &self.0;
gfx_select!(id => instance.command_buffer_drop(id));
}
}
}
#[op]
@ -36,7 +55,7 @@ pub fn op_webgpu_create_command_encoder(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let descriptor = wgpu_types::CommandEncoderDescriptor {
label: label.map(Cow::from),
@ -101,10 +120,10 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
.get::<super::texture::WebGpuTextureView>(rid)
})
.transpose()?
.map(|texture| texture.0);
.map(|texture| texture.1);
Some(wgpu_core::command::RenderPassColorAttachment {
view: texture_view_resource.0,
view: texture_view_resource.1,
resolve_target,
channel: wgpu_core::command::PassChannel {
load_op: at.load_op,
@ -129,7 +148,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
processed_depth_stencil_attachment =
Some(wgpu_core::command::RenderPassDepthStencilAttachment {
view: texture_view_resource.0,
view: texture_view_resource.1,
depth: wgpu_core::command::PassChannel {
load_op: attachment
.depth_load_op
@ -159,7 +178,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
depth_stencil_attachment: processed_depth_stencil_attachment.as_ref(),
};
let render_pass = wgpu_core::command::RenderPass::new(command_encoder_resource.0, &descriptor);
let render_pass = wgpu_core::command::RenderPass::new(command_encoder_resource.1, &descriptor);
let rid = state
.resource_table
@ -185,7 +204,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass(
};
let compute_pass =
wgpu_core::command::ComputePass::new(command_encoder_resource.0, &descriptor);
wgpu_core::command::ComputePass::new(command_encoder_resource.1, &descriptor);
let rid = state
.resource_table
@ -210,15 +229,15 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let source_buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(source)?;
let source_buffer = source_buffer_resource.0;
let source_buffer = source_buffer_resource.1;
let destination_buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(destination)?;
let destination_buffer = destination_buffer_resource.0;
let destination_buffer = destination_buffer_resource.1;
gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_buffer(
command_encoder,
@ -260,7 +279,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let source_buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(source.buffer)?;
@ -269,7 +288,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
.get::<super::texture::WebGpuTexture>(destination.texture)?;
let source = wgpu_core::command::ImageCopyBuffer {
buffer: source_buffer_resource.0,
buffer: source_buffer_resource.1,
layout: wgpu_types::ImageDataLayout {
offset: source.offset,
bytes_per_row: NonZeroU32::new(source.bytes_per_row.unwrap_or(0)),
@ -277,7 +296,7 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
},
};
let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0,
texture: destination_texture_resource.id,
mip_level: destination.mip_level,
origin: destination.origin,
aspect: destination.aspect,
@ -302,7 +321,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let source_texture_resource = state
.resource_table
.get::<super::texture::WebGpuTexture>(source.texture)?;
@ -311,13 +330,13 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
.get::<super::buffer::WebGpuBuffer>(destination.buffer)?;
let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0,
texture: source_texture_resource.id,
mip_level: source.mip_level,
origin: source.origin,
aspect: source.aspect,
};
let destination = wgpu_core::command::ImageCopyBuffer {
buffer: destination_buffer_resource.0,
buffer: destination_buffer_resource.1,
layout: wgpu_types::ImageDataLayout {
offset: destination.offset,
bytes_per_row: NonZeroU32::new(destination.bytes_per_row.unwrap_or(0)),
@ -344,7 +363,7 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let source_texture_resource = state
.resource_table
.get::<super::texture::WebGpuTexture>(source.texture)?;
@ -353,13 +372,13 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture(
.get::<super::texture::WebGpuTexture>(destination.texture)?;
let source = wgpu_core::command::ImageCopyTexture {
texture: source_texture_resource.0,
texture: source_texture_resource.id,
mip_level: source.mip_level,
origin: source.origin,
aspect: source.aspect,
};
let destination = wgpu_core::command::ImageCopyTexture {
texture: destination_texture_resource.0,
texture: destination_texture_resource.id,
mip_level: destination.mip_level,
origin: destination.origin,
aspect: destination.aspect,
@ -384,14 +403,14 @@ pub fn op_webgpu_command_encoder_clear_buffer(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let destination_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(buffer_rid)?;
gfx_ok!(command_encoder => instance.command_encoder_clear_buffer(
command_encoder,
destination_resource.0,
destination_resource.1,
offset,
std::num::NonZeroU64::new(size)
))
@ -407,7 +426,7 @@ pub fn op_webgpu_command_encoder_push_debug_group(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
gfx_ok!(command_encoder => instance.command_encoder_push_debug_group(command_encoder, &group_label))
}
@ -421,7 +440,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
gfx_ok!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder))
}
@ -436,7 +455,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
gfx_ok!(command_encoder => instance.command_encoder_insert_debug_marker(
command_encoder,
@ -455,14 +474,14 @@ pub fn op_webgpu_command_encoder_write_timestamp(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let query_set_resource = state
.resource_table
.get::<super::WebGpuQuerySet>(query_set)?;
gfx_ok!(command_encoder => instance.command_encoder_write_timestamp(
command_encoder,
query_set_resource.0,
query_set_resource.1,
query_index
))
}
@ -481,7 +500,7 @@ pub fn op_webgpu_command_encoder_resolve_query_set(
let command_encoder_resource = state
.resource_table
.get::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let query_set_resource = state
.resource_table
.get::<super::WebGpuQuerySet>(query_set)?;
@ -491,10 +510,10 @@ pub fn op_webgpu_command_encoder_resolve_query_set(
gfx_ok!(command_encoder => instance.command_encoder_resolve_query_set(
command_encoder,
query_set_resource.0,
query_set_resource.1,
first_query,
query_count,
destination_resource.0,
destination_resource.1,
destination_offset
))
}
@ -508,15 +527,22 @@ pub fn op_webgpu_command_encoder_finish(
let command_encoder_resource = state
.resource_table
.take::<WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let instance = state.borrow::<super::Instance>();
let descriptor = wgpu_types::CommandBufferDescriptor {
label: label.map(Cow::from),
};
gfx_put!(command_encoder => instance.command_encoder_finish(
command_encoder,
&descriptor
) => state, WebGpuCommandBuffer)
let (val, maybe_err) = gfx_select!(command_encoder => instance.command_encoder_finish(
command_encoder,
&descriptor
));
let rid = state.resource_table.add(WebGpuCommandBuffer(
instance.clone(),
RefCell::new(Some(val)),
));
Ok(WebGpuResult::rid_err(rid, maybe_err))
}

View File

@ -33,7 +33,7 @@ pub fn op_webgpu_compute_pass_set_pipeline(
wgpu_core::command::compute_ffi::wgpu_compute_pass_set_pipeline(
&mut compute_pass_resource.0.borrow_mut(),
compute_pipeline_resource.0,
compute_pipeline_resource.1,
);
Ok(WebGpuResult::empty())
@ -77,7 +77,7 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups_indirect(
wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_workgroups_indirect(
&mut compute_pass_resource.0.borrow_mut(),
buffer_resource.0,
buffer_resource.1,
indirect_offset,
);
@ -100,7 +100,7 @@ pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query(
wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query(
&mut compute_pass_resource.0.borrow_mut(),
query_set_resource.0,
query_set_resource.1,
query_index,
);
@ -139,7 +139,7 @@ pub fn op_webgpu_compute_pass_write_timestamp(
wgpu_core::command::compute_ffi::wgpu_compute_pass_write_timestamp(
&mut compute_pass_resource.0.borrow_mut(),
query_set_resource.0,
query_set_resource.1,
query_index,
);
@ -156,7 +156,7 @@ pub fn op_webgpu_compute_pass_end(
state
.resource_table
.get::<super::command_encoder::WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let compute_pass_resource = state
.resource_table
.take::<WebGpuComputePass>(compute_pass_rid)?;
@ -209,7 +209,7 @@ pub fn op_webgpu_compute_pass_set_bind_group(
wgpu_core::command::compute_ffi::wgpu_compute_pass_set_bind_group(
&mut compute_pass_resource.0.borrow_mut(),
index,
bind_group_resource.0,
bind_group_resource.1,
dynamic_offsets_data.as_ptr(),
dynamic_offsets_data.len(),
);

View File

@ -52,7 +52,7 @@ mod macros {
macro_rules! gfx_put {
($id:expr => $global:ident.$method:ident( $($param:expr),* ) => $state:expr, $rc:expr) => {{
let (val, maybe_err) = gfx_select!($id => $global.$method($($param),*));
let rid = $state.resource_table.add($rc(val));
let rid = $state.resource_table.add($rc($global.clone(), val));
Ok(WebGpuResult::rid_err(rid, maybe_err))
}};
}
@ -93,27 +93,42 @@ fn check_unstable(state: &OpState, api_name: &str) {
}
}
pub type Instance = wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>;
pub type Instance = std::sync::Arc<wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>>;
struct WebGpuAdapter(wgpu_core::id::AdapterId);
struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId);
impl Resource for WebGpuAdapter {
fn name(&self) -> Cow<str> {
"webGPUAdapter".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.adapter_drop(self.1));
}
}
struct WebGpuDevice(wgpu_core::id::DeviceId);
struct WebGpuDevice(Instance, wgpu_core::id::DeviceId);
impl Resource for WebGpuDevice {
fn name(&self) -> Cow<str> {
"webGPUDevice".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.device_drop(self.1));
}
}
struct WebGpuQuerySet(wgpu_core::id::QuerySetId);
struct WebGpuQuerySet(Instance, wgpu_core::id::QuerySetId);
impl Resource for WebGpuQuerySet {
fn name(&self) -> Cow<str> {
"webGPUQuerySet".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.query_set_drop(self.1));
}
}
pub fn init(unstable: bool) -> Extension {
@ -298,14 +313,14 @@ pub async fn op_webgpu_request_adapter(
let instance = if let Some(instance) = state.try_borrow::<Instance>() {
instance
} else {
state.put(wgpu_core::hub::Global::new(
state.put(std::sync::Arc::new(wgpu_core::hub::Global::new(
"webgpu",
wgpu_core::hub::IdentityManagerFactory,
wgpu_types::InstanceDescriptor {
backends,
dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc,
},
));
)));
state.borrow::<Instance>()
};
@ -331,7 +346,9 @@ pub async fn op_webgpu_request_adapter(
let features = deserialize_features(&adapter_features);
let adapter_limits = gfx_select!(adapter => instance.adapter_limits(adapter))?;
let rid = state.resource_table.add(WebGpuAdapter(adapter));
let instance = instance.clone();
let rid = state.resource_table.add(WebGpuAdapter(instance, adapter));
Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice {
rid,
@ -531,7 +548,7 @@ pub async fn op_webgpu_request_device(
) -> Result<GpuAdapterDevice, AnyError> {
let mut state = state.borrow_mut();
let adapter_resource = state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
let adapter = adapter_resource.0;
let adapter = adapter_resource.1;
let instance = state.borrow::<Instance>();
let descriptor = wgpu_types::DeviceDescriptor {
@ -554,7 +571,8 @@ pub async fn op_webgpu_request_device(
let features = deserialize_features(&device_features);
let limits = gfx_select!(device => instance.device_limits(device))?;
let rid = state.resource_table.add(WebGpuDevice(device));
let instance = instance.clone();
let rid = state.resource_table.add(WebGpuDevice(instance, device));
Ok(GpuAdapterDevice {
rid,
@ -581,7 +599,7 @@ pub async fn op_webgpu_request_adapter_info(
) -> Result<GPUAdapterInfo, AnyError> {
let state = state.borrow_mut();
let adapter_resource = state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
let adapter = adapter_resource.0;
let adapter = adapter_resource.1;
let instance = state.borrow::<Instance>();
let info = gfx_select!(adapter => instance.adapter_get_info(adapter))?;
@ -655,8 +673,8 @@ pub fn op_webgpu_create_query_set(
args: CreateQuerySetArgs,
) -> Result<WebGpuResult, AnyError> {
let device_resource = state.resource_table.get::<WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let instance = &state.borrow::<Instance>();
let device = device_resource.1;
let instance = state.borrow::<Instance>();
let descriptor = wgpu_types::QuerySetDescriptor {
label: args.label.map(Cow::from),

View File

@ -8,31 +8,56 @@ use deno_core::ResourceId;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuError;
use super::error::WebGpuResult;
const MAX_BIND_GROUPS: usize = 8;
pub(crate) struct WebGpuPipelineLayout(pub(crate) wgpu_core::id::PipelineLayoutId);
pub(crate) struct WebGpuPipelineLayout(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::PipelineLayoutId,
);
impl Resource for WebGpuPipelineLayout {
fn name(&self) -> Cow<str> {
"webGPUPipelineLayout".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.pipeline_layout_drop(self.1));
}
}
pub(crate) struct WebGpuComputePipeline(pub(crate) wgpu_core::id::ComputePipelineId);
pub(crate) struct WebGpuComputePipeline(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::ComputePipelineId,
);
impl Resource for WebGpuComputePipeline {
fn name(&self) -> Cow<str> {
"webGPUComputePipeline".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.compute_pipeline_drop(self.1));
}
}
pub(crate) struct WebGpuRenderPipeline(pub(crate) wgpu_core::id::RenderPipelineId);
pub(crate) struct WebGpuRenderPipeline(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::RenderPipelineId,
);
impl Resource for WebGpuRenderPipeline {
fn name(&self) -> Cow<str> {
"webGPURenderPipeline".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.render_pipeline_drop(self.1));
}
}
#[derive(Deserialize)]
@ -68,12 +93,12 @@ pub fn op_webgpu_create_compute_pipeline(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let pipeline_layout = match layout {
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(rid) => {
let id = state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
Some(id.0)
Some(id.1)
}
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => None,
};
@ -86,7 +111,7 @@ pub fn op_webgpu_create_compute_pipeline(
label: label.map(Cow::from),
layout: pipeline_layout,
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: compute_shader_module_resource.0,
module: compute_shader_module_resource.1,
entry_point: Cow::from(compute.entry_point),
// TODO(lucacasonato): support args.compute.constants
},
@ -110,7 +135,7 @@ pub fn op_webgpu_create_compute_pipeline(
let rid = state
.resource_table
.add(WebGpuComputePipeline(compute_pipeline));
.add(WebGpuComputePipeline(instance.clone(), compute_pipeline));
Ok(WebGpuResult::rid_err(rid, maybe_err))
}
@ -133,7 +158,7 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
let compute_pipeline_resource = state
.resource_table
.get::<WebGpuComputePipeline>(compute_pipeline_rid)?;
let compute_pipeline = compute_pipeline_resource.0;
let compute_pipeline = compute_pipeline_resource.1;
let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, ()));
@ -142,7 +167,10 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
let rid = state
.resource_table
.add(super::binding::WebGpuBindGroupLayout(bind_group_layout));
.add(super::binding::WebGpuBindGroupLayout(
instance.clone(),
bind_group_layout,
));
Ok(PipelineLayout {
rid,
@ -304,12 +332,12 @@ pub fn op_webgpu_create_render_pipeline(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let layout = match args.layout {
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(rid) => {
let pipeline_layout_resource = state.resource_table.get::<WebGpuPipelineLayout>(rid)?;
Some(pipeline_layout_resource.0)
Some(pipeline_layout_resource.1)
}
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => None,
};
@ -326,7 +354,7 @@ pub fn op_webgpu_create_render_pipeline(
Some(wgpu_core::pipeline::FragmentState {
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: fragment_shader_module_resource.0,
module: fragment_shader_module_resource.1,
entry_point: Cow::from(fragment.entry_point),
},
targets: Cow::from(fragment.targets),
@ -348,7 +376,7 @@ pub fn op_webgpu_create_render_pipeline(
layout,
vertex: wgpu_core::pipeline::VertexState {
stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: vertex_shader_module_resource.0,
module: vertex_shader_module_resource.1,
entry_point: Cow::Owned(args.vertex.entry_point),
},
buffers: Cow::Owned(vertex_buffers),
@ -379,7 +407,7 @@ pub fn op_webgpu_create_render_pipeline(
let rid = state
.resource_table
.add(WebGpuRenderPipeline(render_pipeline));
.add(WebGpuRenderPipeline(instance.clone(), render_pipeline));
Ok(WebGpuResult::rid_err(rid, maybe_err))
}
@ -394,7 +422,7 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout(
let render_pipeline_resource = state
.resource_table
.get::<WebGpuRenderPipeline>(render_pipeline_rid)?;
let render_pipeline = render_pipeline_resource.0;
let render_pipeline = render_pipeline_resource.1;
let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, index, ()));
@ -403,7 +431,10 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout(
let rid = state
.resource_table
.add(super::binding::WebGpuBindGroupLayout(bind_group_layout));
.add(super::binding::WebGpuBindGroupLayout(
instance.clone(),
bind_group_layout,
));
Ok(PipelineLayout {
rid,

View File

@ -21,7 +21,7 @@ pub fn op_webgpu_queue_submit(
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
let queue = queue_resource.0;
let queue = queue_resource.1;
let ids = command_buffers
.iter()
@ -29,7 +29,8 @@ pub fn op_webgpu_queue_submit(
let buffer_resource = state
.resource_table
.get::<super::command_encoder::WebGpuCommandBuffer>(*rid)?;
Ok(buffer_resource.0)
let mut id = buffer_resource.1.borrow_mut();
Ok(id.take().unwrap())
})
.collect::<Result<Vec<_>, AnyError>>()?;
@ -74,9 +75,9 @@ pub fn op_webgpu_write_buffer(
let buffer_resource = state
.resource_table
.get::<super::buffer::WebGpuBuffer>(buffer)?;
let buffer = buffer_resource.0;
let buffer = buffer_resource.1;
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
let queue = queue_resource.0;
let queue = queue_resource.1;
let data = match size {
Some(size) => &buf[data_offset..(data_offset + size)],
@ -107,10 +108,10 @@ pub fn op_webgpu_write_texture(
.resource_table
.get::<super::texture::WebGpuTexture>(destination.texture)?;
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
let queue = queue_resource.0;
let queue = queue_resource.1;
let destination = wgpu_core::command::ImageCopyTexture {
texture: texture_resource.0,
texture: texture_resource.id,
mip_level: destination.mip_level,
origin: destination.origin,
aspect: destination.aspect,

View File

@ -130,7 +130,7 @@ pub fn op_webgpu_render_pass_begin_pipeline_statistics_query(
wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query(
&mut render_pass_resource.0.borrow_mut(),
query_set_resource.0,
query_set_resource.1,
query_index,
);
@ -169,7 +169,7 @@ pub fn op_webgpu_render_pass_write_timestamp(
wgpu_core::command::render_ffi::wgpu_render_pass_write_timestamp(
&mut render_pass_resource.0.borrow_mut(),
query_set_resource.0,
query_set_resource.1,
query_index,
);
@ -188,7 +188,7 @@ pub fn op_webgpu_render_pass_execute_bundles(
let render_bundle_resource = state
.resource_table
.get::<super::bundle::WebGpuRenderBundle>(*rid)?;
Ok(render_bundle_resource.0)
Ok(render_bundle_resource.1)
})
.collect::<Result<Vec<_>, AnyError>>()?;
@ -219,7 +219,7 @@ pub fn op_webgpu_render_pass_end(
state
.resource_table
.get::<super::command_encoder::WebGpuCommandEncoder>(command_encoder_rid)?;
let command_encoder = command_encoder_resource.0;
let command_encoder = command_encoder_resource.1;
let render_pass_resource = state
.resource_table
.take::<WebGpuRenderPass>(render_pass_rid)?;
@ -269,7 +269,7 @@ pub fn op_webgpu_render_pass_set_bind_group(
wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group(
&mut render_pass_resource.0.borrow_mut(),
index,
bind_group_resource.0,
bind_group_resource.1,
dynamic_offsets_data.as_ptr(),
dynamic_offsets_data.len(),
);
@ -357,7 +357,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
wgpu_core::command::render_ffi::wgpu_render_pass_set_pipeline(
&mut render_pass_resource.0.borrow_mut(),
render_pipeline_resource.0,
render_pipeline_resource.1,
);
Ok(WebGpuResult::empty())
@ -389,7 +389,7 @@ pub fn op_webgpu_render_pass_set_index_buffer(
};
render_pass_resource.0.borrow_mut().set_index_buffer(
buffer_resource.0,
buffer_resource.1,
index_format,
offset,
size,
@ -426,7 +426,7 @@ pub fn op_webgpu_render_pass_set_vertex_buffer(
wgpu_core::command::render_ffi::wgpu_render_pass_set_vertex_buffer(
&mut render_pass_resource.0.borrow_mut(),
slot,
buffer_resource.0,
buffer_resource.1,
offset,
size,
);
@ -500,7 +500,7 @@ pub fn op_webgpu_render_pass_draw_indirect(
wgpu_core::command::render_ffi::wgpu_render_pass_draw_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.0,
buffer_resource.1,
indirect_offset,
);
@ -523,7 +523,7 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect(
wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.0,
buffer_resource.1,
indirect_offset,
);

View File

@ -7,14 +7,23 @@ use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult;
pub(crate) struct WebGpuSampler(pub(crate) wgpu_core::id::SamplerId);
pub(crate) struct WebGpuSampler(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::SamplerId,
);
impl Resource for WebGpuSampler {
fn name(&self) -> Cow<str> {
"webGPUSampler".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.sampler_drop(self.1));
}
}
#[derive(Deserialize)]
@ -43,7 +52,7 @@ pub fn op_webgpu_create_sampler(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let descriptor = wgpu_core::resource::SamplerDescriptor {
label: args.label.map(Cow::from),

View File

@ -6,14 +6,23 @@ use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult;
pub(crate) struct WebGpuShaderModule(pub(crate) wgpu_core::id::ShaderModuleId);
pub(crate) struct WebGpuShaderModule(
pub(crate) super::Instance,
pub(crate) wgpu_core::id::ShaderModuleId,
);
impl Resource for WebGpuShaderModule {
fn name(&self) -> Cow<str> {
"webGPUShaderModule".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.shader_module_drop(self.1));
}
}
#[op]
@ -27,7 +36,7 @@ pub fn op_webgpu_create_shader_module(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let source = wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::from(code));

View File

@ -10,6 +10,7 @@ use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use wgpu_types::SurfaceStatus;
pub fn init_surface(unstable: bool) -> Extension {
@ -36,11 +37,15 @@ pub fn init_surface(unstable: bool) -> Extension {
.build()
}
pub struct WebGpuSurface(pub wgpu_core::id::SurfaceId);
pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId);
impl Resource for WebGpuSurface {
fn name(&self) -> Cow<str> {
"webGPUSurface".into()
}
fn close(self: Rc<Self>) {
self.0.surface_drop(self.1);
}
}
#[derive(Deserialize)]
@ -66,11 +71,11 @@ pub fn op_webgpu_surface_configure(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let surface_resource = state
.resource_table
.get::<WebGpuSurface>(args.surface_rid)?;
let surface = surface_resource.0;
let surface = surface_resource.1;
let conf = wgpu_types::SurfaceConfiguration::<Vec<wgpu_types::TextureFormat>> {
usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage),
@ -97,16 +102,20 @@ pub fn op_webgpu_surface_get_current_texture(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
let surface = surface_resource.0;
let surface = surface_resource.1;
let output = gfx_select!(device => instance.surface_get_current_texture(surface, ()))?;
match output.status {
SurfaceStatus::Good | SurfaceStatus::Suboptimal => {
let id = output.texture_id.unwrap();
let rid = state.resource_table.add(crate::texture::WebGpuTexture(id));
let rid = state.resource_table.add(crate::texture::WebGpuTexture {
instance: instance.clone(),
id,
owned: false,
});
Ok(WebGpuResult::rid(rid))
}
_ => Err(AnyError::msg("Invalid Surface Status")),
@ -123,9 +132,9 @@ pub fn op_webgpu_surface_present(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
let surface = surface_resource.0;
let surface = surface_resource.1;
let _ = gfx_select!(device => instance.surface_present(surface))?;

View File

@ -7,20 +7,41 @@ use deno_core::Resource;
use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::rc::Rc;
use super::error::WebGpuResult;
pub(crate) struct WebGpuTexture(pub(crate) wgpu_core::id::TextureId);
pub(crate) struct WebGpuTexture {
pub(crate) instance: crate::Instance,
pub(crate) id: wgpu_core::id::TextureId,
pub(crate) owned: bool,
}
impl Resource for WebGpuTexture {
fn name(&self) -> Cow<str> {
"webGPUTexture".into()
}
fn close(self: Rc<Self>) {
if self.owned {
let instance = &self.instance;
gfx_select!(self.id => instance.texture_drop(self.id, true));
}
}
}
pub(crate) struct WebGpuTextureView(pub(crate) wgpu_core::id::TextureViewId);
pub(crate) struct WebGpuTextureView(
pub(crate) crate::Instance,
pub(crate) wgpu_core::id::TextureViewId,
);
impl Resource for WebGpuTextureView {
fn name(&self) -> Cow<str> {
"webGPUTextureView".into()
}
fn close(self: Rc<Self>) {
let instance = &self.0;
gfx_select!(self.1 => instance.texture_view_drop(self.1, true)).unwrap();
}
}
#[derive(Deserialize)]
@ -46,7 +67,7 @@ pub fn op_webgpu_create_texture(
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(args.device_rid)?;
let device = device_resource.0;
let device = device_resource.1;
let descriptor = wgpu_core::resource::TextureDescriptor {
label: args.label.map(Cow::from),
@ -59,11 +80,19 @@ pub fn op_webgpu_create_texture(
view_formats: args.view_formats,
};
gfx_put!(device => instance.device_create_texture(
device,
&descriptor,
()
) => state, WebGpuTexture)
let (val, maybe_err) = gfx_select!(device => instance.device_create_texture(
device,
&descriptor,
()
));
let rid = state.resource_table.add(WebGpuTexture {
instance: instance.clone(),
id: val,
owned: true,
});
Ok(WebGpuResult::rid_err(rid, maybe_err))
}
#[derive(Deserialize)]
@ -86,7 +115,7 @@ pub fn op_webgpu_create_texture_view(
let texture_resource = state
.resource_table
.get::<WebGpuTexture>(args.texture_rid)?;
let texture = texture_resource.0;
let texture = texture_resource.id;
let descriptor = wgpu_core::resource::TextureViewDescriptor {
label: args.label.map(Cow::from),