OSDN Git Service

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