summaryrefslogtreecommitdiff
path: root/ext/webgpu/render_pass.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/webgpu/render_pass.rs')
-rw-r--r--ext/webgpu/render_pass.rs83
1 files changed, 44 insertions, 39 deletions
diff --git a/ext/webgpu/render_pass.rs b/ext/webgpu/render_pass.rs
index e01a6d478..125579b52 100644
--- a/ext/webgpu/render_pass.rs
+++ b/ext/webgpu/render_pass.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::null_opbuf;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::ResourceId;
@@ -10,6 +9,8 @@ use serde::Deserialize;
use std::borrow::Cow;
use std::cell::RefCell;
+use crate::pipeline::GpuIndexFormat;
+
use super::error::WebGpuResult;
pub(crate) struct WebGpuRenderPass(
@@ -253,11 +254,13 @@ pub fn op_webgpu_render_pass_execute_bundles(
.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(),
- args.bundles.len(),
+ render_bundle_ids.len(),
);
}
@@ -297,7 +300,7 @@ pub struct RenderPassSetBindGroupArgs {
render_pass_rid: ResourceId,
index: u32,
bind_group: u32,
- dynamic_offsets_data: Option<Vec<u32>>,
+ dynamic_offsets_data: ZeroCopyBuf,
dynamic_offsets_data_start: usize,
dynamic_offsets_data_length: usize,
}
@@ -305,7 +308,7 @@ pub struct RenderPassSetBindGroupArgs {
pub fn op_webgpu_render_pass_set_bind_group(
state: &mut OpState,
args: RenderPassSetBindGroupArgs,
- zero_copy: Option<ZeroCopyBuf>,
+ _: (),
) -> Result<WebGpuResult, AnyError> {
let bind_group_resource =
state
@@ -315,37 +318,35 @@ pub fn op_webgpu_render_pass_set_bind_group(
.resource_table
.get::<WebGpuRenderPass>(args.render_pass_rid)?;
- // I know this might look like it can be easily deduplicated, but it can not
- // be due to the lifetime of the args.dynamic_offsets_data slice. Because we
- // need to use a raw pointer here the slice can be freed before the pointer
- // is used in wgpu_render_pass_set_bind_group. See
- // https://matrix.to/#/!XFRnMvAfptAHthwBCx:matrix.org/$HgrlhD-Me1DwsGb8UdMu2Hqubgks8s7ILwWRwigOUAg
- match args.dynamic_offsets_data {
- Some(data) => 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,
- data.as_slice().as_ptr(),
- args.dynamic_offsets_data_length,
- );
- },
- None => {
- let zero_copy = zero_copy.ok_or_else(null_opbuf)?;
- let (prefix, data, suffix) = unsafe { zero_copy.align_to::<u32>() };
- assert!(prefix.is_empty());
- assert!(suffix.is_empty());
- 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,
- data[args.dynamic_offsets_data_start..].as_ptr(),
- args.dynamic_offsets_data_length,
- );
- }
- }
- };
+ // 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())
}
@@ -366,8 +367,10 @@ pub fn op_webgpu_render_pass_push_debug_group(
.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 {
- let label = std::ffi::CString::new(args.group_label).unwrap();
wgpu_core::command::render_ffi::wgpu_render_pass_push_debug_group(
&mut render_pass_resource.0.borrow_mut(),
label.as_ptr(),
@@ -416,8 +419,10 @@ pub fn op_webgpu_render_pass_insert_debug_marker(
.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 {
- let label = std::ffi::CString::new(args.marker_label).unwrap();
wgpu_core::command::render_ffi::wgpu_render_pass_insert_debug_marker(
&mut render_pass_resource.0.borrow_mut(),
label.as_ptr(),
@@ -461,7 +466,7 @@ pub fn op_webgpu_render_pass_set_pipeline(
pub struct RenderPassSetIndexBufferArgs {
render_pass_rid: ResourceId,
buffer: u32,
- index_format: String,
+ index_format: GpuIndexFormat,
offset: u64,
size: Option<u64>,
}
@@ -489,7 +494,7 @@ pub fn op_webgpu_render_pass_set_index_buffer(
render_pass_resource.0.borrow_mut().set_index_buffer(
buffer_resource.0,
- super::pipeline::serialize_index_format(args.index_format),
+ args.index_format.into(),
args.offset,
size,
);