MPEG-2 encoding path
[profile/ivi/vaapi-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  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <math.h>
33
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36 #include "i965_defines.h"
37 #include "i965_structs.h"
38 #include "gen75_vpp_vebox.h"
39 #include "intel_media.h"
40
41 #define PI  3.1415926
42
43 extern VAStatus
44 i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
45
46 extern VAStatus
47 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
48
49 extern VAStatus
50 i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
51
52 extern VAStatus
53 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
54
55
56 VAStatus vpp_surface_copy(VADriverContextP ctx, VASurfaceID dstSurfaceID, VASurfaceID srcSurfaceID)
57 {
58     VAStatus va_status = VA_STATUS_SUCCESS;
59     VAImage srcImage, dstImage;
60     void *pBufferSrc, *pBufferDst;
61     unsigned char *ySrc, *yDst;
62
63     va_status = vpp_surface_convert(ctx, dstSurfaceID, srcSurfaceID);
64     if(va_status == VA_STATUS_SUCCESS){
65        return va_status;
66     }
67
68     va_status = i965_DeriveImage(ctx, srcSurfaceID, &srcImage);
69     assert(va_status == VA_STATUS_SUCCESS);
70
71     va_status = i965_DeriveImage(ctx, dstSurfaceID, &dstImage);
72     assert(va_status == VA_STATUS_SUCCESS);
73
74     if(srcImage.width  != dstImage.width  ||
75        srcImage.height != dstImage.height ||
76        srcImage.format.fourcc != dstImage.format.fourcc) {
77         return VA_STATUS_ERROR_UNIMPLEMENTED;
78     }
79
80     va_status = i965_MapBuffer(ctx, srcImage.buf, &pBufferSrc);
81     assert(va_status == VA_STATUS_SUCCESS);
82
83     va_status = i965_MapBuffer(ctx, dstImage.buf, &pBufferDst);
84     assert(va_status == VA_STATUS_SUCCESS);
85
86     ySrc = (unsigned char*)(pBufferSrc + srcImage.offsets[0]);
87     yDst = (unsigned char*)(pBufferDst + dstImage.offsets[0]);
88   
89     memcpy(pBufferDst, pBufferSrc, dstImage.data_size);
90
91     i965_UnmapBuffer(ctx, srcImage.buf);
92     i965_UnmapBuffer(ctx, dstImage.buf);
93     i965_DestroyImage(ctx, srcImage.image_id);
94     i965_DestroyImage(ctx, dstImage.image_id);
95
96     return va_status;;
97 }
98
99 VAStatus vpp_surface_convert(VADriverContextP ctx, VASurfaceID dstSurfaceID, VASurfaceID srcSurfaceID)
100 {
101     VAStatus va_status = VA_STATUS_SUCCESS;
102     struct i965_driver_data *i965 = i965_driver_data(ctx);
103     struct object_surface* src_obj_surf = SURFACE(srcSurfaceID);
104     struct object_surface* dst_obj_surf = SURFACE(dstSurfaceID);
105
106     assert(src_obj_surf->orig_width  == dst_obj_surf->orig_width);
107     assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
108
109     VARectangle src_rect, dst_rect;
110     src_rect.x = dst_rect.x = 0;
111     src_rect.y = dst_rect.y = 0; 
112     src_rect.width  = dst_rect.width  = src_obj_surf->orig_width; 
113     src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
114
115     struct i965_surface src_surface, dst_surface;
116     src_surface.id    = srcSurfaceID;
117     src_surface.type  = I965_SURFACE_TYPE_SURFACE;
118     src_surface.flags = I965_SURFACE_FLAG_FRAME;
119
120     dst_surface.id    = dstSurfaceID;
121     dst_surface.type  = I965_SURFACE_TYPE_SURFACE;
122     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
123
124     va_status = i965_image_processing(ctx,
125                                      &src_surface,
126                                      &src_rect,
127                                      &dst_surface,
128                                      &dst_rect);
129     return va_status;
130 }
131
132 VAStatus vpp_surface_scaling(VADriverContextP ctx, VASurfaceID dstSurfaceID, VASurfaceID srcSurfaceID)
133 {
134     VAStatus va_status = VA_STATUS_SUCCESS;
135     int flags = I965_PP_FLAG_AVS;
136     struct i965_driver_data *i965 = i965_driver_data(ctx);
137     struct object_surface* src_obj_surf = SURFACE(srcSurfaceID);
138     struct object_surface* dst_obj_surf = SURFACE(dstSurfaceID);
139
140     assert(src_obj_surf->fourcc == VA_FOURCC('N','V','1','2'));
141     assert(dst_obj_surf->fourcc == VA_FOURCC('N','V','1','2'));
142
143     VARectangle src_rect, dst_rect;
144     src_rect.x = 0;
145     src_rect.y = 0; 
146     src_rect.width  = src_obj_surf->orig_width; 
147     src_rect.height = src_obj_surf->orig_height;
148
149     dst_rect.x = 0;
150     dst_rect.y = 0; 
151     dst_rect.width  = dst_obj_surf->orig_width; 
152     dst_rect.height = dst_obj_surf->orig_height;
153
154     va_status = i965_scaling_processing(ctx,
155                                        srcSurfaceID,
156                                        &src_rect,
157                                        dstSurfaceID,
158                                        &dst_rect,
159                                        flags);
160      
161     return va_status;
162 }
163
164 void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
165 {
166     unsigned int* p_table ;
167     /*
168     VAProcFilterParameterBufferDeinterlacing *di_param =
169             (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
170
171     VAProcFilterParameterBuffer * dn_param =
172             (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
173     */
174     p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
175
176     *p_table ++ = 0;               // reserved  . w0
177     *p_table ++ = ( 0   << 24 |    // denoise STAD threshold . w1
178                     128 << 16 |    // dnmh_history_max
179                     0   << 12 |    // reserved
180                     8   << 8  |    // dnmh_delta[3:0]
181                     0 );           // denoise ASD threshold
182
183     *p_table ++ = ( 0  << 30 |    // reserved . w2
184                     16 << 24 |    // temporal diff th
185                     0  << 22 |    // reserved.
186                     8  << 16 |    // low temporal diff th
187                     0  << 13 |    // STMM C2
188                     0  << 8  |    // denoise moving pixel th
189                     64 );         // denoise th for sum of complexity measure
190
191     *p_table ++ = ( 0 << 30  |   // reserved . w3
192                     4 << 24  |   // good neighbor th[5:0]
193                     9 << 20  |   // CAT slope minus 1
194                     5 << 16  |   // SAD Tight in
195                     0 << 14  |   // smooth mv th
196                     0 << 12  |   // reserved
197                     1 << 8   |   // bne_edge_th[3:0]
198                     15 );        // block noise estimate noise th
199
200     *p_table ++ = ( 0  << 31  |  // STMM blending constant select. w4
201                     64 << 24  |  // STMM trc1
202                     0  << 16  |  // STMM trc2
203                     0  << 14  |  // reserved
204                     2  << 8   |  // VECM_mul
205                     128 );       // maximum STMM
206
207     *p_table ++ = ( 0  << 24  |  // minumum STMM  . W5
208                     0  << 22  |  // STMM shift down
209                     0  << 20  |  // STMM shift up
210                     7  << 16  |  // STMM output shift
211                     128 << 8  |  // SDI threshold
212                     8 );         // SDI delta
213
214     *p_table ++ = ( 0 << 24  |   // SDI fallback mode 1 T1 constant . W6
215                     0 << 16  |   // SDI fallback mode 1 T2 constant
216                     0 << 8   |   // SDI fallback mode 2 constant(angle2x1)
217                     0 );         // FMD temporal difference threshold
218
219     *p_table ++ = ( 32 << 24  |  // FMD #1 vertical difference th . w7
220                     32 << 16  |  // FMD #2 vertical difference th
221                     1  << 14  |  // CAT th1
222                     32 << 8   |  // FMD tear threshold
223                     0  << 7   |  // MCDI Enable, use motion compensated deinterlace algorithm
224                     0  << 6   |  // progressive DN
225                     0  << 4   |  // reserved
226                     0  << 3   |  // DN/DI Top First
227                     0 );         // reserved
228
229     *p_table ++ = ( 0  << 29  |  // reserved . W8
230                     0  << 23  |  // dnmh_history_init[5:0]
231                     10 << 19  |  // neighborPixel th
232                     0  << 18  |  // reserved
233                     0  << 16  |  // FMD for 2nd field of previous frame
234                     25 << 10  |  // MC pixel consistency th
235                     0  << 8   |  // FMD for 1st field for current frame
236                     10 << 4   |  // SAD THB
237                     5 );         // SAD THA
238
239     *p_table ++ = ( 0 << 24  |  // reserved
240                     0 << 16  |  // chr_dnmh_stad_th
241                     0 << 13  |  // reserved
242                     0 << 12  |  // chrome denoise enable
243                     0 << 6   |  // chr temp diff th
244                     0 );        // chr temp diff low
245
246 }
247
248 void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
249 {
250     unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
251     //VAProcFilterParameterBuffer * std_param =
252     //        (VAProcFilterParameterBuffer *) proc_ctx->filter_std;
253
254     if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){ 
255         memset(p_table, 0, 29 * 4);
256     }else{
257         *p_table ++ = 0x9a6e39f0;
258         *p_table ++ = 0x400c0000;
259         *p_table ++ = 0x00001180;
260         *p_table ++ = 0xfe2f2e00;
261         *p_table ++ = 0x000000ff;
262
263         *p_table ++ = 0x00140000;
264         *p_table ++ = 0xd82e0000;
265         *p_table ++ = 0x8285ecec;
266         *p_table ++ = 0x00008282;
267         *p_table ++ = 0x00000000;
268
269         *p_table ++ = 0x02117000;
270         *p_table ++ = 0xa38fec96;
271         *p_table ++ = 0x0000c8c8;
272         *p_table ++ = 0x00000000;
273         *p_table ++ = 0x01478000;
274  
275         *p_table ++ = 0x0007c306;
276         *p_table ++ = 0x00000000;
277         *p_table ++ = 0x00000000;
278         *p_table ++ = 0x1c1bd000;
279         *p_table ++ = 0x00000000;
280
281         *p_table ++ = 0x00000000;
282         *p_table ++ = 0x00000000;
283         *p_table ++ = 0x0007cf80;
284         *p_table ++ = 0x00000000;
285         *p_table ++ = 0x00000000;
286
287         *p_table ++ = 0x1c080000;
288         *p_table ++ = 0x00000000;
289         *p_table ++ = 0x00000000;
290         *p_table ++ = 0x00000000;
291     }
292 }
293
294 void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
295 {
296    unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
297
298     if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){ 
299         memset(p_table, 0, 13 * 4);
300     }else{
301         *p_table ++ = 0x00000068;
302         *p_table ++ = 0x4c382410;
303         *p_table ++ = 0x9c887460;
304         *p_table ++ = 0xebd8c4b0;
305         *p_table ++ = 0x604c3824;
306
307         *p_table ++ = 0xb09c8874;
308         *p_table ++ = 0x0000d8c4;
309         *p_table ++ = 0x00000000;
310         *p_table ++ = 0x00000000;
311         *p_table ++ = 0x00000000;
312
313         *p_table ++ = 0x00000000;
314         *p_table ++ = 0x00000000;
315         *p_table ++ = 0x00000000;
316    }
317 }
318
319 void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
320 {
321     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
322
323 //    VAProcFilterParameterBuffer * tcc_param =
324 //            (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
325
326    if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){ 
327         memset(p_table, 0, 11 * 4);
328     }else{
329         *p_table ++ = 0x00000000;
330         *p_table ++ = 0x00000000;
331         *p_table ++ = 0x1e34cc91;
332         *p_table ++ = 0x3e3cce91;
333         *p_table ++ = 0x02e80195;
334
335         *p_table ++ = 0x0197046b;
336         *p_table ++ = 0x01790174;
337         *p_table ++ = 0x00000000;
338         *p_table ++ = 0x00000000;
339         *p_table ++ = 0x03030000;
340
341         *p_table ++ = 0x009201c0;
342    }
343 }
344
345 void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
346 {
347     unsigned int contrast = 0x80;  //default 
348     int brightness = 0x00;         //default
349     int cos_c_s    = 256 ;         //default
350     int sin_c_s    = 0;            //default 
351     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
352
353     if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
354         memset(p_table, 0, 2 * 4);
355     }else {
356         float  src_saturation = 1.0;
357         float  src_hue = 0.0;
358         float  src_contrast = 1.0;
359         float  src_brightness = 0.0;
360         float  tmp_value = 0.0;
361
362         VAProcFilterParameterBufferColorBalance * amp_param =
363         (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
364         VAProcColorBalanceType attrib = amp_param->attrib;
365
366         if(attrib == VAProcColorBalanceHue) {
367            src_hue = amp_param->value;         //(-180.0, 180.0)
368         }else if(attrib == VAProcColorBalanceSaturation) {
369            src_saturation = amp_param->value; //(0.0, 10.0)
370         }else if(attrib == VAProcColorBalanceBrightness) {
371            src_brightness = amp_param->value; // (-100.0, 100.0)
372            brightness = intel_format_convert(src_brightness, 7, 4, 1);
373         }else if(attrib == VAProcColorBalanceContrast) {
374            src_contrast = amp_param->value;  //  (0.0, 10.0)
375            contrast = intel_format_convert(src_contrast, 4, 7, 0);
376         }
377
378         tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
379         cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
380         
381         tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
382         sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
383      
384         *p_table ++ = ( 0 << 28 |         //reserved
385                         contrast << 17 |  //contrast value (U4.7 format)
386                         0 << 13 |         //reserved
387                         brightness << 1|  // S7.4 format
388                         1);
389
390         *p_table ++ = ( cos_c_s << 16 |  // cos(h) * contrast * saturation
391                         sin_c_s);        // sin(h) * contrast * saturation
392                  
393     }
394 }
395
396
397 void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
398 {
399     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
400     float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
401     float v_coef[3]    = {0.0, 0.0, 0.0};
402     float u_coef[3]    = {0.0, 0.0, 0.0};
403     int   is_transform_enabled = 0;
404
405     if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
406         memset(p_table, 0, 8 * 4);
407         return;
408     }
409
410     VAProcColorStandardType   in_color_std  = proc_ctx->pipeline_param->surface_color_standard;
411     VAProcColorStandardType   out_color_std = proc_ctx->pipeline_param->output_color_standard;
412     assert(in_color_std == out_color_std);  
413     
414     if(proc_ctx->fourcc_input == VA_FOURCC('R','G','B','A') &&
415        (proc_ctx->fourcc_output == VA_FOURCC('N','V','1','2') ||
416         proc_ctx->fourcc_output == VA_FOURCC('Y','V','1','2') ||
417         proc_ctx->fourcc_output == VA_FOURCC('Y','V','Y','2') ||
418         proc_ctx->fourcc_output == VA_FOURCC('A','Y','U','V'))) {
419
420          tran_coef[0] = 0.257;
421          tran_coef[1] = 0.504;
422          tran_coef[2] = 0.098;
423          tran_coef[3] = -0.148;
424          tran_coef[4] = -0.291;
425          tran_coef[5] = 0.439;
426          tran_coef[6] = 0.439;
427          tran_coef[7] = -0.368;
428          tran_coef[8] = -0.071; 
429
430          u_coef[0] = 16 * 4;
431          u_coef[1] = 128 * 4;
432          u_coef[2] = 128 * 4;
433  
434          is_transform_enabled = 1; 
435     }else if((proc_ctx->fourcc_input  == VA_FOURCC('N','V','1','2') || 
436               proc_ctx->fourcc_input  == VA_FOURCC('Y','V','1','2') || 
437               proc_ctx->fourcc_input  == VA_FOURCC('Y','U','Y','2') ||
438               proc_ctx->fourcc_input  == VA_FOURCC('A','Y','U','V'))&&
439               proc_ctx->fourcc_output == VA_FOURCC('R','G','B','A')) {
440
441          tran_coef[0] = 1.164;
442          tran_coef[1] = 0.000;
443          tran_coef[2] = 1.569;
444          tran_coef[3] = 1.164;
445          tran_coef[4] = -0.813;
446          tran_coef[5] = -0.392;
447          tran_coef[6] = 1.164;
448          tran_coef[7] = 2.017;
449          tran_coef[8] = 0.000; 
450
451          v_coef[0] = -16 * 4;
452          v_coef[1] = -128 * 4;
453          v_coef[2] = -128 * 4;
454
455         is_transform_enabled = 1; 
456     }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
457          //enable when input and output format are different.
458          is_transform_enabled = 1;
459     }
460
461     if(is_transform_enabled == 0){
462         memset(p_table, 0, 8 * 4);
463     }else{
464         *p_table ++ = ( 0 << 29 | //reserved
465                         intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
466                         intel_format_convert(tran_coef[0], 2, 10, 1) << 3 |  //c0, s2.10 format
467                         0 << 2 | //reserved
468                         0 << 1 | // yuv_channel swap
469                         is_transform_enabled);                
470
471         *p_table ++ = ( 0 << 26 | //reserved
472                         intel_format_convert(tran_coef[3], 2, 10, 1) << 13 | 
473                         intel_format_convert(tran_coef[2], 2, 10, 1));
474     
475         *p_table ++ = ( 0 << 26 | //reserved
476                         intel_format_convert(tran_coef[5], 2, 10, 1) << 13 | 
477                         intel_format_convert(tran_coef[4], 2, 10, 1));
478
479         *p_table ++ = ( 0 << 26 | //reserved
480                         intel_format_convert(tran_coef[7], 2, 10, 1) << 13 | 
481                         intel_format_convert(tran_coef[6], 2, 10, 1));
482
483         *p_table ++ = ( 0 << 13 | //reserved
484                         intel_format_convert(tran_coef[8], 2, 10, 1));
485
486         *p_table ++ = ( 0 << 22 | //reserved
487                         intel_format_convert(u_coef[0], 10, 0, 1) << 11 | 
488                         intel_format_convert(v_coef[0], 10, 0, 1));
489
490         *p_table ++ = ( 0 << 22 | //reserved
491                         intel_format_convert(u_coef[1], 10, 0, 1) << 11 | 
492                         intel_format_convert(v_coef[1], 10, 0, 1));
493
494         *p_table ++ = ( 0 << 22 | //reserved
495                         intel_format_convert(u_coef[2], 10, 0, 1) << 11 | 
496                         intel_format_convert(v_coef[2], 10, 0, 1));
497     }
498 }
499
500 void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
501 {
502     unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
503    // VAProcFilterParameterBuffer * tcc_param =
504    //         (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
505
506     if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){ 
507         memset(p_table, 0, 3 * 4);
508     }else{
509         *p_table ++ = 0x00000000;
510         *p_table ++ = 0x00030000;
511         *p_table ++ = 0x00030000;
512    }
513 }
514
515 void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
516 {
517     if(proc_ctx->filters_mask & 0x000000ff) {
518         dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
519         dri_bo_map(dndi_bo, 1);
520         proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
521
522         hsw_veb_dndi_table(ctx, proc_ctx);
523
524         dri_bo_unmap(dndi_bo);
525     }
526
527     if(proc_ctx->filters_mask & 0x0000ff00 ||
528        proc_ctx->fourcc_input != proc_ctx->fourcc_output) {
529         dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
530         dri_bo_map(iecp_bo, 1);
531         proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
532
533         hsw_veb_iecp_std_table(ctx, proc_ctx);
534         hsw_veb_iecp_ace_table(ctx, proc_ctx);
535         hsw_veb_iecp_tcc_table(ctx, proc_ctx);
536         hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
537         hsw_veb_iecp_csc_table(ctx, proc_ctx);
538         hsw_veb_iecp_aoi_table(ctx, proc_ctx);
539    
540         dri_bo_unmap(iecp_bo);
541     }
542 }
543
544 void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
545 {
546     struct intel_batchbuffer *batch = proc_ctx->batch;
547     unsigned int is_dn_enabled   = (proc_ctx->filters_mask & 0x01)? 1: 0;
548     unsigned int is_di_enabled   = (proc_ctx->filters_mask & 0x02)? 1: 0;
549     unsigned int is_iecp_enabled = (proc_ctx->filters_mask & 0xff00)?1:0;
550
551     if(proc_ctx->fourcc_input != proc_ctx->fourcc_output ||
552        (is_dn_enabled == 0 && is_di_enabled == 0)){
553        is_iecp_enabled = 1;
554     }
555
556     BEGIN_VEB_BATCH(batch, 6);
557     OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
558     OUT_VEB_BATCH(batch,
559                   0 << 26 |       // state surface control bits
560                   0 << 11 |       // reserved.
561                   0 << 10 |       // pipe sync disable
562                   2 << 8  |       // DI output frame
563                   0 << 7  |       // 444->422 downsample method
564                   0 << 6  |       // 422->420 downsample method
565                   !!(proc_ctx->is_first_frame && (is_di_enabled || is_dn_enabled)) << 5  |   // DN/DI first frame
566                   is_di_enabled   << 4  |             // DI enable
567                   is_dn_enabled   << 3  |             // DN enable
568                   is_iecp_enabled << 2  |             // global IECP enabled
569                   0 << 1  |       // ColorGamutCompressionEnable
570                   0 ) ;           // ColorGamutExpansionEnable.
571
572     OUT_RELOC(batch, 
573               proc_ctx->dndi_state_table.bo,
574               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
575
576     OUT_RELOC(batch,
577               proc_ctx->iecp_state_table.bo, 
578               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
579
580     OUT_RELOC(batch,
581               proc_ctx->gamut_state_table.bo, 
582               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
583
584     OUT_RELOC(batch,
585               proc_ctx->vertex_state_table.bo, 
586               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
587
588     ADVANCE_VEB_BATCH(batch);
589 }
590
591 void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
592 {
593     struct  i965_driver_data *i965 = i965_driver_data(ctx);
594     struct intel_batchbuffer *batch = proc_ctx->batch;
595     unsigned int u_offset_y = 0, v_offset_y = 0;
596     unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
597     unsigned int surface_format = PLANAR_420_8;
598     struct object_surface* obj_surf = NULL;
599     unsigned int surface_pitch = 0;
600     unsigned int half_pitch_chroma = 0;
601
602     if(is_output){   
603          obj_surf = SURFACE(proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id);
604     }else {
605          obj_surf = SURFACE(proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id);
606     }
607
608     assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
609            obj_surf->fourcc == VA_FOURCC_YUY2 ||
610            obj_surf->fourcc == VA_FOURCC_AYUV ||
611            obj_surf->fourcc == VA_FOURCC_RGBA);
612
613     if (obj_surf->fourcc == VA_FOURCC_NV12) {
614         surface_format = PLANAR_420_8;
615         surface_pitch = obj_surf->width; 
616         is_uv_interleaved = 1;
617         half_pitch_chroma = 0;
618     } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
619         surface_format = YCRCB_NORMAL;
620         surface_pitch = obj_surf->width * 2; 
621         is_uv_interleaved = 0;
622         half_pitch_chroma = 0;
623     } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
624         surface_format = PACKED_444A_8;
625         surface_pitch = obj_surf->width * 4; 
626         is_uv_interleaved = 0;
627         half_pitch_chroma = 0;
628     } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
629         surface_format = R8G8B8A8_UNORM_SRGB;
630         surface_pitch = obj_surf->width * 4; 
631         is_uv_interleaved = 0;
632         half_pitch_chroma = 0;
633     }
634
635     u_offset_y = obj_surf->y_cb_offset;
636     v_offset_y = obj_surf->y_cr_offset;
637      
638     dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
639
640     BEGIN_VEB_BATCH(batch, 6);
641     OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
642     OUT_VEB_BATCH(batch,
643                   0 << 1 |         // reserved
644                   is_output);      // surface indentification.
645
646     OUT_VEB_BATCH(batch,
647                   (proc_ctx->height_input - 1) << 18 |  // height . w3
648                   (proc_ctx->width_input) << 4  |       // width
649                   0);                                   // reserve
650
651     OUT_VEB_BATCH(batch,
652                   surface_format      << 28  |  // surface format, YCbCr420. w4
653                   is_uv_interleaved   << 27  |  // interleave chrome , two seperate palar
654                   0                   << 20  |  // reserved
655                   (surface_pitch - 1) << 3   |  // surface pitch, 64 align
656                   half_pitch_chroma   << 2   |  // half pitch for chrome
657                   !!tiling            << 1   |  // tiled surface, linear surface used
658                   (tiling == I915_TILING_Y));   // tiled walk, ignored when liner surface
659
660     OUT_VEB_BATCH(batch,
661                   0 << 29  |     // reserved . w5
662                   0 << 16  |     // X offset for V(Cb)
663                   0 << 15  |     // reserved
664                   u_offset_y);   // Y offset for V(Cb)
665
666     OUT_VEB_BATCH(batch,
667                   0 << 29  |     // reserved . w6
668                   0 << 16  |     // X offset for V(Cr)
669                   0 << 15  |     // reserved
670                   v_offset_y );  // Y offset for V(Cr)
671
672     ADVANCE_VEB_BATCH(batch);
673 }
674
675 void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
676 {
677     struct intel_batchbuffer *batch = proc_ctx->batch;
678     unsigned char frame_ctrl_bits = 0;
679     unsigned int startingX = 0;
680     unsigned int endingX = proc_ctx->width_input;
681     VEBFrameStore tempFrame;
682
683     /* s1:update the previous and current input */
684 /*    tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
685     proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
686     proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
687
688     if(proc_ctx->surface_input_vebox != -1){
689         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
690                      proc_ctx->surface_input_vebox);
691     } else {
692         vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
693                      proc_ctx->surface_input);
694     }
695 */
696     /*s2: update the STMM input and output */
697 /*    tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
698     proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
699     proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
700 */      
701     /*s3:set reloc buffer address */
702     BEGIN_VEB_BATCH(batch, 10);
703     OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
704     OUT_VEB_BATCH(batch,
705                   startingX << 16 |
706                   endingX);
707     OUT_RELOC(batch,
708               proc_ctx->frame_store[FRAME_IN_CURRENT].bo,
709               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
710     OUT_RELOC(batch,
711               proc_ctx->frame_store[FRAME_IN_PREVIOUS].bo,
712               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
713     OUT_RELOC(batch,
714               proc_ctx->frame_store[FRAME_IN_STMM].bo,
715               I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
716     OUT_RELOC(batch,
717               proc_ctx->frame_store[FRAME_OUT_STMM].bo,
718               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
719     OUT_RELOC(batch,
720               proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo,
721               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
722     OUT_RELOC(batch,
723               proc_ctx->frame_store[FRAME_OUT_CURRENT].bo,
724               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
725     OUT_RELOC(batch,
726               proc_ctx->frame_store[FRAME_OUT_PREVIOUS].bo,
727               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
728     OUT_RELOC(batch,
729               proc_ctx->frame_store[FRAME_OUT_STATISTIC].bo,
730               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
731
732     ADVANCE_VEB_BATCH(batch);
733 }
734
735 void hsw_veb_resource_prepare(VADriverContextP ctx,
736                               struct intel_vebox_context *proc_ctx)
737 {
738     VAStatus va_status;
739     dri_bo *bo;
740     struct i965_driver_data *i965 = i965_driver_data(ctx);
741     unsigned int input_fourcc, output_fourcc;
742     unsigned int input_sampling, output_sampling;
743     unsigned int input_tiling, output_tiling;
744     VAGenericID vebox_in_id, vebox_out_id;
745     unsigned int i, swizzle;
746
747     if(proc_ctx->surface_input_vebox != -1){
748        vebox_in_id = proc_ctx->surface_input_vebox;
749     }else{
750        vebox_in_id = proc_ctx->surface_input;
751     } 
752
753     if(proc_ctx->surface_output_vebox != -1){
754        vebox_out_id = proc_ctx->surface_output_vebox;
755     }else{
756        vebox_out_id = proc_ctx->surface_output;
757     } 
758
759     struct object_surface* obj_surf_in  = SURFACE(vebox_in_id);
760     struct object_surface* obj_surf_out = SURFACE(vebox_out_id);
761        
762     if(obj_surf_in->bo == NULL){
763           input_fourcc = VA_FOURCC('N','V','1','2');
764           input_sampling = SUBSAMPLE_YUV420;
765           input_tiling = 0;
766           i965_check_alloc_surface_bo(ctx, obj_surf_in, input_tiling, input_fourcc, input_sampling);
767     } else {
768         input_fourcc = obj_surf_in->fourcc;
769         input_sampling = obj_surf_in->subsampling;
770         dri_bo_get_tiling(obj_surf_in->bo, &input_tiling, &swizzle);
771         input_tiling = !!input_tiling;
772     }
773
774     if(obj_surf_out->bo == NULL){
775           output_fourcc = VA_FOURCC('N','V','1','2');
776           output_sampling = SUBSAMPLE_YUV420;
777           output_tiling = 0;
778           i965_check_alloc_surface_bo(ctx, obj_surf_out, output_tiling, output_fourcc, output_sampling);
779     }else {
780         output_fourcc   = obj_surf_out->fourcc;
781         output_sampling = obj_surf_out->subsampling;
782         dri_bo_get_tiling(obj_surf_out->bo, &output_tiling, &swizzle);
783         output_tiling = !!output_tiling;
784     }
785
786     /* vebox pipelien input surface format info */
787     proc_ctx->fourcc_input = input_fourcc;
788     proc_ctx->fourcc_output = output_fourcc;
789    
790     /* create pipeline surfaces */
791     VASurfaceID surfaces[FRAME_STORE_SUM];
792     va_status =   i965_CreateSurfaces(ctx,
793                                    proc_ctx ->width_input,
794                                    proc_ctx ->height_input,
795                                    VA_RT_FORMAT_YUV420,
796                                    FRAME_STORE_SUM,
797                                    &surfaces);
798     assert(va_status == VA_STATUS_SUCCESS);
799
800     for(i = 0; i < FRAME_STORE_SUM; i ++) {
801         if(proc_ctx->frame_store[i].bo){
802             continue; //refer external surface for vebox pipeline
803         }
804     
805         VASurfaceID new_surface;
806         va_status =   i965_CreateSurfaces(ctx,
807                                           proc_ctx ->width_input,
808                                           proc_ctx ->height_input,
809                                           VA_RT_FORMAT_YUV420,
810                                           1,
811                                           &new_surface);
812         assert(va_status == VA_STATUS_SUCCESS);
813
814         proc_ctx->frame_store[i].surface_id = new_surface;
815         struct object_surface* obj_surf = SURFACE(new_surface);
816
817         if( i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
818            i965_check_alloc_surface_bo(ctx, obj_surf, input_tiling, input_fourcc, input_sampling);
819         } else if( i == FRAME_IN_STMM || i == FRAME_OUT_STMM){
820             i965_check_alloc_surface_bo(ctx, obj_surf, 1, input_fourcc, input_sampling);
821         } else if( i >= FRAME_OUT_CURRENT){
822             i965_check_alloc_surface_bo(ctx, obj_surf, output_tiling, output_fourcc, output_sampling);
823         }
824         proc_ctx->frame_store[i].bo = obj_surf->bo;
825         dri_bo_reference(proc_ctx->frame_store[i].bo);
826         proc_ctx->frame_store[i].is_internal_surface = 1;
827     }
828
829     /* alloc dndi state table  */
830     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
831     bo = dri_bo_alloc(i965->intel.bufmgr,
832                       "vebox: dndi state Buffer",
833                       0x1000, 0x1000);
834     proc_ctx->dndi_state_table.bo = bo;
835     dri_bo_reference(proc_ctx->dndi_state_table.bo);
836  
837     /* alloc iecp state table  */
838     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
839     bo = dri_bo_alloc(i965->intel.bufmgr,
840                       "vebox: iecp state Buffer",
841                       0x1000, 0x1000);
842     proc_ctx->iecp_state_table.bo = bo;
843     dri_bo_reference(proc_ctx->iecp_state_table.bo);
844
845     /* alloc gamut state table  */
846     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
847     bo = dri_bo_alloc(i965->intel.bufmgr,
848                       "vebox: gamut state Buffer",
849                       0x1000, 0x1000);
850     proc_ctx->gamut_state_table.bo = bo;
851     dri_bo_reference(proc_ctx->gamut_state_table.bo);
852
853     /* alloc vertex state table  */
854     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
855     bo = dri_bo_alloc(i965->intel.bufmgr,
856                       "vertex: iecp state Buffer",
857                       0x1000, 0x1000);
858     proc_ctx->vertex_state_table.bo = bo;
859     dri_bo_reference(proc_ctx->vertex_state_table.bo);
860
861 }
862
863 void hsw_veb_surface_reference(VADriverContextP ctx,
864                               struct intel_vebox_context *proc_ctx)
865 {
866     struct object_surface * obj_surf; 
867     struct i965_driver_data *i965 = i965_driver_data(ctx);
868     VAGenericID vebox_in_id, vebox_out_id;
869
870     if(proc_ctx->surface_input_vebox != -1){
871        vebox_in_id = proc_ctx->surface_input_vebox;
872     }else{
873        vebox_in_id = proc_ctx->surface_input;
874     } 
875
876     if(proc_ctx->surface_output_vebox != -1){
877        vebox_out_id = proc_ctx->surface_output_vebox;
878     }else{
879        vebox_out_id = proc_ctx->surface_output;
880     } 
881
882     /* update the input surface */ 
883      obj_surf = SURFACE(vebox_in_id);
884      dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
885      proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = vebox_in_id;
886      proc_ctx->frame_store[FRAME_IN_CURRENT].bo = obj_surf->bo;
887      proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
888      dri_bo_reference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
889
890      /* update the output surface */ 
891      obj_surf = SURFACE(vebox_out_id);
892      if(proc_ctx->filters_mask == VPP_DNDI_DN){
893          dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
894          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = vebox_out_id;
895          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = obj_surf->bo;
896          proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
897          dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
898      }else {
899          dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
900          proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = vebox_out_id;
901          proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = obj_surf->bo;
902          proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
903          dri_bo_reference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
904      } 
905 }
906
907 void hsw_veb_surface_unreference(VADriverContextP ctx,
908                                  struct intel_vebox_context *proc_ctx)
909 {
910     /* unreference the input surface */ 
911     dri_bo_unreference(proc_ctx->frame_store[FRAME_IN_CURRENT].bo);
912     proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id = -1;
913     proc_ctx->frame_store[FRAME_IN_CURRENT].bo = NULL;
914     proc_ctx->frame_store[FRAME_IN_CURRENT].is_internal_surface = 0;
915
916     /* unreference the shared output surface */ 
917     if(proc_ctx->filters_mask == VPP_DNDI_DN){
918        dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo);
919        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id = -1;
920        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].bo = NULL;
921        proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].is_internal_surface = 0;
922     }else{
923        dri_bo_unreference(proc_ctx->frame_store[FRAME_OUT_CURRENT].bo);
924        proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id = -1;
925        proc_ctx->frame_store[FRAME_OUT_CURRENT].bo = NULL;
926        proc_ctx->frame_store[FRAME_OUT_CURRENT].is_internal_surface = 0;
927     }
928 }
929
930 int hsw_veb_pre_format_convert(VADriverContextP ctx,
931                            struct intel_vebox_context *proc_ctx)
932 {
933     VAStatus va_status;
934     struct i965_driver_data *i965 = i965_driver_data(ctx);
935     struct object_surface* obj_surf_input = SURFACE(proc_ctx->surface_input);
936     struct object_surface* obj_surf_output = SURFACE(proc_ctx->surface_output);
937     struct object_surface* obj_surf_input_vebox;
938     struct object_surface* obj_surf_output_vebox;
939     struct object_surface* obj_surf_output_scaled;
940
941     proc_ctx->width_input   = obj_surf_input->orig_width;
942     proc_ctx->height_input  = obj_surf_input->orig_height;
943     proc_ctx->width_output  = obj_surf_output->orig_width;
944     proc_ctx->height_output = obj_surf_output->orig_height;
945    
946     /* only partial frame is not supported to be processed */
947     /*
948     assert(proc_ctx->width_input   == proc_ctx->pipeline_param->surface_region->width);
949     assert(proc_ctx->height_input  == proc_ctx->pipeline_param->surface_region->height);
950     assert(proc_ctx->width_output  == proc_ctx->pipeline_param->output_region->width);
951     assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
952     */
953
954     if(proc_ctx->width_output  != proc_ctx->width_input ||
955        proc_ctx->height_output != proc_ctx->height_input){
956         proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
957     }
958
959      /* convert the following format to NV12 format */
960      if(obj_surf_input->fourcc ==  VA_FOURCC('Y','V','1','2') ||
961            obj_surf_input->fourcc ==  VA_FOURCC('I','4','2','0') ||
962            obj_surf_input->fourcc ==  VA_FOURCC('I','M','C','1') ||
963            obj_surf_input->fourcc ==  VA_FOURCC('I','M','C','2')){
964
965          proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
966
967       } else if(obj_surf_input->fourcc ==  VA_FOURCC('R','G','B','A') ||
968                obj_surf_input->fourcc ==  VA_FOURCC('A','Y','U','V') ||
969                obj_surf_input->fourcc ==  VA_FOURCC('Y','U','Y','2') ||
970                obj_surf_input->fourcc ==  VA_FOURCC('N','V','1','2')){
971                 // nothing to do here
972      } else {
973            /* not support other format as input */ 
974            assert(0);
975      }
976     
977      if(proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT){
978         if(proc_ctx->surface_input_vebox == -1){
979              va_status = i965_CreateSurfaces(ctx,
980                                             proc_ctx->width_input,
981                                             proc_ctx->height_input,
982                                             VA_RT_FORMAT_YUV420,
983                                             1,
984                                             &(proc_ctx->surface_input_vebox));
985              assert(va_status == VA_STATUS_SUCCESS);
986              obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
987              i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
988          }
989        
990          vpp_surface_convert(ctx, proc_ctx->surface_input_vebox, proc_ctx->surface_input);
991       }
992
993       /* create one temporary NV12 surfaces for conversion*/
994      if(obj_surf_output->fourcc ==  VA_FOURCC('Y','V','1','2') ||
995         obj_surf_output->fourcc ==  VA_FOURCC('I','4','2','0') ||
996         obj_surf_output->fourcc ==  VA_FOURCC('I','M','C','1') ||
997         obj_surf_output->fourcc ==  VA_FOURCC('I','M','C','2')) {  
998
999         proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
1000     } else if(obj_surf_output->fourcc ==  VA_FOURCC('R','G','B','A') ||
1001               obj_surf_output->fourcc ==  VA_FOURCC('A','Y','U','V') ||
1002               obj_surf_output->fourcc ==  VA_FOURCC('Y','U','Y','2') ||
1003               obj_surf_output->fourcc ==  VA_FOURCC('N','V','1','2')){
1004               /* Nothing to do here */
1005      } else {
1006            /* not support other format as input */ 
1007            assert(0);
1008      }
1009   
1010      if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
1011         proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1012        if(proc_ctx->surface_output_vebox == -1){
1013              va_status = i965_CreateSurfaces(ctx,
1014                                             proc_ctx->width_input,
1015                                             proc_ctx->height_input,
1016                                             VA_RT_FORMAT_YUV420,
1017                                             1,
1018                                             &(proc_ctx->surface_output_vebox));
1019              assert(va_status == VA_STATUS_SUCCESS);
1020              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
1021              i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
1022        }
1023      }   
1024
1025      if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1026        if(proc_ctx->surface_output_scaled == -1){
1027              va_status = i965_CreateSurfaces(ctx,
1028                                             proc_ctx->width_output,
1029                                             proc_ctx->height_output,
1030                                             VA_RT_FORMAT_YUV420,
1031                                             1,
1032                                             &(proc_ctx->surface_output_scaled));
1033              assert(va_status == VA_STATUS_SUCCESS);
1034              obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
1035              i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
1036        }
1037      } 
1038     
1039      return 0;
1040 }
1041
1042 int hsw_veb_post_format_convert(VADriverContextP ctx,
1043                            struct intel_vebox_context *proc_ctx)
1044 {
1045      struct i965_driver_data *i965 = i965_driver_data(ctx);
1046      VASurfaceID surf_id_pipe_out = 0;
1047
1048      if(proc_ctx->filters_mask == VPP_DNDI_DN){
1049          surf_id_pipe_out = proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].surface_id;
1050      } else {
1051          surf_id_pipe_out = proc_ctx->frame_store[FRAME_OUT_CURRENT].surface_id;
1052      }
1053  
1054     if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1055         !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1056         /* Output surface format is covered by vebox pipeline and 
1057          * processed picture is already store in output surface 
1058          * so nothing will be done here */
1059     } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1060                !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1061        /* convert and copy NV12 to YV12/IMC3/IMC2 output*/
1062         vpp_surface_convert(ctx,proc_ctx->surface_output, surf_id_pipe_out);
1063
1064     } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1065        /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/ output*/
1066         assert((SURFACE(surf_id_pipe_out))->fourcc == VA_FOURCC('N','V','1','2'));
1067      
1068         /* first step :surface scaling */
1069         vpp_surface_scaling(ctx,proc_ctx->surface_output_scaled, surf_id_pipe_out);
1070
1071         /* second step: color format convert and copy to output */
1072         struct object_surface *obj_surf = SURFACE(proc_ctx->surface_output);
1073         if(obj_surf->fourcc ==  VA_FOURCC('Y','V','1','2') ||
1074            obj_surf->fourcc ==  VA_FOURCC('I','4','2','0') ||
1075            obj_surf->fourcc ==  VA_FOURCC('Y','U','Y','2') ||
1076            obj_surf->fourcc ==  VA_FOURCC('I','M','C','2')) {  
1077            vpp_surface_convert(ctx,proc_ctx->surface_output, proc_ctx->surface_output_scaled);
1078        }else {
1079            assert(0); 
1080        }
1081    }
1082
1083     return 0;
1084 }
1085
1086 VAStatus gen75_vebox_process_picture(VADriverContextP ctx,
1087                          struct intel_vebox_context *proc_ctx)
1088 {
1089     struct i965_driver_data *i965 = i965_driver_data(ctx);
1090  
1091     if(proc_ctx->is_first_frame) {
1092         /* prepare the basic pipeline */        
1093         VAProcPipelineParameterBuffer *pipe = proc_ctx->pipeline_param;
1094         VABufferID *filter_ids = (VABufferID*)proc_ctx->pipeline_param->filters ;
1095         VAProcFilterParameterBuffer* filter = NULL;
1096         struct object_buffer *obj_buf = NULL;
1097         unsigned int i;
1098
1099         for(i = 0; i < pipe->num_filters; i ++) {
1100             obj_buf = BUFFER((*(filter_ids + i)));
1101             filter = (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer;
1102             
1103             if(filter->type == VAProcFilterNoiseReduction) {
1104                 proc_ctx->filters_mask |= VPP_DNDI_DN;
1105                 proc_ctx->filter_dn = filter;
1106             } else if (filter->type == VAProcFilterDeinterlacing) {
1107                 proc_ctx->filters_mask |= VPP_DNDI_DI;
1108                 proc_ctx->filter_di = filter;
1109             } else if (filter->type == VAProcFilterColorBalance) {
1110                  proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1111                  proc_ctx->filter_iecp_amp = filter;
1112             } else if (filter->type == VAProcFilterColorStandard){
1113                  proc_ctx->filters_mask |= VPP_IECP_CSC;
1114                  proc_ctx->filter_iecp_csc = filter;
1115           /*} else if (filter->type == VAProcFilterSkinToneDetectAndEnhance){
1116                  proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1117                  proc_ctx->filter_iecp_std = filter;
1118             } else if (filter->type == VAProcFilterTotalColorControl){
1119                  proc_ctx->filters_mask |= VPP_IECP_TCC;
1120                  proc_ctx->filter_iecp_tcc = filter;
1121           */} else {
1122                  //not supported filter type
1123                  return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1124             }
1125         }
1126    }
1127
1128     hsw_veb_pre_format_convert(ctx, proc_ctx);
1129     hsw_veb_surface_reference(ctx, proc_ctx);
1130
1131     if(proc_ctx->is_first_frame){
1132         hsw_veb_resource_prepare(ctx, proc_ctx);
1133     }
1134
1135     intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1136     intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1137     hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE); 
1138     hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE); 
1139     hsw_veb_state_table_setup(ctx, proc_ctx);
1140
1141     hsw_veb_state_command(ctx, proc_ctx);               
1142     hsw_veb_dndi_iecp_command(ctx, proc_ctx);
1143     intel_batchbuffer_end_atomic(proc_ctx->batch);
1144     intel_batchbuffer_flush(proc_ctx->batch);
1145
1146     hsw_veb_post_format_convert(ctx, proc_ctx);
1147     hsw_veb_surface_unreference(ctx, proc_ctx);
1148
1149  
1150     if(proc_ctx->is_first_frame)
1151        proc_ctx->is_first_frame = 0; 
1152      
1153     return VA_STATUS_SUCCESS;
1154 }
1155
1156 void gen75_vebox_context_destroy(VADriverContextP ctx, 
1157                           struct intel_vebox_context *proc_ctx)
1158 {
1159     struct i965_driver_data *i965 = i965_driver_data(ctx);
1160     struct object_surface * obj_surf = NULL;
1161     int i;
1162
1163     if(proc_ctx->surface_input_vebox != -1){
1164        obj_surf = SURFACE(proc_ctx->surface_input_vebox);
1165        i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
1166        proc_ctx->surface_input_vebox = -1;
1167      }
1168
1169     if(proc_ctx->surface_output_vebox != -1){
1170        obj_surf = SURFACE(proc_ctx->surface_output_vebox);
1171        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
1172        proc_ctx->surface_output_vebox = -1;
1173      }
1174
1175     if(proc_ctx->surface_output_scaled != -1){
1176        obj_surf = SURFACE(proc_ctx->surface_output_scaled);
1177        i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
1178        proc_ctx->surface_output_scaled = -1;
1179      }
1180
1181     for(i = 0; i < FRAME_STORE_SUM; i ++) {
1182         if(proc_ctx->frame_store[i].bo){
1183            dri_bo_unreference(proc_ctx->frame_store[i].bo);
1184            i965_DestroySurfaces(ctx, &proc_ctx->frame_store[i].surface_id, 1);
1185         }
1186
1187        proc_ctx->frame_store[i].surface_id = -1;
1188        proc_ctx->frame_store[i].bo = NULL;
1189        proc_ctx->frame_store[i].valid = 0;
1190     }
1191
1192     /* dndi state table  */
1193     dri_bo_unreference(proc_ctx->dndi_state_table.bo);
1194     proc_ctx->dndi_state_table.bo = NULL;
1195
1196     /* iecp state table  */
1197     dri_bo_unreference(proc_ctx->iecp_state_table.bo);
1198     proc_ctx->dndi_state_table.bo = NULL;
1199  
1200     /* gamut statu table */
1201     dri_bo_unreference(proc_ctx->gamut_state_table.bo);
1202     proc_ctx->gamut_state_table.bo = NULL;
1203
1204     /* vertex state table  */
1205     dri_bo_unreference(proc_ctx->vertex_state_table.bo);
1206     proc_ctx->vertex_state_table.bo = NULL;
1207
1208     intel_batchbuffer_free(proc_ctx->batch);
1209
1210     free(proc_ctx);
1211 }
1212
1213 struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
1214 {
1215     struct intel_driver_data *intel = intel_driver_data(ctx);
1216     struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
1217
1218     proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
1219     memset(proc_context->frame_store, 0, sizeof(VEBFrameStore)*FRAME_STORE_SUM);
1220   
1221     proc_context->filters_mask          = 0;
1222     proc_context->is_first_frame        = 1;
1223     proc_context->surface_input_vebox   = -1;
1224     proc_context->surface_output_vebox  = -1;
1225     proc_context->surface_output_scaled = -1;
1226     proc_context->filters_mask          = 0;
1227     proc_context->format_convert_flags  = 0;
1228
1229     return proc_context;
1230 }
1231