1 // SPDX-License-Identifier: MIT 2 // 3 // Copyright 2024 Advanced Micro Devices, Inc. 4 5 #include "dc_spl_translate.h" 6 #include "spl/dc_spl_types.h" 7 #include "dcn20/dcn20_dpp.h" 8 #include "dcn32/dcn32_dpp.h" 9 #include "dcn401/dcn401_dpp.h" 10 11 static struct spl_funcs dcn2_spl_funcs = { 12 .spl_calc_lb_num_partitions = dscl2_spl_calc_lb_num_partitions, 13 }; 14 static struct spl_funcs dcn32_spl_funcs = { 15 .spl_calc_lb_num_partitions = dscl32_spl_calc_lb_num_partitions, 16 }; 17 static struct spl_funcs dcn401_spl_funcs = { 18 .spl_calc_lb_num_partitions = dscl401_spl_calc_lb_num_partitions, 19 }; 20 static void populate_splrect_from_rect(struct spl_rect *spl_rect, const struct rect *rect) 21 { 22 spl_rect->x = rect->x; 23 spl_rect->y = rect->y; 24 spl_rect->width = rect->width; 25 spl_rect->height = rect->height; 26 } 27 static void populate_rect_from_splrect(struct rect *rect, const struct spl_rect *spl_rect) 28 { 29 rect->x = spl_rect->x; 30 rect->y = spl_rect->y; 31 rect->width = spl_rect->width; 32 rect->height = spl_rect->height; 33 } 34 static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality, 35 const struct scaling_taps *scaling_quality) 36 { 37 spl_scaling_quality->h_taps_c = scaling_quality->h_taps_c; 38 spl_scaling_quality->h_taps = scaling_quality->h_taps; 39 spl_scaling_quality->v_taps_c = scaling_quality->v_taps_c; 40 spl_scaling_quality->v_taps = scaling_quality->v_taps; 41 } 42 static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality, 43 const struct spl_taps *spl_scaling_quality) 44 { 45 scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c; 46 scaling_quality->h_taps = spl_scaling_quality->h_taps; 47 scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c; 48 scaling_quality->v_taps = spl_scaling_quality->v_taps; 49 } 50 static void populate_ratios_from_splratios(struct scaling_ratios *ratios, 51 const struct spl_ratios *spl_ratios) 52 { 53 ratios->horz = spl_ratios->horz; 54 ratios->vert = spl_ratios->vert; 55 ratios->horz_c = spl_ratios->horz_c; 56 ratios->vert_c = spl_ratios->vert_c; 57 } 58 static void populate_inits_from_splinits(struct scl_inits *inits, 59 const struct spl_inits *spl_inits) 60 { 61 inits->h = spl_inits->h; 62 inits->v = spl_inits->v; 63 inits->h_c = spl_inits->h_c; 64 inits->v_c = spl_inits->v_c; 65 } 66 /// @brief Translate SPL input parameters from pipe context 67 /// @param pipe_ctx 68 /// @param spl_in 69 void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_in *spl_in) 70 { 71 const struct dc_plane_state *plane_state = pipe_ctx->plane_state; 72 const struct dc_stream_state *stream = pipe_ctx->stream; 73 struct rect odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx); 74 75 // Assign the function to calculate the number of partitions in the line buffer 76 // This is used to determine the vtap support 77 switch (plane_state->ctx->dce_version) { 78 case DCN_VERSION_2_0: 79 spl_in->funcs = &dcn2_spl_funcs; 80 break; 81 case DCN_VERSION_3_2: 82 spl_in->funcs = &dcn32_spl_funcs; 83 break; 84 case DCN_VERSION_4_01: 85 spl_in->funcs = &dcn401_spl_funcs; 86 break; 87 default: 88 spl_in->funcs = &dcn2_spl_funcs; 89 } 90 // Make format field from spl_in point to plane_res scl_data format 91 spl_in->basic_in.format = (enum spl_pixel_format)pipe_ctx->plane_res.scl_data.format; 92 // Make view_format from basic_out point to view_format from stream 93 spl_in->basic_out.view_format = (enum spl_view_3d)stream->view_format; 94 // Populate spl input basic input clip rect from plane state clip rect 95 populate_splrect_from_rect(&spl_in->basic_in.clip_rect, &plane_state->clip_rect); 96 // Populate spl input basic out src rect from stream src rect 97 populate_splrect_from_rect(&spl_in->basic_out.src_rect, &stream->src); 98 // Populate spl input basic out dst rect from stream dst rect 99 populate_splrect_from_rect(&spl_in->basic_out.dst_rect, &stream->dst); 100 // Make spl input basic input info rotation field point to plane state rotation 101 spl_in->basic_in.rotation = (enum spl_rotation_angle)plane_state->rotation; 102 // Populate spl input basic input src rect from plane state src rect 103 populate_splrect_from_rect(&spl_in->basic_in.src_rect, &plane_state->src_rect); 104 // Populate spl input basic input dst rect from plane state dst rect 105 populate_splrect_from_rect(&spl_in->basic_in.dst_rect, &plane_state->dst_rect); 106 // Make spl input basic input info horiz mirror field point to plane state horz mirror 107 spl_in->basic_in.horizontal_mirror = plane_state->horizontal_mirror; 108 109 // Calculate horizontal splits and split index 110 spl_in->basic_in.mpc_combine_h = resource_get_mpc_slice_count(pipe_ctx); 111 112 if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE) 113 spl_in->basic_in.mpc_combine_v = 0; 114 else 115 spl_in->basic_in.mpc_combine_v = resource_get_mpc_slice_index(pipe_ctx); 116 117 populate_splrect_from_rect(&spl_in->basic_out.odm_slice_rect, &odm_slice_src); 118 spl_in->basic_out.odm_combine_factor = 0; 119 spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx); 120 // Make spl input basic out info output_size width point to stream h active 121 spl_in->basic_out.output_size.width = 122 stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right; 123 // Make spl input basic out info output_size height point to v active 124 spl_in->basic_out.output_size.height = 125 stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top; 126 spl_in->basic_out.max_downscale_src_width = 127 pipe_ctx->stream->ctx->dc->debug.max_downscale_src_width; 128 spl_in->basic_out.always_scale = pipe_ctx->stream->ctx->dc->debug.always_scale; 129 // Make spl input basic output info alpha_en field point to plane res scl_data lb_params alpha_en 130 spl_in->basic_out.alpha_en = pipe_ctx->plane_res.scl_data.lb_params.alpha_en; 131 // Make spl input basic input info scaling quality field point to plane state scaling_quality 132 populate_spltaps_from_taps(&spl_in->scaling_quality, &plane_state->scaling_quality); 133 // Translate edge adaptive scaler preference 134 spl_in->prefer_easf = pipe_ctx->stream->ctx->dc->config.prefer_easf; 135 spl_in->disable_easf = false; 136 if (pipe_ctx->stream->ctx->dc->debug.force_easf == 1) 137 spl_in->prefer_easf = false; 138 else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2) 139 spl_in->disable_easf = true; 140 /* Translate adaptive sharpening preference */ 141 if (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 0) { 142 spl_in->adaptive_sharpness.enable = (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 1) ? true : false; 143 if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 2) 144 spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW; 145 else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 3) 146 spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID; 147 else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness >= 4) 148 spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH; 149 } else { 150 spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en; 151 if (plane_state->sharpnessX1000 == 0) 152 spl_in->adaptive_sharpness.enable = false; 153 else if (plane_state->sharpnessX1000 < 999) 154 spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW; 155 else if (plane_state->sharpnessX1000 < 1999) 156 spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID; 157 else // Any other value is high sharpness 158 spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH; 159 } 160 // Translate linear light scaling preference 161 if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0) 162 spl_in->lls_pref = pipe_ctx->stream->ctx->dc->debug.force_lls; 163 else 164 spl_in->lls_pref = plane_state->linear_light_scaling; 165 /* Translate chroma subsampling offset ( cositing ) */ 166 if (pipe_ctx->stream->ctx->dc->debug.force_cositing) 167 spl_in->basic_in.cositing = pipe_ctx->stream->ctx->dc->debug.force_cositing - 1; 168 else 169 spl_in->basic_in.cositing = plane_state->cositing; 170 /* Translate transfer function */ 171 spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type; 172 spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf; 173 174 } 175 176 /// @brief Translate SPL output parameters to pipe context 177 /// @param pipe_ctx 178 /// @param spl_out 179 void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out) 180 { 181 // Make scaler data recout point to spl output field recout 182 populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->scl_data.recout); 183 // Make scaler data ratios point to spl output field ratios 184 populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->scl_data.ratios); 185 // Make scaler data viewport point to spl output field viewport 186 populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->scl_data.viewport); 187 // Make scaler data viewport_c point to spl output field viewport_c 188 populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->scl_data.viewport_c); 189 // Make scaler data taps point to spl output field scaling taps 190 populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->scl_data.taps); 191 // Make scaler data init point to spl output field init 192 populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->scl_data.inits); 193 } 194