diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2023-01-30 15:14:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-30 15:14:16 +0100 |
commit | 3035dee9f14402f57d42ff0b362152140b4dca13 (patch) | |
tree | b9a3d3d36e368b3585970ffe00127c90e16b7a09 /ext/webgpu/src/surface.rs | |
parent | 266915d5ce354fde12b20f8f5ceb5ffdfacb7983 (diff) |
chore: update webgpu (#17534)
Diffstat (limited to 'ext/webgpu/src/surface.rs')
-rw-r--r-- | ext/webgpu/src/surface.rs | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/ext/webgpu/src/surface.rs b/ext/webgpu/src/surface.rs new file mode 100644 index 000000000..1adebb53a --- /dev/null +++ b/ext/webgpu/src/surface.rs @@ -0,0 +1,137 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +use super::WebGpuResult; +use deno_core::error::AnyError; +use deno_core::include_js_files; +use deno_core::op; +use deno_core::Extension; +use deno_core::OpState; +use deno_core::Resource; +use deno_core::ResourceId; +use serde::Deserialize; +use std::borrow::Cow; +use wgpu_types::SurfaceStatus; + +pub fn init_surface(unstable: bool) -> Extension { + Extension::builder("deno_webgpu_surface") + .dependencies(vec!["deno_webidl", "deno_web", "deno_webgpu"]) + .js(include_js_files!( + prefix "deno:deno_webgpu", + "03_surface.js", + "04_surface_idl_types.js", + )) + .ops(vec![ + op_webgpu_surface_configure::decl(), + op_webgpu_surface_get_current_texture::decl(), + op_webgpu_surface_present::decl(), + ]) + .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(super::Unstable(unstable)); + Ok(()) + }) + .build() +} + +pub struct WebGpuSurface(pub wgpu_core::id::SurfaceId); +impl Resource for WebGpuSurface { + fn name(&self) -> Cow<str> { + "webGPUSurface".into() + } +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SurfaceConfigureArgs { + surface_rid: ResourceId, + device_rid: ResourceId, + format: wgpu_types::TextureFormat, + usage: u32, + width: u32, + height: u32, + present_mode: Option<wgpu_types::PresentMode>, + alpha_mode: wgpu_types::CompositeAlphaMode, + view_formats: Vec<wgpu_types::TextureFormat>, +} + +#[op] +pub fn op_webgpu_surface_configure( + state: &mut OpState, + args: SurfaceConfigureArgs, +) -> 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 surface_resource = state + .resource_table + .get::<WebGpuSurface>(args.surface_rid)?; + let surface = surface_resource.0; + + let conf = wgpu_types::SurfaceConfiguration::<Vec<wgpu_types::TextureFormat>> { + usage: wgpu_types::TextureUsages::from_bits_truncate(args.usage), + format: args.format, + width: args.width, + height: args.height, + present_mode: args.present_mode.unwrap_or_default(), + alpha_mode: args.alpha_mode, + view_formats: args.view_formats, + }; + + let err = + gfx_select!(device => instance.surface_configure(surface, device, &conf)); + + Ok(WebGpuResult::maybe_err(err)) +} + +#[op] +pub fn op_webgpu_surface_get_current_texture( + state: &mut OpState, + device_rid: ResourceId, + surface_rid: ResourceId, +) -> Result<WebGpuResult, AnyError> { + let instance = state.borrow::<super::Instance>(); + let device_resource = state + .resource_table + .get::<super::WebGpuDevice>(device_rid)?; + let device = device_resource.0; + let surface_resource = + state.resource_table.get::<WebGpuSurface>(surface_rid)?; + let surface = surface_resource.0; + + let output = + gfx_select!(device => instance.surface_get_current_texture(surface, ()))?; + + match output.status { + SurfaceStatus::Good | SurfaceStatus::Suboptimal => { + let id = output.texture_id.unwrap(); + let rid = state.resource_table.add(crate::texture::WebGpuTexture(id)); + Ok(WebGpuResult::rid(rid)) + } + _ => Err(AnyError::msg("Invalid Surface Status")), + } +} + +#[op] +pub fn op_webgpu_surface_present( + state: &mut OpState, + device_rid: ResourceId, + surface_rid: ResourceId, +) -> Result<(), AnyError> { + let instance = state.borrow::<super::Instance>(); + let device_resource = state + .resource_table + .get::<super::WebGpuDevice>(device_rid)?; + let device = device_resource.0; + let surface_resource = + state.resource_table.get::<WebGpuSurface>(surface_rid)?; + let surface = surface_resource.0; + + let _ = gfx_select!(device => instance.surface_present(surface))?; + + Ok(()) +} |