Update wgpu and use write_texture

This commit is contained in:
Dzmitry Malyshau
2020-05-24 00:35:45 -04:00
parent 4b16959e3e
commit 686b4f71a6
12 changed files with 119 additions and 92 deletions

View File

@@ -28,14 +28,14 @@ vulkan = ["wgc/gfx-backend-vulkan"]
package = "wgpu-core"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "a203333c3e144cfd431c812213966ee32ae59d98"
rev = "4e1d76013c0b272383400beba48dc306e1a350f6"
features = ["raw-window-handle"]
[dependencies.wgt]
package = "wgpu-types"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "a203333c3e144cfd431c812213966ee32ae59d98"
rev = "4e1d76013c0b272383400beba48dc306e1a350f6"
[dependencies]
arrayvec = "0.5"

View File

@@ -32,6 +32,7 @@ impl framework::Example for Example {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
// load (and compile) shaders and create shader modules

View File

@@ -76,14 +76,15 @@ async fn run() {
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d::ZERO,
},
wgpu::BufferCopyView {
buffer: &output_buffer,
offset: 0,
bytes_per_row: size_of::<u32>() as u32 * size,
rows_per_image: 0,
layout: wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: size_of::<u32>() as u32 * size,
rows_per_image: 0,
},
},
texture_extent,
);

View File

@@ -115,12 +115,10 @@ impl framework::Example for Example {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
use std::mem;
let mut init_encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
// Create the vertex and index buffers
let vertex_size = mem::size_of::<Vertex>();
let (vertex_data, index_data) = create_vertices();
@@ -180,21 +178,18 @@ impl framework::Example for Example {
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
});
let texture_view = texture.create_default_view();
let temp_buf =
device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC);
init_encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &temp_buf,
offset: 0,
bytes_per_row: 4 * size,
rows_per_image: 0,
},
queue.write_texture(
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d::ZERO,
},
&texels,
wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * size,
rows_per_image: 0,
},
texture_extent,
);
@@ -304,7 +299,7 @@ impl framework::Example for Example {
uniform_buf,
pipeline,
};
(this, Some(init_encoder.finish()))
(this, None)
}
fn update(&mut self, _event: winit::event::WindowEvent) {
@@ -319,7 +314,7 @@ impl framework::Example for Example {
) {
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
let mx_ref: &[f32; 16] = mx_total.as_ref();
queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0);
queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref));
}
fn render(

View File

@@ -33,6 +33,7 @@ pub trait Example: 'static + Sized {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>);
fn resize(
&mut self,
@@ -79,14 +80,7 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
},
limits: wgpu::Limits::default(),
},
match trace_dir {
Ok(ref value) if !cfg!(feature = "trace") => {
log::error!("Unable to trace into {:?} without \"trace\" feature enabled!", value);
None
}
Ok(ref value) => Some(std::path::Path::new(value)),
Err(_) => None,
},
trace_dir.ok().as_ref().map(std::path::Path::new),
)
.await
.unwrap();
@@ -106,7 +100,7 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
log::info!("Initializing the example...");
let (mut example, init_command_buf) = E::init(&sc_desc, &device);
let (mut example, init_command_buf) = E::init(&sc_desc, &device, &queue);
if init_command_buf.is_some() {
queue.submit(init_command_buf);
}

View File

@@ -211,6 +211,7 @@ impl framework::Example for Example {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
use std::mem;
@@ -275,19 +276,22 @@ impl framework::Example for Example {
label: None,
});
let texture_view = texture.create_default_view();
//Note: we could use queue.write_texture instead, and this is what other
// examples do, but here we want to show another way to do this.
let temp_buf =
device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC);
init_encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &temp_buf,
offset: 0,
bytes_per_row: 4 * size,
rows_per_image: 0,
layout: wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * size,
rows_per_image: 0,
},
},
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d::ZERO,
},
texture_extent,
@@ -403,7 +407,7 @@ impl framework::Example for Example {
) {
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
let mx_ref: &[f32; 16] = mx_total.as_ref();
queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0);
queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref));
}
fn render(

View File

@@ -116,6 +116,7 @@ impl framework::Example for Example {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
log::info!("Press left/right arrow keys to change sample_count.");
let sample_count = 4;

View File

@@ -208,6 +208,7 @@ impl framework::Example for Example {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
_queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
// Create the vertex and index buffers
let vertex_size = mem::size_of::<Vertex>();
@@ -674,9 +675,9 @@ impl framework::Example for Example {
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32);
let mx_ref: &[f32; 16] = mx_total.as_ref();
queue.write_buffer(
bytemuck::cast_slice(mx_ref),
&self.forward_pass.uniform_buf,
0,
bytemuck::cast_slice(mx_ref),
);
let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
@@ -716,16 +717,16 @@ impl framework::Example for Example {
entity.color.a as f32,
],
};
queue.write_buffer(bytemuck::bytes_of(&data), &entity.uniform_buf, 0);
queue.write_buffer(&entity.uniform_buf, 0, bytemuck::bytes_of(&data));
}
if self.lights_are_dirty {
self.lights_are_dirty = false;
for (i, light) in self.lights.iter().enumerate() {
queue.write_buffer(
bytemuck::bytes_of(&light.to_raw()),
&self.light_uniform_buf,
(i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress,
bytemuck::bytes_of(&light.to_raw()),
);
}
}

View File

@@ -38,10 +38,8 @@ impl framework::Example for Skybox {
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (Self, Option<wgpu::CommandBuffer>) {
let mut init_encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutEntry {
@@ -180,20 +178,21 @@ impl framework::Example for Skybox {
image_width,
image_height,
);
let image_buf = device.create_buffer_with_data(image, wgpu::BufferUsage::COPY_SRC);
init_encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &image_buf,
offset: 0,
bytes_per_row: 4 * image_width,
rows_per_image: 0,
},
queue.write_texture(
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: i as u32,
origin: wgpu::Origin3d::ZERO,
origin: wgpu::Origin3d {
x: 0,
y: 0,
z: i as u32,
},
},
&image,
wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * image_width,
rows_per_image: 0,
},
wgpu::Extent3d {
width: image_width,
@@ -239,7 +238,7 @@ impl framework::Example for Skybox {
aspect,
uniforms,
},
Some(init_encoder.finish()),
None,
)
}
@@ -257,7 +256,7 @@ impl framework::Example for Skybox {
let uniforms = Skybox::generate_uniforms(self.aspect);
let mx_total = uniforms[0] * uniforms[1];
let mx_ref: &[f32; 16] = mx_total.as_ref();
queue.write_buffer(bytemuck::cast_slice(mx_ref), &self.uniform_buf, 0);
queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(mx_ref));
}
fn render(
@@ -270,9 +269,9 @@ impl framework::Example for Skybox {
let rotation = cgmath::Matrix4::<f32>::from_angle_x(cgmath::Deg(0.25));
self.uniforms[1] = self.uniforms[1] * rotation;
queue.write_buffer(
bytemuck::cast_slice(&raw_uniforms(&self.uniforms)),
&self.uniform_buf,
0,
bytemuck::cast_slice(&raw_uniforms(&self.uniforms)),
);
let mut encoder =

View File

@@ -166,20 +166,17 @@ mod pass_impl {
}
}
fn map_buffer_copy_view(view: crate::BufferCopyView<'_>) -> wgc::command::BufferCopyView {
fn map_buffer_copy_view(view: crate::BufferCopyView) -> wgc::command::BufferCopyView {
wgc::command::BufferCopyView {
buffer: view.buffer.id,
offset: view.offset,
bytes_per_row: view.bytes_per_row,
rows_per_image: view.rows_per_image,
layout: view.layout,
}
}
fn map_texture_copy_view<'a>(view: crate::TextureCopyView<'a>) -> wgc::command::TextureCopyView {
fn map_texture_copy_view(view: crate::TextureCopyView) -> wgc::command::TextureCopyView {
wgc::command::TextureCopyView {
texture: view.texture.id,
mip_level: view.mip_level,
array_layer: view.array_layer,
origin: view.origin,
}
}
@@ -764,7 +761,7 @@ impl crate::Context for Context {
*encoder,
&map_buffer_copy_view(source),
&map_texture_copy_view(destination),
copy_size
&copy_size
))
}
@@ -779,7 +776,7 @@ impl crate::Context for Context {
*encoder,
&map_texture_copy_view(source),
&map_buffer_copy_view(destination),
copy_size
&copy_size
))
}
@@ -794,7 +791,7 @@ impl crate::Context for Context {
*encoder,
&map_texture_copy_view(source),
&map_texture_copy_view(destination),
copy_size
&copy_size
))
}
@@ -879,11 +876,28 @@ impl crate::Context for Context {
fn queue_write_buffer(
&self,
queue: &Self::QueueId,
data: &[u8],
buffer: &Self::BufferId,
offset: wgt::BufferAddress,
data: &[u8],
) {
gfx_select!(*queue => self.queue_write_buffer(*queue, data, *buffer, offset))
gfx_select!(*queue => self.queue_write_buffer(*queue, *buffer, offset, data))
}
fn queue_write_texture(
&self,
queue: &Self::QueueId,
texture: crate::TextureCopyView,
data: &[u8],
data_layout: wgt::TextureDataLayout,
size: wgt::Extent3d,
) {
gfx_select!(*queue => self.queue_write_texture(
*queue,
&map_texture_copy_view(texture),
data,
&data_layout,
&size
))
}
fn queue_submit<I: Iterator<Item = Self::CommandBufferId>>(

View File

@@ -496,16 +496,15 @@ fn map_texture_view_dimension(
}
}
fn map_buffer_copy_view(view: crate::BufferCopyView<'_>) -> web_sys::GpuBufferCopyView {
let mut mapped = web_sys::GpuBufferCopyView::new(&view.buffer.id.0, view.bytes_per_row);
mapped.rows_per_image(view.rows_per_image);
mapped.offset(view.offset as f64);
fn map_buffer_copy_view(view: crate::BufferCopyView) -> web_sys::GpuBufferCopyView {
let mut mapped = web_sys::GpuBufferCopyView::new(&view.buffer.id.0, view.layout.bytes_per_row);
mapped.rows_per_image(view.layout.rows_per_image);
mapped.offset(view.layout.offset as f64);
mapped
}
fn map_texture_copy_view<'a>(view: crate::TextureCopyView<'a>) -> web_sys::GpuTextureCopyView {
fn map_texture_copy_view(view: crate::TextureCopyView) -> web_sys::GpuTextureCopyView {
let mut mapped = web_sys::GpuTextureCopyView::new(&view.texture.id.0);
mapped.array_layer(view.array_layer);
mapped.mip_level(view.mip_level);
mapped.origin(&map_origin_3d(view.origin));
mapped
@@ -1323,9 +1322,20 @@ impl crate::Context for Context {
fn queue_write_buffer(
&self,
_queue: &Self::QueueId,
_data: &[u8],
_buffer: &Self::BufferId,
_offset: wgt::BufferAddress,
_data: &[u8],
) {
unimplemented!()
}
fn queue_write_texture(
&self,
_queue: &Self::QueueId,
_texture: crate::TextureCopyView,
_data: &[u8],
_data_layout: wgt::TextureDataLayout,
_size: wgt::Extent3d,
) {
unimplemented!()
}

View File

@@ -23,8 +23,8 @@ pub use wgt::{
Extensions, Extent3d, FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp,
Origin3d, PowerPreference, PresentMode, PrimitiveTopology, RasterizationStateDescriptor,
ShaderLocation, ShaderStage, StencilOperation, StencilStateFaceDescriptor, StoreOp,
SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDimension, TextureFormat,
TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat,
SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension,
TextureFormat, TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat,
BIND_BUFFER_ALIGNMENT, MAX_BIND_GROUPS,
};
@@ -291,9 +291,17 @@ trait Context: Sized {
fn queue_write_buffer(
&self,
queue: &Self::QueueId,
data: &[u8],
buffer: &Self::BufferId,
offset: BufferAddress,
data: &[u8],
);
fn queue_write_texture(
&self,
queue: &Self::QueueId,
texture: TextureCopyView,
data: &[u8],
data_layout: wgt::TextureDataLayout,
size: wgt::Extent3d,
);
fn queue_submit<I: Iterator<Item = Self::CommandBufferId>>(
&self,
@@ -838,17 +846,8 @@ pub struct BufferCopyView<'a> {
/// The buffer to be copied to or from.
pub buffer: &'a Buffer,
/// The offset in bytes from the start of the buffer.
/// In the future this must be aligned to 512 bytes, however the requirement is currently unimplemented.
pub offset: BufferAddress,
/// The size in bytes of a single row of the texture.
/// In the future this must be a multiple of 256 bytes, however the requirement is currently unimplemented.
pub bytes_per_row: u32,
/// The height in texels of the imaginary texture view overlaid on the buffer.
/// Must be zero for copies where `copy_size.depth == 1`.
pub rows_per_image: u32,
/// The layout of the texture data in this buffer.
pub layout: wgt::TextureDataLayout,
}
/// A view of a texture which can be used to copy to or from a buffer or another texture.
@@ -860,9 +859,6 @@ pub struct TextureCopyView<'a> {
/// The target mip level of the texture.
pub mip_level: u32,
/// The target layer of the texture.
pub array_layer: u32,
/// The base texel of the texture in the selected `mip_level`.
pub origin: Origin3d,
}
@@ -1590,8 +1586,19 @@ impl<'a> Drop for ComputePass<'a> {
impl Queue {
/// Schedule a data write into `buffer` starting at `offset`.
pub fn write_buffer(&self, data: &[u8], buffer: &Buffer, offset: BufferAddress) {
Context::queue_write_buffer(&*self.context, &self.id, data, &buffer.id, offset)
pub fn write_buffer(&self, buffer: &Buffer, offset: BufferAddress, data: &[u8]) {
Context::queue_write_buffer(&*self.context, &self.id, &buffer.id, offset, data)
}
/// Schedule a data write into `texture`.
pub fn write_texture(
&self,
texture: TextureCopyView,
data: &[u8],
data_layout: wgt::TextureDataLayout,
size: wgt::Extent3d,
) {
Context::queue_write_texture(&*self.context, &self.id, texture, data, data_layout, size)
}
/// Submits a series of finished command buffers for execution.