[rs] Implement read_buffer utility function

This commit is contained in:
Jonathan Behrens
2021-01-11 18:11:51 -05:00
parent f9eb133370
commit 7a02bfca78
2 changed files with 39 additions and 7 deletions

View File

@@ -1901,7 +1901,7 @@ impl crate::BufferMappedRangeSlice for BufferMappedRange {
}
}
impl<'a> Drop for BufferMappedRange<'a> {
impl Drop for BufferMappedRange {
fn drop(&mut self) {
// Copy from the temporary mapping back into the array buffer that was
// originally provided by the browser

View File

@@ -6,6 +6,7 @@ mod encoder;
use std::{
borrow::Cow,
future::Future,
mem::{align_of, size_of},
ptr::copy_nonoverlapping,
};
@@ -55,10 +56,41 @@ pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderSource<'a> {
super::ShaderSource::SpirV(words)
}
struct ReadBuffer(super::BufferMappedRange);
impl std::ops::Deref for ReadBuffer{
type Target = [u8];
fn deref(&self) -> &[u8] {
super::BufferMappedRangeSlice::slice(&self.0)
}
/// CPU accessible buffer used to download data back from the GPU.
pub struct DownloadBuffer(super::Buffer, super::BufferMappedRange);
impl DownloadBuffer {
/// Asynchronously read the contents of a buffer.
pub fn read_buffer(device: &super::Device, queue: &super::Queue, buffer: &super::BufferSlice) -> impl Future<Output=Result<Self, super::BufferAsyncError>> + Send {
let size = match buffer.size {
Some(size) => size.into(),
None => buffer.buffer.map_context.lock().total_size - buffer.offset,
};
let download = device.create_buffer(&super::BufferDescriptor {
size,
usage: super::BufferUsage::COPY_DST | super::BufferUsage::MAP_READ,
mapped_at_creation: false,
label: None,
});
let mut encoder = device.create_command_encoder(&super::CommandEncoderDescriptor { label: None });
encoder.copy_buffer_to_buffer(buffer.buffer, buffer.offset, &download, 0, size);
let command_buffer: super::CommandBuffer = encoder.finish();
queue.submit(Some(command_buffer));
let fut = download.slice(..).map_async(super::MapMode::Read);
async move {
fut.await?;
let mapped_range = super::Context::buffer_get_mapped_range(&*download.context, &download.id, 0..size);
Ok(Self(download, mapped_range))
}
}
}
impl std::ops::Deref for DownloadBuffer{
type Target = [u8];
fn deref(&self) -> &[u8] {
super::BufferMappedRangeSlice::slice(&self.1)
}
}