From 43c04ab2b436ae330a2ad634a4881e53bb9ae49b Mon Sep 17 00:00:00 2001 From: Leo Liu Date: Sat, 5 Jun 2021 18:46:58 -0400 Subject: [PATCH] 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 Reviewed-by: James Zhu Part-of: --- src/amd/common/ac_gpu_info.c | 17 +++++++---- src/amd/common/ac_gpu_info.h | 11 +++++-- src/gallium/drivers/r600/r600_pipe.c | 2 +- src/gallium/drivers/r600/r600_pipe_common.c | 4 +-- src/gallium/drivers/radeon/radeon_uvd_enc.c | 2 +- src/gallium/drivers/radeonsi/si_get.c | 30 ++++++++++++++----- src/gallium/drivers/radeonsi/si_pipe.c | 4 ++- .../winsys/radeon/drm/radeon_drm_winsys.c | 4 +-- 8 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 3539a5e5b8e..fc8ee3c5fc0 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -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); diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h index 65a4d1adf9e..68a4bf182da 100644 --- a/src/amd/common/ac_gpu_info.h +++ b/src/amd/common/ac_gpu_info.h @@ -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; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 8e7258e23d7..0deb6981145 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -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 { diff --git a/src/gallium/drivers/r600/r600_pipe_common.c b/src/gallium/drivers/r600/r600_pipe_common.c index a23cf2acf48..a6af8149dc1 100644 --- a/src/gallium/drivers/r600/r600_pipe_common.c +++ b/src/gallium/drivers/r600/r600_pipe_common.c @@ -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); diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc.c b/src/gallium/drivers/radeon/radeon_uvd_enc.c index 9a26c4ddd03..94287b49a10 100644 --- a/src/gallium/drivers/radeon/radeon_uvd_enc.c +++ b/src/gallium/drivers/radeon/radeon_uvd_enc.c @@ -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); } diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index a2d3fc3ebe4..6e1b8028450 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -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; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 6845b0504c0..e4943add9ad 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -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) diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 08ee7e7e5cf..d06394e0b0b 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -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; }