mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-04 00:08:16 +02:00
v3dv: relax buffer padding in TFU buffer<->image copy
Adjust eligibility check on imageExtent vs slice dimensions rather than on the buffer addressing dimensions. The TFU codepath here always writes/reads the full slice from its origin, so the required invariant is 'imageExtent == slice'; bufferRowLength and bufferImageHeight may be larger than imageExtent (the spec permits this for non-zero values), in which case the TFU reads/writes at the buffer's row/layer stride but only touches slice->width pixels per row and slice->height rows per layer, leaving the trailing padding untouched. The previous combined check (width == slice->width && height == slice->height applied to the buffer dimensions) would reject any caller that set bufferRowLength or bufferImageHeight larger than the image (this is common for buffers shared across mip levels or for alignment requirements like Dawn aligning bufferRowLength to 2 for 1-pixel-wide textures), forcing those copies through the slower TLB / blit / compute paths. For compressed formats, keep the strict equality check since block-level stride semantics are more complex. Assisted-by: Claude Opus 4.7 Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41725>
This commit is contained in:
parent
99bce54daa
commit
2a62490fa7
1 changed files with 21 additions and 5 deletions
|
|
@ -1981,16 +1981,30 @@ copy_buffer_image_tfu(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
const uint32_t mip_level = region->imageSubresource.mipLevel;
|
||||
const struct v3d_resource_slice *slice = &image->planes[plane].slices[mip_level];
|
||||
|
||||
if (width != slice->width || height != slice->height)
|
||||
return false;
|
||||
|
||||
/* Handle region semantics for compressed images */
|
||||
const uint32_t block_w =
|
||||
vk_format_get_blockwidth(image->planes[plane].vk_format);
|
||||
const uint32_t block_h =
|
||||
vk_format_get_blockheight(image->planes[plane].vk_format);
|
||||
|
||||
/* The TFU writes/reads the full slice from its origin, so the copy
|
||||
* region must span it. The buffer side may have trailing row/height
|
||||
* padding (bufferRowLength, bufferImageHeight) that the TFU never
|
||||
* touches. For compressed formats, require tight packing since
|
||||
* block-level stride semantics are more complex.
|
||||
*/
|
||||
if (region->imageExtent.width != slice->width ||
|
||||
region->imageExtent.height != slice->height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool is_compressed = block_w > 1 || block_h > 1;
|
||||
if (is_compressed && (width != slice->width || height != slice->height))
|
||||
return false;
|
||||
|
||||
width = DIV_ROUND_UP(width, block_w);
|
||||
height = DIV_ROUND_UP(height, block_h);
|
||||
const uint32_t tfu_height = is_compressed ? height : slice->height;
|
||||
|
||||
/* Format must be supported for texturing via the TFU. Since we are just
|
||||
* copying raw data and not converting between pixel formats, we can ignore
|
||||
|
|
@ -2032,6 +2046,8 @@ copy_buffer_image_tfu(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
buffer->mem_offset + region->bufferOffset +
|
||||
height * buffer_stride * i;
|
||||
|
||||
const uint32_t tfu_width = is_compressed ? width : slice->width;
|
||||
|
||||
if (to_buffer) {
|
||||
v3d_X((&cmd_buffer->device->devinfo), meta_emit_tfu_job)(
|
||||
cmd_buffer,
|
||||
|
|
@ -2039,7 +2055,7 @@ copy_buffer_image_tfu(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
V3D_TILING_RASTER, width, 1,
|
||||
image_bo->handle, image_offset,
|
||||
slice->tiling, tfu_slice_stride_arg(slice), cpp,
|
||||
width, height, format_plane);
|
||||
tfu_width, tfu_height, format_plane);
|
||||
} else {
|
||||
v3d_X((&cmd_buffer->device->devinfo), meta_emit_tfu_job)(
|
||||
cmd_buffer,
|
||||
|
|
@ -2047,7 +2063,7 @@ copy_buffer_image_tfu(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
slice->tiling, tfu_slice_stride_arg(slice), cpp,
|
||||
buffer_bo->handle, buffer_offset,
|
||||
V3D_TILING_RASTER, width, 1,
|
||||
width, height, format_plane);
|
||||
tfu_width, tfu_height, format_plane);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue