@@ -602,6 +602,7 @@ fn set_pipeline(
602602 Ok ( ( ) )
603603}
604604
605+ // This function is duplicative of `render::set_index_buffer`.
605606fn set_index_buffer (
606607 state : & mut State ,
607608 buffer_guard : & crate :: storage:: Storage < Fallible < Buffer > > ,
@@ -620,21 +621,20 @@ fn set_index_buffer(
620621 buffer. same_device ( & state. device ) ?;
621622 buffer. check_usage ( wgt:: BufferUsages :: INDEX ) ?;
622623
623- let end = match size {
624- Some ( s) => offset + s. get ( ) ,
625- None => buffer. size ,
626- } ;
624+ let end = buffer. resolve_binding_size ( offset, size) ?;
625+
627626 state
628627 . buffer_memory_init_actions
629628 . extend ( buffer. initialization_status . read ( ) . create_action (
630629 & buffer,
631- offset..end,
630+ offset..end. get ( ) ,
632631 MemoryInitKind :: NeedsInitializedMemory ,
633632 ) ) ;
634- state. set_index_buffer ( buffer, index_format, offset..end) ;
633+ state. set_index_buffer ( buffer, index_format, offset..end. get ( ) ) ;
635634 Ok ( ( ) )
636635}
637636
637+ // This function is duplicative of `render::set_vertex_buffer`.
638638fn set_vertex_buffer (
639639 state : & mut State ,
640640 buffer_guard : & crate :: storage:: Storage < Fallible < Buffer > > ,
@@ -662,18 +662,16 @@ fn set_vertex_buffer(
662662 buffer. same_device ( & state. device ) ?;
663663 buffer. check_usage ( wgt:: BufferUsages :: VERTEX ) ?;
664664
665- let end = match size {
666- Some ( s) => offset + s. get ( ) ,
667- None => buffer. size ,
668- } ;
665+ let end = buffer. resolve_binding_size ( offset, size) ?;
666+
669667 state
670668 . buffer_memory_init_actions
671669 . extend ( buffer. initialization_status . read ( ) . create_action (
672670 & buffer,
673- offset..end,
671+ offset..end. get ( ) ,
674672 MemoryInitKind :: NeedsInitializedMemory ,
675673 ) ) ;
676- state. vertex [ slot as usize ] = Some ( VertexState :: new ( buffer, offset..end) ) ;
674+ state. vertex [ slot as usize ] = Some ( VertexState :: new ( buffer, offset..end. get ( ) ) ) ;
677675 Ok ( ( ) )
678676}
679677
@@ -965,10 +963,14 @@ impl RenderBundle {
965963 size,
966964 } => {
967965 let buffer = buffer. try_raw ( snatch_guard) ?;
968- let bb = hal:: BufferBinding {
969- buffer,
970- offset : * offset,
971- size : * size,
966+ let bb = unsafe {
967+ // SAFETY: The binding size was checked against the buffer size
968+ // in `set_index_buffer` and again in `IndexState::flush`.
969+ hal:: BufferBinding :: new_unchecked (
970+ buffer,
971+ * offset,
972+ size. expect ( "size was resolved in `RenderBundleEncoder::finish`" ) ,
973+ )
972974 } ;
973975 unsafe { raw. set_index_buffer ( bb, * index_format) } ;
974976 }
@@ -979,10 +981,14 @@ impl RenderBundle {
979981 size,
980982 } => {
981983 let buffer = buffer. try_raw ( snatch_guard) ?;
982- let bb = hal:: BufferBinding {
983- buffer,
984- offset : * offset,
985- size : * size,
984+ let bb = unsafe {
985+ // SAFETY: The binding size was checked against the buffer size
986+ // in `set_vertex_buffer` and again in `VertexState::flush`.
987+ hal:: BufferBinding :: new_unchecked (
988+ buffer,
989+ * offset,
990+ size. expect ( "size was resolved in `RenderBundleEncoder::finish`" ) ,
991+ )
986992 } ;
987993 unsafe { raw. set_vertex_buffer ( * slot, bb) } ;
988994 }
@@ -1131,6 +1137,9 @@ crate::impl_trackable!(RenderBundle);
11311137/// [`RenderBundleEncoder::finish`] records the currently set index buffer here,
11321138/// and calls [`State::flush_index`] before any indexed draw command to produce
11331139/// a `SetIndexBuffer` command if one is necessary.
1140+ ///
1141+ /// Binding ranges must be validated against the size of the buffer before
1142+ /// being stored in `IndexState`.
11341143#[ derive( Debug ) ]
11351144struct IndexState {
11361145 buffer : Arc < Buffer > ,
@@ -1152,13 +1161,24 @@ impl IndexState {
11521161 /// Generate a `SetIndexBuffer` command to prepare for an indexed draw
11531162 /// command, if needed.
11541163 fn flush ( & mut self ) -> Option < ArcRenderCommand > {
1164+ // This was all checked before, but let's check again just in case.
1165+ let binding_size = self
1166+ . range
1167+ . end
1168+ . checked_sub ( self . range . start )
1169+ . and_then ( wgt:: BufferSize :: new) ;
1170+ assert ! (
1171+ self . range. end <= self . buffer. size && binding_size. is_some( ) ,
1172+ "index buffer range must have non-zero size and be contained in buffer" ,
1173+ ) ;
1174+
11551175 if self . is_dirty {
11561176 self . is_dirty = false ;
11571177 Some ( ArcRenderCommand :: SetIndexBuffer {
11581178 buffer : self . buffer . clone ( ) ,
11591179 index_format : self . format ,
11601180 offset : self . range . start ,
1161- size : wgt :: BufferSize :: new ( self . range . end - self . range . start ) ,
1181+ size : binding_size ,
11621182 } )
11631183 } else {
11641184 None
@@ -1174,6 +1194,9 @@ impl IndexState {
11741194/// calls this type's [`flush`] method just before any draw command to
11751195/// produce a `SetVertexBuffer` commands if one is necessary.
11761196///
1197+ /// Binding ranges must be validated against the size of the buffer before
1198+ /// being stored in `VertexState`.
1199+ ///
11771200/// [`flush`]: IndexState::flush
11781201#[ derive( Debug ) ]
11791202struct VertexState {
@@ -1183,6 +1206,9 @@ struct VertexState {
11831206}
11841207
11851208impl VertexState {
1209+ /// Create a new `VertexState`.
1210+ ///
1211+ /// The `range` must be contained within `buffer`.
11861212 fn new ( buffer : Arc < Buffer > , range : Range < wgt:: BufferAddress > ) -> Self {
11871213 Self {
11881214 buffer,
@@ -1195,13 +1221,24 @@ impl VertexState {
11951221 ///
11961222 /// `slot` is the index of the vertex buffer slot that `self` tracks.
11971223 fn flush ( & mut self , slot : u32 ) -> Option < ArcRenderCommand > {
1224+ // This was all checked before, but let's check again just in case.
1225+ let binding_size = self
1226+ . range
1227+ . end
1228+ . checked_sub ( self . range . start )
1229+ . and_then ( wgt:: BufferSize :: new) ;
1230+ assert ! (
1231+ self . range. end <= self . buffer. size && binding_size. is_some( ) ,
1232+ "vertex buffer range must have non-zero size and be contained in buffer" ,
1233+ ) ;
1234+
11981235 if self . is_dirty {
11991236 self . is_dirty = false ;
12001237 Some ( ArcRenderCommand :: SetVertexBuffer {
12011238 slot,
12021239 buffer : self . buffer . clone ( ) ,
12031240 offset : self . range . start ,
1204- size : wgt :: BufferSize :: new ( self . range . end - self . range . start ) ,
1241+ size : binding_size ,
12051242 } )
12061243 } else {
12071244 None
0 commit comments