diff --git a/src/gallium/drivers/radeonsi/si_vpe.c b/src/gallium/drivers/radeonsi/si_vpe.c index b8415bab315..ec4664aa105 100644 --- a/src/gallium/drivers/radeonsi/si_vpe.c +++ b/src/gallium/drivers/radeonsi/si_vpe.c @@ -493,7 +493,8 @@ si_vpe_set_plane_info(struct vpe_video_processor *vpeproc, const struct pipe_vpp_desc *process_properties, struct pipe_surface *surfaces, int which_surface, - struct vpe_surface_info *surface_info) + struct vpe_surface_info *surface_info, + bool is_geometric_scaling_round) { struct vpe_plane_address *plane_address = &surface_info->address; struct vpe_plane_size *plane_size = &surface_info->plane_size; @@ -501,9 +502,16 @@ si_vpe_set_plane_info(struct vpe_video_processor *vpeproc, struct si_texture *si_tex_1; enum pipe_format format; - if (which_surface == USE_SRC_SURFACE) - format = vpeproc->src_buffer->buffer_format; - else + /* When is_geometric_scaling_round is true, + * means that we are handling the 2nd-final rounds of geometric scaling. + * the fromat of source frame should be set to format of dst_buffer. + */ + if (which_surface == USE_SRC_SURFACE) { + if (is_geometric_scaling_round) + format = vpeproc->dst_buffer->buffer_format; + else + format = vpeproc->src_buffer->buffer_format; + } else format = vpeproc->dst_buffer->buffer_format; /* Trusted memory not supported now */ @@ -556,12 +564,13 @@ si_vpe_set_surface_info(struct vpe_video_processor *vpeproc, const struct pipe_vpp_desc *process_properties, struct pipe_surface *surfaces, int which_surface, - struct vpe_surface_info *surface_info) + struct vpe_surface_info *surface_info, + bool is_geometric_scaling_round) { assert(surface_info); /* Set up surface pitch, plane address, color space */ - if (VPE_STATUS_OK != si_vpe_set_plane_info(vpeproc, process_properties, surfaces, which_surface, surface_info)) + if (VPE_STATUS_OK != si_vpe_set_plane_info(vpeproc, process_properties, surfaces, which_surface, surface_info, is_geometric_scaling_round)) return VPE_STATUS_NOT_SUPPORTED; struct si_texture *tex = (struct si_texture *)surfaces[0].texture; @@ -673,7 +682,8 @@ si_vpe_init_polyphase_filter(struct vpe_video_processor *vpeproc, static void si_vpe_set_stream_in_param(struct vpe_video_processor *vpeproc, const struct pipe_vpp_desc *process_properties, - struct vpe_stream *stream) + struct vpe_stream *stream, + bool is_geometric_scaling_round) { struct vpe *vpe_handle = vpeproc->vpe_handle; struct vpe_scaling_info *scaling_info = &stream->scaling_info; @@ -749,7 +759,7 @@ si_vpe_set_stream_in_param(struct vpe_video_processor *vpeproc, stream->upper_luma_bound = 0.5; stream->flags.reserved = 0; - stream->flags.geometric_scaling = 0; + stream->flags.geometric_scaling = is_geometric_scaling_round; stream->flags.hdr_metadata = 0; /* TO-DO: support HDR10 Metadata */ @@ -1066,7 +1076,8 @@ static enum vpe_status si_vpe_processor_check_and_build_settins(struct vpe_video_processor *vpeproc, const struct pipe_vpp_desc *process_properties, struct pipe_surface *src_surfaces, - struct pipe_surface *dst_surfaces) + struct pipe_surface *dst_surfaces, + bool is_geometric_scaling_round) { enum vpe_status result = VPE_STATUS_OK; struct vpe *vpe_handle = vpeproc->vpe_handle; @@ -1085,7 +1096,8 @@ si_vpe_processor_check_and_build_settins(struct vpe_video_processor *vpeproc, process_properties, src_surfaces, USE_SRC_SURFACE, - &build_param->streams[0].surface_info); + &build_param->streams[0].surface_info, + is_geometric_scaling_round); if (VPE_STATUS_OK != result) { SIVPE_WARN(vpeproc->log_level, "Set Src surface failed with result: %d\n", result); return result; @@ -1095,14 +1107,16 @@ si_vpe_processor_check_and_build_settins(struct vpe_video_processor *vpeproc, si_vpe_set_stream_in_param( vpeproc, process_properties, - &build_param->streams[0]); + &build_param->streams[0], + is_geometric_scaling_round); /* Init output surface setting */ result = si_vpe_set_surface_info(vpeproc, process_properties, dst_surfaces, USE_DST_SURFACE, - &build_param->dst_surface); + &build_param->dst_surface, + is_geometric_scaling_round); if (VPE_STATUS_OK != result) { SIVPE_WARN(vpeproc->log_level, "Set Dst surface failed with result: %d\n", result); return result; @@ -1150,7 +1164,8 @@ static enum vpe_status si_vpe_construct_blt(struct vpe_video_processor *vpeproc, const struct pipe_vpp_desc *process_properties, struct pipe_surface *src_surfaces, - struct pipe_surface *dst_surfaces) + struct pipe_surface *dst_surfaces, + bool is_geometric_scaling_round) { enum vpe_status result = VPE_STATUS_OK; struct vpe *vpe_handle = vpeproc->vpe_handle; @@ -1166,7 +1181,7 @@ si_vpe_construct_blt(struct vpe_video_processor *vpeproc, /* Check if the blt operation is supported and build related settings. * Command settings will be is stored in vpeproc->vpe_build_param. */ - result = si_vpe_processor_check_and_build_settins(vpeproc, process_properties, src_surfaces, dst_surfaces); + result = si_vpe_processor_check_and_build_settins(vpeproc, process_properties, src_surfaces, dst_surfaces, is_geometric_scaling_round); if (VPE_STATUS_OK != result) { return result; } @@ -1344,7 +1359,7 @@ si_vpe_processor_process_frame(struct pipe_video_codec *codec, /* Perform general processing */ if ((scaling_ratio[0] <= VPE_MAX_GEOMETRIC_DOWNSCALE) && (scaling_ratio[1] <= VPE_MAX_GEOMETRIC_DOWNSCALE)) { - result = si_vpe_construct_blt(vpeproc, process_properties, vpeproc->src_surfaces, vpeproc->dst_surfaces); + result = si_vpe_construct_blt(vpeproc, process_properties, vpeproc->src_surfaces, vpeproc->dst_surfaces, false); return result == VPE_STATUS_OK ? 0 : 1; } @@ -1454,7 +1469,10 @@ si_vpe_processor_process_frame(struct pipe_video_codec *codec, src_surfaces = vpeproc->src_surfaces; dst_surfaces = tmp_geo_scaling_surf_1; - result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces); + /* Fitst Round, no need to change the format of input and output frames + * Set is_geometric_scaling_round = false + */ + result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces, false); if (VPE_STATUS_OK != result) { SIVPE_ERR("Failed in Geometric Scaling first blt command\n"); return result; @@ -1465,6 +1483,7 @@ si_vpe_processor_process_frame(struct pipe_video_codec *codec, /* Second to Final Round: * The source format should be reset to the format of DstFormat. * And other option should be cleaned. + * Set is_geometric_scaling_round = true to force the format of source format to the format of DstFormat. */ process_geoscl.orientation = PIPE_VIDEO_VPP_ORIENTATION_DEFAULT; process_geoscl.blend.global_alpha = 1.0f; @@ -1486,7 +1505,7 @@ si_vpe_processor_process_frame(struct pipe_video_codec *codec, src_surfaces = dst_surfaces; dst_surfaces = tmp_surfaces; - result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces); + result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces, true); if (VPE_STATUS_OK != result) { SIVPE_ERR("Failed in Geometric Scaling first blt command\n"); return result; @@ -1510,7 +1529,7 @@ si_vpe_processor_process_frame(struct pipe_video_codec *codec, src_surfaces = dst_surfaces; dst_surfaces = vpeproc->dst_surfaces; - result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces); + result = si_vpe_construct_blt(vpeproc, &process_geoscl, src_surfaces, dst_surfaces, true); if (VPE_STATUS_OK != result) { SIVPE_ERR("Failed in Geometric Scaling first blt command\n"); return result;