mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[rs] Add Buffer.slice fn for #199
This fn is used for set_index_buffer, set_vertex_buffer, and BindingResource
This commit is contained in:
@@ -202,24 +202,17 @@ impl framework::Example for Example {
|
||||
bindings: &[
|
||||
wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &sim_param_buffer,
|
||||
range: 0..(4 * sim_param_data.len() as u64), // 4 = size_of f32
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(sim_param_buffer.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &particle_buffers[i],
|
||||
range: 0..(4 * initial_particle_data.len() as u64), // 4 = size_of f32
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(particle_buffers[i].slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 2,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &particle_buffers[(i + 1) % 2], // bind to opposite buffer
|
||||
range: 0..(4 * initial_particle_data.len() as u64), // 4 = size_of f32
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(
|
||||
particle_buffers[(i + 1) % 2].slice(..), // bind to opposite buffer
|
||||
),
|
||||
},
|
||||
],
|
||||
label: None,
|
||||
@@ -296,9 +289,9 @@ impl framework::Example for Example {
|
||||
let mut rpass = command_encoder.begin_render_pass(&render_pass_descriptor);
|
||||
rpass.set_pipeline(&self.render_pipeline);
|
||||
// render dst particles
|
||||
rpass.set_vertex_buffer(0, &self.particle_buffers[(self.frame_num + 1) % 2], 0, 0);
|
||||
rpass.set_vertex_buffer(0, self.particle_buffers[(self.frame_num + 1) % 2].slice(..));
|
||||
// the three instance-local vertices
|
||||
rpass.set_vertex_buffer(1, &self.vertices_buffer, 0, 0);
|
||||
rpass.set_vertex_buffer(1, self.vertices_buffer.slice(..));
|
||||
rpass.draw(0..3, 0..NUM_PARTICLES);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,10 +224,7 @@ impl framework::Example for Example {
|
||||
bindings: &[
|
||||
wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..64,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 1,
|
||||
@@ -356,8 +353,8 @@ impl framework::Example for Example {
|
||||
});
|
||||
rpass.set_pipeline(&self.pipeline);
|
||||
rpass.set_bind_group(0, &self.bind_group, &[]);
|
||||
rpass.set_index_buffer(&self.index_buf, 0, 0);
|
||||
rpass.set_vertex_buffer(0, &self.vertex_buf, 0, 0);
|
||||
rpass.set_index_buffer(self.index_buf.slice(..));
|
||||
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
|
||||
rpass.draw_indexed(0..self.index_count as u32, 0, 0..1);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,10 +80,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
|
||||
layout: &bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &storage_buffer,
|
||||
range: 0..size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(storage_buffer.slice(..)),
|
||||
}],
|
||||
label: None,
|
||||
});
|
||||
|
||||
@@ -319,10 +319,7 @@ impl framework::Example for Example {
|
||||
bindings: &[
|
||||
wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..64,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 1,
|
||||
@@ -440,7 +437,7 @@ impl framework::Example for Example {
|
||||
});
|
||||
rpass.set_pipeline(&self.draw_pipeline);
|
||||
rpass.set_bind_group(0, &self.bind_group, &[]);
|
||||
rpass.set_vertex_buffer(0, &self.vertex_buf, 0, 0);
|
||||
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
|
||||
rpass.draw(0..4, 0..1);
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ impl framework::Example for Example {
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&self.pipeline);
|
||||
rpass.set_vertex_buffer(0, &self.vertex_buffer, 0, 0);
|
||||
rpass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||
rpass.draw(0..self.vertex_count, 0..1);
|
||||
}
|
||||
|
||||
|
||||
@@ -257,10 +257,7 @@ impl framework::Example for Example {
|
||||
layout: &local_bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &plane_uniform_buf,
|
||||
range: 0..entity_uniform_size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(plane_uniform_buf.slice(..)),
|
||||
}],
|
||||
label: None,
|
||||
});
|
||||
@@ -333,10 +330,7 @@ impl framework::Example for Example {
|
||||
layout: &local_bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..entity_uniform_size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
}],
|
||||
label: None,
|
||||
}),
|
||||
@@ -452,10 +446,7 @@ impl framework::Example for Example {
|
||||
layout: &bind_group_layout,
|
||||
bindings: &[wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..uniform_size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
}],
|
||||
label: None,
|
||||
});
|
||||
@@ -555,7 +546,6 @@ impl framework::Example for Example {
|
||||
proj: *mx_total.as_ref(),
|
||||
num_lights: [lights.len() as u32, 0, 0, 0],
|
||||
};
|
||||
let uniform_size = mem::size_of::<ForwardUniforms>() as wgpu::BufferAddress;
|
||||
let uniform_buf = device.create_buffer_with_data(
|
||||
bytemuck::bytes_of(&forward_uniforms),
|
||||
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
@@ -567,17 +557,11 @@ impl framework::Example for Example {
|
||||
bindings: &[
|
||||
wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..uniform_size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &light_uniform_buf,
|
||||
range: 0..light_uniform_size,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(light_uniform_buf.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 2,
|
||||
@@ -820,8 +804,8 @@ impl framework::Example for Example {
|
||||
|
||||
for entity in &self.entities {
|
||||
pass.set_bind_group(1, &entity.bind_group, &[]);
|
||||
pass.set_index_buffer(&entity.index_buf, 0, 0);
|
||||
pass.set_vertex_buffer(0, &entity.vertex_buf, 0, 0);
|
||||
pass.set_index_buffer(entity.index_buf.slice(..));
|
||||
pass.set_vertex_buffer(0, entity.vertex_buf.slice(..));
|
||||
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
|
||||
}
|
||||
}
|
||||
@@ -856,8 +840,8 @@ impl framework::Example for Example {
|
||||
|
||||
for entity in &self.entities {
|
||||
pass.set_bind_group(1, &entity.bind_group, &[]);
|
||||
pass.set_index_buffer(&entity.index_buf, 0, 0);
|
||||
pass.set_vertex_buffer(0, &entity.vertex_buf, 0, 0);
|
||||
pass.set_index_buffer(entity.index_buf.slice(..));
|
||||
pass.set_vertex_buffer(0, entity.vertex_buf.slice(..));
|
||||
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ impl framework::Example for Skybox {
|
||||
&uniforms,
|
||||
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
);
|
||||
let uniform_buf_size = std::mem::size_of::<Uniforms>();
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: &[&bind_group_layout],
|
||||
@@ -234,10 +233,7 @@ impl framework::Example for Skybox {
|
||||
bindings: &[
|
||||
wgpu::Binding {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &uniform_buf,
|
||||
range: 0..uniform_buf_size as wgpu::BufferAddress,
|
||||
},
|
||||
resource: wgpu::BindingResource::Buffer(uniform_buf.slice(..)),
|
||||
},
|
||||
wgpu::Binding {
|
||||
binding: 1,
|
||||
|
||||
@@ -356,15 +356,14 @@ impl crate::Context for Context {
|
||||
.iter()
|
||||
.map(|binding| bm::BindGroupEntry {
|
||||
binding: binding.binding,
|
||||
resource: match binding.resource {
|
||||
BindingResource::Buffer {
|
||||
ref buffer,
|
||||
ref range,
|
||||
} => bm::BindingResource::Buffer(bm::BufferBinding {
|
||||
buffer: buffer.id,
|
||||
offset: range.start,
|
||||
size: range.end - range.start,
|
||||
}),
|
||||
resource: match &binding.resource {
|
||||
BindingResource::Buffer(buffer_slice) => {
|
||||
bm::BindingResource::Buffer(bm::BufferBinding {
|
||||
buffer: buffer_slice.buffer.id,
|
||||
offset: buffer_slice.offset,
|
||||
size: buffer_slice.size_or_0(),
|
||||
})
|
||||
}
|
||||
BindingResource::Sampler(ref sampler) => {
|
||||
bm::BindingResource::Sampler(sampler.id)
|
||||
}
|
||||
|
||||
@@ -826,15 +826,12 @@ impl crate::Context for Context {
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| {
|
||||
let mapped_resource = match binding.resource {
|
||||
BindingResource::Buffer {
|
||||
ref buffer,
|
||||
ref range,
|
||||
} => {
|
||||
let mapped_resource = match &binding.resource {
|
||||
BindingResource::Buffer(buffer_slice) => {
|
||||
let mut mapped_buffer_binding =
|
||||
web_sys::GpuBufferBinding::new(&buffer.id.0);
|
||||
mapped_buffer_binding.offset(range.start as f64);
|
||||
mapped_buffer_binding.size((range.end - range.start) as f64);
|
||||
web_sys::GpuBufferBinding::new(&buffer_slice.buffer.id.0);
|
||||
mapped_buffer_binding.offset(buffer_slice.offset as f64);
|
||||
mapped_buffer_binding.size(buffer_slice.size_or_0() as f64);
|
||||
JsValue::from(mapped_buffer_binding.clone())
|
||||
}
|
||||
BindingResource::Sampler(ref sampler) => JsValue::from(sampler.id.0.clone()),
|
||||
|
||||
@@ -6,7 +6,13 @@ mod backend;
|
||||
mod macros;
|
||||
|
||||
use futures::FutureExt as _;
|
||||
use std::{future::Future, marker::PhantomData, ops::Range, sync::Arc, thread};
|
||||
use std::{
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
ops::{Bound, Range, RangeBounds},
|
||||
sync::Arc,
|
||||
thread,
|
||||
};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use wgc::instance::{AdapterInfo, DeviceType};
|
||||
@@ -339,6 +345,21 @@ pub struct Buffer {
|
||||
//detail: <C as Context>::BufferDetail,
|
||||
}
|
||||
|
||||
/// A description of what portion of a buffer to use
|
||||
pub struct BufferSlice<'a> {
|
||||
buffer: &'a Buffer,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferAddress>,
|
||||
}
|
||||
|
||||
impl<'a> BufferSlice<'a> {
|
||||
/// This fn can be used for calling lower-level APIs where `0` denotes that the slice should
|
||||
/// extend to the end of the buffer.
|
||||
fn size_or_0(&self) -> BufferAddress {
|
||||
self.size.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A handle to a texture on the GPU.
|
||||
pub struct Texture {
|
||||
context: Arc<C>,
|
||||
@@ -535,10 +556,7 @@ pub struct Queue {
|
||||
|
||||
/// A resource that can be bound to a pipeline.
|
||||
pub enum BindingResource<'a> {
|
||||
Buffer {
|
||||
buffer: &'a Buffer,
|
||||
range: Range<BufferAddress>,
|
||||
},
|
||||
Buffer(BufferSlice<'a>),
|
||||
Sampler(&'a Sampler),
|
||||
TextureView(&'a TextureView),
|
||||
}
|
||||
@@ -1167,6 +1185,26 @@ impl Drop for BufferWriteMapping {
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
/// Use only a portion of this Buffer for a given operation. Choosing a range with 0 size will
|
||||
/// return a slice that extends to the end of the buffer.
|
||||
pub fn slice<S: RangeBounds<BufferAddress>>(&self, bounds: S) -> BufferSlice {
|
||||
let offset = match bounds.start_bound() {
|
||||
Bound::Included(&bound) => bound,
|
||||
Bound::Excluded(&bound) => bound + 1,
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
let size = match bounds.end_bound() {
|
||||
Bound::Included(&bound) => Some(bound + 1 - offset),
|
||||
Bound::Excluded(&bound) => Some(bound - offset),
|
||||
Bound::Unbounded => None,
|
||||
};
|
||||
BufferSlice {
|
||||
buffer: self,
|
||||
offset,
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
/// Map the buffer for reading. The result is returned in a future.
|
||||
///
|
||||
/// For the future to complete, `device.poll(...)` must be called elsewhere in the runtime, possibly integrated
|
||||
@@ -1376,15 +1414,13 @@ impl<'a> RenderPass<'a> {
|
||||
///
|
||||
/// Subsequent calls to [`draw_indexed`](RenderPass::draw_indexed) on this [`RenderPass`] will
|
||||
/// use `buffer` as the source index buffer.
|
||||
///
|
||||
/// If `size == 0`, the remaining part of the buffer is considered.
|
||||
pub fn set_index_buffer(
|
||||
&mut self,
|
||||
buffer: &'a Buffer,
|
||||
offset: BufferAddress,
|
||||
size: BufferAddress,
|
||||
) {
|
||||
RenderPassInner::set_index_buffer(&mut self.id, &buffer.id, offset, size)
|
||||
pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>) {
|
||||
RenderPassInner::set_index_buffer(
|
||||
&mut self.id,
|
||||
&buffer_slice.buffer.id,
|
||||
buffer_slice.offset,
|
||||
buffer_slice.size_or_0(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Assign a vertex buffer to a slot.
|
||||
@@ -1395,20 +1431,18 @@ impl<'a> RenderPass<'a> {
|
||||
/// The `slot` refers to the index of the matching descriptor in
|
||||
/// [`RenderPipelineDescriptor::vertex_buffers`].
|
||||
///
|
||||
/// If `size == 0`, the remaining part of the buffer is considered.
|
||||
///
|
||||
/// [`draw`]: #method.draw
|
||||
/// [`draw_indexed`]: #method.draw_indexed
|
||||
/// [`RenderPass`]: struct.RenderPass.html
|
||||
/// [`RenderPipelineDescriptor::vertex_buffers`]: struct.RenderPipelineDescriptor.html#structfield.vertex_buffers
|
||||
pub fn set_vertex_buffer(
|
||||
&mut self,
|
||||
slot: u32,
|
||||
buffer: &'a Buffer,
|
||||
offset: BufferAddress,
|
||||
size: BufferAddress,
|
||||
) {
|
||||
RenderPassInner::set_vertex_buffer(&mut self.id, slot, &buffer.id, offset, size)
|
||||
pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
|
||||
RenderPassInner::set_vertex_buffer(
|
||||
&mut self.id,
|
||||
slot,
|
||||
&buffer_slice.buffer.id,
|
||||
buffer_slice.offset,
|
||||
buffer_slice.size_or_0(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Sets the scissor region.
|
||||
|
||||
Reference in New Issue
Block a user