radv/video: Support quantization map on VCN5
VCN5 needs to convert the input map image to internal format. Reviewed-by: Autumn Ashton <misyl@froggi.es> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37156>
This commit is contained in:
@@ -492,8 +492,12 @@ radv_physical_device_get_format_properties(struct radv_physical_device *pdev, Vk
|
||||
tiled |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
|
||||
}
|
||||
|
||||
if (pdev->video_encode_enabled && format == VK_FORMAT_R32_SINT) {
|
||||
linear |= VK_FORMAT_FEATURE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
if (pdev->video_encode_enabled) {
|
||||
const VkFormat map_format = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? VK_FORMAT_R16_SINT : VK_FORMAT_R32_SINT;
|
||||
if (format == map_format) {
|
||||
linear |= VK_FORMAT_FEATURE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
tiled |= VK_FORMAT_FEATURE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
}
|
||||
}
|
||||
|
||||
out_properties->linearTilingFeatures = linear;
|
||||
|
||||
@@ -649,7 +649,7 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
|
||||
.KHR_video_encode_av1 =
|
||||
(radv_video_encode_av1_supported(pdev) && VIDEO_CODEC_AV1ENC && pdev->video_encode_enabled),
|
||||
.KHR_video_encode_intra_refresh = pdev->video_encode_enabled,
|
||||
.KHR_video_encode_quantization_map = pdev->video_encode_enabled && pdev->info.vcn_ip_version < VCN_5_0_0,
|
||||
.KHR_video_encode_quantization_map = pdev->video_encode_enabled && radv_video_encode_qp_map_supported(pdev),
|
||||
.KHR_video_encode_queue = pdev->video_encode_enabled,
|
||||
.KHR_vulkan_memory_model = true,
|
||||
.KHR_workgroup_memory_explicit_layout = true,
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
static void set_reg(struct radv_cmd_buffer *cmd_buffer, unsigned reg, uint32_t val);
|
||||
|
||||
static inline bool
|
||||
bool
|
||||
radv_check_vcn_fw_version(const struct radv_physical_device *pdev, uint32_t dec, uint32_t enc, uint32_t rev)
|
||||
{
|
||||
return pdev->info.vcn_dec_version > dec || pdev->info.vcn_enc_minor_version > enc ||
|
||||
@@ -804,7 +804,7 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
uint32_t
|
||||
radv_video_get_qp_map_texel_size(VkVideoCodecOperationFlagBitsKHR codec)
|
||||
{
|
||||
switch (codec) {
|
||||
@@ -902,7 +902,7 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
||||
enc_caps->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
|
||||
|
||||
if (pdev->info.vcn_ip_version < VCN_5_0_0)
|
||||
if (radv_video_encode_qp_map_supported(pdev))
|
||||
enc_caps->flags |= VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
}
|
||||
if (intra_refresh_caps) {
|
||||
@@ -1254,7 +1254,7 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
|
||||
|
||||
qp_map_texel_size = profile_qp_map_texel_size;
|
||||
|
||||
profile_format = VK_FORMAT_R32_SINT;
|
||||
profile_format = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? VK_FORMAT_R16_SINT : VK_FORMAT_R32_SINT;
|
||||
} else {
|
||||
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
|
||||
profile_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
@@ -1468,6 +1468,9 @@ radv_BindVideoSessionMemoryKHR(VkDevice _device, VkVideoSessionKHR videoSession,
|
||||
case RADV_BIND_INTRA_ONLY:
|
||||
copy_bind(&vid->intra_only_dpb, &pBindSessionMemoryInfos[i]);
|
||||
break;
|
||||
case RADV_BIND_ENCODE_QP_MAP:
|
||||
copy_bind(&vid->qp_map, &pBindSessionMemoryInfos[i]);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
@@ -30,6 +30,7 @@ struct radv_cmd_stream;
|
||||
#define RADV_BIND_SESSION_CTX 0
|
||||
#define RADV_BIND_DECODER_CTX 1
|
||||
#define RADV_BIND_INTRA_ONLY 2
|
||||
#define RADV_BIND_ENCODE_QP_MAP 3
|
||||
#define RADV_BIND_ENCODE_AV1_CDF_STORE RADV_BIND_DECODER_CTX
|
||||
|
||||
struct radv_vid_mem {
|
||||
@@ -51,6 +52,7 @@ struct radv_video_session {
|
||||
struct radv_vid_mem ctx;
|
||||
|
||||
struct radv_vid_mem intra_only_dpb;
|
||||
struct radv_vid_mem qp_map;
|
||||
|
||||
unsigned dbg_frame_cnt;
|
||||
rvcn_enc_session_init_t enc_session;
|
||||
@@ -93,5 +95,8 @@ void radv_video_get_enc_dpb_image(struct radv_device *device, const struct VkVid
|
||||
struct radv_image *image, struct radv_image_create_info *create_info);
|
||||
bool radv_video_decode_vp9_supported(const struct radv_physical_device *pdev);
|
||||
bool radv_video_encode_av1_supported(const struct radv_physical_device *pdev);
|
||||
bool radv_video_encode_qp_map_supported(const struct radv_physical_device *pdev);
|
||||
uint32_t radv_video_get_qp_map_texel_size(VkVideoCodecOperationFlagBitsKHR codec);
|
||||
bool radv_check_vcn_fw_version(const struct radv_physical_device *pdev, uint32_t dec, uint32_t enc, uint32_t rev);
|
||||
|
||||
#endif /* RADV_VIDEO_H */
|
||||
|
||||
@@ -1707,6 +1707,52 @@ radv_enc_intra_refresh(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeIn
|
||||
RADEON_ENC_END();
|
||||
}
|
||||
|
||||
static void
|
||||
radv_enc_qp_map_input(struct radv_cmd_buffer *cmd_buffer, const struct VkVideoEncodeInfoKHR *enc_info)
|
||||
{
|
||||
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
|
||||
const struct VkVideoEncodeQuantizationMapInfoKHR *quantization_map_info =
|
||||
vk_find_struct_const(enc_info->pNext, VIDEO_ENCODE_QUANTIZATION_MAP_INFO_KHR);
|
||||
const struct radv_image_view *qp_map_view =
|
||||
quantization_map_info ? radv_image_view_from_handle(quantization_map_info->quantizationMap) : NULL;
|
||||
const struct radv_image *qp_map = qp_map_view ? qp_map_view->image : NULL;
|
||||
struct radv_cmd_stream *cs = cmd_buffer->cs;
|
||||
|
||||
if (!(enc_info->flags & VK_VIDEO_ENCODE_WITH_QUANTIZATION_DELTA_MAP_BIT_KHR) || !qp_map)
|
||||
return;
|
||||
|
||||
const uint64_t va_in = qp_map->bindings[0].addr;
|
||||
radv_cs_add_buffer(device->ws, cs->b, qp_map->bindings[0].bo);
|
||||
|
||||
const uint64_t va_out =
|
||||
radv_buffer_get_va(cmd_buffer->video.vid->qp_map.mem->bo) + cmd_buffer->video.vid->qp_map.offset;
|
||||
radv_cs_add_buffer(device->ws, cmd_buffer->cs->b, cmd_buffer->video.vid->qp_map.mem->bo);
|
||||
|
||||
radv_vcn_sq_header(cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_COMMON, false);
|
||||
|
||||
struct rvcn_cmn_engine_ib_package *ib_header = (struct rvcn_cmn_engine_ib_package *)&(cs->b->buf[cs->b->cdw]);
|
||||
ib_header->package_size =
|
||||
sizeof(struct rvcn_cmn_engine_ib_package) + sizeof(struct rvcn_cmn_engine_op_resolveinputparamlayout);
|
||||
cs->b->cdw++;
|
||||
ib_header->package_type = RADEON_VCN_IB_COMMON_OP_RESOLVEINPUTPARAMLAYOUT;
|
||||
cs->b->cdw++;
|
||||
|
||||
struct rvcn_cmn_engine_op_resolveinputparamlayout *resolve_input =
|
||||
(struct rvcn_cmn_engine_op_resolveinputparamlayout *)&(cs->b->buf[cs->b->cdw]);
|
||||
resolve_input->map_type = RADEON_VCN_RESOLVE_INPUT_PARAM_LAYOUT_TYPE_QPMAP_INT16;
|
||||
resolve_input->map_width = qp_map->vk.extent.width;
|
||||
resolve_input->map_height = qp_map->vk.extent.height;
|
||||
resolve_input->input_buffer_address_lo = va_in & 0xffffffff;
|
||||
resolve_input->input_buffer_address_hi = va_in >> 32;
|
||||
resolve_input->input_buffer_pitch = qp_map->planes[0].surface.u.gfx9.surf_pitch;
|
||||
resolve_input->input_buffer_swizzle_mode = qp_map->planes[0].surface.u.gfx9.swizzle_mode;
|
||||
resolve_input->output_buffer_address_lo = va_out & 0xffffffff;
|
||||
resolve_input->output_buffer_address_hi = va_out >> 32;
|
||||
|
||||
cs->b->cdw += sizeof(*resolve_input) / 4;
|
||||
radv_vcn_sq_tail(cs, &cmd_buffer->video.sq);
|
||||
}
|
||||
|
||||
static void
|
||||
radv_enc_qp_map(struct radv_cmd_buffer *cmd_buffer, const struct VkVideoEncodeInfoKHR *enc_info)
|
||||
{
|
||||
@@ -1720,18 +1766,24 @@ radv_enc_qp_map(struct radv_cmd_buffer *cmd_buffer, const struct VkVideoEncodeIn
|
||||
|
||||
RADEON_ENC_BEGIN(pdev->vcn_enc_cmds.enc_qp_map);
|
||||
if (enc_info->flags & VK_VIDEO_ENCODE_WITH_QUANTIZATION_DELTA_MAP_BIT_KHR && qp_map) {
|
||||
/* VCN < 5 uses a 32-bit signed integer for QP maps. */
|
||||
assert(qp_map->vk.format == VK_FORMAT_R32_SINT);
|
||||
|
||||
const uint32_t qp_map_type = cmd_buffer->video.vid->enc_rate_control_method == RENCODE_RATE_CONTROL_METHOD_NONE
|
||||
? RENCODE_QP_MAP_TYPE_DELTA
|
||||
: RENCODE_QP_MAP_TYPE_MAP_PA;
|
||||
radv_cs_add_buffer(device->ws, cmd_buffer->cs->b, qp_map->bindings[0].bo);
|
||||
const uint64_t va = qp_map->bindings[0].addr;
|
||||
RADEON_ENC_CS(qp_map_type);
|
||||
RADEON_ENC_CS(va >> 32);
|
||||
RADEON_ENC_CS(va & 0xffffffff);
|
||||
RADEON_ENC_CS(qp_map->planes[0].surface.u.gfx9.surf_pitch);
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) {
|
||||
uint64_t va = radv_buffer_get_va(cmd_buffer->video.vid->qp_map.mem->bo);
|
||||
va += cmd_buffer->video.vid->qp_map.offset;
|
||||
RADEON_ENC_CS(RENCODE_QP_MAP_TYPE_DELTA);
|
||||
RADEON_ENC_CS(va >> 32);
|
||||
RADEON_ENC_CS(va & 0xffffffff);
|
||||
RADEON_ENC_CS(0);
|
||||
} else {
|
||||
const uint32_t qp_map_type = cmd_buffer->video.vid->enc_rate_control_method == RENCODE_RATE_CONTROL_METHOD_NONE
|
||||
? RENCODE_QP_MAP_TYPE_DELTA
|
||||
: RENCODE_QP_MAP_TYPE_MAP_PA;
|
||||
radv_cs_add_buffer(device->ws, cmd_buffer->cs->b, qp_map->bindings[0].bo);
|
||||
const uint64_t va = qp_map->bindings[0].addr;
|
||||
RADEON_ENC_CS(qp_map_type);
|
||||
RADEON_ENC_CS(va >> 32);
|
||||
RADEON_ENC_CS(va & 0xffffffff);
|
||||
RADEON_ENC_CS(qp_map->planes[0].surface.u.gfx9.surf_pitch);
|
||||
}
|
||||
} else {
|
||||
RADEON_ENC_CS(RENCODE_QP_MAP_TYPE_NONE);
|
||||
RADEON_ENC_CS(0);
|
||||
@@ -2732,6 +2784,9 @@ radv_vcn_encode_video(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInf
|
||||
|
||||
radeon_check_space(device->ws, cs->b, 1600);
|
||||
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5)
|
||||
radv_enc_qp_map_input(cmd_buffer, enc_info);
|
||||
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_4)
|
||||
radv_vcn_sq_header(cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_ENCODE, false);
|
||||
|
||||
@@ -3304,6 +3359,22 @@ radv_video_get_encode_session_memory_requirements(struct radv_device *device, st
|
||||
m->memoryRequirements.memoryTypeBits |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (vid->vk.flags & VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR &&
|
||||
pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) {
|
||||
const uint32_t texel_size = radv_video_get_qp_map_texel_size(vid->vk.op);
|
||||
const uint32_t map_width = DIV_ROUND_UP(vid->vk.max_coded.width, texel_size);
|
||||
const uint32_t map_height = DIV_ROUND_UP(vid->vk.max_coded.height, texel_size);
|
||||
|
||||
vk_outarray_append_typed(VkVideoSessionMemoryRequirementsKHR, &out, m)
|
||||
{
|
||||
m->memoryBindIndex = RADV_BIND_ENCODE_QP_MAP;
|
||||
m->memoryRequirements.size = map_width * map_height * sizeof(int16_t);
|
||||
m->memoryRequirements.alignment = 0;
|
||||
m->memoryRequirements.memoryTypeBits = memory_type_bits;
|
||||
}
|
||||
}
|
||||
|
||||
return vk_outarray_status(&out);
|
||||
}
|
||||
|
||||
@@ -3365,3 +3436,11 @@ radv_video_encode_av1_supported(const struct radv_physical_device *pdev)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
radv_video_encode_qp_map_supported(const struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 9, 9, 28);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user