diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-01-20 15:23:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-20 15:23:53 +0100 |
commit | 3ab68bd0a2aff6df12388f2c3b5ed7ae3333a6ca (patch) | |
tree | 9a81824deb4e5a2b29c3eeb5a2adaa3e00720c45 /ext/webgpu/src | |
parent | 1cc38f5155bdc5605d74cd959660fa04f782ac63 (diff) |
revert(#13402): experiment: wgpu sync (#13439)
Diffstat (limited to 'ext/webgpu/src')
-rw-r--r-- | ext/webgpu/src/binding.rs | 341 | ||||
-rw-r--r-- | ext/webgpu/src/buffer.rs | 229 | ||||
-rw-r--r-- | ext/webgpu/src/bundle.rs | 459 | ||||
-rw-r--r-- | ext/webgpu/src/command_encoder.rs | 646 | ||||
-rw-r--r-- | ext/webgpu/src/compute_pass.rs | 354 | ||||
-rw-r--r-- | ext/webgpu/src/error.rs | 292 | ||||
-rw-r--r-- | ext/webgpu/src/lib.rs | 908 | ||||
-rw-r--r-- | ext/webgpu/src/queue.rs | 142 | ||||
-rw-r--r-- | ext/webgpu/src/render_pass.rs | 649 | ||||
-rw-r--r-- | ext/webgpu/src/shader.rs | 52 |
10 files changed, 0 insertions, 4072 deletions
diff --git a/ext/webgpu/src/binding.rs b/ext/webgpu/src/binding.rs deleted file mode 100644 index 9a8fa455f..000000000 --- a/ext/webgpu/src/binding.rs +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::convert::{TryFrom, TryInto}; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuBindGroupLayout( - pub(crate) wgpu_core::id::BindGroupLayoutId, -); -impl Resource for WebGpuBindGroupLayout { - fn name(&self) -> Cow<str> { - "webGPUBindGroupLayout".into() - } -} - -pub(crate) struct WebGpuBindGroup(pub(crate) wgpu_core::id::BindGroupId); -impl Resource for WebGpuBindGroup { - fn name(&self) -> Cow<str> { - "webGPUBindGroup".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBufferBindingLayout { - r#type: GpuBufferBindingType, - has_dynamic_offset: bool, - min_binding_size: u64, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuBufferBindingType { - Uniform, - Storage, - ReadOnlyStorage, -} - -impl From<GpuBufferBindingType> for wgpu_types::BufferBindingType { - fn from(binding_type: GpuBufferBindingType) -> Self { - match binding_type { - GpuBufferBindingType::Uniform => wgpu_types::BufferBindingType::Uniform, - GpuBufferBindingType::Storage => { - wgpu_types::BufferBindingType::Storage { read_only: false } - } - GpuBufferBindingType::ReadOnlyStorage => { - wgpu_types::BufferBindingType::Storage { read_only: true } - } - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuSamplerBindingLayout { - r#type: wgpu_types::SamplerBindingType, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuTextureBindingLayout { - sample_type: GpuTextureSampleType, - view_dimension: wgpu_types::TextureViewDimension, - multisampled: bool, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuTextureSampleType { - Float, - UnfilterableFloat, - Depth, - Sint, - Uint, -} - -impl From<GpuTextureSampleType> for wgpu_types::TextureSampleType { - fn from(sample_type: GpuTextureSampleType) -> Self { - match sample_type { - GpuTextureSampleType::Float => { - wgpu_types::TextureSampleType::Float { filterable: true } - } - GpuTextureSampleType::UnfilterableFloat => { - wgpu_types::TextureSampleType::Float { filterable: false } - } - GpuTextureSampleType::Depth => wgpu_types::TextureSampleType::Depth, - GpuTextureSampleType::Sint => wgpu_types::TextureSampleType::Sint, - GpuTextureSampleType::Uint => wgpu_types::TextureSampleType::Uint, - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuStorageTextureBindingLayout { - access: GpuStorageTextureAccess, - format: wgpu_types::TextureFormat, - view_dimension: wgpu_types::TextureViewDimension, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuStorageTextureAccess { - WriteOnly, -} - -impl From<GpuStorageTextureAccess> for wgpu_types::StorageTextureAccess { - fn from(access: GpuStorageTextureAccess) -> Self { - match access { - GpuStorageTextureAccess::WriteOnly => { - wgpu_types::StorageTextureAccess::WriteOnly - } - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBindGroupLayoutEntry { - binding: u32, - visibility: u32, - #[serde(flatten)] - binding_type: GpuBindingType, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -enum GpuBindingType { - Buffer(GpuBufferBindingLayout), - Sampler(GpuSamplerBindingLayout), - Texture(GpuTextureBindingLayout), - StorageTexture(GpuStorageTextureBindingLayout), -} - -impl TryFrom<GpuBindingType> for wgpu_types::BindingType { - type Error = AnyError; - - fn try_from( - binding_type: GpuBindingType, - ) -> Result<wgpu_types::BindingType, Self::Error> { - let binding_type = match binding_type { - GpuBindingType::Buffer(buffer) => wgpu_types::BindingType::Buffer { - ty: buffer.r#type.into(), - has_dynamic_offset: buffer.has_dynamic_offset, - min_binding_size: std::num::NonZeroU64::new(buffer.min_binding_size), - }, - GpuBindingType::Sampler(sampler) => { - wgpu_types::BindingType::Sampler(sampler.r#type) - } - GpuBindingType::Texture(texture) => wgpu_types::BindingType::Texture { - sample_type: texture.sample_type.into(), - view_dimension: texture.view_dimension, - multisampled: texture.multisampled, - }, - GpuBindingType::StorageTexture(storage_texture) => { - wgpu_types::BindingType::StorageTexture { - access: storage_texture.access.into(), - format: storage_texture.format, - view_dimension: storage_texture.view_dimension, - } - } - }; - Ok(binding_type) - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBindGroupLayoutArgs { - device_rid: ResourceId, - label: Option<String>, - entries: Vec<GpuBindGroupLayoutEntry>, -} - -pub fn op_webgpu_create_bind_group_layout( - state: &mut OpState, - args: CreateBindGroupLayoutArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let mut entries = vec![]; - - for entry in args.entries { - entries.push(wgpu_types::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgpu_types::ShaderStages::from_bits(entry.visibility) - .unwrap(), - ty: entry.binding_type.try_into()?, - count: None, // native-only - }); - } - - let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { - label: args.label.map(Cow::from), - entries: Cow::from(entries), - }; - - gfx_put!(device => instance.device_create_bind_group_layout( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBindGroupLayout) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreatePipelineLayoutArgs { - device_rid: ResourceId, - label: Option<String>, - bind_group_layouts: Vec<u32>, -} - -pub fn op_webgpu_create_pipeline_layout( - state: &mut OpState, - args: CreatePipelineLayoutArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let mut bind_group_layouts = vec![]; - - for rid in &args.bind_group_layouts { - let bind_group_layout = - state.resource_table.get::<WebGpuBindGroupLayout>(*rid)?; - bind_group_layouts.push(bind_group_layout.0); - } - - let descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { - label: args.label.map(Cow::from), - bind_group_layouts: Cow::from(bind_group_layouts), - push_constant_ranges: Default::default(), - }; - - gfx_put!(device => instance.device_create_pipeline_layout( - device, - &descriptor, - std::marker::PhantomData - ) => state, super::pipeline::WebGpuPipelineLayout) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuBindGroupEntry { - binding: u32, - kind: String, - resource: ResourceId, - offset: Option<u64>, - size: Option<u64>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBindGroupArgs { - device_rid: ResourceId, - label: Option<String>, - layout: ResourceId, - entries: Vec<GpuBindGroupEntry>, -} - -pub fn op_webgpu_create_bind_group( - state: &mut OpState, - args: CreateBindGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let mut entries = vec![]; - - for entry in &args.entries { - let e = wgpu_core::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.kind.as_str() { - "GPUSampler" => { - let sampler_resource = - state - .resource_table - .get::<super::sampler::WebGpuSampler>(entry.resource)?; - wgpu_core::binding_model::BindingResource::Sampler(sampler_resource.0) - } - "GPUTextureView" => { - let texture_view_resource = - state - .resource_table - .get::<super::texture::WebGpuTextureView>(entry.resource)?; - wgpu_core::binding_model::BindingResource::TextureView( - texture_view_resource.0, - ) - } - "GPUBufferBinding" => { - let buffer_resource = - state - .resource_table - .get::<super::buffer::WebGpuBuffer>(entry.resource)?; - wgpu_core::binding_model::BindingResource::Buffer( - wgpu_core::binding_model::BufferBinding { - buffer_id: buffer_resource.0, - offset: entry.offset.unwrap_or(0), - size: std::num::NonZeroU64::new(entry.size.unwrap_or(0)), - }, - ) - } - _ => unreachable!(), - }, - }; - entries.push(e); - } - - let bind_group_layout = state - .resource_table - .get::<WebGpuBindGroupLayout>(args.layout)?; - - let descriptor = wgpu_core::binding_model::BindGroupDescriptor { - label: args.label.map(Cow::from), - layout: bind_group_layout.0, - entries: Cow::from(entries), - }; - - gfx_put!(device => instance.device_create_bind_group( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBindGroup) -} diff --git a/ext/webgpu/src/buffer.rs b/ext/webgpu/src/buffer.rs deleted file mode 100644 index 3f2c07883..000000000 --- a/ext/webgpu/src/buffer.rs +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::type_error; -use deno_core::error::AnyError; -use deno_core::futures::channel::oneshot; -use deno_core::OpState; -use deno_core::Resource; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; -use std::time::Duration; - -use super::error::DomExceptionOperationError; -use super::error::WebGpuResult; - -pub(crate) struct WebGpuBuffer(pub(crate) wgpu_core::id::BufferId); -impl Resource for WebGpuBuffer { - fn name(&self) -> Cow<str> { - "webGPUBuffer".into() - } -} - -struct WebGpuBufferMapped(*mut u8, usize); -impl Resource for WebGpuBufferMapped { - fn name(&self) -> Cow<str> { - "webGPUBufferMapped".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateBufferArgs { - device_rid: ResourceId, - label: Option<String>, - size: u64, - usage: u32, - mapped_at_creation: bool, -} - -pub fn op_webgpu_create_buffer( - state: &mut OpState, - args: CreateBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let descriptor = wgpu_core::resource::BufferDescriptor { - label: args.label.map(Cow::from), - size: args.size, - usage: wgpu_types::BufferUsages::from_bits(args.usage) - .ok_or_else(|| type_error("usage is not valid"))?, - mapped_at_creation: args.mapped_at_creation, - }; - - gfx_put!(device => instance.device_create_buffer( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuBuffer) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferGetMapAsyncArgs { - buffer_rid: ResourceId, - device_rid: ResourceId, - mode: u32, - offset: u64, - size: u64, -} - -pub async fn op_webgpu_buffer_get_map_async( - state: Rc<RefCell<OpState>>, - args: BufferGetMapAsyncArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let (sender, receiver) = oneshot::channel::<Result<(), AnyError>>(); - - let device; - { - let state_ = state.borrow(); - let instance = state_.borrow::<super::Instance>(); - let buffer_resource = - state_.resource_table.get::<WebGpuBuffer>(args.buffer_rid)?; - let buffer = buffer_resource.0; - let device_resource = state_ - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - device = device_resource.0; - - let boxed_sender = Box::new(sender); - let sender_ptr = Box::into_raw(boxed_sender) as *mut u8; - - extern "C" fn buffer_map_future_wrapper( - status: wgpu_core::resource::BufferMapAsyncStatus, - user_data: *mut u8, - ) { - let sender_ptr = user_data as *mut oneshot::Sender<Result<(), AnyError>>; - let boxed_sender = unsafe { Box::from_raw(sender_ptr) }; - boxed_sender - .send(match status { - wgpu_core::resource::BufferMapAsyncStatus::Success => Ok(()), - _ => unreachable!(), // TODO - }) - .unwrap(); - } - - // TODO(lucacasonato): error handling - let maybe_err = gfx_select!(buffer => instance.buffer_map_async( - buffer, - args.offset..(args.offset + args.size), - wgpu_core::resource::BufferMapOperation { - host: match args.mode { - 1 => wgpu_core::device::HostMap::Read, - 2 => wgpu_core::device::HostMap::Write, - _ => unreachable!(), - }, - callback: buffer_map_future_wrapper, - user_data: sender_ptr, - } - )) - .err(); - - if maybe_err.is_some() { - return Ok(WebGpuResult::maybe_err(maybe_err)); - } - } - - let done = Rc::new(RefCell::new(false)); - let done_ = done.clone(); - let device_poll_fut = async move { - while !*done.borrow() { - { - let state = state.borrow(); - let instance = state.borrow::<super::Instance>(); - gfx_select!(device => instance.device_poll(device, false)).unwrap() - } - tokio::time::sleep(Duration::from_millis(10)).await; - } - Ok::<(), AnyError>(()) - }; - - let receiver_fut = async move { - receiver.await??; - let mut done = done_.borrow_mut(); - *done = true; - Ok::<(), AnyError>(()) - }; - - tokio::try_join!(device_poll_fut, receiver_fut)?; - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferGetMappedRangeArgs { - buffer_rid: ResourceId, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_buffer_get_mapped_range( - state: &mut OpState, - args: BufferGetMappedRangeArgs, - mut zero_copy: ZeroCopyBuf, -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let buffer_resource = - state.resource_table.get::<WebGpuBuffer>(args.buffer_rid)?; - let buffer = buffer_resource.0; - - let (slice_pointer, range_size) = - gfx_select!(buffer => instance.buffer_get_mapped_range( - buffer, - args.offset, - args.size - )) - .map_err(|e| DomExceptionOperationError::new(&e.to_string()))?; - - let slice = unsafe { - std::slice::from_raw_parts_mut(slice_pointer, range_size as usize) - }; - zero_copy.copy_from_slice(slice); - - let rid = state - .resource_table - .add(WebGpuBufferMapped(slice_pointer, range_size as usize)); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct BufferUnmapArgs { - buffer_rid: ResourceId, - mapped_rid: ResourceId, -} - -pub fn op_webgpu_buffer_unmap( - state: &mut OpState, - args: BufferUnmapArgs, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<WebGpuResult, AnyError> { - let mapped_resource = state - .resource_table - .take::<WebGpuBufferMapped>(args.mapped_rid)?; - let instance = state.borrow::<super::Instance>(); - let buffer_resource = - state.resource_table.get::<WebGpuBuffer>(args.buffer_rid)?; - let buffer = buffer_resource.0; - - let slice_pointer = mapped_resource.0; - let size = mapped_resource.1; - - if let Some(buffer) = zero_copy { - let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) }; - slice.copy_from_slice(&buffer); - } - - gfx_ok!(buffer => instance.buffer_unmap(buffer)) -} diff --git a/ext/webgpu/src/bundle.rs b/ext/webgpu/src/bundle.rs deleted file mode 100644 index ea327651a..000000000 --- a/ext/webgpu/src/bundle.rs +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::rc::Rc; - -use super::error::WebGpuResult; - -struct WebGpuRenderBundleEncoder( - RefCell<wgpu_core::command::RenderBundleEncoder>, -); -impl Resource for WebGpuRenderBundleEncoder { - fn name(&self) -> Cow<str> { - "webGPURenderBundleEncoder".into() - } -} - -pub(crate) struct WebGpuRenderBundle(pub(crate) wgpu_core::id::RenderBundleId); -impl Resource for WebGpuRenderBundle { - fn name(&self) -> Cow<str> { - "webGPURenderBundle".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateRenderBundleEncoderArgs { - device_rid: ResourceId, - label: Option<String>, - color_formats: Vec<wgpu_types::TextureFormat>, - depth_stencil_format: Option<wgpu_types::TextureFormat>, - sample_count: u32, - depth_read_only: bool, - stencil_read_only: bool, -} - -pub fn op_webgpu_create_render_bundle_encoder( - state: &mut OpState, - args: CreateRenderBundleEncoderArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let mut color_formats = vec![]; - - for format in args.color_formats { - color_formats.push(format); - } - - let depth_stencil = if let Some(format) = args.depth_stencil_format { - Some(wgpu_types::RenderBundleDepthStencil { - format, - depth_read_only: args.depth_read_only, - stencil_read_only: args.stencil_read_only, - }) - } else { - None - }; - - let descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { - label: args.label.map(Cow::from), - color_formats: Cow::from(color_formats), - sample_count: args.sample_count, - depth_stencil, - multiview: None, - }; - - let res = - wgpu_core::command::RenderBundleEncoder::new(&descriptor, device, None); - let (render_bundle_encoder, maybe_err) = match res { - Ok(encoder) => (encoder, None), - Err(e) => ( - wgpu_core::command::RenderBundleEncoder::dummy(device), - Some(e), - ), - }; - - let rid = state - .resource_table - .add(WebGpuRenderBundleEncoder(RefCell::new( - render_bundle_encoder, - ))); - - Ok(WebGpuResult::rid_err(rid, maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderFinishArgs { - render_bundle_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_render_bundle_encoder_finish( - state: &mut OpState, - args: RenderBundleEncoderFinishArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .take::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - let render_bundle_encoder = Rc::try_unwrap(render_bundle_encoder_resource) - .ok() - .expect("unwrapping render_bundle_encoder_resource should succeed") - .0 - .into_inner(); - let instance = state.borrow::<super::Instance>(); - - gfx_put!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( - render_bundle_encoder, - &wgpu_core::command::RenderBundleDescriptor { - label: args.label.map(Cow::from), - }, - std::marker::PhantomData - ) => state, WebGpuRenderBundle) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetBindGroupArgs { - render_bundle_encoder_rid: ResourceId, - index: u32, - bind_group: ResourceId, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_render_bundle_encoder_set_bind_group( - state: &mut OpState, - args: RenderBundleEncoderSetBindGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = - state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group)?; - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - // Align the data - assert!(args.dynamic_offsets_data.len() % std::mem::size_of::<u32>() == 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = - unsafe { args.dynamic_offsets_data.align_to::<u32>() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - - let start = args.dynamic_offsets_data_start; - let len = args.dynamic_offsets_data_length; - - // Assert that length and start are both in bounds - assert!(start <= dynamic_offsets_data.len()); - assert!(len <= dynamic_offsets_data.len() - start); - - let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; - - // SAFETY: the raw pointer and length are of the same slice, and that slice - // lives longer than the below function invocation. - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - dynamic_offsets_data.as_ptr(), - dynamic_offsets_data.len(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderPushDebugGroupArgs { - render_bundle_encoder_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_render_bundle_encoder_push_debug_group( - state: &mut OpState, - args: RenderBundleEncoderPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - let label = std::ffi::CString::new(args.group_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_push_debug_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - label.as_ptr(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderPopDebugGroupArgs { - render_bundle_encoder_rid: ResourceId, -} - -pub fn op_webgpu_render_bundle_encoder_pop_debug_group( - state: &mut OpState, - args: RenderBundleEncoderPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_pop_debug_group( - &mut render_bundle_encoder_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderInsertDebugMarkerArgs { - render_bundle_encoder_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_render_bundle_encoder_insert_debug_marker( - state: &mut OpState, - args: RenderBundleEncoderInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - let label = std::ffi::CString::new(args.marker_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( - &mut render_bundle_encoder_resource.0.borrow_mut(), - label.as_ptr(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetPipelineArgs { - render_bundle_encoder_rid: ResourceId, - pipeline: ResourceId, -} - -pub fn op_webgpu_render_bundle_encoder_set_pipeline( - state: &mut OpState, - args: RenderBundleEncoderSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pipeline_resource = - state - .resource_table - .get::<super::pipeline::WebGpuRenderPipeline>(args.pipeline)?; - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline( - &mut render_bundle_encoder_resource.0.borrow_mut(), - render_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetIndexBufferArgs { - render_bundle_encoder_rid: ResourceId, - buffer: ResourceId, - index_format: wgpu_types::IndexFormat, - offset: u64, - size: u64, -} - -pub fn op_webgpu_render_bundle_encoder_set_index_buffer( - state: &mut OpState, - args: RenderBundleEncoderSetIndexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer)?; - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - render_bundle_encoder_resource - .0 - .borrow_mut() - .set_index_buffer( - buffer_resource.0, - args.index_format, - args.offset, - std::num::NonZeroU64::new(args.size), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderSetVertexBufferArgs { - render_bundle_encoder_rid: ResourceId, - slot: u32, - buffer: ResourceId, - offset: u64, - size: u64, -} - -pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer( - state: &mut OpState, - args: RenderBundleEncoderSetVertexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer)?; - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.slot, - buffer_resource.0, - args.offset, - std::num::NonZeroU64::new(args.size), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawArgs { - render_bundle_encoder_rid: ResourceId, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, -} - -pub fn op_webgpu_render_bundle_encoder_draw( - state: &mut OpState, - args: RenderBundleEncoderDrawArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.vertex_count, - args.instance_count, - args.first_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawIndexedArgs { - render_bundle_encoder_rid: ResourceId, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, -} - -pub fn op_webgpu_render_bundle_encoder_draw_indexed( - state: &mut OpState, - args: RenderBundleEncoderDrawIndexedArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed( - &mut render_bundle_encoder_resource.0.borrow_mut(), - args.index_count, - args.instance_count, - args.first_index, - args.base_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderBundleEncoderDrawIndirectArgs { - render_bundle_encoder_rid: ResourceId, - indirect_buffer: ResourceId, - indirect_offset: u64, -} - -pub fn op_webgpu_render_bundle_encoder_draw_indirect( - state: &mut OpState, - args: RenderBundleEncoderDrawIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer)?; - let render_bundle_encoder_resource = - state - .resource_table - .get::<WebGpuRenderBundleEncoder>(args.render_bundle_encoder_rid)?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect( - &mut render_bundle_encoder_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} diff --git a/ext/webgpu/src/command_encoder.rs b/ext/webgpu/src/command_encoder.rs deleted file mode 100644 index 894b08f27..000000000 --- a/ext/webgpu/src/command_encoder.rs +++ /dev/null @@ -1,646 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::num::NonZeroU32; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuCommandEncoder( - pub(crate) wgpu_core::id::CommandEncoderId, -); -impl Resource for WebGpuCommandEncoder { - fn name(&self) -> Cow<str> { - "webGPUCommandEncoder".into() - } -} - -pub(crate) struct WebGpuCommandBuffer( - pub(crate) wgpu_core::id::CommandBufferId, -); -impl Resource for WebGpuCommandBuffer { - fn name(&self) -> Cow<str> { - "webGPUCommandBuffer".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateCommandEncoderArgs { - device_rid: ResourceId, - label: Option<String>, - _measure_execution_time: Option<bool>, // not yet implemented -} - -pub fn op_webgpu_create_command_encoder( - state: &mut OpState, - args: CreateCommandEncoderArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let descriptor = wgpu_types::CommandEncoderDescriptor { - label: args.label.map(Cow::from), - }; - - gfx_put!(device => instance.device_create_command_encoder( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuCommandEncoder) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuRenderPassColorAttachment { - view: ResourceId, - resolve_target: Option<ResourceId>, - load_op: GpuLoadOp<wgpu_types::Color>, - store_op: wgpu_core::command::StoreOp, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case")] -enum GpuLoadOp<T> { - Load, - Clear(T), -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuRenderPassDepthStencilAttachment { - view: ResourceId, - depth_load_op: GpuLoadOp<f32>, - depth_store_op: wgpu_core::command::StoreOp, - depth_read_only: bool, - stencil_load_op: GpuLoadOp<u32>, - stencil_store_op: wgpu_core::command::StoreOp, - stencil_read_only: bool, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderBeginRenderPassArgs { - command_encoder_rid: ResourceId, - label: Option<String>, - color_attachments: Vec<GpuRenderPassColorAttachment>, - depth_stencil_attachment: Option<GpuRenderPassDepthStencilAttachment>, - _occlusion_query_set: Option<u32>, // not yet implemented -} - -pub fn op_webgpu_command_encoder_begin_render_pass( - state: &mut OpState, - args: CommandEncoderBeginRenderPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - - let mut color_attachments = vec![]; - - for color_attachment in args.color_attachments { - let texture_view_resource = - state - .resource_table - .get::<super::texture::WebGpuTextureView>(color_attachment.view)?; - - let resolve_target = color_attachment - .resolve_target - .map(|rid| { - state - .resource_table - .get::<super::texture::WebGpuTextureView>(rid) - }) - .transpose()? - .map(|texture| texture.0); - - let attachment = wgpu_core::command::RenderPassColorAttachment { - view: texture_view_resource.0, - resolve_target, - channel: match color_attachment.load_op { - GpuLoadOp::Load => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: color_attachment.store_op, - clear_value: Default::default(), - read_only: false, - }, - GpuLoadOp::Clear(color) => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: color_attachment.store_op, - clear_value: color, - read_only: false, - }, - }, - }; - - color_attachments.push(attachment) - } - - let mut depth_stencil_attachment = None; - - if let Some(attachment) = args.depth_stencil_attachment { - let texture_view_resource = - state - .resource_table - .get::<super::texture::WebGpuTextureView>(attachment.view)?; - - depth_stencil_attachment = - Some(wgpu_core::command::RenderPassDepthStencilAttachment { - view: texture_view_resource.0, - depth: match attachment.depth_load_op { - GpuLoadOp::Load => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: attachment.depth_store_op, - clear_value: 0.0, - read_only: attachment.depth_read_only, - }, - GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: attachment.depth_store_op, - clear_value: value, - read_only: attachment.depth_read_only, - }, - }, - stencil: match attachment.stencil_load_op { - GpuLoadOp::Load => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Load, - store_op: attachment.stencil_store_op, - clear_value: 0, - read_only: attachment.stencil_read_only, - }, - GpuLoadOp::Clear(value) => wgpu_core::command::PassChannel { - load_op: wgpu_core::command::LoadOp::Clear, - store_op: attachment.stencil_store_op, - clear_value: value, - read_only: attachment.stencil_read_only, - }, - }, - }); - } - - let descriptor = wgpu_core::command::RenderPassDescriptor { - label: args.label.map(Cow::from), - color_attachments: Cow::from(color_attachments), - depth_stencil_attachment: depth_stencil_attachment.as_ref(), - }; - - let render_pass = wgpu_core::command::RenderPass::new( - command_encoder_resource.0, - &descriptor, - ); - - let rid = state - .resource_table - .add(super::render_pass::WebGpuRenderPass(RefCell::new( - render_pass, - ))); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderBeginComputePassArgs { - command_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_command_encoder_begin_compute_pass( - state: &mut OpState, - args: CommandEncoderBeginComputePassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - - let descriptor = wgpu_core::command::ComputePassDescriptor { - label: args.label.map(Cow::from), - }; - - let compute_pass = wgpu_core::command::ComputePass::new( - command_encoder_resource.0, - &descriptor, - ); - - let rid = state - .resource_table - .add(super::compute_pass::WebGpuComputePass(RefCell::new( - compute_pass, - ))); - - Ok(WebGpuResult::rid(rid)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyBufferToBufferArgs { - command_encoder_rid: ResourceId, - source: ResourceId, - source_offset: u64, - destination: ResourceId, - destination_offset: u64, - size: u64, -} - -pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( - state: &mut OpState, - args: CommandEncoderCopyBufferToBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let source_buffer_resource = - state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.source)?; - let source_buffer = source_buffer_resource.0; - let destination_buffer_resource = - state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination)?; - let destination_buffer = destination_buffer_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( - command_encoder, - source_buffer, - args.source_offset, - destination_buffer, - args.destination_offset, - args.size - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuImageCopyBuffer { - buffer: ResourceId, - offset: u64, - bytes_per_row: Option<u32>, - rows_per_image: Option<u32>, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuImageCopyTexture { - pub texture: ResourceId, - pub mip_level: u32, - pub origin: wgpu_types::Origin3d, - pub aspect: wgpu_types::TextureAspect, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyBufferToTextureArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyBuffer, - destination: GpuImageCopyTexture, - copy_size: wgpu_types::Extent3d, -} - -pub fn op_webgpu_command_encoder_copy_buffer_to_texture( - state: &mut OpState, - args: CommandEncoderCopyBufferToTextureArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let source_buffer_resource = - state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.source.buffer)?; - let destination_texture_resource = - state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture)?; - - let source = wgpu_core::command::ImageCopyBuffer { - buffer: source_buffer_resource.0, - layout: wgpu_types::ImageDataLayout { - offset: args.source.offset, - bytes_per_row: NonZeroU32::new(args.source.bytes_per_row.unwrap_or(0)), - rows_per_image: NonZeroU32::new(args.source.rows_per_image.unwrap_or(0)), - }, - }; - let destination = wgpu_core::command::ImageCopyTexture { - texture: destination_texture_resource.0, - mip_level: args.destination.mip_level, - origin: args.destination.origin, - aspect: args.destination.aspect, - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture( - command_encoder, - &source, - &destination, - &args.copy_size - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyTextureToBufferArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyBuffer, - copy_size: wgpu_types::Extent3d, -} - -pub fn op_webgpu_command_encoder_copy_texture_to_buffer( - state: &mut OpState, - args: CommandEncoderCopyTextureToBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let source_texture_resource = - state - .resource_table - .get::<super::texture::WebGpuTexture>(args.source.texture)?; - let destination_buffer_resource = - state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination.buffer)?; - - let source = wgpu_core::command::ImageCopyTexture { - texture: source_texture_resource.0, - mip_level: args.source.mip_level, - origin: args.source.origin, - aspect: args.source.aspect, - }; - let destination = wgpu_core::command::ImageCopyBuffer { - buffer: destination_buffer_resource.0, - layout: wgpu_types::ImageDataLayout { - offset: args.destination.offset, - bytes_per_row: NonZeroU32::new( - args.destination.bytes_per_row.unwrap_or(0), - ), - rows_per_image: NonZeroU32::new( - args.destination.rows_per_image.unwrap_or(0), - ), - }, - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_buffer( - command_encoder, - &source, - &destination, - &args.copy_size - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderCopyTextureToTextureArgs { - command_encoder_rid: ResourceId, - source: GpuImageCopyTexture, - destination: GpuImageCopyTexture, - copy_size: wgpu_types::Extent3d, -} - -pub fn op_webgpu_command_encoder_copy_texture_to_texture( - state: &mut OpState, - args: CommandEncoderCopyTextureToTextureArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let source_texture_resource = - state - .resource_table - .get::<super::texture::WebGpuTexture>(args.source.texture)?; - let destination_texture_resource = - state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture)?; - - let source = wgpu_core::command::ImageCopyTexture { - texture: source_texture_resource.0, - mip_level: args.source.mip_level, - origin: args.source.origin, - aspect: args.source.aspect, - }; - let destination = wgpu_core::command::ImageCopyTexture { - texture: destination_texture_resource.0, - mip_level: args.destination.mip_level, - origin: args.destination.origin, - aspect: args.destination.aspect, - }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture( - command_encoder, - &source, - &destination, - &args.copy_size - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderClearBufferArgs { - command_encoder_rid: u32, - destination_rid: u32, - destination_offset: u64, - size: u64, -} - -pub fn op_webgpu_command_encoder_clear_buffer( - state: &mut OpState, - args: CommandEncoderClearBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let destination_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination_rid)?; - - gfx_ok!(command_encoder => instance.command_encoder_clear_buffer( - command_encoder, - destination_resource.0, - args.destination_offset, - std::num::NonZeroU64::new(args.size) - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderPushDebugGroupArgs { - command_encoder_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_command_encoder_push_debug_group( - state: &mut OpState, - args: CommandEncoderPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance - .command_encoder_push_debug_group(command_encoder, &args.group_label)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderPopDebugGroupArgs { - command_encoder_rid: ResourceId, -} - -pub fn op_webgpu_command_encoder_pop_debug_group( - state: &mut OpState, - args: CommandEncoderPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderInsertDebugMarkerArgs { - command_encoder_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_command_encoder_insert_debug_marker( - state: &mut OpState, - args: CommandEncoderInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - - gfx_ok!(command_encoder => instance.command_encoder_insert_debug_marker( - command_encoder, - &args.marker_label - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderWriteTimestampArgs { - command_encoder_rid: ResourceId, - query_set: ResourceId, - query_index: u32, -} - -pub fn op_webgpu_command_encoder_write_timestamp( - state: &mut OpState, - args: CommandEncoderWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - - gfx_ok!(command_encoder => instance.command_encoder_write_timestamp( - command_encoder, - query_set_resource.0, - args.query_index - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderResolveQuerySetArgs { - command_encoder_rid: ResourceId, - query_set: ResourceId, - first_query: u32, - query_count: u32, - destination: ResourceId, - destination_offset: u64, -} - -pub fn op_webgpu_command_encoder_resolve_query_set( - state: &mut OpState, - args: CommandEncoderResolveQuerySetArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let command_encoder_resource = state - .resource_table - .get::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - let destination_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.destination)?; - - gfx_ok!(command_encoder => instance.command_encoder_resolve_query_set( - command_encoder, - query_set_resource.0, - args.first_query, - args.query_count, - destination_resource.0, - args.destination_offset - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CommandEncoderFinishArgs { - command_encoder_rid: ResourceId, - label: Option<String>, -} - -pub fn op_webgpu_command_encoder_finish( - state: &mut OpState, - args: CommandEncoderFinishArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .take::<WebGpuCommandEncoder>(args.command_encoder_rid)?; - let command_encoder = command_encoder_resource.0; - let instance = state.borrow::<super::Instance>(); - - let descriptor = wgpu_types::CommandBufferDescriptor { - label: args.label.map(Cow::from), - }; - - gfx_put!(command_encoder => instance.command_encoder_finish( - command_encoder, - &descriptor - ) => state, WebGpuCommandBuffer) -} diff --git a/ext/webgpu/src/compute_pass.rs b/ext/webgpu/src/compute_pass.rs deleted file mode 100644 index 03d9163cb..000000000 --- a/ext/webgpu/src/compute_pass.rs +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuComputePass( - pub(crate) RefCell<wgpu_core::command::ComputePass>, -); -impl Resource for WebGpuComputePass { - fn name(&self) -> Cow<str> { - "webGPUComputePass".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassSetPipelineArgs { - compute_pass_rid: ResourceId, - pipeline: ResourceId, -} - -pub fn op_webgpu_compute_pass_set_pipeline( - state: &mut OpState, - args: ComputePassSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pipeline_resource = - state - .resource_table - .get::<super::pipeline::WebGpuComputePipeline>(args.pipeline)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_set_pipeline( - &mut compute_pass_resource.0.borrow_mut(), - compute_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassDispatchArgs { - compute_pass_rid: ResourceId, - x: u32, - y: u32, - z: u32, -} - -pub fn op_webgpu_compute_pass_dispatch( - state: &mut OpState, - args: ComputePassDispatchArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch( - &mut compute_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.z, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassDispatchIndirectArgs { - compute_pass_rid: ResourceId, - indirect_buffer: ResourceId, - indirect_offset: u64, -} - -pub fn op_webgpu_compute_pass_dispatch_indirect( - state: &mut OpState, - args: ComputePassDispatchIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_dispatch_indirect( - &mut compute_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassBeginPipelineStatisticsQueryArgs { - compute_pass_rid: ResourceId, - query_set: ResourceId, - query_index: u32, -} - -pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query( - state: &mut OpState, - args: ComputePassBeginPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_begin_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassEndPipelineStatisticsQueryArgs { - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_end_pipeline_statistics_query( - state: &mut OpState, - args: ComputePassEndPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_end_pipeline_statistics_query( - &mut compute_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassWriteTimestampArgs { - compute_pass_rid: ResourceId, - query_set: ResourceId, - query_index: u32, -} - -pub fn op_webgpu_compute_pass_write_timestamp( - state: &mut OpState, - args: ComputePassWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_write_timestamp( - &mut compute_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassEndPassArgs { - command_encoder_rid: ResourceId, - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_end_pass( - state: &mut OpState, - args: ComputePassEndPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<super::command_encoder::WebGpuCommandEncoder>( - args.command_encoder_rid, - )?; - let command_encoder = command_encoder_resource.0; - let compute_pass_resource = state - .resource_table - .take::<WebGpuComputePass>(args.compute_pass_rid)?; - let compute_pass = &compute_pass_resource.0.borrow(); - let instance = state.borrow::<super::Instance>(); - - gfx_ok!(command_encoder => instance.command_encoder_run_compute_pass( - command_encoder, - compute_pass - )) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassSetBindGroupArgs { - compute_pass_rid: ResourceId, - index: u32, - bind_group: ResourceId, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_compute_pass_set_bind_group( - state: &mut OpState, - args: ComputePassSetBindGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = - state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group)?; - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - // Align the data - assert!(args.dynamic_offsets_data_start % std::mem::size_of::<u32>() == 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = - unsafe { args.dynamic_offsets_data.align_to::<u32>() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - - let start = args.dynamic_offsets_data_start; - let len = args.dynamic_offsets_data_length; - - // Assert that length and start are both in bounds - assert!(start <= dynamic_offsets_data.len()); - assert!(len <= dynamic_offsets_data.len() - start); - - let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; - - // SAFETY: the raw pointer and length are of the same slice, and that slice - // lives longer than the below function invocation. - unsafe { - wgpu_core::command::compute_ffi::wgpu_compute_pass_set_bind_group( - &mut compute_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - dynamic_offsets_data.as_ptr(), - dynamic_offsets_data.len(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassPushDebugGroupArgs { - compute_pass_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_compute_pass_push_debug_group( - state: &mut OpState, - args: ComputePassPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - let label = std::ffi::CString::new(args.group_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::compute_ffi::wgpu_compute_pass_push_debug_group( - &mut compute_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassPopDebugGroupArgs { - compute_pass_rid: ResourceId, -} - -pub fn op_webgpu_compute_pass_pop_debug_group( - state: &mut OpState, - args: ComputePassPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - wgpu_core::command::compute_ffi::wgpu_compute_pass_pop_debug_group( - &mut compute_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ComputePassInsertDebugMarkerArgs { - compute_pass_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_compute_pass_insert_debug_marker( - state: &mut OpState, - args: ComputePassInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let compute_pass_resource = state - .resource_table - .get::<WebGpuComputePass>(args.compute_pass_rid)?; - - let label = std::ffi::CString::new(args.marker_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::compute_ffi::wgpu_compute_pass_insert_debug_marker( - &mut compute_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} diff --git a/ext/webgpu/src/error.rs b/ext/webgpu/src/error.rs deleted file mode 100644 index ae6e48054..000000000 --- a/ext/webgpu/src/error.rs +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -use deno_core::error::AnyError; -use deno_core::ResourceId; -use serde::Serialize; -use std::convert::From; -use std::fmt; -use wgpu_core::binding_model::CreateBindGroupError; -use wgpu_core::binding_model::CreateBindGroupLayoutError; -use wgpu_core::binding_model::CreatePipelineLayoutError; -use wgpu_core::binding_model::GetBindGroupLayoutError; -use wgpu_core::command::ClearError; -use wgpu_core::command::CommandEncoderError; -use wgpu_core::command::ComputePassError; -use wgpu_core::command::CopyError; -use wgpu_core::command::CreateRenderBundleError; -use wgpu_core::command::QueryError; -use wgpu_core::command::RenderBundleError; -use wgpu_core::command::RenderPassError; -use wgpu_core::device::queue::QueueSubmitError; -use wgpu_core::device::queue::QueueWriteError; -use wgpu_core::device::DeviceError; -use wgpu_core::pipeline::CreateComputePipelineError; -use wgpu_core::pipeline::CreateRenderPipelineError; -use wgpu_core::pipeline::CreateShaderModuleError; -use wgpu_core::resource::BufferAccessError; -use wgpu_core::resource::CreateBufferError; -use wgpu_core::resource::CreateQuerySetError; -use wgpu_core::resource::CreateSamplerError; -use wgpu_core::resource::CreateTextureError; -use wgpu_core::resource::CreateTextureViewError; - -#[derive(Serialize)] -pub struct WebGpuResult { - pub rid: Option<ResourceId>, - pub err: Option<WebGpuError>, -} - -impl WebGpuResult { - pub fn rid(rid: ResourceId) -> Self { - Self { - rid: Some(rid), - err: None, - } - } - - pub fn rid_err<T: Into<WebGpuError>>( - rid: ResourceId, - err: Option<T>, - ) -> Self { - Self { - rid: Some(rid), - err: err.map(|e| e.into()), - } - } - - pub fn maybe_err<T: Into<WebGpuError>>(err: Option<T>) -> Self { - Self { - rid: None, - err: err.map(|e| e.into()), - } - } - - pub fn empty() -> Self { - Self { - rid: None, - err: None, - } - } -} - -#[derive(Serialize)] -#[serde(tag = "type", content = "value")] -#[serde(rename_all = "kebab-case")] -pub enum WebGpuError { - Lost, - OutOfMemory, - Validation(String), -} - -impl From<CreateBufferError> for WebGpuError { - fn from(err: CreateBufferError) -> Self { - match err { - CreateBufferError::Device(err) => err.into(), - CreateBufferError::AccessError(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<DeviceError> for WebGpuError { - fn from(err: DeviceError) -> Self { - match err { - DeviceError::Lost => WebGpuError::Lost, - DeviceError::OutOfMemory => WebGpuError::OutOfMemory, - DeviceError::Invalid => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<BufferAccessError> for WebGpuError { - fn from(err: BufferAccessError) -> Self { - match err { - BufferAccessError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateBindGroupLayoutError> for WebGpuError { - fn from(err: CreateBindGroupLayoutError) -> Self { - match err { - CreateBindGroupLayoutError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreatePipelineLayoutError> for WebGpuError { - fn from(err: CreatePipelineLayoutError) -> Self { - match err { - CreatePipelineLayoutError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateBindGroupError> for WebGpuError { - fn from(err: CreateBindGroupError) -> Self { - match err { - CreateBindGroupError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<RenderBundleError> for WebGpuError { - fn from(err: RenderBundleError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateRenderBundleError> for WebGpuError { - fn from(err: CreateRenderBundleError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CopyError> for WebGpuError { - fn from(err: CopyError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CommandEncoderError> for WebGpuError { - fn from(err: CommandEncoderError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<QueryError> for WebGpuError { - fn from(err: QueryError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<ComputePassError> for WebGpuError { - fn from(err: ComputePassError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateComputePipelineError> for WebGpuError { - fn from(err: CreateComputePipelineError) -> Self { - match err { - CreateComputePipelineError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<GetBindGroupLayoutError> for WebGpuError { - fn from(err: GetBindGroupLayoutError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateRenderPipelineError> for WebGpuError { - fn from(err: CreateRenderPipelineError) -> Self { - match err { - CreateRenderPipelineError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<RenderPassError> for WebGpuError { - fn from(err: RenderPassError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateSamplerError> for WebGpuError { - fn from(err: CreateSamplerError) -> Self { - match err { - CreateSamplerError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateShaderModuleError> for WebGpuError { - fn from(err: CreateShaderModuleError) -> Self { - match err { - CreateShaderModuleError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateTextureError> for WebGpuError { - fn from(err: CreateTextureError) -> Self { - match err { - CreateTextureError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<CreateTextureViewError> for WebGpuError { - fn from(err: CreateTextureViewError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -impl From<CreateQuerySetError> for WebGpuError { - fn from(err: CreateQuerySetError) -> Self { - match err { - CreateQuerySetError::Device(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<QueueSubmitError> for WebGpuError { - fn from(err: QueueSubmitError) -> Self { - match err { - QueueSubmitError::Queue(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<QueueWriteError> for WebGpuError { - fn from(err: QueueWriteError) -> Self { - match err { - QueueWriteError::Queue(err) => err.into(), - err => WebGpuError::Validation(err.to_string()), - } - } -} - -impl From<ClearError> for WebGpuError { - fn from(err: ClearError) -> Self { - WebGpuError::Validation(err.to_string()) - } -} - -#[derive(Debug)] -pub struct DomExceptionOperationError { - pub msg: String, -} - -impl DomExceptionOperationError { - pub fn new(msg: &str) -> Self { - DomExceptionOperationError { - msg: msg.to_string(), - } - } -} - -impl fmt::Display for DomExceptionOperationError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad(&self.msg) - } -} - -impl std::error::Error for DomExceptionOperationError {} - -pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { - e.downcast_ref::<DomExceptionOperationError>() - .map(|_| "DOMExceptionOperationError") -} diff --git a/ext/webgpu/src/lib.rs b/ext/webgpu/src/lib.rs deleted file mode 100644 index 77bb10a60..000000000 --- a/ext/webgpu/src/lib.rs +++ /dev/null @@ -1,908 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::include_js_files; -use deno_core::op_async; -use deno_core::op_sync; -use deno_core::Extension; -use deno_core::OpFn; -use deno_core::OpState; -use deno_core::Resource; -use deno_core::ResourceId; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::collections::HashSet; -use std::rc::Rc; -pub use wgpu_core; -pub use wgpu_types; -use wgpu_types::PowerPreference; - -use error::DomExceptionOperationError; -use error::WebGpuResult; - -#[macro_use] -mod macros { - macro_rules! gfx_select { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => { - match $id.backend() { - #[cfg(not(target_os = "macos"))] - wgpu_types::Backend::Vulkan => $global.$method::<wgpu_core::api::Vulkan>( $($param),* ), - #[cfg(target_os = "macos")] - wgpu_types::Backend::Metal => $global.$method::<wgpu_core::api::Metal>( $($param),* ), - #[cfg(windows)] - wgpu_types::Backend::Dx12 => $global.$method::<wgpu_core::api::Dx12>( $($param),* ), - #[cfg(all(unix, not(target_os = "macos")))] - wgpu_types::Backend::Gl => $global.$method::<wgpu_core::api::Gles>( $($param),+ ), - other => panic!("Unexpected backend {:?}", other), - } - }; - } - - 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)); - Ok(WebGpuResult::rid_err(rid, maybe_err)) - }}; - } - - macro_rules! gfx_ok { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {{ - let maybe_err = gfx_select!($id => $global.$method($($param),*)).err(); - Ok(WebGpuResult::maybe_err(maybe_err)) - }}; - } -} - -pub mod binding; -pub mod buffer; -pub mod bundle; -pub mod command_encoder; -pub mod compute_pass; -pub mod error; -pub mod pipeline; -pub mod queue; -pub mod render_pass; -pub mod sampler; -pub mod shader; -pub mod texture; - -pub struct Unstable(pub bool); - -fn check_unstable(state: &OpState, api_name: &str) { - let unstable = state.borrow::<Unstable>(); - if !unstable.0 { - eprintln!( - "Unstable API '{}'. The --unstable flag must be provided.", - api_name - ); - std::process::exit(70); - } -} - -type Instance = wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>; - -struct WebGpuAdapter(wgpu_core::id::AdapterId); -impl Resource for WebGpuAdapter { - fn name(&self) -> Cow<str> { - "webGPUAdapter".into() - } -} - -struct WebGpuDevice(wgpu_core::id::DeviceId); -impl Resource for WebGpuDevice { - fn name(&self) -> Cow<str> { - "webGPUDevice".into() - } -} - -struct WebGpuQuerySet(wgpu_core::id::QuerySetId); -impl Resource for WebGpuQuerySet { - fn name(&self) -> Cow<str> { - "webGPUQuerySet".into() - } -} - -pub fn init(unstable: bool) -> Extension { - Extension::builder() - .js(include_js_files!( - prefix "deno:ext/webgpu", - "01_webgpu.js", - "02_idl_types.js", - )) - .ops(declare_webgpu_ops()) - .state(move |state| { - // TODO: check & possibly streamline this - // Unstable might be able to be OpMiddleware - // let unstable_checker = state.borrow::<super::UnstableChecker>(); - // let unstable = unstable_checker.unstable; - state.put(Unstable(unstable)); - Ok(()) - }) - .build() -} - -fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { - let mut return_features: Vec<&'static str> = vec![]; - - if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { - return_features.push("depth-clip-control"); - } - if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { - return_features.push("pipeline-statistics-query"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { - return_features.push("texture-compression-bc"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { - return_features.push("texture-compression-etc2"); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR) { - return_features.push("texture-compression-astc"); - } - if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { - return_features.push("timestamp-query"); - } - if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) { - return_features.push("indirect-first-instance"); - } - - // extended from spec - if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { - return_features.push("mappable-primary-buffers"); - } - if features.contains(wgpu_types::Features::TEXTURE_BINDING_ARRAY) { - return_features.push("texture-binding-array"); - } - if features.contains(wgpu_types::Features::BUFFER_BINDING_ARRAY) { - return_features.push("buffer-binding-array"); - } - if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) { - return_features.push("storage-resource-binding-array"); - } - if features.contains( - wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, - ) { - return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing"); - } - if features.contains( - wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - ) { - return_features.push("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"); - } - if features.contains(wgpu_types::Features::UNSIZED_BINDING_ARRAY) { - return_features.push("unsized-binding-array"); - } - if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT) { - return_features.push("multi-draw-indirect"); - } - if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT) { - return_features.push("multi-draw-indirect-count"); - } - if features.contains(wgpu_types::Features::PUSH_CONSTANTS) { - return_features.push("push-constants"); - } - if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { - return_features.push("address-mode-clamp-to-border"); - } - if features - .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) - { - return_features.push("texture-adapter-specific-format-features"); - } - if features.contains(wgpu_types::Features::SHADER_FLOAT64) { - return_features.push("shader-float64"); - } - if features.contains(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT) { - return_features.push("vertex-attribute-64bit"); - } - if features.contains(wgpu_types::Features::CONSERVATIVE_RASTERIZATION) { - return_features.push("conservative-rasterization"); - } - if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) { - return_features.push("vertex-writable-storage"); - } - if features.contains(wgpu_types::Features::CLEAR_TEXTURE) { - return_features.push("clear-texture"); - } - if features.contains(wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH) { - return_features.push("spirv-shader-passthrough"); - } - if features.contains(wgpu_types::Features::SHADER_PRIMITIVE_INDEX) { - return_features.push("shader-primitive-index"); - } - - return_features -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RequestAdapterArgs { - power_preference: Option<wgpu_types::PowerPreference>, - force_fallback_adapter: bool, -} - -#[derive(Serialize)] -#[serde(untagged)] -pub enum GpuAdapterDeviceOrErr { - Error { err: String }, - Features(GpuAdapterDevice), -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct GpuAdapterDevice { - rid: ResourceId, - name: Option<String>, - limits: wgpu_types::Limits, - features: Vec<&'static str>, - is_software: bool, -} - -pub async fn op_webgpu_request_adapter( - state: Rc<RefCell<OpState>>, - args: RequestAdapterArgs, - _: (), -) -> Result<GpuAdapterDeviceOrErr, AnyError> { - let mut state = state.borrow_mut(); - check_unstable(&state, "navigator.gpu.requestAdapter"); - let backends = std::env::var("DENO_WEBGPU_BACKEND") - .ok() - .map_or_else(wgpu_types::Backends::all, |s| { - wgpu_core::instance::parse_backends_from_comma_list(&s) - }); - let instance = if let Some(instance) = state.try_borrow::<Instance>() { - instance - } else { - state.put(wgpu_core::hub::Global::new( - "webgpu", - wgpu_core::hub::IdentityManagerFactory, - backends, - )); - state.borrow::<Instance>() - }; - - let descriptor = wgpu_core::instance::RequestAdapterOptions { - power_preference: match args.power_preference { - Some(power_preference) => power_preference, - None => PowerPreference::default(), - }, - force_fallback_adapter: args.force_fallback_adapter, - compatible_surface: None, // windowless - }; - let res = instance.request_adapter( - &descriptor, - wgpu_core::instance::AdapterInputs::Mask(backends, |_| { - std::marker::PhantomData - }), - ); - - let adapter = match res { - Ok(adapter) => adapter, - Err(err) => { - return Ok(GpuAdapterDeviceOrErr::Error { - err: err.to_string(), - }) - } - }; - let name = gfx_select!(adapter => instance.adapter_get_info(adapter))?.name; - let adapter_features = - gfx_select!(adapter => instance.adapter_features(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)); - - Ok(GpuAdapterDeviceOrErr::Features(GpuAdapterDevice { - rid, - name: Some(name), - features, - limits: adapter_limits, - is_software: false, - })) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RequestDeviceArgs { - adapter_rid: ResourceId, - label: Option<String>, - required_features: Option<GpuRequiredFeatures>, - required_limits: Option<wgpu_types::Limits>, -} - -#[derive(Deserialize)] -pub struct GpuRequiredFeatures(HashSet<String>); - -impl From<GpuRequiredFeatures> for wgpu_types::Features { - fn from(required_features: GpuRequiredFeatures) -> wgpu_types::Features { - let mut features: wgpu_types::Features = wgpu_types::Features::empty(); - features.set( - wgpu_types::Features::DEPTH_CLIP_CONTROL, - required_features.0.contains("depth-clip-control"), - ); - features.set( - wgpu_types::Features::PIPELINE_STATISTICS_QUERY, - required_features.0.contains("pipeline-statistics-query"), - ); - features.set( - wgpu_types::Features::TEXTURE_COMPRESSION_BC, - required_features.0.contains("texture-compression-bc"), - ); - features.set( - wgpu_types::Features::TEXTURE_COMPRESSION_ETC2, - required_features.0.contains("texture-compression-etc2"), - ); - features.set( - wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_LDR, - required_features.0.contains("texture-compression-astc"), - ); - features.set( - wgpu_types::Features::TIMESTAMP_QUERY, - required_features.0.contains("timestamp-query"), - ); - features.set( - wgpu_types::Features::INDIRECT_FIRST_INSTANCE, - required_features.0.contains("indirect-first-instance"), - ); - - // extended from spec - features.set( - wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS, - required_features.0.contains("mappable-primary-buffers"), - ); - features.set( - wgpu_types::Features::TEXTURE_BINDING_ARRAY, - required_features.0.contains("texture-binding-array"), - ); - features.set( - wgpu_types::Features::BUFFER_BINDING_ARRAY, - required_features.0.contains("buffer-binding-array"), - ); - features.set( - wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY, - required_features - .0 - .contains("storage-resource-binding-array"), - ); - features.set( - wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, - required_features - .0 - .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"), - ); - features.set( - wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - required_features - .0 - .contains("uniform-buffer-and-storage-buffer-texture-non-uniform-indexing"), - ); - features.set( - wgpu_types::Features::UNSIZED_BINDING_ARRAY, - required_features.0.contains("unsized-binding-array"), - ); - features.set( - wgpu_types::Features::MULTI_DRAW_INDIRECT, - required_features.0.contains("multi-draw-indirect"), - ); - features.set( - wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT, - required_features.0.contains("multi-draw-indirect-count"), - ); - features.set( - wgpu_types::Features::PUSH_CONSTANTS, - required_features.0.contains("push-constants"), - ); - features.set( - wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER, - required_features.0.contains("address-mode-clamp-to-border"), - ); - features.set( - wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, - required_features - .0 - .contains("texture-adapter-specific-format-features"), - ); - features.set( - wgpu_types::Features::SHADER_FLOAT64, - required_features.0.contains("shader-float64"), - ); - features.set( - wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT, - required_features.0.contains("vertex-attribute-64bit"), - ); - features.set( - wgpu_types::Features::CONSERVATIVE_RASTERIZATION, - required_features.0.contains("conservative-rasterization"), - ); - features.set( - wgpu_types::Features::VERTEX_WRITABLE_STORAGE, - required_features.0.contains("vertex-writable-storage"), - ); - features.set( - wgpu_types::Features::CLEAR_TEXTURE, - required_features.0.contains("clear-commands"), - ); - features.set( - wgpu_types::Features::SPIRV_SHADER_PASSTHROUGH, - required_features.0.contains("spirv-shader-passthrough"), - ); - features.set( - wgpu_types::Features::SHADER_PRIMITIVE_INDEX, - required_features.0.contains("shader-primitive-index"), - ); - - features - } -} - -pub async fn op_webgpu_request_device( - state: Rc<RefCell<OpState>>, - args: RequestDeviceArgs, - _: (), -) -> Result<GpuAdapterDevice, AnyError> { - let mut state = state.borrow_mut(); - let adapter_resource = state - .resource_table - .get::<WebGpuAdapter>(args.adapter_rid)?; - let adapter = adapter_resource.0; - let instance = state.borrow::<Instance>(); - - let descriptor = wgpu_types::DeviceDescriptor { - label: args.label.map(Cow::from), - features: args.required_features.map(Into::into).unwrap_or_default(), - limits: args.required_limits.map(Into::into).unwrap_or_default(), - }; - - let (device, maybe_err) = gfx_select!(adapter => instance.adapter_request_device( - adapter, - &descriptor, - std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), - std::marker::PhantomData - )); - if let Some(err) = maybe_err { - return Err(DomExceptionOperationError::new(&err.to_string()).into()); - } - - let device_features = - gfx_select!(device => instance.device_features(device))?; - let features = deserialize_features(&device_features); - let limits = gfx_select!(device => instance.device_limits(device))?; - - let rid = state.resource_table.add(WebGpuDevice(device)); - - Ok(GpuAdapterDevice { - rid, - name: None, - features, - limits, - // TODO(lucacasonato): report correctly from wgpu - is_software: false, - }) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateQuerySetArgs { - device_rid: ResourceId, - label: Option<String>, - #[serde(flatten)] - r#type: GpuQueryType, - count: u32, -} - -#[derive(Deserialize)] -#[serde(rename_all = "kebab-case", tag = "type")] -enum GpuQueryType { - Occlusion, - #[serde(rename_all = "camelCase")] - PipelineStatistics { - pipeline_statistics: HashSet<String>, - }, - Timestamp, -} - -impl From<GpuQueryType> for wgpu_types::QueryType { - fn from(query_type: GpuQueryType) -> Self { - match query_type { - GpuQueryType::Occlusion => wgpu_types::QueryType::Occlusion, - GpuQueryType::PipelineStatistics { - pipeline_statistics, - } => { - use wgpu_types::PipelineStatisticsTypes; - - let mut types = PipelineStatisticsTypes::empty(); - - if pipeline_statistics.contains("vertex-shader-invocations") { - types.set(PipelineStatisticsTypes::VERTEX_SHADER_INVOCATIONS, true); - } - if pipeline_statistics.contains("clipper-invocations") { - types.set(PipelineStatisticsTypes::CLIPPER_INVOCATIONS, true); - } - if pipeline_statistics.contains("clipper-primitives-out") { - types.set(PipelineStatisticsTypes::CLIPPER_PRIMITIVES_OUT, true); - } - if pipeline_statistics.contains("fragment-shader-invocations") { - types.set(PipelineStatisticsTypes::FRAGMENT_SHADER_INVOCATIONS, true); - } - if pipeline_statistics.contains("compute-shader-invocations") { - types.set(PipelineStatisticsTypes::COMPUTE_SHADER_INVOCATIONS, true); - } - - wgpu_types::QueryType::PipelineStatistics(types) - } - GpuQueryType::Timestamp => wgpu_types::QueryType::Timestamp, - } - } -} - -pub fn op_webgpu_create_query_set( - state: &mut OpState, - 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 descriptor = wgpu_types::QuerySetDescriptor { - label: args.label.map(Cow::from), - ty: args.r#type.into(), - count: args.count, - }; - - gfx_put!(device => instance.device_create_query_set( - device, - &descriptor, - std::marker::PhantomData - ) => state, WebGpuQuerySet) -} - -fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> { - vec![ - // Request device/adapter - ( - "op_webgpu_request_adapter", - op_async(op_webgpu_request_adapter), - ), - ( - "op_webgpu_request_device", - op_async(op_webgpu_request_device), - ), - // Query Set - ( - "op_webgpu_create_query_set", - op_sync(op_webgpu_create_query_set), - ), - // buffer - ( - "op_webgpu_create_buffer", - op_sync(buffer::op_webgpu_create_buffer), - ), - ( - "op_webgpu_buffer_get_mapped_range", - op_sync(buffer::op_webgpu_buffer_get_mapped_range), - ), - ( - "op_webgpu_buffer_unmap", - op_sync(buffer::op_webgpu_buffer_unmap), - ), - // buffer async - ( - "op_webgpu_buffer_get_map_async", - op_async(buffer::op_webgpu_buffer_get_map_async), - ), - // remaining sync ops - - // texture - ( - "op_webgpu_create_texture", - op_sync(texture::op_webgpu_create_texture), - ), - ( - "op_webgpu_create_texture_view", - op_sync(texture::op_webgpu_create_texture_view), - ), - // sampler - ( - "op_webgpu_create_sampler", - op_sync(sampler::op_webgpu_create_sampler), - ), - // binding - ( - "op_webgpu_create_bind_group_layout", - op_sync(binding::op_webgpu_create_bind_group_layout), - ), - ( - "op_webgpu_create_pipeline_layout", - op_sync(binding::op_webgpu_create_pipeline_layout), - ), - ( - "op_webgpu_create_bind_group", - op_sync(binding::op_webgpu_create_bind_group), - ), - // pipeline - ( - "op_webgpu_create_compute_pipeline", - op_sync(pipeline::op_webgpu_create_compute_pipeline), - ), - ( - "op_webgpu_compute_pipeline_get_bind_group_layout", - op_sync(pipeline::op_webgpu_compute_pipeline_get_bind_group_layout), - ), - ( - "op_webgpu_create_render_pipeline", - op_sync(pipeline::op_webgpu_create_render_pipeline), - ), - ( - "op_webgpu_render_pipeline_get_bind_group_layout", - op_sync(pipeline::op_webgpu_render_pipeline_get_bind_group_layout), - ), - // command_encoder - ( - "op_webgpu_create_command_encoder", - op_sync(command_encoder::op_webgpu_create_command_encoder), - ), - ( - "op_webgpu_command_encoder_begin_render_pass", - op_sync(command_encoder::op_webgpu_command_encoder_begin_render_pass), - ), - ( - "op_webgpu_command_encoder_begin_compute_pass", - op_sync(command_encoder::op_webgpu_command_encoder_begin_compute_pass), - ), - ( - "op_webgpu_command_encoder_copy_buffer_to_buffer", - op_sync(command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer), - ), - ( - "op_webgpu_command_encoder_copy_buffer_to_texture", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture, - ), - ), - ( - "op_webgpu_command_encoder_copy_texture_to_buffer", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer, - ), - ), - ( - "op_webgpu_command_encoder_copy_texture_to_texture", - op_sync( - command_encoder::op_webgpu_command_encoder_copy_texture_to_texture, - ), - ), - ( - "op_webgpu_command_encoder_clear_buffer", - op_sync(command_encoder::op_webgpu_command_encoder_clear_buffer), - ), - ( - "op_webgpu_command_encoder_push_debug_group", - op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group), - ), - ( - "op_webgpu_command_encoder_pop_debug_group", - op_sync(command_encoder::op_webgpu_command_encoder_pop_debug_group), - ), - ( - "op_webgpu_command_encoder_insert_debug_marker", - op_sync(command_encoder::op_webgpu_command_encoder_insert_debug_marker), - ), - ( - "op_webgpu_command_encoder_write_timestamp", - op_sync(command_encoder::op_webgpu_command_encoder_write_timestamp), - ), - ( - "op_webgpu_command_encoder_resolve_query_set", - op_sync(command_encoder::op_webgpu_command_encoder_resolve_query_set), - ), - ( - "op_webgpu_command_encoder_finish", - op_sync(command_encoder::op_webgpu_command_encoder_finish), - ), - // render_pass - ( - "op_webgpu_render_pass_set_viewport", - op_sync(render_pass::op_webgpu_render_pass_set_viewport), - ), - ( - "op_webgpu_render_pass_set_scissor_rect", - op_sync(render_pass::op_webgpu_render_pass_set_scissor_rect), - ), - ( - "op_webgpu_render_pass_set_blend_constant", - op_sync(render_pass::op_webgpu_render_pass_set_blend_constant), - ), - ( - "op_webgpu_render_pass_set_stencil_reference", - op_sync(render_pass::op_webgpu_render_pass_set_stencil_reference), - ), - ( - "op_webgpu_render_pass_begin_pipeline_statistics_query", - op_sync( - render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query, - ), - ), - ( - "op_webgpu_render_pass_end_pipeline_statistics_query", - op_sync(render_pass::op_webgpu_render_pass_end_pipeline_statistics_query), - ), - ( - "op_webgpu_render_pass_write_timestamp", - op_sync(render_pass::op_webgpu_render_pass_write_timestamp), - ), - ( - "op_webgpu_render_pass_execute_bundles", - op_sync(render_pass::op_webgpu_render_pass_execute_bundles), - ), - ( - "op_webgpu_render_pass_end_pass", - op_sync(render_pass::op_webgpu_render_pass_end_pass), - ), - ( - "op_webgpu_render_pass_set_bind_group", - op_sync(render_pass::op_webgpu_render_pass_set_bind_group), - ), - ( - "op_webgpu_render_pass_push_debug_group", - op_sync(render_pass::op_webgpu_render_pass_push_debug_group), - ), - ( - "op_webgpu_render_pass_pop_debug_group", - op_sync(render_pass::op_webgpu_render_pass_pop_debug_group), - ), - ( - "op_webgpu_render_pass_insert_debug_marker", - op_sync(render_pass::op_webgpu_render_pass_insert_debug_marker), - ), - ( - "op_webgpu_render_pass_set_pipeline", - op_sync(render_pass::op_webgpu_render_pass_set_pipeline), - ), - ( - "op_webgpu_render_pass_set_index_buffer", - op_sync(render_pass::op_webgpu_render_pass_set_index_buffer), - ), - ( - "op_webgpu_render_pass_set_vertex_buffer", - op_sync(render_pass::op_webgpu_render_pass_set_vertex_buffer), - ), - ( - "op_webgpu_render_pass_draw", - op_sync(render_pass::op_webgpu_render_pass_draw), - ), - ( - "op_webgpu_render_pass_draw_indexed", - op_sync(render_pass::op_webgpu_render_pass_draw_indexed), - ), - ( - "op_webgpu_render_pass_draw_indirect", - op_sync(render_pass::op_webgpu_render_pass_draw_indirect), - ), - ( - "op_webgpu_render_pass_draw_indexed_indirect", - op_sync(render_pass::op_webgpu_render_pass_draw_indexed_indirect), - ), - // compute_pass - ( - "op_webgpu_compute_pass_set_pipeline", - op_sync(compute_pass::op_webgpu_compute_pass_set_pipeline), - ), - ( - "op_webgpu_compute_pass_dispatch", - op_sync(compute_pass::op_webgpu_compute_pass_dispatch), - ), - ( - "op_webgpu_compute_pass_dispatch_indirect", - op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect), - ), - ( - "op_webgpu_compute_pass_begin_pipeline_statistics_query", - op_sync( - compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query, - ), - ), - ( - "op_webgpu_compute_pass_end_pipeline_statistics_query", - op_sync( - compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query, - ), - ), - ( - "op_webgpu_compute_pass_write_timestamp", - op_sync(compute_pass::op_webgpu_compute_pass_write_timestamp), - ), - ( - "op_webgpu_compute_pass_end_pass", - op_sync(compute_pass::op_webgpu_compute_pass_end_pass), - ), - ( - "op_webgpu_compute_pass_set_bind_group", - op_sync(compute_pass::op_webgpu_compute_pass_set_bind_group), - ), - ( - "op_webgpu_compute_pass_push_debug_group", - op_sync(compute_pass::op_webgpu_compute_pass_push_debug_group), - ), - ( - "op_webgpu_compute_pass_pop_debug_group", - op_sync(compute_pass::op_webgpu_compute_pass_pop_debug_group), - ), - ( - "op_webgpu_compute_pass_insert_debug_marker", - op_sync(compute_pass::op_webgpu_compute_pass_insert_debug_marker), - ), - // bundle - ( - "op_webgpu_create_render_bundle_encoder", - op_sync(bundle::op_webgpu_create_render_bundle_encoder), - ), - ( - "op_webgpu_render_bundle_encoder_finish", - op_sync(bundle::op_webgpu_render_bundle_encoder_finish), - ), - ( - "op_webgpu_render_bundle_encoder_set_bind_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_bind_group), - ), - ( - "op_webgpu_render_bundle_encoder_push_debug_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_push_debug_group), - ), - ( - "op_webgpu_render_bundle_encoder_pop_debug_group", - op_sync(bundle::op_webgpu_render_bundle_encoder_pop_debug_group), - ), - ( - "op_webgpu_render_bundle_encoder_insert_debug_marker", - op_sync(bundle::op_webgpu_render_bundle_encoder_insert_debug_marker), - ), - ( - "op_webgpu_render_bundle_encoder_set_pipeline", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_pipeline), - ), - ( - "op_webgpu_render_bundle_encoder_set_index_buffer", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_index_buffer), - ), - ( - "op_webgpu_render_bundle_encoder_set_vertex_buffer", - op_sync(bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer), - ), - ( - "op_webgpu_render_bundle_encoder_draw", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw), - ), - ( - "op_webgpu_render_bundle_encoder_draw_indexed", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indexed), - ), - ( - "op_webgpu_render_bundle_encoder_draw_indirect", - op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indirect), - ), - // queue - ( - "op_webgpu_queue_submit", - op_sync(queue::op_webgpu_queue_submit), - ), - ( - "op_webgpu_write_buffer", - op_sync(queue::op_webgpu_write_buffer), - ), - ( - "op_webgpu_write_texture", - op_sync(queue::op_webgpu_write_texture), - ), - // shader - ( - "op_webgpu_create_shader_module", - op_sync(shader::op_webgpu_create_shader_module), - ), - ] -} diff --git a/ext/webgpu/src/queue.rs b/ext/webgpu/src/queue.rs deleted file mode 100644 index a662c4ead..000000000 --- a/ext/webgpu/src/queue.rs +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use std::num::NonZeroU32; - -use deno_core::error::AnyError; -use deno_core::OpState; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use serde::Deserialize; - -use super::error::WebGpuResult; - -type WebGpuQueue = super::WebGpuDevice; - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueSubmitArgs { - queue_rid: ResourceId, - command_buffers: Vec<ResourceId>, -} - -pub fn op_webgpu_queue_submit( - state: &mut OpState, - args: QueueSubmitArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let queue_resource = - state.resource_table.get::<WebGpuQueue>(args.queue_rid)?; - let queue = queue_resource.0; - - let mut ids = vec![]; - - for rid in args.command_buffers { - let buffer_resource = - state - .resource_table - .get::<super::command_encoder::WebGpuCommandBuffer>(rid)?; - ids.push(buffer_resource.0); - } - - let maybe_err = - gfx_select!(queue => instance.queue_submit(queue, &ids)).err(); - - Ok(WebGpuResult::maybe_err(maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GpuImageDataLayout { - offset: u64, - bytes_per_row: Option<u32>, - rows_per_image: Option<u32>, -} - -impl From<GpuImageDataLayout> for wgpu_types::ImageDataLayout { - fn from(layout: GpuImageDataLayout) -> Self { - wgpu_types::ImageDataLayout { - offset: layout.offset, - bytes_per_row: NonZeroU32::new(layout.bytes_per_row.unwrap_or(0)), - rows_per_image: NonZeroU32::new(layout.rows_per_image.unwrap_or(0)), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueWriteBufferArgs { - queue_rid: ResourceId, - buffer: ResourceId, - buffer_offset: u64, - data_offset: usize, - size: Option<usize>, -} - -pub fn op_webgpu_write_buffer( - state: &mut OpState, - args: QueueWriteBufferArgs, - zero_copy: ZeroCopyBuf, -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer)?; - let buffer = buffer_resource.0; - let queue_resource = - state.resource_table.get::<WebGpuQueue>(args.queue_rid)?; - let queue = queue_resource.0; - - let data = match args.size { - Some(size) => &zero_copy[args.data_offset..(args.data_offset + size)], - None => &zero_copy[args.data_offset..], - }; - let maybe_err = gfx_select!(queue => instance.queue_write_buffer( - queue, - buffer, - args.buffer_offset, - data - )) - .err(); - - Ok(WebGpuResult::maybe_err(maybe_err)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct QueueWriteTextureArgs { - queue_rid: ResourceId, - destination: super::command_encoder::GpuImageCopyTexture, - data_layout: GpuImageDataLayout, - size: wgpu_types::Extent3d, -} - -pub fn op_webgpu_write_texture( - state: &mut OpState, - args: QueueWriteTextureArgs, - zero_copy: ZeroCopyBuf, -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let texture_resource = state - .resource_table - .get::<super::texture::WebGpuTexture>(args.destination.texture)?; - let queue_resource = - state.resource_table.get::<WebGpuQueue>(args.queue_rid)?; - let queue = queue_resource.0; - - let destination = wgpu_core::command::ImageCopyTexture { - texture: texture_resource.0, - mip_level: args.destination.mip_level, - origin: args.destination.origin, - aspect: args.destination.aspect, - }; - let data_layout = args.data_layout.into(); - - gfx_ok!(queue => instance.queue_write_texture( - queue, - &destination, - &*zero_copy, - &data_layout, - &args.size - )) -} diff --git a/ext/webgpu/src/render_pass.rs b/ext/webgpu/src/render_pass.rs deleted file mode 100644 index 469bf727e..000000000 --- a/ext/webgpu/src/render_pass.rs +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::type_error; -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::ZeroCopyBuf; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; -use std::cell::RefCell; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuRenderPass( - pub(crate) RefCell<wgpu_core::command::RenderPass>, -); -impl Resource for WebGpuRenderPass { - fn name(&self) -> Cow<str> { - "webGPURenderPass".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetViewportArgs { - render_pass_rid: ResourceId, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, -} - -pub fn op_webgpu_render_pass_set_viewport( - state: &mut OpState, - args: RenderPassSetViewportArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_viewport( - &mut render_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.width, - args.height, - args.min_depth, - args.max_depth, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetScissorRectArgs { - render_pass_rid: ResourceId, - x: u32, - y: u32, - width: u32, - height: u32, -} - -pub fn op_webgpu_render_pass_set_scissor_rect( - state: &mut OpState, - args: RenderPassSetScissorRectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_scissor_rect( - &mut render_pass_resource.0.borrow_mut(), - args.x, - args.y, - args.width, - args.height, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetBlendConstantArgs { - render_pass_rid: ResourceId, - color: wgpu_types::Color, -} - -pub fn op_webgpu_render_pass_set_blend_constant( - state: &mut OpState, - args: RenderPassSetBlendConstantArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_blend_constant( - &mut render_pass_resource.0.borrow_mut(), - &args.color, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetStencilReferenceArgs { - render_pass_rid: ResourceId, - reference: u32, -} - -pub fn op_webgpu_render_pass_set_stencil_reference( - state: &mut OpState, - args: RenderPassSetStencilReferenceArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_stencil_reference( - &mut render_pass_resource.0.borrow_mut(), - args.reference, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassBeginPipelineStatisticsQueryArgs { - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_render_pass_begin_pipeline_statistics_query( - state: &mut OpState, - args: RenderPassBeginPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_begin_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassEndPipelineStatisticsQueryArgs { - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_end_pipeline_statistics_query( - state: &mut OpState, - args: RenderPassEndPipelineStatisticsQueryArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_end_pipeline_statistics_query( - &mut render_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassWriteTimestampArgs { - render_pass_rid: ResourceId, - query_set: u32, - query_index: u32, -} - -pub fn op_webgpu_render_pass_write_timestamp( - state: &mut OpState, - args: RenderPassWriteTimestampArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - let query_set_resource = state - .resource_table - .get::<super::WebGpuQuerySet>(args.query_set)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_write_timestamp( - &mut render_pass_resource.0.borrow_mut(), - query_set_resource.0, - args.query_index, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassExecuteBundlesArgs { - render_pass_rid: ResourceId, - bundles: Vec<u32>, -} - -pub fn op_webgpu_render_pass_execute_bundles( - state: &mut OpState, - args: RenderPassExecuteBundlesArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let mut render_bundle_ids = vec![]; - - for rid in &args.bundles { - let render_bundle_resource = - state - .resource_table - .get::<super::bundle::WebGpuRenderBundle>(*rid)?; - render_bundle_ids.push(render_bundle_resource.0); - } - - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - // SAFETY: the raw pointer and length are of the same slice, and that slice - // lives longer than the below function invocation. - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_execute_bundles( - &mut render_pass_resource.0.borrow_mut(), - render_bundle_ids.as_ptr(), - render_bundle_ids.len(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassEndPassArgs { - command_encoder_rid: ResourceId, - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_end_pass( - state: &mut OpState, - args: RenderPassEndPassArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let command_encoder_resource = state - .resource_table - .get::<super::command_encoder::WebGpuCommandEncoder>( - args.command_encoder_rid, - )?; - let command_encoder = command_encoder_resource.0; - let render_pass_resource = state - .resource_table - .take::<WebGpuRenderPass>(args.render_pass_rid)?; - let render_pass = &render_pass_resource.0.borrow(); - let instance = state.borrow::<super::Instance>(); - - gfx_ok!(command_encoder => instance.command_encoder_run_render_pass(command_encoder, render_pass)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetBindGroupArgs { - render_pass_rid: ResourceId, - index: u32, - bind_group: u32, - dynamic_offsets_data: ZeroCopyBuf, - dynamic_offsets_data_start: usize, - dynamic_offsets_data_length: usize, -} - -pub fn op_webgpu_render_pass_set_bind_group( - state: &mut OpState, - args: RenderPassSetBindGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let bind_group_resource = - state - .resource_table - .get::<super::binding::WebGpuBindGroup>(args.bind_group)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - // Align the data - assert!(args.dynamic_offsets_data_start % std::mem::size_of::<u32>() == 0); - // SAFETY: A u8 to u32 cast is safe because we asserted that the length is a - // multiple of 4. - let (prefix, dynamic_offsets_data, suffix) = - unsafe { args.dynamic_offsets_data.align_to::<u32>() }; - assert!(prefix.is_empty()); - assert!(suffix.is_empty()); - - let start = args.dynamic_offsets_data_start; - let len = args.dynamic_offsets_data_length; - - // Assert that length and start are both in bounds - assert!(start <= dynamic_offsets_data.len()); - assert!(len <= dynamic_offsets_data.len() - start); - - let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; - - // SAFETY: the raw pointer and length are of the same slice, and that slice - // lives longer than the below function invocation. - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_set_bind_group( - &mut render_pass_resource.0.borrow_mut(), - args.index, - bind_group_resource.0, - dynamic_offsets_data.as_ptr(), - dynamic_offsets_data.len(), - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassPushDebugGroupArgs { - render_pass_rid: ResourceId, - group_label: String, -} - -pub fn op_webgpu_render_pass_push_debug_group( - state: &mut OpState, - args: RenderPassPushDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - let label = std::ffi::CString::new(args.group_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_push_debug_group( - &mut render_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassPopDebugGroupArgs { - render_pass_rid: ResourceId, -} - -pub fn op_webgpu_render_pass_pop_debug_group( - state: &mut OpState, - args: RenderPassPopDebugGroupArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_pop_debug_group( - &mut render_pass_resource.0.borrow_mut(), - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassInsertDebugMarkerArgs { - render_pass_rid: ResourceId, - marker_label: String, -} - -pub fn op_webgpu_render_pass_insert_debug_marker( - state: &mut OpState, - args: RenderPassInsertDebugMarkerArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - let label = std::ffi::CString::new(args.marker_label).unwrap(); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::render_ffi::wgpu_render_pass_insert_debug_marker( - &mut render_pass_resource.0.borrow_mut(), - label.as_ptr(), - 0, // wgpu#975 - ); - } - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetPipelineArgs { - render_pass_rid: ResourceId, - pipeline: u32, -} - -pub fn op_webgpu_render_pass_set_pipeline( - state: &mut OpState, - args: RenderPassSetPipelineArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pipeline_resource = - state - .resource_table - .get::<super::pipeline::WebGpuRenderPipeline>(args.pipeline)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_pipeline( - &mut render_pass_resource.0.borrow_mut(), - render_pipeline_resource.0, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetIndexBufferArgs { - render_pass_rid: ResourceId, - buffer: u32, - index_format: wgpu_types::IndexFormat, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_render_pass_set_index_buffer( - state: &mut OpState, - args: RenderPassSetIndexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - let size = if let Some(size) = args.size { - Some( - std::num::NonZeroU64::new(size) - .ok_or_else(|| type_error("size must be larger than 0"))?, - ) - } else { - None - }; - - render_pass_resource.0.borrow_mut().set_index_buffer( - buffer_resource.0, - args.index_format, - args.offset, - size, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassSetVertexBufferArgs { - render_pass_rid: ResourceId, - slot: u32, - buffer: u32, - offset: u64, - size: Option<u64>, -} - -pub fn op_webgpu_render_pass_set_vertex_buffer( - state: &mut OpState, - args: RenderPassSetVertexBufferArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.buffer)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - let size = if let Some(size) = args.size { - Some( - std::num::NonZeroU64::new(size) - .ok_or_else(|| type_error("size must be larger than 0"))?, - ) - } else { - None - }; - - wgpu_core::command::render_ffi::wgpu_render_pass_set_vertex_buffer( - &mut render_pass_resource.0.borrow_mut(), - args.slot, - buffer_resource.0, - args.offset, - size, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawArgs { - render_pass_rid: ResourceId, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, -} - -pub fn op_webgpu_render_pass_draw( - state: &mut OpState, - args: RenderPassDrawArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw( - &mut render_pass_resource.0.borrow_mut(), - args.vertex_count, - args.instance_count, - args.first_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndexedArgs { - render_pass_rid: ResourceId, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, -} - -pub fn op_webgpu_render_pass_draw_indexed( - state: &mut OpState, - args: RenderPassDrawIndexedArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed( - &mut render_pass_resource.0.borrow_mut(), - args.index_count, - args.instance_count, - args.first_index, - args.base_vertex, - args.first_instance, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndirectArgs { - render_pass_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_pass_draw_indirect( - state: &mut OpState, - args: RenderPassDrawIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indirect( - &mut render_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RenderPassDrawIndexedIndirectArgs { - render_pass_rid: ResourceId, - indirect_buffer: u32, - indirect_offset: u64, -} - -pub fn op_webgpu_render_pass_draw_indexed_indirect( - state: &mut OpState, - args: RenderPassDrawIndexedIndirectArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let buffer_resource = state - .resource_table - .get::<super::buffer::WebGpuBuffer>(args.indirect_buffer)?; - let render_pass_resource = state - .resource_table - .get::<WebGpuRenderPass>(args.render_pass_rid)?; - - wgpu_core::command::render_ffi::wgpu_render_pass_draw_indexed_indirect( - &mut render_pass_resource.0.borrow_mut(), - buffer_resource.0, - args.indirect_offset, - ); - - Ok(WebGpuResult::empty()) -} diff --git a/ext/webgpu/src/shader.rs b/ext/webgpu/src/shader.rs deleted file mode 100644 index 60290de8b..000000000 --- a/ext/webgpu/src/shader.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -use deno_core::ResourceId; -use deno_core::{OpState, Resource}; -use serde::Deserialize; -use std::borrow::Cow; - -use super::error::WebGpuResult; - -pub(crate) struct WebGpuShaderModule(pub(crate) wgpu_core::id::ShaderModuleId); -impl Resource for WebGpuShaderModule { - fn name(&self) -> Cow<str> { - "webGPUShaderModule".into() - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CreateShaderModuleArgs { - device_rid: ResourceId, - label: Option<String>, - code: String, - _source_map: Option<()>, // not yet implemented -} - -pub fn op_webgpu_create_shader_module( - state: &mut OpState, - args: CreateShaderModuleArgs, - _: (), -) -> Result<WebGpuResult, AnyError> { - let instance = state.borrow::<super::Instance>(); - let device_resource = state - .resource_table - .get::<super::WebGpuDevice>(args.device_rid)?; - let device = device_resource.0; - - let source = - wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::from(args.code)); - - let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { - label: args.label.map(Cow::from), - shader_bound_checks: wgpu_types::ShaderBoundChecks::default(), - }; - - gfx_put!(device => instance.device_create_shader_module( - device, - &descriptor, - source, - std::marker::PhantomData - ) => state, WebGpuShaderModule) -} |