2023-01-14 16:07:46 +00:00
|
|
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
2023-01-09 15:44:20 +00:00
|
|
|
|
|
|
|
use super::WebGpuResult;
|
|
|
|
use deno_core::error::AnyError;
|
2023-10-04 04:25:56 +00:00
|
|
|
use deno_core::op2;
|
2023-01-09 15:44:20 +00:00
|
|
|
use deno_core::OpState;
|
|
|
|
use deno_core::Resource;
|
|
|
|
use deno_core::ResourceId;
|
|
|
|
use serde::Deserialize;
|
|
|
|
use std::borrow::Cow;
|
2023-03-03 17:18:01 +00:00
|
|
|
use std::rc::Rc;
|
2023-01-09 15:44:20 +00:00
|
|
|
use wgpu_types::SurfaceStatus;
|
|
|
|
|
2023-06-06 15:08:32 +00:00
|
|
|
deno_core::extension!(
|
|
|
|
deno_webgpu_surface,
|
|
|
|
deps = [deno_webidl, deno_web, deno_webgpu],
|
|
|
|
ops = [
|
|
|
|
op_webgpu_surface_configure,
|
|
|
|
op_webgpu_surface_get_current_texture,
|
|
|
|
op_webgpu_surface_present,
|
|
|
|
],
|
|
|
|
esm = ["02_surface.js"],
|
|
|
|
options = { unstable: bool },
|
|
|
|
state = |state, options| {
|
|
|
|
state.put(super::Unstable(options.unstable));
|
|
|
|
},
|
|
|
|
);
|
2023-03-11 06:24:20 +00:00
|
|
|
|
2023-03-03 17:18:01 +00:00
|
|
|
pub struct WebGpuSurface(pub crate::Instance, pub wgpu_core::id::SurfaceId);
|
2023-01-09 15:44:20 +00:00
|
|
|
impl Resource for WebGpuSurface {
|
|
|
|
fn name(&self) -> Cow<str> {
|
|
|
|
"webGPUSurface".into()
|
|
|
|
}
|
2023-03-03 17:18:01 +00:00
|
|
|
|
|
|
|
fn close(self: Rc<Self>) {
|
|
|
|
self.0.surface_drop(self.1);
|
|
|
|
}
|
2023-01-09 15:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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,
|
2023-01-25 21:04:41 +00:00
|
|
|
view_formats: Vec<wgpu_types::TextureFormat>,
|
2023-01-09 15:44:20 +00:00
|
|
|
}
|
|
|
|
|
2023-10-04 04:25:56 +00:00
|
|
|
#[op2]
|
|
|
|
#[serde]
|
2023-01-09 15:44:20 +00:00
|
|
|
pub fn op_webgpu_surface_configure(
|
|
|
|
state: &mut OpState,
|
2023-10-04 04:25:56 +00:00
|
|
|
#[serde] args: SurfaceConfigureArgs,
|
2023-01-09 15:44:20 +00:00
|
|
|
) -> Result<WebGpuResult, AnyError> {
|
|
|
|
let instance = state.borrow::<super::Instance>();
|
|
|
|
let device_resource = state
|
|
|
|
.resource_table
|
|
|
|
.get::<super::WebGpuDevice>(args.device_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let device = device_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
let surface_resource = state
|
|
|
|
.resource_table
|
|
|
|
.get::<WebGpuSurface>(args.surface_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let surface = surface_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
|
2023-01-25 21:04:41 +00:00
|
|
|
let conf = wgpu_types::SurfaceConfiguration::<Vec<wgpu_types::TextureFormat>> {
|
2023-01-09 15:44:20 +00:00
|
|
|
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,
|
2023-01-25 21:04:41 +00:00
|
|
|
view_formats: args.view_formats,
|
2024-01-29 14:37:57 +00:00
|
|
|
desired_maximum_frame_latency: 2,
|
2023-01-09 15:44:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let err = gfx_select!(device => instance.surface_configure(surface, device, &conf));
|
|
|
|
|
|
|
|
Ok(WebGpuResult::maybe_err(err))
|
|
|
|
}
|
|
|
|
|
2023-10-04 04:25:56 +00:00
|
|
|
#[op2]
|
|
|
|
#[serde]
|
2023-01-09 15:44:20 +00:00
|
|
|
pub fn op_webgpu_surface_get_current_texture(
|
|
|
|
state: &mut OpState,
|
2023-10-04 04:25:56 +00:00
|
|
|
#[smi] device_rid: ResourceId,
|
|
|
|
#[smi] surface_rid: ResourceId,
|
2023-01-09 15:44:20 +00:00
|
|
|
) -> Result<WebGpuResult, AnyError> {
|
|
|
|
let instance = state.borrow::<super::Instance>();
|
|
|
|
let device_resource = state
|
|
|
|
.resource_table
|
|
|
|
.get::<super::WebGpuDevice>(device_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let device = device_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let surface = surface_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
|
2024-01-29 14:37:57 +00:00
|
|
|
let output = gfx_select!(device => instance.surface_get_current_texture(surface, None))?;
|
2023-01-09 15:44:20 +00:00
|
|
|
|
|
|
|
match output.status {
|
|
|
|
SurfaceStatus::Good | SurfaceStatus::Suboptimal => {
|
|
|
|
let id = output.texture_id.unwrap();
|
2023-03-03 17:18:01 +00:00
|
|
|
let rid = state.resource_table.add(crate::texture::WebGpuTexture {
|
|
|
|
instance: instance.clone(),
|
|
|
|
id,
|
|
|
|
owned: false,
|
|
|
|
});
|
2023-01-09 15:44:20 +00:00
|
|
|
Ok(WebGpuResult::rid(rid))
|
|
|
|
}
|
|
|
|
_ => Err(AnyError::msg("Invalid Surface Status")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-04 04:25:56 +00:00
|
|
|
#[op2(fast)]
|
2023-01-09 15:44:20 +00:00
|
|
|
pub fn op_webgpu_surface_present(
|
|
|
|
state: &mut OpState,
|
2023-10-04 04:25:56 +00:00
|
|
|
#[smi] device_rid: ResourceId,
|
|
|
|
#[smi] surface_rid: ResourceId,
|
2023-01-09 15:44:20 +00:00
|
|
|
) -> Result<(), AnyError> {
|
|
|
|
let instance = state.borrow::<super::Instance>();
|
|
|
|
let device_resource = state
|
|
|
|
.resource_table
|
|
|
|
.get::<super::WebGpuDevice>(device_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let device = device_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
|
2023-03-03 17:18:01 +00:00
|
|
|
let surface = surface_resource.1;
|
2023-01-09 15:44:20 +00:00
|
|
|
|
|
|
|
let _ = gfx_select!(device => instance.surface_present(surface))?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|