mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Add get_mapped_range_as_array_buffer which - on wasm WebGPU builds - avoids copying mapped data into wasm heap (#4042) (#4103)
Co-authored-by: Ryan Kaplan <ryan@Ryans-M2.local>
This commit is contained in:
parent
21098cdace
commit
8c891114ac
@ -40,6 +40,12 @@ Bottom level categories:
|
||||
|
||||
## Unreleased
|
||||
|
||||
## v0.17.1
|
||||
|
||||
### Added/New Features
|
||||
|
||||
- Add `get_mapped_range_as_array_buffer` for faster buffer read-backs in wasm builds. By @ryankaplan in [#4042] (https://github.com/gfx-rs/wgpu/pull/4042).
|
||||
|
||||
## v0.17.0 (2023-07-20)
|
||||
|
||||
This is the first release that featured `wgpu-info` as a binary crate for getting information about what devices wgpu sees in your system. It can dump the information in both human readable format and json.
|
||||
|
@ -1890,10 +1890,8 @@ impl crate::context::Context for Context {
|
||||
buffer_data: &Self::BufferData,
|
||||
sub_range: Range<wgt::BufferAddress>,
|
||||
) -> Box<dyn crate::context::BufferMappedRange> {
|
||||
let array_buffer = buffer_data.0.get_mapped_range_with_f64_and_f64(
|
||||
sub_range.start as f64,
|
||||
(sub_range.end - sub_range.start) as f64,
|
||||
);
|
||||
let array_buffer =
|
||||
self.buffer_get_mapped_range_as_array_buffer(_buffer, buffer_data, sub_range);
|
||||
let actual_mapping = js_sys::Uint8Array::new(&array_buffer);
|
||||
let temporary_mapping = actual_mapping.to_vec();
|
||||
Box::new(BufferMappedRange {
|
||||
@ -1902,6 +1900,18 @@ impl crate::context::Context for Context {
|
||||
})
|
||||
}
|
||||
|
||||
fn buffer_get_mapped_range_as_array_buffer(
|
||||
&self,
|
||||
_buffer: &Self::BufferId,
|
||||
buffer_data: &Self::BufferData,
|
||||
sub_range: Range<wgt::BufferAddress>,
|
||||
) -> js_sys::ArrayBuffer {
|
||||
buffer_data.0.get_mapped_range_with_f64_and_f64(
|
||||
sub_range.start as f64,
|
||||
(sub_range.end - sub_range.start) as f64,
|
||||
)
|
||||
}
|
||||
|
||||
fn buffer_unmap(&self, _buffer: &Self::BufferId, buffer_data: &Self::BufferData) {
|
||||
buffer_data.0.unmap();
|
||||
}
|
||||
|
@ -307,6 +307,16 @@ pub trait Context: Debug + WasmNotSend + WasmNotSync + Sized {
|
||||
buffer_data: &Self::BufferData,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> Box<dyn BufferMappedRange>;
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
fn buffer_get_mapped_range_as_array_buffer(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
buffer_data: &Self::BufferData,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> js_sys::ArrayBuffer;
|
||||
fn buffer_unmap(&self, buffer: &Self::BufferId, buffer_data: &Self::BufferData);
|
||||
fn texture_create_view(
|
||||
&self,
|
||||
@ -1375,6 +1385,16 @@ pub(crate) trait DynContext: Debug + WasmNotSend + WasmNotSync {
|
||||
buffer_data: &crate::Data,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> Box<dyn BufferMappedRange>;
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
fn buffer_get_mapped_range_as_array_buffer(
|
||||
&self,
|
||||
buffer: &ObjectId,
|
||||
buffer_data: &crate::Data,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> js_sys::ArrayBuffer;
|
||||
fn buffer_unmap(&self, buffer: &ObjectId, buffer_data: &crate::Data);
|
||||
fn texture_create_view(
|
||||
&self,
|
||||
@ -2453,6 +2473,21 @@ where
|
||||
Context::buffer_get_mapped_range(self, &buffer, buffer_data, sub_range)
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
fn buffer_get_mapped_range_as_array_buffer(
|
||||
&self,
|
||||
buffer: &ObjectId,
|
||||
buffer_data: &crate::Data,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> js_sys::ArrayBuffer {
|
||||
let buffer = <T::BufferId>::from(*buffer);
|
||||
let buffer_data = downcast_ref(buffer_data);
|
||||
Context::buffer_get_mapped_range_as_array_buffer(self, &buffer, buffer_data, sub_range)
|
||||
}
|
||||
|
||||
fn buffer_unmap(&self, buffer: &ObjectId, buffer_data: &crate::Data) {
|
||||
let buffer = <T::BufferId>::from(*buffer);
|
||||
let buffer_data = downcast_ref(buffer_data);
|
||||
|
@ -2931,6 +2931,26 @@ impl<'a> BufferSlice<'a> {
|
||||
BufferView { slice: *self, data }
|
||||
}
|
||||
|
||||
/// Synchronously and immediately map a buffer for reading. If the buffer is not immediately mappable
|
||||
/// through [`BufferDescriptor::mapped_at_creation`] or [`BufferSlice::map_async`], will panic.
|
||||
///
|
||||
/// This is useful in wasm builds when you want to pass mapped data directly to js. Unlike `get_mapped_range`
|
||||
/// which unconditionally copies mapped data into the wasm heap, this function directly hands you the
|
||||
/// ArrayBuffer that we mapped the data into in js.
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
pub fn get_mapped_range_as_array_buffer(&self) -> js_sys::ArrayBuffer {
|
||||
let end = self.buffer.map_context.lock().add(self.offset, self.size);
|
||||
DynContext::buffer_get_mapped_range_as_array_buffer(
|
||||
&*self.buffer.context,
|
||||
&self.buffer.id,
|
||||
self.buffer.data.as_ref(),
|
||||
self.offset..end,
|
||||
)
|
||||
}
|
||||
|
||||
/// Synchronously and immediately map a buffer for writing. If the buffer is not immediately mappable
|
||||
/// through [`BufferDescriptor::mapped_at_creation`] or [`BufferSlice::map_async`], will panic.
|
||||
pub fn get_mapped_range_mut(&self) -> BufferViewMut<'a> {
|
||||
|
Loading…
Reference in New Issue
Block a user