mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-14 06:30:26 +01:00
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:
parent
7be87ca82a
commit
fa6704a523
6 changed files with 261 additions and 78 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
|||
®ion->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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue