Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3769 | Serge | 1 | /* |
2 | * Copyright © 2011 Intel Corporation |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the |
||
6 | * "Software"), to deal in the Software without restriction, including |
||
7 | * without limitation the rights to use, copy, modify, merge, publish, |
||
8 | * distribute, sub license, and/or sell copies of the Software, and to |
||
9 | * permit persons to whom the Software is furnished to do so, subject to |
||
10 | * the following conditions: |
||
11 | * |
||
12 | * The above copyright notice and this permission notice (including the |
||
13 | * next paragraph) shall be included in all copies or substantial portions |
||
14 | * of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
19 | * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
20 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
23 | * |
||
24 | * Authors: |
||
25 | * Li Xiaowei |
||
26 | */ |
||
27 | |||
28 | #include |
||
29 | #include |
||
30 | #include |
||
31 | #include |
||
32 | #include |
||
33 | |||
34 | #include "intel_batchbuffer.h" |
||
35 | #include "intel_driver.h" |
||
36 | #include "i965_defines.h" |
||
37 | #include "i965_structs.h" |
||
38 | #include "gen75_vpp_vebox.h" |
||
39 | |||
40 | #define PI 3.1415926 |
||
41 | |||
42 | extern VAStatus |
||
43 | i965_CreateSurfaces(VADriverContextP ctx, |
||
44 | int width, |
||
45 | int height, |
||
46 | int format, |
||
47 | int num_surfaces, |
||
48 | VASurfaceID *surfaces); |
||
49 | |||
50 | int format_convert(float src, int out_int_bits, int out_frac_bits,int out_sign_flag) |
||
51 | { |
||
52 | unsigned char negative_flag = (src < 0.0) ? 1 : 0; |
||
53 | float src_1 = (!negative_flag)? src: -src ; |
||
54 | unsigned int factor = 1 << out_frac_bits; |
||
55 | int output_value = 0; |
||
56 | |||
57 | unsigned int integer_part = 0;//floor(src_1); |
||
58 | unsigned int fraction_part = ((int)((src_1 - integer_part) * factor)) & (factor - 1) ; |
||
59 | |||
60 | output_value = (integer_part << out_frac_bits) | fraction_part; |
||
61 | |||
62 | if(negative_flag) |
||
63 | output_value = (~output_value + 1) & ((1 <<(out_int_bits + out_frac_bits)) -1); |
||
64 | |||
65 | if(out_sign_flag == 1 && negative_flag) |
||
66 | { |
||
67 | output_value |= negative_flag <<(out_int_bits + out_frac_bits); |
||
68 | } |
||
69 | return output_value; |
||
70 | } |
||
71 | |||
72 | void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
73 | { |
||
74 | unsigned int* p_table ; |
||
75 | /* |
||
76 | VAProcFilterParameterBufferDeinterlacing *di_param = |
||
77 | (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di; |
||
78 | |||
79 | VAProcFilterParameterBuffer * dn_param = |
||
80 | (VAProcFilterParameterBuffer *) proc_ctx->filter_dn; |
||
81 | */ |
||
82 | p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr; |
||
83 | |||
84 | *p_table ++ = 0; // reserved . w0 |
||
85 | *p_table ++ = ( 0 << 24 | // denoise STAD threshold . w1 |
||
86 | 128 << 16 | // dnmh_history_max |
||
87 | |||
88 | 8 << 8 | // dnmh_delta[3:0] |
||
89 | |||
90 | |||
91 | *p_table ++ = ( 0 << 30 | // reserved . w2 |
||
92 | 16 << 24 | // temporal diff th |
||
93 | |||
94 | 8 << 16 | // low temporal diff th |
||
95 | |||
96 | |||
97 | 64 ); // denoise th for sum of complexity measure |
||
98 | |||
99 | *p_table ++ = ( 0 << 30 | // reserved . w3 |
||
100 | 4 << 24 | // good neighbor th[5:0] |
||
101 | 9 << 20 | // CAT slope minus 1 |
||
102 | 5 << 16 | // SAD Tight in |
||
103 | |||
104 | |||
105 | 1 << 8 | // bne_edge_th[3:0] |
||
106 | 15 ); // block noise estimate noise th |
||
107 | |||
108 | *p_table ++ = ( 0 << 31 | // STMM blending constant select. w4 |
||
109 | 64 << 24 | // STMM trc1 |
||
110 | |||
111 | |||
112 | 2 << 8 | // VECM_mul |
||
113 | 128 ); // maximum STMM |
||
114 | |||
115 | *p_table ++ = ( 0 << 24 | // minumum STMM . W5 |
||
116 | |||
117 | |||
118 | 7 << 16 | // STMM output shift |
||
119 | 128 << 8 | // SDI threshold |
||
120 | 8 ); // SDI delta |
||
121 | |||
122 | *p_table ++ = ( 0 << 24 | // SDI fallback mode 1 T1 constant . W6 |
||
123 | |||
124 | |||
125 | |||
126 | |||
127 | *p_table ++ = ( 32 << 24 | // FMD #1 vertical difference th . w7 |
||
128 | 32 << 16 | // FMD #2 vertical difference th |
||
129 | 1 << 14 | // CAT th1 |
||
130 | 32 << 8 | // FMD tear threshold |
||
131 | |||
132 | |||
133 | |||
134 | |||
135 | |||
136 | |||
137 | *p_table ++ = ( 0 << 29 | // reserved . W8 |
||
138 | |||
139 | 10 << 19 | // neighborPixel th |
||
140 | |||
141 | |||
142 | 25 << 10 | // MC pixel consistency th |
||
143 | |||
144 | 10 << 4 | // SAD THB |
||
145 | 5 ); // SAD THA |
||
146 | |||
147 | *p_table ++ = ( 0 << 24 | // reserved |
||
148 | |||
149 | |||
150 | |||
151 | |||
152 | |||
153 | |||
154 | } |
||
155 | |||
156 | void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
157 | { |
||
158 | unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ; |
||
159 | /* |
||
160 | VAProcFilterParameterBuffer * std_param = |
||
161 | (VAProcFilterParameterBuffer *) proc_ctx->filter_std; |
||
162 | */ |
||
163 | if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){ |
||
164 | memset(p_table, 0, 29 * 4); |
||
165 | }else{ |
||
166 | *p_table ++ = 0x9a6e39f0; |
||
167 | *p_table ++ = 0x400c0000; |
||
168 | *p_table ++ = 0x00001180; |
||
169 | *p_table ++ = 0xfe2f2e00; |
||
170 | *p_table ++ = 0x000000ff; |
||
171 | |||
172 | *p_table ++ = 0x00140000; |
||
173 | *p_table ++ = 0xd82e0000; |
||
174 | *p_table ++ = 0x8285ecec; |
||
175 | *p_table ++ = 0x00008282; |
||
176 | *p_table ++ = 0x00000000; |
||
177 | |||
178 | *p_table ++ = 0x02117000; |
||
179 | *p_table ++ = 0xa38fec96; |
||
180 | *p_table ++ = 0x0000c8c8; |
||
181 | *p_table ++ = 0x00000000; |
||
182 | *p_table ++ = 0x01478000; |
||
183 | |||
184 | *p_table ++ = 0x0007c306; |
||
185 | *p_table ++ = 0x00000000; |
||
186 | *p_table ++ = 0x00000000; |
||
187 | *p_table ++ = 0x1c1bd000; |
||
188 | *p_table ++ = 0x00000000; |
||
189 | |||
190 | *p_table ++ = 0x00000000; |
||
191 | *p_table ++ = 0x00000000; |
||
192 | *p_table ++ = 0x0007cf80; |
||
193 | *p_table ++ = 0x00000000; |
||
194 | *p_table ++ = 0x00000000; |
||
195 | |||
196 | *p_table ++ = 0x1c080000; |
||
197 | *p_table ++ = 0x00000000; |
||
198 | *p_table ++ = 0x00000000; |
||
199 | *p_table ++ = 0x00000000; |
||
200 | } |
||
201 | } |
||
202 | |||
203 | void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
204 | { |
||
205 | unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116); |
||
206 | |||
207 | if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){ |
||
208 | memset(p_table, 0, 13 * 4); |
||
209 | }else{ |
||
210 | *p_table ++ = 0x00000068; |
||
211 | *p_table ++ = 0x4c382410; |
||
212 | *p_table ++ = 0x9c887460; |
||
213 | *p_table ++ = 0xebd8c4b0; |
||
214 | *p_table ++ = 0x604c3824; |
||
215 | |||
216 | *p_table ++ = 0xb09c8874; |
||
217 | *p_table ++ = 0x0000d8c4; |
||
218 | *p_table ++ = 0x00000000; |
||
219 | *p_table ++ = 0x00000000; |
||
220 | *p_table ++ = 0x00000000; |
||
221 | |||
222 | *p_table ++ = 0x00000000; |
||
223 | *p_table ++ = 0x00000000; |
||
224 | *p_table ++ = 0x00000000; |
||
225 | } |
||
226 | } |
||
227 | |||
228 | void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
229 | { |
||
230 | unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168); |
||
231 | /* |
||
232 | VAProcFilterParameterBuffer * tcc_param = |
||
233 | (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc; |
||
234 | */ |
||
235 | if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){ |
||
236 | memset(p_table, 0, 11 * 4); |
||
237 | }else{ |
||
238 | *p_table ++ = 0x00000000; |
||
239 | *p_table ++ = 0x00000000; |
||
240 | *p_table ++ = 0x1e34cc91; |
||
241 | *p_table ++ = 0x3e3cce91; |
||
242 | *p_table ++ = 0x02e80195; |
||
243 | |||
244 | *p_table ++ = 0x0197046b; |
||
245 | *p_table ++ = 0x01790174; |
||
246 | *p_table ++ = 0x00000000; |
||
247 | *p_table ++ = 0x00000000; |
||
248 | *p_table ++ = 0x03030000; |
||
249 | |||
250 | *p_table ++ = 0x009201c0; |
||
251 | } |
||
252 | } |
||
253 | |||
254 | void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
255 | { |
||
256 | unsigned int contrast = 0x80; //default |
||
257 | int brightness = 0x00; //default |
||
258 | int cos_c_s = 256 ; //default |
||
259 | int sin_c_s = 0; //default |
||
260 | unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212); |
||
261 | |||
262 | if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){ |
||
263 | memset(p_table, 0, 2 * 4); |
||
264 | }else { |
||
265 | float tmp_value = 0.0; |
||
266 | float src_saturation = 1.0; |
||
267 | float src_hue = 0.0; |
||
268 | float src_contrast = 1.0; |
||
269 | /* |
||
270 | float src_brightness = 0.0; |
||
271 | |||
272 | VAProcFilterParameterBufferColorBalance * amp_param = |
||
273 | (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp; |
||
274 | VAProcColorBalanceType attrib = amp_param->attrib; |
||
275 | |||
276 | if(attrib == VAProcColorBalanceHue) { |
||
277 | src_hue = amp_param->value; //(-180.0, 180.0) |
||
278 | }else if(attrib == VAProcColorBalanceSaturation) { |
||
279 | src_saturation = amp_param->value; //(0.0, 10.0) |
||
280 | }else if(attrib == VAProcColorBalanceBrightness) { |
||
281 | src_brightness = amp_param->value; // (-100.0, 100.0) |
||
282 | brightness = format_convert(src_brightness, 7, 4, 1); |
||
283 | }else if(attrib == VAProcColorBalanceContrast) { |
||
284 | src_contrast = amp_param->value; // (0.0, 10.0) |
||
285 | contrast = format_convert(src_contrast, 4, 7, 0); |
||
286 | } |
||
287 | */ |
||
288 | tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation; |
||
289 | cos_c_s = format_convert(tmp_value, 7, 8, 1); |
||
290 | |||
291 | tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation; |
||
292 | sin_c_s = format_convert(tmp_value, 7, 8, 1); |
||
293 | |||
294 | *p_table ++ = ( 0 << 28 | //reserved |
||
295 | contrast << 17 | //contrast value (U4.7 format) |
||
296 | |||
297 | brightness << 1| // S7.4 format |
||
298 | 1); |
||
299 | |||
300 | *p_table ++ = ( cos_c_s << 16 | // cos(h) * contrast * saturation |
||
301 | sin_c_s); // sin(h) * contrast * saturation |
||
302 | |||
303 | } |
||
304 | } |
||
305 | |||
306 | |||
307 | void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
308 | { |
||
309 | unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220); |
||
310 | float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; |
||
311 | float v_coef[3] = {0.0, 0.0, 0.0}; |
||
312 | float u_coef[3] = {0.0, 0.0, 0.0}; |
||
313 | int is_transform_enabled = 0; |
||
314 | |||
315 | if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){ |
||
316 | memset(p_table, 0, 8 * 4); |
||
317 | return; |
||
318 | } |
||
319 | /* |
||
320 | VAProcColorStandardType in_color_std = proc_ctx->pipeline_param->surface_color_standard; |
||
321 | VAProcColorStandardType out_color_std = proc_ctx->pipeline_param->output_color_standard; |
||
322 | assert(in_color_std == out_color_std); |
||
323 | */ |
||
324 | if(proc_ctx->fourcc_input == VA_FOURCC('R','G','B','A') && |
||
325 | (proc_ctx->fourcc_output == VA_FOURCC('N','V','1','2') || |
||
326 | proc_ctx->fourcc_output == VA_FOURCC('Y','V','1','2') || |
||
327 | proc_ctx->fourcc_output == VA_FOURCC('Y','V','Y','2') || |
||
328 | proc_ctx->fourcc_output == VA_FOURCC('A','Y','U','V'))) { |
||
329 | |||
330 | tran_coef[0] = 0.257; |
||
331 | tran_coef[1] = 0.504; |
||
332 | tran_coef[2] = 0.098; |
||
333 | tran_coef[3] = -0.148; |
||
334 | tran_coef[4] = -0.291; |
||
335 | tran_coef[5] = 0.439; |
||
336 | tran_coef[6] = 0.439; |
||
337 | tran_coef[7] = -0.368; |
||
338 | tran_coef[8] = -0.071; |
||
339 | |||
340 | u_coef[0] = 16 * 4; |
||
341 | u_coef[1] = 128 * 4; |
||
342 | u_coef[2] = 128 * 4; |
||
343 | |||
344 | is_transform_enabled = 1; |
||
345 | }else if((proc_ctx->fourcc_input == VA_FOURCC('N','V','1','2') || |
||
346 | proc_ctx->fourcc_input == VA_FOURCC('Y','V','1','2') || |
||
347 | proc_ctx->fourcc_input == VA_FOURCC('Y','U','Y','2') || |
||
348 | proc_ctx->fourcc_input == VA_FOURCC('A','Y','U','V'))&& |
||
349 | proc_ctx->fourcc_output == VA_FOURCC('R','G','B','A')) { |
||
350 | |||
351 | tran_coef[0] = 1.164; |
||
352 | tran_coef[1] = 0.000; |
||
353 | tran_coef[2] = 1.569; |
||
354 | tran_coef[3] = 1.164; |
||
355 | tran_coef[4] = -0.813; |
||
356 | tran_coef[5] = -0.392; |
||
357 | tran_coef[6] = 1.164; |
||
358 | tran_coef[7] = 2.017; |
||
359 | tran_coef[8] = 0.000; |
||
360 | |||
361 | v_coef[0] = -16 * 4; |
||
362 | v_coef[1] = -128 * 4; |
||
363 | v_coef[2] = -128 * 4; |
||
364 | |||
365 | is_transform_enabled = 1; |
||
366 | }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){ |
||
367 | //enable when input and output format are different. |
||
368 | is_transform_enabled = 1; |
||
369 | } |
||
370 | |||
371 | if(is_transform_enabled == 0){ |
||
372 | memset(p_table, 0, 8 * 4); |
||
373 | }else{ |
||
374 | *p_table ++ = ( 0 << 29 | //reserved |
||
375 | format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format |
||
376 | format_convert(tran_coef[0], 2, 10, 1) << 3 | //c0, s2.10 format |
||
377 | |||
378 | |||
379 | is_transform_enabled); |
||
380 | |||
381 | *p_table ++ = ( 0 << 26 | //reserved |
||
382 | format_convert(tran_coef[3], 2, 10, 1) << 13 | |
||
383 | format_convert(tran_coef[2], 2, 10, 1)); |
||
384 | |||
385 | *p_table ++ = ( 0 << 26 | //reserved |
||
386 | format_convert(tran_coef[5], 2, 10, 1) << 13 | |
||
387 | format_convert(tran_coef[4], 2, 10, 1)); |
||
388 | |||
389 | *p_table ++ = ( 0 << 26 | //reserved |
||
390 | format_convert(tran_coef[7], 2, 10, 1) << 13 | |
||
391 | format_convert(tran_coef[6], 2, 10, 1)); |
||
392 | |||
393 | *p_table ++ = ( 0 << 13 | //reserved |
||
394 | format_convert(tran_coef[8], 2, 10, 1)); |
||
395 | |||
396 | *p_table ++ = ( 0 << 22 | //reserved |
||
397 | format_convert(u_coef[0], 10, 0, 1) << 11 | |
||
398 | format_convert(v_coef[0], 10, 0, 1)); |
||
399 | |||
400 | *p_table ++ = ( 0 << 22 | //reserved |
||
401 | format_convert(u_coef[1], 10, 0, 1) << 11 | |
||
402 | format_convert(v_coef[1], 10, 0, 1)); |
||
403 | |||
404 | *p_table ++ = ( 0 << 22 | //reserved |
||
405 | format_convert(u_coef[2], 10, 0, 1) << 11 | |
||
406 | format_convert(v_coef[2], 10, 0, 1)); |
||
407 | } |
||
408 | } |
||
409 | |||
410 | void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
411 | { |
||
412 | unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252); |
||
413 | /* |
||
414 | VAProcFilterParameterBuffer * tcc_param = |
||
415 | (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc; |
||
416 | */ |
||
417 | if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){ |
||
418 | memset(p_table, 0, 3 * 4); |
||
419 | }else{ |
||
420 | *p_table ++ = 0x00000000; |
||
421 | *p_table ++ = 0x00030000; |
||
422 | *p_table ++ = 0x00030000; |
||
423 | } |
||
424 | } |
||
425 | |||
426 | void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
427 | { |
||
428 | if(proc_ctx->filters_mask & 0x000000ff) { |
||
429 | dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo; |
||
430 | dri_bo_map(dndi_bo, 1); |
||
431 | proc_ctx->dndi_state_table.ptr = dndi_bo->virtual; |
||
432 | |||
433 | hsw_veb_dndi_table(ctx, proc_ctx); |
||
434 | |||
435 | dri_bo_unmap(dndi_bo); |
||
436 | } |
||
437 | |||
438 | if(proc_ctx->filters_mask & 0x0000ff00 || |
||
439 | proc_ctx->fourcc_input != proc_ctx->fourcc_output) { |
||
440 | dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo; |
||
441 | dri_bo_map(iecp_bo, 1); |
||
442 | proc_ctx->iecp_state_table.ptr = iecp_bo->virtual; |
||
443 | |||
444 | hsw_veb_iecp_std_table(ctx, proc_ctx); |
||
445 | hsw_veb_iecp_ace_table(ctx, proc_ctx); |
||
446 | hsw_veb_iecp_tcc_table(ctx, proc_ctx); |
||
447 | hsw_veb_iecp_pro_amp_table(ctx, proc_ctx); |
||
448 | hsw_veb_iecp_csc_table(ctx, proc_ctx); |
||
449 | hsw_veb_iecp_aoi_table(ctx, proc_ctx); |
||
450 | |||
451 | dri_bo_unmap(iecp_bo); |
||
452 | } |
||
453 | } |
||
454 | |||
455 | void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
456 | { |
||
457 | struct intel_batchbuffer *batch = proc_ctx->batch; |
||
458 | unsigned int is_dn_enabled = (proc_ctx->filters_mask & 0x01)? 1: 0; |
||
459 | unsigned int is_di_enabled = (proc_ctx->filters_mask & 0x02)? 1: 0; |
||
460 | unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0; |
||
461 | |||
462 | BEGIN_VEB_BATCH(batch, 6); |
||
463 | OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2)); |
||
464 | OUT_VEB_BATCH(batch, |
||
465 | |||
466 | |||
467 | |||
468 | 2 << 8 | // DI output frame |
||
469 | |||
470 | |||
471 | !!(proc_ctx->is_first_frame && (is_di_enabled || is_dn_enabled)) << 5 | // DN/DI first frame |
||
472 | is_di_enabled << 4 | // DI enable |
||
473 | is_dn_enabled << 3 | // DN enable |
||
474 | is_iecp_enabled << 2 | // global IECP enabled |
||
475 | |||
476 | |||
477 | |||
478 | OUT_RELOC(batch, |
||
479 | proc_ctx->dndi_state_table.bo, |
||
480 | I915_GEM_DOMAIN_INSTRUCTION, 0, 0); |
||
481 | |||
482 | OUT_RELOC(batch, |
||
483 | proc_ctx->iecp_state_table.bo, |
||
484 | I915_GEM_DOMAIN_INSTRUCTION, 0, 0); |
||
485 | |||
486 | OUT_RELOC(batch, |
||
487 | proc_ctx->gamut_state_table.bo, |
||
488 | I915_GEM_DOMAIN_INSTRUCTION, 0, 0); |
||
489 | |||
490 | OUT_RELOC(batch, |
||
491 | proc_ctx->vertex_state_table.bo, |
||
492 | I915_GEM_DOMAIN_INSTRUCTION, 0, 0); |
||
493 | |||
494 | ADVANCE_VEB_BATCH(batch); |
||
495 | } |
||
496 | |||
497 | void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output) |
||
498 | { |
||
499 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
500 | struct intel_batchbuffer *batch = proc_ctx->batch; |
||
501 | unsigned int u_offset_y = 0, v_offset_y = 0; |
||
502 | unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0; |
||
503 | unsigned int surface_format = PLANAR_420_8; |
||
504 | struct object_surface* obj_surf = NULL; |
||
505 | unsigned int surface_pitch = 0; |
||
506 | unsigned int half_pitch_chroma = 0; |
||
507 | |||
508 | if(is_output){ |
||
509 | obj_surf = SURFACE(proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id); |
||
510 | }else { |
||
511 | obj_surf = SURFACE(proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id); |
||
512 | } |
||
513 | |||
514 | if (obj_surf->fourcc == VA_FOURCC_NV12) { |
||
515 | surface_format = PLANAR_420_8; |
||
516 | surface_pitch = obj_surf->width; |
||
517 | printf("NV12, is_output=%d, width = %d, pitch is = %d\n",is_output, obj_surf->orig_width, obj_surf->width); |
||
518 | is_uv_interleaved = 1; |
||
519 | half_pitch_chroma = 0; |
||
520 | } else if (obj_surf->fourcc == VA_FOURCC_YUY2) { |
||
521 | surface_format = YCRCB_NORMAL; |
||
522 | surface_pitch = obj_surf->width * 2; |
||
523 | is_uv_interleaved = 0; |
||
524 | half_pitch_chroma = 0; |
||
525 | } else if (obj_surf->fourcc == VA_FOURCC_AYUV) { |
||
526 | surface_format = PACKED_444A_8; |
||
527 | surface_pitch = obj_surf->width * 4; |
||
528 | is_uv_interleaved = 0; |
||
529 | half_pitch_chroma = 0; |
||
530 | } else if (obj_surf->fourcc == VA_FOURCC_RGBA) { |
||
531 | surface_format = R8G8B8A8_UNORM_SRGB; |
||
532 | surface_pitch = obj_surf->width * 4; |
||
533 | is_uv_interleaved = 0; |
||
534 | half_pitch_chroma = 0; |
||
535 | } |
||
536 | |||
537 | u_offset_y = obj_surf->y_cb_offset; |
||
538 | v_offset_y = obj_surf->y_cr_offset; |
||
539 | |||
540 | dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle); |
||
541 | |||
542 | BEGIN_VEB_BATCH(batch, 6); |
||
543 | OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2)); |
||
544 | OUT_VEB_BATCH(batch, |
||
545 | |||
546 | is_output); // surface indentification. |
||
547 | |||
548 | OUT_VEB_BATCH(batch, |
||
549 | (proc_ctx->pic_height - 1) << 18 | // height . w3 |
||
550 | (proc_ctx->pic_width ) << 4 | // width |
||
551 | 0); // reserve |
||
552 | |||
553 | OUT_VEB_BATCH(batch, |
||
554 | surface_format << 28 | // surface format, YCbCr420. w4 |
||
555 | is_uv_interleaved << 27 | // interleave chrome , two seperate palar |
||
556 | |||
557 | (surface_pitch - 1) << 3 | // surface pitch, 64 align |
||
558 | half_pitch_chroma << 2 | // half pitch for chrome |
||
559 | !!tiling << 1 | // tiled surface, linear surface used |
||
560 | (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface |
||
561 | |||
562 | OUT_VEB_BATCH(batch, |
||
563 | |||
564 | |||
565 | |||
566 | u_offset_y); // Y offset for V(Cb) |
||
567 | |||
568 | OUT_VEB_BATCH(batch, |
||
569 | |||
570 | |||
571 | |||
572 | v_offset_y ); // Y offset for V(Cr) |
||
573 | |||
574 | ADVANCE_VEB_BATCH(batch); |
||
575 | } |
||
576 | |||
577 | void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx) |
||
578 | { |
||
579 | struct intel_batchbuffer *batch = proc_ctx->batch; |
||
580 | unsigned char frame_ctrl_bits = 0; |
||
581 | unsigned int startingX = 0; |
||
582 | unsigned int endingX = proc_ctx->pic_width; |
||
583 | |||
584 | BEGIN_VEB_BATCH(batch, 10); |
||
585 | OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2)); |
||
586 | OUT_VEB_BATCH(batch, |
||
587 | startingX << 16 | |
||
588 | endingX); |
||
589 | OUT_RELOC(batch, |
||
590 | proc_ctx->frame_store[FRAME_IN_CURRENT].bo, |
||
591 | I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits); |
||
592 | OUT_RELOC(batch, |
||
593 | proc_ctx->frame_store[FRAME_IN_PREVIOUS].bo, |
||
594 | I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits); |
||
595 | OUT_RELOC(batch, |
||
596 | proc_ctx->frame_store[FRAME_IN_STMM].bo, |
||
597 | I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits); |
||
598 | OUT_RELOC(batch, |
||
599 | proc_ctx->frame_store[FRAME_OUT_STMM].bo, |
||
600 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits); |
||
601 | OUT_RELOC(batch, |
||
602 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo, |
||
603 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits); |
||
604 | OUT_RELOC(batch, |
||
605 | proc_ctx->frame_store[FRAME_OUT_CURRENT].bo, |
||
606 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits); |
||
607 | OUT_RELOC(batch, |
||
608 | proc_ctx->frame_store[FRAME_OUT_PREVIOUS].bo, |
||
609 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits); |
||
610 | OUT_RELOC(batch, |
||
611 | proc_ctx->frame_store[FRAME_OUT_STATISTIC].bo, |
||
612 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits); |
||
613 | |||
614 | ADVANCE_VEB_BATCH(batch); |
||
615 | } |
||
616 | |||
617 | |||
618 | void hsw_veb_surface_reference(VADriverContextP ctx, |
||
619 | struct intel_vebox_context *proc_ctx) |
||
620 | { |
||
621 | struct object_surface * obj_surf; |
||
622 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
623 | |||
624 | /* update the input surface */ |
||
625 | obj_surf = SURFACE(proc_ctx->surface_input); |
||
626 | proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = proc_ctx->surface_input; |
||
627 | proc_ctx->frame_store[FRAME_IN_CURRENT].bo = obj_surf->bo; |
||
628 | proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0; |
||
629 | dri_bo_reference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo); |
||
630 | |||
631 | /* update the output surface */ |
||
632 | if(proc_ctx->filters_mask == VPP_DNDI_DN){ |
||
633 | obj_surf = SURFACE(proc_ctx->surface_output); |
||
634 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = proc_ctx->surface_output; |
||
635 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = obj_surf->bo; |
||
636 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0; |
||
637 | dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo); |
||
638 | }else { |
||
639 | obj_surf = SURFACE(proc_ctx->surface_output); |
||
640 | proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = proc_ctx->surface_output; |
||
641 | proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = obj_surf->bo; |
||
642 | proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0; |
||
643 | dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo); |
||
644 | } |
||
645 | } |
||
646 | |||
647 | void hsw_veb_surface_unreference(VADriverContextP ctx, |
||
648 | struct intel_vebox_context *proc_ctx) |
||
649 | { |
||
650 | /* unreference the input surface */ |
||
651 | dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo); |
||
652 | proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = -1; |
||
653 | proc_ctx->frame_store[FRAME_IN_CURRENT].bo = NULL; |
||
654 | proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0; |
||
655 | dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo); |
||
656 | |||
657 | /* unreference the shared output surface */ |
||
658 | if(proc_ctx->filters_mask == VPP_DNDI_DN){ |
||
659 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = -1; |
||
660 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = NULL; |
||
661 | proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0; |
||
662 | dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo); |
||
663 | }else{ |
||
664 | proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = -1; |
||
665 | proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = NULL; |
||
666 | proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0; |
||
667 | dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo); |
||
668 | } |
||
669 | } |
||
670 | |||
671 | void hsw_veb_resource_prepare(VADriverContextP ctx, |
||
672 | struct intel_vebox_context *proc_ctx) |
||
673 | { |
||
674 | VAStatus va_status; |
||
675 | dri_bo *bo; |
||
676 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
||
677 | unsigned int input_fourcc, output_fourcc; |
||
678 | unsigned int input_sampling, output_sampling; |
||
679 | unsigned int input_tiling, output_tiling; |
||
680 | unsigned int i, swizzle; |
||
681 | |||
682 | struct object_surface* obj_surf_in = SURFACE(proc_ctx->surface_input); |
||
683 | struct object_surface* obj_surf_out = SURFACE(proc_ctx->surface_output); |
||
684 | |||
685 | assert(obj_surf_in->orig_width == obj_surf_out->orig_width && |
||
686 | obj_surf_in->orig_height == obj_surf_out->orig_height); |
||
687 | |||
688 | proc_ctx->pic_width = obj_surf_in->orig_width; |
||
689 | proc_ctx->pic_height = obj_surf_in->orig_height; |
||
690 | |||
691 | /* record vebox pipeline input surface format information*/ |
||
692 | if(obj_surf_in->bo == NULL){ |
||
693 | input_fourcc = VA_FOURCC('N','V','1','2'); |
||
694 | input_sampling = SUBSAMPLE_YUV420; |
||
695 | input_tiling = 1; |
||
696 | i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling); |
||
697 | } else { |
||
698 | input_fourcc = obj_surf_in->fourcc; |
||
699 | input_sampling = obj_surf_in->subsampling; |
||
700 | dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle); |
||
701 | input_tiling = !!input_tiling; |
||
702 | } |
||
703 | |||
704 | /* record vebox pipeline output surface format information */ |
||
705 | if(obj_surf_out->bo == NULL){ |
||
706 | output_fourcc = VA_FOURCC('N','V','1','2'); |
||
707 | output_sampling = SUBSAMPLE_YUV420; |
||
708 | output_tiling = 1; |
||
709 | i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling); |
||
710 | }else { |
||
711 | output_fourcc = obj_surf_out->fourcc; |
||
712 | output_sampling = obj_surf_out->subsampling; |
||
713 | dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle); |
||
714 | output_tiling = !!output_tiling; |
||
715 | } |
||
716 | |||
717 | assert(input_fourcc == VA_FOURCC_NV12 || |
||
718 | input_fourcc == VA_FOURCC_YUY2 || |
||
719 | input_fourcc == VA_FOURCC_AYUV || |
||
720 | input_fourcc == VA_FOURCC_RGBA); |
||
721 | assert(output_fourcc == VA_FOURCC_NV12 || |
||
722 | output_fourcc == VA_FOURCC_YUY2 || |
||
723 | output_fourcc == VA_FOURCC_AYUV || |
||
724 | output_fourcc == VA_FOURCC_RGBA); |
||
725 | |||
726 | proc_ctx->fourcc_input = input_fourcc; |
||
727 | proc_ctx->fourcc_output = output_fourcc; |
||
728 | |||
729 | /* allocate vebox pipeline surfaces */ |
||
730 | VASurfaceID surfaces[FRAME_STORE_SUM]; |
||
731 | va_status = i965_CreateSurfaces(ctx, |
||
732 | proc_ctx ->pic_width, |
||
733 | proc_ctx ->pic_height, |
||
734 | VA_RT_FORMAT_YUV420, |
||
735 | FRAME_STORE_SUM, |
||
736 | surfaces); |
||
737 | assert(va_status == VA_STATUS_SUCCESS); |
||
738 | |||
739 | for(i = FRAME_IN_CURRENT; i < FRAME_STORE_SUM; i ++) { |
||
740 | proc_ctx->frame_store[i].surface_id = surfaces[i]; |
||
741 | struct object_surface* obj_surf = SURFACE(surfaces[i]); |
||
742 | if( i == FRAME_IN_CURRENT) { |
||
743 | proc_ctx->frame_store[i].surface_id = proc_ctx->surface_input; |
||
744 | proc_ctx->frame_store[i].bo = (SURFACE(proc_ctx->surface_input))->bo; |
||
745 | proc_ctx->frame_store[i].is_internal_surface = 0; |
||
746 | continue; |
||
747 | }else if( i == FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) { |
||
748 | i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling); |
||
749 | } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){ |
||
750 | i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling); |
||
751 | } else if( i >= FRAME_OUT_CURRENT){ |
||
752 | i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling); |
||
753 | } |
||
754 | proc_ctx->frame_store[i].bo = obj_surf->bo; |
||
755 | dri_bo_reference(proc_ctx->frame_store[i].bo); |
||
756 | proc_ctx->frame_store[i].is_internal_surface = 1; |
||
757 | } |
||
758 | |||
759 | /* alloc dndi state table */ |
||
760 | dri_bo_unreference(proc_ctx->dndi_state_table.bo); |
||
761 | bo = dri_bo_alloc(i965->intel.bufmgr, |
||
762 | "vebox: dndi state Buffer", |
||
763 | 0x1000, 0x1000); |
||
764 | proc_ctx->dndi_state_table.bo = bo; |
||
765 | dri_bo_reference(proc_ctx->dndi_state_table.bo); |
||
766 | |||
767 | /* alloc iecp state table */ |
||
768 | dri_bo_unreference(proc_ctx->iecp_state_table.bo); |
||
769 | bo = dri_bo_alloc(i965->intel.bufmgr, |
||
770 | "vebox: iecp state Buffer", |
||
771 | 0x1000, 0x1000); |
||
772 | proc_ctx->iecp_state_table.bo = bo; |
||
773 | dri_bo_reference(proc_ctx->iecp_state_table.bo); |
||
774 | |||
775 | /* alloc gamut state table */ |
||
776 | dri_bo_unreference(proc_ctx->gamut_state_table.bo); |
||
777 | bo = dri_bo_alloc(i965->intel.bufmgr, |
||
778 | "vebox: gamut state Buffer", |
||
779 | 0x1000, 0x1000); |
||
780 | proc_ctx->gamut_state_table.bo = bo; |
||
781 | dri_bo_reference(proc_ctx->gamut_state_table.bo); |
||
782 | |||
783 | /* alloc vertex state table */ |
||
784 | dri_bo_unreference(proc_ctx->vertex_state_table.bo); |
||
785 | bo = dri_bo_alloc(i965->intel.bufmgr, |
||
786 | "vertex: iecp state Buffer", |
||
787 | 0x1000, 0x1000); |
||
788 | proc_ctx->vertex_state_table.bo = bo; |
||
789 | dri_bo_reference(proc_ctx->vertex_state_table.bo); |
||
790 | |||
791 | } |
||
792 | |||
793 | VAStatus gen75_vebox_process_picture(VADriverContextP ctx, |
||
794 | struct intel_vebox_context *proc_ctx) |
||
795 | { |
||
796 | VAStatus va_status = VA_STATUS_SUCCESS; |
||
797 | |||
798 | if(proc_ctx->is_first_frame) |
||
799 | hsw_veb_resource_prepare(ctx, proc_ctx); |
||
800 | |||
801 | hsw_veb_surface_reference(ctx, proc_ctx); |
||
802 | |||
803 | intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000); |
||
804 | intel_batchbuffer_emit_mi_flush(proc_ctx->batch); |
||
805 | hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE); |
||
806 | hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE); |
||
807 | hsw_veb_state_table_setup(ctx, proc_ctx); |
||
808 | |||
809 | hsw_veb_state_command(ctx, proc_ctx); |
||
810 | hsw_veb_dndi_iecp_command(ctx, proc_ctx); |
||
811 | intel_batchbuffer_end_atomic(proc_ctx->batch); |
||
812 | intel_batchbuffer_flush(proc_ctx->batch); |
||
813 | |||
814 | hsw_veb_surface_unreference(ctx, proc_ctx); |
||
815 | |||
816 | if(proc_ctx->is_first_frame) |
||
817 | proc_ctx->is_first_frame = 0; |
||
818 | |||
819 | return va_status; |
||
820 | } |
||
821 | |||
822 | void gen75_vebox_context_destroy(VADriverContextP ctx, |
||
823 | struct intel_vebox_context *proc_ctx) |
||
824 | { |
||
825 | int i; |
||
826 | /* release vebox pipeline surface */ |
||
827 | for(i = 0; i < FRAME_STORE_SUM; i ++) { |
||
828 | if(proc_ctx->frame_store[i].is_internal_surface){ |
||
829 | dri_bo_unreference(proc_ctx->frame_store[i].bo); |
||
830 | } |
||
831 | proc_ctx->frame_store[i].surface_id = -1; |
||
832 | proc_ctx->frame_store[i].bo = NULL; |
||
833 | } |
||
834 | /* release dndi state table */ |
||
835 | dri_bo_unreference(proc_ctx->dndi_state_table.bo); |
||
836 | proc_ctx->dndi_state_table.bo = NULL; |
||
837 | |||
838 | /* release iecp state table */ |
||
839 | dri_bo_unreference(proc_ctx->iecp_state_table.bo); |
||
840 | proc_ctx->dndi_state_table.bo = NULL; |
||
841 | |||
842 | intel_batchbuffer_free(proc_ctx->batch); |
||
843 | |||
844 | free(proc_ctx); |
||
845 | } |
||
846 | |||
847 | struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx) |
||
848 | { |
||
849 | struct intel_driver_data *intel = intel_driver_data(ctx); |
||
850 | struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context)); |
||
851 | |||
852 | proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0); |
||
853 | memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM); |
||
854 | |||
855 | proc_context->filters_mask = 0; |
||
856 | proc_context->is_first_frame = 1; |
||
857 | proc_context->filters_mask = 0; |
||
858 | |||
859 | return proc_context; |
||
860 | }>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>(out_int_bits><(out_int_bits>(out_int_bits><(out_int_bits>><>><>> |
||
861 |