radv: align video images internal width/height inside the driver.
Due to how the decoders work, they will write garbage data into the padding, and later using the image for sampling with linear images will use the garbage to create broken results. Let the user specify the image size and align it up in the driver, so sampling of the image later has the correct w/h. cc: mesa-stable Reviewed-by: Lynne <dev@lynne.ee> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23227>
This commit is contained in:
@@ -675,7 +675,7 @@ radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *me
|
||||
struct radv_image_create_info create_info = {.no_metadata_planes = true,
|
||||
.bo_metadata = &metadata};
|
||||
|
||||
result = radv_image_create_layout(device, create_info, NULL, mem->image);
|
||||
result = radv_image_create_layout(device, create_info, NULL, NULL, mem->image);
|
||||
if (result != VK_SUCCESS) {
|
||||
device->ws->buffer_destroy(device->ws, mem->bo);
|
||||
mem->bo = NULL;
|
||||
|
@@ -187,7 +187,7 @@ radv_alloc_memory(struct radv_device *device, const VkMemoryAllocateInfo *pAlloc
|
||||
/* This gives a basic ability to import radeonsi images
|
||||
* that don't have DCC. This is not guaranteed by any
|
||||
* spec and can be removed after we support modifiers. */
|
||||
result = radv_image_create_layout(device, create_info, NULL, mem->image);
|
||||
result = radv_image_create_layout(device, create_info, NULL, NULL, mem->image);
|
||||
if (result != VK_SUCCESS) {
|
||||
device->ws->buffer_destroy(device->ws, mem->bo);
|
||||
goto fail;
|
||||
|
@@ -1747,6 +1747,7 @@ radv_get_ac_surf_info(struct radv_device *device, const struct radv_image *image
|
||||
VkResult
|
||||
radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info,
|
||||
const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info,
|
||||
const struct VkVideoProfileListInfoKHR *profile_list,
|
||||
struct radv_image *image)
|
||||
{
|
||||
/* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
|
||||
@@ -1762,6 +1763,19 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
|
||||
|
||||
radv_image_reset_layout(device->physical_device, image);
|
||||
|
||||
/*
|
||||
* Due to how the decoder works, the user can't supply an oversized image, because if it attempts
|
||||
* to sample it later with a linear filter, it will get garbage after the height it wants,
|
||||
* so we let the user specify the width/height unaligned, and align them preallocation.
|
||||
*/
|
||||
if (image->vk.usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR)) {
|
||||
assert(profile_list);
|
||||
uint32_t width_align, height_align;
|
||||
vk_video_get_profile_alignments(profile_list, &width_align, &height_align);
|
||||
image_info.width = align(image_info.width, width_align);
|
||||
image_info.height = align(image_info.height, height_align);
|
||||
}
|
||||
|
||||
unsigned plane_count = radv_get_internal_plane_count(device->physical_device, image->vk.format);
|
||||
for (unsigned plane = 0; plane < plane_count; ++plane) {
|
||||
struct ac_surf_info info = image_info;
|
||||
@@ -1943,6 +1957,8 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_
|
||||
const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
|
||||
vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
|
||||
const struct VkVideoProfileListInfoKHR *profile_list =
|
||||
vk_find_struct_const(pCreateInfo->pNext, VIDEO_PROFILE_LIST_INFO_KHR);
|
||||
|
||||
unsigned plane_count = radv_get_internal_plane_count(device->physical_device, format);
|
||||
|
||||
@@ -2003,7 +2019,7 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, image);
|
||||
VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, profile_list, image);
|
||||
if (result != VK_SUCCESS) {
|
||||
radv_destroy_image(device, alloc, image);
|
||||
return result;
|
||||
|
@@ -2852,6 +2852,7 @@ struct radv_image_create_info {
|
||||
VkResult
|
||||
radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info,
|
||||
const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info,
|
||||
const struct VkVideoProfileListInfoKHR *profile_list,
|
||||
struct radv_image *image);
|
||||
|
||||
VkResult radv_image_create(VkDevice _device, const struct radv_image_create_info *info,
|
||||
|
Reference in New Issue
Block a user