@@ -235,96 +235,87 @@ pub(crate) fn validate_linear_texture_data(
235
235
copy_size : & Extent3d ,
236
236
need_copy_aligned_rows : bool ,
237
237
) -> Result < ( BufferAddress , BufferAddress ) , TransferError > {
238
- // Convert all inputs to BufferAddress (u64) to avoid some of the overflow issues
239
- // Note: u64 is not always enough to prevent overflow, especially when multiplying
240
- // something with a potentially large depth value, so it is preferable to validate
241
- // the copy size before calling this function (for example via `validate_texture_copy_range`).
242
- let copy_width = copy_size. width as BufferAddress ;
243
- let copy_height = copy_size. height as BufferAddress ;
244
- let depth_or_array_layers = copy_size. depth_or_array_layers as BufferAddress ;
245
-
246
- let offset = layout. offset ;
247
-
248
- let block_size = format. block_copy_size ( Some ( aspect) ) . unwrap ( ) as BufferAddress ;
249
- let ( block_width, block_height) = format. block_dimensions ( ) ;
250
- let block_width = block_width as BufferAddress ;
251
- let block_height = block_height as BufferAddress ;
252
-
253
- if copy_width % block_width != 0 {
238
+ let wgt:: BufferTextureCopyInfo {
239
+ copy_width,
240
+ copy_height,
241
+ depth_or_array_layers,
242
+
243
+ offset,
244
+
245
+ block_size_bytes,
246
+ block_width_texels,
247
+ block_height_texels,
248
+
249
+ width_blocks : _,
250
+ height_blocks,
251
+
252
+ row_bytes_dense,
253
+ row_stride_bytes,
254
+
255
+ image_stride_rows : _,
256
+ image_stride_bytes,
257
+
258
+ image_rows_dense : _,
259
+ image_bytes_dense : _,
260
+
261
+ bytes_in_copy,
262
+ } = layout. get_buffer_texture_copy_info ( format, aspect, copy_size) ;
263
+
264
+ if copy_width % block_width_texels != 0 {
254
265
return Err ( TransferError :: UnalignedCopyWidth ) ;
255
266
}
256
- if copy_height % block_height != 0 {
267
+ if copy_height % block_height_texels != 0 {
257
268
return Err ( TransferError :: UnalignedCopyHeight ) ;
258
269
}
259
270
260
- let width_in_blocks = copy_width / block_width;
261
- let height_in_blocks = copy_height / block_height;
262
-
263
- let bytes_in_last_row = width_in_blocks * block_size;
264
-
265
- let bytes_per_row = if let Some ( bytes_per_row) = layout. bytes_per_row {
266
- let bytes_per_row = bytes_per_row as BufferAddress ;
267
- if bytes_per_row < bytes_in_last_row {
271
+ if let Some ( raw_bytes_per_row) = layout. bytes_per_row {
272
+ let raw_bytes_per_row = raw_bytes_per_row as BufferAddress ;
273
+ if raw_bytes_per_row < row_bytes_dense {
268
274
return Err ( TransferError :: InvalidBytesPerRow ) ;
269
275
}
270
- bytes_per_row
271
276
} else {
272
- if depth_or_array_layers > 1 || height_in_blocks > 1 {
277
+ if depth_or_array_layers > 1 || height_blocks > 1 {
273
278
return Err ( TransferError :: UnspecifiedBytesPerRow ) ;
274
279
}
275
- 0
276
- } ;
277
- let rows_per_image = if let Some ( rows_per_image ) = layout. rows_per_image {
278
- let rows_per_image = rows_per_image as BufferAddress ;
279
- if rows_per_image < height_in_blocks {
280
+ }
281
+
282
+ if let Some ( raw_rows_per_image ) = layout. rows_per_image {
283
+ let raw_rows_per_image = raw_rows_per_image as BufferAddress ;
284
+ if raw_rows_per_image < height_blocks {
280
285
return Err ( TransferError :: InvalidRowsPerImage ) ;
281
286
}
282
- rows_per_image
283
287
} else {
284
288
if depth_or_array_layers > 1 {
285
289
return Err ( TransferError :: UnspecifiedRowsPerImage ) ;
286
290
}
287
- 0
288
291
} ;
289
292
290
293
if need_copy_aligned_rows {
291
294
let bytes_per_row_alignment = wgt:: COPY_BYTES_PER_ROW_ALIGNMENT as BufferAddress ;
292
295
293
- let mut offset_alignment = block_size ;
296
+ let mut offset_alignment = block_size_bytes ;
294
297
if format. is_depth_stencil_format ( ) {
295
298
offset_alignment = 4
296
299
}
297
300
if offset % offset_alignment != 0 {
298
301
return Err ( TransferError :: UnalignedBufferOffset ( offset) ) ;
299
302
}
300
303
301
- if bytes_per_row % bytes_per_row_alignment != 0 {
304
+ if row_stride_bytes % bytes_per_row_alignment != 0 {
302
305
return Err ( TransferError :: UnalignedBytesPerRow ) ;
303
306
}
304
307
}
305
308
306
- let bytes_per_image = bytes_per_row * rows_per_image;
307
-
308
- let required_bytes_in_copy = if depth_or_array_layers == 0 {
309
- 0
310
- } else {
311
- let mut required_bytes_in_copy = bytes_per_image * ( depth_or_array_layers - 1 ) ;
312
- if height_in_blocks > 0 {
313
- required_bytes_in_copy += bytes_per_row * ( height_in_blocks - 1 ) + bytes_in_last_row;
314
- }
315
- required_bytes_in_copy
316
- } ;
317
-
318
- if offset + required_bytes_in_copy > buffer_size {
309
+ if offset + bytes_in_copy > buffer_size {
319
310
return Err ( TransferError :: BufferOverrun {
320
311
start_offset : offset,
321
- end_offset : offset + required_bytes_in_copy ,
312
+ end_offset : offset + bytes_in_copy ,
322
313
buffer_size,
323
314
side : buffer_side,
324
315
} ) ;
325
316
}
326
317
327
- Ok ( ( required_bytes_in_copy , bytes_per_image ) )
318
+ Ok ( ( bytes_in_copy , image_stride_bytes ) )
328
319
}
329
320
330
321
/// WebGPU's [validating texture copy range][vtcr] algorithm.
0 commit comments