mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 07:30:09 +01:00
panvk: implement VK_EXT_host_image_copy for linear color images
Depth/stencil and tiled images require some additional complexity, so will be implemented in later commits. Signed-off-by: Olivia Lee <olivia.lee@collabora.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35910>
This commit is contained in:
parent
adb85dc307
commit
1cd61ee948
7 changed files with 452 additions and 13 deletions
|
|
@ -525,7 +525,7 @@ Vulkan 1.4 -- all DONE: anv, hk, lvp, nvk, radv/gfx8+, tu/a7xx+, vn
|
|||
VK_KHR_shader_float_controls2 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn)
|
||||
VK_KHR_shader_subgroup_rotate DONE (anv, lvp, nvk, panvk, radv, tu, vn)
|
||||
VK_KHR_vertex_attribute_divisor DONE (anv, lvp, nvk, panvk, radv, tu, v3dv, vn)
|
||||
VK_EXT_host_image_copy DONE (anv, lvp, nvk/Turing+, radv/gfx10+, tu, vn)
|
||||
VK_EXT_host_image_copy DONE (anv, lvp, nvk/Turing+, panvk, radv/gfx10+, tu, vn)
|
||||
VK_EXT_pipeline_protected_access DONE (anv/gfx12+, vn)
|
||||
VK_EXT_pipeline_robustness DONE (anv, lvp, nvk, panvk, radv, v3dv, tu, vn)
|
||||
|
||||
|
|
|
|||
|
|
@ -72,3 +72,4 @@ deprecated EGL_WL_bind_wayland_display
|
|||
VK_KHR_shader_atomic_int64 on panvk/v10+
|
||||
VK_EXT_host_image_copy on RADV (RDNA1+)
|
||||
VK_KHR_cooperative_matrix on nvk/turing+
|
||||
VK_KHR_host_image_copy on panvk
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ libpanvk_files = files(
|
|||
'panvk_buffer.c',
|
||||
'panvk_cmd_pool.c',
|
||||
'panvk_device_memory.c',
|
||||
'panvk_host_copy.c',
|
||||
'panvk_image.c',
|
||||
'panvk_instance.c',
|
||||
'panvk_mempool.c',
|
||||
|
|
|
|||
366
src/panfrost/vulkan/panvk_host_copy.c
Normal file
366
src/panfrost/vulkan/panvk_host_copy.c
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright © 2025 Collabora Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "panvk_device.h"
|
||||
#include "panvk_device_memory.h"
|
||||
#include "panvk_entrypoints.h"
|
||||
#include "panvk_image.h"
|
||||
|
||||
#include "vk_object.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
struct image_params {
|
||||
struct panvk_image *img;
|
||||
void *ptr;
|
||||
VkOffset3D offset;
|
||||
VkImageSubresourceLayers subres;
|
||||
};
|
||||
|
||||
struct memory_params {
|
||||
void *ptr;
|
||||
struct vk_image_buffer_layout layout;
|
||||
};
|
||||
|
||||
/* Copy either memory->image or image->memory. The direction is controlled by
|
||||
* the memory_to_img argument. */
|
||||
static void
|
||||
panvk_copy_image_to_from_memory(struct image_params img,
|
||||
struct memory_params mem,
|
||||
VkExtent3D extent, VkHostImageCopyFlags flags,
|
||||
bool memory_to_img)
|
||||
{
|
||||
/* We don't support copying tiled images yet */
|
||||
assert(img.img->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR);
|
||||
|
||||
/* We don't have to care about the multisample layout for image/memory
|
||||
* copies. From the Vulkan 1.4.317 spec:
|
||||
*
|
||||
* VUID-VkCopyImageToMemoryInfo-srcImage-07973 srcImage must have a sample
|
||||
* count equal to VK_SAMPLE_COUNT_1_BIT
|
||||
*
|
||||
* VUID-VkCopyMemoryToImageInfo-dstImage-07973 dstImage must have a sample
|
||||
* count equal to VK_SAMPLE_COUNT_1_BIT
|
||||
*/
|
||||
assert(img.img->vk.samples == VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
/* From the Vulkan 1.4.317 spec:
|
||||
*
|
||||
* VUID-VkImageToMemoryCopy-aspectMask-09103 The aspectMask member of
|
||||
* imageSubresource must only have a single bit set
|
||||
*/
|
||||
assert(util_bitcount(img.subres.aspectMask) == 1);
|
||||
unsigned plane_idx =
|
||||
panvk_plane_index(img.img->vk.format, img.subres.aspectMask);
|
||||
assert(plane_idx < PANVK_MAX_PLANES);
|
||||
struct panvk_image_plane *plane = &img.img->planes[plane_idx];
|
||||
const struct pan_image_layout *plane_layout = &plane->plane.layout;
|
||||
const struct pan_image_slice_layout *slice_layout =
|
||||
&plane_layout->slices[img.subres.mipLevel];
|
||||
|
||||
VkFormat vkfmt =
|
||||
vk_format_get_aspect_format(img.img->vk.format, img.subres.aspectMask);
|
||||
const struct util_format_description *fmt = vk_format_description(vkfmt);
|
||||
|
||||
unsigned block_width_px = fmt->block.width;
|
||||
unsigned block_height_px = fmt->block.height;
|
||||
assert(fmt->block.bits % 8 == 0);
|
||||
unsigned block_size_B = fmt->block.bits / 8;
|
||||
assert(mem.layout.element_size_B == block_size_B);
|
||||
|
||||
unsigned row_size_bl = DIV_ROUND_UP(extent.width, block_width_px);
|
||||
unsigned row_size_B = row_size_bl * block_size_B;
|
||||
|
||||
unsigned layer_count =
|
||||
vk_image_subresource_layer_count(&img.img->vk, &img.subres);
|
||||
|
||||
void *img_base_ptr = img.ptr + plane->offset + slice_layout->offset_B;
|
||||
for (unsigned layer = 0; layer < layer_count; layer++) {
|
||||
unsigned img_layer = layer + img.subres.baseArrayLayer;
|
||||
void *img_layer_ptr = img_base_ptr +
|
||||
img_layer * plane_layout->array_stride_B;
|
||||
void *mem_layer_ptr = mem.ptr + layer * mem.layout.image_stride_B;
|
||||
|
||||
if (flags & VK_HOST_IMAGE_COPY_MEMCPY_BIT) {
|
||||
if (memory_to_img)
|
||||
memcpy(img_layer_ptr, mem_layer_ptr, slice_layout->size_B);
|
||||
else
|
||||
memcpy(mem_layer_ptr, img_layer_ptr, slice_layout->size_B);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned z = 0; z < extent.depth; z++) {
|
||||
unsigned img_z = z + img.offset.z;
|
||||
void *img_depth_ptr = img_layer_ptr +
|
||||
img_z * slice_layout->tiled_or_linear.surface_stride_B;
|
||||
/* There is no distinction between array and 3D images in the memory
|
||||
* layout, image_stride_B applies to both */
|
||||
void *mem_depth_ptr = mem_layer_ptr + z * mem.layout.image_stride_B;
|
||||
|
||||
for (unsigned y = 0; y < extent.height; y += block_height_px) {
|
||||
unsigned img_y_bl = (y + img.offset.y) / block_height_px;
|
||||
unsigned mem_y_bl = y / block_height_px;
|
||||
unsigned img_x_bl = img.offset.x / block_width_px;
|
||||
void *img_row_ptr = img_depth_ptr +
|
||||
img_y_bl * slice_layout->tiled_or_linear.row_stride_B +
|
||||
img_x_bl * block_size_B;
|
||||
void *mem_row_ptr = mem_depth_ptr +
|
||||
mem_y_bl * mem.layout.row_stride_B;
|
||||
|
||||
if (memory_to_img)
|
||||
memcpy(img_row_ptr, mem_row_ptr, row_size_B);
|
||||
else
|
||||
memcpy(mem_row_ptr, img_row_ptr, row_size_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_copy_memory_to_image(struct panvk_image *dst, void *dst_cpu,
|
||||
const VkMemoryToImageCopy *region,
|
||||
VkHostImageCopyFlags flags)
|
||||
{
|
||||
struct memory_params src_params = {
|
||||
/* Casting away const, but we don't write to it so it's fine */
|
||||
.ptr = (void *) region->pHostPointer,
|
||||
.layout = vk_memory_to_image_copy_layout(&dst->vk, region),
|
||||
};
|
||||
struct image_params dst_params = {
|
||||
.img = dst,
|
||||
.ptr = dst_cpu,
|
||||
.offset = region->imageOffset,
|
||||
.subres = region->imageSubresource,
|
||||
};
|
||||
|
||||
panvk_copy_image_to_from_memory(
|
||||
dst_params, src_params, region->imageExtent, flags, true);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
panvk_CopyMemoryToImage(VkDevice device, const VkCopyMemoryToImageInfo *info)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_device, dev, device);
|
||||
VK_FROM_HANDLE(panvk_image, dst, info->dstImage);
|
||||
|
||||
void *dst_cpu = pan_kmod_bo_mmap(
|
||||
dst->mem->bo, 0, pan_kmod_bo_size(dst->mem->bo), PROT_WRITE, MAP_SHARED,
|
||||
NULL);
|
||||
if (dst_cpu == MAP_FAILED)
|
||||
return panvk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
|
||||
"Failed to CPU map image");
|
||||
|
||||
for (unsigned i = 0; i < info->regionCount; i++) {
|
||||
panvk_copy_memory_to_image(dst, dst_cpu, &info->pRegions[i],
|
||||
info->flags);
|
||||
}
|
||||
|
||||
ASSERTED int ret = os_munmap(dst_cpu, pan_kmod_bo_size(dst->mem->bo));
|
||||
assert(!ret);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_copy_image_to_memory(struct panvk_image *src, void *src_cpu,
|
||||
const VkImageToMemoryCopy *region,
|
||||
VkHostImageCopyFlags flags)
|
||||
{
|
||||
struct memory_params dst_params = {
|
||||
.ptr = region->pHostPointer,
|
||||
.layout = vk_image_to_memory_copy_layout(&src->vk, region),
|
||||
};
|
||||
struct image_params src_params = {
|
||||
.img = src,
|
||||
.ptr = src_cpu,
|
||||
.offset = region->imageOffset,
|
||||
.subres = region->imageSubresource,
|
||||
};
|
||||
|
||||
panvk_copy_image_to_from_memory(
|
||||
src_params, dst_params, region->imageExtent, flags, false);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
panvk_CopyImageToMemory(VkDevice device, const VkCopyImageToMemoryInfo *info)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_device, dev, device);
|
||||
VK_FROM_HANDLE(panvk_image, src, info->srcImage);
|
||||
|
||||
void *src_cpu = pan_kmod_bo_mmap(
|
||||
src->mem->bo, 0, pan_kmod_bo_size(src->mem->bo), PROT_READ, MAP_SHARED,
|
||||
NULL);
|
||||
if (src_cpu == MAP_FAILED)
|
||||
return panvk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
|
||||
"Failed to CPU map image");
|
||||
|
||||
for (unsigned i = 0; i < info->regionCount; i++) {
|
||||
panvk_copy_image_to_memory(src, src_cpu, &info->pRegions[i],
|
||||
info->flags);
|
||||
}
|
||||
|
||||
ASSERTED int ret = os_munmap(src_cpu, pan_kmod_bo_size(src->mem->bo));
|
||||
assert(!ret);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_copy_image_to_image(struct panvk_image *dst, void *dst_cpu,
|
||||
struct panvk_image *src, void *src_cpu,
|
||||
const VkImageCopy2 *region,
|
||||
VkHostImageCopyFlags flags)
|
||||
{
|
||||
/* We don't support copying tiled images yet */
|
||||
assert(src->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR);
|
||||
assert(dst->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR);
|
||||
|
||||
VkImageSubresourceLayers src_subres = region->srcSubresource;
|
||||
VkImageSubresourceLayers dst_subres = region->dstSubresource;
|
||||
|
||||
/* Multiple aspect bits are only allowed with ZS, which we don't support */
|
||||
assert(util_bitcount(src_subres.aspectMask == 1));
|
||||
assert(util_bitcount(dst_subres.aspectMask == 1));
|
||||
unsigned src_plane_idx =
|
||||
panvk_plane_index(src->vk.format, src_subres.aspectMask);
|
||||
unsigned dst_plane_idx =
|
||||
panvk_plane_index(dst->vk.format, dst_subres.aspectMask);
|
||||
assert(src_plane_idx < PANVK_MAX_PLANES);
|
||||
assert(dst_plane_idx < PANVK_MAX_PLANES);
|
||||
struct panvk_image_plane *src_plane = &src->planes[src_plane_idx];
|
||||
struct panvk_image_plane *dst_plane = &dst->planes[dst_plane_idx];
|
||||
const struct pan_image_layout *src_plane_layout = &dst_plane->plane.layout;
|
||||
const struct pan_image_layout *dst_plane_layout = &src_plane->plane.layout;
|
||||
const struct pan_image_slice_layout *src_slice_layout =
|
||||
&src_plane_layout->slices[src_subres.mipLevel];
|
||||
const struct pan_image_slice_layout *dst_slice_layout =
|
||||
&dst_plane_layout->slices[dst_subres.mipLevel];
|
||||
|
||||
VkFormat src_vkfmt =
|
||||
vk_format_get_aspect_format(src->vk.format, src_subres.aspectMask);
|
||||
VkFormat dst_vkfmt =
|
||||
vk_format_get_aspect_format(dst->vk.format, dst_subres.aspectMask);
|
||||
const struct util_format_description *src_fmt =
|
||||
vk_format_description(src_vkfmt);
|
||||
const struct util_format_description *dst_fmt =
|
||||
vk_format_description(dst_vkfmt);
|
||||
|
||||
unsigned block_width_px = src_fmt->block.width;
|
||||
unsigned block_height_px = src_fmt->block.height;
|
||||
assert(src_fmt->block.bits % 8 == 0);
|
||||
unsigned block_size_B = src_fmt->block.bits / 8;
|
||||
|
||||
/* This doesn't actually seem to be a requirement in the spec, but that's
|
||||
* probably unintentional */
|
||||
assert(dst_fmt->block.width == block_width_px);
|
||||
assert(dst_fmt->block.height == block_height_px);
|
||||
assert(dst_fmt->block.bits == src_fmt->block.bits);
|
||||
|
||||
unsigned row_size_bl = DIV_ROUND_UP(region->extent.width, block_width_px);
|
||||
unsigned row_size_B = row_size_bl * block_size_B;
|
||||
|
||||
unsigned src_layer_count =
|
||||
vk_image_subresource_layer_count(&src->vk, &src_subres);
|
||||
unsigned dst_layer_count =
|
||||
vk_image_subresource_layer_count(&dst->vk, &dst_subres);
|
||||
/* This also is not explicitly required in the spec */
|
||||
assert(src_layer_count == dst_layer_count);
|
||||
unsigned layer_count = src_layer_count;
|
||||
|
||||
unsigned sample_count = src->vk.samples;
|
||||
/* This also is not explicitly required in the spec */
|
||||
assert(dst->vk.samples == sample_count);
|
||||
/* Multisampled images are implemented as 3D */
|
||||
unsigned depth = sample_count > 1 ? sample_count : region->extent.depth;
|
||||
|
||||
void *src_base_ptr =
|
||||
src_cpu + src_plane->offset + src_slice_layout->offset_B;
|
||||
void *dst_base_ptr =
|
||||
dst_cpu + dst_plane->offset + dst_slice_layout->offset_B;
|
||||
for (unsigned layer = 0; layer < layer_count; layer++) {
|
||||
unsigned src_layer = layer + src_subres.baseArrayLayer;
|
||||
unsigned dst_layer = layer + dst_subres.baseArrayLayer;
|
||||
void *src_layer_ptr = src_base_ptr +
|
||||
src_layer * src_slice_layout->tiled_or_linear.surface_stride_B;
|
||||
void *dst_layer_ptr = dst_base_ptr +
|
||||
dst_layer * dst_slice_layout->tiled_or_linear.surface_stride_B;
|
||||
|
||||
if (flags & VK_HOST_IMAGE_COPY_MEMCPY_BIT) {
|
||||
assert(src_slice_layout->size_B == dst_slice_layout->size_B);
|
||||
memcpy(dst_layer_ptr, src_layer_ptr, src_slice_layout->size_B);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned z = 0; z < depth; z++) {
|
||||
unsigned src_z = z + region->srcOffset.z;
|
||||
unsigned dst_z = z + region->dstOffset.z;
|
||||
void *src_depth_ptr = src_layer_ptr +
|
||||
src_z * src_slice_layout->tiled_or_linear.surface_stride_B;
|
||||
void *dst_depth_ptr = dst_layer_ptr +
|
||||
dst_z * dst_slice_layout->tiled_or_linear.surface_stride_B;
|
||||
|
||||
for (unsigned y = 0; y < region->extent.height; y += block_height_px) {
|
||||
unsigned src_y_bl = (y + region->srcOffset.y) / block_height_px;
|
||||
unsigned dst_y_bl = (y + region->dstOffset.y) / block_height_px;
|
||||
unsigned src_x_bl = region->srcOffset.x / block_width_px;
|
||||
unsigned dst_x_bl = region->dstOffset.x / block_width_px;
|
||||
void *src_row_ptr = src_depth_ptr +
|
||||
src_y_bl * src_slice_layout->tiled_or_linear.row_stride_B +
|
||||
src_x_bl * block_size_B;
|
||||
void *dst_row_ptr = dst_depth_ptr +
|
||||
dst_y_bl * dst_slice_layout->tiled_or_linear.row_stride_B +
|
||||
dst_x_bl * block_size_B;
|
||||
|
||||
memcpy(dst_row_ptr, src_row_ptr, row_size_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
panvk_CopyImageToImage(VkDevice device, const VkCopyImageToImageInfo *info)
|
||||
{
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
VK_FROM_HANDLE(panvk_device, dev, device);
|
||||
VK_FROM_HANDLE(panvk_image, dst, info->dstImage);
|
||||
VK_FROM_HANDLE(panvk_image, src, info->srcImage);
|
||||
|
||||
void *dst_cpu = pan_kmod_bo_mmap(
|
||||
dst->mem->bo, 0, pan_kmod_bo_size(dst->mem->bo), PROT_WRITE, MAP_SHARED,
|
||||
NULL);
|
||||
if (dst_cpu == MAP_FAILED)
|
||||
return panvk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
|
||||
"Failed to CPU map image");
|
||||
|
||||
void *src_cpu = pan_kmod_bo_mmap(
|
||||
src->mem->bo, 0, pan_kmod_bo_size(src->mem->bo), PROT_READ, MAP_SHARED,
|
||||
NULL);
|
||||
if (src_cpu == MAP_FAILED) {
|
||||
result = panvk_errorf(dev, VK_ERROR_MEMORY_MAP_FAILED,
|
||||
"Failed to CPU map image");
|
||||
goto unmap_dst;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < info->regionCount; i++) {
|
||||
panvk_copy_image_to_image(dst, dst_cpu, src, src_cpu, &info->pRegions[i],
|
||||
info->flags);
|
||||
}
|
||||
|
||||
ASSERTED int ret = os_munmap(src_cpu, pan_kmod_bo_size(src->mem->bo));
|
||||
assert(!ret);
|
||||
unmap_dst:
|
||||
ret = os_munmap(dst_cpu, pan_kmod_bo_size(dst->mem->bo));
|
||||
assert(!ret);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
panvk_TransitionImageLayout(VkDevice device, uint32_t transitionCount,
|
||||
const VkHostImageLayoutTransitionInfo *transitions)
|
||||
{
|
||||
/* We don't use image layouts, this is a no-op */
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -530,6 +530,11 @@ get_image_subresource_layout(const struct panvk_image *image,
|
|||
layout->rowPitch = slice_layout->tiled_or_linear.row_stride_B;
|
||||
layout->depthPitch = slice_layout->tiled_or_linear.surface_stride_B;
|
||||
}
|
||||
|
||||
VkSubresourceHostMemcpySize *memcpy_size =
|
||||
vk_find_struct(layout2->pNext, SUBRESOURCE_HOST_MEMCPY_SIZE);
|
||||
if (memcpy_size)
|
||||
memcpy_size->size = slice_layout->size_B;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ format_is_supported(struct panvk_physical_device *physical_device,
|
|||
|
||||
static VkFormatFeatureFlags2
|
||||
get_image_plane_format_features(struct panvk_physical_device *physical_device,
|
||||
VkFormat format)
|
||||
VkFormat format, VkImageTiling tiling)
|
||||
{
|
||||
VkFormatFeatureFlags2 features = 0;
|
||||
enum pipe_format pfmt = vk_format_to_pipe_format(format);
|
||||
|
|
@ -583,12 +583,16 @@ get_image_plane_format_features(struct panvk_physical_device *physical_device,
|
|||
if (fmt.bind & PAN_BIND_DEPTH_STENCIL)
|
||||
features |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
if (features != 0 && vk_format_is_color(format) &&
|
||||
tiling == VK_IMAGE_TILING_LINEAR)
|
||||
features |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static VkFormatFeatureFlags2
|
||||
get_image_format_features(struct panvk_physical_device *physical_device,
|
||||
VkFormat format)
|
||||
VkFormat format, VkImageTiling tiling)
|
||||
{
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(format);
|
||||
|
|
@ -599,7 +603,7 @@ get_image_format_features(struct panvk_physical_device *physical_device,
|
|||
return 0;
|
||||
|
||||
if (ycbcr_info == NULL)
|
||||
return get_image_plane_format_features(physical_device, format);
|
||||
return get_image_plane_format_features(physical_device, format, tiling);
|
||||
|
||||
if (unsupported_yuv_format(vk_format_to_pipe_format(format)))
|
||||
return 0;
|
||||
|
|
@ -613,7 +617,8 @@ get_image_format_features(struct panvk_physical_device *physical_device,
|
|||
const struct vk_format_ycbcr_plane *plane_info =
|
||||
&ycbcr_info->planes[plane];
|
||||
features &=
|
||||
get_image_plane_format_features(physical_device, plane_info->format);
|
||||
get_image_plane_format_features(physical_device, plane_info->format,
|
||||
tiling);
|
||||
if (plane_info->denominator_scales[0] > 1 ||
|
||||
plane_info->denominator_scales[1] > 1)
|
||||
cosited_chroma = true;
|
||||
|
|
@ -734,22 +739,26 @@ panvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
|
|||
{
|
||||
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
|
||||
|
||||
VkFormatFeatureFlags2 tex =
|
||||
get_image_format_features(physical_device, format);
|
||||
VkFormatFeatureFlags2 tex_linear =
|
||||
get_image_format_features(physical_device, format,
|
||||
VK_IMAGE_TILING_LINEAR);
|
||||
VkFormatFeatureFlags2 tex_optimal =
|
||||
get_image_format_features(physical_device, format,
|
||||
VK_IMAGE_TILING_OPTIMAL);
|
||||
VkFormatFeatureFlags2 buffer =
|
||||
get_buffer_format_features(physical_device, format);
|
||||
|
||||
pFormatProperties->formatProperties = (VkFormatProperties){
|
||||
.linearTilingFeatures = tex,
|
||||
.optimalTilingFeatures = tex,
|
||||
.linearTilingFeatures = tex_linear,
|
||||
.optimalTilingFeatures = tex_optimal,
|
||||
.bufferFeatures = buffer,
|
||||
};
|
||||
|
||||
VkFormatProperties3 *formatProperties3 =
|
||||
vk_find_struct(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
|
||||
if (formatProperties3) {
|
||||
formatProperties3->linearTilingFeatures = tex;
|
||||
formatProperties3->optimalTilingFeatures = tex;
|
||||
formatProperties3->linearTilingFeatures = tex_linear;
|
||||
formatProperties3->optimalTilingFeatures = tex_optimal;
|
||||
formatProperties3->bufferFeatures = buffer;
|
||||
}
|
||||
|
||||
|
|
@ -877,14 +886,15 @@ get_image_format_properties(struct panvk_physical_device *physical_device,
|
|||
*/
|
||||
if (ycbcr_info == NULL) {
|
||||
format_feature_flags =
|
||||
get_image_format_features(physical_device, info->format);
|
||||
get_image_format_features(physical_device, info->format, info->tiling);
|
||||
} else {
|
||||
format_feature_flags = ~0u;
|
||||
assert(ycbcr_info->n_planes > 0);
|
||||
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
|
||||
const VkFormat plane_format = ycbcr_info->planes[plane].format;
|
||||
format_feature_flags &=
|
||||
get_image_format_features(physical_device, plane_format);
|
||||
get_image_format_features(physical_device, plane_format,
|
||||
info->tiling);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1075,6 +1085,7 @@ panvk_GetPhysicalDeviceImageFormatProperties2(
|
|||
VkExternalImageFormatProperties *external_props = NULL;
|
||||
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
||||
VkFormatFeatureFlags2 format_feature_flags;
|
||||
VkHostImageCopyDevicePerformanceQuery *hic_props = NULL;
|
||||
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
||||
VkResult result;
|
||||
|
||||
|
|
@ -1107,6 +1118,9 @@ panvk_GetPhysicalDeviceImageFormatProperties2(
|
|||
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
|
||||
cubic_props = (void *)s;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY:
|
||||
hic_props = (void *)s;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
|
||||
ycbcr_props = (void *)s;
|
||||
break;
|
||||
|
|
@ -1157,6 +1171,11 @@ panvk_GetPhysicalDeviceImageFormatProperties2(
|
|||
}
|
||||
}
|
||||
|
||||
if (hic_props) {
|
||||
hic_props->optimalDeviceAccess = true;
|
||||
hic_props->identicalMemoryLayout = true;
|
||||
}
|
||||
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(base_info->format);
|
||||
const unsigned plane_count =
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ panvk_per_arch(get_physical_device_extensions)(
|
|||
.EXT_global_priority_query = true,
|
||||
.EXT_graphics_pipeline_library = true,
|
||||
.EXT_hdr_metadata = true,
|
||||
.EXT_host_image_copy = true,
|
||||
.EXT_host_query_reset = true,
|
||||
.EXT_image_2d_view_of_3d = true,
|
||||
/* EXT_image_drm_format_modifier depends on KHR_sampler_ycbcr_conversion */
|
||||
|
|
@ -377,6 +378,9 @@ panvk_per_arch(get_physical_device_features)(
|
|||
/* VK_KHR_global_priority */
|
||||
.globalPriorityQuery = true,
|
||||
|
||||
/* VK_EXT_host_image_copy */
|
||||
.hostImageCopy = true,
|
||||
|
||||
/* VK_KHR_index_type_uint8 */
|
||||
.indexTypeUint8 = true,
|
||||
|
||||
|
|
@ -943,6 +947,9 @@ panvk_per_arch(get_physical_device_properties)(
|
|||
.pixelRate = device->model->rates.pixel,
|
||||
.texelRate = device->model->rates.texel,
|
||||
.fmaRate = device->model->rates.fma,
|
||||
|
||||
/* VK_EXT_host_image_copy */
|
||||
.identicalMemoryTypeRequirements = true,
|
||||
};
|
||||
|
||||
snprintf(properties->deviceName, sizeof(properties->deviceName), "%s",
|
||||
|
|
@ -986,4 +993,44 @@ panvk_per_arch(get_physical_device_properties)(
|
|||
memcpy(properties->shaderModuleIdentifierAlgorithmUUID,
|
||||
vk_shaderModuleIdentifierAlgorithmUUID,
|
||||
sizeof(properties->shaderModuleIdentifierAlgorithmUUID));
|
||||
|
||||
/* VK_EXT_host_image_copy */
|
||||
/* We don't use image layouts, advertise all of them */
|
||||
static VkImageLayout supported_host_copy_layouts[] = {
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_PREINITIALIZED,
|
||||
|
||||
/* Only if vk1.1+ is supported */
|
||||
#if PAN_ARCH >= 10
|
||||
/* Vulkan 1.1 */
|
||||
VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
|
||||
|
||||
/* Vulkan 1.2 */
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
|
||||
|
||||
/* Vulkan 1.3 */
|
||||
VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||
|
||||
/* Vulkan 1.4 */
|
||||
VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ,
|
||||
#endif
|
||||
};
|
||||
properties->pCopySrcLayouts = supported_host_copy_layouts;
|
||||
properties->copySrcLayoutCount = ARRAY_SIZE(supported_host_copy_layouts);
|
||||
properties->pCopyDstLayouts = supported_host_copy_layouts;
|
||||
properties->copyDstLayoutCount = ARRAY_SIZE(supported_host_copy_layouts);
|
||||
/* All HW has the same tiling layout, key off build hash only */
|
||||
STATIC_ASSERT(sizeof(instance->driver_build_sha) >= VK_UUID_SIZE);
|
||||
memcpy(properties->optimalTilingLayoutUUID, instance->driver_build_sha,
|
||||
VK_UUID_SIZE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue