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