radeonsi: separate video hw info based on HW engine individually

This removes previous "has_hw_decode" and "uvd_enc_supported" and
makes information more accuate for cases where HW decode, HW encode,
and HW JPEG decode might partially available.

Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: James Zhu <James.Zhu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11201>
This commit is contained in:
Leo Liu
2021-06-05 18:46:58 -04:00
parent 8ddba3b5ea
commit 43c04ab2b4
8 changed files with 53 additions and 21 deletions

View File

@@ -687,11 +687,14 @@ bool ac_query_gpu_info(int fd, void *dev_p, struct radeon_info *info,
info->max_tcc_blocks = device_info.num_tcc_blocks;
info->max_se = amdinfo->num_shader_engines;
info->max_sa_per_se = amdinfo->num_shader_arrays_per_engine;
info->has_hw_decode = (uvd.available_rings != 0) || (vcn_dec.available_rings != 0) ||
(vcn_jpeg.available_rings != 0);
info->uvd_fw_version = uvd.available_rings ? uvd_version : 0;
info->vce_fw_version = vce.available_rings ? vce_version : 0;
info->uvd_enc_supported = uvd_enc.available_rings ? true : false;
info->has_video_hw.uvd_decode = uvd.available_rings != 0;
info->has_video_hw.vcn_decode = vcn_dec.available_rings != 0;
info->has_video_hw.jpeg_decode = vcn_jpeg.available_rings != 0;
info->has_video_hw.vce_encode = vce.available_rings != 0;
info->has_video_hw.uvd_encode = uvd_enc.available_rings != 0;
info->has_video_hw.vcn_encode = vcn_enc.available_rings != 0;
info->has_userptr = true;
info->has_syncobj = has_syncobj(fd);
info->has_timeline_syncobj = has_timeline_syncobj(fd);
@@ -1194,8 +1197,12 @@ void ac_print_gpu_info(struct radeon_info *info, FILE *f)
fprintf(f, " ce_fw_feature = %i\n", info->ce_fw_feature);
fprintf(f, "Multimedia info:\n");
fprintf(f, " has_hw_decode = %u\n", info->has_hw_decode);
fprintf(f, " uvd_enc_supported = %u\n", info->uvd_enc_supported);
fprintf(f, " uvd_decode = %u\n", info->has_video_hw.uvd_decode);
fprintf(f, " vcn_decode = %u\n", info->has_video_hw.vcn_decode);
fprintf(f, " jpeg_decode = %u\n", info->has_video_hw.jpeg_decode);
fprintf(f, " vce_encode = %u\n", info->has_video_hw.vce_encode);
fprintf(f, " uvd_encode = %u\n", info->has_video_hw.uvd_encode);
fprintf(f, " vcn_encode = %u\n", info->has_video_hw.vcn_encode);
fprintf(f, " uvd_fw_version = %u\n", info->uvd_fw_version);
fprintf(f, " vce_fw_version = %u\n", info->vce_fw_version);
fprintf(f, " vce_harvest_config = %i\n", info->vce_harvest_config);

View File

@@ -133,8 +133,15 @@ struct radeon_info {
uint32_t ce_fw_feature;
/* Multimedia info. */
bool has_hw_decode;
bool uvd_enc_supported;
struct {
bool uvd_decode;
bool vcn_decode;
bool jpeg_decode;
bool vce_encode;
bool uvd_encode;
bool vcn_encode;
} has_video_hw;
uint32_t uvd_fw_version;
uint32_t vce_fw_version;
uint32_t vce_harvest_config;

View File

@@ -158,7 +158,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen,
r600_init_blit_functions(rctx);
if (rscreen->b.info.has_hw_decode) {
if (rscreen->b.info.has_video_hw.uvd_decode) {
rctx->b.b.create_video_codec = r600_uvd_create_decoder;
rctx->b.b.create_video_buffer = r600_video_buffer_create;
} else {

View File

@@ -1239,7 +1239,7 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
rscreen->b.resource_from_user_memory = r600_buffer_from_user_memory;
rscreen->b.query_memory_info = r600_query_memory_info;
if (rscreen->info.has_hw_decode) {
if (rscreen->info.has_video_hw.uvd_decode) {
rscreen->b.get_video_param = rvid_get_video_param;
rscreen->b.is_video_format_supported = rvid_is_format_supported;
} else {
@@ -1287,7 +1287,7 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
printf("has_dedicated_vram = %u\n", rscreen->info.has_dedicated_vram);
printf("r600_has_virtual_memory = %i\n", rscreen->info.r600_has_virtual_memory);
printf("gfx_ib_pad_with_type2 = %i\n", rscreen->info.gfx_ib_pad_with_type2);
printf("has_hw_decode = %u\n", rscreen->info.has_hw_decode);
printf("uvd_decode = %u\n", rscreen->info.has_video_hw.uvd_decode);
printf("num_rings[RING_DMA] = %i\n", rscreen->info.num_rings[RING_DMA]);
printf("num_rings[RING_COMPUTE] = %u\n", rscreen->info.num_rings[RING_COMPUTE]);
printf("uvd_fw_version = %u\n", rscreen->info.uvd_fw_version);

View File

@@ -351,5 +351,5 @@ error:
bool si_radeon_uvd_enc_supported(struct si_screen *sscreen)
{
return (sscreen->info.uvd_enc_supported);
return (sscreen->info.has_video_hw.uvd_encode);
}

View File

@@ -481,9 +481,9 @@ static const char *si_get_name(struct pipe_screen *pscreen)
return sscreen->renderer_string;
}
static int si_get_video_param_no_decode(struct pipe_screen *screen, enum pipe_video_profile profile,
enum pipe_video_entrypoint entrypoint,
enum pipe_video_cap param)
static int si_get_video_param_no_video_hw(struct pipe_screen *screen, enum pipe_video_profile profile,
enum pipe_video_entrypoint entrypoint,
enum pipe_video_cap param)
{
switch (param) {
case PIPE_VIDEO_CAP_SUPPORTED:
@@ -515,6 +515,11 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
enum pipe_video_format codec = u_reduce_video_profile(profile);
if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
if (!(sscreen->info.has_video_hw.vce_encode ||
sscreen->info.has_video_hw.uvd_encode ||
sscreen->info.has_video_hw.vcn_encode))
return 0;
switch (param) {
case PIPE_VIDEO_CAP_SUPPORTED:
return (
@@ -560,6 +565,11 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
if (codec < PIPE_VIDEO_FORMAT_MPEG4_AVC &&
sscreen->info.family >= CHIP_BEIGE_GOBY)
return false;
if (codec != PIPE_VIDEO_FORMAT_JPEG &&
!(sscreen->info.has_video_hw.uvd_decode ||
sscreen->info.has_video_hw.vcn_decode))
return false;
switch (codec) {
case PIPE_VIDEO_FORMAT_MPEG12:
return profile != PIPE_VIDEO_PROFILE_MPEG1;
@@ -583,8 +593,12 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
return profile == PIPE_VIDEO_PROFILE_HEVC_MAIN;
return false;
case PIPE_VIDEO_FORMAT_JPEG:
if (sscreen->info.family >= CHIP_RAVEN)
return true;
if (sscreen->info.family >= CHIP_RAVEN) {
if (!sscreen->info.has_video_hw.jpeg_decode)
return false;
else
return true;
}
if (sscreen->info.family < CHIP_CARRIZO || sscreen->info.family >= CHIP_VEGA10)
return false;
if (!(sscreen->info.is_amdgpu && sscreen->info.drm_minor >= 19)) {
@@ -955,11 +969,13 @@ void si_init_screen_get_functions(struct si_screen *sscreen)
sscreen->b.query_memory_info = si_query_memory_info;
sscreen->b.get_disk_shader_cache = si_get_disk_shader_cache;
if (sscreen->info.has_hw_decode) {
if (sscreen->info.has_video_hw.uvd_decode || sscreen->info.has_video_hw.vcn_decode ||
sscreen->info.has_video_hw.jpeg_decode || sscreen->info.has_video_hw.vce_encode ||
sscreen->info.has_video_hw.uvd_encode || sscreen->info.has_video_hw.vcn_encode) {
sscreen->b.get_video_param = si_get_video_param;
sscreen->b.is_video_format_supported = si_vid_is_format_supported;
} else {
sscreen->b.get_video_param = si_get_video_param_no_decode;
sscreen->b.get_video_param = si_get_video_param_no_video_hw;
sscreen->b.is_video_format_supported = vl_video_buffer_is_format_supported;
}

View File

@@ -603,7 +603,9 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign
sctx->sample_mask = 0xffff;
/* Initialize multimedia functions. */
if (sscreen->info.has_hw_decode) {
if (sscreen->info.has_video_hw.uvd_decode || sscreen->info.has_video_hw.vcn_decode ||
sscreen->info.has_video_hw.jpeg_decode || sscreen->info.has_video_hw.vce_encode ||
sscreen->info.has_video_hw.uvd_encode || sscreen->info.has_video_hw.vcn_encode) {
sctx->b.create_video_codec = si_uvd_create_decoder;
sctx->b.create_video_buffer = si_video_buffer_create;
if (screen->resource_create_with_modifiers)

View File

@@ -314,13 +314,13 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
}
/* Check for UVD and VCE */
ws->info.has_hw_decode = false;
ws->info.has_video_hw.uvd_decode = false;
ws->info.vce_fw_version = 0x00000000;
if (ws->info.drm_minor >= 32) {
uint32_t value = RADEON_CS_RING_UVD;
if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
"UVD Ring working", &value)) {
ws->info.has_hw_decode = value;
ws->info.has_video_hw.uvd_decode = value;
ws->info.num_rings[RING_UVD] = 1;
}