pvr: add multiplanar format support

Reviewed-by: Simon Perretta <simon.perretta@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39231>
This commit is contained in:
Ella Stanforth 2026-01-27 14:11:50 +00:00 committed by Marge Bot
parent 7be87ca82a
commit fa6704a523
6 changed files with 261 additions and 78 deletions

View file

@ -685,6 +685,7 @@ static VkResult pvr_setup_texture_state_words(
uint32_t view_index)
{
const struct pvr_image *image = vk_to_pvr_image(image_view->vk.image);
const struct pvr_image_plane *plane = pvr_single_plane_const(image);
struct pvr_texture_state_info info = {
.format = image_view->vk.format,
.mem_layout = image->memlayout,
@ -695,8 +696,8 @@ static VkResult pvr_setup_texture_state_words(
.extent = image_view->vk.extent,
.mip_levels = 1,
.sample_count = image_view->vk.image->samples,
.stride = image->physical_extent.width,
.offset = image->layer_size * view_index,
.stride = plane->physical_extent.width,
.offset = plane->layer_size * view_index,
.addr = image->dev_addr,
};
const uint8_t *const swizzle = pvr_get_format_swizzle(info.format);
@ -1106,7 +1107,8 @@ static void pvr_setup_pbe_state(
uint32_t view_index)
{
const struct pvr_image *image = pvr_image_view_get_image(iview);
uint32_t level_pitch = image->mip_levels[iview->vk.base_mip_level].pitch;
const struct pvr_image_plane *plane = pvr_single_plane_const(image);
uint32_t level_pitch = plane->mip_levels[iview->vk.base_mip_level].pitch;
struct pvr_pbe_surf_params surface_params;
struct pvr_pbe_render_params render_params;
@ -1147,13 +1149,13 @@ static void pvr_setup_pbe_state(
*/
surface_params.addr = PVR_DEV_ADDR_OFFSET(
image->vma->dev_addr,
image->layer_size * view_index +
image->mip_levels[iview->vk.base_mip_level].offset);
plane->layer_size * view_index +
plane->mip_levels[iview->vk.base_mip_level].offset);
if (!iview->vk.storage.z_slice_offset) {
surface_params.addr =
PVR_DEV_ADDR_OFFSET(surface_params.addr,
iview->vk.base_array_layer * image->layer_size);
iview->vk.base_array_layer * plane->layer_size);
}
surface_params.mem_layout = image->memlayout;
@ -1288,13 +1290,15 @@ static bool pvr_sub_cmd_gfx_requires_ds_subtile_alignment(
{
const struct pvr_image *const ds_image =
pvr_image_view_get_image(job->ds.iview);
const struct pvr_image_plane *const ds_plane =
pvr_single_plane_const(ds_image);
uint32_t zls_tile_size_x;
uint32_t zls_tile_size_y;
rogue_get_zls_tile_size_xy(dev_info, &zls_tile_size_x, &zls_tile_size_y);
if (ds_image->physical_extent.width >= zls_tile_size_x &&
ds_image->physical_extent.height >= zls_tile_size_y) {
if (ds_plane->physical_extent.width >= zls_tile_size_x &&
ds_plane->physical_extent.height >= zls_tile_size_y) {
return false;
}
@ -1325,6 +1329,8 @@ pvr_sub_cmd_gfx_align_ds_subtiles(struct pvr_cmd_buffer *const cmd_buffer,
container_of(gfx_sub_cmd, struct pvr_sub_cmd, gfx);
struct pvr_ds_attachment *const ds = &gfx_sub_cmd->job.ds;
const struct pvr_image *const ds_image = pvr_image_view_get_image(ds->iview);
const struct pvr_image_plane *const ds_plane =
pvr_single_plane_const(ds_image);
const VkFormat copy_format = pvr_get_raw_copy_format(ds_image->vk.format);
struct pvr_suballoc_bo *buffer;
@ -1354,9 +1360,9 @@ pvr_sub_cmd_gfx_align_ds_subtiles(struct pvr_cmd_buffer *const cmd_buffer,
&scale.height);
rounded_size = (VkExtent2D){
.width = ALIGN_POT(ds_image->physical_extent.width, zls_tile_size.width),
.width = ALIGN_POT(ds_plane->physical_extent.width, zls_tile_size.width),
.height =
ALIGN_POT(ds_image->physical_extent.height, zls_tile_size.height),
ALIGN_POT(ds_plane->physical_extent.height, zls_tile_size.height),
};
buffer_layer_size = vk_format_get_blocksize(ds_image->vk.format) *
@ -1767,13 +1773,14 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
struct pvr_image_view *ds_iview =
render_pass_info->attachments[hw_render->ds_attach_idx];
const struct pvr_image *ds_image = pvr_image_view_get_image(ds_iview);
const struct pvr_image_plane *ds_plane = pvr_single_plane_const(ds_image);
job->has_depth_attachment = vk_format_has_depth(ds_image->vk.format);
job->has_stencil_attachment = vk_format_has_stencil(ds_image->vk.format);
if (job->has_depth_attachment || job->has_stencil_attachment) {
uint32_t level_pitch =
ds_image->mip_levels[ds_iview->vk.base_mip_level].pitch;
ds_plane->mip_levels[ds_iview->vk.base_mip_level].pitch;
const bool render_area_is_tile_aligned =
pvr_is_render_area_tile_aligned(cmd_buffer, ds_iview);
bool store_was_optimised_out = false;
@ -1787,12 +1794,12 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
pvr_stride_from_pitch(level_pitch, ds_iview->vk.format);
job->ds.height = ds_iview->vk.extent.height;
job->ds.physical_extent = (VkExtent2D){
.width = u_minify(ds_image->physical_extent.width,
.width = u_minify(ds_plane->physical_extent.width,
ds_iview->vk.base_mip_level),
.height = u_minify(ds_image->physical_extent.height,
.height = u_minify(ds_plane->physical_extent.height,
ds_iview->vk.base_mip_level),
};
job->ds.layer_size = ds_image->layer_size;
job->ds.layer_size = ds_plane->layer_size;
job->ds_clear_value = default_ds_clear_value;

View file

@ -19,6 +19,7 @@
#include "pvr_tex_state.h"
static void pvr_adjust_non_compressed_view(const struct pvr_image *image,
const struct pvr_image_plane *plane,
struct pvr_texture_state_info *info)
{
const uint32_t base_level = info->base_level;
@ -37,7 +38,7 @@ static void pvr_adjust_non_compressed_view(const struct pvr_image *image,
info->extent.height = u_minify(info->extent.height, base_level);
info->extent.depth = u_minify(info->extent.depth, base_level);
info->extent = vk_image_extent_to_elements(&image->vk, info->extent);
info->offset += image->mip_levels[base_level].offset;
info->offset += plane->mip_levels[base_level].offset;
info->base_level = 0;
}
@ -62,6 +63,17 @@ VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
image = pvr_image_view_get_image(iview);
const struct pvr_image_plane *plane;
const struct vk_format_ycbcr_info *ycbcr_image =
vk_format_get_ycbcr_info(image->vk.format);
const struct vk_format_ycbcr_info *ycbcr_iview =
vk_format_get_ycbcr_info(iview->vk.format);
if (ycbcr_image && !ycbcr_iview) {
plane = pvr_plane_from_aspect_const(image, iview->vk.aspects);
} else {
plane = &image->planes[0];
}
if (image->vk.image_type == VK_IMAGE_TYPE_3D &&
(iview->vk.view_type == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
@ -77,9 +89,9 @@ VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
info.is_cube = (info.type == VK_IMAGE_VIEW_TYPE_CUBE ||
info.type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
info.array_size = iview->vk.layer_count;
info.offset = iview->vk.base_array_layer * image->layer_size;
info.offset = iview->vk.base_array_layer * plane->layer_size;
info.mipmaps_present = (image->vk.mip_levels > 1) ? true : false;
info.stride = image->physical_extent.width;
info.stride = plane->physical_extent.width;
info.tex_state_type = PVR_TEXTURE_STATE_SAMPLE;
info.mem_layout = image->memlayout;
info.flags = 0;
@ -87,14 +99,14 @@ VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
info.addr = image->dev_addr;
info.format = pCreateInfo->format;
info.layer_size = image->layer_size;
info.layer_size = plane->layer_size;
if (image->vk.create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) {
info.offset = 0;
info.z_slice = iview->vk.base_array_layer;
}
pvr_adjust_non_compressed_view(image, &info);
pvr_adjust_non_compressed_view(image, plane, &info);
vk_component_mapping_to_pipe_swizzle(iview->vk.swizzle, input_swizzle);
@ -155,7 +167,7 @@ VkResult PVR_PER_ARCH(CreateImageView)(VkDevice _device,
info.mip_levels = 1;
info.mipmaps_present = false;
info.stride = u_minify(image->physical_extent.width, info.base_level);
info.stride = u_minify(plane->physical_extent.width, info.base_level);
info.base_level = 0;
info.tex_state_type = PVR_TEXTURE_STATE_ATTACHMENT;

View file

@ -1037,7 +1037,7 @@ void pvr_GetImageMemoryRequirements2(VkDevice _device,
*/
pMemoryRequirements->memoryRequirements.alignment = image->alignment;
pMemoryRequirements->memoryRequirements.size =
align64(image->size, image->alignment);
align64(image->total_size, image->alignment);
pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types;
vk_foreach_struct (ext, pMemoryRequirements->pNext) {

View file

@ -64,60 +64,88 @@ static void pvr_image_init_memlayout(struct pvr_image *image)
}
}
static void pvr_image_init_physical_extent(struct pvr_image *image,
unsigned pbe_stride_align)
static void pvr_image_plane_init_physical_extent(
struct pvr_image *image,
unsigned pbe_stride_align,
const struct vk_format_ycbcr_info *ycbcr_info,
uint8_t i)
{
assert(image->memlayout != PVR_MEMLAYOUT_UNDEFINED);
struct pvr_image_plane *plane = &image->planes[i];
/* clang-format off */
if (image->vk.mip_levels > 1 ||
image->memlayout == PVR_MEMLAYOUT_TWIDDLED ||
image->memlayout == PVR_MEMLAYOUT_3DTWIDDLED) {
/* clang-format on */
image->physical_extent.width =
plane->physical_extent.width =
util_next_power_of_two(image->vk.extent.width);
image->physical_extent.height =
plane->physical_extent.height =
util_next_power_of_two(image->vk.extent.height);
image->physical_extent.depth =
plane->physical_extent.depth =
util_next_power_of_two(image->vk.extent.depth);
} else {
assert(image->memlayout == PVR_MEMLAYOUT_LINEAR);
image->physical_extent = image->vk.extent;
plane->physical_extent = image->vk.extent;
/* If the image is being rendered to (written by the PBE) make sure the
* width is aligned correctly.
*/
if (image->vk.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
image->physical_extent.width =
align(image->physical_extent.width, pbe_stride_align);
plane->physical_extent.width =
align(plane->physical_extent.width, pbe_stride_align);
}
}
if (ycbcr_info) {
plane->physical_extent.width /=
ycbcr_info->planes[i].denominator_scales[0];
plane->physical_extent.height /=
ycbcr_info->planes[i].denominator_scales[1];
}
}
static void pvr_image_setup_mip_levels(struct pvr_image *image)
static void pvr_image_init_physical_extent(struct pvr_image *image,
unsigned pbe_stride_align)
{
assert(image->memlayout != PVR_MEMLAYOUT_UNDEFINED);
const struct vk_format_ycbcr_info *ycbcr_info =
vk_format_get_ycbcr_info(image->vk.format);
for (uint8_t plane = 0; plane < image->plane_count; plane++) {
pvr_image_plane_init_physical_extent(image,
pbe_stride_align,
ycbcr_info,
plane);
}
}
static void pvr_image_plane_setup_mip_levels(struct pvr_image *image, uint8_t i)
{
struct pvr_image_plane *plane = &image->planes[i];
VkFormat plane_format = vk_format_get_plane_format(image->vk.format, i);
const uint32_t extent_alignment =
image->vk.image_type == VK_IMAGE_TYPE_3D ? 4 : 1;
const unsigned int cpp = vk_format_get_blocksize(image->vk.format);
const unsigned int cpp = vk_format_get_blocksize(plane_format);
VkExtent3D extent =
vk_image_extent_to_elements(&image->vk, image->physical_extent);
vk_image_extent_to_elements(&image->vk, plane->physical_extent);
assert(image->vk.mip_levels <= ARRAY_SIZE(image->mip_levels));
assert(image->vk.mip_levels <= ARRAY_SIZE(plane->mip_levels));
image->layer_size = 0;
plane->layer_size = 0;
for (uint32_t i = 0; i < image->vk.mip_levels; i++) {
struct pvr_mip_level *mip_level = &image->mip_levels[i];
struct pvr_mip_level *mip_level = &plane->mip_levels[i];
mip_level->pitch = cpp * align(extent.width, extent_alignment);
mip_level->height_pitch = align(extent.height, extent_alignment);
mip_level->size = image->vk.samples * mip_level->pitch *
mip_level->height_pitch *
align(extent.depth, extent_alignment);
mip_level->offset = image->layer_size;
mip_level->offset = plane->layer_size;
image->layer_size += mip_level->size;
plane->layer_size += mip_level->size;
extent.height = u_minify(extent.height, 1);
extent.width = u_minify(extent.width, 1);
@ -132,7 +160,7 @@ static void pvr_image_setup_mip_levels(struct pvr_image *image)
const uint32_t height_pitch = align(extent.height, extent_alignment);
const uint32_t pitch = cpp * align(extent.width, extent_alignment);
image->layer_size += image->vk.samples * pitch * height_pitch *
plane->layer_size += image->vk.samples * pitch * height_pitch *
align(extent.depth, extent_alignment);
extent.height = u_minify(extent.height, 1);
@ -147,9 +175,23 @@ static void pvr_image_setup_mip_levels(struct pvr_image *image)
* requirement comes from.
*/
if (image->vk.array_layers > 1)
image->layer_size = align64(image->layer_size, image->alignment);
plane->layer_size = align64(plane->layer_size, image->alignment);
image->size = image->layer_size * image->vk.array_layers;
plane->size = plane->layer_size * image->vk.array_layers;
}
static void pvr_image_setup_mip_levels(struct pvr_image *image)
{
VkDeviceSize offset = 0;
for (uint8_t plane = 0; plane < image->plane_count; plane++) {
pvr_image_plane_setup_mip_levels(image, plane);
offset = align(offset, image->alignment);
image->planes[plane].offset = offset;
offset += image->planes[plane].size;
}
image->total_size = offset;
}
static unsigned get_pbe_stride_align(const struct pvr_device_info *dev_info);
@ -178,6 +220,8 @@ VkResult pvr_CreateImage(VkDevice _device,
*/
image->alignment = 4096U;
image->plane_count = vk_format_get_plane_count(image->vk.format);
unsigned pbe_stride_align = get_pbe_stride_align(&device->pdevice->dev_info);
/* Initialize the image using the saved information from pCreateInfo */
@ -270,7 +314,7 @@ VkResult pvr_BindImageMemory2(VkDevice _device,
result = pvr_bind_memory(device,
mem,
offset,
image->size,
image->total_size,
image->alignment,
&image->vma,
&image->dev_addr);
@ -292,17 +336,20 @@ void pvr_get_image_subresource_layout(const struct pvr_image *image,
const VkImageSubresource *subresource,
VkSubresourceLayout *layout)
{
const struct pvr_image_plane *plane =
pvr_plane_from_aspect_const(image, subresource->aspectMask);
const struct pvr_mip_level *mip_level =
&image->mip_levels[subresource->mipLevel];
&plane->mip_levels[subresource->mipLevel];
pvr_assert(subresource->mipLevel < image->vk.mip_levels);
pvr_assert(subresource->arrayLayer < image->vk.array_layers);
layout->offset =
subresource->arrayLayer * image->layer_size + mip_level->offset;
layout->offset = plane->offset +
subresource->arrayLayer * plane->layer_size +
mip_level->offset;
layout->rowPitch = mip_level->pitch;
layout->depthPitch = mip_level->pitch * mip_level->height_pitch;
layout->arrayPitch = image->layer_size;
layout->arrayPitch = plane->layer_size;
layout->size = mip_level->size;
}

View file

@ -21,6 +21,8 @@
#include "pvr_common.h"
#include "pvr_types.h"
#define PVR_MAX_PLANE_COUNT 3
struct pvr_mip_level {
/* Offset of the mip level in bytes */
uint32_t offset;
@ -35,6 +37,17 @@ struct pvr_mip_level {
uint32_t height_pitch;
};
struct pvr_image_plane {
/* Derived and other state */
VkExtent3D physical_extent;
VkDeviceSize layer_size;
VkDeviceSize size;
VkDeviceSize offset;
struct pvr_mip_level mip_levels[14];
};
struct pvr_image {
struct vk_image vk;
@ -44,17 +57,78 @@ struct pvr_image {
/* Device address the image is mapped to in device virtual address space */
pvr_dev_addr_t dev_addr;
/* Derived and other state */
VkExtent3D physical_extent;
enum pvr_memlayout memlayout;
VkDeviceSize layer_size;
VkDeviceSize size;
VkDeviceSize alignment;
VkDeviceSize total_size;
struct pvr_mip_level mip_levels[14];
uint8_t plane_count;
struct pvr_image_plane planes[PVR_MAX_PLANE_COUNT];
};
/* Gets the first plane and asserts we only have one plane. For use in areas
* where we never want to deal with multiplanar images.
*/
static inline struct pvr_image_plane *pvr_single_plane(struct pvr_image *image)
{
assert(image->plane_count == 1);
return &image->planes[0];
}
static inline const struct pvr_image_plane *
pvr_single_plane_const(const struct pvr_image *image)
{
assert(image->plane_count == 1);
return &image->planes[0];
}
static inline struct pvr_image_plane *
pvr_plane_from_aspect(struct pvr_image *image, VkImageAspectFlags aspect)
{
switch (aspect) {
case VK_IMAGE_ASPECT_COLOR_BIT:
case VK_IMAGE_ASPECT_DEPTH_BIT:
case VK_IMAGE_ASPECT_STENCIL_BIT:
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
return pvr_single_plane(image);
case VK_IMAGE_ASPECT_PLANE_0_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT:
return &image->planes[0];
case VK_IMAGE_ASPECT_PLANE_1_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
return &image->planes[1];
case VK_IMAGE_ASPECT_PLANE_2_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
return &image->planes[2];
default:
UNREACHABLE("invalid image aspect");
}
}
static inline const struct pvr_image_plane *
pvr_plane_from_aspect_const(const struct pvr_image *image,
VkImageAspectFlags aspect)
{
switch (aspect) {
case VK_IMAGE_ASPECT_COLOR_BIT:
case VK_IMAGE_ASPECT_DEPTH_BIT:
case VK_IMAGE_ASPECT_STENCIL_BIT:
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
return pvr_single_plane_const(image);
case VK_IMAGE_ASPECT_PLANE_0_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT:
return &image->planes[0];
case VK_IMAGE_ASPECT_PLANE_1_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
return &image->planes[1];
case VK_IMAGE_ASPECT_PLANE_2_BIT:
case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
return &image->planes[2];
default:
UNREACHABLE("invalid image aspect");
}
}
struct pvr_image_view {
struct vk_image_view vk;

View file

@ -166,9 +166,33 @@ static void pvr_setup_transfer_surface(struct pvr_device *device,
VkFormat format,
VkImageAspectFlags aspect_mask)
{
const uint32_t height = MAX2(image->vk.extent.height >> mip_level, 1U);
const uint32_t width = MAX2(image->vk.extent.width >> mip_level, 1U);
enum pipe_format image_pformat = vk_format_to_pipe_format(image->vk.format);
uint8_t plane;
switch (aspect_mask) {
case VK_IMAGE_ASPECT_PLANE_1_BIT:
plane = 1;
break;
case VK_IMAGE_ASPECT_PLANE_2_BIT:
plane = 2;
break;
default:
plane = 0;
break;
};
const uint32_t height =
MAX2(vk_format_get_plane_height(image->vk.format,
plane,
image->vk.extent.height) >>
mip_level,
1U);
const uint32_t width =
MAX2(vk_format_get_plane_width(image->vk.format,
plane,
image->vk.extent.width) >>
mip_level,
1U);
enum pipe_format image_pformat = vk_format_to_pipe_format(
vk_format_get_plane_aspect_format(image->vk.format, aspect_mask));
enum pipe_format pformat = vk_format_to_pipe_format(format);
const VkImageSubresource sub_resource = {
.aspectMask = aspect_mask,
@ -376,7 +400,9 @@ void pvr_rogue_CmdBlitImage2(VkCommandBuffer commandBuffer,
&region->srcOffsets[0],
&src_extent,
initial_depth_offset,
src->vk.format,
vk_format_get_plane_aspect_format(
src->vk.format,
region->srcSubresource.aspectMask),
region->srcSubresource.aspectMask);
pvr_setup_transfer_surface(device,
@ -388,7 +414,9 @@ void pvr_rogue_CmdBlitImage2(VkCommandBuffer commandBuffer,
&dst_offset,
&dst_extent,
min_dst_z,
dst->vk.format,
vk_format_get_plane_aspect_format(
dst->vk.format,
region->dstSubresource.aspectMask),
region->dstSubresource.aspectMask);
for (uint32_t dst_z = min_dst_z; dst_z < max_dst_z; dst_z++) {
@ -504,8 +532,12 @@ pvr_copy_or_resolve_image_region(struct pvr_cmd_buffer *cmd_buffer,
const VkImageCopy2 *region,
struct pvr_transfer_cmd *ds_transfer_cmd)
{
enum pipe_format src_pformat = vk_format_to_pipe_format(src->vk.format);
enum pipe_format dst_pformat = vk_format_to_pipe_format(dst->vk.format);
enum pipe_format src_pformat = vk_format_to_pipe_format(
vk_format_get_plane_aspect_format(src->vk.format,
region->srcSubresource.aspectMask));
enum pipe_format dst_pformat = vk_format_to_pipe_format(
vk_format_get_plane_aspect_format(dst->vk.format,
region->dstSubresource.aspectMask));
bool src_block_compressed = util_format_is_compressed(src_pformat);
bool dst_block_compressed = util_format_is_compressed(dst_pformat);
VkExtent3D src_extent;
@ -566,12 +598,16 @@ pvr_copy_or_resolve_image_region(struct pvr_cmd_buffer *cmd_buffer,
if (src->vk.samples > dst->vk.samples) {
/* Resolve op needs to know the actual format. */
dst_format = dst->vk.format;
dst_format =
vk_format_get_plane_aspect_format(dst->vk.format,
region->dstSubresource.aspectMask);
} else {
/* We don't care what format dst is as it's guaranteed to be size
* compatible with src.
*/
dst_format = pvr_get_raw_copy_format(src->vk.format);
dst_format = pvr_get_raw_copy_format(
vk_format_get_plane_aspect_format(src->vk.format,
region->srcSubresource.aspectMask));
}
src_format = dst_format;
@ -872,7 +908,9 @@ pvr_copy_buffer_to_image_region_format(struct pvr_cmd_buffer *const cmd_buffer,
buffer_dev_addr,
buffer_offset,
src_format,
image->vk.format,
vk_format_get_plane_aspect_format(
image->vk.format,
region->imageSubresource.aspectMask),
region->imageExtent.width,
region->imageExtent.height,
row_length_in_texels);
@ -938,7 +976,8 @@ pvr_copy_buffer_to_image_region(struct pvr_cmd_buffer *const cmd_buffer,
dst_format = image->vk.format;
} else {
src_format = pvr_get_raw_copy_format(image->vk.format);
src_format = pvr_get_raw_copy_format(
vk_format_get_plane_aspect_format(image->vk.format, aspect_mask));
dst_format = src_format;
}
@ -980,7 +1019,9 @@ pvr_copy_image_to_buffer_region_format(struct pvr_cmd_buffer *const cmd_buffer,
const VkFormat src_format,
const VkFormat dst_format)
{
enum pipe_format pformat = vk_format_to_pipe_format(image->vk.format);
enum pipe_format pformat = vk_format_to_pipe_format(
vk_format_get_plane_aspect_format(image->vk.format,
region->imageSubresource.aspectMask));
struct pvr_transfer_cmd_surface dst_surface = { 0 };
VkImageSubresource sub_resource;
uint32_t buffer_image_height;
@ -1010,15 +1051,17 @@ pvr_copy_image_to_buffer_region_format(struct pvr_cmd_buffer *const cmd_buffer,
max_depth_slice = region->imageExtent.depth + region->imageOffset.z;
pvr_setup_buffer_surface(&dst_surface,
&dst_rect,
buffer_dev_addr,
region->bufferOffset,
dst_format,
image->vk.format,
buffer_row_length,
buffer_image_height,
buffer_row_length);
pvr_setup_buffer_surface(
&dst_surface,
&dst_rect,
buffer_dev_addr,
region->bufferOffset,
dst_format,
vk_format_get_plane_aspect_format(image->vk.format,
region->imageSubresource.aspectMask),
buffer_row_length,
buffer_image_height,
buffer_row_length);
dst_rect.extent.width = region->imageExtent.width;
dst_rect.extent.height = region->imageExtent.height;
@ -1110,7 +1153,8 @@ pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer *const cmd_buffer,
{
const VkImageAspectFlags aspect_mask = region->imageSubresource.aspectMask;
VkFormat src_format = pvr_get_copy_format(image->vk.format);
VkFormat src_format = pvr_get_copy_format(
vk_format_get_plane_aspect_format(image->vk.format, aspect_mask));
VkFormat dst_format;
/* From the Vulkan spec:
@ -1119,10 +1163,10 @@ pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer *const cmd_buffer,
*/
assert(image->vk.samples == VK_SAMPLE_COUNT_1_BIT);
/* Color and depth aspect copies can nearly all be done using an appropriate
/* All but stencil aspect copies can nearly all be done using an appropriate
* raw format.
*/
if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) {
if (aspect_mask & (~VK_IMAGE_ASPECT_STENCIL_BIT)) {
if (src_format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
dst_format = VK_FORMAT_D32_SFLOAT;
} else {
@ -1138,8 +1182,7 @@ pvr_copy_image_to_buffer_region(struct pvr_cmd_buffer *const cmd_buffer,
*/
dst_format = VK_FORMAT_S8_UINT;
} else {
/* YUV Planes require specific formats. */
dst_format = src_format;
UNREACHABLE("");
}
return pvr_copy_image_to_buffer_region_format(cmd_buffer,