mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
webgpu: Sync GPUBuffer
(#33154)
* More helpers on `Promise` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Sync `GPUBuffer` Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Set some good expectations Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Some bad expect also on firefox Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Extract DataBlock, DataView impl from GPUBuffer Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Fix size check to work on 32bit platforms Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
bb5926b329
commit
7fce24f9d5
12 changed files with 690 additions and 1163 deletions
|
@ -267,9 +267,8 @@ pub enum WebGPURequest {
|
|||
},
|
||||
UnmapBuffer {
|
||||
buffer_id: id::BufferId,
|
||||
device_id: id::DeviceId,
|
||||
array_buffer: IpcSharedMemory,
|
||||
is_map_read: bool,
|
||||
write_back: bool,
|
||||
offset: u64,
|
||||
size: u64,
|
||||
},
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
//! IPC messages that are send to WebGPU DOM objects.
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wgc::id;
|
||||
use wgc::pipeline::CreateShaderModuleError;
|
||||
use wgpu_core::device::HostMap;
|
||||
use wgpu_core::instance::{RequestAdapterError, RequestDeviceError};
|
||||
use wgpu_core::resource::BufferAccessError;
|
||||
pub use {wgpu_core as wgc, wgpu_types as wgt};
|
||||
|
@ -72,6 +75,13 @@ pub struct Pipeline<T: std::fmt::Debug + Serialize> {
|
|||
pub label: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Mapping {
|
||||
pub data: IpcSharedMemory,
|
||||
pub mode: HostMap,
|
||||
pub range: Range<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum WebGPUResponse {
|
||||
|
@ -85,7 +95,7 @@ pub enum WebGPUResponse {
|
|||
Result<wgt::DeviceDescriptor<Option<String>>, RequestDeviceError>,
|
||||
),
|
||||
),
|
||||
BufferMapAsync(Result<IpcSharedMemory, BufferAccessError>),
|
||||
BufferMapAsync(Result<Mapping, BufferAccessError>),
|
||||
SubmittedWorkDone,
|
||||
PoppedErrorScope(Result<Option<Error>, PopError>),
|
||||
CompilationInfo(Option<ShaderCompilationInfo>),
|
||||
|
|
|
@ -40,8 +40,8 @@ use crate::gpu_error::ErrorScope;
|
|||
use crate::poll_thread::Poller;
|
||||
use crate::render_commands::apply_render_command;
|
||||
use crate::{
|
||||
Adapter, ComputePassId, Error, Pipeline, PopError, PresentationData, RenderPassId, WebGPU,
|
||||
WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse,
|
||||
Adapter, ComputePassId, Error, Mapping, Pipeline, PopError, PresentationData, RenderPassId,
|
||||
WebGPU, WebGPUAdapter, WebGPUDevice, WebGPUMsg, WebGPUQueue, WebGPURequest, WebGPUResponse,
|
||||
};
|
||||
|
||||
pub const PRESENTATION_BUFFER_COUNT: usize = 10;
|
||||
|
@ -191,11 +191,11 @@ impl WGPU {
|
|||
let callback = BufferMapCallback::from_rust(Box::from(
|
||||
move |result: BufferAccessResult| {
|
||||
drop(token);
|
||||
let response = result.map(|_| {
|
||||
let response = result.and_then(|_| {
|
||||
let global = &glob;
|
||||
let (slice_pointer, range_size) = gfx_select!(buffer_id =>
|
||||
global.buffer_get_mapped_range(buffer_id, 0, None))
|
||||
.unwrap();
|
||||
global.buffer_get_mapped_range(buffer_id, offset, size))
|
||||
?;
|
||||
// SAFETY: guarantee to be safe from wgpu
|
||||
let data = unsafe {
|
||||
slice::from_raw_parts(
|
||||
|
@ -204,7 +204,11 @@ impl WGPU {
|
|||
)
|
||||
};
|
||||
|
||||
IpcSharedMemory::from_bytes(data)
|
||||
Ok(Mapping {
|
||||
data: IpcSharedMemory::from_bytes(data),
|
||||
range: offset..offset + range_size,
|
||||
mode: host_map,
|
||||
})
|
||||
});
|
||||
if let Err(e) =
|
||||
resp_sender.send(WebGPUResponse::BufferMapAsync(response))
|
||||
|
@ -226,13 +230,6 @@ impl WGPU {
|
|||
operation
|
||||
));
|
||||
self.poller.wake();
|
||||
if let Err(e) = &result {
|
||||
if let Err(w) =
|
||||
sender.send(WebGPUResponse::BufferMapAsync(Err(e.to_owned())))
|
||||
{
|
||||
warn!("Failed to send BufferMapAsync Response ({:?})", w);
|
||||
}
|
||||
}
|
||||
// Per spec we also need to raise validation error here
|
||||
self.maybe_dispatch_wgpu_error(device_id, result.err());
|
||||
},
|
||||
|
@ -1208,31 +1205,31 @@ impl WGPU {
|
|||
},
|
||||
WebGPURequest::UnmapBuffer {
|
||||
buffer_id,
|
||||
device_id,
|
||||
array_buffer,
|
||||
is_map_read,
|
||||
write_back,
|
||||
offset,
|
||||
size,
|
||||
} => {
|
||||
let global = &self.global;
|
||||
if !is_map_read {
|
||||
let (slice_pointer, range_size) =
|
||||
gfx_select!(buffer_id => global.buffer_get_mapped_range(
|
||||
if write_back {
|
||||
if let Ok((slice_pointer, range_size)) = gfx_select!(
|
||||
buffer_id => global.buffer_get_mapped_range(
|
||||
buffer_id,
|
||||
offset,
|
||||
Some(size)
|
||||
))
|
||||
.unwrap();
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
slice_pointer.as_ptr(),
|
||||
range_size as usize,
|
||||
)
|
||||
) {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
slice_pointer.as_ptr(),
|
||||
range_size as usize,
|
||||
)
|
||||
}
|
||||
.copy_from_slice(&array_buffer);
|
||||
}
|
||||
.copy_from_slice(&array_buffer);
|
||||
}
|
||||
let result = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
|
||||
self.maybe_dispatch_wgpu_error(device_id, result.err());
|
||||
// Ignore result because this operation always succeed from user perspective
|
||||
let _result = gfx_select!(buffer_id => global.buffer_unmap(buffer_id));
|
||||
},
|
||||
WebGPURequest::WriteBuffer {
|
||||
device_id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue