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 <xiaowei.a.li@intel.com>
26 * Li Zhong <zhong.li@intel.com>
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 #include <math.h>
34
35 #include "intel_batchbuffer.h"
36 #include "intel_driver.h"
37 #include "i965_defines.h"
38 #include "i965_structs.h"
39 #include "gen75_vpp_vebox.h"
40 #include "intel_media.h"
41
42 #include "i965_post_processing.h"
43
44 #define PI 3.1415926
45
46 extern VAStatus
47 i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
48
49 extern VAStatus
50 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
51
52 extern VAStatus
53 i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
54
55 extern VAStatus
56 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
57
58 VAStatus
vpp_surface_convert(VADriverContextP ctx,struct object_surface * src_obj_surf,struct object_surface * dst_obj_surf)59 vpp_surface_convert(VADriverContextP ctx, struct object_surface *src_obj_surf,
60 struct object_surface *dst_obj_surf)
61 {
62 VAStatus va_status = VA_STATUS_SUCCESS;
63
64 assert(src_obj_surf->orig_width == dst_obj_surf->orig_width);
65 assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
66
67 VARectangle src_rect, dst_rect;
68 src_rect.x = dst_rect.x = 0;
69 src_rect.y = dst_rect.y = 0;
70 src_rect.width = dst_rect.width = src_obj_surf->orig_width;
71 src_rect.height = dst_rect.height = src_obj_surf->orig_height;
72
73 struct i965_surface src_surface, dst_surface;
74 src_surface.base = (struct object_base *)src_obj_surf;
75 src_surface.type = I965_SURFACE_TYPE_SURFACE;
76 src_surface.flags = I965_SURFACE_FLAG_FRAME;
77
78 dst_surface.base = (struct object_base *)dst_obj_surf;
79 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
80 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
81
82 va_status = i965_image_processing(ctx,
83 &src_surface,
84 &src_rect,
85 &dst_surface,
86 &dst_rect);
87 return va_status;
88 }
89
90 static VAStatus
vpp_surface_scaling(VADriverContextP ctx,struct object_surface * src_obj_surf,struct object_surface * dst_obj_surf,uint32_t flags)91 vpp_surface_scaling(VADriverContextP ctx, struct object_surface *src_obj_surf,
92 struct object_surface *dst_obj_surf, uint32_t flags)
93 {
94 VAStatus va_status = VA_STATUS_SUCCESS;
95
96 assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
97 assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
98
99 VARectangle src_rect, dst_rect;
100 src_rect.x = 0;
101 src_rect.y = 0;
102 src_rect.width = src_obj_surf->orig_width;
103 src_rect.height = src_obj_surf->orig_height;
104
105 dst_rect.x = 0;
106 dst_rect.y = 0;
107 dst_rect.width = dst_obj_surf->orig_width;
108 dst_rect.height = dst_obj_surf->orig_height;
109
110 va_status = i965_scaling_processing(ctx,
111 src_obj_surf,
112 &src_rect,
113 dst_obj_surf,
114 &dst_rect,
115 flags);
116
117 return va_status;
118 }
119
120 static VAStatus
vpp_sharpness_filtering(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)121 vpp_sharpness_filtering(VADriverContextP ctx,
122 struct intel_vebox_context *proc_ctx)
123 {
124 VAStatus va_status = VA_STATUS_SUCCESS;
125
126 if (proc_ctx->vpp_gpe_ctx == NULL) {
127 proc_ctx->vpp_gpe_ctx = vpp_gpe_context_init(ctx);
128 }
129
130 proc_ctx->vpp_gpe_ctx->pipeline_param = proc_ctx->pipeline_param;
131 proc_ctx->vpp_gpe_ctx->surface_pipeline_input_object = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
132 proc_ctx->vpp_gpe_ctx->surface_output_object = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
133
134 va_status = vpp_gpe_process_picture(ctx, proc_ctx->vpp_gpe_ctx);
135
136 return va_status;
137 }
138
hsw_veb_dndi_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)139 void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
140 {
141 struct i965_driver_data *i965 = i965_driver_data(ctx);
142 unsigned int* p_table ;
143 unsigned int progressive_dn = 1;
144 unsigned int dndi_top_first = 0;
145 unsigned int is_mcdi_enabled = 0;
146
147 if (proc_ctx->is_di_enabled) {
148 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
149 proc_ctx->filter_di;
150
151 progressive_dn = 0;
152
153 /* If we are in "First Frame" mode, i.e. past frames are not
154 available for motion measure, then don't use the TFF flag */
155 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
156 VA_DEINTERLACING_BOTTOM_FIELD :
157 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
158
159 is_mcdi_enabled =
160 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
161 }
162
163 /*
164 VAProcFilterParameterBufferDeinterlacing *di_param =
165 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
166
167 VAProcFilterParameterBuffer * dn_param =
168 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
169 */
170 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
171
172 if (IS_HASWELL(i965->intel.device_info))
173 *p_table ++ = 0; // reserved . w0
174
175 *p_table ++ = (140 << 24 | // denoise STAD threshold . w1
176 192 << 16 | // dnmh_history_max
177 0 << 12 | // reserved
178 7 << 8 | // dnmh_delta[3:0]
179 38); // denoise ASD threshold
180
181 *p_table ++ = (0 << 30 | // reserved . w2
182 0 << 24 | // temporal diff th
183 0 << 22 | // reserved.
184 0 << 16 | // low temporal diff th
185 2 << 13 | // STMM C2
186 1 << 8 | // denoise moving pixel th
187 38); // denoise th for sum of complexity measure
188
189 *p_table ++ = (0 << 30 | // reserved . w3
190 12 << 24 | // good neighbor th[5:0]
191 9 << 20 | // CAT slope minus 1
192 5 << 16 | // SAD Tight in
193 0 << 14 | // smooth mv th
194 0 << 12 | // reserved
195 1 << 8 | // bne_edge_th[3:0]
196 20); // block noise estimate noise th
197
198 *p_table ++ = (0 << 31 | // STMM blending constant select. w4
199 64 << 24 | // STMM trc1
200 125 << 16 | // STMM trc2
201 0 << 14 | // reserved
202 30 << 8 | // VECM_mul
203 150); // maximum STMM
204
205 *p_table ++ = (118 << 24 | // minumum STMM . W5
206 0 << 22 | // STMM shift down
207 1 << 20 | // STMM shift up
208 5 << 16 | // STMM output shift
209 100 << 8 | // SDI threshold
210 5); // SDI delta
211
212 *p_table ++ = (50 << 24 | // SDI fallback mode 1 T1 constant . W6
213 100 << 16 | // SDI fallback mode 1 T2 constant
214 37 << 8 | // SDI fallback mode 2 constant(angle2x1)
215 175); // FMD temporal difference threshold
216
217 *p_table ++ = (16 << 24 | // FMD #1 vertical difference th . w7
218 100 << 16 | // FMD #2 vertical difference th
219 0 << 14 | // CAT th1
220 2 << 8 | // FMD tear threshold
221 is_mcdi_enabled << 7 | // MCDI Enable, use motion compensated deinterlace algorithm
222 progressive_dn << 6 | // progressive DN
223 0 << 4 | // reserved
224 dndi_top_first << 3 | // DN/DI Top First
225 0); // reserved
226
227 *p_table ++ = (0 << 29 | // reserved . W8
228 32 << 23 | // dnmh_history_init[5:0]
229 10 << 19 | // neighborPixel th
230 0 << 18 | // reserved
231 0 << 16 | // FMD for 2nd field of previous frame
232 25 << 10 | // MC pixel consistency th
233 0 << 8 | // FMD for 1st field for current frame
234 10 << 4 | // SAD THB
235 5); // SAD THA
236
237 *p_table ++ = (0 << 24 | // reserved
238 140 << 16 | // chr_dnmh_stad_th
239 0 << 13 | // reserved
240 1 << 12 | // chrome denoise enable
241 13 << 6 | // chr temp diff th
242 7); // chr temp diff low
243
244 if (IS_GEN8(i965->intel.device_info) ||
245 IS_GEN9(i965->intel.device_info) ||
246 IS_GEN10(i965->intel.device_info))
247 *p_table ++ = 0; // parameters for hot pixel,
248 }
249
250 //Set default values for STDE
set_std_table_default(struct intel_vebox_context * proc_ctx,unsigned int * p_table)251 void set_std_table_default(struct intel_vebox_context *proc_ctx, unsigned int *p_table)
252 {
253
254 //DWord 15
255 *p_table ++ = (0 << 31 | // Reserved
256 0x3F8 << 21 | // SATB1 (10 bits, default 8, optimized value -8)
257 31 << 14 | // SATP3
258 6 << 7 | // SATP2
259 0x7A); // SATP1 (7 bits, default 6, optimized value -6)
260
261 //DWord 16
262 *p_table ++ = (0 << 31 | // Reserved
263 297 << 20 | // SATS0
264 124 << 10 | // SATB3
265 8); // SATB2
266
267 //DWord 17
268 *p_table ++ = (0 << 22 | // Reserved
269 297 << 11 | // SATS2
270 85); // SATS1
271
272 //DWord 18
273 *p_table ++ = (14 << 25 | // HUEP3
274 6 << 18 | // HUEP2
275 0x7A << 11 | // HUEP1 (7 bits, default value -6 = 7Ah)
276 256); // SATS3
277
278 //DWord 19
279 *p_table ++ = (0 << 30 | // Reserved
280 256 << 20 | // HUEB3
281 8 << 10 | // HUEB2
282 0x3F8); // HUEB1 (10 bits, default value 8, optimized value -8)
283
284 //DWord 20
285 *p_table ++ = (0 << 22 | // Reserved
286 85 << 11 | // HUES1
287 384); // HUES0
288
289 //DWord 21
290 *p_table ++ = (0 << 22 | // Reserved
291 256 << 11 | // HUES3
292 384); // HUES2
293
294 //DWord 22
295 *p_table ++ = (0 << 31 | // Reserved
296 0 << 21 | // SATB1_DARK
297 31 << 14 | // SATP3_DARK
298 31 << 7 | // SATP2_DARK
299 0x7B); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
300
301 //DWord 23
302 *p_table ++ = (0 << 31 | // Reserved
303 305 << 20 | // SATS0_DARK
304 124 << 10 | // SATB3_DARK
305 124); // SATB2_DARK
306
307 //DWord 24
308 *p_table ++ = (0 << 22 | // Reserved
309 256 << 11 | // SATS2_DARK
310 220); // SATS1_DARK
311
312 //DWord 25
313 *p_table ++ = (14 << 25 | // HUEP3_DARK
314 14 << 18 | // HUEP2_DARK
315 14 << 11 | // HUEP1_DARK
316 256); // SATS3_DARK
317
318 //DWord 26
319 *p_table ++ = (0 << 30 | // Reserved
320 56 << 20 | // HUEB3_DARK
321 56 << 10 | // HUEB2_DARK
322 56); // HUEB1_DARK
323
324 //DWord 27
325 *p_table ++ = (0 << 22 | // Reserved
326 256 << 11 | // HUES1_DARK
327 256); // HUES0_DARK
328
329 //DWord 28
330 *p_table ++ = (0 << 22 | // Reserved
331 256 << 11 | // HUES3_DARK
332 256); // HUES2_DARK
333 }
334
335 //Set values for STDE factor 3
set_std_table_3(struct intel_vebox_context * proc_ctx,unsigned int * p_table)336 void set_std_table_3(struct intel_vebox_context *proc_ctx, unsigned int *p_table)
337 {
338
339 //DWord 15
340 *p_table ++ = (0 << 31 | // Reserved
341 1016 << 21 | // SATB1 (10 bits, default 8, optimized value 1016)
342 31 << 14 | // SATP3
343 6 << 7 | // SATP2
344 122); // SATP1 (7 bits, default 6, optimized value 122)
345
346 //DWord 16
347 *p_table ++ = (0 << 31 | // Reserved
348 297 << 20 | // SATS0
349 124 << 10 | // SATB3
350 8); // SATB2
351
352 //DWord 17
353 *p_table ++ = (0 << 22 | // Reserved
354 297 << 11 | // SATS2
355 85); // SATS1
356
357 //DWord 18
358 *p_table ++ = (14 << 25 | // HUEP3
359 6 << 18 | // HUEP2
360 122 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized 122)
361 256); // SATS3
362
363 //DWord 19
364 *p_table ++ = (0 << 30 | // Reserved
365 56 << 20 | // HUEB3 (default 256, optimized 56)
366 8 << 10 | // HUEB2
367 1016); // HUEB1 (10 bits, default value 8, optimized value 1016)
368
369 //DWord 20
370 *p_table ++ = (0 << 22 | // Reserved
371 85 << 11 | // HUES1
372 384); // HUES0
373
374 //DWord 21
375 *p_table ++ = (0 << 22 | // Reserved
376 256 << 11 | // HUES3
377 384); // HUES2
378
379 //DWord 22
380 *p_table ++ = (0 << 31 | // Reserved
381 0 << 21 | // SATB1_DARK
382 31 << 14 | // SATP3_DARK
383 31 << 7 | // SATP2_DARK
384 123); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
385
386 //DWord 23
387 *p_table ++ = (0 << 31 | // Reserved
388 305 << 20 | // SATS0_DARK
389 124 << 10 | // SATB3_DARK
390 124); // SATB2_DARK
391
392 //DWord 24
393 *p_table ++ = (0 << 22 | // Reserved
394 256 << 11 | // SATS2_DARK
395 220); // SATS1_DARK
396
397 //DWord 25
398 *p_table ++ = (14 << 25 | // HUEP3_DARK
399 14 << 18 | // HUEP2_DARK
400 14 << 11 | // HUEP1_DARK
401 256); // SATS3_DARK
402
403 //DWord 26
404 *p_table ++ = (0 << 30 | // Reserved
405 56 << 20 | // HUEB3_DARK
406 56 << 10 | // HUEB2_DARK
407 56); // HUEB1_DARK
408
409 //DWord 27
410 *p_table ++ = (0 << 22 | // Reserved
411 256 << 11 | // HUES1_DARK
412 256); // HUES0_DARK
413
414 //DWord 28
415 *p_table ++ = (0 << 22 | // Reserved
416 256 << 11 | // HUES3_DARK
417 256); // HUES2_DARK
418 }
419
420 //Set values for STDE factor 6
set_std_table_6(struct intel_vebox_context * proc_ctx,unsigned int * p_table)421 void set_std_table_6(struct intel_vebox_context *proc_ctx, unsigned int *p_table)
422 {
423
424 //DWord 15
425 *p_table ++ = (0 << 31 | // Reserved
426 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
427 31 << 14 | // SATP3
428 31 << 7 | // SATP2 (default 6, optimized 31)
429 114); // SATP1 (7 bits, default 6, optimized value 114)
430
431 //DWord 16
432 *p_table ++ = (0 << 31 | // Reserved
433 467 << 20 | // SATS0 (default 297, optimized 467)
434 124 << 10 | // SATB3
435 124); // SATB2
436
437 //DWord 17
438 *p_table ++ = (0 << 22 | // Reserved
439 256 << 11 | // SATS2 (default 297, optimized 256)
440 176); // SATS1
441
442 //DWord 18
443 *p_table ++ = (14 << 25 | // HUEP3
444 14 << 18 | // HUEP2
445 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
446 256); // SATS3
447
448 //DWord 19
449 *p_table ++ = (0 << 30 | // Reserved
450 56 << 20 | // HUEB3
451 56 << 10 | // HUEB2
452 56); // HUEB1 (10 bits, default value 8, optimized value 56)
453
454 //DWord 20
455 *p_table ++ = (0 << 22 | // Reserved
456 256 << 11 | // HUES1
457 256); // HUES0
458
459 //DWord 21
460 *p_table ++ = (0 << 22 | // Reserved
461 256 << 11 | // HUES3
462 256); // HUES2
463
464 //DWord 22
465 *p_table ++ = (0 << 31 | // Reserved
466 0 << 21 | // SATB1_DARK
467 31 << 14 | // SATP3_DARK
468 31 << 7 | // SATP2_DARK
469 123); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
470
471 //DWord 23
472 *p_table ++ = (0 << 31 | // Reserved
473 305 << 20 | // SATS0_DARK
474 124 << 10 | // SATB3_DARK
475 124); // SATB2_DARK
476
477 //DWord 24
478 *p_table ++ = (0 << 22 | // Reserved
479 256 << 11 | // SATS2_DARK
480 220); // SATS1_DARK
481
482 //DWord 25
483 *p_table ++ = (14 << 25 | // HUEP3_DARK
484 14 << 18 | // HUEP2_DARK
485 14 << 11 | // HUEP1_DARK
486 256); // SATS3_DARK
487
488 //DWord 26
489 *p_table ++ = (0 << 30 | // Reserved
490 56 << 20 | // HUEB3_DARK
491 56 << 10 | // HUEB2_DARK
492 56); // HUEB1_DARK
493
494 //DWord 27
495 *p_table ++ = (0 << 22 | // Reserved
496 256 << 11 | // HUES1_DARK
497 256); // HUES0_DARK
498
499 //DWord 28
500 *p_table ++ = (0 << 22 | // Reserved
501 256 << 11 | // HUES3_DARK
502 256); // HUES2_DARK
503 }
504
505 //Set values for STDE factor 9
set_std_table_9(struct intel_vebox_context * proc_ctx,unsigned int * p_table)506 void set_std_table_9(struct intel_vebox_context *proc_ctx, unsigned int *p_table)
507 {
508
509 //DWord 15
510 *p_table ++ = (0 << 31 | // Reserved
511 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
512 31 << 14 | // SATP3
513 31 << 7 | // SATP2 (default 6, optimized 31)
514 108); // SATP1 (7 bits, default 6, optimized value 108)
515
516 //DWord 16
517 *p_table ++ = (0 << 31 | // Reserved
518 721 << 20 | // SATS0 (default 297, optimized 721)
519 124 << 10 | // SATB3
520 124); // SATB2
521
522 //DWord 17
523 *p_table ++ = (0 << 22 | // Reserved
524 256 << 11 | // SATS2 (default 297, optimized 256)
525 156); // SATS1 (default 176, optimized 156)
526
527 //DWord 18
528 *p_table ++ = (14 << 25 | // HUEP3
529 14 << 18 | // HUEP2
530 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
531 256); // SATS3
532
533 //DWord 19
534 *p_table ++ = (0 << 30 | // Reserved
535 56 << 20 | // HUEB3
536 56 << 10 | // HUEB2
537 56); // HUEB1 (10 bits, default value 8, optimized value 56)
538
539 //DWord 20
540 *p_table ++ = (0 << 22 | // Reserved
541 256 << 11 | // HUES1
542 256); // HUES0
543
544 //DWord 21
545 *p_table ++ = (0 << 22 | // Reserved
546 256 << 11 | // HUES3
547 256); // HUES2
548
549 //DWord 22
550 *p_table ++ = (0 << 31 | // Reserved
551 0 << 21 | // SATB1_DARK
552 31 << 14 | // SATP3_DARK
553 31 << 7 | // SATP2_DARK
554 123); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
555
556 //DWord 23
557 *p_table ++ = (0 << 31 | // Reserved
558 305 << 20 | // SATS0_DARK
559 124 << 10 | // SATB3_DARK
560 124); // SATB2_DARK
561
562 //DWord 24
563 *p_table ++ = (0 << 22 | // Reserved
564 256 << 11 | // SATS2_DARK
565 220); // SATS1_DARK
566
567 //DWord 25
568 *p_table ++ = (14 << 25 | // HUEP3_DARK
569 14 << 18 | // HUEP2_DARK
570 14 << 11 | // HUEP1_DARK
571 256); // SATS3_DARK
572
573 //DWord 26
574 *p_table ++ = (0 << 30 | // Reserved
575 56 << 20 | // HUEB3_DARK
576 56 << 10 | // HUEB2_DARK
577 56); // HUEB1_DARK
578
579 //DWord 27
580 *p_table ++ = (0 << 22 | // Reserved
581 256 << 11 | // HUES1_DARK
582 256); // HUES0_DARK
583
584 //DWord 28
585 *p_table ++ = (0 << 22 | // Reserved
586 256 << 11 | // HUES3_DARK
587 256); // HUES2_DARK
588 }
589
590
hsw_veb_iecp_std_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)591 void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
592 {
593 unsigned int *p_table = (unsigned int *)proc_ctx->iecp_state_table.ptr;
594
595 if (!(proc_ctx->filters_mask & VPP_IECP_STD_STE)) {
596 memset(p_table, 0, 29 * 4);
597 } else {
598 int stde_factor = 0; //default value
599 VAProcFilterParameterBuffer * std_param = (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_std;
600 stde_factor = std_param->value;
601
602 //DWord 0
603 *p_table ++ = (154 << 24 | // V_Mid
604 110 << 16 | // U_Mid
605 14 << 10 | // Hue_Max
606 31 << 4 | // Sat_Max
607 0 << 3 | // Reserved
608 0 << 2 | // Output Control is set to output the 1=STD score /0=Output Pixels
609 1 << 1 | // Set STE Enable
610 1); // Set STD Enable
611
612 //DWord 1
613 *p_table ++ = (0 << 31 | // Reserved
614 4 << 28 | // Diamond Margin
615 0 << 21 | // Diamond_du
616 3 << 18 | // HS_Margin
617 79 << 10 | // Cos(alpha)
618 0 << 8 | // Reserved
619 101); // Sin(alpha)
620
621 //DWord 2
622 *p_table ++ = (0 << 21 | // Reserved
623 100 << 13 | // Diamond_alpha
624 35 << 7 | // Diamond_Th
625 0);
626
627 //DWord 3
628 *p_table ++ = (254 << 24 | // Y_point_3
629 47 << 16 | // Y_point_2
630 46 << 8 | // Y_point_1
631 1 << 7 | // VY_STD_Enable
632 0); // Reserved
633
634 //DWord 4
635 *p_table ++ = (0 << 18 | // Reserved
636 31 << 13 | // Y_slope_2
637 31 << 8 | // Y_slope_1
638 255); // Y_point_4
639
640 //DWord 5
641 *p_table ++ = (400 << 16 | // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
642 3300); // INV_Margin_VYL => 1/Margin_VYL
643
644 //DWord 6
645 *p_table ++ = (216 << 24 | // P1L
646 46 << 16 | // P0L
647 1600); // INV_Margin_VYU
648
649 //DWord 7
650 *p_table ++ = (130 << 24 | // B1L
651 133 << 16 | // B0L
652 236 << 8 | // P3L
653 236); // P2L
654
655 //DWord 8
656 *p_table ++ = (0 << 27 | // Reserved
657 0x7FB << 16 | // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
658 130 << 8 | // B3L
659 130);
660
661 //DWord 9
662 *p_table ++ = (0 << 22 | // Reserved
663 0 << 11 | // S2L
664 0); // S1L
665
666 //DWord 10
667 *p_table ++ = (0 << 27 | // Reserved
668 66 << 19 | // P1U
669 46 << 11 | // P0U
670 0); // S3
671
672 //DWord 11
673 *p_table ++ = (163 << 24 | // B1U
674 143 << 16 | // B0U
675 236 << 8 | // P3U
676 150); // P2U
677
678 //DWord 12
679 *p_table ++ = (0 << 27 | // Reserved
680 256 << 16 | // S0U
681 200 << 8 | // B3U
682 200); // B2U
683
684 //DWord 13
685 *p_table ++ = (0 << 22 | // Reserved
686 0x74D << 11 | // S2U (11 bits, Default value -179 = F4Dh)
687 113); // S1U
688
689 //DWoord 14
690 *p_table ++ = (0 << 28 | // Reserved
691 20 << 20 | // Skin_types_margin
692 120 << 12 | // Skin_types_thresh
693 1 << 11 | // Skin_Types_Enable
694 0); // S3U
695
696 //Set DWord 15 through DWord 28 in their respective methods.
697 switch (stde_factor) {
698 case 3:
699 set_std_table_3(proc_ctx, p_table);
700 break;
701
702 case 6:
703 set_std_table_6(proc_ctx, p_table);
704 break;
705
706 case 9:
707 set_std_table_9(proc_ctx, p_table);
708 break;
709
710 default:
711 set_std_table_default(proc_ctx, p_table);
712 break;
713 }
714 }//end of else
715 }
716
hsw_veb_iecp_ace_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)717 void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
718 {
719 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
720
721 if (!(proc_ctx->filters_mask & VPP_IECP_ACE)) {
722 memset(p_table, 0, 13 * 4);
723 } else {
724 *p_table ++ = 0x00000068;
725 *p_table ++ = 0x4c382410;
726 *p_table ++ = 0x9c887460;
727 *p_table ++ = 0xebd8c4b0;
728 *p_table ++ = 0x604c3824;
729
730 *p_table ++ = 0xb09c8874;
731 *p_table ++ = 0x0000d8c4;
732 *p_table ++ = 0x00000000;
733 *p_table ++ = 0x00000000;
734 *p_table ++ = 0x00000000;
735
736 *p_table ++ = 0x00000000;
737 *p_table ++ = 0x00000000;
738 *p_table ++ = 0x00000000;
739 }
740 }
741
hsw_veb_iecp_tcc_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)742 void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
743 {
744 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
745 // VAProcFilterParameterBuffer * tcc_param =
746 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
747
748 if (!(proc_ctx->filters_mask & VPP_IECP_TCC)) {
749 memset(p_table, 0, 11 * 4);
750 } else {
751 *p_table ++ = 0x00000000;
752 *p_table ++ = 0x00000000;
753 *p_table ++ = 0x1e34cc91;
754 *p_table ++ = 0x3e3cce91;
755 *p_table ++ = 0x02e80195;
756
757 *p_table ++ = 0x0197046b;
758 *p_table ++ = 0x01790174;
759 *p_table ++ = 0x00000000;
760 *p_table ++ = 0x00000000;
761 *p_table ++ = 0x03030000;
762
763 *p_table ++ = 0x009201c0;
764 }
765 }
766
hsw_veb_iecp_pro_amp_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)767 void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
768 {
769 unsigned int contrast = 0x80; //default
770 int brightness = 0x00; //default
771 int cos_c_s = 256 ; //default
772 int sin_c_s = 0; //default
773 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
774
775 if (!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)) {
776 memset(p_table, 0, 2 * 4);
777 } else {
778 float src_saturation = 1.0;
779 float src_hue = 0.0;
780 float src_contrast = 1.0;
781 float src_brightness = 0.0;
782 float tmp_value = 0.0;
783 unsigned int i = 0;
784
785 VAProcFilterParameterBufferColorBalance * amp_params =
786 (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
787
788 for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++) {
789 VAProcColorBalanceType attrib = amp_params[i].attrib;
790
791 if (attrib == VAProcColorBalanceHue) {
792 src_hue = amp_params[i].value; //(-180.0, 180.0)
793 } else if (attrib == VAProcColorBalanceSaturation) {
794 src_saturation = amp_params[i].value; //(0.0, 10.0)
795 } else if (attrib == VAProcColorBalanceBrightness) {
796 src_brightness = amp_params[i].value; // (-100.0, 100.0)
797 brightness = intel_format_convert(src_brightness, 7, 4, 1);
798 } else if (attrib == VAProcColorBalanceContrast) {
799 src_contrast = amp_params[i].value; // (0.0, 10.0)
800 contrast = intel_format_convert(src_contrast, 4, 7, 0);
801 }
802 }
803
804 tmp_value = cos(src_hue / 180 * PI) * src_contrast * src_saturation;
805 cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
806
807 tmp_value = sin(src_hue / 180 * PI) * src_contrast * src_saturation;
808 sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
809
810 *p_table ++ = (0 << 28 | //reserved
811 contrast << 17 | //contrast value (U4.7 format)
812 0 << 13 | //reserved
813 brightness << 1 | // S7.4 format
814 1);
815
816 *p_table ++ = (cos_c_s << 16 | // cos(h) * contrast * saturation
817 sin_c_s); // sin(h) * contrast * saturation
818
819 }
820 }
821
822
hsw_veb_iecp_csc_transform_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)823 void hsw_veb_iecp_csc_transform_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
824 {
825 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
826 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
827 float v_coef[3] = {0.0, 0.0, 0.0};
828 float u_coef[3] = {0.0, 0.0, 0.0};
829 int is_transform_enabled = 0;
830
831 if (!(proc_ctx->filters_mask & VPP_IECP_CSC_TRANSFORM)) {
832 memset(p_table, 0, 8 * 4);
833 return;
834 }
835
836 if (proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
837 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
838 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
839 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
840 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
841
842 tran_coef[0] = 0.257;
843 tran_coef[1] = 0.504;
844 tran_coef[2] = 0.098;
845 tran_coef[3] = -0.148;
846 tran_coef[4] = -0.291;
847 tran_coef[5] = 0.439;
848 tran_coef[6] = 0.439;
849 tran_coef[7] = -0.368;
850 tran_coef[8] = -0.071;
851
852 u_coef[0] = 16 * 4;
853 u_coef[1] = 128 * 4;
854 u_coef[2] = 128 * 4;
855
856 is_transform_enabled = 1;
857 } else if ((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
858 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
859 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
860 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
861 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
862 tran_coef[0] = 1.164;
863 tran_coef[1] = 0.000;
864 tran_coef[2] = 1.569;
865 tran_coef[3] = 1.164;
866 tran_coef[4] = -0.813;
867 tran_coef[5] = -0.392;
868 tran_coef[6] = 1.164;
869 tran_coef[7] = 2.017;
870 tran_coef[8] = 0.000;
871
872 v_coef[0] = -16 * 4;
873 v_coef[1] = -128 * 4;
874 v_coef[2] = -128 * 4;
875
876 is_transform_enabled = 1;
877 } else if (proc_ctx->fourcc_input != proc_ctx->fourcc_output) {
878 //enable when input and output format are different.
879 is_transform_enabled = 1;
880 }
881
882 if (is_transform_enabled == 0) {
883 memset(p_table, 0, 8 * 4);
884 } else {
885 *p_table ++ = (0 << 29 | //reserved
886 intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
887 intel_format_convert(tran_coef[0], 2, 10, 1) << 3 | //c0, s2.10 format
888 0 << 2 | //reserved
889 0 << 1 | // yuv_channel swap
890 is_transform_enabled);
891
892 *p_table ++ = (0 << 26 | //reserved
893 intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
894 intel_format_convert(tran_coef[2], 2, 10, 1));
895
896 *p_table ++ = (0 << 26 | //reserved
897 intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
898 intel_format_convert(tran_coef[4], 2, 10, 1));
899
900 *p_table ++ = (0 << 26 | //reserved
901 intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
902 intel_format_convert(tran_coef[6], 2, 10, 1));
903
904 *p_table ++ = (0 << 13 | //reserved
905 intel_format_convert(tran_coef[8], 2, 10, 1));
906
907 *p_table ++ = (0 << 22 | //reserved
908 intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
909 intel_format_convert(v_coef[0], 10, 0, 1));
910
911 *p_table ++ = (0 << 22 | //reserved
912 intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
913 intel_format_convert(v_coef[1], 10, 0, 1));
914
915 *p_table ++ = (0 << 22 | //reserved
916 intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
917 intel_format_convert(v_coef[2], 10, 0, 1));
918 }
919 }
920
hsw_veb_iecp_aoi_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)921 void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
922 {
923 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
924 // VAProcFilterParameterBuffer * tcc_param =
925 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
926
927 if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
928 memset(p_table, 0, 3 * 4);
929 } else {
930 *p_table ++ = 0x00000000;
931 *p_table ++ = 0x00030000;
932 *p_table ++ = 0x00030000;
933 }
934 }
935
hsw_veb_state_table_setup(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)936 void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
937 {
938 if (proc_ctx->filters_mask & VPP_DNDI_MASK) {
939 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
940 dri_bo_map(dndi_bo, 1);
941 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
942
943 hsw_veb_dndi_table(ctx, proc_ctx);
944
945 dri_bo_unmap(dndi_bo);
946 }
947
948 if (proc_ctx->filters_mask & VPP_IECP_MASK) {
949 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
950 dri_bo_map(iecp_bo, 1);
951 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
952 memset(proc_ctx->iecp_state_table.ptr, 0, 97 * 4);
953
954 hsw_veb_iecp_std_table(ctx, proc_ctx);
955 hsw_veb_iecp_ace_table(ctx, proc_ctx);
956 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
957 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
958 hsw_veb_iecp_csc_transform_table(ctx, proc_ctx);
959 hsw_veb_iecp_aoi_table(ctx, proc_ctx);
960
961 dri_bo_unmap(iecp_bo);
962 }
963 }
964
hsw_veb_state_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)965 void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
966 {
967 struct intel_batchbuffer *batch = proc_ctx->batch;
968
969 BEGIN_VEB_BATCH(batch, 6);
970 OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
971 OUT_VEB_BATCH(batch,
972 0 << 26 | // state surface control bits
973 0 << 11 | // reserved.
974 0 << 10 | // pipe sync disable
975 proc_ctx->current_output_type << 8 | // DI output frame
976 1 << 7 | // 444->422 downsample method
977 1 << 6 | // 422->420 downsample method
978 proc_ctx->is_first_frame << 5 | // DN/DI first frame
979 proc_ctx->is_di_enabled << 4 | // DI enable
980 proc_ctx->is_dn_enabled << 3 | // DN enable
981 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
982 0 << 1 | // ColorGamutCompressionEnable
983 0) ; // ColorGamutExpansionEnable.
984
985 OUT_RELOC(batch,
986 proc_ctx->dndi_state_table.bo,
987 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
988
989 OUT_RELOC(batch,
990 proc_ctx->iecp_state_table.bo,
991 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
992
993 OUT_RELOC(batch,
994 proc_ctx->gamut_state_table.bo,
995 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
996
997 OUT_RELOC(batch,
998 proc_ctx->vertex_state_table.bo,
999 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1000
1001 ADVANCE_VEB_BATCH(batch);
1002 }
1003
hsw_veb_surface_state(VADriverContextP ctx,struct intel_vebox_context * proc_ctx,unsigned int is_output)1004 void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
1005 {
1006 struct intel_batchbuffer *batch = proc_ctx->batch;
1007 unsigned int u_offset_y = 0, v_offset_y = 0;
1008 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
1009 unsigned int surface_format = PLANAR_420_8;
1010 struct object_surface* obj_surf = NULL;
1011 unsigned int surface_pitch = 0;
1012 unsigned int half_pitch_chroma = 0;
1013
1014 if (is_output) {
1015 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
1016 } else {
1017 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1018 }
1019
1020 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
1021 obj_surf->fourcc == VA_FOURCC_YUY2 ||
1022 obj_surf->fourcc == VA_FOURCC_AYUV ||
1023 obj_surf->fourcc == VA_FOURCC_RGBA);
1024
1025 if (obj_surf->fourcc == VA_FOURCC_NV12) {
1026 surface_format = PLANAR_420_8;
1027 surface_pitch = obj_surf->width;
1028 is_uv_interleaved = 1;
1029 half_pitch_chroma = 0;
1030 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
1031 surface_format = YCRCB_NORMAL;
1032 surface_pitch = obj_surf->width * 2;
1033 is_uv_interleaved = 0;
1034 half_pitch_chroma = 0;
1035 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
1036 surface_format = PACKED_444A_8;
1037 surface_pitch = obj_surf->width * 4;
1038 is_uv_interleaved = 0;
1039 half_pitch_chroma = 0;
1040 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
1041 surface_format = R8G8B8A8_UNORM_SRGB;
1042 surface_pitch = obj_surf->width * 4;
1043 is_uv_interleaved = 0;
1044 half_pitch_chroma = 0;
1045 }
1046
1047 u_offset_y = obj_surf->y_cb_offset;
1048 v_offset_y = obj_surf->y_cr_offset;
1049
1050 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
1051
1052 BEGIN_VEB_BATCH(batch, 6);
1053 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
1054 OUT_VEB_BATCH(batch,
1055 0 << 1 | // reserved
1056 is_output); // surface indentification.
1057
1058 OUT_VEB_BATCH(batch,
1059 (obj_surf->orig_height - 1) << 18 | // height . w3
1060 (obj_surf->orig_width - 1) << 4 | // width
1061 0); // reserve
1062
1063 OUT_VEB_BATCH(batch,
1064 surface_format << 28 | // surface format, YCbCr420. w4
1065 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
1066 0 << 20 | // reserved
1067 (surface_pitch - 1) << 3 | // surface pitch, 64 align
1068 half_pitch_chroma << 2 | // half pitch for chrome
1069 !!tiling << 1 | // tiled surface, linear surface used
1070 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
1071
1072 OUT_VEB_BATCH(batch,
1073 0 << 29 | // reserved . w5
1074 0 << 16 | // X offset for V(Cb)
1075 0 << 15 | // reserved
1076 u_offset_y); // Y offset for V(Cb)
1077
1078 OUT_VEB_BATCH(batch,
1079 0 << 29 | // reserved . w6
1080 0 << 16 | // X offset for V(Cr)
1081 0 << 15 | // reserved
1082 v_offset_y); // Y offset for V(Cr)
1083
1084 ADVANCE_VEB_BATCH(batch);
1085 }
1086
hsw_veb_dndi_iecp_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1087 void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1088 {
1089 struct intel_batchbuffer *batch = proc_ctx->batch;
1090 unsigned char frame_ctrl_bits = 0;
1091 struct object_surface *obj_surface = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1092 unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1093
1094 assert(obj_surface);
1095 if (width64 > obj_surface->orig_width)
1096 width64 = obj_surface->orig_width;
1097
1098 /* s1:update the previous and current input */
1099 /* tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1100 proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
1101 proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
1102
1103 if(proc_ctx->surface_input_vebox != -1){
1104 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1105 proc_ctx->surface_input_vebox);
1106 } else {
1107 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1108 proc_ctx->surface_input);
1109 }
1110 */
1111 /*s2: update the STMM input and output */
1112 /* tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
1113 proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
1114 proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
1115 */
1116 /*s3:set reloc buffer address */
1117 BEGIN_VEB_BATCH(batch, 10);
1118 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
1119 OUT_VEB_BATCH(batch, (width64 - 1));
1120 OUT_RELOC(batch,
1121 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1122 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1123 OUT_RELOC(batch,
1124 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1125 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1126 OUT_RELOC(batch,
1127 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1128 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1129 OUT_RELOC(batch,
1130 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1131 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1132 OUT_RELOC(batch,
1133 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1134 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1135 OUT_RELOC(batch,
1136 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1137 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1138 OUT_RELOC(batch,
1139 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1140 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1141 OUT_RELOC(batch,
1142 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1143 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1144
1145 ADVANCE_VEB_BATCH(batch);
1146 }
1147
1148 static void
frame_store_reset(VEBFrameStore * fs)1149 frame_store_reset(VEBFrameStore *fs)
1150 {
1151 fs->obj_surface = NULL;
1152 fs->surface_id = VA_INVALID_ID;
1153 fs->is_internal_surface = 0;
1154 fs->is_scratch_surface = 0;
1155 }
1156
1157 static void
frame_store_clear(VEBFrameStore * fs,VADriverContextP ctx)1158 frame_store_clear(VEBFrameStore *fs, VADriverContextP ctx)
1159 {
1160 if (fs->obj_surface && fs->is_scratch_surface) {
1161 VASurfaceID surface_id = fs->obj_surface->base.id;
1162 i965_DestroySurfaces(ctx, &surface_id, 1);
1163 }
1164 frame_store_reset(fs);
1165 }
1166
1167 static VAStatus
gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1168 gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,
1169 struct intel_vebox_context *proc_ctx)
1170 {
1171 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1172 struct object_surface *input_obj_surface, *output_obj_surface;
1173 unsigned int input_fourcc, output_fourcc;
1174 unsigned int input_sampling, output_sampling;
1175 unsigned int input_tiling, output_tiling;
1176 unsigned int i, swizzle;
1177 drm_intel_bo *bo;
1178 VAStatus status;
1179
1180 /* Determine input surface info. Use native VEBOX format whenever
1181 possible. i.e. when the input surface format is not supported
1182 by the VEBOX engine, then allocate a temporary surface (live
1183 during the whole VPP pipeline lifetime)
1184
1185 XXX: derive an actual surface format compatible with the input
1186 surface chroma format */
1187 input_obj_surface = proc_ctx->surface_input_vebox_object ?
1188 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1189 if (input_obj_surface->bo) {
1190 input_fourcc = input_obj_surface->fourcc;
1191 input_sampling = input_obj_surface->subsampling;
1192 dri_bo_get_tiling(input_obj_surface->bo, &input_tiling, &swizzle);
1193 input_tiling = !!input_tiling;
1194 } else {
1195 input_fourcc = VA_FOURCC_NV12;
1196 input_sampling = SUBSAMPLE_YUV420;
1197 input_tiling = 1;
1198 status = i965_check_alloc_surface_bo(ctx, input_obj_surface,
1199 input_tiling, input_fourcc, input_sampling);
1200 if (status != VA_STATUS_SUCCESS)
1201 return status;
1202 }
1203
1204 /* Determine output surface info.
1205
1206 XXX: derive an actual surface format compatible with the input
1207 surface chroma format */
1208 output_obj_surface = proc_ctx->surface_output_vebox_object ?
1209 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1210 if (output_obj_surface->bo) {
1211 output_fourcc = output_obj_surface->fourcc;
1212 output_sampling = output_obj_surface->subsampling;
1213 dri_bo_get_tiling(output_obj_surface->bo, &output_tiling, &swizzle);
1214 output_tiling = !!output_tiling;
1215 } else {
1216 output_fourcc = VA_FOURCC_NV12;
1217 output_sampling = SUBSAMPLE_YUV420;
1218 output_tiling = 1;
1219 status = i965_check_alloc_surface_bo(ctx, output_obj_surface,
1220 output_tiling, output_fourcc, output_sampling);
1221 if (status != VA_STATUS_SUCCESS)
1222 return status;
1223 }
1224
1225 /* Update VEBOX pipeline formats */
1226 proc_ctx->fourcc_input = input_fourcc;
1227 proc_ctx->fourcc_output = output_fourcc;
1228 if (input_fourcc != output_fourcc) {
1229 proc_ctx->filters_mask |= VPP_IECP_CSC;
1230
1231 if (input_fourcc == VA_FOURCC_RGBA &&
1232 (output_fourcc == VA_FOURCC_NV12 ||
1233 output_fourcc == VA_FOURCC_P010)) {
1234 proc_ctx->filters_mask |= VPP_IECP_CSC_TRANSFORM;
1235 } else if (output_fourcc == VA_FOURCC_RGBA &&
1236 (input_fourcc == VA_FOURCC_NV12 ||
1237 input_fourcc == VA_FOURCC_P010)) {
1238 proc_ctx->filters_mask |= VPP_IECP_CSC_TRANSFORM;
1239 }
1240 }
1241
1242 proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
1243
1244 /* Create pipeline surfaces */
1245 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i ++) {
1246 struct object_surface *obj_surface;
1247 VASurfaceID new_surface;
1248
1249 if (proc_ctx->frame_store[i].obj_surface)
1250 continue; // user allocated surface, not VEBOX internal
1251
1252 status = i965_CreateSurfaces(ctx, proc_ctx->width_input,
1253 proc_ctx->height_input, VA_RT_FORMAT_YUV420, 1, &new_surface);
1254 if (status != VA_STATUS_SUCCESS)
1255 return status;
1256
1257 obj_surface = SURFACE(new_surface);
1258 assert(obj_surface != NULL);
1259
1260 if (i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
1261 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1262 input_tiling, input_fourcc, input_sampling);
1263 } else if (i == FRAME_IN_STMM || i == FRAME_OUT_STMM) {
1264 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1265 1, input_fourcc, input_sampling);
1266 } else if (i >= FRAME_OUT_CURRENT) {
1267 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1268 output_tiling, output_fourcc, output_sampling);
1269 }
1270 if (status != VA_STATUS_SUCCESS)
1271 return status;
1272
1273 proc_ctx->frame_store[i].obj_surface = obj_surface;
1274 proc_ctx->frame_store[i].is_internal_surface = 1;
1275 proc_ctx->frame_store[i].is_scratch_surface = 1;
1276 }
1277
1278 /* Allocate DNDI state table */
1279 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1280 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: dndi state Buffer",
1281 0x1000, 0x1000);
1282 proc_ctx->dndi_state_table.bo = bo;
1283 if (!bo)
1284 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1285
1286 /* Allocate IECP state table */
1287 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1288 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: iecp state Buffer",
1289 0x1000, 0x1000);
1290 proc_ctx->iecp_state_table.bo = bo;
1291 if (!bo)
1292 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1293
1294 /* Allocate Gamut state table */
1295 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1296 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: gamut state Buffer",
1297 0x1000, 0x1000);
1298 proc_ctx->gamut_state_table.bo = bo;
1299 if (!bo)
1300 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1301
1302 /* Allocate vertex state table */
1303 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1304 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: vertex state Buffer",
1305 0x1000, 0x1000);
1306 proc_ctx->vertex_state_table.bo = bo;
1307 if (!bo)
1308 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1309
1310 return VA_STATUS_SUCCESS;
1311 }
1312
1313 static VAStatus
gen75_vebox_ensure_surfaces(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1314 gen75_vebox_ensure_surfaces(VADriverContextP ctx,
1315 struct intel_vebox_context *proc_ctx)
1316 {
1317 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1318 struct object_surface *obj_surface;
1319 VEBFrameStore *ifs, *ofs;
1320 bool is_new_frame = 0;
1321 int i;
1322
1323 /* Update the previous input surface */
1324 obj_surface = proc_ctx->surface_input_object;
1325
1326 is_new_frame = proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id !=
1327 obj_surface->base.id;
1328 if (is_new_frame) {
1329 ifs = &proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1330 ofs = &proc_ctx->frame_store[proc_ctx->is_dn_enabled ?
1331 FRAME_OUT_CURRENT_DN : FRAME_IN_CURRENT];
1332 do {
1333 const VAProcPipelineParameterBuffer * const pipe =
1334 proc_ctx->pipeline_param;
1335
1336 if (pipe->num_forward_references < 1)
1337 break;
1338 if (pipe->forward_references[0] == VA_INVALID_ID)
1339 break;
1340
1341 obj_surface = SURFACE(pipe->forward_references[0]);
1342 if (!obj_surface || obj_surface->base.id == ifs->surface_id)
1343 break;
1344
1345 frame_store_clear(ifs, ctx);
1346 if (obj_surface->base.id == ofs->surface_id) {
1347 *ifs = *ofs;
1348 frame_store_reset(ofs);
1349 } else {
1350 ifs->obj_surface = obj_surface;
1351 ifs->surface_id = obj_surface->base.id;
1352 ifs->is_internal_surface = 0;
1353 ifs->is_scratch_surface = 0;
1354 }
1355 } while (0);
1356 }
1357
1358 /* Update the input surface */
1359 obj_surface = proc_ctx->surface_input_vebox_object ?
1360 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1361
1362 ifs = &proc_ctx->frame_store[FRAME_IN_CURRENT];
1363 frame_store_clear(ifs, ctx);
1364 ifs->obj_surface = obj_surface;
1365 ifs->surface_id = proc_ctx->surface_input_object->base.id;
1366 ifs->is_internal_surface = proc_ctx->surface_input_vebox_object != NULL;
1367 ifs->is_scratch_surface = 0;
1368
1369 /* Update the Spatial Temporal Motion Measure (STMM) surfaces */
1370 if (is_new_frame) {
1371 const VEBFrameStore tmpfs = proc_ctx->frame_store[FRAME_IN_STMM];
1372 proc_ctx->frame_store[FRAME_IN_STMM] =
1373 proc_ctx->frame_store[FRAME_OUT_STMM];
1374 proc_ctx->frame_store[FRAME_OUT_STMM] = tmpfs;
1375 }
1376
1377 /* Reset the output surfaces to defaults. i.e. clean from user surfaces */
1378 for (i = FRAME_OUT_CURRENT_DN; i <= FRAME_OUT_PREVIOUS; i++) {
1379 ofs = &proc_ctx->frame_store[i];
1380 if (!ofs->is_scratch_surface)
1381 ofs->obj_surface = NULL;
1382 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1383 }
1384
1385 /* Update the output surfaces */
1386 obj_surface = proc_ctx->surface_output_vebox_object ?
1387 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1388
1389 proc_ctx->current_output_type = 2;
1390 if (proc_ctx->filters_mask == VPP_DNDI_DN && !proc_ctx->is_iecp_enabled)
1391 proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
1392 else if (proc_ctx->is_di_adv_enabled && !proc_ctx->is_first_frame) {
1393 proc_ctx->current_output_type = 0;
1394 proc_ctx->current_output = proc_ctx->is_second_field ?
1395 FRAME_OUT_CURRENT : FRAME_OUT_PREVIOUS;
1396 } else
1397 proc_ctx->current_output = FRAME_OUT_CURRENT;
1398 ofs = &proc_ctx->frame_store[proc_ctx->current_output];
1399 frame_store_clear(ofs, ctx);
1400 ofs->obj_surface = obj_surface;
1401 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1402 ofs->is_internal_surface = proc_ctx->surface_output_vebox_object != NULL;
1403 ofs->is_scratch_surface = 0;
1404
1405 return VA_STATUS_SUCCESS;
1406 }
1407
hsw_veb_pre_format_convert(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1408 VAStatus hsw_veb_pre_format_convert(VADriverContextP ctx,
1409 struct intel_vebox_context *proc_ctx)
1410 {
1411 VAStatus va_status;
1412 struct i965_driver_data *i965 = i965_driver_data(ctx);
1413 struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
1414 struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
1415 struct object_surface* obj_surf_input_vebox;
1416 struct object_surface* obj_surf_output_vebox;
1417
1418 proc_ctx->format_convert_flags = 0;
1419
1420 if ((obj_surf_input == NULL) || (obj_surf_output == NULL)) {
1421 ASSERT_RET(0, VA_STATUS_ERROR_INVALID_PARAMETER);
1422 }
1423
1424 if (proc_ctx->pipeline_param->surface_region) {
1425 proc_ctx->width_input = proc_ctx->pipeline_param->surface_region->width;
1426 proc_ctx->height_input = proc_ctx->pipeline_param->surface_region->height;
1427 } else {
1428 proc_ctx->width_input = obj_surf_input->orig_width;
1429 proc_ctx->height_input = obj_surf_input->orig_height;
1430 }
1431
1432 if (proc_ctx->pipeline_param->output_region) {
1433 proc_ctx->width_output = proc_ctx->pipeline_param->output_region->width;
1434 proc_ctx->height_output = proc_ctx->pipeline_param->output_region->height;
1435 } else {
1436 proc_ctx->width_output = obj_surf_output->orig_width;
1437 proc_ctx->height_output = obj_surf_output->orig_height;
1438 }
1439
1440 /* only partial frame is not supported to be processed */
1441 /*
1442 assert(proc_ctx->width_input == proc_ctx->pipeline_param->surface_region->width);
1443 assert(proc_ctx->height_input == proc_ctx->pipeline_param->surface_region->height);
1444 assert(proc_ctx->width_output == proc_ctx->pipeline_param->output_region->width);
1445 assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
1446 */
1447
1448 if (proc_ctx->width_output != proc_ctx->width_input ||
1449 proc_ctx->height_output != proc_ctx->height_input) {
1450 proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
1451 }
1452
1453 /* convert the following format to NV12 format */
1454 if (obj_surf_input->fourcc == VA_FOURCC_YV12 ||
1455 obj_surf_input->fourcc == VA_FOURCC_I420 ||
1456 obj_surf_input->fourcc == VA_FOURCC_IMC1 ||
1457 obj_surf_input->fourcc == VA_FOURCC_IMC3 ||
1458 obj_surf_input->fourcc == VA_FOURCC_RGBA ||
1459 obj_surf_input->fourcc == VA_FOURCC_BGRA) {
1460
1461 proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
1462
1463 } else if (obj_surf_input->fourcc == VA_FOURCC_AYUV ||
1464 obj_surf_input->fourcc == VA_FOURCC_YUY2 ||
1465 obj_surf_input->fourcc == VA_FOURCC_NV12 ||
1466 obj_surf_input->fourcc == VA_FOURCC_P010) {
1467
1468 // nothing to do here
1469 } else {
1470 /* not support other format as input */
1471 ASSERT_RET(0, VA_STATUS_ERROR_UNIMPLEMENTED);
1472 }
1473
1474 if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
1475 if (proc_ctx->surface_input_vebox_object == NULL) {
1476 va_status = i965_CreateSurfaces(ctx,
1477 proc_ctx->width_input,
1478 proc_ctx->height_input,
1479 VA_RT_FORMAT_YUV420,
1480 1,
1481 &(proc_ctx->surface_input_vebox));
1482 assert(va_status == VA_STATUS_SUCCESS);
1483 obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
1484 assert(obj_surf_input_vebox);
1485
1486 if (obj_surf_input_vebox) {
1487 proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
1488 i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1489 }
1490 }
1491
1492 vpp_surface_convert(ctx, proc_ctx->surface_input_object, proc_ctx->surface_input_vebox_object);
1493 }
1494
1495 /* create one temporary NV12 surfaces for conversion*/
1496 if (obj_surf_output->fourcc == VA_FOURCC_YV12 ||
1497 obj_surf_output->fourcc == VA_FOURCC_I420 ||
1498 obj_surf_output->fourcc == VA_FOURCC_IMC1 ||
1499 obj_surf_output->fourcc == VA_FOURCC_IMC3 ||
1500 obj_surf_output->fourcc == VA_FOURCC_RGBA ||
1501 obj_surf_output->fourcc == VA_FOURCC_BGRA) {
1502
1503 proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
1504 } else if (obj_surf_output->fourcc == VA_FOURCC_AYUV ||
1505 obj_surf_output->fourcc == VA_FOURCC_YUY2 ||
1506 obj_surf_output->fourcc == VA_FOURCC_NV12 ||
1507 obj_surf_output->fourcc == VA_FOURCC_P010) {
1508
1509 /* Nothing to do here */
1510 } else {
1511 /* not support other format as input */
1512 ASSERT_RET(0, VA_STATUS_ERROR_UNIMPLEMENTED);
1513 }
1514
1515 if (proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
1516 proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1517 if (proc_ctx->surface_output_vebox_object == NULL) {
1518 va_status = i965_CreateSurfaces(ctx,
1519 proc_ctx->width_input,
1520 proc_ctx->height_input,
1521 VA_RT_FORMAT_YUV420,
1522 1,
1523 &(proc_ctx->surface_output_vebox));
1524 assert(va_status == VA_STATUS_SUCCESS);
1525 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
1526 assert(obj_surf_output_vebox);
1527
1528 if (obj_surf_output_vebox) {
1529 proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
1530 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1531 }
1532 }
1533 }
1534
1535 if (proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1536 if (proc_ctx->surface_output_scaled_object == NULL) {
1537 va_status = i965_CreateSurfaces(ctx,
1538 proc_ctx->width_output,
1539 proc_ctx->height_output,
1540 VA_RT_FORMAT_YUV420,
1541 1,
1542 &(proc_ctx->surface_output_scaled));
1543 assert(va_status == VA_STATUS_SUCCESS);
1544 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
1545 assert(obj_surf_output_vebox);
1546
1547 if (obj_surf_output_vebox) {
1548 proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
1549 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1550 }
1551 }
1552 }
1553
1554 return VA_STATUS_SUCCESS;
1555 }
1556
1557 VAStatus
hsw_veb_post_format_convert(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1558 hsw_veb_post_format_convert(VADriverContextP ctx,
1559 struct intel_vebox_context *proc_ctx)
1560 {
1561 struct object_surface *obj_surface = NULL;
1562 VAStatus va_status = VA_STATUS_SUCCESS;
1563
1564 obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
1565
1566 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1567 /* copy the saved frame in the second call */
1568 va_status = vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1569 } else if (!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1570 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)) {
1571 /* Output surface format is covered by vebox pipeline and
1572 * processed picture is already store in output surface
1573 * so nothing will be done here */
1574 } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1575 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)) {
1576 /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1577 va_status = vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1578
1579 } else if (proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1580 VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1581 /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1582 assert(obj_surface->fourcc == VA_FOURCC_NV12);
1583
1584 /* first step :surface scaling */
1585 vpp_surface_scaling(ctx, obj_surface,
1586 proc_ctx->surface_output_scaled_object, pipe->filter_flags);
1587
1588 /* second step: color format convert and copy to output */
1589 obj_surface = proc_ctx->surface_output_object;
1590
1591 va_status = vpp_surface_convert(ctx, proc_ctx->surface_output_scaled_object, obj_surface);
1592 }
1593
1594 return va_status;
1595 }
1596
1597 static VAStatus
gen75_vebox_init_pipe_params(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1598 gen75_vebox_init_pipe_params(VADriverContextP ctx,
1599 struct intel_vebox_context *proc_ctx)
1600 {
1601 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1602 const VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1603 VAProcFilterParameterBuffer *filter;
1604 unsigned int i;
1605
1606 proc_ctx->filters_mask = 0;
1607 for (i = 0; i < pipe->num_filters; i++) {
1608 struct object_buffer * const obj_buffer = BUFFER(pipe->filters[i]);
1609
1610 assert(obj_buffer && obj_buffer->buffer_store);
1611 if (!obj_buffer || !obj_buffer->buffer_store)
1612 return VA_STATUS_ERROR_INVALID_PARAMETER;
1613
1614 filter = (VAProcFilterParameterBuffer *)
1615 obj_buffer->buffer_store->buffer;
1616 switch (filter->type) {
1617 case VAProcFilterNoiseReduction:
1618 proc_ctx->filters_mask |= VPP_DNDI_DN;
1619 proc_ctx->filter_dn = filter;
1620 break;
1621 case VAProcFilterDeinterlacing:
1622 proc_ctx->filters_mask |= VPP_DNDI_DI;
1623 proc_ctx->filter_di = filter;
1624 break;
1625 case VAProcFilterColorBalance:
1626 proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1627 proc_ctx->filter_iecp_amp = filter;
1628 proc_ctx->filter_iecp_amp_num_elements = obj_buffer->num_elements;
1629 break;
1630 case VAProcFilterSkinToneEnhancement:
1631 proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1632 proc_ctx->filter_iecp_std = filter;
1633 break;
1634 case VAProcFilterSharpening:
1635 proc_ctx->filters_mask |= VPP_SHARP;
1636 break;
1637 default:
1638 WARN_ONCE("unsupported filter (type: %d)\n", filter->type);
1639 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1640 }
1641 }
1642
1643 if (proc_ctx->filters_mask == 0)
1644 proc_ctx->filters_mask |= VPP_IECP_CSC;
1645
1646 return VA_STATUS_SUCCESS;
1647 }
1648
1649 static VAStatus
gen75_vebox_init_filter_params(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1650 gen75_vebox_init_filter_params(VADriverContextP ctx,
1651 struct intel_vebox_context *proc_ctx)
1652 {
1653 proc_ctx->format_convert_flags = 0; /* initialized in hsw_veb_pre_format_convert() */
1654
1655 proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
1656 proc_ctx->is_dn_enabled = (proc_ctx->filters_mask & VPP_DNDI_DN) != 0;
1657 proc_ctx->is_di_enabled = (proc_ctx->filters_mask & VPP_DNDI_DI) != 0;
1658 proc_ctx->is_di_adv_enabled = 0;
1659 proc_ctx->is_first_frame = 0;
1660 proc_ctx->is_second_field = 0;
1661
1662 /* Check whether we are deinterlacing the second field */
1663 if (proc_ctx->is_di_enabled) {
1664 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1665 proc_ctx->filter_di;
1666
1667 const unsigned int tff =
1668 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
1669 const unsigned int is_top_field =
1670 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
1671
1672 if ((tff ^ is_top_field) != 0) {
1673 struct object_surface * const obj_surface =
1674 proc_ctx->surface_input_object;
1675
1676 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id != obj_surface->base.id) {
1677 WARN_ONCE("invalid surface provided for second field\n");
1678 return VA_STATUS_ERROR_INVALID_PARAMETER;
1679 }
1680 proc_ctx->is_second_field = 1;
1681 }
1682 }
1683
1684 /* Check whether we are deinterlacing the first frame */
1685 if (proc_ctx->is_di_enabled) {
1686 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1687 proc_ctx->filter_di;
1688
1689 switch (deint_params->algorithm) {
1690 case VAProcDeinterlacingBob:
1691 proc_ctx->is_first_frame = 1;
1692 break;
1693 case VAProcDeinterlacingMotionAdaptive:
1694 case VAProcDeinterlacingMotionCompensated:
1695 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id == VA_INVALID_ID)
1696 proc_ctx->is_first_frame = 1;
1697 else if (proc_ctx->is_second_field) {
1698 /* At this stage, we have already deinterlaced the
1699 first field successfully. So, the first frame flag
1700 is trigerred if the previous field was deinterlaced
1701 without reference frame */
1702 if (proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id == VA_INVALID_ID)
1703 proc_ctx->is_first_frame = 1;
1704 } else {
1705 const VAProcPipelineParameterBuffer * const pipe =
1706 proc_ctx->pipeline_param;
1707
1708 if (pipe->num_forward_references < 1 ||
1709 pipe->forward_references[0] == VA_INVALID_ID) {
1710 WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
1711 return VA_STATUS_ERROR_INVALID_PARAMETER;
1712 }
1713 }
1714 proc_ctx->is_di_adv_enabled = 1;
1715 break;
1716 default:
1717 WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
1718 deint_params->algorithm);
1719 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1720 }
1721 }
1722 return VA_STATUS_SUCCESS;
1723 }
1724
1725 VAStatus
gen75_vebox_process_picture(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1726 gen75_vebox_process_picture(VADriverContextP ctx,
1727 struct intel_vebox_context *proc_ctx)
1728 {
1729 VAStatus status;
1730
1731 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1732 if (status != VA_STATUS_SUCCESS)
1733 return status;
1734
1735 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1736 if (status != VA_STATUS_SUCCESS)
1737 return status;
1738
1739 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
1740 if (status != VA_STATUS_SUCCESS)
1741 return status;
1742
1743 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1744 if (status != VA_STATUS_SUCCESS)
1745 return status;
1746
1747 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1748 if (status != VA_STATUS_SUCCESS)
1749 return status;
1750
1751 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
1752 vpp_sharpness_filtering(ctx, proc_ctx);
1753 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1754 assert(proc_ctx->is_second_field);
1755 /* directly copy the saved frame in the second call */
1756 } else {
1757 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1758 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1759 hsw_veb_state_table_setup(ctx, proc_ctx);
1760 hsw_veb_state_command(ctx, proc_ctx);
1761 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
1762 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
1763 hsw_veb_dndi_iecp_command(ctx, proc_ctx);
1764 intel_batchbuffer_end_atomic(proc_ctx->batch);
1765 intel_batchbuffer_flush(proc_ctx->batch);
1766 }
1767
1768 status = hsw_veb_post_format_convert(ctx, proc_ctx);
1769
1770 return status;
1771 }
1772
gen75_vebox_context_destroy(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1773 void gen75_vebox_context_destroy(VADriverContextP ctx,
1774 struct intel_vebox_context *proc_ctx)
1775 {
1776 int i;
1777
1778 if (proc_ctx->vpp_gpe_ctx) {
1779 vpp_gpe_context_destroy(ctx, proc_ctx->vpp_gpe_ctx);
1780 proc_ctx->vpp_gpe_ctx = NULL;
1781 }
1782
1783 if (proc_ctx->surface_input_vebox != VA_INVALID_ID) {
1784 i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
1785 proc_ctx->surface_input_vebox = VA_INVALID_ID;
1786 proc_ctx->surface_input_vebox_object = NULL;
1787 }
1788
1789 if (proc_ctx->surface_output_vebox != VA_INVALID_ID) {
1790 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
1791 proc_ctx->surface_output_vebox = VA_INVALID_ID;
1792 proc_ctx->surface_output_vebox_object = NULL;
1793 }
1794
1795 if (proc_ctx->surface_output_scaled != VA_INVALID_ID) {
1796 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
1797 proc_ctx->surface_output_scaled = VA_INVALID_ID;
1798 proc_ctx->surface_output_scaled_object = NULL;
1799 }
1800
1801 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i++)
1802 frame_store_clear(&proc_ctx->frame_store[i], ctx);
1803
1804 /* dndi state table */
1805 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1806 proc_ctx->dndi_state_table.bo = NULL;
1807
1808 /* iecp state table */
1809 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1810 proc_ctx->iecp_state_table.bo = NULL;
1811
1812 /* gamut statu table */
1813 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1814 proc_ctx->gamut_state_table.bo = NULL;
1815
1816 /* vertex state table */
1817 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1818 proc_ctx->vertex_state_table.bo = NULL;
1819
1820 intel_batchbuffer_free(proc_ctx->batch);
1821
1822 free(proc_ctx);
1823 }
1824
gen75_vebox_context_init(VADriverContextP ctx)1825 struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
1826 {
1827 struct intel_driver_data *intel = intel_driver_data(ctx);
1828 struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
1829 int i;
1830
1831 assert(proc_context);
1832 proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
1833
1834 for (i = 0; i < ARRAY_ELEMS(proc_context->frame_store); i++)
1835 proc_context->frame_store[i].surface_id = VA_INVALID_ID;
1836
1837 proc_context->filters_mask = 0;
1838 proc_context->surface_output_object = NULL;
1839 proc_context->surface_input_object = NULL;
1840 proc_context->surface_input_vebox = VA_INVALID_ID;
1841 proc_context->surface_input_vebox_object = NULL;
1842 proc_context->surface_output_vebox = VA_INVALID_ID;
1843 proc_context->surface_output_vebox_object = NULL;
1844 proc_context->surface_output_scaled = VA_INVALID_ID;
1845 proc_context->surface_output_scaled_object = NULL;
1846 proc_context->filters_mask = 0;
1847 proc_context->format_convert_flags = 0;
1848 proc_context->vpp_gpe_ctx = NULL;
1849
1850 return proc_context;
1851 }
1852
bdw_veb_state_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1853 void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1854 {
1855 struct intel_batchbuffer *batch = proc_ctx->batch;
1856
1857 BEGIN_VEB_BATCH(batch, 0xc);
1858 OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
1859 OUT_VEB_BATCH(batch,
1860 0 << 25 | // state surface control bits
1861 0 << 23 | // reserved.
1862 0 << 22 | // gamut expansion position
1863 0 << 15 | // reserved.
1864 0 << 14 | // single slice vebox enable
1865 0 << 13 | // hot pixel filter enable
1866 0 << 12 | // alpha plane enable
1867 0 << 11 | // vignette enable
1868 0 << 10 | // demosaic enable
1869 proc_ctx->current_output_type << 8 | // DI output frame
1870 1 << 7 | // 444->422 downsample method
1871 1 << 6 | // 422->420 downsample method
1872 proc_ctx->is_first_frame << 5 | // DN/DI first frame
1873 proc_ctx->is_di_enabled << 4 | // DI enable
1874 proc_ctx->is_dn_enabled << 3 | // DN enable
1875 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
1876 0 << 1 | // ColorGamutCompressionEnable
1877 0) ; // ColorGamutExpansionEnable.
1878
1879 OUT_RELOC64(batch,
1880 proc_ctx->dndi_state_table.bo,
1881 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1882
1883 OUT_RELOC64(batch,
1884 proc_ctx->iecp_state_table.bo,
1885 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1886
1887 OUT_RELOC64(batch,
1888 proc_ctx->gamut_state_table.bo,
1889 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1890
1891 OUT_RELOC64(batch,
1892 proc_ctx->vertex_state_table.bo,
1893 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1894
1895
1896 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
1897 OUT_VEB_BATCH(batch, 0);
1898
1899 ADVANCE_VEB_BATCH(batch);
1900 }
1901
bdw_veb_dndi_iecp_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1902 void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1903 {
1904 struct intel_batchbuffer *batch = proc_ctx->batch;
1905 unsigned char frame_ctrl_bits = 0;
1906 struct object_surface *obj_surface = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
1907 unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1908
1909 assert(obj_surface);
1910 if (width64 > obj_surface->orig_width)
1911 width64 = obj_surface->orig_width;
1912
1913 BEGIN_VEB_BATCH(batch, 0x14);
1914 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
1915 OUT_VEB_BATCH(batch, (width64 - 1));
1916
1917 OUT_RELOC64(batch,
1918 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1919 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
1920
1921 OUT_RELOC64(batch,
1922 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1923 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
1924
1925 OUT_RELOC64(batch,
1926 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1927 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
1928
1929 OUT_RELOC64(batch,
1930 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1931 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
1932
1933 OUT_RELOC64(batch,
1934 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1935 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
1936
1937 OUT_RELOC64(batch,
1938 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1939 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
1940
1941 OUT_RELOC64(batch,
1942 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1943 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
1944
1945 OUT_RELOC64(batch,
1946 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1947 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
1948
1949 OUT_VEB_BATCH(batch, 0); //DWord 18
1950 OUT_VEB_BATCH(batch, 0); //DWord 19
1951
1952 ADVANCE_VEB_BATCH(batch);
1953 }
1954
1955 VAStatus
gen8_vebox_process_picture(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)1956 gen8_vebox_process_picture(VADriverContextP ctx,
1957 struct intel_vebox_context *proc_ctx)
1958 {
1959 VAStatus status;
1960
1961 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1962 if (status != VA_STATUS_SUCCESS)
1963 return status;
1964
1965 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1966 if (status != VA_STATUS_SUCCESS)
1967 return status;
1968
1969 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
1970 if (status != VA_STATUS_SUCCESS)
1971 return status;
1972
1973 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1974 if (status != VA_STATUS_SUCCESS)
1975 return status;
1976
1977 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1978 if (status != VA_STATUS_SUCCESS)
1979 return status;
1980
1981 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
1982 vpp_sharpness_filtering(ctx, proc_ctx);
1983 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1984 assert(proc_ctx->is_second_field);
1985 /* directly copy the saved frame in the second call */
1986 } else {
1987 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1988 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1989 hsw_veb_state_table_setup(ctx, proc_ctx);
1990 bdw_veb_state_command(ctx, proc_ctx);
1991 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
1992 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
1993 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
1994 intel_batchbuffer_end_atomic(proc_ctx->batch);
1995 intel_batchbuffer_flush(proc_ctx->batch);
1996 }
1997
1998 status = hsw_veb_post_format_convert(ctx, proc_ctx);
1999
2000 return status;
2001 }
2002
2003
2004 void
skl_veb_dndi_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2005 skl_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2006 {
2007 unsigned int* p_table ;
2008 unsigned int progressive_dn = 1;
2009 unsigned int dndi_top_first = 0;
2010 unsigned int is_mcdi_enabled = 0;
2011
2012 if (proc_ctx->is_di_enabled) {
2013 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
2014 proc_ctx->filter_di;
2015
2016 progressive_dn = 0;
2017
2018 /* If we are in "First Frame" mode, i.e. past frames are not
2019 available for motion measure, then don't use the TFF flag */
2020 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
2021 VA_DEINTERLACING_BOTTOM_FIELD :
2022 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
2023
2024 is_mcdi_enabled =
2025 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
2026 }
2027
2028 /*
2029 VAProcFilterParameterBufferDeinterlacing *di_param =
2030 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
2031
2032 VAProcFilterParameterBuffer * dn_param =
2033 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
2034 */
2035 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
2036
2037 *p_table ++ = (140 << 20 | // denoise stad threshold . w1
2038 192 << 12 | // dnmh_history_max
2039 7 << 8 | // dnmh_delta[3:0]
2040 1); // denoise moving pixel threshold
2041
2042 *p_table ++ = (38 << 20 | // denoise asd threshold
2043 0 << 10 | // temporal diff th
2044 0); // low temporal diff th
2045
2046 *p_table ++ = (progressive_dn << 28 | // progressive dn
2047 38 << 16 | // denoise th for sum of complexity measure
2048 32 << 10 | // dnmh_history_init[5:0]
2049 0); // reserved
2050
2051 *p_table ++ = (0 << 28 | // hot pixel count
2052 0 << 20 | // hot pixel threshold
2053 1 << 12 | // block noise estimate edge threshold
2054 20); // block noise estimate noise threshold
2055
2056 *p_table ++ = (140 << 16 | // chroma denoise stad threshold
2057 0 << 13 | // reserved
2058 1 << 12 | // chrome denoise enable
2059 13 << 6 | // chr temp diff th
2060 7); // chr temp diff low
2061
2062 *p_table ++ = 0; // weight
2063
2064 *p_table ++ = (0 << 16 | // dn_thmax
2065 0); // dn_thmin
2066
2067 *p_table ++ = (0 << 16 | // dn_prt5
2068 0); // dn_dyn_thmin
2069
2070 *p_table ++ = (0 << 16 | // dn_prt4
2071 0); // dn_prt3
2072
2073 *p_table ++ = (0 << 16 | // dn_prt2
2074 0); // dn_prt1
2075
2076 *p_table ++ = (0 << 16 | // dn_prt0
2077 0 << 10 | // dn_wd22
2078 0 << 5 | // dh_wd21
2079 0); // dh_wd20
2080
2081 *p_table ++ = (0 << 25 | // dn_wd12
2082 0 << 20 | // dn_wd11
2083 0 << 15 | // dn_wd10
2084 0 << 10 | // dn_wd02
2085 0 << 5 | // dn_wd01
2086 0); // dn_wd00
2087
2088 *p_table ++ = (2 << 10 | // stmm c2
2089 9 << 6 | // cat slope minus 1
2090 5 << 2 | // sad tight threshold
2091 0); // smooth mv th
2092
2093 *p_table ++ = (0 << 31 | // stmm blending constant select
2094 64 << 24 | // stmm trc1
2095 125 << 16 | // stmm trc2
2096 0 << 14 | // reserved
2097 30 << 8 | // multiplier for vecm
2098 150); // maximum stmm
2099
2100 *p_table ++ = (118 << 24 | // minumum stmm
2101 0 << 22 | // stmm shift down
2102 1 << 20 | // stmm shift up
2103 5 << 16 | // stmm output shift
2104 100 << 8 | // sdi threshold
2105 5); // sdi delta
2106
2107 *p_table ++ = (50 << 24 | // sdi fallback mode 1 t1 constant
2108 100 << 16 | // sdi fallback mode 1 t2 constant
2109 37 << 8 | // sdi fallback mode 2 constant(angle2x1)
2110 175); // fmd temporal difference threshold
2111
2112 *p_table ++ = (16 << 24 | // fmd #1 vertical difference th . w7
2113 100 << 16 | // fmd #2 vertical difference th
2114 0 << 14 | // cat threshold
2115 2 << 8 | // fmd tear threshold
2116 is_mcdi_enabled << 7 | // mcdi enable, use motion compensated deinterlace algorithm
2117 dndi_top_first << 3 | // dn/di top first
2118 0); // reserved
2119
2120 *p_table ++ = (10 << 19 | // neighbor pixel threshold
2121 0 << 16 | // fmd for 2nd field of previous frame
2122 25 << 10 | // mc pixel consistency threshold
2123 0 << 8 | // fmd for 1st field for current frame
2124 10 << 4 | // sad thb
2125 5); // sad tha
2126 }
2127
skl_veb_iecp_csc_transform_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2128 void skl_veb_iecp_csc_transform_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2129 {
2130 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
2131 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
2132 float v_coef[3] = {0.0, 0.0, 0.0};
2133 float u_coef[3] = {0.0, 0.0, 0.0};
2134 int is_transform_enabled = 0;
2135
2136 if (!(proc_ctx->filters_mask & VPP_IECP_CSC_TRANSFORM)) {
2137 memset(p_table, 0, 12 * 4);
2138 return;
2139 }
2140
2141 if (proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
2142 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
2143 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
2144 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
2145 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
2146
2147 tran_coef[0] = 0.257;
2148 tran_coef[1] = 0.504;
2149 tran_coef[2] = 0.098;
2150 tran_coef[3] = -0.148;
2151 tran_coef[4] = -0.291;
2152 tran_coef[5] = 0.439;
2153 tran_coef[6] = 0.439;
2154 tran_coef[7] = -0.368;
2155 tran_coef[8] = -0.071;
2156
2157 u_coef[0] = 16 * 4;
2158 u_coef[1] = 128 * 4;
2159 u_coef[2] = 128 * 4;
2160
2161 is_transform_enabled = 1;
2162 } else if ((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
2163 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
2164 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
2165 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
2166 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
2167 tran_coef[0] = 1.164;
2168 tran_coef[1] = 0.000;
2169 tran_coef[2] = 1.569;
2170 tran_coef[3] = 1.164;
2171 tran_coef[4] = -0.813;
2172 tran_coef[5] = -0.392;
2173 tran_coef[6] = 1.164;
2174 tran_coef[7] = 2.017;
2175 tran_coef[8] = 0.000;
2176
2177 v_coef[0] = -16 * 4;
2178 v_coef[1] = -128 * 4;
2179 v_coef[2] = -128 * 4;
2180
2181 is_transform_enabled = 1;
2182 } else if (proc_ctx->fourcc_input != proc_ctx->fourcc_output) {
2183 //enable when input and output format are different.
2184 is_transform_enabled = 1;
2185 }
2186
2187 if (is_transform_enabled == 0) {
2188 memset(p_table, 0, 12 * 4);
2189 } else {
2190 *p_table ++ = (is_transform_enabled << 31 |
2191 0 << 29 | // yuv_channel swap
2192 intel_format_convert(tran_coef[0], 2, 16, 1)); //c0, s2.16 format
2193
2194 *p_table ++ = (0 << 19 | //reserved
2195 intel_format_convert(tran_coef[1], 2, 16, 1)); //c1, s2.16 format
2196
2197 *p_table ++ = (0 << 19 | //reserved
2198 intel_format_convert(tran_coef[2], 2, 16, 1)); //c2, s2.16 format
2199
2200 *p_table ++ = (0 << 19 | //reserved
2201 intel_format_convert(tran_coef[3], 2, 16, 1)); //c3, s2.16 format
2202
2203 *p_table ++ = (0 << 19 | //reserved
2204 intel_format_convert(tran_coef[4], 2, 16, 1)); //c4, s2.16 format
2205
2206 *p_table ++ = (0 << 19 | //reserved
2207 intel_format_convert(tran_coef[5], 2, 16, 1)); //c5, s2.16 format
2208
2209 *p_table ++ = (0 << 19 | //reserved
2210 intel_format_convert(tran_coef[6], 2, 16, 1)); //c6, s2.16 format
2211
2212 *p_table ++ = (0 << 19 | //reserved
2213 intel_format_convert(tran_coef[7], 2, 16, 1)); //c7, s2.16 format
2214
2215 *p_table ++ = (0 << 19 | //reserved
2216 intel_format_convert(tran_coef[8], 2, 16, 1)); //c8, s2.16 format
2217
2218 *p_table ++ = (intel_format_convert(u_coef[0], 16, 0, 1) << 16 |
2219 intel_format_convert(v_coef[0], 16, 0, 1));
2220
2221 *p_table ++ = (intel_format_convert(u_coef[1], 16, 0, 1) << 16 |
2222 intel_format_convert(v_coef[1], 16, 0, 1));
2223
2224 *p_table ++ = (intel_format_convert(u_coef[2], 16, 0, 1) << 16 |
2225 intel_format_convert(v_coef[2], 16, 0, 1));
2226 }
2227 }
2228
skl_veb_iecp_aoi_table(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2229 void skl_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2230 {
2231 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 27 * sizeof(unsigned int));
2232
2233 if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
2234 memset(p_table, 0, 3 * 4);
2235 } else {
2236 *p_table ++ = 0x00000000;
2237 *p_table ++ = 0x00030000;
2238 *p_table ++ = 0x00030000;
2239 }
2240 }
2241
skl_veb_state_table_setup(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2242 void skl_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2243 {
2244 if (proc_ctx->filters_mask & VPP_DNDI_MASK) {
2245 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
2246 dri_bo_map(dndi_bo, 1);
2247 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
2248
2249 skl_veb_dndi_table(ctx, proc_ctx);
2250
2251 dri_bo_unmap(dndi_bo);
2252 }
2253
2254 if (proc_ctx->filters_mask & VPP_IECP_MASK) {
2255 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
2256 dri_bo_map(iecp_bo, 1);
2257 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
2258 memset(proc_ctx->iecp_state_table.ptr, 0, 2048); // Change the size to 2048 in case a large table used in the future
2259
2260 hsw_veb_iecp_std_table(ctx, proc_ctx);
2261 hsw_veb_iecp_ace_table(ctx, proc_ctx);
2262 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
2263 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
2264 skl_veb_iecp_csc_transform_table(ctx, proc_ctx);
2265 skl_veb_iecp_aoi_table(ctx, proc_ctx);
2266
2267 dri_bo_unmap(iecp_bo);
2268 }
2269 }
2270
2271 void
skl_veb_state_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2272 skl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2273 {
2274 struct i965_driver_data *i965 = i965_driver_data(ctx);
2275 struct intel_batchbuffer *batch = proc_ctx->batch;
2276
2277 BEGIN_VEB_BATCH(batch, 0x10);
2278 OUT_VEB_BATCH(batch, VEB_STATE | (0x10 - 2));
2279 OUT_VEB_BATCH(batch,
2280 ((i965->intel.mocs_state) << 25) | // state surface control bits
2281 0 << 23 | // reserved.
2282 0 << 22 | // gamut expansion position
2283 0 << 15 | // reserved.
2284 0 << 14 | // single slice vebox enable
2285 0 << 13 | // hot pixel filter enable
2286 0 << 12 | // alpha plane enable
2287 0 << 11 | // vignette enable
2288 0 << 10 | // demosaic enable
2289 proc_ctx->current_output_type << 8 | // DI output frame
2290 1 << 7 | // 444->422 downsample method
2291 1 << 6 | // 422->420 downsample method
2292 proc_ctx->is_first_frame << 5 | // DN/DI first frame
2293 proc_ctx->is_di_enabled << 4 | // DI enable
2294 proc_ctx->is_dn_enabled << 3 | // DN enable
2295 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
2296 0 << 1 | // ColorGamutCompressionEnable
2297 0) ; // ColorGamutExpansionEnable.
2298
2299 OUT_RELOC(batch,
2300 proc_ctx->dndi_state_table.bo,
2301 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2302
2303 OUT_VEB_BATCH(batch, 0);
2304
2305 OUT_RELOC(batch,
2306 proc_ctx->iecp_state_table.bo,
2307 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2308
2309 OUT_VEB_BATCH(batch, 0);
2310
2311 OUT_RELOC(batch,
2312 proc_ctx->gamut_state_table.bo,
2313 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2314
2315 OUT_VEB_BATCH(batch, 0);
2316
2317 OUT_RELOC(batch,
2318 proc_ctx->vertex_state_table.bo,
2319 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2320
2321 OUT_VEB_BATCH(batch, 0);
2322
2323 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
2324 OUT_VEB_BATCH(batch, 0);
2325
2326 OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
2327 OUT_VEB_BATCH(batch, 0);
2328
2329 OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
2330 OUT_VEB_BATCH(batch, 0);
2331
2332 ADVANCE_VEB_BATCH(batch);
2333 }
2334
skl_veb_surface_state(VADriverContextP ctx,struct intel_vebox_context * proc_ctx,unsigned int is_output)2335 void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
2336 {
2337 struct intel_batchbuffer *batch = proc_ctx->batch;
2338 unsigned int u_offset_y = 0, v_offset_y = 0;
2339 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
2340 unsigned int surface_format = PLANAR_420_8;
2341 struct object_surface* obj_surf = NULL;
2342 unsigned int surface_pitch = 0;
2343 unsigned int half_pitch_chroma = 0;
2344 unsigned int derived_pitch;
2345
2346 if (is_output) {
2347 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
2348 } else {
2349 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
2350 }
2351
2352 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
2353 obj_surf->fourcc == VA_FOURCC_YUY2 ||
2354 obj_surf->fourcc == VA_FOURCC_AYUV ||
2355 obj_surf->fourcc == VA_FOURCC_RGBA ||
2356 obj_surf->fourcc == VA_FOURCC_P010);
2357
2358 if (obj_surf->fourcc == VA_FOURCC_NV12) {
2359 surface_format = PLANAR_420_8;
2360 surface_pitch = obj_surf->width;
2361 is_uv_interleaved = 1;
2362 half_pitch_chroma = 0;
2363 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
2364 surface_format = YCRCB_NORMAL;
2365 surface_pitch = obj_surf->width * 2;
2366 is_uv_interleaved = 0;
2367 half_pitch_chroma = 0;
2368 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
2369 surface_format = PACKED_444A_8;
2370 surface_pitch = obj_surf->width * 4;
2371 is_uv_interleaved = 0;
2372 half_pitch_chroma = 0;
2373 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
2374 surface_format = R8G8B8A8_UNORM_SRGB;
2375 surface_pitch = obj_surf->width * 4;
2376 is_uv_interleaved = 0;
2377 half_pitch_chroma = 0;
2378 } else if (obj_surf->fourcc == VA_FOURCC_P010) {
2379 surface_format = PLANAR_420_16;
2380 surface_pitch = obj_surf->width;
2381 is_uv_interleaved = 1;
2382 half_pitch_chroma = 0;
2383 }
2384
2385 derived_pitch = surface_pitch;
2386
2387 u_offset_y = obj_surf->y_cb_offset;
2388 v_offset_y = obj_surf->y_cr_offset;
2389
2390 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
2391
2392 BEGIN_VEB_BATCH(batch, 9);
2393 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
2394 OUT_VEB_BATCH(batch,
2395 0 << 1 | // reserved
2396 is_output); // surface indentification.
2397
2398 OUT_VEB_BATCH(batch,
2399 (obj_surf->orig_height - 1) << 18 | // height . w3
2400 (obj_surf->orig_width - 1) << 4 | // width
2401 0); // reserve
2402
2403 OUT_VEB_BATCH(batch,
2404 surface_format << 28 | // surface format, YCbCr420. w4
2405 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
2406 0 << 20 | // reserved
2407 (surface_pitch - 1) << 3 | // surface pitch, 64 align
2408 half_pitch_chroma << 2 | // half pitch for chrome
2409 !!tiling << 1 | // tiled surface, linear surface used
2410 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
2411
2412 OUT_VEB_BATCH(batch,
2413 0 << 16 | // X offset for V(Cb)
2414 u_offset_y); // Y offset for V(Cb)
2415
2416 OUT_VEB_BATCH(batch,
2417 0 << 16 | // X offset for V(Cr)
2418 v_offset_y); // Y offset for V(Cr)
2419
2420 OUT_VEB_BATCH(batch, 0);
2421
2422 OUT_VEB_BATCH(batch, derived_pitch - 1);
2423
2424 OUT_VEB_BATCH(batch, 0);
2425
2426 ADVANCE_VEB_BATCH(batch);
2427 }
2428
2429 VAStatus
gen9_vebox_process_picture(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2430 gen9_vebox_process_picture(VADriverContextP ctx,
2431 struct intel_vebox_context *proc_ctx)
2432 {
2433 VAStatus status;
2434
2435 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
2436 if (status != VA_STATUS_SUCCESS)
2437 return status;
2438
2439 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
2440 if (status != VA_STATUS_SUCCESS)
2441 return status;
2442
2443 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
2444 if (status != VA_STATUS_SUCCESS)
2445 return status;
2446
2447 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
2448 if (status != VA_STATUS_SUCCESS)
2449 return status;
2450
2451 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
2452 if (status != VA_STATUS_SUCCESS)
2453 return status;
2454
2455 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
2456 vpp_sharpness_filtering(ctx, proc_ctx);
2457 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
2458 assert(proc_ctx->is_second_field);
2459 /* directly copy the saved frame in the second call */
2460 } else {
2461 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
2462 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
2463 skl_veb_state_table_setup(ctx, proc_ctx);
2464 skl_veb_state_command(ctx, proc_ctx);
2465 skl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
2466 skl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
2467 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
2468 intel_batchbuffer_end_atomic(proc_ctx->batch);
2469 intel_batchbuffer_flush(proc_ctx->batch);
2470 }
2471
2472 status = hsw_veb_post_format_convert(ctx, proc_ctx);
2473
2474 return status;
2475 }
2476
2477 void
cnl_veb_state_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2478 cnl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2479 {
2480 struct intel_batchbuffer *batch = proc_ctx->batch;
2481
2482 BEGIN_VEB_BATCH(batch, 0x13);
2483 OUT_VEB_BATCH(batch, VEB_STATE | (0x13 - 2));
2484 OUT_VEB_BATCH(batch,
2485 0 << 25 | // state surface control bits
2486 0 << 23 | // reserved.
2487 0 << 22 | // gamut expansion position
2488 0 << 15 | // reserved.
2489 0 << 14 | // single slice vebox enable
2490 0 << 13 | // hot pixel filter enable
2491 0 << 12 | // alpha plane enable
2492 0 << 11 | // vignette enable
2493 0 << 10 | // demosaic enable
2494 proc_ctx->current_output_type << 8 | // DI output frame
2495 1 << 7 | // 444->422 downsample method
2496 1 << 6 | // 422->420 downsample method
2497 proc_ctx->is_first_frame << 5 | // DN/DI first frame
2498 proc_ctx->is_di_enabled << 4 | // DI enable
2499 proc_ctx->is_dn_enabled << 3 | // DN enable
2500 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
2501 0 << 1 | // ColorGamutCompressionEnable
2502 0) ; // ColorGamutExpansionEnable.
2503
2504 OUT_RELOC64(batch,
2505 proc_ctx->dndi_state_table.bo,
2506 I915_GEM_DOMAIN_INSTRUCTION, 0, 0); // DW 2-3
2507
2508 OUT_RELOC64(batch,
2509 proc_ctx->iecp_state_table.bo,
2510 I915_GEM_DOMAIN_INSTRUCTION, 0, 0); // DW 4-5
2511
2512 OUT_RELOC64(batch,
2513 proc_ctx->gamut_state_table.bo,
2514 I915_GEM_DOMAIN_INSTRUCTION, 0, 0); // DW 6-7
2515
2516 OUT_RELOC64(batch,
2517 proc_ctx->vertex_state_table.bo,
2518 I915_GEM_DOMAIN_INSTRUCTION, 0, 0); // DW 8-9
2519
2520 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
2521 OUT_VEB_BATCH(batch, 0);
2522
2523 OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
2524 OUT_VEB_BATCH(batch, 0);
2525
2526 OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
2527 OUT_VEB_BATCH(batch, 0);
2528
2529 OUT_VEB_BATCH(batch, 0);
2530 OUT_VEB_BATCH(batch, 0);
2531 OUT_VEB_BATCH(batch, 0);
2532
2533
2534 ADVANCE_VEB_BATCH(batch);
2535 }
2536
cnl_veb_dndi_iecp_command(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2537 void cnl_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2538 {
2539 struct intel_batchbuffer *batch = proc_ctx->batch;
2540 unsigned char frame_ctrl_bits = 0;
2541 struct object_surface *obj_surface = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
2542 unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
2543
2544 assert(obj_surface);
2545 if (width64 > obj_surface->orig_width)
2546 width64 = obj_surface->orig_width;
2547
2548 BEGIN_VEB_BATCH(batch, 0x18);
2549 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x18 - 2));//DWord 0
2550 OUT_VEB_BATCH(batch, (width64 - 1));
2551
2552 OUT_RELOC64(batch,
2553 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
2554 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2-3
2555
2556 OUT_RELOC64(batch,
2557 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
2558 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4-4
2559
2560 OUT_RELOC64(batch,
2561 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
2562 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6-7
2563
2564 OUT_RELOC64(batch,
2565 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
2566 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8-9
2567
2568 OUT_RELOC64(batch,
2569 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
2570 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10-11
2571
2572 OUT_RELOC64(batch,
2573 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
2574 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12-13
2575
2576 OUT_RELOC64(batch,
2577 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
2578 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14-15
2579
2580 OUT_RELOC64(batch,
2581 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
2582 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16-17
2583
2584 OUT_VEB_BATCH(batch, 0); //DWord 18
2585 OUT_VEB_BATCH(batch, 0); //DWord 19
2586
2587 OUT_VEB_BATCH(batch, 0); //DWord 20
2588 OUT_VEB_BATCH(batch, 0); //DWord 21
2589 OUT_VEB_BATCH(batch, 0); //DWord 22
2590 OUT_VEB_BATCH(batch, 0); //DWord 23
2591
2592 ADVANCE_VEB_BATCH(batch);
2593 }
2594
cnl_veb_surface_state(VADriverContextP ctx,struct intel_vebox_context * proc_ctx,unsigned int is_output)2595 void cnl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
2596 {
2597 struct intel_batchbuffer *batch = proc_ctx->batch;
2598 unsigned int u_offset_y = 0, v_offset_y = 0;
2599 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
2600 unsigned int surface_format = PLANAR_420_8;
2601 struct object_surface* obj_surf = NULL;
2602 unsigned int surface_pitch = 0;
2603 unsigned int half_pitch_chroma = 0;
2604 unsigned int derived_pitch;
2605
2606 if (is_output) {
2607 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
2608 } else {
2609 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
2610 }
2611
2612 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
2613 obj_surf->fourcc == VA_FOURCC_YUY2 ||
2614 obj_surf->fourcc == VA_FOURCC_AYUV ||
2615 obj_surf->fourcc == VA_FOURCC_RGBA ||
2616 obj_surf->fourcc == VA_FOURCC_P010);
2617
2618 if (obj_surf->fourcc == VA_FOURCC_NV12) {
2619 surface_format = PLANAR_420_8;
2620 surface_pitch = obj_surf->width;
2621 is_uv_interleaved = 1;
2622 half_pitch_chroma = 0;
2623 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
2624 surface_format = YCRCB_NORMAL;
2625 surface_pitch = obj_surf->width * 2;
2626 is_uv_interleaved = 0;
2627 half_pitch_chroma = 0;
2628 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
2629 surface_format = PACKED_444A_8;
2630 surface_pitch = obj_surf->width * 4;
2631 is_uv_interleaved = 0;
2632 half_pitch_chroma = 0;
2633 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
2634 surface_format = R8G8B8A8_UNORM_SRGB;
2635 surface_pitch = obj_surf->width * 4;
2636 is_uv_interleaved = 0;
2637 half_pitch_chroma = 0;
2638 } else if (obj_surf->fourcc == VA_FOURCC_P010) {
2639 surface_format = PLANAR_420_16;
2640 surface_pitch = obj_surf->width;
2641 is_uv_interleaved = 1;
2642 half_pitch_chroma = 0;
2643 }
2644
2645 derived_pitch = surface_pitch;
2646
2647 u_offset_y = obj_surf->y_cb_offset;
2648 v_offset_y = obj_surf->y_cr_offset;
2649
2650 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
2651
2652 BEGIN_VEB_BATCH(batch, 9);
2653 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
2654 OUT_VEB_BATCH(batch,
2655 0 << 1 | // reserved
2656 is_output); // surface indentification.
2657
2658 OUT_VEB_BATCH(batch,
2659 (obj_surf->orig_height - 1) << 18 | // height . w3
2660 (obj_surf->orig_width - 1) << 4 | // width
2661 0); // reserve
2662
2663 OUT_VEB_BATCH(batch,
2664 surface_format << 27 | // surface format, YCbCr420. w4
2665 is_uv_interleaved << 20 | // interleave chrome , two seperate palar
2666 (surface_pitch - 1) << 3 | // surface pitch, 64 align
2667 half_pitch_chroma << 2 | // half pitch for chrome
2668 !!tiling << 1 | // tiled surface, linear surface used
2669 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
2670
2671 OUT_VEB_BATCH(batch,
2672 0 << 16 | // X offset for V(Cb)
2673 u_offset_y); // Y offset for V(Cb)
2674
2675 OUT_VEB_BATCH(batch,
2676 0 << 16 | // X offset for V(Cr)
2677 v_offset_y); // Y offset for V(Cr)
2678
2679 OUT_VEB_BATCH(batch, 0);
2680
2681 OUT_VEB_BATCH(batch, derived_pitch - 1);
2682
2683 OUT_VEB_BATCH(batch, 0);
2684
2685 ADVANCE_VEB_BATCH(batch);
2686 }
2687
2688 VAStatus
gen10_vebox_process_picture(VADriverContextP ctx,struct intel_vebox_context * proc_ctx)2689 gen10_vebox_process_picture(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2690 {
2691 VAStatus status;
2692
2693 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
2694 if (status != VA_STATUS_SUCCESS)
2695 return status;
2696
2697 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
2698 if (status != VA_STATUS_SUCCESS)
2699 return status;
2700
2701 status = hsw_veb_pre_format_convert(ctx, proc_ctx);
2702 if (status != VA_STATUS_SUCCESS)
2703 return status;
2704
2705 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
2706 if (status != VA_STATUS_SUCCESS)
2707 return status;
2708
2709 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
2710 if (status != VA_STATUS_SUCCESS)
2711 return status;
2712
2713 if (proc_ctx->filters_mask & VPP_SHARP_MASK) {
2714 vpp_sharpness_filtering(ctx, proc_ctx);
2715 } else if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
2716 assert(proc_ctx->is_second_field);
2717 /* directly copy the saved frame in the second call */
2718 } else {
2719 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
2720 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
2721 skl_veb_state_table_setup(ctx, proc_ctx);
2722 cnl_veb_state_command(ctx, proc_ctx);
2723 cnl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
2724 cnl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
2725 cnl_veb_dndi_iecp_command(ctx, proc_ctx);
2726 intel_batchbuffer_end_atomic(proc_ctx->batch);
2727 intel_batchbuffer_flush(proc_ctx->batch);
2728 }
2729
2730 status = hsw_veb_post_format_convert(ctx, proc_ctx);
2731
2732 return status;
2733 }
2734