1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4
5 #include "spl_debug.h"
6 #include "dc_spl_filters.h"
7 #include "dc_spl_isharp_filters.h"
8
9 //========================================
10 // Delta Gain 1DLUT
11 // LUT content is packed as 4-bytes into one DWORD/entry
12 // A_start = 0.000000
13 // A_end = 10.000000
14 // A_gain = 3.000000
15 // B_start = 11.000000
16 // B_end = 127.000000
17 // C_start = 40.000000
18 // C_end = 127.000000
19 //========================================
20 static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = {
21 0x03010000,
22 0x0F0B0805,
23 0x211E1813,
24 0x2B292624,
25 0x3533302E,
26 0x3E3C3A37,
27 0x46444240,
28 0x4D4B4A48,
29 0x5352504F,
30 0x59575655,
31 0x5D5C5B5A,
32 0x61605F5E,
33 0x64646362,
34 0x66666565,
35 0x68686767,
36 0x68686868,
37 0x68686868,
38 0x67676868,
39 0x65656666,
40 0x62636464,
41 0x5E5F6061,
42 0x5A5B5C5D,
43 0x55565759,
44 0x4F505253,
45 0x484A4B4D,
46 0x40424446,
47 0x373A3C3E,
48 0x2E303335,
49 0x2426292B,
50 0x191B1E21,
51 0x0D101316,
52 0x0003060A,
53 };
54
55 // Blur and scale coefficients
56 //========================================================
57 // <using> gen_BlurScale_coeffs.m
58 // <date> 25-Apr-2022
59 // <num_taps> 4
60 // <num_phases> 64
61 // <CoefType> Blur & Scale LPF
62 // <CoefQuant> S1.10
63 //========================================================
64 static const uint16_t filter_isharp_bs_4tap_in_6_64p[198] = {
65 0x0000, 0x00E5, 0x0237, 0x00E4, 0x0000, 0x0000,
66 0x0000, 0x00DE, 0x0237, 0x00EB, 0x0000, 0x0000,
67 0x0000, 0x00D7, 0x0236, 0x00F2, 0x0001, 0x0000,
68 0x0000, 0x00D0, 0x0235, 0x00FA, 0x0001, 0x0000,
69 0x0000, 0x00C9, 0x0234, 0x0101, 0x0002, 0x0000,
70 0x0000, 0x00C2, 0x0233, 0x0108, 0x0003, 0x0000,
71 0x0000, 0x00BB, 0x0232, 0x0110, 0x0003, 0x0000,
72 0x0000, 0x00B5, 0x0230, 0x0117, 0x0004, 0x0000,
73 0x0000, 0x00AE, 0x022E, 0x011F, 0x0005, 0x0000,
74 0x0000, 0x00A8, 0x022C, 0x0126, 0x0006, 0x0000,
75 0x0000, 0x00A2, 0x022A, 0x012D, 0x0007, 0x0000,
76 0x0000, 0x009C, 0x0228, 0x0134, 0x0008, 0x0000,
77 0x0000, 0x0096, 0x0225, 0x013C, 0x0009, 0x0000,
78 0x0000, 0x0090, 0x0222, 0x0143, 0x000B, 0x0000,
79 0x0000, 0x008A, 0x021F, 0x014B, 0x000C, 0x0000,
80 0x0000, 0x0085, 0x021C, 0x0151, 0x000E, 0x0000,
81 0x0000, 0x007F, 0x0218, 0x015A, 0x000F, 0x0000,
82 0x0000, 0x007A, 0x0215, 0x0160, 0x0011, 0x0000,
83 0x0000, 0x0074, 0x0211, 0x0168, 0x0013, 0x0000,
84 0x0000, 0x006F, 0x020D, 0x016F, 0x0015, 0x0000,
85 0x0000, 0x006A, 0x0209, 0x0176, 0x0017, 0x0000,
86 0x0000, 0x0065, 0x0204, 0x017E, 0x0019, 0x0000,
87 0x0000, 0x0060, 0x0200, 0x0185, 0x001B, 0x0000,
88 0x0000, 0x005C, 0x01FB, 0x018C, 0x001D, 0x0000,
89 0x0000, 0x0057, 0x01F6, 0x0193, 0x0020, 0x0000,
90 0x0000, 0x0053, 0x01F1, 0x019A, 0x0022, 0x0000,
91 0x0000, 0x004E, 0x01EC, 0x01A1, 0x0025, 0x0000,
92 0x0000, 0x004A, 0x01E6, 0x01A8, 0x0028, 0x0000,
93 0x0000, 0x0046, 0x01E1, 0x01AF, 0x002A, 0x0000,
94 0x0000, 0x0042, 0x01DB, 0x01B6, 0x002D, 0x0000,
95 0x0000, 0x003F, 0x01D5, 0x01BB, 0x0031, 0x0000,
96 0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000,
97 0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000
98 };
99 //========================================================
100 // <using> gen_BlurScale_coeffs.m
101 // <date> 25-Apr-2022
102 // <num_taps> 4
103 // <num_phases> 64
104 // <CoefType> Blur & Scale LPF
105 // <CoefQuant> S1.10
106 //========================================================
107 static const uint16_t filter_isharp_bs_4tap_64p[132] = {
108 0x00E5, 0x0237, 0x00E4, 0x0000,
109 0x00DE, 0x0237, 0x00EB, 0x0000,
110 0x00D7, 0x0236, 0x00F2, 0x0001,
111 0x00D0, 0x0235, 0x00FA, 0x0001,
112 0x00C9, 0x0234, 0x0101, 0x0002,
113 0x00C2, 0x0233, 0x0108, 0x0003,
114 0x00BB, 0x0232, 0x0110, 0x0003,
115 0x00B5, 0x0230, 0x0117, 0x0004,
116 0x00AE, 0x022E, 0x011F, 0x0005,
117 0x00A8, 0x022C, 0x0126, 0x0006,
118 0x00A2, 0x022A, 0x012D, 0x0007,
119 0x009C, 0x0228, 0x0134, 0x0008,
120 0x0096, 0x0225, 0x013C, 0x0009,
121 0x0090, 0x0222, 0x0143, 0x000B,
122 0x008A, 0x021F, 0x014B, 0x000C,
123 0x0085, 0x021C, 0x0151, 0x000E,
124 0x007F, 0x0218, 0x015A, 0x000F,
125 0x007A, 0x0215, 0x0160, 0x0011,
126 0x0074, 0x0211, 0x0168, 0x0013,
127 0x006F, 0x020D, 0x016F, 0x0015,
128 0x006A, 0x0209, 0x0176, 0x0017,
129 0x0065, 0x0204, 0x017E, 0x0019,
130 0x0060, 0x0200, 0x0185, 0x001B,
131 0x005C, 0x01FB, 0x018C, 0x001D,
132 0x0057, 0x01F6, 0x0193, 0x0020,
133 0x0053, 0x01F1, 0x019A, 0x0022,
134 0x004E, 0x01EC, 0x01A1, 0x0025,
135 0x004A, 0x01E6, 0x01A8, 0x0028,
136 0x0046, 0x01E1, 0x01AF, 0x002A,
137 0x0042, 0x01DB, 0x01B6, 0x002D,
138 0x003F, 0x01D5, 0x01BB, 0x0031,
139 0x003B, 0x01CF, 0x01C2, 0x0034,
140 0x0037, 0x01C9, 0x01C9, 0x0037,
141 };
142 //========================================================
143 // <using> gen_BlurScale_coeffs.m
144 // <date> 09-Jun-2022
145 // <num_taps> 3
146 // <num_phases> 64
147 // <CoefType> Blur & Scale LPF
148 // <CoefQuant> S1.10
149 //========================================================
150 static const uint16_t filter_isharp_bs_3tap_64p[99] = {
151 0x0200, 0x0200, 0x0000,
152 0x01F6, 0x0206, 0x0004,
153 0x01EC, 0x020B, 0x0009,
154 0x01E2, 0x0211, 0x000D,
155 0x01D8, 0x0216, 0x0012,
156 0x01CE, 0x021C, 0x0016,
157 0x01C4, 0x0221, 0x001B,
158 0x01BA, 0x0226, 0x0020,
159 0x01B0, 0x022A, 0x0026,
160 0x01A6, 0x022F, 0x002B,
161 0x019C, 0x0233, 0x0031,
162 0x0192, 0x0238, 0x0036,
163 0x0188, 0x023C, 0x003C,
164 0x017E, 0x0240, 0x0042,
165 0x0174, 0x0244, 0x0048,
166 0x016A, 0x0248, 0x004E,
167 0x0161, 0x024A, 0x0055,
168 0x0157, 0x024E, 0x005B,
169 0x014D, 0x0251, 0x0062,
170 0x0144, 0x0253, 0x0069,
171 0x013A, 0x0256, 0x0070,
172 0x0131, 0x0258, 0x0077,
173 0x0127, 0x025B, 0x007E,
174 0x011E, 0x025C, 0x0086,
175 0x0115, 0x025E, 0x008D,
176 0x010B, 0x0260, 0x0095,
177 0x0102, 0x0262, 0x009C,
178 0x00F9, 0x0263, 0x00A4,
179 0x00F0, 0x0264, 0x00AC,
180 0x00E7, 0x0265, 0x00B4,
181 0x00DF, 0x0264, 0x00BD,
182 0x00D6, 0x0265, 0x00C5,
183 0x00CD, 0x0266, 0x00CD,
184 };
185
186 /* Converted Blur & Scale coeff tables from S1.10 to S1.12 */
187 static const uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198] = {
188 0x0000, 0x0394, 0x08dc, 0x0390, 0x0000, 0x0000,
189 0x0000, 0x0378, 0x08dc, 0x03ac, 0x0000, 0x0000,
190 0x0000, 0x035c, 0x08d8, 0x03c8, 0x0004, 0x0000,
191 0x0000, 0x0340, 0x08d4, 0x03e8, 0x0004, 0x0000,
192 0x0000, 0x0324, 0x08d0, 0x0404, 0x0008, 0x0000,
193 0x0000, 0x0308, 0x08cc, 0x0420, 0x000c, 0x0000,
194 0x0000, 0x02ec, 0x08c8, 0x0440, 0x000c, 0x0000,
195 0x0000, 0x02d4, 0x08c0, 0x045c, 0x0010, 0x0000,
196 0x0000, 0x02b8, 0x08b8, 0x047c, 0x0014, 0x0000,
197 0x0000, 0x02a0, 0x08b0, 0x0498, 0x0018, 0x0000,
198 0x0000, 0x0288, 0x08a8, 0x04b4, 0x001c, 0x0000,
199 0x0000, 0x0270, 0x08a0, 0x04d0, 0x0020, 0x0000,
200 0x0000, 0x0258, 0x0894, 0x04f0, 0x0024, 0x0000,
201 0x0000, 0x0240, 0x0888, 0x050c, 0x002c, 0x0000,
202 0x0000, 0x0228, 0x087c, 0x052c, 0x0030, 0x0000,
203 0x0000, 0x0214, 0x0870, 0x0544, 0x0038, 0x0000,
204 0x0000, 0x01fc, 0x0860, 0x0568, 0x003c, 0x0000,
205 0x0000, 0x01e8, 0x0854, 0x0580, 0x0044, 0x0000,
206 0x0000, 0x01d0, 0x0844, 0x05a0, 0x004c, 0x0000,
207 0x0000, 0x01bc, 0x0834, 0x05bc, 0x0054, 0x0000,
208 0x0000, 0x01a8, 0x0824, 0x05d8, 0x005c, 0x0000,
209 0x0000, 0x0194, 0x0810, 0x05f8, 0x0064, 0x0000,
210 0x0000, 0x0180, 0x0800, 0x0614, 0x006c, 0x0000,
211 0x0000, 0x0170, 0x07ec, 0x0630, 0x0074, 0x0000,
212 0x0000, 0x015c, 0x07d8, 0x064c, 0x0080, 0x0000,
213 0x0000, 0x014c, 0x07c4, 0x0668, 0x0088, 0x0000,
214 0x0000, 0x0138, 0x07b0, 0x0684, 0x0094, 0x0000,
215 0x0000, 0x0128, 0x0798, 0x06a0, 0x00a0, 0x0000,
216 0x0000, 0x0118, 0x0784, 0x06bc, 0x00a8, 0x0000,
217 0x0000, 0x0108, 0x076c, 0x06d8, 0x00b4, 0x0000,
218 0x0000, 0x00fc, 0x0754, 0x06ec, 0x00c4, 0x0000,
219 0x0000, 0x00ec, 0x073c, 0x0708, 0x00d0, 0x0000,
220 0x0000, 0x00dc, 0x0724, 0x0724, 0x00dc, 0x0000,
221 };
222
223 static const uint16_t filter_isharp_bs_4tap_64p_s1_12[132] = {
224 0x0394, 0x08dc, 0x0390, 0x0000,
225 0x0378, 0x08dc, 0x03ac, 0x0000,
226 0x035c, 0x08d8, 0x03c8, 0x0004,
227 0x0340, 0x08d4, 0x03e8, 0x0004,
228 0x0324, 0x08d0, 0x0404, 0x0008,
229 0x0308, 0x08cc, 0x0420, 0x000c,
230 0x02ec, 0x08c8, 0x0440, 0x000c,
231 0x02d4, 0x08c0, 0x045c, 0x0010,
232 0x02b8, 0x08b8, 0x047c, 0x0014,
233 0x02a0, 0x08b0, 0x0498, 0x0018,
234 0x0288, 0x08a8, 0x04b4, 0x001c,
235 0x0270, 0x08a0, 0x04d0, 0x0020,
236 0x0258, 0x0894, 0x04f0, 0x0024,
237 0x0240, 0x0888, 0x050c, 0x002c,
238 0x0228, 0x087c, 0x052c, 0x0030,
239 0x0214, 0x0870, 0x0544, 0x0038,
240 0x01fc, 0x0860, 0x0568, 0x003c,
241 0x01e8, 0x0854, 0x0580, 0x0044,
242 0x01d0, 0x0844, 0x05a0, 0x004c,
243 0x01bc, 0x0834, 0x05bc, 0x0054,
244 0x01a8, 0x0824, 0x05d8, 0x005c,
245 0x0194, 0x0810, 0x05f8, 0x0064,
246 0x0180, 0x0800, 0x0614, 0x006c,
247 0x0170, 0x07ec, 0x0630, 0x0074,
248 0x015c, 0x07d8, 0x064c, 0x0080,
249 0x014c, 0x07c4, 0x0668, 0x0088,
250 0x0138, 0x07b0, 0x0684, 0x0094,
251 0x0128, 0x0798, 0x06a0, 0x00a0,
252 0x0118, 0x0784, 0x06bc, 0x00a8,
253 0x0108, 0x076c, 0x06d8, 0x00b4,
254 0x00fc, 0x0754, 0x06ec, 0x00c4,
255 0x00ec, 0x073c, 0x0708, 0x00d0,
256 0x00dc, 0x0724, 0x0724, 0x00dc,
257 };
258
259 static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = {
260 0x0800, 0x0800, 0x0000,
261 0x07d8, 0x0818, 0x0010,
262 0x07b0, 0x082c, 0x0024,
263 0x0788, 0x0844, 0x0034,
264 0x0760, 0x0858, 0x0048,
265 0x0738, 0x0870, 0x0058,
266 0x0710, 0x0884, 0x006c,
267 0x06e8, 0x0898, 0x0080,
268 0x06c0, 0x08a8, 0x0098,
269 0x0698, 0x08bc, 0x00ac,
270 0x0670, 0x08cc, 0x00c4,
271 0x0648, 0x08e0, 0x00d8,
272 0x0620, 0x08f0, 0x00f0,
273 0x05f8, 0x0900, 0x0108,
274 0x05d0, 0x0910, 0x0120,
275 0x05a8, 0x0920, 0x0138,
276 0x0584, 0x0928, 0x0154,
277 0x055c, 0x0938, 0x016c,
278 0x0534, 0x0944, 0x0188,
279 0x0510, 0x094c, 0x01a4,
280 0x04e8, 0x0958, 0x01c0,
281 0x04c4, 0x0960, 0x01dc,
282 0x049c, 0x096c, 0x01f8,
283 0x0478, 0x0970, 0x0218,
284 0x0454, 0x0978, 0x0234,
285 0x042c, 0x0980, 0x0254,
286 0x0408, 0x0988, 0x0270,
287 0x03e4, 0x098c, 0x0290,
288 0x03c0, 0x0990, 0x02b0,
289 0x039c, 0x0994, 0x02d0,
290 0x037c, 0x0990, 0x02f4,
291 0x0358, 0x0994, 0x0314,
292 0x0334, 0x0998, 0x0334,
293 };
294
295 /* Pre-generated 1DLUT for given setup and sharpness level */
296 static struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
297 {
298 0, 0,
299 {
300 0, 0, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0,
302 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0,
304 }
305 },
306 {
307 0, 0,
308 {
309 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0,
313 }
314 },
315 {
316 0, 0,
317 {
318 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0,
322 }
323 },
324 {
325 0, 0,
326 {
327 0, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0,
331 }
332 },
333 };
334
335 static struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = {
336 {1125, 1000, 0},
337 {11, 10, 1},
338 {1075, 1000, 2},
339 {105, 100, 3},
340 {1025, 1000, 4},
341 {1, 1, 5},
342 };
343
spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)344 static unsigned int spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)
345 {
346 int j;
347 struct spl_fixed31_32 ratio_level;
348 struct scale_ratio_to_sharpness_level_adj *lookup_ptr;
349 unsigned int sharpness_level_down_adj;
350
351 /*
352 * Adjust sharpness level based on current scaling ratio
353 *
354 * We have 5 discrete scaling ratios which we will use to adjust the
355 * sharpness level down by 1 as we pass each ratio. The ratios
356 * are
357 *
358 * 1.125 upscale and higher - no adj
359 * 1.100 - under 1.125 - adj level down 1
360 * 1.075 - under 1.100 - adj level down 2
361 * 1.050 - under 1.075 - adj level down 3
362 * 1.025 - under 1.050 - adj level down 4
363 * 1.000 - under 1.025 - adj level down 5
364 *
365 */
366 j = 0;
367 sharpness_level_down_adj = 0;
368 lookup_ptr = sharpness_level_adj;
369 while (j < NUM_SHARPNESS_ADJ_LEVELS) {
370 ratio_level = SPL_NAMESPACE(spl_fixpt_from_fraction(lookup_ptr->ratio_numer,
371 lookup_ptr->ratio_denom));
372 if (ratio.value >= ratio_level.value) {
373 sharpness_level_down_adj = lookup_ptr->level_down_adj;
374 break;
375 }
376 lookup_ptr++;
377 j++;
378 }
379 return sharpness_level_down_adj;
380 }
381
spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,unsigned int discrete_sharpness_level,enum system_setup setup,struct spl_sharpness_range sharpness_range,enum scale_to_sharpness_policy scale_to_sharpness_policy)382 static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,
383 unsigned int discrete_sharpness_level, enum system_setup setup,
384 struct spl_sharpness_range sharpness_range,
385 enum scale_to_sharpness_policy scale_to_sharpness_policy)
386 {
387 unsigned int sharpness_level = 0;
388 unsigned int sharpness_level_down_adj = 0;
389
390 int min_sharpness, max_sharpness, mid_sharpness;
391
392 /*
393 * Adjust sharpness level if policy requires we adjust it based on
394 * scale ratio. Based on scale ratio, we may adjust the sharpness
395 * level down by a certain number of steps. We will not select
396 * a sharpness value of 0 so the lowest sharpness level will be
397 * 0 or 1 depending on what the min_sharpness is
398 *
399 * If the policy is no required, this code maybe removed at a later
400 * date
401 */
402 switch (setup) {
403
404 case HDR_L:
405 min_sharpness = sharpness_range.hdr_rgb_min;
406 max_sharpness = sharpness_range.hdr_rgb_max;
407 mid_sharpness = sharpness_range.hdr_rgb_mid;
408 if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
409 sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
410 break;
411 case HDR_NL:
412 /* currently no use case, use Non-linear SDR values for now */
413 case SDR_NL:
414 min_sharpness = sharpness_range.sdr_yuv_min;
415 max_sharpness = sharpness_range.sdr_yuv_max;
416 mid_sharpness = sharpness_range.sdr_yuv_mid;
417 if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV)
418 sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
419 break;
420 case SDR_L:
421 default:
422 min_sharpness = sharpness_range.sdr_rgb_min;
423 max_sharpness = sharpness_range.sdr_rgb_max;
424 mid_sharpness = sharpness_range.sdr_rgb_mid;
425 if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
426 sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
427 break;
428 }
429
430 if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level))
431 discrete_sharpness_level = 1;
432 else if (sharpness_level_down_adj >= discrete_sharpness_level)
433 discrete_sharpness_level = 0;
434 else
435 discrete_sharpness_level -= sharpness_level_down_adj;
436
437 int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
438 int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
439
440 // lower half linear approximation
441 if (discrete_sharpness_level < 5)
442 sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
443 // upper half linear approximation
444 else
445 sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
446
447 return sharpness_level;
448 }
449
SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve (struct spl_fixed31_32 ratio,enum system_setup setup,struct adaptive_sharpness sharpness,enum scale_to_sharpness_policy scale_to_sharpness_policy))450 void SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve(
451 struct spl_fixed31_32 ratio, enum system_setup setup,
452 struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy))
453 {
454 uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
455 struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
456 int j;
457 int size_1dlut;
458 int sharp_calc_int;
459 uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
460
461 /* Custom sharpnessX1000 value */
462 unsigned int sharpnessX1000 = spl_calculate_sharpness_level(ratio,
463 sharpness.sharpness_level, setup,
464 sharpness.sharpness_range, scale_to_sharpness_policy);
465 sharp_level = SPL_NAMESPACE(spl_fixpt_from_fraction(sharpnessX1000, 1000));
466
467 /*
468 * Check if pregen 1dlut table is already precalculated
469 * If numer/denom is different, then recalculate
470 */
471 if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
472 (filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
473 return;
474
475 /*
476 * Calculate LUT_128_gained with this equation:
477 *
478 * LUT_128_gained[i] = (uint8)(0.5 + min(255,(double)(LUT_128[i])*sharpLevel/iGain))
479 * where LUT_128[i] is contents of 3p0x isharp 1dlut
480 * where sharpLevel is desired sharpness level
481 * where iGain is base sharpness level 3.0
482 * where LUT_128_gained[i] is adjusted 1dlut value based on desired sharpness level
483 */
484 byte_ptr_1dlut_src = (uint8_t *)filter_isharp_1D_lut_3p0x;
485 byte_ptr_1dlut_dst = (uint8_t *)filter_pregen_store;
486 size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
487 memset(byte_ptr_1dlut_dst, 0, size_1dlut);
488 for (j = 0; j < size_1dlut; j++) {
489 sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
490 sharp_calc = SPL_NAMESPACE(spl_fixpt_mul(sharp_base, sharp_level));
491 sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
492 sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
493 sharp_calc = spl_fixpt_add(sharp_calc,
494 SPL_NAMESPACE(spl_fixpt_from_fraction(1, 2)));
495 sharp_calc_int = spl_fixpt_floor(sharp_calc);
496 /* Clamp it at 0x7F so it doesn't wrap */
497 if (sharp_calc_int > 127)
498 sharp_calc_int = 127;
499 *byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
500
501 byte_ptr_1dlut_src++;
502 byte_ptr_1dlut_dst++;
503 }
504
505 /* Update 1dlut table and sharpness level */
506 memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
507 filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
508 filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
509 }
510
SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut (enum system_setup setup))511 uint32_t *SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup))
512 {
513 return filter_isharp_1D_lut_pregen[setup].value;
514 }
515
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p (int taps))516 const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(int taps))
517 {
518 if (taps == 3)
519 return filter_isharp_bs_3tap_64p_s1_12;
520 else if (taps == 4)
521 return filter_isharp_bs_4tap_64p_s1_12;
522 else if (taps == 6)
523 return filter_isharp_bs_4tap_in_6_64p_s1_12;
524 else {
525 /* should never happen, bug */
526 SPL_BREAK_TO_DEBUGGER();
527 return NULL;
528 }
529 }
530
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10 (int taps))531 const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps))
532 {
533 if (taps == 3)
534 return filter_isharp_bs_3tap_64p;
535 else if (taps == 4)
536 return filter_isharp_bs_4tap_64p;
537 else if (taps == 6)
538 return filter_isharp_bs_4tap_in_6_64p;
539 else {
540 /* should never happen, bug */
541 SPL_BREAK_TO_DEBUGGER();
542 return NULL;
543 }
544 }
545
SPL_NAMESPACE(spl_set_blur_scale_data (struct dscl_prog_data * dscl_prog_data,const struct spl_scaler_data * data))546 void SPL_NAMESPACE(spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
547 const struct spl_scaler_data *data))
548 {
549 dscl_prog_data->filter_blur_scale_h =
550 SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.h_taps));
551
552 dscl_prog_data->filter_blur_scale_v =
553 SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps));
554 }
555