OSDN Git Service

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