mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
fc2fd95a98
* Change the signature of `wgpu_core::Global::queue_submit` to return a `(SubmissionIndex, …)` in addition to its current error type. * Change the control flow of errors in `Queue::submit` to break to the end of a block. This is similar to what we already do in many APIs in `wgpu_core`. * Hoist the scope of the local `submit_index` binding so it can be used at the point where we need to convert current error paths to also return the submission index. Later, we will likely want to avoid actually retrieving a new submission index so we can minimize the critical section of code. We'll need to figure out a strategy for returning a valid (but not necessarily unique) index in the case of failures that prevent successful submission.
132 lines
3.8 KiB
Rust
132 lines
3.8 KiB
Rust
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
|
|
use crate::command_encoder::WebGpuCommandBuffer;
|
|
use crate::Instance;
|
|
use deno_core::error::AnyError;
|
|
use deno_core::op2;
|
|
use deno_core::OpState;
|
|
use deno_core::Resource;
|
|
use deno_core::ResourceId;
|
|
use serde::Deserialize;
|
|
use std::borrow::Cow;
|
|
use std::rc::Rc;
|
|
|
|
use super::error::WebGpuResult;
|
|
|
|
pub struct WebGpuQueue(pub Instance, pub wgpu_core::id::QueueId);
|
|
impl Resource for WebGpuQueue {
|
|
fn name(&self) -> Cow<str> {
|
|
"webGPUQueue".into()
|
|
}
|
|
|
|
fn close(self: Rc<Self>) {
|
|
self.0.queue_drop(self.1);
|
|
}
|
|
}
|
|
|
|
#[op2]
|
|
#[serde]
|
|
pub fn op_webgpu_queue_submit(
|
|
state: &mut OpState,
|
|
#[smi] queue_rid: ResourceId,
|
|
#[serde] command_buffers: Vec<ResourceId>,
|
|
) -> Result<WebGpuResult, AnyError> {
|
|
let instance = state.borrow::<Instance>();
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
|
let queue = queue_resource.1;
|
|
|
|
let ids = command_buffers
|
|
.iter()
|
|
.map(|rid| {
|
|
let buffer_resource = state.resource_table.get::<WebGpuCommandBuffer>(*rid)?;
|
|
let mut id = buffer_resource.1.borrow_mut();
|
|
Ok(id.take().unwrap())
|
|
})
|
|
.collect::<Result<Vec<_>, AnyError>>()?;
|
|
|
|
let maybe_err = instance.queue_submit(queue, &ids).err().map(|(_idx, e)| e);
|
|
|
|
for rid in command_buffers {
|
|
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
|
|
resource.close();
|
|
}
|
|
|
|
Ok(WebGpuResult::maybe_err(maybe_err))
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub 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: layout.bytes_per_row,
|
|
rows_per_image: layout.rows_per_image,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[op2]
|
|
#[serde]
|
|
pub fn op_webgpu_write_buffer(
|
|
state: &mut OpState,
|
|
#[smi] queue_rid: ResourceId,
|
|
#[smi] buffer: ResourceId,
|
|
#[number] buffer_offset: u64,
|
|
#[number] data_offset: usize,
|
|
#[number] size: Option<usize>,
|
|
#[buffer] buf: &[u8],
|
|
) -> Result<WebGpuResult, AnyError> {
|
|
let instance = state.borrow::<Instance>();
|
|
let buffer_resource = state
|
|
.resource_table
|
|
.get::<super::buffer::WebGpuBuffer>(buffer)?;
|
|
let buffer = buffer_resource.1;
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
|
let queue = queue_resource.1;
|
|
|
|
let data = match size {
|
|
Some(size) => &buf[data_offset..(data_offset + size)],
|
|
None => &buf[data_offset..],
|
|
};
|
|
let maybe_err = instance
|
|
.queue_write_buffer(queue, buffer, buffer_offset, data)
|
|
.err();
|
|
|
|
Ok(WebGpuResult::maybe_err(maybe_err))
|
|
}
|
|
|
|
#[op2]
|
|
#[serde]
|
|
pub fn op_webgpu_write_texture(
|
|
state: &mut OpState,
|
|
#[smi] queue_rid: ResourceId,
|
|
#[serde] destination: super::command_encoder::GpuImageCopyTexture,
|
|
#[serde] data_layout: GpuImageDataLayout,
|
|
#[serde] size: wgpu_types::Extent3d,
|
|
#[buffer] buf: &[u8],
|
|
) -> Result<WebGpuResult, AnyError> {
|
|
let instance = state.borrow::<Instance>();
|
|
let texture_resource = state
|
|
.resource_table
|
|
.get::<super::texture::WebGpuTexture>(destination.texture)?;
|
|
let queue_resource = state.resource_table.get::<WebGpuQueue>(queue_rid)?;
|
|
let queue = queue_resource.1;
|
|
|
|
let destination = wgpu_core::command::ImageCopyTexture {
|
|
texture: texture_resource.id,
|
|
mip_level: destination.mip_level,
|
|
origin: destination.origin,
|
|
aspect: destination.aspect,
|
|
};
|
|
let data_layout = data_layout.into();
|
|
|
|
gfx_ok!(instance.queue_write_texture(queue, &destination, buf, &data_layout, &size))
|
|
}
|