mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02: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_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_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_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_protected_access DONE (anv/gfx12+, vn)
|
||||||
VK_EXT_pipeline_robustness DONE (anv, lvp, nvk, panvk, radv, v3dv, tu, 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_KHR_shader_atomic_int64 on panvk/v10+
|
||||||
VK_EXT_host_image_copy on RADV (RDNA1+)
|
VK_EXT_host_image_copy on RADV (RDNA1+)
|
||||||
VK_KHR_cooperative_matrix on nvk/turing+
|
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_buffer.c',
|
||||||
'panvk_cmd_pool.c',
|
'panvk_cmd_pool.c',
|
||||||
'panvk_device_memory.c',
|
'panvk_device_memory.c',
|
||||||
|
'panvk_host_copy.c',
|
||||||
'panvk_image.c',
|
'panvk_image.c',
|
||||||
'panvk_instance.c',
|
'panvk_instance.c',
|
||||||
'panvk_mempool.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->rowPitch = slice_layout->tiled_or_linear.row_stride_B;
|
||||||
layout->depthPitch = slice_layout->tiled_or_linear.surface_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
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
|
|
|
||||||
|
|
@ -530,7 +530,7 @@ format_is_supported(struct panvk_physical_device *physical_device,
|
||||||
|
|
||||||
static VkFormatFeatureFlags2
|
static VkFormatFeatureFlags2
|
||||||
get_image_plane_format_features(struct panvk_physical_device *physical_device,
|
get_image_plane_format_features(struct panvk_physical_device *physical_device,
|
||||||
VkFormat format)
|
VkFormat format, VkImageTiling tiling)
|
||||||
{
|
{
|
||||||
VkFormatFeatureFlags2 features = 0;
|
VkFormatFeatureFlags2 features = 0;
|
||||||
enum pipe_format pfmt = vk_format_to_pipe_format(format);
|
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)
|
if (fmt.bind & PAN_BIND_DEPTH_STENCIL)
|
||||||
features |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT;
|
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;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkFormatFeatureFlags2
|
static VkFormatFeatureFlags2
|
||||||
get_image_format_features(struct panvk_physical_device *physical_device,
|
get_image_format_features(struct panvk_physical_device *physical_device,
|
||||||
VkFormat format)
|
VkFormat format, VkImageTiling tiling)
|
||||||
{
|
{
|
||||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||||
vk_format_get_ycbcr_info(format);
|
vk_format_get_ycbcr_info(format);
|
||||||
|
|
@ -599,7 +603,7 @@ get_image_format_features(struct panvk_physical_device *physical_device,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ycbcr_info == NULL)
|
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)))
|
if (unsupported_yuv_format(vk_format_to_pipe_format(format)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -613,7 +617,8 @@ get_image_format_features(struct panvk_physical_device *physical_device,
|
||||||
const struct vk_format_ycbcr_plane *plane_info =
|
const struct vk_format_ycbcr_plane *plane_info =
|
||||||
&ycbcr_info->planes[plane];
|
&ycbcr_info->planes[plane];
|
||||||
features &=
|
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 ||
|
if (plane_info->denominator_scales[0] > 1 ||
|
||||||
plane_info->denominator_scales[1] > 1)
|
plane_info->denominator_scales[1] > 1)
|
||||||
cosited_chroma = true;
|
cosited_chroma = true;
|
||||||
|
|
@ -734,22 +739,26 @@ panvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
|
||||||
{
|
{
|
||||||
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
|
VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice);
|
||||||
|
|
||||||
VkFormatFeatureFlags2 tex =
|
VkFormatFeatureFlags2 tex_linear =
|
||||||
get_image_format_features(physical_device, format);
|
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 =
|
VkFormatFeatureFlags2 buffer =
|
||||||
get_buffer_format_features(physical_device, format);
|
get_buffer_format_features(physical_device, format);
|
||||||
|
|
||||||
pFormatProperties->formatProperties = (VkFormatProperties){
|
pFormatProperties->formatProperties = (VkFormatProperties){
|
||||||
.linearTilingFeatures = tex,
|
.linearTilingFeatures = tex_linear,
|
||||||
.optimalTilingFeatures = tex,
|
.optimalTilingFeatures = tex_optimal,
|
||||||
.bufferFeatures = buffer,
|
.bufferFeatures = buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFormatProperties3 *formatProperties3 =
|
VkFormatProperties3 *formatProperties3 =
|
||||||
vk_find_struct(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
|
vk_find_struct(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
|
||||||
if (formatProperties3) {
|
if (formatProperties3) {
|
||||||
formatProperties3->linearTilingFeatures = tex;
|
formatProperties3->linearTilingFeatures = tex_linear;
|
||||||
formatProperties3->optimalTilingFeatures = tex;
|
formatProperties3->optimalTilingFeatures = tex_optimal;
|
||||||
formatProperties3->bufferFeatures = buffer;
|
formatProperties3->bufferFeatures = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -877,14 +886,15 @@ get_image_format_properties(struct panvk_physical_device *physical_device,
|
||||||
*/
|
*/
|
||||||
if (ycbcr_info == NULL) {
|
if (ycbcr_info == NULL) {
|
||||||
format_feature_flags =
|
format_feature_flags =
|
||||||
get_image_format_features(physical_device, info->format);
|
get_image_format_features(physical_device, info->format, info->tiling);
|
||||||
} else {
|
} else {
|
||||||
format_feature_flags = ~0u;
|
format_feature_flags = ~0u;
|
||||||
assert(ycbcr_info->n_planes > 0);
|
assert(ycbcr_info->n_planes > 0);
|
||||||
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
|
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
|
||||||
const VkFormat plane_format = ycbcr_info->planes[plane].format;
|
const VkFormat plane_format = ycbcr_info->planes[plane].format;
|
||||||
format_feature_flags &=
|
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;
|
VkExternalImageFormatProperties *external_props = NULL;
|
||||||
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL;
|
||||||
VkFormatFeatureFlags2 format_feature_flags;
|
VkFormatFeatureFlags2 format_feature_flags;
|
||||||
|
VkHostImageCopyDevicePerformanceQuery *hic_props = NULL;
|
||||||
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
|
|
@ -1107,6 +1118,9 @@ panvk_GetPhysicalDeviceImageFormatProperties2(
|
||||||
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
|
case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT:
|
||||||
cubic_props = (void *)s;
|
cubic_props = (void *)s;
|
||||||
break;
|
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:
|
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
|
||||||
ycbcr_props = (void *)s;
|
ycbcr_props = (void *)s;
|
||||||
break;
|
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 =
|
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||||
vk_format_get_ycbcr_info(base_info->format);
|
vk_format_get_ycbcr_info(base_info->format);
|
||||||
const unsigned plane_count =
|
const unsigned plane_count =
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ panvk_per_arch(get_physical_device_extensions)(
|
||||||
.EXT_global_priority_query = true,
|
.EXT_global_priority_query = true,
|
||||||
.EXT_graphics_pipeline_library = true,
|
.EXT_graphics_pipeline_library = true,
|
||||||
.EXT_hdr_metadata = true,
|
.EXT_hdr_metadata = true,
|
||||||
|
.EXT_host_image_copy = true,
|
||||||
.EXT_host_query_reset = true,
|
.EXT_host_query_reset = true,
|
||||||
.EXT_image_2d_view_of_3d = true,
|
.EXT_image_2d_view_of_3d = true,
|
||||||
/* EXT_image_drm_format_modifier depends on KHR_sampler_ycbcr_conversion */
|
/* 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 */
|
/* VK_KHR_global_priority */
|
||||||
.globalPriorityQuery = true,
|
.globalPriorityQuery = true,
|
||||||
|
|
||||||
|
/* VK_EXT_host_image_copy */
|
||||||
|
.hostImageCopy = true,
|
||||||
|
|
||||||
/* VK_KHR_index_type_uint8 */
|
/* VK_KHR_index_type_uint8 */
|
||||||
.indexTypeUint8 = true,
|
.indexTypeUint8 = true,
|
||||||
|
|
||||||
|
|
@ -943,6 +947,9 @@ panvk_per_arch(get_physical_device_properties)(
|
||||||
.pixelRate = device->model->rates.pixel,
|
.pixelRate = device->model->rates.pixel,
|
||||||
.texelRate = device->model->rates.texel,
|
.texelRate = device->model->rates.texel,
|
||||||
.fmaRate = device->model->rates.fma,
|
.fmaRate = device->model->rates.fma,
|
||||||
|
|
||||||
|
/* VK_EXT_host_image_copy */
|
||||||
|
.identicalMemoryTypeRequirements = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
snprintf(properties->deviceName, sizeof(properties->deviceName), "%s",
|
snprintf(properties->deviceName, sizeof(properties->deviceName), "%s",
|
||||||
|
|
@ -986,4 +993,44 @@ panvk_per_arch(get_physical_device_properties)(
|
||||||
memcpy(properties->shaderModuleIdentifierAlgorithmUUID,
|
memcpy(properties->shaderModuleIdentifierAlgorithmUUID,
|
||||||
vk_shaderModuleIdentifierAlgorithmUUID,
|
vk_shaderModuleIdentifierAlgorithmUUID,
|
||||||
sizeof(properties->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