mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[rs] Update web bindings
This commit is contained in:
parent
6f712d59bd
commit
f79845e777
@ -97,6 +97,10 @@ test = true
|
||||
#gfx-backend-dx12 = { version = "0.6", path = "../gfx/src/backend/dx12" }
|
||||
#gfx-backend-dx11 = { version = "0.6", path = "../gfx/src/backend/dx11" }
|
||||
#gfx-backend-metal = { version = "0.6", path = "../gfx/src/backend/metal" }
|
||||
wasm-bindgen = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
wasm-bindgen-futures = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
web-sys = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
js-sys = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc = "0.2.7"
|
||||
@ -149,6 +153,7 @@ web-sys = { version = "=0.3.45", features = [
|
||||
"GpuInputStepMode",
|
||||
"GpuLimits",
|
||||
"GpuLoadOp",
|
||||
"GpuMapMode",
|
||||
"GpuOrigin3dDict",
|
||||
"GpuPipelineLayout",
|
||||
"GpuPipelineLayoutDescriptor",
|
||||
|
||||
@ -1216,7 +1216,7 @@ impl crate::Context for Context {
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
sub_range: Range<wgt::BufferAddress>,
|
||||
) -> &[u8] {
|
||||
) -> BufferMappedRange {
|
||||
let size = sub_range.end - sub_range.start;
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(buffer.id => global.buffer_get_mapped_range(
|
||||
@ -1224,28 +1224,15 @@ impl crate::Context for Context {
|
||||
sub_range.start,
|
||||
wgt::BufferSize::new(size)
|
||||
)) {
|
||||
Ok(ptr) => unsafe { slice::from_raw_parts(ptr, size as usize) },
|
||||
Ok(ptr) => BufferMappedRange {
|
||||
ptr,
|
||||
size: size as usize,
|
||||
phantom: PhantomData,
|
||||
},
|
||||
Err(err) => self.handle_error_fatal(err, "Buffer::get_mapped_range"),
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_get_mapped_range_mut(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
sub_range: Range<wgt::BufferAddress>,
|
||||
) -> &mut [u8] {
|
||||
let size = sub_range.end - sub_range.start;
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(buffer.id => global.buffer_get_mapped_range(
|
||||
buffer.id,
|
||||
sub_range.start,
|
||||
wgt::BufferSize::new(size)
|
||||
)) {
|
||||
Ok(ptr) => unsafe { slice::from_raw_parts_mut(ptr, size as usize) },
|
||||
Err(err) => self.handle_error_fatal(err, "Buffer::get_mapped_range_mut"),
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_unmap(&self, buffer: &Self::BufferId) {
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(buffer.id => global.buffer_unmap(buffer.id)) {
|
||||
@ -1740,3 +1727,27 @@ fn default_error_handler(err: crate::Error) {
|
||||
|
||||
panic!("Handling wgpu errors as fatal by default");
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BufferMappedRange<'a> {
|
||||
ptr: *mut u8,
|
||||
size: usize,
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> crate::BufferMappedRangeSlice for BufferMappedRange<'a> {
|
||||
fn slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.ptr, self.size) }
|
||||
}
|
||||
|
||||
fn slice_mut(&mut self) -> &mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.ptr, self.size) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for BufferMappedRange<'a> {
|
||||
fn drop(&mut self) {
|
||||
// Intentionally left blank so that `BufferMappedRange` still
|
||||
// implements `Drop`, to match the web backend
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod web;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub(crate) use web::Context;
|
||||
pub(crate) use web::{Context, BufferMappedRange};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod direct;
|
||||
@ -9,7 +9,7 @@ mod direct;
|
||||
mod error;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) use direct::Context;
|
||||
pub(crate) use direct::{Context, BufferMappedRange};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod native_gpu_future;
|
||||
|
||||
@ -42,29 +42,6 @@ impl fmt::Debug for Context {
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn create_buffer_init_polyfill(
|
||||
device: &Sendable<web_sys::GpuDevice>,
|
||||
desc: &BufferDescriptor<'_>,
|
||||
contents: &[u8],
|
||||
) -> Sendable<web_sys::GpuBuffer> {
|
||||
// Emulate buffer mapping with the old API. This is a temporary
|
||||
// polyfill until the new buffer mapping API is available on gecko.
|
||||
let mut buffer_desc =
|
||||
web_sys::GpuBufferDescriptor::new(desc.size as f64, desc.usage.bits());
|
||||
if let Some(label) = desc.label {
|
||||
buffer_desc.label(label);
|
||||
}
|
||||
let buffer = device.0.create_buffer(&buffer_desc);
|
||||
let data = js_sys::Uint8Array::from(contents).buffer();
|
||||
device
|
||||
.0
|
||||
.default_queue()
|
||||
.write_buffer_with_u32(&buffer, 0, &data);
|
||||
Sendable(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ComputePass(web_sys::GpuComputePassEncoder);
|
||||
#[derive(Debug)]
|
||||
@ -331,7 +308,7 @@ fn map_texture_format(texture_format: wgt::TextureFormat) -> web_sys::GpuTexture
|
||||
TextureFormat::Bgra8Unorm => tf::Bgra8unorm,
|
||||
TextureFormat::Bgra8UnormSrgb => tf::Bgra8unormSrgb,
|
||||
TextureFormat::Rgb10a2Unorm => tf::Rgb10a2unorm,
|
||||
TextureFormat::Rg11b10Float => tf::Rg11b10float,
|
||||
TextureFormat::Rg11b10Float => tf::Rg11b10ufloat,
|
||||
TextureFormat::Rg32Uint => tf::Rg32uint,
|
||||
TextureFormat::Rg32Sint => tf::Rg32sint,
|
||||
TextureFormat::Rg32Float => tf::Rg32float,
|
||||
@ -355,9 +332,7 @@ fn map_texture_component_type(
|
||||
wgt::TextureComponentType::Float => web_sys::GpuTextureComponentType::Float,
|
||||
wgt::TextureComponentType::Sint => web_sys::GpuTextureComponentType::Sint,
|
||||
wgt::TextureComponentType::Uint => web_sys::GpuTextureComponentType::Uint,
|
||||
wgt::TextureComponentType::DepthComparison => {
|
||||
panic!("depth-comparison is not supported here yet")
|
||||
}
|
||||
wgt::TextureComponentType::DepthComparison => web_sys::GpuTextureComponentType::DepthComparison,
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,7 +558,11 @@ fn map_vertex_state_descriptor(
|
||||
}
|
||||
|
||||
fn map_extent_3d(extent: wgt::Extent3d) -> web_sys::GpuExtent3dDict {
|
||||
web_sys::GpuExtent3dDict::new(extent.depth, extent.height, extent.width)
|
||||
let mut mapped = web_sys::GpuExtent3dDict::new();
|
||||
mapped.depth(extent.depth);
|
||||
mapped.height(extent.height);
|
||||
mapped.width(extent.height);
|
||||
mapped
|
||||
}
|
||||
|
||||
fn map_origin_3d(origin: wgt::Origin3d) -> web_sys::GpuOrigin3dDict {
|
||||
@ -617,7 +596,8 @@ fn map_texture_view_dimension(
|
||||
}
|
||||
|
||||
fn map_buffer_copy_view(view: crate::BufferCopyView) -> web_sys::GpuBufferCopyView {
|
||||
let mut mapped = web_sys::GpuBufferCopyView::new(view.layout.bytes_per_row, &view.buffer.id.0);
|
||||
let mut mapped = web_sys::GpuBufferCopyView::new(&view.buffer.id.0);
|
||||
mapped.bytes_per_row(view.layout.bytes_per_row);
|
||||
mapped.rows_per_image(view.layout.rows_per_image);
|
||||
mapped.offset(view.layout.offset as f64);
|
||||
mapped
|
||||
@ -666,6 +646,13 @@ fn map_store_op(store: bool) -> web_sys::GpuStoreOp {
|
||||
}
|
||||
}
|
||||
|
||||
fn map_map_mode(mode: crate::MapMode) -> u32 {
|
||||
match mode {
|
||||
crate::MapMode::Read => web_sys::GpuMapMode::READ,
|
||||
crate::MapMode::Write => web_sys::GpuMapMode::WRITE,
|
||||
}
|
||||
}
|
||||
|
||||
type JsFutureResult = Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>;
|
||||
type FutureMap<T> = futures::future::Map<wasm_bindgen_futures::JsFuture, fn(JsFutureResult) -> T>;
|
||||
|
||||
@ -688,35 +675,13 @@ fn future_request_device(
|
||||
.map_err(|_| crate::RequestDeviceError)
|
||||
}
|
||||
|
||||
pub(crate) struct MapFuture<T> {
|
||||
child: wasm_bindgen_futures::JsFuture,
|
||||
buffer: Option<web_sys::GpuBuffer>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
impl<T> Unpin for MapFuture<T> {}
|
||||
//type MapData = (web_sys::GpuBuffer, Vec<u8>);
|
||||
|
||||
impl std::future::Future for MapFuture<()> {
|
||||
type Output = Result<(), crate::BufferAsyncError>;
|
||||
fn poll(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
context: &mut std::task::Context,
|
||||
) -> std::task::Poll<Self::Output> {
|
||||
std::future::Future::poll(
|
||||
std::pin::Pin::new(&mut self.as_mut().get_mut().child),
|
||||
context,
|
||||
)
|
||||
.map(|result| {
|
||||
let _buffer = self.buffer.take().unwrap();
|
||||
result
|
||||
.map(|js_value| {
|
||||
let array_buffer = js_sys::ArrayBuffer::from(js_value);
|
||||
let _view = js_sys::Uint8Array::new(&array_buffer);
|
||||
() //TODO
|
||||
})
|
||||
.map_err(|_| crate::BufferAsyncError)
|
||||
})
|
||||
}
|
||||
fn future_map_async(
|
||||
result: JsFutureResult,
|
||||
) -> Result<(), crate::BufferAsyncError>
|
||||
{
|
||||
result
|
||||
.map(|_| ())
|
||||
.map_err(|_| crate::BufferAsyncError)
|
||||
}
|
||||
|
||||
impl crate::Context for Context {
|
||||
@ -748,7 +713,7 @@ impl crate::Context for Context {
|
||||
type RequestDeviceFuture = MakeSendFuture<
|
||||
FutureMap<Result<(Self::DeviceId, Self::QueueId), crate::RequestDeviceError>>,
|
||||
>;
|
||||
type MapAsyncFuture = MakeSendFuture<MapFuture<()>>;
|
||||
type MapAsyncFuture = MakeSendFuture<FutureMap<Result<(), crate::BufferAsyncError>>>;
|
||||
|
||||
fn init(_backends: wgt::BackendBit) -> Self {
|
||||
Context(web_sys::window().unwrap().navigator().gpu())
|
||||
@ -893,6 +858,7 @@ impl crate::Context for Context {
|
||||
BindingType::StorageBuffer { readonly: true, .. } => bt::ReadonlyStorageBuffer,
|
||||
BindingType::Sampler { comparison: false } => bt::Sampler,
|
||||
BindingType::Sampler { .. } => bt::ComparisonSampler,
|
||||
BindingType::SampledTexture { multisampled: true, .. } => bt::MultisampledTexture,
|
||||
BindingType::SampledTexture { .. } => bt::SampledTexture,
|
||||
BindingType::StorageTexture { readonly: true, .. } => {
|
||||
bt::ReadonlyStorageTexture
|
||||
@ -921,12 +887,10 @@ impl crate::Context for Context {
|
||||
|
||||
if let BindingType::SampledTexture {
|
||||
component_type,
|
||||
multisampled,
|
||||
..
|
||||
} = bind.ty
|
||||
{
|
||||
mapped_entry.texture_component_type(map_texture_component_type(component_type));
|
||||
mapped_entry.multisampled(multisampled);
|
||||
}
|
||||
|
||||
match bind.ty {
|
||||
@ -1096,6 +1060,7 @@ impl crate::Context for Context {
|
||||
) -> Self::BufferId {
|
||||
let mut mapped_desc =
|
||||
web_sys::GpuBufferDescriptor::new(desc.size as f64, desc.usage.bits());
|
||||
mapped_desc.mapped_at_creation(desc.mapped_at_creation);
|
||||
if let Some(ref label) = desc.label {
|
||||
mapped_desc.label(label);
|
||||
}
|
||||
@ -1182,32 +1147,37 @@ impl crate::Context for Context {
|
||||
|
||||
fn buffer_map_async(
|
||||
&self,
|
||||
_buffer: &Self::BufferId,
|
||||
_mode: crate::MapMode,
|
||||
_range: Range<wgt::BufferAddress>,
|
||||
buffer: &Self::BufferId,
|
||||
mode: crate::MapMode,
|
||||
range: Range<wgt::BufferAddress>,
|
||||
) -> Self::MapAsyncFuture {
|
||||
unimplemented!()
|
||||
//MakeSendFuture(MapFuture {
|
||||
// child: wasm_bindgen_futures::JsFuture::from(buffer.0.map_async()),
|
||||
// buffer: Some(buffer.0.clone()),
|
||||
// marker: PhantomData,
|
||||
//})
|
||||
let map_promise = buffer.0.map_async_with_f64_and_f64(
|
||||
map_map_mode(mode),
|
||||
range.start as f64,
|
||||
(range.end - range.start) as f64,
|
||||
);
|
||||
|
||||
MakeSendFuture(
|
||||
wasm_bindgen_futures::JsFuture::from(map_promise).map(future_map_async),
|
||||
)
|
||||
}
|
||||
|
||||
fn buffer_get_mapped_range(
|
||||
&self,
|
||||
_buffer: &Self::BufferId,
|
||||
_sub_range: Range<wgt::BufferAddress>,
|
||||
) -> &[u8] {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn buffer_get_mapped_range_mut(
|
||||
&self,
|
||||
_buffer: &Self::BufferId,
|
||||
_sub_range: Range<wgt::BufferAddress>,
|
||||
) -> &mut [u8] {
|
||||
unimplemented!()
|
||||
buffer: &Self::BufferId,
|
||||
sub_range: Range<wgt::BufferAddress>,
|
||||
) -> BufferMappedRange {
|
||||
let array_buffer = buffer.0.get_mapped_range_with_f64_and_f64(
|
||||
sub_range.start as f64,
|
||||
(sub_range.end - sub_range.start) as f64,
|
||||
);
|
||||
let actual_mapping = js_sys::Uint8Array::new(&array_buffer);
|
||||
let temporary_mapping = actual_mapping.to_vec();
|
||||
BufferMappedRange {
|
||||
actual_mapping,
|
||||
temporary_mapping,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_unmap(&self, buffer: &Self::BufferId) {
|
||||
@ -1499,13 +1469,13 @@ impl crate::Context for Context {
|
||||
Sendable(encoder.finish_with_descriptor(&mapped_desc))
|
||||
}
|
||||
|
||||
fn command_encoder_insert_debug_marker(&self, encoder: &Self::CommandEncoderId, label: &str) {
|
||||
fn command_encoder_insert_debug_marker(&self, _encoder: &Self::CommandEncoderId, _label: &str) {
|
||||
// TODO
|
||||
}
|
||||
fn command_encoder_push_debug_group(&self, encoder: &Self::CommandEncoderId, label: &str) {
|
||||
fn command_encoder_push_debug_group(&self, _encoder: &Self::CommandEncoderId, _label: &str) {
|
||||
// TODO
|
||||
}
|
||||
fn command_encoder_pop_debug_group(&self, encoder: &Self::CommandEncoderId) {
|
||||
fn command_encoder_pop_debug_group(&self, _encoder: &Self::CommandEncoderId) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -1524,7 +1494,16 @@ impl crate::Context for Context {
|
||||
offset: wgt::BufferAddress,
|
||||
data: &[u8],
|
||||
) {
|
||||
queue.0.write_buffer_with_f64_and_f64_and_f64(
|
||||
/* Skip the copy once gecko allows BufferSource instead of ArrayBuffer
|
||||
queue.0.write_buffer_with_f64_and_u8_array_and_f64_and_f64(
|
||||
&buffer.0,
|
||||
offset as f64,
|
||||
data,
|
||||
0f64,
|
||||
data.len() as f64,
|
||||
);
|
||||
*/
|
||||
queue.0.write_buffer_with_f64_and_buffer_source_and_f64_and_f64(
|
||||
&buffer.0,
|
||||
offset as f64,
|
||||
&js_sys::Uint8Array::from(data).buffer(),
|
||||
@ -1541,11 +1520,20 @@ impl crate::Context for Context {
|
||||
data_layout: wgt::TextureDataLayout,
|
||||
size: wgt::Extent3d,
|
||||
) {
|
||||
let mut mapped_data_layout = web_sys::GpuTextureDataLayout::new(data_layout.bytes_per_row);
|
||||
let mut mapped_data_layout = web_sys::GpuTextureDataLayout::new();
|
||||
mapped_data_layout.bytes_per_row(data_layout.bytes_per_row);
|
||||
mapped_data_layout.rows_per_image(data_layout.rows_per_image);
|
||||
mapped_data_layout.offset(data_layout.offset as f64);
|
||||
|
||||
queue.0.write_texture_with_gpu_extent_3d_dict(
|
||||
/* Skip the copy once gecko allows BufferSource instead of ArrayBuffer
|
||||
queue.0.write_texture_with_u8_array_and_gpu_extent_3d_dict(
|
||||
&map_texture_copy_view(texture),
|
||||
data,
|
||||
&mapped_data_layout,
|
||||
&map_extent_3d(size),
|
||||
);
|
||||
*/
|
||||
queue.0.write_texture_with_buffer_source_and_gpu_extent_3d_dict(
|
||||
&map_texture_copy_view(texture),
|
||||
&js_sys::Uint8Array::from(data).buffer(),
|
||||
&mapped_data_layout,
|
||||
@ -1565,3 +1553,33 @@ impl crate::Context for Context {
|
||||
}
|
||||
|
||||
pub(crate) type SwapChainOutputDetail = ();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BufferMappedRange<'a> {
|
||||
actual_mapping: js_sys::Uint8Array,
|
||||
temporary_mapping: Vec<u8>,
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> crate::BufferMappedRangeSlice for BufferMappedRange<'a> {
|
||||
fn slice(&self) -> &[u8] {
|
||||
&self.temporary_mapping
|
||||
}
|
||||
|
||||
fn slice_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.temporary_mapping
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for BufferMappedRange<'a> {
|
||||
fn drop(&mut self) {
|
||||
// Copy from the temporary mapping back into the array buffer that was
|
||||
// originally provided by the browser
|
||||
let temporary_mapping_slice = self.temporary_mapping.as_slice();
|
||||
unsafe {
|
||||
// Note: no allocations can happen between `view` and `set`, or this
|
||||
// will break
|
||||
self.actual_mapping.set(&js_sys::Uint8Array::view(temporary_mapping_slice), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ pub use wgt::{
|
||||
COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT,
|
||||
};
|
||||
|
||||
use backend::Context as C;
|
||||
use backend::{Context as C, BufferMappedRange};
|
||||
|
||||
trait ComputePassInner<Ctx: Context> {
|
||||
fn set_pipeline(&mut self, pipeline: &Ctx::ComputePipelineId);
|
||||
@ -274,18 +274,11 @@ trait Context: Debug + Send + Sized + Sync {
|
||||
mode: MapMode,
|
||||
range: Range<BufferAddress>,
|
||||
) -> Self::MapAsyncFuture;
|
||||
//TODO: we might be able to merge these, depending on how Web backend
|
||||
// turns out to be implemented.
|
||||
fn buffer_get_mapped_range(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> &[u8];
|
||||
fn buffer_get_mapped_range_mut(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
sub_range: Range<BufferAddress>,
|
||||
) -> &mut [u8];
|
||||
) -> BufferMappedRange;
|
||||
fn buffer_unmap(&self, buffer: &Self::BufferId);
|
||||
fn swap_chain_get_current_texture_view(
|
||||
&self,
|
||||
@ -466,9 +459,8 @@ pub enum Maintain {
|
||||
Poll,
|
||||
}
|
||||
|
||||
/// The main purpose of this struct is to resolve mapped ranges
|
||||
/// (convert sizes to end points), and to ensure that the sub-ranges
|
||||
/// don't intersect.
|
||||
/// The main purpose of this struct is to resolve mapped ranges (convert sizes
|
||||
/// to end points), and to ensure that the sub-ranges don't intersect.
|
||||
#[derive(Debug)]
|
||||
struct MapContext {
|
||||
total_size: BufferAddress,
|
||||
@ -1602,18 +1594,23 @@ fn range_to_offset_size<S: RangeBounds<BufferAddress>>(
|
||||
(offset, size)
|
||||
}
|
||||
|
||||
trait BufferMappedRangeSlice {
|
||||
fn slice(&self) -> &[u8];
|
||||
fn slice_mut(&mut self) -> &mut [u8];
|
||||
}
|
||||
|
||||
/// Read only view into a mapped buffer.
|
||||
#[derive(Debug)]
|
||||
pub struct BufferView<'a> {
|
||||
slice: BufferSlice<'a>,
|
||||
data: &'a [u8],
|
||||
data: BufferMappedRange<'a>,
|
||||
}
|
||||
|
||||
/// Write only view into mapped buffer.
|
||||
#[derive(Debug)]
|
||||
pub struct BufferViewMut<'a> {
|
||||
slice: BufferSlice<'a>,
|
||||
data: &'a mut [u8],
|
||||
data: BufferMappedRange<'a>,
|
||||
readable: bool,
|
||||
}
|
||||
|
||||
@ -1621,7 +1618,7 @@ impl std::ops::Deref for BufferView<'_> {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &[u8] {
|
||||
self.data
|
||||
self.data.slice()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1634,25 +1631,25 @@ impl std::ops::Deref for BufferViewMut<'_> {
|
||||
"Attempting to read a write-only mapping for buffer {:?}",
|
||||
self.slice.buffer.id
|
||||
);
|
||||
self.data
|
||||
self.data.slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for BufferViewMut<'_> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.data
|
||||
self.data.slice_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for BufferView<'_> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.data
|
||||
self.data.slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for BufferViewMut<'_> {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
self.data
|
||||
self.data.slice_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1724,21 +1721,19 @@ impl<'a> BufferSlice<'a> {
|
||||
&self,
|
||||
mode: MapMode,
|
||||
) -> impl Future<Output = Result<(), BufferAsyncError>> + Send {
|
||||
let end = {
|
||||
let mut mc = self.buffer.map_context.lock();
|
||||
assert_eq!(
|
||||
mc.initial_range,
|
||||
0..0,
|
||||
"Buffer {:?} is already mapped",
|
||||
self.buffer.id
|
||||
);
|
||||
let end = match self.size {
|
||||
Some(s) => self.offset + s.get(),
|
||||
None => mc.total_size,
|
||||
};
|
||||
mc.initial_range = self.offset..end;
|
||||
end
|
||||
let mut mc = self.buffer.map_context.lock();
|
||||
assert_eq!(
|
||||
mc.initial_range,
|
||||
0..0,
|
||||
"Buffer {:?} is already mapped",
|
||||
self.buffer.id
|
||||
);
|
||||
let end = match self.size {
|
||||
Some(s) => self.offset + s.get(),
|
||||
None => mc.total_size,
|
||||
};
|
||||
mc.initial_range = self.offset..end;
|
||||
|
||||
Context::buffer_map_async(
|
||||
&*self.buffer.context,
|
||||
&self.buffer.id,
|
||||
@ -1763,7 +1758,7 @@ impl<'a> BufferSlice<'a> {
|
||||
/// through [`BufferDescriptor::mapped_at_creation`] or [`BufferSlice::map_async`], will panic.
|
||||
pub fn get_mapped_range_mut(&self) -> BufferViewMut<'a> {
|
||||
let end = self.buffer.map_context.lock().add(self.offset, self.size);
|
||||
let data = Context::buffer_get_mapped_range_mut(
|
||||
let data = Context::buffer_get_mapped_range(
|
||||
&*self.buffer.context,
|
||||
&self.buffer.id,
|
||||
self.offset..end,
|
||||
|
||||
@ -9,7 +9,6 @@ use std::{
|
||||
};
|
||||
|
||||
pub use belt::StagingBelt;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Treat the given byte slice as a SPIR-V module.
|
||||
///
|
||||
@ -75,39 +74,16 @@ impl DeviceExt for crate::Device {
|
||||
|
||||
map_context.initial_range = 0..padded_size;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let buffer = crate::Buffer {
|
||||
context: Arc::clone(&self.context),
|
||||
id: crate::backend::Context::create_buffer_init_polyfill(
|
||||
&self.id,
|
||||
&wgt_descriptor,
|
||||
descriptor.contents,
|
||||
),
|
||||
map_context: parking_lot::Mutex::new(map_context),
|
||||
usage: descriptor.usage,
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let buffer = {
|
||||
let buffer = crate::Buffer {
|
||||
context: Arc::clone(&self.context),
|
||||
id: crate::Context::device_create_buffer(&*self.context, &self.id, &wgt_descriptor),
|
||||
map_context: parking_lot::Mutex::new(map_context),
|
||||
usage: descriptor.usage,
|
||||
};
|
||||
|
||||
let range = crate::Context::buffer_get_mapped_range_mut(
|
||||
&*self.context,
|
||||
&buffer.id,
|
||||
0..padded_size,
|
||||
);
|
||||
range[0..unpadded_size as usize].copy_from_slice(descriptor.contents);
|
||||
let buffer = self.create_buffer(&wgt_descriptor);
|
||||
{
|
||||
let mut slice = buffer.slice(..).get_mapped_range_mut();
|
||||
slice[0..unpadded_size as usize].copy_from_slice(descriptor.contents);
|
||||
|
||||
for i in unpadded_size..padded_size {
|
||||
range[i as usize] = 0;
|
||||
slice[i as usize] = 0;
|
||||
}
|
||||
|
||||
buffer.unmap();
|
||||
buffer
|
||||
};
|
||||
}
|
||||
buffer.unmap();
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user