Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cts_runner/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,15 @@ webgpu:api,validation,encoding,cmds,setBindGroup:state_and_binding_index:encoder
webgpu:api,validation,encoding,cmds,setBindGroup:state_and_binding_index:encoderType="render%20bundle";state="valid";*
webgpu:api,validation,encoding,cmds,setBindGroup:state_and_binding_index:encoderType="render%20pass";state="invalid";*
webgpu:api,validation,encoding,cmds,setBindGroup:state_and_binding_index:encoderType="render%20pass";state="valid";*
webgpu:api,validation,encoding,cmds,setImmediates:*
webgpu:api,validation,encoding,encoder_open_state:compute_pass_commands:*
webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*
//FAIL: webgpu:api,validation,encoding,encoder_open_state:render_bundle_commands:*
// https://github.com/gfx-rs/wgpu/issues/7857
webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:*
webgpu:api,validation,encoding,encoder_state:*
webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:*
webgpu:api,validation,encoding,programmable,pipeline_immediate:*
webgpu:api,validation,encoding,queries,begin_end:nesting:*
webgpu:api,validation,encoding,queries,begin_end:occlusion_query,*
webgpu:api,validation,encoding,queries,general:occlusion_query,*
Expand Down
5 changes: 5 additions & 0 deletions deno_webgpu/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ impl GPUSupportedLimits {

// TODO(@crowlKats): support max_bind_groups_plus_vertex_buffers

#[getter]
fn maxImmediateSize(&self) -> u32 {
self.0.max_immediate_size
}

#[getter]
fn maxBindingsPerBindGroup(&self) -> u32 {
self.0.max_bindings_per_bind_group
Expand Down
115 changes: 115 additions & 0 deletions deno_webgpu/compute_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use deno_core::webidl::WebIdlConverter;
use deno_core::webidl::WebIdlError;
use deno_core::GarbageCollected;
use deno_core::WebIDL;
use wgpu_core::binding_model::ImmediateUploadError;

use crate::error::GPUError;
use crate::error::GPUGenericError;
use crate::Instance;

Expand Down Expand Up @@ -230,6 +232,119 @@ impl GPUComputePassEncoder {

Ok(())
}

// TODO: share marshalling code
#[required(2)]
#[undefined]
fn set_immediates<'a>(
&self,
scope: &mut v8::HandleScope<'a>,
#[webidl(options(enforce_range = true))] range_offset: u32,
data: v8::Local<v8::Value>,
data_offset: v8::Local<'a, v8::Value>,
size: v8::Local<'a, v8::Value>,
) -> Result<(), WebIdlError> {
const PREFIX: &str =
"Failed to execute 'setImmediateData' on 'GPUComputePassEncoder'";

let data_size;
let data_byte_len;
let data_buffer;
// TODO: Surely some helpers for this must exist?
if let Ok(typed_array) = data.try_cast::<v8::TypedArray>() {
data_byte_len = typed_array.byte_length();
data_size = typed_array.length();
data_buffer = typed_array.buffer(scope).and_then(|b| b.data());
} else if let Ok(array_buf_view) = data.try_cast::<v8::ArrayBufferView>() {
data_byte_len = array_buf_view.byte_length();
data_size = 1;
data_buffer = array_buf_view.buffer(scope).and_then(|b| b.data());
} else if let Ok(array_buf) = data.try_cast::<v8::ArrayBuffer>() {
data_byte_len = array_buf.byte_length();
data_size = 1;
data_buffer = array_buf.data();
} else if let Ok(shared_array_buf) =
data.try_cast::<v8::SharedArrayBuffer>()
{
data_byte_len = shared_array_buf.byte_length();
data_size = 1;
// TODO: file issue about `data` convenience accessor
data_buffer = shared_array_buf.get_backing_store().data();
} else {
return Err(WebIdlError::new(
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 2")).into(),
deno_core::webidl::WebIdlErrorKind::ConvertToConverterType(
"AllowSharedBufferSource",
),
));
}

let data_offset = <u64 as WebIdlConverter<'a>>::convert(
scope,
data_offset,
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 3")).into(),
&IntOptions {
clamp: false,
enforce_range: true,
},
)
.map(|o| (o as usize) * data_size)?;

let size = u64::convert(
scope,
size,
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 4")).into(),
&IntOptions {
clamp: false,
enforce_range: true,
},
)
.map(|o| (o as usize) * data_size)?;

let data: &[_] = data_buffer.map_or(&[], |b| unsafe {
// SAFETY: created from an array buffer, slice is dropped at end of function call
std::slice::from_raw_parts(b.as_ptr() as *const u8, data_byte_len)
});

let data = match data.get(data_offset..(data_offset + size)) {
Some(some) => some,
None => {
let err = if data_offset > data.len() {
ImmediateUploadError::StartOffsetOverrun {
start_offset: data_offset as u32,
immediate_size: data_byte_len as u32,
}
} else {
ImmediateUploadError::EndOffsetOverrun {
start_offset: data_offset as u32,
size: size as u32,
immediate_size: data_byte_len as u32,
}
};

self
.error_handler
.push_error(Some(GPUError::Validation(err.to_string())));

return Ok(());
}
};

let err = self
.instance
.compute_pass_set_immediates(
&mut self.compute_pass.borrow_mut(),
range_offset,
data,
)
.err();
self.error_handler.push_error(err);

Ok(())
}
}

#[derive(WebIDL)]
Expand Down
2 changes: 1 addition & 1 deletion deno_webgpu/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl GPUDevice {
let wgpu_descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor {
label: crate::transform_label(descriptor.label.clone()),
bind_group_layouts: Cow::Owned(bind_group_layouts),
immediate_size: 0,
immediate_size: descriptor.immediate_size,
};

let (id, err) = self.instance.device_create_pipeline_layout(
Expand Down
3 changes: 3 additions & 0 deletions deno_webgpu/pipeline_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,7 @@ pub(crate) struct GPUPipelineLayoutDescriptor {

pub bind_group_layouts:
Vec<Nullable<Ptr<super::bind_group_layout::GPUBindGroupLayout>>>,

#[webidl(default = 0)]
pub immediate_size: u32,
}
114 changes: 114 additions & 0 deletions deno_webgpu/render_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ use deno_core::webidl::WebIdlConverter;
use deno_core::webidl::WebIdlError;
use deno_core::GarbageCollected;
use deno_core::WebIDL;
use wgpu_core::binding_model::ImmediateUploadError;

use crate::buffer::GPUBuffer;
use crate::error::GPUError;
use crate::error::GPUGenericError;
use crate::render_bundle::GPURenderBundle;
use crate::texture::GPUTexture;
Expand Down Expand Up @@ -364,6 +366,118 @@ impl GPURenderPassEncoder {
self.error_handler.push_error(err);
}

#[required(2)]
#[undefined]
fn set_immediates<'a>(
&self,
scope: &mut v8::HandleScope<'a>,
#[webidl(options(enforce_range = true))] range_offset: u32,
data: v8::Local<v8::Value>,
data_offset: v8::Local<'a, v8::Value>,
size: v8::Local<'a, v8::Value>,
) -> Result<(), WebIdlError> {
const PREFIX: &str =
"Failed to execute 'setImmediateData' on 'GPURenderPassEncoder'";

let data_size;
let data_byte_len;
let data_buffer;
// TODO: Surely some helpers for this must exist?
if let Ok(typed_array) = data.try_cast::<v8::TypedArray>() {
data_byte_len = typed_array.byte_length();
data_size = typed_array.length();
data_buffer = typed_array.buffer(scope).and_then(|b| b.data());
} else if let Ok(array_buf_view) = data.try_cast::<v8::ArrayBufferView>() {
data_byte_len = array_buf_view.byte_length();
data_size = 1;
data_buffer = array_buf_view.buffer(scope).and_then(|b| b.data());
} else if let Ok(array_buf) = data.try_cast::<v8::ArrayBuffer>() {
data_byte_len = array_buf.byte_length();
data_size = 1;
data_buffer = array_buf.data();
} else if let Ok(shared_array_buf) =
data.try_cast::<v8::SharedArrayBuffer>()
{
data_byte_len = shared_array_buf.byte_length();
data_size = 1;
// TODO: file issue about `data` convenience accessor
data_buffer = shared_array_buf.get_backing_store().data();
} else {
return Err(WebIdlError::new(
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 2")).into(),
deno_core::webidl::WebIdlErrorKind::ConvertToConverterType(
"AllowSharedBufferSource",
),
));
}

let data_offset = <u64 as WebIdlConverter<'a>>::convert(
scope,
data_offset,
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 3")).into(),
&IntOptions {
clamp: false,
enforce_range: true,
},
)
.map(|o| (o as usize) * data_size)?;

let size = u64::convert(
scope,
size,
Cow::Borrowed(PREFIX),
(|| Cow::Borrowed("Argument 4")).into(),
&IntOptions {
clamp: false,
enforce_range: true,
},
)
.map(|o| (o as usize) * data_size)?;

let data: &[_] = data_buffer.map_or(&[], |b| unsafe {
// SAFETY: created from an array buffer, slice is dropped at end of function call
std::slice::from_raw_parts(b.as_ptr() as *const u8, data_byte_len)
});

let data = match data.get(data_offset..(data_offset + size)) {
Some(some) => some,
None => {
let err = if data_offset > data.len() {
ImmediateUploadError::StartOffsetOverrun {
start_offset: data_offset as u32,
immediate_size: data_byte_len as u32,
}
} else {
ImmediateUploadError::EndOffsetOverrun {
start_offset: data_offset as u32,
size: size as u32,
immediate_size: data_byte_len as u32,
}
};

self
.error_handler
.push_error(Some(GPUError::Validation(err.to_string())));

return Ok(());
}
};

let err = self
.instance
.render_pass_set_immediates(
&mut self.render_pass.borrow_mut(),
range_offset,
data,
)
.err();
self.error_handler.push_error(err);

Ok(())
}

#[required(1)]
#[undefined]
fn draw(
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/ray_shadows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn create_matrix(config: &wgpu::SurfaceConfiguration) -> Uniforms {

impl crate::framework::Example for Example {
fn required_features() -> wgpu::Features {
wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::IMMEDIATES
wgpu::Features::EXPERIMENTAL_RAY_QUERY
}

fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities {
Expand Down
9 changes: 9 additions & 0 deletions naga/src/front/wgsl/parse/directive/language_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl LanguageExtension {
const PACKED4X8_INTEGER_DOT_PRODUCT: &'static str = "packed_4x8_integer_dot_product";
const UNRESTRICTED_POINTER_PARAMETERS: &'static str = "unrestricted_pointer_parameters";
const POINTER_COMPOSITE_ACCESS: &'static str = "pointer_composite_access";
const IMMEDIATE_ADDRESS_SPACE: &'static str = "immediate_address_space";

/// Convert from a sentinel word in WGSL into its associated [`LanguageExtension`], if possible.
pub fn from_ident(s: &str) -> Option<Self> {
Expand All @@ -33,6 +34,9 @@ impl LanguageExtension {
Self::POINTER_COMPOSITE_ACCESS => {
Self::Implemented(ImplementedLanguageExtension::PointerCompositeAccess)
}
Self::IMMEDIATE_ADDRESS_SPACE => {
Self::Implemented(ImplementedLanguageExtension::ImmediateAddressSpace)
}
_ => return None,
})
}
Expand All @@ -57,6 +61,7 @@ pub enum ImplementedLanguageExtension {
ReadOnlyAndReadWriteStorageTextures,
Packed4x8IntegerDotProduct,
PointerCompositeAccess,
ImmediateAddressSpace,
}

impl ImplementedLanguageExtension {
Expand All @@ -65,6 +70,7 @@ impl ImplementedLanguageExtension {
Self::ReadOnlyAndReadWriteStorageTextures,
Self::Packed4x8IntegerDotProduct,
Self::PointerCompositeAccess,
Self::ImmediateAddressSpace,
];

/// Returns slice of all variants of [`ImplementedLanguageExtension`].
Expand All @@ -84,6 +90,9 @@ impl ImplementedLanguageExtension {
ImplementedLanguageExtension::PointerCompositeAccess => {
LanguageExtension::POINTER_COMPOSITE_ACCESS
}
ImplementedLanguageExtension::ImmediateAddressSpace => {
LanguageExtension::IMMEDIATE_ADDRESS_SPACE
}
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) {
static NUM_WORKGROUPS_BUILTIN: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::IMMEDIATES)
.downlevel_flags(
wgpu::DownlevelFlags::COMPUTE_SHADERS | wgpu::DownlevelFlags::INDIRECT_EXECUTION,
)
Expand All @@ -36,7 +35,6 @@ static NUM_WORKGROUPS_BUILTIN: GpuTestConfiguration = GpuTestConfiguration::new(
static DISCARD_DISPATCH: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::IMMEDIATES)
.downlevel_flags(
wgpu::DownlevelFlags::COMPUTE_SHADERS | wgpu::DownlevelFlags::INDIRECT_EXECUTION,
)
Expand Down Expand Up @@ -67,7 +65,6 @@ static DISCARD_DISPATCH: GpuTestConfiguration = GpuTestConfiguration::new()
static RESET_BIND_GROUPS: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::IMMEDIATES)
.downlevel_flags(
wgpu::DownlevelFlags::COMPUTE_SHADERS | wgpu::DownlevelFlags::INDIRECT_EXECUTION,
)
Expand Down Expand Up @@ -109,7 +106,6 @@ static RESET_BIND_GROUPS: GpuTestConfiguration = GpuTestConfiguration::new()
static ZERO_SIZED_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::IMMEDIATES)
.downlevel_flags(
wgpu::DownlevelFlags::COMPUTE_SHADERS | wgpu::DownlevelFlags::INDIRECT_EXECUTION,
)
Expand Down
Loading
Loading