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