mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-26 16:53:48 +00:00
hal/gles: fix dirty vertex buffers that are unused
This commit is contained in:
parent
36ce638381
commit
9219489894
@ -28,6 +28,7 @@ pub(super) struct State {
|
||||
has_pass_label: bool,
|
||||
instance_vbuf_mask: usize,
|
||||
dirty_vbuf_mask: usize,
|
||||
active_first_instance: u32,
|
||||
push_offset_to_uniform: ArrayVec<super::UniformDesc, { super::MAX_PUSH_CONSTANTS }>,
|
||||
}
|
||||
|
||||
@ -91,34 +92,44 @@ impl super::CommandEncoder {
|
||||
.private_caps
|
||||
.contains(super::PrivateCapabilities::VERTEX_BUFFER_LAYOUT)
|
||||
{
|
||||
for (index, &(ref vb_desc, ref vb)) in self.state.vertex_buffers.iter().enumerate() {
|
||||
for (index, pair) in self.state.vertex_buffers.iter().enumerate() {
|
||||
if self.state.dirty_vbuf_mask & (1 << index) == 0 {
|
||||
continue;
|
||||
}
|
||||
let vb = vb.as_ref().unwrap();
|
||||
let instance_offset = match vb_desc.step {
|
||||
wgt::VertexStepMode::Vertex => 0,
|
||||
wgt::VertexStepMode::Instance => first_instance * vb_desc.stride,
|
||||
let (buffer_desc, vb) = match *pair {
|
||||
// Not all dirty bindings are necessarily filled. Some may be unused.
|
||||
(_, None) => continue,
|
||||
(ref vb_desc, Some(ref vb)) => (vb_desc.clone(), vb),
|
||||
};
|
||||
let instance_offset = match buffer_desc.step {
|
||||
wgt::VertexStepMode::Vertex => 0,
|
||||
wgt::VertexStepMode::Instance => first_instance * buffer_desc.stride,
|
||||
};
|
||||
|
||||
self.cmd_buffer.commands.push(C::SetVertexBuffer {
|
||||
index: index as u32,
|
||||
buffer: super::BufferBinding {
|
||||
raw: vb.raw,
|
||||
offset: vb.offset + instance_offset as wgt::BufferAddress,
|
||||
},
|
||||
buffer_desc: vb_desc.clone(),
|
||||
buffer_desc,
|
||||
});
|
||||
self.state.dirty_vbuf_mask ^= 1 << index;
|
||||
}
|
||||
} else {
|
||||
let mut vbuf_mask = 0;
|
||||
for attribute in self.state.vertex_attributes.iter() {
|
||||
if self.state.dirty_vbuf_mask & (1 << attribute.buffer_index) == 0 {
|
||||
continue;
|
||||
}
|
||||
let (buffer_desc, buffer) =
|
||||
self.state.vertex_buffers[attribute.buffer_index as usize].clone();
|
||||
let (buffer_desc, vb) =
|
||||
match self.state.vertex_buffers[attribute.buffer_index as usize] {
|
||||
// Not all dirty bindings are necessarily filled. Some may be unused.
|
||||
(_, None) => continue,
|
||||
(ref vb_desc, Some(ref vb)) => (vb_desc.clone(), vb),
|
||||
};
|
||||
|
||||
let mut attribute_desc = attribute.clone();
|
||||
let vb = buffer.unwrap();
|
||||
attribute_desc.offset += vb.offset as u32;
|
||||
if buffer_desc.step == wgt::VertexStepMode::Instance {
|
||||
attribute_desc.offset += buffer_desc.stride * first_instance;
|
||||
@ -129,7 +140,9 @@ impl super::CommandEncoder {
|
||||
buffer_desc,
|
||||
attribute_desc,
|
||||
});
|
||||
vbuf_mask |= 1 << attribute.buffer_index;
|
||||
}
|
||||
self.state.dirty_vbuf_mask ^= vbuf_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,13 +164,13 @@ impl super::CommandEncoder {
|
||||
}
|
||||
|
||||
fn prepare_draw(&mut self, first_instance: u32) {
|
||||
if first_instance != 0 {
|
||||
if first_instance != self.state.active_first_instance {
|
||||
// rebind all per-instance buffers on first-instance change
|
||||
self.state.dirty_vbuf_mask |= self.state.instance_vbuf_mask;
|
||||
self.state.active_first_instance = first_instance;
|
||||
}
|
||||
if self.state.dirty_vbuf_mask != 0 {
|
||||
self.rebind_vertex_data(first_instance);
|
||||
let vertex_rate_mask = self.state.dirty_vbuf_mask & !self.state.instance_vbuf_mask;
|
||||
self.state.dirty_vbuf_mask ^= vertex_rate_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,6 +552,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
}
|
||||
self.state.instance_vbuf_mask = 0;
|
||||
self.state.dirty_vbuf_mask = 0;
|
||||
self.state.active_first_instance = 0;
|
||||
self.state.color_targets.clear();
|
||||
self.state.vertex_attributes.clear();
|
||||
self.state.primitive = super::PrimitiveState::default();
|
||||
|
Loading…
Reference in New Issue
Block a user