radv/video: enable video encoding behind perftest flag

This probes the vcn firmware version to make sure it can support
the encode extensions properly, then uses the perf test flag if so.

Acked-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25900>
This commit is contained in:
Dave Airlie
2023-10-25 16:51:41 +10:00
parent 967e4e09de
commit 05cd42417f
9 changed files with 91 additions and 3 deletions

View File

@@ -78,6 +78,7 @@ enum {
RADV_PERFTEST_TRANSFER_QUEUE = 1u << 13,
RADV_PERFTEST_NIR_CACHE = 1u << 14,
RADV_PERFTEST_RT_WAVE_32 = 1u << 15,
RADV_PERFTEST_VIDEO_ENCODE = 1u << 16,
};
bool radv_init_trace(struct radv_device *device);

View File

@@ -733,6 +733,12 @@ radv_physical_device_get_format_properties(struct radv_physical_device *pdev, Vk
tiling |= VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR | VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR;
}
if (pdev->video_encode_enabled) {
if (format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
format == VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)
tiling |= VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR | VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR;
}
if (multiplanar)
tiling |= VK_FORMAT_FEATURE_2_DISJOINT_BIT;

View File

@@ -46,6 +46,9 @@ radv_choose_tiling(struct radv_device *device, const VkImageCreateInfo *pCreateI
if (pCreateInfo->usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
return RADEON_SURF_MODE_LINEAR_ALIGNED;
if (pCreateInfo->usage & (VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR))
return RADEON_SURF_MODE_LINEAR_ALIGNED;
/* MSAA resources must be 2D tiled. */
if (pCreateInfo->samples > 1)
return RADEON_SURF_MODE_2D;
@@ -1107,7 +1110,9 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in
* 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)) {
if (image->vk.usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)) {
assert(profile_list);
uint32_t width_align, height_align;
radv_video_get_profile_alignments(pdev, profile_list, &width_align, &height_align);

View File

@@ -98,6 +98,7 @@ static const struct debug_control radv_perftest_options[] = {{"localbos", RADV_P
{"transfer_queue", RADV_PERFTEST_TRANSFER_QUEUE},
{"nircache", RADV_PERFTEST_NIR_CACHE},
{"rtwave32", RADV_PERFTEST_RT_WAVE_32},
{"video_encode", RADV_PERFTEST_VIDEO_ENCODE},
{NULL, 0}};
const char *

View File

@@ -250,6 +250,13 @@ radv_physical_device_init_queue_table(struct radv_physical_device *pdev)
idx++;
}
if (pdev->video_encode_enabled) {
if (pdev->info.ip[AMD_IP_VCN_ENC].num_queues > 0) {
pdev->vk_queue_to_radv[idx] = RADV_QUEUE_VIDEO_ENC;
idx++;
}
}
if (radv_sparse_queue_enabled(pdev)) {
pdev->vk_queue_to_radv[idx] = RADV_QUEUE_SPARSE;
idx++;
@@ -568,6 +575,9 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
.KHR_video_decode_queue = !!(instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE),
.KHR_video_decode_h264 = VIDEO_CODEC_H264DEC && !!(instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE),
.KHR_video_decode_h265 = VIDEO_CODEC_H265DEC && !!(instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE),
.KHR_video_encode_h264 = VIDEO_CODEC_H264ENC && pdev->video_encode_enabled,
.KHR_video_encode_h265 = VIDEO_CODEC_H265ENC && pdev->video_encode_enabled,
.KHR_video_encode_queue = pdev->video_encode_enabled,
.KHR_vulkan_memory_model = true,
.KHR_workgroup_memory_explicit_layout = true,
.KHR_zero_initialize_workgroup_memory = true,
@@ -2069,6 +2079,8 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
pdev->rt_wave_size = 64;
}
radv_probe_video_encode(pdev);
pdev->max_shared_size = pdev->info.gfx_level >= GFX7 ? 65536 : 32768;
radv_physical_device_init_mem_types(pdev);
@@ -2123,6 +2135,7 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
ac_print_gpu_info(&pdev->info, stdout);
radv_init_physical_device_decoder(pdev);
radv_init_physical_device_encoder(pdev);
radv_physical_device_init_queue_table(pdev);
@@ -2232,6 +2245,11 @@ radv_get_physical_device_queue_family_properties(struct radv_physical_device *pd
num_queue_families++;
}
if (pdev->video_encode_enabled) {
if (pdev->info.ip[AMD_IP_VCN_ENC].num_queues > 0)
num_queue_families++;
}
if (radv_sparse_queue_enabled(pdev)) {
num_queue_families++;
}
@@ -2299,6 +2317,20 @@ radv_get_physical_device_queue_family_properties(struct radv_physical_device *pd
}
}
if (pdev->video_encode_enabled) {
if (pdev->info.ip[AMD_IP_VCN_ENC].num_queues > 0) {
if (*pCount > idx) {
*pQueueFamilyProperties[idx] = (VkQueueFamilyProperties){
.queueFlags = VK_QUEUE_VIDEO_ENCODE_BIT_KHR,
.queueCount = pdev->info.ip[AMD_IP_VCN_ENC].num_queues,
.timestampValidBits = 64,
.minImageTransferGranularity = (VkExtent3D){1, 1, 1},
};
idx++;
}
}
}
if (radv_sparse_queue_enabled(pdev)) {
if (*pCount > idx) {
*pQueueFamilyProperties[idx] = (VkQueueFamilyProperties){
@@ -2333,10 +2365,10 @@ radv_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, ui
VkQueueFamilyProperties *properties[] = {
&pQueueFamilyProperties[0].queueFamilyProperties, &pQueueFamilyProperties[1].queueFamilyProperties,
&pQueueFamilyProperties[2].queueFamilyProperties, &pQueueFamilyProperties[3].queueFamilyProperties,
&pQueueFamilyProperties[4].queueFamilyProperties,
&pQueueFamilyProperties[4].queueFamilyProperties, &pQueueFamilyProperties[5].queueFamilyProperties,
};
radv_get_physical_device_queue_family_properties(pdev, pCount, properties);
assert(*pCount <= 5);
assert(*pCount <= 6);
for (uint32_t i = 0; i < *pCount; i++) {
vk_foreach_struct (ext, pQueueFamilyProperties[i].pNext) {
@@ -2365,6 +2397,12 @@ radv_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, ui
pdev->info.vcn_ip_version != VCN_3_0_33)
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR;
}
if (pQueueFamilyProperties[i].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) {
if (VIDEO_CODEC_H264ENC)
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR;
if (VIDEO_CODEC_H265ENC)
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR;
}
break;
}
default:

View File

@@ -181,6 +181,7 @@ struct radv_physical_device {
rvcn_enc_cmd_t vcn_enc_cmds;
enum radv_video_enc_hw_ver enc_hw_ver;
uint32_t encoder_interface_version;
bool video_encode_enabled;
struct radv_physical_device_cache_key cache_key;
};

View File

@@ -783,6 +783,8 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
p->imageType = VK_IMAGE_TYPE_2D;
p->imageTiling = VK_IMAGE_TILING_OPTIMAL;
p->imageUsageFlags = pVideoFormatInfo->imageUsage;
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR)
p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
}
if (pVideoFormatInfo->imageUsage & (VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
@@ -796,6 +798,8 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
p->imageType = VK_IMAGE_TYPE_2D;
p->imageTiling = VK_IMAGE_TILING_OPTIMAL;
p->imageUsageFlags = pVideoFormatInfo->imageUsage;
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR)
p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
}
}

View File

@@ -72,6 +72,7 @@ void radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, bool e
void radv_vcn_sq_tail(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq);
void radv_init_physical_device_encoder(struct radv_physical_device *pdevice);
void radv_probe_video_encode(struct radv_physical_device *pdev);
void radv_video_enc_begin_coding(struct radv_cmd_buffer *cmd_buffer);
void radv_video_enc_end_coding(struct radv_cmd_buffer *cmd_buffer);
void radv_video_enc_control_video_coding(struct radv_cmd_buffer *cmd_buffer,

View File

@@ -27,6 +27,7 @@
**************************************************************************/
#include "radv_buffer.h"
#include "radv_cs.h"
#include "radv_debug.h"
#include "radv_device_memory.h"
#include "radv_entrypoints.h"
#include "radv_image_view.h"
@@ -105,6 +106,36 @@
#define RENCODE_FW_INTERFACE_MAJOR_VERSION 1
#define RENCODE_FW_INTERFACE_MINOR_VERSION 9
void
radv_probe_video_encode(struct radv_physical_device *pdev)
{
pdev->video_encode_enabled = false;
if (pdev->info.vcn_ip_version >= VCN_4_0_0) {
if (pdev->info.vcn_enc_major_version != RENCODE_V4_FW_INTERFACE_MAJOR_VERSION)
return;
if (pdev->info.vcn_enc_minor_version < RENCODE_V4_FW_INTERFACE_MINOR_VERSION)
return;
} else if (pdev->info.vcn_ip_version >= VCN_3_0_0) {
if (pdev->info.vcn_enc_major_version != RENCODE_V3_FW_INTERFACE_MAJOR_VERSION)
return;
if (pdev->info.vcn_enc_minor_version < RENCODE_V3_FW_INTERFACE_MINOR_VERSION)
return;
} else if (pdev->info.vcn_ip_version >= VCN_2_0_0) {
if (pdev->info.vcn_enc_major_version != RENCODE_V2_FW_INTERFACE_MAJOR_VERSION)
return;
if (pdev->info.vcn_enc_minor_version < RENCODE_V2_FW_INTERFACE_MINOR_VERSION)
return;
} else {
if (pdev->info.vcn_enc_major_version != RENCODE_FW_INTERFACE_MAJOR_VERSION)
return;
if (pdev->info.vcn_enc_minor_version < RENCODE_FW_INTERFACE_MINOR_VERSION)
return;
}
struct radv_instance *instance = radv_physical_device_instance(pdev);
pdev->video_encode_enabled = !!(instance->perftest_flags & RADV_PERFTEST_VIDEO_ENCODE);
}
void
radv_init_physical_device_encoder(struct radv_physical_device *pdev)
{