OSDN Git Service

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