2022-01-20 02:10:16 -05:00
|
|
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
2021-03-01 05:31:13 -05:00
|
|
|
|
2021-05-06 10:48:45 -04:00
|
|
|
use std::num::NonZeroU32;
|
|
|
|
|
2021-03-01 05:31:13 -05:00
|
|
|
use deno_core::error::AnyError;
|
2022-03-14 13:44:15 -04:00
|
|
|
use deno_core::op;
|
2021-03-01 05:31:13 -05:00
|
|
|
use deno_core::OpState;
|
2021-03-19 13:25:37 -04:00
|
|
|
use deno_core::ResourceId;
|
2021-03-01 05:31:13 -05:00
|
|
|
use deno_core::ZeroCopyBuf;
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
2021-04-05 12:40:24 -04:00
|
|
|
use super::error::WebGpuResult;
|
2021-03-01 05:31:13 -05:00
|
|
|
|
2021-03-25 14:17:37 -04:00
|
|
|
type WebGpuQueue = super::WebGpuDevice;
|
2021-03-01 05:31:13 -05:00
|
|
|
|
2022-03-14 13:44:15 -04:00
|
|
|
#[op]
|
2021-03-01 05:31:13 -05:00
|
|
|
pub fn op_webgpu_queue_submit(
|
|
|
|
state: &mut OpState,
|
2022-07-19 20:22:26 -04:00
|
|
|
queue_rid: ResourceId,
|
|
|
|
command_buffers: Vec<ResourceId>,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<WebGpuResult, AnyError> {
|
2021-03-01 05:31:13 -05:00
|
|
|
let instance = state.borrow::<super::Instance>();
|
2022-07-19 20:22:26 -04:00
|
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
2021-03-01 05:31:13 -05:00
|
|
|
let queue = queue_resource.0;
|
|
|
|
|
2022-07-19 20:22:26 -04:00
|
|
|
let ids = command_buffers
|
|
|
|
.iter()
|
|
|
|
.map(|rid| {
|
|
|
|
let buffer_resource =
|
|
|
|
state
|
|
|
|
.resource_table
|
|
|
|
.get::<super::command_encoder::WebGpuCommandBuffer>(*rid)?;
|
|
|
|
Ok(buffer_resource.0)
|
|
|
|
})
|
|
|
|
.collect::<Result<Vec<_>, AnyError>>()?;
|
2021-03-01 05:31:13 -05:00
|
|
|
|
|
|
|
let maybe_err =
|
|
|
|
gfx_select!(queue => instance.queue_submit(queue, &ids)).err();
|
|
|
|
|
2022-07-19 20:22:26 -04:00
|
|
|
for rid in command_buffers {
|
|
|
|
state.resource_table.close(rid)?;
|
|
|
|
}
|
|
|
|
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(WebGpuResult::maybe_err(maybe_err))
|
2021-03-01 05:31:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2022-07-19 20:22:26 -04:00
|
|
|
pub struct GpuImageDataLayout {
|
2021-08-24 14:32:25 -04:00
|
|
|
offset: u64,
|
2021-03-01 05:31:13 -05:00
|
|
|
bytes_per_row: Option<u32>,
|
|
|
|
rows_per_image: Option<u32>,
|
|
|
|
}
|
|
|
|
|
2021-08-24 14:32:25 -04:00
|
|
|
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)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 20:22:26 -04:00
|
|
|
#[op]
|
|
|
|
pub fn op_webgpu_write_buffer(
|
|
|
|
state: &mut OpState,
|
2021-03-19 13:25:37 -04:00
|
|
|
queue_rid: ResourceId,
|
2021-08-24 14:32:25 -04:00
|
|
|
buffer: ResourceId,
|
2021-03-01 05:31:13 -05:00
|
|
|
buffer_offset: u64,
|
|
|
|
data_offset: usize,
|
|
|
|
size: Option<usize>,
|
2022-07-19 20:22:26 -04:00
|
|
|
buf: ZeroCopyBuf,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<WebGpuResult, AnyError> {
|
2021-03-01 05:31:13 -05:00
|
|
|
let instance = state.borrow::<super::Instance>();
|
|
|
|
let buffer_resource = state
|
|
|
|
.resource_table
|
2022-07-19 20:22:26 -04:00
|
|
|
.get::<super::buffer::WebGpuBuffer>(buffer)?;
|
2021-03-01 05:31:13 -05:00
|
|
|
let buffer = buffer_resource.0;
|
2022-07-19 20:22:26 -04:00
|
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
2021-03-01 05:31:13 -05:00
|
|
|
let queue = queue_resource.0;
|
|
|
|
|
2022-07-19 20:22:26 -04:00
|
|
|
let data = match size {
|
|
|
|
Some(size) => &buf[data_offset..(data_offset + size)],
|
|
|
|
None => &buf[data_offset..],
|
2021-03-01 05:31:13 -05:00
|
|
|
};
|
|
|
|
let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
|
|
|
|
queue,
|
|
|
|
buffer,
|
2022-07-19 20:22:26 -04:00
|
|
|
buffer_offset,
|
2021-03-01 05:31:13 -05:00
|
|
|
data
|
|
|
|
))
|
|
|
|
.err();
|
|
|
|
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(WebGpuResult::maybe_err(maybe_err))
|
2021-03-01 05:31:13 -05:00
|
|
|
}
|
|
|
|
|
2022-07-19 20:22:26 -04:00
|
|
|
#[op]
|
|
|
|
pub fn op_webgpu_write_texture(
|
|
|
|
state: &mut OpState,
|
2021-03-19 13:25:37 -04:00
|
|
|
queue_rid: ResourceId,
|
2021-03-25 14:17:37 -04:00
|
|
|
destination: super::command_encoder::GpuImageCopyTexture,
|
|
|
|
data_layout: GpuImageDataLayout,
|
2022-01-24 17:47:05 -05:00
|
|
|
size: wgpu_types::Extent3d,
|
2022-07-19 20:22:26 -04:00
|
|
|
buf: ZeroCopyBuf,
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<WebGpuResult, AnyError> {
|
2021-03-01 05:31:13 -05:00
|
|
|
let instance = state.borrow::<super::Instance>();
|
|
|
|
let texture_resource = state
|
|
|
|
.resource_table
|
2022-07-19 20:22:26 -04:00
|
|
|
.get::<super::texture::WebGpuTexture>(destination.texture)?;
|
|
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
2021-03-01 05:31:13 -05:00
|
|
|
let queue = queue_resource.0;
|
|
|
|
|
2021-05-06 10:48:45 -04:00
|
|
|
let destination = wgpu_core::command::ImageCopyTexture {
|
2021-03-01 05:31:13 -05:00
|
|
|
texture: texture_resource.0,
|
2022-07-19 20:22:26 -04:00
|
|
|
mip_level: destination.mip_level,
|
|
|
|
origin: destination.origin,
|
|
|
|
aspect: destination.aspect,
|
2021-03-01 05:31:13 -05:00
|
|
|
};
|
2022-07-19 20:22:26 -04:00
|
|
|
let data_layout = data_layout.into();
|
2021-03-01 05:31:13 -05:00
|
|
|
|
2021-05-03 10:42:59 -04:00
|
|
|
gfx_ok!(queue => instance.queue_write_texture(
|
2021-03-01 05:31:13 -05:00
|
|
|
queue,
|
|
|
|
&destination,
|
2022-07-19 20:22:26 -04:00
|
|
|
&*buf,
|
2021-03-01 05:31:13 -05:00
|
|
|
&data_layout,
|
2022-07-19 20:22:26 -04:00
|
|
|
&size
|
2021-03-01 05:31:13 -05:00
|
|
|
))
|
|
|
|
}
|