anv: add initial support for AV1 decoding
Co-authored-by: Hyunjun Ko <zzoon@igalia.com> - Allow intrabc - Fix to manage refrenece frames using referenceNameSlotIndices - Fix to set bitmask of motion field projection correctly - Set destination buffer offset to the BSD_OBJECT - Support 10-bit decoding. - Fix small bugs. - Change to C-style comment. Signed-off-by: Hyunjun Ko <zzoon@igalia.com> Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32775>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "vk_format.h"
|
||||
#include "av1_tables.h"
|
||||
|
||||
#define ANV_OFFSET_IMPLICIT UINT64_MAX
|
||||
|
||||
@@ -946,19 +947,7 @@ add_video_buffers(struct anv_device *device,
|
||||
unsigned h_mb = DIV_ROUND_UP(image->vk.extent.height, ANV_MB_HEIGHT);
|
||||
size = w_mb * h_mb * 128;
|
||||
} else {
|
||||
for (unsigned i = 0; i < profile_list->profileCount; i++) {
|
||||
if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR ||
|
||||
profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR) {
|
||||
unsigned w_mb = DIV_ROUND_UP(image->vk.extent.width, ANV_MB_WIDTH);
|
||||
unsigned h_mb = DIV_ROUND_UP(image->vk.extent.height, ANV_MB_HEIGHT);
|
||||
size = w_mb * h_mb * 128;
|
||||
} else if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR ||
|
||||
profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR) {
|
||||
unsigned w_mb = DIV_ROUND_UP(image->vk.extent.width, 32);
|
||||
unsigned h_mb = DIV_ROUND_UP(image->vk.extent.height, 32);
|
||||
size = ALIGN(w_mb * h_mb, 2) << 6;
|
||||
}
|
||||
}
|
||||
size = anv_video_get_image_mv_size(device, image, profile_list);
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
@@ -966,6 +955,19 @@ add_video_buffers(struct anv_device *device,
|
||||
|
||||
ok = image_binding_grow(device, image, ANV_IMAGE_MEMORY_BINDING_PRIVATE,
|
||||
ANV_OFFSET_IMPLICIT, size, 65536, &image->vid_dmv_top_surface);
|
||||
if (ok != VK_SUCCESS)
|
||||
return ok;
|
||||
|
||||
/* Doesn't work for av1 without provided profiles */
|
||||
if (!independent_profile) {
|
||||
for (unsigned i = 0; i < profile_list->profileCount; i++) {
|
||||
if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) {
|
||||
ok = image_binding_grow(device, image, ANV_IMAGE_MEMORY_BINDING_PRIVATE,
|
||||
ANV_OFFSET_IMPLICIT, av1_cdf_max_num_bytes, 4096, &image->av1_cdf_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@@ -238,6 +238,7 @@ get_device_extensions(const struct anv_physical_device *device,
|
||||
.KHR_video_decode_queue = device->video_decode_enabled,
|
||||
.KHR_video_decode_h264 = VIDEO_CODEC_H264DEC && device->video_decode_enabled,
|
||||
.KHR_video_decode_h265 = VIDEO_CODEC_H265DEC && device->video_decode_enabled,
|
||||
.KHR_video_decode_av1 = device->info.ver >= 12 && VIDEO_CODEC_AV1DEC && device->video_decode_enabled,
|
||||
.KHR_video_encode_queue = device->video_encode_enabled,
|
||||
.KHR_video_encode_h264 = VIDEO_CODEC_H264ENC && device->video_encode_enabled,
|
||||
.KHR_video_encode_h265 = device->info.ver >= 12 && VIDEO_CODEC_H265ENC && device->video_encode_enabled,
|
||||
@@ -2810,6 +2811,8 @@ void anv_GetPhysicalDeviceQueueFamilyProperties2(
|
||||
if (queue_family->queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
|
||||
prop->videoCodecOperations = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR |
|
||||
VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
|
||||
if (pdevice->info.ver >= 12)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR;
|
||||
}
|
||||
|
||||
if (queue_family->queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) {
|
||||
|
@@ -5525,6 +5525,7 @@ struct anv_image {
|
||||
|
||||
/* Link in the anv_device.image_private_objects list */
|
||||
struct list_head link;
|
||||
struct anv_image_memory_range av1_cdf_table;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
@@ -6315,11 +6316,52 @@ enum anv_vid_mem_h265_types {
|
||||
ANV_VID_MEM_H265_ENC_MAX,
|
||||
};
|
||||
|
||||
enum anv_vid_mem_av1_types {
|
||||
ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE,
|
||||
ANV_VID_MEM_AV1_BITSTREAM_TILE_LINE_ROWSTORE,
|
||||
ANV_VID_MEM_AV1_INTRA_PREDICTION_LINE_ROWSTORE,
|
||||
ANV_VID_MEM_AV1_INTRA_PREDICTION_TILE_LINE_ROWSTORE,
|
||||
ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_LINE,
|
||||
ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_TILE_LINE,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_META_TILE_COLUMN,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_Y,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_U,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_V,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_Y,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_U,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_V,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_Y,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_U,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_V,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_Y,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_U,
|
||||
ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_V,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_LINE,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_TILE_LINE,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_TILE_COLUMN,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_LINE,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_COLUMN,
|
||||
ANV_VID_MEM_AV1_CDEF_FILTER_TOP_LEFT_CORNER,
|
||||
ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_Y,
|
||||
ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_U,
|
||||
ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_V,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_Y,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_U,
|
||||
ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_V,
|
||||
ANV_VID_MEM_AV1_CDF_DEFAULTS_0,
|
||||
ANV_VID_MEM_AV1_CDF_DEFAULTS_1,
|
||||
ANV_VID_MEM_AV1_CDF_DEFAULTS_2,
|
||||
ANV_VID_MEM_AV1_CDF_DEFAULTS_3,
|
||||
ANV_VID_MEM_AV1_DBD_BUFFER,
|
||||
ANV_VID_MEM_AV1_MAX,
|
||||
};
|
||||
|
||||
struct anv_video_session {
|
||||
struct vk_video_session vk;
|
||||
|
||||
bool cdf_initialized;
|
||||
/* the decoder needs some private memory allocations */
|
||||
struct anv_vid_mem vid_mem[ANV_VID_MEM_H265_ENC_MAX];
|
||||
struct anv_vid_mem vid_mem[ANV_VID_MEM_AV1_MAX];
|
||||
};
|
||||
|
||||
struct anv_video_session_params {
|
||||
@@ -6327,6 +6369,13 @@ struct anv_video_session_params {
|
||||
VkVideoEncodeRateControlModeFlagBitsKHR rc_mode;
|
||||
};
|
||||
|
||||
void anv_init_av1_cdf_tables(struct anv_cmd_buffer *cmd,
|
||||
struct anv_video_session *vid);
|
||||
|
||||
uint32_t anv_video_get_image_mv_size(struct anv_device *device,
|
||||
struct anv_image *image,
|
||||
const struct VkVideoProfileListInfoKHR *profile_list);
|
||||
|
||||
void
|
||||
anv_dump_pipe_bits(enum anv_pipe_bits bits, FILE *f);
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "anv_private.h"
|
||||
|
||||
#include "av1_tables.h"
|
||||
#include "vk_video/vulkan_video_codecs_common.h"
|
||||
|
||||
VkResult
|
||||
@@ -115,13 +116,18 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
|
||||
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
||||
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = 32;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = 32;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = 1;
|
||||
pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH;
|
||||
pCapabilities->pictureAccessGranularity.height = ANV_MB_HEIGHT;
|
||||
pCapabilities->minCodedExtent.width = ANV_MB_WIDTH;
|
||||
pCapabilities->minCodedExtent.height = ANV_MB_HEIGHT;
|
||||
pCapabilities->maxCodedExtent.width = 4096;
|
||||
pCapabilities->maxCodedExtent.height = 4096;
|
||||
pCapabilities->flags = VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
|
||||
struct VkVideoDecodeCapabilitiesKHR *dec_caps = (struct VkVideoDecodeCapabilitiesKHR *)
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_CAPABILITIES_KHR);
|
||||
|
||||
if (dec_caps)
|
||||
dec_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
|
||||
|
||||
@@ -154,6 +160,31 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION;
|
||||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR: {
|
||||
|
||||
const struct VkVideoDecodeAV1ProfileInfoKHR *av1_profile =
|
||||
vk_find_struct_const(pVideoProfile->pNext, VIDEO_DECODE_AV1_PROFILE_INFO_KHR);
|
||||
|
||||
if (av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_MAIN)
|
||||
return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR;
|
||||
|
||||
if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR &&
|
||||
pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
|
||||
return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
|
||||
|
||||
struct VkVideoDecodeAV1CapabilitiesKHR *ext = (struct VkVideoDecodeAV1CapabilitiesKHR *)
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_AV1_CAPABILITIES_KHR);
|
||||
|
||||
ext->maxLevel = STD_VIDEO_AV1_LEVEL_6_0;
|
||||
|
||||
pCapabilities->maxDpbSlots = 8;
|
||||
pCapabilities->maxActiveReferencePictures = 7;
|
||||
dec_caps->flags |= VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
|
||||
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION;
|
||||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
|
||||
struct VkVideoDecodeH265CapabilitiesKHR *ext = (struct VkVideoDecodeH265CapabilitiesKHR *)
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H265_CAPABILITIES_KHR);
|
||||
@@ -485,6 +516,192 @@ get_h265_video_session_mem_reqs(struct anv_video_session *vid,
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t av1_buffer_size[ANV_VID_MEM_AV1_MAX][4] = {
|
||||
{ 2 , 4 , 2 , 4 }, /* bsdLineBuf, */
|
||||
{ 2 , 4 , 2 , 4 }, /* bsdTileLineBuf, */
|
||||
{ 2 , 4 , 4 , 8 }, /* intraPredLine, */
|
||||
{ 2 , 4 , 4 , 8 }, /* intraPredTileLine, */
|
||||
{ 4 , 8 , 4 , 8 }, /* spatialMvLineBuf, */
|
||||
{ 4 , 8 , 4 , 8 }, /* spatialMvTileLineBuf, */
|
||||
{ 1 , 1 , 1 , 1 }, /* lrMetaTileCol, */
|
||||
{ 7 , 7 , 7 , 7 }, /* lrTileLineY, */
|
||||
{ 5 , 5 , 5 , 5 }, /* lrTileLineU, */
|
||||
{ 5 , 5 , 5 , 5 }, /* lrTileLineV, */
|
||||
{ 9 , 17 , 11 , 21 }, /* deblockLineYBuf, */
|
||||
{ 3 , 4 , 3 , 5 }, /* deblockLineUBuf, */
|
||||
{ 3 , 4 , 3 , 5 }, /* deblockLineVBuf, */
|
||||
{ 9 , 17 , 11 , 21 }, /* deblockTileLineYBuf, */
|
||||
{ 3 , 4 , 3 , 5 }, /* deblockTileLineVBuf, */
|
||||
{ 3 , 4 , 3 , 5 }, /* deblockTileLineUBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* deblockTileColYBuf, */
|
||||
{ 2 , 4 , 3 , 5 }, /* deblockTileColUBuf, */
|
||||
{ 2 , 4 , 3 , 5 }, /* deblockTileColVBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* cdefLineBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* cdefTileLineBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* cdefTileColBuf, */
|
||||
{ 1 , 1 , 1 , 1 }, /* cdefMetaTileLine, */
|
||||
{ 1 , 1 , 1 , 1 }, /* cdefMetaTileCol, */
|
||||
{ 1 , 1 , 1 , 1 }, /* cdefTopLeftCornerBuf, */
|
||||
{ 22, 44 , 29 , 58 }, /* superResTileColYBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* superResTileColUBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* superResTileColVBuf, */
|
||||
{ 9 , 17 , 11 , 22 }, /* lrTileColYBuf, */
|
||||
{ 5 , 9 , 6 , 12 }, /* lrTileColUBuf, */
|
||||
{ 5 , 9 , 6 , 12 }, /* lrTileColVBuf, */
|
||||
};
|
||||
|
||||
static const uint8_t av1_buffer_size_ext[ANV_VID_MEM_AV1_MAX][4] = {
|
||||
{ 0 , 0 , 0 , 0 }, /* bsdLineBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* bsdTileLineBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* intraPredLine, */
|
||||
{ 0 , 0 , 0 , 0 }, /* intraPredTileLine, */
|
||||
{ 0 , 0 , 0 , 0 }, /* spatialMvLineBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* spatialMvTileLineBuf, */
|
||||
{ 1 , 1 , 1 , 1 }, /* lrMetaTileCol, */
|
||||
{ 0 , 0 , 0 , 0 }, /* lrTileLineY, */
|
||||
{ 0 , 0 , 0 , 0 }, /* lrTileLineU, */
|
||||
{ 0 , 0 , 0 , 0 }, /* lrTileLineV, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockLineYBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockLineUBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockLineVBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileLineYBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileLineVBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileLineUBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileColYBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileColUBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* deblockTileColVBuf, */
|
||||
{ 1 , 1 , 2 , 2 }, /* cdefLineBuf, */
|
||||
{ 1 , 1 , 2 , 2 }, /* cdefTileLineBuf, */
|
||||
{ 1 , 1 , 2 , 2 }, /* cdefTileColBuf, */
|
||||
{ 0 , 0 , 0 , 0 }, /* cdefMetaTileLine, */
|
||||
{ 1 , 1 , 1 , 1 }, /* cdefMetaTileCol, */
|
||||
{ 0 , 0 , 0 , 0 }, /* cdefTopLeftCornerBuf, */
|
||||
{ 22, 44 , 29 , 58 }, /* superResTileColYBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* superResTileColUBuf, */
|
||||
{ 8 , 16 , 10 , 20 }, /* superResTileColVBuf, */
|
||||
{ 2 , 2 , 2 , 2 }, /* lrTileColYBuf, */
|
||||
{ 1 , 1 , 1 , 1 }, /* lrTileColUBuf, */
|
||||
{ 1 , 1 , 1 , 1 }, /* lrTileColVBuf, */
|
||||
};
|
||||
|
||||
static void
|
||||
get_av1_video_session_mem_reqs(struct anv_video_session *vid,
|
||||
VkVideoSessionMemoryRequirementsKHR *mem_reqs,
|
||||
uint32_t *pVideoSessionMemoryRequirementsCount,
|
||||
uint32_t memory_types)
|
||||
{
|
||||
VK_OUTARRAY_MAKE_TYPED(VkVideoSessionMemoryRequirementsKHR,
|
||||
out,
|
||||
mem_reqs,
|
||||
pVideoSessionMemoryRequirementsCount);
|
||||
const uint32_t av1_mi_size_log2 = 2;
|
||||
const uint32_t av1_max_mib_size_log2 = 5;
|
||||
uint32_t width = vid->vk.max_coded.width;
|
||||
uint32_t height = vid->vk.max_coded.height;
|
||||
uint32_t mi_cols = width >> av1_mi_size_log2;
|
||||
uint32_t mi_rows = height >> av1_mi_size_log2;
|
||||
uint32_t width_in_sb = align(mi_cols, (1 << av1_mi_size_log2)) >> av1_mi_size_log2;
|
||||
uint32_t height_in_sb = align(mi_rows, (1 << av1_mi_size_log2)) >> av1_mi_size_log2;
|
||||
uint32_t max_tile_width_sb = DIV_ROUND_UP(4096, 1 << (av1_max_mib_size_log2 + av1_mi_size_log2));
|
||||
uint32_t max_tile_cols = 16; /* TODO. get the profile to work this out */
|
||||
|
||||
/* Assume 8-bit 128x128 sb is true, can't know at this point */
|
||||
int buf_size_idx = 1;
|
||||
|
||||
for (enum anv_vid_mem_av1_types mem = ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE;
|
||||
mem < ANV_VID_MEM_AV1_MAX; mem++) {
|
||||
VkDeviceSize buffer_size = 0;
|
||||
|
||||
switch (mem) {
|
||||
case ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE:
|
||||
case ANV_VID_MEM_AV1_INTRA_PREDICTION_LINE_ROWSTORE:
|
||||
case ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_LINE:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_Y:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_U:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_V:
|
||||
buffer_size = max_tile_width_sb * av1_buffer_size[mem][buf_size_idx];
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_LINE:
|
||||
buffer_size = max_tile_width_sb * av1_buffer_size[mem][buf_size_idx] +
|
||||
av1_buffer_size_ext[mem][buf_size_idx];
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_BITSTREAM_TILE_LINE_ROWSTORE:
|
||||
case ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_TILE_LINE:
|
||||
case ANV_VID_MEM_AV1_INTRA_PREDICTION_TILE_LINE_ROWSTORE:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_Y:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_U:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_V:
|
||||
buffer_size = width_in_sb * av1_buffer_size[mem][buf_size_idx];
|
||||
break;
|
||||
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_Y:
|
||||
buffer_size = max_tile_cols * 7;
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_U:
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_V:
|
||||
buffer_size = max_tile_cols * 5;
|
||||
break;
|
||||
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_Y:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_U:
|
||||
case ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_V:
|
||||
buffer_size = height_in_sb * av1_buffer_size[mem][buf_size_idx];
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_TILE_LINE:
|
||||
buffer_size = width_in_sb * av1_buffer_size[mem][buf_size_idx] +
|
||||
av1_buffer_size_ext[mem][buf_size_idx];
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_LINE:
|
||||
buffer_size = max_tile_cols;
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_TOP_LEFT_CORNER:
|
||||
buffer_size = max_tile_cols * 8; /* TODO. take from profile */
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_TILE_COLUMN:
|
||||
case ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_COLUMN:
|
||||
case ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_Y:
|
||||
case ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_U:
|
||||
case ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_V:
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_Y:
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_U:
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_V:
|
||||
case ANV_VID_MEM_AV1_LOOP_RESTORATION_META_TILE_COLUMN:
|
||||
buffer_size = height_in_sb * av1_buffer_size[mem][buf_size_idx] +
|
||||
av1_buffer_size_ext[mem][buf_size_idx];
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_0:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_1:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_2:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_3:
|
||||
buffer_size = av1_cdf_max_num_bytes;
|
||||
break;
|
||||
case ANV_VID_MEM_AV1_DBD_BUFFER:
|
||||
buffer_size = 1;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mem) {
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_0:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_1:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_2:
|
||||
case ANV_VID_MEM_AV1_CDF_DEFAULTS_3:
|
||||
break;
|
||||
default:
|
||||
buffer_size *= 64;
|
||||
break;
|
||||
}
|
||||
vk_outarray_append_typed(VkVideoSessionMemoryRequirementsKHR, &out, p) {
|
||||
p->memoryBindIndex = mem;
|
||||
p->memoryRequirements.size = buffer_size;
|
||||
p->memoryRequirements.alignment = 4096;
|
||||
p->memoryRequirements.memoryTypeBits = memory_types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device,
|
||||
VkVideoSessionKHR videoSession,
|
||||
@@ -523,6 +740,12 @@ anv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device,
|
||||
pVideoSessionMemoryRequirementsCount,
|
||||
memory_types);
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
|
||||
get_av1_video_session_mem_reqs(vid,
|
||||
mem_reqs,
|
||||
pVideoSessionMemoryRequirementsCount,
|
||||
memory_types);
|
||||
break;
|
||||
default:
|
||||
unreachable("unknown codec");
|
||||
}
|
||||
@@ -559,6 +782,7 @@ anv_BindVideoSessionMemoryKHR(VkDevice _device,
|
||||
switch (vid->vk.op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
|
||||
for (unsigned i = 0; i < bind_mem_count; i++) {
|
||||
copy_bind(&vid->vid_mem[bind_mem[i].memoryBindIndex], &bind_mem[i]);
|
||||
}
|
||||
@@ -660,3 +884,115 @@ anv_GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(VkPhysicalDevice physi
|
||||
/* TODO. */
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
init_single_av1_entry(const struct syntax_element_cdf_table_layout *entry, uint16_t *dst_ptr)
|
||||
{
|
||||
uint16_t entry_count_per_cl = entry->entry_count_per_cl;
|
||||
uint16_t entry_count_total = entry->entry_count_total;
|
||||
uint16_t start_cl = entry->start_cl;
|
||||
|
||||
const uint16_t *src = entry->init_data;
|
||||
uint16_t *dst = dst_ptr + start_cl * 32;
|
||||
uint16_t entry_count_left = entry_count_total;
|
||||
|
||||
while (entry_count_left >= entry_count_per_cl) {
|
||||
memcpy(dst, src, entry_count_per_cl * sizeof(uint16_t));
|
||||
entry_count_left -= entry_count_per_cl;
|
||||
|
||||
src += entry_count_per_cl;
|
||||
dst += 32;
|
||||
}
|
||||
|
||||
if (entry_count_left > 0)
|
||||
memcpy(dst, src, entry_count_left * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
#define INIT_TABLE(x) do {\
|
||||
for (unsigned i = 0; i < ARRAY_SIZE((x)); i++) \
|
||||
init_single_av1_entry(&(x)[i], dst_ptr); \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
init_all_av1_entry(uint16_t *dst_ptr, int index)
|
||||
{
|
||||
INIT_TABLE(av1_cdf_intra_part1);
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
INIT_TABLE(av1_cdf_intra_coeffs_0);
|
||||
break;
|
||||
case 1:
|
||||
INIT_TABLE(av1_cdf_intra_coeffs_1);
|
||||
break;
|
||||
case 2:
|
||||
INIT_TABLE(av1_cdf_intra_coeffs_2);
|
||||
break;
|
||||
case 3:
|
||||
INIT_TABLE(av1_cdf_intra_coeffs_3);
|
||||
break;
|
||||
default:
|
||||
unreachable("illegal av1 entry\n");
|
||||
}
|
||||
INIT_TABLE(av1_cdf_intra_part2);
|
||||
INIT_TABLE(av1_cdf_inter);
|
||||
}
|
||||
|
||||
void
|
||||
anv_init_av1_cdf_tables(struct anv_cmd_buffer *cmd,
|
||||
struct anv_video_session *vid)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
VkResult result =
|
||||
anv_device_map_bo(cmd->device,
|
||||
vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + i].mem->bo,
|
||||
vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + i].offset,
|
||||
vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + i].size,
|
||||
NULL,
|
||||
&ptr);
|
||||
|
||||
if (result != VK_SUCCESS) {
|
||||
anv_batch_set_error(&cmd->batch, result);
|
||||
return;
|
||||
}
|
||||
|
||||
init_all_av1_entry(ptr, i);
|
||||
anv_device_unmap_bo(cmd->device, vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + i].mem->bo, ptr,
|
||||
vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + i].size, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
anv_video_get_image_mv_size(struct anv_device *device,
|
||||
struct anv_image *image,
|
||||
const struct VkVideoProfileListInfoKHR *profile_list)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
for (unsigned i = 0; i < profile_list->profileCount; i++) {
|
||||
if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) {
|
||||
unsigned w_mb = DIV_ROUND_UP(image->vk.extent.width, ANV_MB_WIDTH);
|
||||
unsigned h_mb = DIV_ROUND_UP(image->vk.extent.height, ANV_MB_HEIGHT);
|
||||
size = w_mb * h_mb * 128;
|
||||
} else if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
|
||||
unsigned w_mb = DIV_ROUND_UP(image->vk.extent.width, 32);
|
||||
unsigned h_mb = DIV_ROUND_UP(image->vk.extent.height, 32);
|
||||
size = ALIGN(w_mb * h_mb, 2) << 6;
|
||||
} else if (profile_list->pProfiles[i].videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) {
|
||||
const uint32_t av1_mi_size_log2 = 2;
|
||||
uint32_t width = image->vk.extent.width;
|
||||
uint32_t height = image->vk.extent.height;
|
||||
uint32_t mi_cols = width >> av1_mi_size_log2;
|
||||
uint32_t mi_rows = height >> av1_mi_size_log2;
|
||||
uint32_t width_in_sb = align(mi_cols, (1 << av1_mi_size_log2)) >> av1_mi_size_log2;
|
||||
uint32_t height_in_sb = align(mi_rows, (1 << av1_mi_size_log2)) >> av1_mi_size_log2;
|
||||
uint32_t sb_total = width_in_sb * height_in_sb;
|
||||
|
||||
size = sb_total * 16;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user