Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3133,7 +3133,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMesh {
return RenderCommandResult::Skip;
};

pass.set_index_buffer(index_buffer_slice.buffer.slice(..), 0, *index_format);
pass.set_index_buffer(index_buffer_slice.buffer.slice(..), *index_format);

match item.extra_index() {
PhaseItemExtraIndex::None | PhaseItemExtraIndex::DynamicOffset(_) => {
Expand Down
53 changes: 21 additions & 32 deletions crates/bevy_render/src/render_phase/draw_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use wgpu::{IndexFormat, QuerySet, RenderPass};
#[cfg(feature = "detailed_trace")]
use tracing::trace;

type BufferSliceKey = (BufferId, wgpu::BufferAddress, wgpu::BufferSize);

/// Tracks the state of a [`TrackedRenderPass`].
///
/// This is used to skip redundant operations on the [`TrackedRenderPass`] (e.g. setting an already
Expand All @@ -25,8 +27,8 @@ struct DrawState {
pipeline: Option<RenderPipelineId>,
bind_groups: Vec<(Option<BindGroupId>, Vec<u32>)>,
/// List of vertex buffers by [`BufferId`], offset, and size. See [`DrawState::buffer_slice_key`]
vertex_buffers: Vec<Option<(BufferId, u64, u64)>>,
index_buffer: Option<(BufferId, u64, IndexFormat)>,
vertex_buffers: Vec<Option<BufferSliceKey>>,
index_buffer: Option<(BufferSliceKey, IndexFormat)>,

/// Stores whether this state is populated or empty for quick state invalidation
stores_state: bool,
Expand Down Expand Up @@ -87,7 +89,7 @@ impl DrawState {
}

/// Returns the value used for checking whether `BufferSlice`s are equivalent.
fn buffer_slice_key(&self, buffer_slice: &BufferSlice) -> (BufferId, u64, u64) {
fn buffer_slice_key(&self, buffer_slice: &BufferSlice) -> BufferSliceKey {
(
buffer_slice.id(),
buffer_slice.offset(),
Expand All @@ -96,19 +98,14 @@ impl DrawState {
}

/// Marks the index `buffer` as bound.
fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) {
self.index_buffer = Some((buffer, offset, index_format));
fn set_index_buffer(&mut self, buffer_slice: &BufferSlice, index_format: IndexFormat) {
self.index_buffer = Some((self.buffer_slice_key(buffer_slice), index_format));
self.stores_state = true;
}

/// Checks, whether the index `buffer` is already bound.
fn is_index_buffer_set(
&self,
buffer: BufferId,
offset: u64,
index_format: IndexFormat,
) -> bool {
self.index_buffer == Some((buffer, offset, index_format))
fn is_index_buffer_set(&self, buffer: &BufferSlice, index_format: IndexFormat) -> bool {
self.index_buffer == Some((self.buffer_slice_key(buffer), index_format))
}

/// Resets tracking state
Expand Down Expand Up @@ -256,29 +253,21 @@ impl<'a> TrackedRenderPass<'a> {
///
/// Subsequent calls to [`TrackedRenderPass::draw_indexed`] will use the buffer referenced by
/// `buffer_slice` as the source index buffer.
pub fn set_index_buffer(
&mut self,
buffer_slice: BufferSlice<'a>,
offset: u64,
index_format: IndexFormat,
) {
if self
.state
.is_index_buffer_set(buffer_slice.id(), offset, index_format)
{
#[cfg(feature = "detailed_trace")]
trace!(
"set index buffer (already set): {:?} ({})",
buffer_slice.id(),
offset
);
pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat) {
let already_set = self.state.is_index_buffer_set(&buffer_slice, index_format);
#[cfg(feature = "detailed_trace")]
trace!(
"set index buffer{}: {:?} (offset = {}, size = {})",
if already_set { " (already set)" } else { "" },
buffer_slice.id(),
buffer_slice.offset(),
buffer_slice.size(),
);
if already_set {
return;
}
#[cfg(feature = "detailed_trace")]
trace!("set index buffer: {:?} ({})", buffer_slice.id(), offset);
self.pass.set_index_buffer(*buffer_slice, index_format);
self.state
.set_index_buffer(buffer_slice.id(), offset, index_format);
self.state.set_index_buffer(&buffer_slice, index_format);
}

/// Draws primitives from the active vertex buffer(s).
Expand Down
27 changes: 1 addition & 26 deletions crates/bevy_render/src/render_resource/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::define_atomic_id;
use crate::WgpuWrapper;
use core::ops::{Bound, Deref, RangeBounds};
use core::ops::{Deref, RangeBounds};

define_atomic_id!(BufferId);

Expand All @@ -17,21 +17,8 @@ impl Buffer {
}

pub fn slice(&self, bounds: impl RangeBounds<wgpu::BufferAddress>) -> BufferSlice<'_> {
// need to compute and store this manually because wgpu doesn't export offset and size on wgpu::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) => bound + 1,
Bound::Excluded(&bound) => bound,
Bound::Unbounded => self.value.size(),
} - offset;
BufferSlice {
id: self.id,
offset,
size,
value: self.value.slice(bounds),
}
}
Expand Down Expand Up @@ -63,26 +50,14 @@ impl Deref for Buffer {
#[derive(Clone, Debug)]
pub struct BufferSlice<'a> {
id: BufferId,
offset: wgpu::BufferAddress,
value: wgpu::BufferSlice<'a>,
size: wgpu::BufferAddress,
}

impl<'a> BufferSlice<'a> {
#[inline]
pub fn id(&self) -> BufferId {
self.id
}

#[inline]
pub fn offset(&self) -> wgpu::BufferAddress {
self.offset
}

#[inline]
pub fn size(&self) -> wgpu::BufferAddress {
self.size
}
}

impl<'a> Deref for BufferSlice<'a> {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/mesh2d/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMesh2d {
return RenderCommandResult::Skip;
};

pass.set_index_buffer(index_buffer_slice.buffer.slice(..), 0, *index_format);
pass.set_index_buffer(index_buffer_slice.buffer.slice(..), *index_format);

pass.draw_indexed(
index_buffer_slice.range.start..(index_buffer_slice.range.start + count),
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,6 @@ impl<P: PhaseItem> RenderCommand<P> for DrawSpriteBatch {

pass.set_index_buffer(
sprite_meta.sprite_index_buffer.buffer().unwrap().slice(..),
0,
IndexFormat::Uint32,
);
pass.set_vertex_buffer(
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui_render/src/box_shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawBoxShadow {
// Store the vertices
pass.set_vertex_buffer(0, vertices.slice(..));
// Define how to "connect" the vertices
pass.set_index_buffer(indices.slice(..), 0, IndexFormat::Uint32);
pass.set_index_buffer(indices.slice(..), IndexFormat::Uint32);
// Draw the vertices
pass.draw_indexed(batch.range.clone(), 0, 0..1);
RenderCommandResult::Success
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui_render/src/gradient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawGradient {
// Store the vertices
pass.set_vertex_buffer(0, vertices.slice(..));
// Define how to "connect" the vertices
pass.set_index_buffer(indices.slice(..), 0, IndexFormat::Uint32);
pass.set_index_buffer(indices.slice(..), IndexFormat::Uint32);
// Draw the vertices
pass.draw_indexed(batch.range.clone(), 0, 0..1);
RenderCommandResult::Success
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_ui_render/src/render_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ impl<P: PhaseItem> RenderCommand<P> for DrawUiNode {
// Define how to "connect" the vertices
pass.set_index_buffer(
indices.slice(..),
0,
bevy_render::render_resource::IndexFormat::Uint32,
);
// Draw the vertices
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawSlicer {
// Store the vertices
pass.set_vertex_buffer(0, vertices.slice(..));
// Define how to "connect" the vertices
pass.set_index_buffer(indices.slice(..), 0, IndexFormat::Uint32);
pass.set_index_buffer(indices.slice(..), IndexFormat::Uint32);
// Draw the vertices
pass.draw_indexed(batch.range.clone(), 0, 0..1);
RenderCommandResult::Success
Expand Down
1 change: 0 additions & 1 deletion examples/shader_advanced/custom_phase_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ where
.buffer()
.unwrap()
.slice(..),
0,
IndexFormat::Uint32,
);

Expand Down
2 changes: 1 addition & 1 deletion examples/shader_advanced/custom_shader_instancing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshInstanced {
return RenderCommandResult::Skip;
};

pass.set_index_buffer(index_buffer_slice.buffer.slice(..), 0, *index_format);
pass.set_index_buffer(index_buffer_slice.buffer.slice(..), *index_format);
pass.draw_indexed(
index_buffer_slice.range.start..(index_buffer_slice.range.start + count),
vertex_buffer_slice.range.start as i32,
Expand Down
18 changes: 18 additions & 0 deletions release-content/migration-guides/set_index_buffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: `TrackedRenderPass::set_index_buffer` no longer takes buffer offset
pull_requests: [20468]
---

`TrackedRenderPass::set_index_buffer` no longer takes a separate buffer offset argument, which wasn't actually forwarded to wgpu. You have already needed to pass a `BufferSlice` that is sliced to the desired offset/size.

Before:

```rust
pass.set_index_buffer(indices.slice(1..), 1, IndexFormat::Uint32);
```

After:

```rust
pass.set_index_buffer(indices.slice(1..), IndexFormat::Uint32);
```