Check the pointer against NULL
[platform/upstream/libva-intel-driver.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
57 extern VAStatus
58 i965_CreateSurfaces(VADriverContextP ctx,
59                     int width,
60                     int height,
61                     int format,
62                     int num_surfaces,
63                     VASurfaceID *surfaces);
64
65 VAStatus vpp_surface_convert(VADriverContextP ctx,
66                              struct object_surface *src_obj_surf,
67                              struct object_surface *dst_obj_surf)
68 {
69     VAStatus va_status = VA_STATUS_SUCCESS;
70
71     assert(src_obj_surf->orig_width  == dst_obj_surf->orig_width);
72     assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
73
74     VARectangle src_rect, dst_rect;
75     src_rect.x = dst_rect.x = 0;
76     src_rect.y = dst_rect.y = 0; 
77     src_rect.width  = dst_rect.width  = src_obj_surf->orig_width; 
78     src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
79
80     struct i965_surface src_surface, dst_surface;
81     src_surface.base  = (struct object_base *)src_obj_surf;
82     src_surface.type  = I965_SURFACE_TYPE_SURFACE;
83     src_surface.flags = I965_SURFACE_FLAG_FRAME;
84
85     dst_surface.base  = (struct object_base *)dst_obj_surf;
86     dst_surface.type  = I965_SURFACE_TYPE_SURFACE;
87     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
88
89     va_status = i965_image_processing(ctx,
90                                      &src_surface,
91                                      &src_rect,
92                                      &dst_surface,
93                                      &dst_rect);
94     return va_status;
95 }
96
97 VAStatus vpp_surface_scaling(VADriverContextP ctx,
98                              struct object_surface *dst_obj_surf,
99                              struct object_surface *src_obj_surf)
100 {
101     VAStatus va_status = VA_STATUS_SUCCESS;
102     int flags = I965_PP_FLAG_AVS;
103
104     assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
105     assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
106
107     VARectangle src_rect, dst_rect;
108     src_rect.x = 0;
109     src_rect.y = 0; 
110     src_rect.width  = src_obj_surf->orig_width; 
111     src_rect.height = src_obj_surf->orig_height;
112
113     dst_rect.x = 0;
114     dst_rect.y = 0; 
115     dst_rect.width  = dst_obj_surf->orig_width; 
116     dst_rect.height = dst_obj_surf->orig_height;
117
118     va_status = i965_scaling_processing(ctx,
119                                        src_obj_surf,
120                                        &src_rect,
121                                        dst_obj_surf,
122                                        &dst_rect,
123                                        flags);
124      
125     return va_status;
126 }
127
128 void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
129 {
130     struct i965_driver_data *i965 = i965_driver_data(ctx);
131     unsigned int* p_table ;
132     int progressive_dn = 1;
133     int dndi_top_first = 0;
134     int motion_compensated_enable = 0;
135
136     if (proc_ctx->filters_mask & VPP_DNDI_DI) {
137         VAProcFilterParameterBufferDeinterlacing *di_param =
138             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
139         assert(di_param);
140
141         progressive_dn = 0;
142         dndi_top_first = !(di_param->flags & VA_DEINTERLACING_BOTTOM_FIELD);
143         motion_compensated_enable = (di_param->algorithm == VAProcDeinterlacingMotionCompensated);
144     }
145
146     /*
147     VAProcFilterParameterBufferDeinterlacing *di_param =
148             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
149
150     VAProcFilterParameterBuffer * dn_param =
151             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
152     */
153     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
154
155      if (IS_HASWELL(i965->intel.device_info))
156          *p_table ++ = 0;               // reserved  . w0
157
158     *p_table ++ = ( 140 << 24 |    // denoise STAD threshold . w1
159                     192 << 16 |    // dnmh_history_max
160                     0   << 12 |    // reserved
161                     7   << 8  |    // dnmh_delta[3:0]
162                     38 );          // denoise ASD threshold
163
164     *p_table ++ = ( 0  << 30 |    // reserved . w2
165                     0  << 24 |    // temporal diff th
166                     0  << 22 |    // reserved.
167                     0  << 16 |    // low temporal diff th
168                     2  << 13 |    // STMM C2
169                     1  << 8  |    // denoise moving pixel th
170                     38 );         // denoise th for sum of complexity measure
171
172     *p_table ++ = ( 0 << 30  |   // reserved . w3
173                     12<< 24  |   // good neighbor th[5:0]
174                     9 << 20  |   // CAT slope minus 1
175                     5 << 16  |   // SAD Tight in
176                     0 << 14  |   // smooth mv th
177                     0 << 12  |   // reserved
178                     1 << 8   |   // bne_edge_th[3:0]
179                     20 );        // block noise estimate noise th
180
181     *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
182                     64 << 24  |  // STMM trc1
183                     125<< 16  |  // STMM trc2
184                     0  << 14  |  // reserved
185                     30 << 8   |  // VECM_mul
186                     150 );       // maximum STMM
187
188     *p_table ++ = ( 118<< 24  |  // minumum STMM  . W5
189                     0  << 22  |  // STMM shift down
190                     1  << 20  |  // STMM shift up
191                     5  << 16  |  // STMM output shift
192                     100 << 8  |  // SDI threshold
193                     5 );         // SDI delta
194
195     *p_table ++ = ( 50  << 24 |  // SDI fallback mode 1 T1 constant . W6
196                     100 << 16 |  // SDI fallback mode 1 T2 constant
197                     37  << 8  |  // SDI fallback mode 2 constant(angle2x1)
198                     175 );       // FMD temporal difference threshold
199
200     *p_table ++ = ( 16 << 24  |  // FMD #1 vertical difference th . w7
201                     100<< 16  |  // FMD #2 vertical difference th
202                     0  << 14  |  // CAT th1
203                     2  << 8   |  // FMD tear threshold
204                     motion_compensated_enable  << 7   |  // MCDI Enable, use motion compensated deinterlace algorithm
205                     progressive_dn  << 6   |  // progressive DN
206                     0  << 4   |  // reserved
207                     dndi_top_first  << 3   |  // DN/DI Top First
208                     0 );         // reserved
209
210     *p_table ++ = ( 0  << 29  |  // reserved . W8
211                     32 << 23  |  // dnmh_history_init[5:0]
212                     10 << 19  |  // neighborPixel th
213                     0  << 18  |  // reserved
214                     0  << 16  |  // FMD for 2nd field of previous frame
215                     25 << 10  |  // MC pixel consistency th
216                     0  << 8   |  // FMD for 1st field for current frame
217                     10 << 4   |  // SAD THB
218                     5 );         // SAD THA
219
220     *p_table ++ = ( 0  << 24  |  // reserved
221                     140<< 16  |  // chr_dnmh_stad_th
222                     0  << 13  |  // reserved
223                     1  << 12  |  // chrome denoise enable
224                     13 << 6   |  // chr temp diff th
225                     7 );         // chr temp diff low
226
227     if (IS_GEN8(i965->intel.device_info))
228         *p_table ++ = 0;         // parameters for hot pixel, 
229 }
230
231 void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
232 {
233     unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
234     //VAProcFilterParameterBuffer * std_param =
235     //        (VAProcFilterParameterBuffer *) proc_ctx->filter_std;
236
237     if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){ 
238         memset(p_table, 0, 29 * 4);
239     }else{
240         //DWord 0
241         *p_table ++ = ( 154 << 24 |   // V_Mid
242                         110 << 16 |   // U_Mid
243                         14 << 10  |   // Hue_Max
244                         31 << 4   |   // Sat_Max
245                         0 << 3    |   // Reserved
246                         0 << 2    |   // Output Control is set to output the 1=STD score /0=Output Pixels
247                         1 << 1    |   // Set STE Enable
248                         1 );          // Set STD Enable
249
250         //DWord 1
251         *p_table ++ = ( 0 << 31   |   // Reserved
252                         4 << 28   |   // Diamond Margin
253                         0 << 21   |   // Diamond_du
254                         3 << 18   |   // HS_Margin
255                         79 << 10  |   // Cos(alpha)
256                         0 << 8    |   // Reserved
257                         101 );        // Sin(alpha)
258
259         //DWord 2
260         *p_table ++ = ( 0 << 21   |   // Reserved
261                         100 << 13 |   // Diamond_alpha
262                         35 << 7   |   // Diamond_Th
263                         0 );
264
265         //DWord 3
266         *p_table ++ = ( 254 << 24 |   // Y_point_3
267                         47 << 16  |   // Y_point_2
268                         46 << 8   |   // Y_point_1
269                         1 << 7    |   // VY_STD_Enable
270                         0 );          // Reserved
271
272         //DWord 4
273         *p_table ++ = ( 0 << 18   |   // Reserved
274                         31 << 13  |   // Y_slope_2
275                         31 << 8   |   // Y_slope_1
276                         255 );        // Y_point_4
277
278         //DWord 5
279         *p_table ++ = ( 400 << 16 |   // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
280                         3300 );       // INV_Margin_VYL => 1/Margin_VYL
281
282         //DWord 6
283         *p_table ++ = ( 216 << 24 |   // P1L
284                         46 << 16  |   // P0L
285                         1600 );       // INV_Margin_VYU
286
287         //DWord 7
288         *p_table ++ = ( 130 << 24 |   // B1L
289                         133 << 16 |   // B0L
290                         236 << 8  |   // P3L
291                         236 );        // P2L
292
293         //DWord 8
294         *p_table ++ = ( 0 << 27      |   // Reserved
295                         0x7FB << 16  |   // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
296                         130 << 8     |   // B3L
297                         130 );
298
299         //DWord 9
300         *p_table ++ = ( 0 << 22   |    // Reserved
301                         0 << 11   |    // S2L
302                         0);            // S1L
303
304         //DWord 10
305         *p_table ++ = ( 0 << 27   |    // Reserved
306                         66 << 19  |    // P1U
307                         46 << 11  |    // P0U
308                         0 );           // S3
309
310         //DWord 11
311         *p_table ++ = ( 163 << 24 |    // B1U
312                         143 << 16 |    // B0U
313                         236 << 8  |    // P3U
314                         150 );         // P2U
315
316         //DWord 12
317         *p_table ++ = ( 0 << 27   |    // Reserved
318                         256 << 16 |    // S0U
319                         200 << 8  |    // B3U
320                         200 );         // B2U
321
322         //DWord 13
323         *p_table ++ = ( 0 << 22     |    // Reserved
324                         0x74D << 11 |    // S2U (11 bits, Default value -179 = F4Dh)
325                         113 );           // S1U
326
327         //DWoord 14
328         *p_table ++ = ( 0 << 28   |    // Reserved
329                         20 << 20  |    // Skin_types_margin
330                         120 << 12 |    // Skin_types_thresh
331                         1 << 11   |    // Skin_Types_Enable
332                         0 );           // S3U
333
334         //DWord 15
335         *p_table ++ = ( 0 << 31     |    // Reserved
336                         0x3F8 << 21 |    // SATB1 (10 bits, default 8, optimized value -8)
337                         31 << 14    |    // SATP3
338                         6 << 7      |    // SATP2
339                         0x7A );          // SATP1 (7 bits, default 6, optimized value -6)
340
341         //DWord 16
342         *p_table ++ = ( 0 << 31   |    // Reserved
343                         297 << 20 |    // SATS0
344                         124 << 10 |    // SATB3
345                         8 );           // SATB2
346
347         //DWord 17
348         *p_table ++ = ( 0 << 22   |    // Reserved
349                         297 << 11 |    // SATS2
350                         85 );          // SATS1
351
352         //DWord 18
353         *p_table ++ = ( 14 << 25    |    // HUEP3
354                         6 << 18     |    // HUEP2
355                         0x7A << 11  |    // HUEP1 (7 bits, default value -6 = 7Ah)
356                         256 );           // SATS3
357
358         //DWord 19
359         *p_table ++ = ( 0 << 30   |    // Reserved
360                         256 << 20 |    // HUEB3
361                         8 << 10   |    // HUEB2
362                         0x3F8 );       // HUEB1 (10 bits, default value 8, optimized value -8)
363
364         //DWord 20
365         *p_table ++ = ( 0 << 22   |    // Reserved
366                         85 << 11  |    // HUES1
367                         384 );         // HUES
368
369         //DWord 21
370         *p_table ++ = ( 0 << 22   |    // Reserved
371                         256 << 11 |    // HUES3
372                         384 );         // HUES2
373
374         //DWord 22
375         *p_table ++ = ( 0 << 31   |    // Reserved
376                         0 << 21   |    // SATB1_DARK
377                         31 << 14  |    // SATP3_DARK
378                         31 << 7   |    // SATP2_DARK
379                         0x7B );        // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
380
381         //DWord 23
382         *p_table ++ = ( 0 << 31   |    // Reserved
383                         305 << 20 |    // SATS0_DARK
384                         124 << 10 |    // SATB3_DARK
385                         124 );         // SATB2_DARK
386
387         //DWord 24
388         *p_table ++ = ( 0 << 22   |    // Reserved
389                         256 << 11 |    // SATS2_DARK
390                         220 );         // SATS1_DARK
391
392         //DWord 25
393         *p_table ++ = ( 14 << 25  |    // HUEP3_DARK
394                         14 << 18  |    // HUEP2_DARK
395                         14 << 11  |    // HUEP1_DARK
396                         256 );         // SATS3_DARK
397
398         //DWord 26
399         *p_table ++ = ( 0 << 30   |    // Reserved
400                         56 << 20  |    // HUEB3_DARK
401                         56 << 10  |    // HUEB2_DARK
402                         56 );          // HUEB1_DARK
403
404         //DWord 27
405         *p_table ++ = ( 0 << 22   |    // Reserved
406                         256 << 11 |    // HUES1_DARK
407                         256 );         // HUES0_DARK
408
409         //DWord 28
410         *p_table ++ = ( 0 << 22   |    // Reserved
411                         256 << 11 |    // HUES3_DARK
412                         256 );         // HUES2_DARK
413     }
414 }
415
416 void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
417 {
418    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
419
420     if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){ 
421         memset(p_table, 0, 13 * 4);
422     }else{
423         *p_table ++ = 0x00000068;
424         *p_table ++ = 0x4c382410;
425         *p_table ++ = 0x9c887460;
426         *p_table ++ = 0xebd8c4b0;
427         *p_table ++ = 0x604c3824;
428
429         *p_table ++ = 0xb09c8874;
430         *p_table ++ = 0x0000d8c4;
431         *p_table ++ = 0x00000000;
432         *p_table ++ = 0x00000000;
433         *p_table ++ = 0x00000000;
434
435         *p_table ++ = 0x00000000;
436         *p_table ++ = 0x00000000;
437         *p_table ++ = 0x00000000;
438    }
439 }
440
441 void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
442 {
443     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
444 //    VAProcFilterParameterBuffer * tcc_param =
445 //            (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
446
447    if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){ 
448         memset(p_table, 0, 11 * 4);
449     }else{
450         *p_table ++ = 0x00000000;
451         *p_table ++ = 0x00000000;
452         *p_table ++ = 0x1e34cc91;
453         *p_table ++ = 0x3e3cce91;
454         *p_table ++ = 0x02e80195;
455
456         *p_table ++ = 0x0197046b;
457         *p_table ++ = 0x01790174;
458         *p_table ++ = 0x00000000;
459         *p_table ++ = 0x00000000;
460         *p_table ++ = 0x03030000;
461
462         *p_table ++ = 0x009201c0;
463    }
464 }
465
466 void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
467 {
468     unsigned int contrast = 0x80;  //default 
469     int brightness = 0x00;         //default
470     int cos_c_s    = 256 ;         //default
471     int sin_c_s    = 0;            //default 
472     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
473
474     if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
475         memset(p_table, 0, 2 * 4);
476     }else {
477         float  src_saturation = 1.0;
478         float  src_hue = 0.0;
479         float  src_contrast = 1.0;
480         float  src_brightness = 0.0;
481         float  tmp_value = 0.0;
482         unsigned int i = 0;
483
484         VAProcFilterParameterBufferColorBalance * amp_params =
485             (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
486  
487         for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
488             VAProcColorBalanceType attrib = amp_params[i].attrib;
489
490             if(attrib == VAProcColorBalanceHue) {
491                src_hue = amp_params[i].value;         //(-180.0, 180.0)
492             }else if(attrib == VAProcColorBalanceSaturation) {
493                src_saturation = amp_params[i].value; //(0.0, 10.0)
494             }else if(attrib == VAProcColorBalanceBrightness) {
495                src_brightness = amp_params[i].value; // (-100.0, 100.0)
496                brightness = intel_format_convert(src_brightness, 7, 4, 1);
497             }else if(attrib == VAProcColorBalanceContrast) {
498                src_contrast = amp_params[i].value;  //  (0.0, 10.0)
499                contrast = intel_format_convert(src_contrast, 4, 7, 0);
500             }
501         }
502
503         tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
504         cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
505         
506         tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
507         sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
508      
509         *p_table ++ = ( 0 << 28 |         //reserved
510                         contrast << 17 |  //contrast value (U4.7 format)
511                         0 << 13 |         //reserved
512                         brightness << 1|  // S7.4 format
513                         1);
514
515         *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
516                         sin_c_s);        // sin(h) * contrast * saturation
517                  
518     }
519 }
520
521
522 void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
523 {
524     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
525     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
526     float v_coef[3]    = {0.0, 0.0, 0.0};
527     float u_coef[3]    = {0.0, 0.0, 0.0};
528     int   is_transform_enabled = 0;
529
530     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
531         memset(p_table, 0, 8 * 4);
532         return;
533     }
534
535     if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
536        (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
537         proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
538         proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
539         proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
540
541          tran_coef[0] = 0.257;
542          tran_coef[1] = 0.504;
543          tran_coef[2] = 0.098;
544          tran_coef[3] = -0.148;
545          tran_coef[4] = -0.291;
546          tran_coef[5] = 0.439;
547          tran_coef[6] = 0.439;
548          tran_coef[7] = -0.368;
549          tran_coef[8] = -0.071; 
550
551          u_coef[0] = 16 * 4;
552          u_coef[1] = 128 * 4;
553          u_coef[2] = 128 * 4;
554  
555          is_transform_enabled = 1; 
556     }else if((proc_ctx->fourcc_input  == VA_FOURCC_NV12 ||
557               proc_ctx->fourcc_input  == VA_FOURCC_YV12 ||
558               proc_ctx->fourcc_input  == VA_FOURCC_YUY2 ||
559               proc_ctx->fourcc_input  == VA_FOURCC_AYUV) &&
560               proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
561          tran_coef[0] = 1.164;
562          tran_coef[1] = 0.000;
563          tran_coef[2] = 1.569;
564          tran_coef[3] = 1.164;
565          tran_coef[4] = -0.813;
566          tran_coef[5] = -0.392;
567          tran_coef[6] = 1.164;
568          tran_coef[7] = 2.017;
569          tran_coef[8] = 0.000; 
570
571          v_coef[0] = -16 * 4;
572          v_coef[1] = -128 * 4;
573          v_coef[2] = -128 * 4;
574
575         is_transform_enabled = 1; 
576     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
577          //enable when input and output format are different.
578          is_transform_enabled = 1;
579     }
580
581     if(is_transform_enabled == 0){
582         memset(p_table, 0, 8 * 4);
583     }else{
584         *p_table ++ = ( 0 << 29 | //reserved
585                         intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
586                         intel_format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
587                         0 << 2 | //reserved
588                         0 << 1 | // yuv_channel swap
589                         is_transform_enabled);                
590
591         *p_table ++ = ( 0 << 26 | //reserved
592                         intel_format_convert(tran_coef[3], 2, 10, 1) << 13 | 
593                         intel_format_convert(tran_coef[2], 2, 10, 1));
594     
595         *p_table ++ = ( 0 << 26 | //reserved
596                         intel_format_convert(tran_coef[5], 2, 10, 1) << 13 | 
597                         intel_format_convert(tran_coef[4], 2, 10, 1));
598
599         *p_table ++ = ( 0 << 26 | //reserved
600                         intel_format_convert(tran_coef[7], 2, 10, 1) << 13 | 
601                         intel_format_convert(tran_coef[6], 2, 10, 1));
602
603         *p_table ++ = ( 0 << 13 | //reserved
604                         intel_format_convert(tran_coef[8], 2, 10, 1));
605
606         *p_table ++ = ( 0 << 22 | //reserved
607                         intel_format_convert(u_coef[0], 10, 0, 1) << 11 | 
608                         intel_format_convert(v_coef[0], 10, 0, 1));
609
610         *p_table ++ = ( 0 << 22 | //reserved
611                         intel_format_convert(u_coef[1], 10, 0, 1) << 11 | 
612                         intel_format_convert(v_coef[1], 10, 0, 1));
613
614         *p_table ++ = ( 0 << 22 | //reserved
615                         intel_format_convert(u_coef[2], 10, 0, 1) << 11 | 
616                         intel_format_convert(v_coef[2], 10, 0, 1));
617     }
618 }
619
620 void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
621 {
622     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
623    // VAProcFilterParameterBuffer * tcc_param =
624    //         (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
625
626     if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){ 
627         memset(p_table, 0, 3 * 4);
628     }else{
629         *p_table ++ = 0x00000000;
630         *p_table ++ = 0x00030000;
631         *p_table ++ = 0x00030000;
632    }
633 }
634
635 void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
636 {
637     if(proc_ctx->filters_mask & 0x000000ff) {
638         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
639         dri_bo_map(dndi_bo, 1);
640         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
641
642         hsw_veb_dndi_table(ctx, proc_ctx);
643
644         dri_bo_unmap(dndi_bo);
645     }
646
647     if(proc_ctx->filters_mask & 0x0000ff00) {
648         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
649         dri_bo_map(iecp_bo, 1);
650         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
651
652         hsw_veb_iecp_std_table(ctx, proc_ctx);
653         hsw_veb_iecp_ace_table(ctx, proc_ctx);
654         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
655         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
656         hsw_veb_iecp_csc_table(ctx, proc_ctx);
657         hsw_veb_iecp_aoi_table(ctx, proc_ctx);
658    
659         dri_bo_unmap(iecp_bo);
660     }
661 }
662
663 void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
664 {
665     struct intel_batchbuffer *batch = proc_ctx->batch;
666     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
667     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
668     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
669     unsigned int is_first_frame  = !!((proc_ctx->frame_order == -1) &&
670                                       (is_di_enabled ||
671                                        is_dn_enabled));
672     unsigned int di_output_frames_flag = 2; /* Output Current Frame Only */
673
674     if(proc_ctx->fourcc_input != proc_ctx->fourcc_output ||
675        (is_dn_enabled == 0 && is_di_enabled == 0)){
676        is_iecp_enabled = 1;
677     }
678
679     if (is_di_enabled) {
680         VAProcFilterParameterBufferDeinterlacing *di_param =
681             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
682
683         assert(di_param);
684         
685         if (di_param->algorithm == VAProcDeinterlacingBob)
686             is_first_frame = 1;
687
688         if ((di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
689             di_param->algorithm == VAProcDeinterlacingMotionCompensated) &&
690             proc_ctx->frame_order != -1)
691             di_output_frames_flag = 0; /* Output both Current Frame and Previous Frame */
692     }
693
694     BEGIN_VEB_BATCH(batch, 6);
695     OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
696     OUT_VEB_BATCH(batch,
697                   0 << 26 |       // state surface control bits
698                   0 << 11 |       // reserved.
699                   0 << 10 |       // pipe sync disable
700                   di_output_frames_flag << 8  |       // DI output frame
701                   1 << 7  |       // 444->422 downsample method
702                   1 << 6  |       // 422->420 downsample method
703                   is_first_frame  << 5  |   // DN/DI first frame
704                   is_di_enabled   << 4  |             // DI enable
705                   is_dn_enabled   << 3  |             // DN enable
706                   is_iecp_enabled << 2  |             // global IECP enabled
707                   0 << 1  |       // ColorGamutCompressionEnable
708                   0 ) ;           // ColorGamutExpansionEnable.
709
710     OUT_RELOC(batch, 
711               proc_ctx->dndi_state_table.bo,
712               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
713
714     OUT_RELOC(batch,
715               proc_ctx->iecp_state_table.bo, 
716               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
717
718     OUT_RELOC(batch,
719               proc_ctx->gamut_state_table.bo, 
720               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
721
722     OUT_RELOC(batch,
723               proc_ctx->vertex_state_table.bo, 
724               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
725
726     ADVANCE_VEB_BATCH(batch);
727 }
728
729 void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
730 {
731     struct intel_batchbuffer *batch = proc_ctx->batch;
732     unsigned int u_offset_y = 0, v_offset_y = 0;
733     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
734     unsigned int surface_format = PLANAR_420_8;
735     struct object_surface* obj_surf = NULL;
736     unsigned int surface_pitch = 0;
737     unsigned int half_pitch_chroma = 0;
738
739     if(is_output){   
740         obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
741     }else {
742         obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
743     }
744
745     assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
746            obj_surf->fourcc == VA_FOURCC_YUY2 ||
747            obj_surf->fourcc == VA_FOURCC_AYUV ||
748            obj_surf->fourcc == VA_FOURCC_RGBA);
749
750     if (obj_surf->fourcc == VA_FOURCC_NV12) {
751         surface_format = PLANAR_420_8;
752         surface_pitch = obj_surf->width; 
753         is_uv_interleaved = 1;
754         half_pitch_chroma = 0;
755     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
756         surface_format = YCRCB_NORMAL;
757         surface_pitch = obj_surf->width * 2; 
758         is_uv_interleaved = 0;
759         half_pitch_chroma = 0;
760     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
761         surface_format = PACKED_444A_8;
762         surface_pitch = obj_surf->width * 4; 
763         is_uv_interleaved = 0;
764         half_pitch_chroma = 0;
765     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
766         surface_format = R8G8B8A8_UNORM_SRGB;
767         surface_pitch = obj_surf->width * 4; 
768         is_uv_interleaved = 0;
769         half_pitch_chroma = 0;
770     }
771
772     u_offset_y = obj_surf->y_cb_offset;
773     v_offset_y = obj_surf->y_cr_offset;
774      
775     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
776
777     BEGIN_VEB_BATCH(batch, 6);
778     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
779     OUT_VEB_BATCH(batch,
780                   0 << 1 |         // reserved
781                   is_output);      // surface indentification.
782
783     OUT_VEB_BATCH(batch,
784                   (obj_surf->height - 1) << 18 |  // height . w3
785                   (obj_surf->width -1 )  << 4  |  // width
786                   0);                             // reserve
787
788     OUT_VEB_BATCH(batch,
789                   surface_format      << 28  |  // surface format, YCbCr420. w4
790                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
791                   0                   << 20  |  // reserved
792                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
793                   half_pitch_chroma   << 2   |  // half pitch for chrome
794                   !!tiling            << 1   |  // tiled surface, linear surface used
795                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
796
797     OUT_VEB_BATCH(batch,
798                   0 << 29  |     // reserved . w5
799                   0 << 16  |     // X offset for V(Cb)
800                   0 << 15  |     // reserved
801                   u_offset_y);   // Y offset for V(Cb)
802
803     OUT_VEB_BATCH(batch,
804                   0 << 29  |     // reserved . w6
805                   0 << 16  |     // X offset for V(Cr)
806                   0 << 15  |     // reserved
807                   v_offset_y );  // Y offset for V(Cr)
808
809     ADVANCE_VEB_BATCH(batch);
810 }
811
812 void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
813 {
814     struct intel_batchbuffer *batch = proc_ctx->batch;
815     unsigned char frame_ctrl_bits = 0;
816     unsigned int startingX = 0;
817     unsigned int endingX = (proc_ctx->width_input + 63 ) / 64 * 64;
818
819     /* s1:update the previous and current input */
820 /*    tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
821     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
822     proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
823
824     if(proc_ctx->surface_input_vebox != -1){
825         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
826                      proc_ctx->surface_input_vebox);
827     } else {
828         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
829                      proc_ctx->surface_input);
830     }
831 */
832     /*s2: update the STMM input and output */
833 /*    tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
834     proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
835     proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
836 */      
837     /*s3:set reloc buffer address */
838     BEGIN_VEB_BATCH(batch, 10);
839     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
840     OUT_VEB_BATCH(batch,
841                   startingX << 16 |
842                   (endingX-1));
843     OUT_RELOC(batch,
844               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
845               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
846     OUT_RELOC(batch,
847               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
848               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
849     OUT_RELOC(batch,
850               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
851               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
852     OUT_RELOC(batch,
853               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
854               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
855     OUT_RELOC(batch,
856               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
857               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
858     OUT_RELOC(batch,
859               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
860               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
861     OUT_RELOC(batch,
862               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
863               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
864     OUT_RELOC(batch,
865               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
866               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
867
868     ADVANCE_VEB_BATCH(batch);
869 }
870
871 void hsw_veb_resource_prepare(VADriverContextP ctx,
872                               struct intel_vebox_context *proc_ctx)
873 {
874     VAStatus va_status;
875     dri_bo *bo;
876     struct i965_driver_data *i965 = i965_driver_data(ctx);
877     unsigned int input_fourcc, output_fourcc;
878     unsigned int input_sampling, output_sampling;
879     unsigned int input_tiling, output_tiling;
880     unsigned int i, swizzle;
881     struct object_surface *obj_surf_out = NULL, *obj_surf_in = NULL;
882
883     if (proc_ctx->surface_input_vebox_object != NULL) {
884         obj_surf_in = proc_ctx->surface_input_vebox_object;
885     } else {
886         obj_surf_in = proc_ctx->surface_input_object;
887     } 
888
889     if (proc_ctx->surface_output_vebox_object != NULL) {
890         obj_surf_out = proc_ctx->surface_output_vebox_object;
891     } else {
892         obj_surf_out = proc_ctx->surface_output_object;
893     } 
894
895     if(obj_surf_in->bo == NULL){
896           input_fourcc = VA_FOURCC_NV12;
897           input_sampling = SUBSAMPLE_YUV420;
898           input_tiling = 0;
899           i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling);
900     } else {
901         input_fourcc = obj_surf_in->fourcc;
902         input_sampling = obj_surf_in->subsampling;
903         dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle);
904         input_tiling = !!input_tiling;
905     }
906
907     if(obj_surf_out->bo == NULL){
908           output_fourcc = VA_FOURCC_NV12;
909           output_sampling = SUBSAMPLE_YUV420;
910           output_tiling = 0;
911           i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling);
912     }else {
913         output_fourcc   = obj_surf_out->fourcc;
914         output_sampling = obj_surf_out->subsampling;
915         dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle);
916         output_tiling = !!output_tiling;
917     }
918
919     /* vebox pipelien input surface format info */
920     proc_ctx->fourcc_input = input_fourcc;
921     proc_ctx->fourcc_output = output_fourcc;
922    
923     /* create pipeline surfaces */
924     for(i = 0; i < FRAME_STORE_SUM; i ++) {
925         if(proc_ctx->frame_store[i].obj_surface){
926             continue; //refer external surface for vebox pipeline
927         }
928     
929         VASurfaceID new_surface;
930         struct object_surface *obj_surf = NULL;
931
932         va_status =   i965_CreateSurfaces(ctx,
933                                           proc_ctx ->width_input,
934                                           proc_ctx ->height_input,
935                                           VA_RT_FORMAT_YUV420,
936                                           1,
937                                           &new_surface);
938         assert(va_status == VA_STATUS_SUCCESS);
939
940         obj_surf = SURFACE(new_surface);
941         assert(obj_surf);
942
943         if( i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
944             i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling);
945         } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){
946             i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling);
947         } else if( i >= FRAME_OUT_CURRENT){
948             i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling);
949         }
950
951         proc_ctx->frame_store[i].surface_id = new_surface;
952         proc_ctx->frame_store[i].is_internal_surface = 1;
953         proc_ctx->frame_store[i].obj_surface = obj_surf;
954     }
955
956     /* alloc dndi state table  */
957     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
958     bo = dri_bo_alloc(i965->intel.bufmgr,
959                       "vebox: dndi state Buffer",
960                       0x1000, 0x1000);
961     proc_ctx->dndi_state_table.bo = bo;
962     dri_bo_reference(proc_ctx->dndi_state_table.bo);
963  
964     /* alloc iecp state table  */
965     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
966     bo = dri_bo_alloc(i965->intel.bufmgr,
967                       "vebox: iecp state Buffer",
968                       0x1000, 0x1000);
969     proc_ctx->iecp_state_table.bo = bo;
970     dri_bo_reference(proc_ctx->iecp_state_table.bo);
971
972     /* alloc gamut state table  */
973     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
974     bo = dri_bo_alloc(i965->intel.bufmgr,
975                       "vebox: gamut state Buffer",
976                       0x1000, 0x1000);
977     proc_ctx->gamut_state_table.bo = bo;
978     dri_bo_reference(proc_ctx->gamut_state_table.bo);
979
980     /* alloc vertex state table  */
981     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
982     bo = dri_bo_alloc(i965->intel.bufmgr,
983                       "vertex: iecp state Buffer",
984                       0x1000, 0x1000);
985     proc_ctx->vertex_state_table.bo = bo;
986     dri_bo_reference(proc_ctx->vertex_state_table.bo);
987
988 }
989
990 static VAStatus
991 hsw_veb_surface_reference(VADriverContextP ctx,
992                           struct intel_vebox_context *proc_ctx)
993 {
994     struct object_surface * obj_surf; 
995     VEBFrameStore tmp_store;
996
997     if (proc_ctx->surface_input_vebox_object != NULL) {
998         obj_surf = proc_ctx->surface_input_vebox_object;
999     } else {
1000         obj_surf = proc_ctx->surface_input_object;
1001     } 
1002
1003     /* update the input surface */ 
1004     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = VA_INVALID_ID;
1005     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
1006     proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface = obj_surf;
1007
1008     /* update the previous input surface */
1009     if (proc_ctx->frame_order != -1) {
1010         if (proc_ctx->filters_mask == VPP_DNDI_DN) {
1011             proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_OUT_CURRENT_DN];
1012         } else if (proc_ctx->filters_mask & VPP_DNDI_DI) {
1013             VAProcFilterParameterBufferDeinterlacing *di_param =
1014                 (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
1015
1016             if (di_param && 
1017                 (di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
1018                 di_param->algorithm == VAProcDeinterlacingMotionCompensated)) {
1019                 if ((proc_ctx->filters_mask & VPP_DNDI_DN) &&
1020                     proc_ctx->frame_order == 0) { /* DNDI */
1021                     tmp_store = proc_ctx->frame_store[FRAME_OUT_CURRENT_DN];
1022                     proc_ctx->frame_store[FRAME_OUT_CURRENT_DN] = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1023                     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = tmp_store;
1024                 } else { /* DI only */
1025                     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
1026                     struct object_surface *obj_surf = NULL;
1027                     struct i965_driver_data * const i965 = i965_driver_data(ctx);
1028
1029                     if (!pipe ||
1030                         !pipe->num_forward_references ||
1031                         pipe->forward_references[0] == VA_INVALID_ID) {
1032                         WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
1033
1034                         return VA_STATUS_ERROR_INVALID_PARAMETER;
1035                     }
1036
1037                     obj_surf = SURFACE(pipe->forward_references[0]);
1038                     assert(obj_surf && obj_surf->bo);
1039                 
1040                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id = pipe->forward_references[0];
1041                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].is_internal_surface = 0;
1042                     proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface = obj_surf;
1043                 }
1044             }
1045         }
1046     }
1047
1048     /* update STMM surface */
1049     if (proc_ctx->frame_order != -1) {
1050         tmp_store = proc_ctx->frame_store[FRAME_IN_STMM];
1051         proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM];
1052         proc_ctx->frame_store[FRAME_OUT_STMM] = tmp_store;
1053     }
1054
1055     /* update the output surface */ 
1056     if (proc_ctx->surface_output_vebox_object != NULL) {
1057         obj_surf = proc_ctx->surface_output_vebox_object;
1058     } else {
1059         obj_surf = proc_ctx->surface_output_object;
1060     } 
1061
1062     if (proc_ctx->filters_mask == VPP_DNDI_DN) {
1063         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = VA_INVALID_ID;
1064         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
1065         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface = obj_surf;
1066         proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
1067     } else if (proc_ctx->filters_mask & VPP_DNDI_DI) {
1068         VAProcFilterParameterBufferDeinterlacing *di_param =
1069             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
1070
1071         if (di_param && 
1072             (di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
1073             di_param->algorithm == VAProcDeinterlacingMotionCompensated)) {
1074             if (proc_ctx->frame_order == -1) {
1075                 proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
1076                 proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
1077                 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
1078                 proc_ctx->current_output = FRAME_OUT_CURRENT;
1079             } else if (proc_ctx->frame_order == 0) {
1080                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].surface_id = VA_INVALID_ID;
1081                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].is_internal_surface = 0;
1082                 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface = obj_surf;
1083                 proc_ctx->current_output = FRAME_OUT_PREVIOUS;
1084             } else {
1085                 proc_ctx->current_output = FRAME_OUT_CURRENT;
1086                 proc_ctx->format_convert_flags |= POST_COPY_CONVERT;
1087             }
1088         } else {
1089             proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
1090             proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
1091             proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
1092             proc_ctx->current_output = FRAME_OUT_CURRENT;
1093         }
1094     } else {
1095         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
1096         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
1097         proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = obj_surf;
1098         proc_ctx->current_output = FRAME_OUT_CURRENT;
1099     }
1100
1101     return VA_STATUS_SUCCESS;
1102 }
1103
1104 void hsw_veb_surface_unreference(VADriverContextP ctx,
1105                                  struct intel_vebox_context *proc_ctx)
1106 {
1107     /* unreference the input surface */ 
1108     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = VA_INVALID_ID;
1109     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
1110     proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface = NULL;
1111
1112     /* unreference the shared output surface */ 
1113     if (proc_ctx->filters_mask == VPP_DNDI_DN) {
1114         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = VA_INVALID_ID;
1115         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
1116         proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface = NULL;
1117     } else {
1118         proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = VA_INVALID_ID;
1119         proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
1120         proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface = NULL;
1121     }
1122 }
1123
1124 int hsw_veb_pre_format_convert(VADriverContextP ctx,
1125                            struct intel_vebox_context *proc_ctx)
1126 {
1127     VAStatus va_status;
1128     struct i965_driver_data *i965 = i965_driver_data(ctx);
1129     struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
1130     struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
1131     struct object_surface* obj_surf_input_vebox;
1132     struct object_surface* obj_surf_output_vebox;
1133
1134     proc_ctx->format_convert_flags = 0;
1135
1136     proc_ctx->width_input   = obj_surf_input->orig_width;
1137     proc_ctx->height_input  = obj_surf_input->orig_height;
1138     proc_ctx->width_output  = obj_surf_output->orig_width;
1139     proc_ctx->height_output = obj_surf_output->orig_height;
1140    
1141     /* only partial frame is not supported to be processed */
1142     /*
1143     assert(proc_ctx->width_input   == proc_ctx->pipeline_param->surface_region->width);
1144     assert(proc_ctx->height_input  == proc_ctx->pipeline_param->surface_region->height);
1145     assert(proc_ctx->width_output  == proc_ctx->pipeline_param->output_region->width);
1146     assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
1147     */
1148
1149     if(proc_ctx->width_output  != proc_ctx->width_input ||
1150        proc_ctx->height_output != proc_ctx->height_input){
1151         proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
1152     }
1153
1154      /* convert the following format to NV12 format */
1155      if(obj_surf_input->fourcc ==  VA_FOURCC_YV12 ||
1156         obj_surf_input->fourcc ==  VA_FOURCC_I420 ||
1157         obj_surf_input->fourcc ==  VA_FOURCC_IMC1 ||
1158         obj_surf_input->fourcc ==  VA_FOURCC_IMC3 ||
1159         obj_surf_input->fourcc ==  VA_FOURCC_RGBA){
1160
1161          proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
1162
1163       } else if(obj_surf_input->fourcc ==  VA_FOURCC_AYUV ||
1164                 obj_surf_input->fourcc ==  VA_FOURCC_YUY2 ||
1165                 obj_surf_input->fourcc ==  VA_FOURCC_NV12){
1166                 // nothing to do here
1167      } else {
1168            /* not support other format as input */ 
1169            assert(0);
1170      }
1171     
1172      if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
1173          if(proc_ctx->surface_input_vebox_object == NULL){
1174              va_status = i965_CreateSurfaces(ctx,
1175                                             proc_ctx->width_input,
1176                                             proc_ctx->height_input,
1177                                             VA_RT_FORMAT_YUV420,
1178                                             1,
1179                                             &(proc_ctx->surface_input_vebox));
1180              assert(va_status == VA_STATUS_SUCCESS);
1181              obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
1182              assert(obj_surf_input_vebox);
1183
1184              if (obj_surf_input_vebox) {
1185                  proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
1186                  i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1187              }
1188          }
1189        
1190          vpp_surface_convert(ctx, proc_ctx->surface_input_vebox_object, proc_ctx->surface_input_object);
1191       }
1192
1193       /* create one temporary NV12 surfaces for conversion*/
1194      if(obj_surf_output->fourcc ==  VA_FOURCC_YV12 ||
1195         obj_surf_output->fourcc ==  VA_FOURCC_I420 ||
1196         obj_surf_output->fourcc ==  VA_FOURCC_IMC1 ||
1197         obj_surf_output->fourcc ==  VA_FOURCC_IMC3 ||
1198         obj_surf_output->fourcc ==  VA_FOURCC_RGBA) {
1199
1200         proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
1201     } else if(obj_surf_output->fourcc ==  VA_FOURCC_AYUV ||
1202               obj_surf_output->fourcc ==  VA_FOURCC_YUY2 ||
1203               obj_surf_output->fourcc ==  VA_FOURCC_NV12){
1204               /* Nothing to do here */
1205      } else {
1206            /* not support other format as input */ 
1207            assert(0);
1208      }
1209   
1210      if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
1211         proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1212        if(proc_ctx->surface_output_vebox_object == NULL){
1213              va_status = i965_CreateSurfaces(ctx,
1214                                             proc_ctx->width_input,
1215                                             proc_ctx->height_input,
1216                                             VA_RT_FORMAT_YUV420,
1217                                             1,
1218                                             &(proc_ctx->surface_output_vebox));
1219              assert(va_status == VA_STATUS_SUCCESS);
1220              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
1221              assert(obj_surf_output_vebox);
1222
1223              if (obj_surf_output_vebox) {
1224                  proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
1225                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1226              }
1227        }
1228      }   
1229
1230      if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1231        if(proc_ctx->surface_output_scaled_object == NULL){
1232              va_status = i965_CreateSurfaces(ctx,
1233                                             proc_ctx->width_output,
1234                                             proc_ctx->height_output,
1235                                             VA_RT_FORMAT_YUV420,
1236                                             1,
1237                                             &(proc_ctx->surface_output_scaled));
1238              assert(va_status == VA_STATUS_SUCCESS);
1239              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
1240              assert(obj_surf_output_vebox);
1241
1242              if (obj_surf_output_vebox) {
1243                  proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
1244                  i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1245              }
1246        }
1247      } 
1248     
1249      return 0;
1250 }
1251
1252 int hsw_veb_post_format_convert(VADriverContextP ctx,
1253                            struct intel_vebox_context *proc_ctx)
1254 {
1255     struct object_surface *obj_surface = NULL;
1256     
1257     obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
1258
1259     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1260         /* copy the saved frame in the second call */
1261         vpp_surface_convert(ctx,proc_ctx->surface_output_object, obj_surface);
1262     } else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1263        !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1264         /* Output surface format is covered by vebox pipeline and 
1265          * processed picture is already store in output surface 
1266          * so nothing will be done here */
1267     } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1268                !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1269        /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1270         vpp_surface_convert(ctx,proc_ctx->surface_output_object, obj_surface);
1271
1272     } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1273        /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1274         assert(obj_surface->fourcc == VA_FOURCC_NV12);
1275      
1276         /* first step :surface scaling */
1277         vpp_surface_scaling(ctx,proc_ctx->surface_output_scaled_object, obj_surface);
1278
1279         /* second step: color format convert and copy to output */
1280         obj_surface = proc_ctx->surface_output_object;
1281
1282         if(obj_surface->fourcc ==  VA_FOURCC_NV12 ||
1283            obj_surface->fourcc ==  VA_FOURCC_YV12 ||
1284            obj_surface->fourcc ==  VA_FOURCC_I420 ||
1285            obj_surface->fourcc ==  VA_FOURCC_YUY2 ||
1286            obj_surface->fourcc ==  VA_FOURCC_IMC1 ||
1287            obj_surface->fourcc ==  VA_FOURCC_IMC3 ||
1288            obj_surface->fourcc ==  VA_FOURCC_RGBA) {
1289            vpp_surface_convert(ctx, proc_ctx->surface_output_object, proc_ctx->surface_output_scaled_object);
1290        }else {
1291            assert(0); 
1292        }
1293    }
1294
1295     return 0;
1296 }
1297
1298 VAStatus gen75_vebox_process_picture(VADriverContextP ctx,
1299                          struct intel_vebox_context *proc_ctx)
1300 {
1301     struct i965_driver_data *i965 = i965_driver_data(ctx);
1302  
1303     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
1304     VAProcFilterParameterBuffer* filter = NULL;
1305     struct object_buffer *obj_buf = NULL;
1306     unsigned int i;
1307
1308     for (i = 0; i < pipe->num_filters; i ++) {
1309          obj_buf = BUFFER(pipe->filters[i]);
1310          
1311          assert(obj_buf && obj_buf->buffer_store);
1312
1313          if (!obj_buf || !obj_buf->buffer_store)
1314              goto error;
1315
1316          filter = (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
1317             
1318          if (filter->type == VAProcFilterNoiseReduction) {
1319              proc_ctx->filters_mask |= VPP_DNDI_DN;
1320              proc_ctx->filter_dn = filter;
1321          } else if (filter->type == VAProcFilterDeinterlacing) {
1322              proc_ctx->filters_mask |= VPP_DNDI_DI;
1323              proc_ctx->filter_di = filter;
1324          } else if (filter->type == VAProcFilterColorBalance) {
1325              proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1326              proc_ctx->filter_iecp_amp = filter;
1327              proc_ctx->filter_iecp_amp_num_elements = obj_buf->num_elements;
1328          } else if (filter->type == VAProcFilterSkinToneEnhancement) {
1329              proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1330              proc_ctx->filter_iecp_std = filter;
1331          }
1332     }
1333
1334     hsw_veb_pre_format_convert(ctx, proc_ctx);
1335     hsw_veb_surface_reference(ctx, proc_ctx);
1336
1337     if (proc_ctx->frame_order == -1) {
1338         hsw_veb_resource_prepare(ctx, proc_ctx);
1339     }
1340
1341     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1342         assert(proc_ctx->frame_order == 1);
1343         /* directly copy the saved frame in the second call */
1344     } else {
1345         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1346         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1347         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE); 
1348         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE); 
1349         hsw_veb_state_table_setup(ctx, proc_ctx);
1350
1351         hsw_veb_state_command(ctx, proc_ctx);           
1352         hsw_veb_dndi_iecp_command(ctx, proc_ctx);
1353         intel_batchbuffer_end_atomic(proc_ctx->batch);
1354         intel_batchbuffer_flush(proc_ctx->batch);
1355     }
1356
1357     hsw_veb_post_format_convert(ctx, proc_ctx);
1358     // hsw_veb_surface_unreference(ctx, proc_ctx);
1359
1360     proc_ctx->frame_order = (proc_ctx->frame_order + 1) % 2;
1361      
1362     return VA_STATUS_SUCCESS;
1363
1364 error:
1365     return VA_STATUS_ERROR_INVALID_PARAMETER;
1366 }
1367
1368 void gen75_vebox_context_destroy(VADriverContextP ctx, 
1369                           struct intel_vebox_context *proc_ctx)
1370 {
1371     int i;
1372
1373     if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
1374        i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
1375        proc_ctx->surface_input_vebox = VA_INVALID_ID;
1376        proc_ctx->surface_input_vebox_object = NULL;
1377      }
1378
1379     if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
1380        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
1381        proc_ctx->surface_output_vebox = VA_INVALID_ID;
1382        proc_ctx->surface_output_vebox_object = NULL;
1383      }
1384
1385     if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
1386        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
1387        proc_ctx->surface_output_scaled = VA_INVALID_ID;
1388        proc_ctx->surface_output_scaled_object = NULL;
1389      }
1390
1391     for(i = 0; i < FRAME_STORE_SUM; i ++) {
1392         if (proc_ctx->frame_store[i].is_internal_surface == 1) {
1393             assert(proc_ctx->frame_store[i].surface_id != VA_INVALID_ID);
1394
1395             if (proc_ctx->frame_store[i].surface_id != VA_INVALID_ID)
1396                 i965_DestroySurfaces(ctx, &proc_ctx->frame_store[i].surface_id, 1);
1397         }
1398
1399         proc_ctx->frame_store[i].surface_id = VA_INVALID_ID;
1400         proc_ctx->frame_store[i].is_internal_surface = 0;
1401         proc_ctx->frame_store[i].obj_surface = NULL;
1402     }
1403
1404     /* dndi state table  */
1405     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
1406     proc_ctx->dndi_state_table.bo = NULL;
1407
1408     /* iecp state table  */
1409     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
1410     proc_ctx->dndi_state_table.bo = NULL;
1411  
1412     /* gamut statu table */
1413     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
1414     proc_ctx->gamut_state_table.bo = NULL;
1415
1416     /* vertex state table  */
1417     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
1418     proc_ctx->vertex_state_table.bo = NULL;
1419
1420     intel_batchbuffer_free(proc_ctx->batch);
1421
1422     free(proc_ctx);
1423 }
1424
1425 struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
1426 {
1427     struct intel_driver_data *intel = intel_driver_data(ctx);
1428     struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
1429     int i;
1430
1431     proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
1432     memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM);
1433
1434     for (i = 0; i < FRAME_STORE_SUM; i ++) {
1435         proc_context->frame_store[i].surface_id = VA_INVALID_ID;
1436         proc_context->frame_store[i].is_internal_surface = 0;
1437         proc_context->frame_store[i].obj_surface = NULL;
1438     }
1439   
1440     proc_context->filters_mask          = 0;
1441     proc_context->frame_order           = -1; /* the first frame */
1442     proc_context->surface_output_object = NULL;
1443     proc_context->surface_input_object  = NULL;
1444     proc_context->surface_input_vebox   = VA_INVALID_ID;
1445     proc_context->surface_input_vebox_object = NULL;
1446     proc_context->surface_output_vebox  = VA_INVALID_ID;
1447     proc_context->surface_output_vebox_object = NULL;
1448     proc_context->surface_output_scaled = VA_INVALID_ID;
1449     proc_context->surface_output_scaled_object = NULL;
1450     proc_context->filters_mask          = 0;
1451     proc_context->format_convert_flags  = 0;
1452
1453     return proc_context;
1454 }
1455
1456 void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1457 {
1458     struct intel_batchbuffer *batch = proc_ctx->batch;
1459     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
1460     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
1461     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
1462     unsigned int is_first_frame  = !!((proc_ctx->frame_order == -1) &&
1463                                       (is_di_enabled ||
1464                                        is_dn_enabled));
1465     unsigned int di_output_frames_flag = 2; /* Output Current Frame Only */
1466
1467     if(proc_ctx->fourcc_input != proc_ctx->fourcc_output ||
1468        (is_dn_enabled == 0 && is_di_enabled == 0)){
1469        is_iecp_enabled = 1;
1470     }
1471
1472     if (is_di_enabled) {
1473         VAProcFilterParameterBufferDeinterlacing *di_param =
1474             (VAProcFilterParameterBufferDeinterlacing *)proc_ctx->filter_di;
1475
1476         assert(di_param);
1477         
1478         if (di_param->algorithm == VAProcDeinterlacingBob)
1479             is_first_frame = 1;
1480
1481         if ((di_param->algorithm == VAProcDeinterlacingMotionAdaptive ||
1482             di_param->algorithm == VAProcDeinterlacingMotionCompensated) &&
1483             proc_ctx->frame_order != -1)
1484             di_output_frames_flag = 0; /* Output both Current Frame and Previous Frame */
1485     }
1486
1487     BEGIN_VEB_BATCH(batch, 0xc);
1488     OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
1489     OUT_VEB_BATCH(batch,
1490                   0 << 25 |       // state surface control bits
1491                   0 << 23 |       // reserved.
1492                   0 << 22 |       // gamut expansion position
1493                   0 << 15 |       // reserved.
1494                   0 << 14 |       // single slice vebox enable
1495                   0 << 13 |       // hot pixel filter enable
1496                   0 << 12 |       // alpha plane enable
1497                   0 << 11 |       // vignette enable
1498                   0 << 10 |       // demosaic enable
1499                   di_output_frames_flag << 8  |       // DI output frame
1500                   1 << 7  |       // 444->422 downsample method
1501                   1 << 6  |       // 422->420 downsample method
1502                   is_first_frame  << 5  |   // DN/DI first frame
1503                   is_di_enabled   << 4  |             // DI enable
1504                   is_dn_enabled   << 3  |             // DN enable
1505                   is_iecp_enabled << 2  |             // global IECP enabled
1506                   0 << 1  |       // ColorGamutCompressionEnable
1507                   0 ) ;           // ColorGamutExpansionEnable.
1508
1509     OUT_RELOC(batch,
1510               proc_ctx->dndi_state_table.bo,
1511               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1512
1513     OUT_VEB_BATCH(batch, 0);
1514
1515     OUT_RELOC(batch,
1516               proc_ctx->iecp_state_table.bo,
1517               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1518
1519     OUT_VEB_BATCH(batch, 0);
1520
1521     OUT_RELOC(batch,
1522               proc_ctx->gamut_state_table.bo,
1523               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1524
1525     OUT_VEB_BATCH(batch, 0);
1526
1527     OUT_RELOC(batch,
1528               proc_ctx->vertex_state_table.bo,
1529               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1530
1531     OUT_VEB_BATCH(batch, 0);
1532
1533     OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
1534     OUT_VEB_BATCH(batch, 0);
1535
1536     ADVANCE_VEB_BATCH(batch);
1537 }
1538
1539 void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1540 {
1541     struct intel_batchbuffer *batch = proc_ctx->batch;
1542     unsigned char frame_ctrl_bits = 0;
1543     unsigned int startingX = 0;
1544     unsigned int endingX = (proc_ctx->width_input + 63 ) / 64 * 64;
1545
1546     BEGIN_VEB_BATCH(batch, 0x14);
1547     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
1548     OUT_VEB_BATCH(batch,
1549                   startingX << 16 |
1550                   endingX -1);//DWord 1
1551
1552     OUT_RELOC(batch,
1553               proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1554               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
1555     OUT_VEB_BATCH(batch,0);//DWord 3
1556
1557     OUT_RELOC(batch,
1558               proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1559               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
1560     OUT_VEB_BATCH(batch,0);//DWord 5
1561
1562     OUT_RELOC(batch,
1563               proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1564               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
1565     OUT_VEB_BATCH(batch,0);//DWord 7
1566
1567     OUT_RELOC(batch,
1568               proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1569               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
1570     OUT_VEB_BATCH(batch,0);//DWord 9
1571
1572     OUT_RELOC(batch,
1573               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1574               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
1575     OUT_VEB_BATCH(batch,0);//DWord 11
1576
1577     OUT_RELOC(batch,
1578               proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1579               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
1580     OUT_VEB_BATCH(batch,0);//DWord 13
1581
1582     OUT_RELOC(batch,
1583               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1584               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
1585     OUT_VEB_BATCH(batch,0);//DWord 15
1586
1587     OUT_RELOC(batch,
1588               proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1589               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
1590     OUT_VEB_BATCH(batch,0);//DWord 17
1591
1592     OUT_VEB_BATCH(batch,0);//DWord 18
1593     OUT_VEB_BATCH(batch,0);//DWord 19
1594
1595     ADVANCE_VEB_BATCH(batch);
1596 }
1597
1598 VAStatus gen8_vebox_process_picture(VADriverContextP ctx,
1599                          struct intel_vebox_context *proc_ctx)
1600 {
1601     struct i965_driver_data *i965 = i965_driver_data(ctx);
1602  
1603     VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
1604     VAProcFilterParameterBuffer* filter = NULL;
1605     struct object_buffer *obj_buf = NULL;
1606     unsigned int i;
1607
1608     for (i = 0; i < pipe->num_filters; i ++) {
1609          obj_buf = BUFFER(pipe->filters[i]);
1610          
1611          assert(obj_buf && obj_buf->buffer_store);
1612
1613          if (!obj_buf || !obj_buf->buffer_store)
1614              goto error;
1615
1616          filter = (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
1617             
1618          if (filter->type == VAProcFilterNoiseReduction) {
1619              proc_ctx->filters_mask |= VPP_DNDI_DN;
1620              proc_ctx->filter_dn = filter;
1621          } else if (filter->type == VAProcFilterDeinterlacing) {
1622              proc_ctx->filters_mask |= VPP_DNDI_DI;
1623              proc_ctx->filter_di = filter;
1624          } else if (filter->type == VAProcFilterColorBalance) {
1625              proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1626              proc_ctx->filter_iecp_amp = filter;
1627              proc_ctx->filter_iecp_amp_num_elements = obj_buf->num_elements;
1628          } else if (filter->type == VAProcFilterSkinToneEnhancement) {
1629              proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1630              proc_ctx->filter_iecp_std = filter;
1631          }
1632     }
1633
1634     hsw_veb_pre_format_convert(ctx, proc_ctx);
1635     hsw_veb_surface_reference(ctx, proc_ctx);
1636
1637     if (proc_ctx->frame_order == -1) {
1638         hsw_veb_resource_prepare(ctx, proc_ctx);
1639     }
1640
1641     if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1642         assert(proc_ctx->frame_order == 1);
1643         /* directly copy the saved frame in the second call */
1644     } else {
1645         intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1646         intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1647         hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE); 
1648         hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE); 
1649         hsw_veb_state_table_setup(ctx, proc_ctx);
1650
1651         bdw_veb_state_command(ctx, proc_ctx);           
1652         bdw_veb_dndi_iecp_command(ctx, proc_ctx);
1653         intel_batchbuffer_end_atomic(proc_ctx->batch);
1654         intel_batchbuffer_flush(proc_ctx->batch);
1655     }
1656
1657     hsw_veb_post_format_convert(ctx, proc_ctx);
1658     // hsw_veb_surface_unreference(ctx, proc_ctx);
1659
1660     proc_ctx->frame_order = (proc_ctx->frame_order + 1) % 2;
1661      
1662     return VA_STATUS_SUCCESS;
1663
1664 error:
1665     return VA_STATUS_ERROR_INVALID_PARAMETER;
1666 }
1667