Skip to content

Commit

Permalink
Revert changes to wgpu, focus on wgpu-core
Browse files Browse the repository at this point in the history
  • Loading branch information
eliemichel committed Oct 27, 2024
1 parent 353ddbe commit 4c9371f
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 164 deletions.
5 changes: 1 addition & 4 deletions wgpu-core/src/device/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1413,10 +1413,7 @@ impl Global {
let result = queue.on_submitted_work_done(closure);
match result {
Some(submission_index) => submission_index,
None => queue
.device
.last_successful_submission_index
.load(Ordering::Acquire),
None => 0, // meaning no wait is necessary
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{
mem::{self, ManuallyDrop},
ops::Range,
ptr::NonNull,
sync::{atomic::Ordering, Arc},
sync::Arc,
};

/// Information about the wgpu-core resource.
Expand Down Expand Up @@ -635,7 +635,7 @@ impl Buffer {

let submit_index = match device.lock_life().map(self) {
Some(index) => index,
None => device.active_submission_index.load(Ordering::SeqCst),
None => 0, // meaning no wait is necessary
};

Ok(submit_index)
Expand Down
64 changes: 4 additions & 60 deletions wgpu/src/api/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ impl Buffer {
/// end of the buffer.
pub fn slice<S: RangeBounds<BufferAddress>>(&self, bounds: S) -> BufferSlice<'_> {
let (offset, size) = range_to_offset_size(bounds);
check_buffer_bounds(self.size, offset, size);
BufferSlice {
buffer: self,
offset,
Expand Down Expand Up @@ -338,7 +337,7 @@ impl<'a> BufferSlice<'a> {
&self,
mode: MapMode,
callback: impl FnOnce(Result<(), BufferAsyncError>) + WasmNotSend + 'static,
) -> WgpuFuture {
) {
let mut mc = self.buffer.map_context.lock();
assert_eq!(mc.initial_range, 0..0, "Buffer is already mapped");
let end = match self.size {
Expand All @@ -347,15 +346,13 @@ impl<'a> BufferSlice<'a> {
};
mc.initial_range = self.offset..end;

let data = DynContext::buffer_map_async(
DynContext::buffer_map_async(
&*self.buffer.context,
self.buffer.data.as_ref(),
mode,
self.offset..end,
Box::new(callback),
);

WgpuFuture { data }
)
}

/// Gain read-only access to the bytes of a [mapped] [`Buffer`].
Expand Down Expand Up @@ -676,31 +673,6 @@ impl Drop for Buffer {
}
}

fn check_buffer_bounds(
buffer_size: BufferAddress,
offset: BufferAddress,
size: Option<BufferSize>,
) {
// A slice of length 0 is invalid, so the offset must not be equal to or greater than the buffer size.
if offset >= buffer_size {
panic!(
"slice offset {} is out of range for buffer of size {}",
offset, buffer_size
);
}

if let Some(size) = size {
// Detect integer overflow.
let end = offset.checked_add(size.get());
if end.map_or(true, |end| end > buffer_size) {
panic!(
"slice offset {} size {} is out of range for buffer of size {}",
offset, size, buffer_size
);
}
}
}

fn range_to_offset_size<S: RangeBounds<BufferAddress>>(
bounds: S,
) -> (BufferAddress, Option<BufferSize>) {
Expand All @@ -718,10 +690,9 @@ fn range_to_offset_size<S: RangeBounds<BufferAddress>>(

(offset, size)
}

#[cfg(test)]
mod tests {
use super::{check_buffer_bounds, range_to_offset_size, BufferSize};
use super::{range_to_offset_size, BufferSize};

#[test]
fn range_to_offset_size_works() {
Expand All @@ -744,31 +715,4 @@ mod tests {
fn range_to_offset_size_panics_for_unbounded_empty_range() {
range_to_offset_size(..0);
}

#[test]
#[should_panic]
fn check_buffer_bounds_panics_for_offset_at_size() {
check_buffer_bounds(100, 100, None);
}

#[test]
fn check_buffer_bounds_works_for_end_in_range() {
check_buffer_bounds(200, 100, BufferSize::new(50));
check_buffer_bounds(200, 100, BufferSize::new(100));
check_buffer_bounds(u64::MAX, u64::MAX - 100, BufferSize::new(100));
check_buffer_bounds(u64::MAX, 0, BufferSize::new(u64::MAX));
check_buffer_bounds(u64::MAX, 1, BufferSize::new(u64::MAX - 1));
}

#[test]
#[should_panic]
fn check_buffer_bounds_panics_for_end_over_size() {
check_buffer_bounds(200, 100, BufferSize::new(101));
}

#[test]
#[should_panic]
fn check_buffer_bounds_panics_for_end_wraparound() {
check_buffer_bounds(u64::MAX, 1, BufferSize::new(u64::MAX));
}
}
30 changes: 4 additions & 26 deletions wgpu/src/api/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,10 @@ impl Instance {
/// during instantiation, and which [DX12 shader compiler][Dx12Compiler] wgpu will use.
///
/// [`Backends::BROWSER_WEBGPU`] takes a special role:
/// If it is set and a [`navigator.gpu`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/gpu)
/// object is present, this instance will *only* be able to create WebGPU adapters.
///
/// ⚠️ On some browsers this check is insufficient to determine whether WebGPU is supported,
/// as the browser may define the `navigator.gpu` object, but be unable to create any WebGPU adapters.
/// For targeting _both_ WebGPU & WebGL is recommended to use [`crate::util::new_instance_with_webgpu_detection`].
///
/// If you instead want to force use of WebGL, either disable the `webgpu` compile-time feature
/// or don't add the [`Backends::BROWSER_WEBGPU`] flag to the the `instance_desc`'s `backends` field.
/// If it is set and WebGPU support is detected, this instance will *only* be able to create
/// WebGPU adapters. If you instead want to force use of WebGL, either
/// disable the `webgpu` compile-time feature or don't add the [`Backends::BROWSER_WEBGPU`]
/// flag to the the `instance_desc`'s `backends` field.
/// If it is set and WebGPU support is *not* detected, the instance will use wgpu-core
/// to create adapters. Meaning that if the `webgl` feature is enabled, it is able to create
/// a WebGL adapter.
Expand Down Expand Up @@ -394,20 +389,3 @@ impl Instance {
.map(|ctx| ctx.generate_report())
}
}

/// Status returned when waiting on WgpuFuture objects.
#[derive(Clone, Debug)]
pub(crate) enum WaitStatus {
// At least one WgpuFuture completed successfully.
//Success,

// No WgpuFuture completed within the timeout.
//TimedOut,
/// A Timed-Wait was performed when timedWaitAnyEnable instance feature is false.
UnsupportedTimeout,
// The number of futures waited on in a Timed-Wait is greater than the supported timedWaitAnyMaxCount.
//UnsupportedCount,

// An invalid wait was performed with Mixed-Sources.
//UnsupportedMixedSources,
}
16 changes: 3 additions & 13 deletions wgpu/src/api/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ impl Drop for Queue {
///
/// This type is unique to the Rust API of `wgpu`.
/// There is no analogue in the WebGPU specification.
/// NB: WgpuFuture should probably be used instead of this
#[derive(Debug, Clone)]
pub struct SubmissionIndex {
#[cfg_attr(not(native), allow(dead_code))]
Expand All @@ -51,14 +50,6 @@ pub type Maintain = wgt::Maintain<SubmissionIndex>;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(Maintain: Send, Sync);

/// This is not std::future, but rather a WGPUFuture, namely an opaque handle that can be queried
/// for completion, but does not hold any returned data.
///
/// It's 'id' field is to be interpreted as a submission id (like wgc::SubmissionId)
pub type WgpuFuture = SubmissionIndex;
#[cfg(send_sync)]
static_assertions::assert_impl_all!(WgpuFuture: Send, Sync);

/// A write-only view into a staging buffer.
///
/// Reading into this buffer won't yield the contents of the buffer from the
Expand Down Expand Up @@ -284,12 +275,11 @@ impl Queue {
/// has completed. There are no restrictions on the code you can run in the callback, however on native the
/// call to the function will not complete until the callback returns, so prefer keeping callbacks short
/// and used to set flags, send messages, etc.
pub fn on_submitted_work_done(&self, callback: impl FnOnce() + Send + 'static) -> WgpuFuture {
let data = DynContext::queue_on_submitted_work_done(
pub fn on_submitted_work_done(&self, callback: impl FnOnce() + Send + 'static) {
DynContext::queue_on_submitted_work_done(
&*self.context,
self.data.as_ref(),
Box::new(callback),
);
WgpuFuture { data }
)
}
}
28 changes: 6 additions & 22 deletions wgpu/src/backend/webgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ fn map_wgt_limits(limits: webgpu_sys::GpuSupportedLimits) -> wgt::Limits {
max_vertex_buffer_array_stride: limits.max_vertex_buffer_array_stride(),
min_uniform_buffer_offset_alignment: limits.min_uniform_buffer_offset_alignment(),
min_storage_buffer_offset_alignment: limits.min_storage_buffer_offset_alignment(),
max_inter_stage_shader_components: limits.max_inter_stage_shader_components(),
max_color_attachments: limits.max_color_attachments(),
max_color_attachment_bytes_per_sample: limits.max_color_attachment_bytes_per_sample(),
max_compute_workgroup_storage_size: limits.max_compute_workgroup_storage_size(),
Expand All @@ -828,7 +829,6 @@ fn map_wgt_limits(limits: webgpu_sys::GpuSupportedLimits) -> wgt::Limits {
max_subgroup_size: wgt::Limits::default().max_subgroup_size,
max_push_constant_size: wgt::Limits::default().max_push_constant_size,
max_non_sampler_bindings: wgt::Limits::default().max_non_sampler_bindings,
max_inter_stage_shader_components: wgt::Limits::default().max_inter_stage_shader_components,
}
}

Expand Down Expand Up @@ -875,6 +875,7 @@ fn map_js_sys_limits(limits: &wgt::Limits) -> js_sys::Object {
(maxBufferSize, max_buffer_size),
(maxVertexAttributes, max_vertex_attributes),
(maxVertexBufferArrayStride, max_vertex_buffer_array_stride),
(maxInterStageShaderComponents, max_inter_stage_shader_components),
(maxComputeWorkgroupStorageSize, max_compute_workgroup_storage_size),
(maxComputeInvocationsPerWorkgroup, max_compute_invocations_per_workgroup),
(maxComputeWorkgroupSizeX, max_compute_workgroup_size_x),
Expand Down Expand Up @@ -1087,12 +1088,8 @@ pub struct BrowserGpuPropertyInaccessible;
/// Returns the browser's gpu object or `Err(BrowserGpuPropertyInaccessible)` if
/// the current context is neither the main thread nor a dedicated worker.
///
/// If WebGPU is not supported, the Gpu property may (!) be `undefined`,
/// and so this function will return `Ok(None)`.
/// Note that this check is insufficient to determine whether WebGPU is
/// supported, as the browser may define the Gpu property, but be unable to
/// create any WebGPU adapters.
/// To detect whether WebGPU is supported, use the [`crate::utils::is_browser_webgpu_supported`] function.
/// If WebGPU is not supported, the Gpu property is `undefined`, and so this
/// function will return `Ok(None)`.
///
/// See:
/// * <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/gpu>
Expand Down Expand Up @@ -1162,8 +1159,6 @@ impl crate::context::Context for ContextWebGpu {
Box<dyn Fn(JsFutureResult) -> CompilationInfo>,
>;

type WgpuFuture = wasm_bindgen_futures::JsFuture;

fn init(_instance_desc: wgt::InstanceDescriptor) -> Self {
let Ok(gpu) = get_browser_gpu_property() else {
panic!(
Expand Down Expand Up @@ -1253,16 +1248,6 @@ impl crate::context::Context for ContextWebGpu {
}
}

fn instance_wait_any(
&self,
_futures: &[&Self::WgpuFuture],
_timeout_ns: u64,
) -> crate::WaitStatus {
// TODO: Yield back to the browser, run the equivalent of the following JavaScript:
// > await Promise.any([ ...futures, new Promise(resolve => setTimeout(timeout_ns, resolve) ]))
crate::WaitStatus::UnsupportedTimeout
}

fn adapter_request_device(
&self,
adapter_data: &Self::AdapterData,
Expand Down Expand Up @@ -2162,7 +2147,7 @@ impl crate::context::Context for ContextWebGpu {
mode: crate::MapMode,
range: Range<wgt::BufferAddress>,
callback: crate::context::BufferMapCallback,
) -> Self::WgpuFuture {
) {
let map_promise = buffer_data.0.buffer.map_async_with_f64_and_f64(
map_map_mode(mode),
range.start as f64,
Expand All @@ -2172,7 +2157,6 @@ impl crate::context::Context for ContextWebGpu {
buffer_data.0.set_mapped_range(range);

register_then_closures(&map_promise, callback, Ok(()), Err(crate::BufferAsyncError));
map_promise.into()
}

fn buffer_get_mapped_range(
Expand Down Expand Up @@ -2786,7 +2770,7 @@ impl crate::context::Context for ContextWebGpu {
&self,
_queue_data: &Self::QueueData,
_callback: crate::context::SubmittedWorkDoneCallback,
) -> Self::WgpuFuture {
) {
unimplemented!()
}

Expand Down
22 changes: 5 additions & 17 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,6 @@ impl crate::Context for ContextWgpuCore {
type PopErrorScopeFuture = Ready<Option<crate::Error>>;
type CompilationInfoFuture = Ready<CompilationInfo>;

type WgpuFuture = wgc::SubmissionIndex;

fn init(instance_desc: wgt::InstanceDescriptor) -> Self {
Self(wgc::global::Global::new("wgpu", instance_desc))
}
Expand Down Expand Up @@ -608,15 +606,6 @@ impl crate::Context for ContextWgpuCore {
ready(id.ok())
}

fn instance_wait_any(
&self,
_futures: &[&Self::WgpuFuture],
_timeout_ns: u64,
) -> crate::WaitStatus {
// TODO: We need to know at the instance level whether a submission ID is completed...
crate::WaitStatus::UnsupportedTimeout
}

fn adapter_request_device(
&self,
adapter_data: &Self::AdapterData,
Expand Down Expand Up @@ -1402,7 +1391,7 @@ impl crate::Context for ContextWgpuCore {
mode: MapMode,
range: Range<wgt::BufferAddress>,
callback: crate::context::BufferMapCallback,
) -> Self::WgpuFuture {
) {
let operation = wgc::resource::BufferMapOperation {
host: match mode {
MapMode::Read => wgc::device::HostMap::Read,
Expand All @@ -1422,10 +1411,9 @@ impl crate::Context for ContextWgpuCore {
Some(range.end - range.start),
operation,
) {
Ok(index) => index,
Ok(_) => (),
Err(cause) => {
self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async");
Self::SubmissionIndexData::MAX // invalid submission index
self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async")
}
}
}
Expand Down Expand Up @@ -2107,9 +2095,9 @@ impl crate::Context for ContextWgpuCore {
&self,
queue_data: &Self::QueueData,
callback: crate::context::SubmittedWorkDoneCallback,
) -> Self::WgpuFuture {
) {
let closure = wgc::device::queue::SubmittedWorkDoneClosure::from_rust(callback);
self.0.queue_on_submitted_work_done(queue_data.id, closure)
self.0.queue_on_submitted_work_done(queue_data.id, closure);
}

fn device_start_capture(&self, device_data: &Self::DeviceData) {
Expand Down
Loading

0 comments on commit 4c9371f

Please sign in to comment.