Check the pointer against NULL
[platform/upstream/libva-intel-driver.git] / src / i965_post_processing.c
1 /*
2  * Copyright © 2010 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  *    Xiang Haihao <haihao.xiang@intel.com>
26  *
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36 #include "i965_defines.h"
37 #include "i965_structs.h"
38 #include "i965_drv_video.h"
39 #include "i965_post_processing.h"
40 #include "i965_render.h"
41 #include "intel_media.h"
42
43 extern VAStatus
44 vpp_surface_convert(VADriverContextP ctx,
45                     struct object_surface *src_obj_surf,
46                     struct object_surface *dst_obj_surf);
47
48 #define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
49
50 #define SURFACE_STATE_PADDED_SIZE               MAX(SURFACE_STATE_PADDED_SIZE_GEN8,\
51                         MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7))
52
53 #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
54 #define BINDING_TABLE_OFFSET                    SURFACE_STATE_OFFSET(MAX_PP_SURFACES)
55
56 #define GPU_ASM_BLOCK_WIDTH         16
57 #define GPU_ASM_BLOCK_HEIGHT        8
58 #define GPU_ASM_X_OFFSET_ALIGNMENT  4
59
60 #define VA_STATUS_SUCCESS_1                     0xFFFFFFFE
61
62 extern VAStatus
63 i965_CreateSurfaces(VADriverContextP ctx,
64                     int width,
65                     int height,
66                     int format,
67                     int num_surfaces,
68                     VASurfaceID *surfaces);
69
70 static const uint32_t pp_null_gen5[][4] = {
71 #include "shaders/post_processing/gen5_6/null.g4b.gen5"
72 };
73
74 static const uint32_t pp_nv12_load_save_nv12_gen5[][4] = {
75 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g4b.gen5"
76 };
77
78 static const uint32_t pp_nv12_load_save_pl3_gen5[][4] = {
79 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g4b.gen5"
80 };
81
82 static const uint32_t pp_pl3_load_save_nv12_gen5[][4] = {
83 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g4b.gen5"
84 };
85
86 static const uint32_t pp_pl3_load_save_pl3_gen5[][4] = {
87 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g4b.gen5"
88 };
89
90 static const uint32_t pp_nv12_scaling_gen5[][4] = {
91 #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g4b.gen5"
92 };
93
94 static const uint32_t pp_nv12_avs_gen5[][4] = {
95 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g4b.gen5"
96 };
97
98 static const uint32_t pp_nv12_dndi_gen5[][4] = {
99 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g4b.gen5"
100 };
101
102 static const uint32_t pp_nv12_dn_gen5[][4] = {
103 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g4b.gen5"
104 };
105
106 static const uint32_t pp_nv12_load_save_pa_gen5[][4] = {
107 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g4b.gen5"
108 };
109
110 static const uint32_t pp_pl3_load_save_pa_gen5[][4] = {
111 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g4b.gen5"
112 };
113
114 static const uint32_t pp_pa_load_save_nv12_gen5[][4] = {
115 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g4b.gen5"
116 };
117
118 static const uint32_t pp_pa_load_save_pl3_gen5[][4] = {
119 #include "shaders/post_processing/gen5_6/pa_load_save_pl3.g4b.gen5"
120 };
121
122 static const uint32_t pp_pa_load_save_pa_gen5[][4] = {
123 #include "shaders/post_processing/gen5_6/pa_load_save_pa.g4b.gen5"
124 };
125
126 static const uint32_t pp_rgbx_load_save_nv12_gen5[][4] = {
127 #include "shaders/post_processing/gen5_6/rgbx_load_save_nv12.g4b.gen5"
128 };
129
130 static const uint32_t pp_nv12_load_save_rgbx_gen5[][4] = {
131 #include "shaders/post_processing/gen5_6/nv12_load_save_rgbx.g4b.gen5"
132 };
133
134 static VAStatus pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
135                                    const struct i965_surface *src_surface,
136                                    const VARectangle *src_rect,
137                                    struct i965_surface *dst_surface,
138                                    const VARectangle *dst_rect,
139                                    void *filter_param);
140 static VAStatus pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
141                                             const struct i965_surface *src_surface,
142                                             const VARectangle *src_rect,
143                                             struct i965_surface *dst_surface,
144                                             const VARectangle *dst_rect,
145                                             void *filter_param);
146 static VAStatus pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
147                                            const struct i965_surface *src_surface,
148                                            const VARectangle *src_rect,
149                                            struct i965_surface *dst_surface,
150                                            const VARectangle *dst_rect,
151                                            void *filter_param);
152 static VAStatus gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
153                                              const struct i965_surface *src_surface,
154                                              const VARectangle *src_rect,
155                                              struct i965_surface *dst_surface,
156                                              const VARectangle *dst_rect,
157                                              void *filter_param);
158 static VAStatus pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
159                                                 const struct i965_surface *src_surface,
160                                                 const VARectangle *src_rect,
161                                                 struct i965_surface *dst_surface,
162                                                 const VARectangle *dst_rect,
163                                                 void *filter_param);
164 static VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
165                                         const struct i965_surface *src_surface,
166                                         const VARectangle *src_rect,
167                                         struct i965_surface *dst_surface,
168                                         const VARectangle *dst_rect,
169                                         void *filter_param);
170 static VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
171                                       const struct i965_surface *src_surface,
172                                       const VARectangle *src_rect,
173                                       struct i965_surface *dst_surface,
174                                       const VARectangle *dst_rect,
175                                       void *filter_param);
176
177 static struct pp_module pp_modules_gen5[] = {
178     {
179         {
180             "NULL module (for testing)",
181             PP_NULL,
182             pp_null_gen5,
183             sizeof(pp_null_gen5),
184             NULL,
185         },
186
187         pp_null_initialize,
188     },
189
190     {
191         {
192             "NV12_NV12",
193             PP_NV12_LOAD_SAVE_N12,
194             pp_nv12_load_save_nv12_gen5,
195             sizeof(pp_nv12_load_save_nv12_gen5),
196             NULL,
197         },
198
199         pp_plx_load_save_plx_initialize,
200     },
201
202     {
203         {
204             "NV12_PL3",
205             PP_NV12_LOAD_SAVE_PL3,
206             pp_nv12_load_save_pl3_gen5,
207             sizeof(pp_nv12_load_save_pl3_gen5),
208             NULL,
209         },
210
211         pp_plx_load_save_plx_initialize,
212     },
213
214     {
215         {
216             "PL3_NV12",
217             PP_PL3_LOAD_SAVE_N12,
218             pp_pl3_load_save_nv12_gen5,
219             sizeof(pp_pl3_load_save_nv12_gen5),
220             NULL,
221         },
222
223         pp_plx_load_save_plx_initialize,
224     },
225
226     {
227         {
228             "PL3_PL3",
229             PP_PL3_LOAD_SAVE_PL3,
230             pp_pl3_load_save_pl3_gen5,
231             sizeof(pp_pl3_load_save_pl3_gen5),
232             NULL,
233         },
234
235         pp_plx_load_save_plx_initialize
236     },
237
238     {
239         {
240             "NV12 Scaling module",
241             PP_NV12_SCALING,
242             pp_nv12_scaling_gen5,
243             sizeof(pp_nv12_scaling_gen5),
244             NULL,
245         },
246
247         pp_nv12_scaling_initialize,
248     },
249
250     {
251         {
252             "NV12 AVS module",
253             PP_NV12_AVS,
254             pp_nv12_avs_gen5,
255             sizeof(pp_nv12_avs_gen5),
256             NULL,
257         },
258
259         pp_nv12_avs_initialize_nlas,
260     },
261
262     {
263         {
264             "NV12 DNDI module",
265             PP_NV12_DNDI,
266             pp_nv12_dndi_gen5,
267             sizeof(pp_nv12_dndi_gen5),
268             NULL,
269         },
270
271         pp_nv12_dndi_initialize,
272     },
273
274     {
275         {
276             "NV12 DN module",
277             PP_NV12_DN,
278             pp_nv12_dn_gen5,
279             sizeof(pp_nv12_dn_gen5),
280             NULL,
281         },
282
283         pp_nv12_dn_initialize,
284     },
285
286     {
287         {
288             "NV12_PA module",
289             PP_NV12_LOAD_SAVE_PA,
290             pp_nv12_load_save_pa_gen5,
291             sizeof(pp_nv12_load_save_pa_gen5),
292             NULL,
293         },
294     
295         pp_plx_load_save_plx_initialize,
296     },
297
298     {
299         {
300             "PL3_PA module",
301             PP_PL3_LOAD_SAVE_PA,
302             pp_pl3_load_save_pa_gen5,
303             sizeof(pp_pl3_load_save_pa_gen5),
304             NULL,
305         },
306     
307         pp_plx_load_save_plx_initialize,
308     },
309
310     {
311         {
312             "PA_NV12 module",
313             PP_PA_LOAD_SAVE_NV12,
314             pp_pa_load_save_nv12_gen5,
315             sizeof(pp_pa_load_save_nv12_gen5),
316             NULL,
317         },
318     
319         pp_plx_load_save_plx_initialize,
320     },
321
322     {
323         {
324             "PA_PL3 module",
325             PP_PA_LOAD_SAVE_PL3,
326             pp_pa_load_save_pl3_gen5,
327             sizeof(pp_pa_load_save_pl3_gen5),
328             NULL,
329         },
330     
331         pp_plx_load_save_plx_initialize,
332     },
333
334     {
335         {
336             "PA_PA module",
337             PP_PA_LOAD_SAVE_PA,
338             pp_pa_load_save_pa_gen5,
339             sizeof(pp_pa_load_save_pa_gen5),
340             NULL,
341         },
342
343         pp_plx_load_save_plx_initialize,
344     },
345
346     {
347         {
348             "RGBX_NV12 module",
349             PP_RGBX_LOAD_SAVE_NV12,
350             pp_rgbx_load_save_nv12_gen5,
351             sizeof(pp_rgbx_load_save_nv12_gen5),
352             NULL,
353         },
354     
355         pp_plx_load_save_plx_initialize,
356     },
357             
358     {
359         {
360             "NV12_RGBX module",
361             PP_NV12_LOAD_SAVE_RGBX,
362             pp_nv12_load_save_rgbx_gen5,
363             sizeof(pp_nv12_load_save_rgbx_gen5),
364             NULL,
365         },
366     
367         pp_plx_load_save_plx_initialize,
368     },
369 };
370
371 static const uint32_t pp_null_gen6[][4] = {
372 #include "shaders/post_processing/gen5_6/null.g6b"
373 };
374
375 static const uint32_t pp_nv12_load_save_nv12_gen6[][4] = {
376 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g6b"
377 };
378
379 static const uint32_t pp_nv12_load_save_pl3_gen6[][4] = {
380 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g6b"
381 };
382
383 static const uint32_t pp_pl3_load_save_nv12_gen6[][4] = {
384 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g6b"
385 };
386
387 static const uint32_t pp_pl3_load_save_pl3_gen6[][4] = {
388 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g6b"
389 };
390
391 static const uint32_t pp_nv12_scaling_gen6[][4] = {
392 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
393 };
394
395 static const uint32_t pp_nv12_avs_gen6[][4] = {
396 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
397 };
398
399 static const uint32_t pp_nv12_dndi_gen6[][4] = {
400 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g6b"
401 };
402
403 static const uint32_t pp_nv12_dn_gen6[][4] = {
404 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g6b"
405 };
406
407 static const uint32_t pp_nv12_load_save_pa_gen6[][4] = {
408 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g6b"
409 };
410
411 static const uint32_t pp_pl3_load_save_pa_gen6[][4] = {
412 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g6b"
413 };
414
415 static const uint32_t pp_pa_load_save_nv12_gen6[][4] = {
416 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g6b"
417 };
418
419 static const uint32_t pp_pa_load_save_pl3_gen6[][4] = {
420 #include "shaders/post_processing/gen5_6/pa_load_save_pl3.g6b"
421 };
422
423 static const uint32_t pp_pa_load_save_pa_gen6[][4] = {
424 #include "shaders/post_processing/gen5_6/pa_load_save_pa.g6b"
425 };
426
427 static const uint32_t pp_rgbx_load_save_nv12_gen6[][4] = {
428 #include "shaders/post_processing/gen5_6/rgbx_load_save_nv12.g6b"
429 };
430
431 static const uint32_t pp_nv12_load_save_rgbx_gen6[][4] = {
432 #include "shaders/post_processing/gen5_6/nv12_load_save_rgbx.g6b"
433 };
434
435 static struct pp_module pp_modules_gen6[] = {
436     {
437         {
438             "NULL module (for testing)",
439             PP_NULL,
440             pp_null_gen6,
441             sizeof(pp_null_gen6),
442             NULL,
443         },
444
445         pp_null_initialize,
446     },
447
448     {
449         {
450             "NV12_NV12",
451             PP_NV12_LOAD_SAVE_N12,
452             pp_nv12_load_save_nv12_gen6,
453             sizeof(pp_nv12_load_save_nv12_gen6),
454             NULL,
455         },
456
457         pp_plx_load_save_plx_initialize,
458     },
459
460     {
461         {
462             "NV12_PL3",
463             PP_NV12_LOAD_SAVE_PL3,
464             pp_nv12_load_save_pl3_gen6,
465             sizeof(pp_nv12_load_save_pl3_gen6),
466             NULL,
467         },
468         
469         pp_plx_load_save_plx_initialize,
470     },
471
472     {
473         {
474             "PL3_NV12",
475             PP_PL3_LOAD_SAVE_N12,
476             pp_pl3_load_save_nv12_gen6,
477             sizeof(pp_pl3_load_save_nv12_gen6),
478             NULL,
479         },
480
481         pp_plx_load_save_plx_initialize,
482     },
483
484     {
485         {
486             "PL3_PL3",
487             PP_PL3_LOAD_SAVE_PL3,
488             pp_pl3_load_save_pl3_gen6,
489             sizeof(pp_pl3_load_save_pl3_gen6),
490             NULL,
491         },
492
493         pp_plx_load_save_plx_initialize,
494     },
495
496     {
497         {
498             "NV12 Scaling module",
499             PP_NV12_SCALING,
500             pp_nv12_scaling_gen6,
501             sizeof(pp_nv12_scaling_gen6),
502             NULL,
503         },
504
505         gen6_nv12_scaling_initialize,
506     },
507
508     {
509         {
510             "NV12 AVS module",
511             PP_NV12_AVS,
512             pp_nv12_avs_gen6,
513             sizeof(pp_nv12_avs_gen6),
514             NULL,
515         },
516
517         pp_nv12_avs_initialize_nlas,
518     },
519
520     {
521         {
522             "NV12 DNDI module",
523             PP_NV12_DNDI,
524             pp_nv12_dndi_gen6,
525             sizeof(pp_nv12_dndi_gen6),
526             NULL,
527         },
528
529         pp_nv12_dndi_initialize,
530     },
531
532     {
533         {
534             "NV12 DN module",
535             PP_NV12_DN,
536             pp_nv12_dn_gen6,
537             sizeof(pp_nv12_dn_gen6),
538             NULL,
539         },
540
541         pp_nv12_dn_initialize,
542     },
543     {
544         {
545             "NV12_PA module",
546             PP_NV12_LOAD_SAVE_PA,
547             pp_nv12_load_save_pa_gen6,
548             sizeof(pp_nv12_load_save_pa_gen6),
549             NULL,
550         },
551     
552         pp_plx_load_save_plx_initialize,
553     },
554
555     {
556         {
557             "PL3_PA module",
558             PP_PL3_LOAD_SAVE_PA,
559             pp_pl3_load_save_pa_gen6,
560             sizeof(pp_pl3_load_save_pa_gen6),
561             NULL,
562         },
563     
564         pp_plx_load_save_plx_initialize,
565     },
566
567     {
568         {
569             "PA_NV12 module",
570             PP_PA_LOAD_SAVE_NV12,
571             pp_pa_load_save_nv12_gen6,
572             sizeof(pp_pa_load_save_nv12_gen6),
573             NULL,
574         },
575     
576         pp_plx_load_save_plx_initialize,
577     },
578
579     {
580         {
581             "PA_PL3 module",
582             PP_PA_LOAD_SAVE_PL3,
583             pp_pa_load_save_pl3_gen6,
584             sizeof(pp_pa_load_save_pl3_gen6),
585             NULL,
586         },
587     
588         pp_plx_load_save_plx_initialize,
589     },
590
591     {
592         {
593             "PA_PA module",
594             PP_PA_LOAD_SAVE_PA,
595             pp_pa_load_save_pa_gen6,
596             sizeof(pp_pa_load_save_pa_gen6),
597             NULL,
598         },
599
600         pp_plx_load_save_plx_initialize,
601     },
602
603     {
604         {
605             "RGBX_NV12 module",
606             PP_RGBX_LOAD_SAVE_NV12,
607             pp_rgbx_load_save_nv12_gen6,
608             sizeof(pp_rgbx_load_save_nv12_gen6),
609             NULL,
610         },
611     
612         pp_plx_load_save_plx_initialize,
613     },
614
615     {
616         {
617             "NV12_RGBX module",
618             PP_NV12_LOAD_SAVE_RGBX,
619             pp_nv12_load_save_rgbx_gen6,
620             sizeof(pp_nv12_load_save_rgbx_gen6),
621             NULL,
622         },
623     
624         pp_plx_load_save_plx_initialize,
625     },
626 };
627
628 static const uint32_t pp_null_gen7[][4] = {
629 };
630
631 static const uint32_t pp_nv12_load_save_nv12_gen7[][4] = {
632 #include "shaders/post_processing/gen7/pl2_to_pl2.g7b"
633 };
634
635 static const uint32_t pp_nv12_load_save_pl3_gen7[][4] = {
636 #include "shaders/post_processing/gen7/pl2_to_pl3.g7b"
637 };
638
639 static const uint32_t pp_pl3_load_save_nv12_gen7[][4] = {
640 #include "shaders/post_processing/gen7/pl3_to_pl2.g7b"
641 };
642
643 static const uint32_t pp_pl3_load_save_pl3_gen7[][4] = {
644 #include "shaders/post_processing/gen7/pl3_to_pl3.g7b"
645 };
646
647 static const uint32_t pp_nv12_scaling_gen7[][4] = {
648 #include "shaders/post_processing/gen7/avs.g7b"
649 };
650
651 static const uint32_t pp_nv12_avs_gen7[][4] = {
652 #include "shaders/post_processing/gen7/avs.g7b"
653 };
654
655 static const uint32_t pp_nv12_dndi_gen7[][4] = {
656 #include "shaders/post_processing/gen7/dndi.g7b"
657 };
658
659 static const uint32_t pp_nv12_dn_gen7[][4] = {
660 #include "shaders/post_processing/gen7/nv12_dn_nv12.g7b"
661 };
662 static const uint32_t pp_nv12_load_save_pa_gen7[][4] = {
663 #include "shaders/post_processing/gen7/pl2_to_pa.g7b"
664 };
665 static const uint32_t pp_pl3_load_save_pa_gen7[][4] = {
666 #include "shaders/post_processing/gen7/pl3_to_pa.g7b"
667 };
668 static const uint32_t pp_pa_load_save_nv12_gen7[][4] = {
669 #include "shaders/post_processing/gen7/pa_to_pl2.g7b"
670 };
671 static const uint32_t pp_pa_load_save_pl3_gen7[][4] = {
672 #include "shaders/post_processing/gen7/pa_to_pl3.g7b"
673 };
674 static const uint32_t pp_pa_load_save_pa_gen7[][4] = {
675 #include "shaders/post_processing/gen7/pa_to_pa.g7b"
676 };
677 static const uint32_t pp_rgbx_load_save_nv12_gen7[][4] = {
678 #include "shaders/post_processing/gen7/rgbx_to_nv12.g7b"
679 };
680 static const uint32_t pp_nv12_load_save_rgbx_gen7[][4] = {
681 #include "shaders/post_processing/gen7/pl2_to_rgbx.g7b"
682 };
683
684 static VAStatus gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
685                                            const struct i965_surface *src_surface,
686                                            const VARectangle *src_rect,
687                                            struct i965_surface *dst_surface,
688                                            const VARectangle *dst_rect,
689                                            void *filter_param);
690 static VAStatus gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
691                                              const struct i965_surface *src_surface,
692                                              const VARectangle *src_rect,
693                                              struct i965_surface *dst_surface,
694                                              const VARectangle *dst_rect,
695                                              void *filter_param);
696 static VAStatus gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
697                                            const struct i965_surface *src_surface,
698                                            const VARectangle *src_rect,
699                                            struct i965_surface *dst_surface,
700                                            const VARectangle *dst_rect,
701                                            void *filter_param);
702
703 static struct pp_module pp_modules_gen7[] = {
704     {
705         {
706             "NULL module (for testing)",
707             PP_NULL,
708             pp_null_gen7,
709             sizeof(pp_null_gen7),
710             NULL,
711         },
712
713         pp_null_initialize,
714     },
715
716     {
717         {
718             "NV12_NV12",
719             PP_NV12_LOAD_SAVE_N12,
720             pp_nv12_load_save_nv12_gen7,
721             sizeof(pp_nv12_load_save_nv12_gen7),
722             NULL,
723         },
724
725         gen7_pp_plx_avs_initialize,
726     },
727
728     {
729         {
730             "NV12_PL3",
731             PP_NV12_LOAD_SAVE_PL3,
732             pp_nv12_load_save_pl3_gen7,
733             sizeof(pp_nv12_load_save_pl3_gen7),
734             NULL,
735         },
736         
737         gen7_pp_plx_avs_initialize,
738     },
739
740     {
741         {
742             "PL3_NV12",
743             PP_PL3_LOAD_SAVE_N12,
744             pp_pl3_load_save_nv12_gen7,
745             sizeof(pp_pl3_load_save_nv12_gen7),
746             NULL,
747         },
748
749         gen7_pp_plx_avs_initialize,
750     },
751
752     {
753         {
754             "PL3_PL3",
755             PP_PL3_LOAD_SAVE_PL3,
756             pp_pl3_load_save_pl3_gen7,
757             sizeof(pp_pl3_load_save_pl3_gen7),
758             NULL,
759         },
760
761         gen7_pp_plx_avs_initialize,
762     },
763
764     {
765         {
766             "NV12 Scaling module",
767             PP_NV12_SCALING,
768             pp_nv12_scaling_gen7,
769             sizeof(pp_nv12_scaling_gen7),
770             NULL,
771         },
772
773         gen7_pp_plx_avs_initialize,
774     },
775
776     {
777         {
778             "NV12 AVS module",
779             PP_NV12_AVS,
780             pp_nv12_avs_gen7,
781             sizeof(pp_nv12_avs_gen7),
782             NULL,
783         },
784
785         gen7_pp_plx_avs_initialize,
786     },
787
788     {
789         {
790             "NV12 DNDI module",
791             PP_NV12_DNDI,
792             pp_nv12_dndi_gen7,
793             sizeof(pp_nv12_dndi_gen7),
794             NULL,
795         },
796
797         gen7_pp_nv12_dndi_initialize,
798     },
799
800     {
801         {
802             "NV12 DN module",
803             PP_NV12_DN,
804             pp_nv12_dn_gen7,
805             sizeof(pp_nv12_dn_gen7),
806             NULL,
807         },
808
809         gen7_pp_nv12_dn_initialize,
810     },
811     {
812         {
813             "NV12_PA module",
814             PP_NV12_LOAD_SAVE_PA,
815             pp_nv12_load_save_pa_gen7,
816             sizeof(pp_nv12_load_save_pa_gen7),
817             NULL,
818         },
819     
820         gen7_pp_plx_avs_initialize,
821     },
822
823     {
824         {
825             "PL3_PA module",
826             PP_PL3_LOAD_SAVE_PA,
827             pp_pl3_load_save_pa_gen7,
828             sizeof(pp_pl3_load_save_pa_gen7),
829             NULL,
830         },
831     
832         gen7_pp_plx_avs_initialize,
833     },
834
835     {
836         {
837             "PA_NV12 module",
838             PP_PA_LOAD_SAVE_NV12,
839             pp_pa_load_save_nv12_gen7,
840             sizeof(pp_pa_load_save_nv12_gen7),
841             NULL,
842         },
843     
844         gen7_pp_plx_avs_initialize,
845     },
846
847     {
848         {
849             "PA_PL3 module",
850             PP_PA_LOAD_SAVE_PL3,
851             pp_pa_load_save_pl3_gen7,
852             sizeof(pp_pa_load_save_pl3_gen7),
853             NULL,
854         },
855     
856         gen7_pp_plx_avs_initialize,
857     },
858
859     {
860         {
861             "PA_PA module",
862             PP_PA_LOAD_SAVE_PA,
863             pp_pa_load_save_pa_gen7,
864             sizeof(pp_pa_load_save_pa_gen7),
865             NULL,
866         },
867
868         gen7_pp_plx_avs_initialize,
869     },
870
871     {
872         {
873             "RGBX_NV12 module",
874             PP_RGBX_LOAD_SAVE_NV12,
875             pp_rgbx_load_save_nv12_gen7,
876             sizeof(pp_rgbx_load_save_nv12_gen7),
877             NULL,
878         },
879     
880         gen7_pp_plx_avs_initialize,
881     },
882
883     {
884         {
885             "NV12_RGBX module",
886             PP_NV12_LOAD_SAVE_RGBX,
887             pp_nv12_load_save_rgbx_gen7,
888             sizeof(pp_nv12_load_save_rgbx_gen7),
889             NULL,
890         },
891     
892         gen7_pp_plx_avs_initialize,
893     },
894             
895 };
896
897 static const uint32_t pp_null_gen75[][4] = {
898 };
899
900 static const uint32_t pp_nv12_load_save_nv12_gen75[][4] = {
901 #include "shaders/post_processing/gen7/pl2_to_pl2.g75b"
902 };
903
904 static const uint32_t pp_nv12_load_save_pl3_gen75[][4] = {
905 #include "shaders/post_processing/gen7/pl2_to_pl3.g75b"
906 };
907
908 static const uint32_t pp_pl3_load_save_nv12_gen75[][4] = {
909 #include "shaders/post_processing/gen7/pl3_to_pl2.g75b"
910 };
911
912 static const uint32_t pp_pl3_load_save_pl3_gen75[][4] = {
913 #include "shaders/post_processing/gen7/pl3_to_pl3.g75b"
914 };
915
916 static const uint32_t pp_nv12_scaling_gen75[][4] = {
917 #include "shaders/post_processing/gen7/avs.g75b"
918 };
919
920 static const uint32_t pp_nv12_avs_gen75[][4] = {
921 #include "shaders/post_processing/gen7/avs.g75b"
922 };
923
924 static const uint32_t pp_nv12_dndi_gen75[][4] = {
925 // #include "shaders/post_processing/gen7/dndi.g75b"
926 };
927
928 static const uint32_t pp_nv12_dn_gen75[][4] = {
929 // #include "shaders/post_processing/gen7/nv12_dn_nv12.g75b"
930 };
931 static const uint32_t pp_nv12_load_save_pa_gen75[][4] = {
932 #include "shaders/post_processing/gen7/pl2_to_pa.g75b"
933 };
934 static const uint32_t pp_pl3_load_save_pa_gen75[][4] = {
935 #include "shaders/post_processing/gen7/pl3_to_pa.g75b"
936 };
937 static const uint32_t pp_pa_load_save_nv12_gen75[][4] = {
938 #include "shaders/post_processing/gen7/pa_to_pl2.g75b"
939 };
940 static const uint32_t pp_pa_load_save_pl3_gen75[][4] = {
941 #include "shaders/post_processing/gen7/pa_to_pl3.g75b"
942 };
943 static const uint32_t pp_pa_load_save_pa_gen75[][4] = {
944 #include "shaders/post_processing/gen7/pa_to_pa.g75b"
945 };
946 static const uint32_t pp_rgbx_load_save_nv12_gen75[][4] = {
947 #include "shaders/post_processing/gen7/rgbx_to_nv12.g75b"
948 };
949 static const uint32_t pp_nv12_load_save_rgbx_gen75[][4] = {
950 #include "shaders/post_processing/gen7/pl2_to_rgbx.g75b"
951 };
952
953 static struct pp_module pp_modules_gen75[] = {
954     {
955         {
956             "NULL module (for testing)",
957             PP_NULL,
958             pp_null_gen75,
959             sizeof(pp_null_gen75),
960             NULL,
961         },
962
963         pp_null_initialize,
964     },
965
966     {
967         {
968             "NV12_NV12",
969             PP_NV12_LOAD_SAVE_N12,
970             pp_nv12_load_save_nv12_gen75,
971             sizeof(pp_nv12_load_save_nv12_gen75),
972             NULL,
973         },
974
975         gen7_pp_plx_avs_initialize,
976     },
977
978     {
979         {
980             "NV12_PL3",
981             PP_NV12_LOAD_SAVE_PL3,
982             pp_nv12_load_save_pl3_gen75,
983             sizeof(pp_nv12_load_save_pl3_gen75),
984             NULL,
985         },
986         
987         gen7_pp_plx_avs_initialize,
988     },
989
990     {
991         {
992             "PL3_NV12",
993             PP_PL3_LOAD_SAVE_N12,
994             pp_pl3_load_save_nv12_gen75,
995             sizeof(pp_pl3_load_save_nv12_gen75),
996             NULL,
997         },
998
999         gen7_pp_plx_avs_initialize,
1000     },
1001
1002     {
1003         {
1004             "PL3_PL3",
1005             PP_PL3_LOAD_SAVE_PL3,
1006             pp_pl3_load_save_pl3_gen75,
1007             sizeof(pp_pl3_load_save_pl3_gen75),
1008             NULL,
1009         },
1010
1011         gen7_pp_plx_avs_initialize,
1012     },
1013
1014     {
1015         {
1016             "NV12 Scaling module",
1017             PP_NV12_SCALING,
1018             pp_nv12_scaling_gen75,
1019             sizeof(pp_nv12_scaling_gen75),
1020             NULL,
1021         },
1022
1023         gen7_pp_plx_avs_initialize,
1024     },
1025
1026     {
1027         {
1028             "NV12 AVS module",
1029             PP_NV12_AVS,
1030             pp_nv12_avs_gen75,
1031             sizeof(pp_nv12_avs_gen75),
1032             NULL,
1033         },
1034
1035         gen7_pp_plx_avs_initialize,
1036     },
1037
1038     {
1039         {
1040             "NV12 DNDI module",
1041             PP_NV12_DNDI,
1042             pp_nv12_dndi_gen75,
1043             sizeof(pp_nv12_dndi_gen75),
1044             NULL,
1045         },
1046
1047         gen7_pp_nv12_dn_initialize,
1048     },
1049
1050     {
1051         {
1052             "NV12 DN module",
1053             PP_NV12_DN,
1054             pp_nv12_dn_gen75,
1055             sizeof(pp_nv12_dn_gen75),
1056             NULL,
1057         },
1058
1059         gen7_pp_nv12_dn_initialize,
1060     },
1061
1062     {
1063         {
1064             "NV12_PA module",
1065             PP_NV12_LOAD_SAVE_PA,
1066             pp_nv12_load_save_pa_gen75,
1067             sizeof(pp_nv12_load_save_pa_gen75),
1068             NULL,
1069         },
1070     
1071         gen7_pp_plx_avs_initialize,
1072     },
1073
1074     {
1075         {
1076             "PL3_PA module",
1077             PP_PL3_LOAD_SAVE_PA,
1078             pp_pl3_load_save_pa_gen75,
1079             sizeof(pp_pl3_load_save_pa_gen75),
1080             NULL,
1081         },
1082     
1083         gen7_pp_plx_avs_initialize,
1084     },
1085
1086     {
1087         {
1088             "PA_NV12 module",
1089             PP_PA_LOAD_SAVE_NV12,
1090             pp_pa_load_save_nv12_gen75,
1091             sizeof(pp_pa_load_save_nv12_gen75),
1092             NULL,
1093         },
1094     
1095         gen7_pp_plx_avs_initialize,
1096     },
1097
1098     {
1099         {
1100             "PA_PL3 module",
1101             PP_PA_LOAD_SAVE_PL3,
1102             pp_pa_load_save_pl3_gen75,
1103             sizeof(pp_pa_load_save_pl3_gen75),
1104             NULL,
1105         },
1106     
1107         gen7_pp_plx_avs_initialize,
1108     },
1109
1110     {
1111         {
1112             "PA_PA module",
1113             PP_PA_LOAD_SAVE_PA,
1114             pp_pa_load_save_pa_gen75,
1115             sizeof(pp_pa_load_save_pa_gen75),
1116             NULL,
1117         },
1118
1119         gen7_pp_plx_avs_initialize,
1120     },
1121
1122     {
1123         {
1124             "RGBX_NV12 module",
1125             PP_RGBX_LOAD_SAVE_NV12,
1126             pp_rgbx_load_save_nv12_gen75,
1127             sizeof(pp_rgbx_load_save_nv12_gen75),
1128             NULL,
1129         },
1130     
1131         gen7_pp_plx_avs_initialize,
1132     },
1133
1134     {
1135         {
1136             "NV12_RGBX module",
1137             PP_NV12_LOAD_SAVE_RGBX,
1138             pp_nv12_load_save_rgbx_gen75,
1139             sizeof(pp_nv12_load_save_rgbx_gen75),
1140             NULL,
1141         },
1142     
1143         gen7_pp_plx_avs_initialize,
1144     },
1145             
1146 };
1147
1148 static int
1149 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
1150 {
1151     int fourcc;
1152
1153     if (surface->type == I965_SURFACE_TYPE_IMAGE) {
1154         struct object_image *obj_image = (struct object_image *)surface->base;
1155         fourcc = obj_image->image.format.fourcc;
1156     } else {
1157         struct object_surface *obj_surface = (struct object_surface *)surface->base;
1158         fourcc = obj_surface->fourcc;
1159     }
1160
1161     return fourcc;
1162 }
1163
1164 static void
1165 pp_get_surface_size(VADriverContextP ctx, const struct i965_surface *surface, int *width, int *height)
1166 {
1167     if (surface->type == I965_SURFACE_TYPE_IMAGE) {
1168         struct object_image *obj_image = (struct object_image *)surface->base;
1169
1170         *width = obj_image->image.width;
1171         *height = obj_image->image.height;
1172     } else {
1173         struct object_surface *obj_surface = (struct object_surface *)surface->base;
1174
1175         *width = obj_surface->orig_width;
1176         *height = obj_surface->orig_height;
1177     }
1178 }
1179
1180 static void
1181 pp_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
1182 {
1183     switch (tiling) {
1184     case I915_TILING_NONE:
1185         ss->ss3.tiled_surface = 0;
1186         ss->ss3.tile_walk = 0;
1187         break;
1188     case I915_TILING_X:
1189         ss->ss3.tiled_surface = 1;
1190         ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
1191         break;
1192     case I915_TILING_Y:
1193         ss->ss3.tiled_surface = 1;
1194         ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
1195         break;
1196     }
1197 }
1198
1199 static void
1200 pp_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
1201 {
1202     switch (tiling) {
1203     case I915_TILING_NONE:
1204         ss->ss2.tiled_surface = 0;
1205         ss->ss2.tile_walk = 0;
1206         break;
1207     case I915_TILING_X:
1208         ss->ss2.tiled_surface = 1;
1209         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
1210         break;
1211     case I915_TILING_Y:
1212         ss->ss2.tiled_surface = 1;
1213         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
1214         break;
1215     }
1216 }
1217
1218 static void
1219 gen7_pp_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
1220 {
1221     switch (tiling) {
1222     case I915_TILING_NONE:
1223         ss->ss0.tiled_surface = 0;
1224         ss->ss0.tile_walk = 0;
1225         break;
1226     case I915_TILING_X:
1227         ss->ss0.tiled_surface = 1;
1228         ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
1229         break;
1230     case I915_TILING_Y:
1231         ss->ss0.tiled_surface = 1;
1232         ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
1233         break;
1234     }
1235 }
1236
1237 static void
1238 gen7_pp_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
1239 {
1240     switch (tiling) {
1241     case I915_TILING_NONE:
1242         ss->ss2.tiled_surface = 0;
1243         ss->ss2.tile_walk = 0;
1244         break;
1245     case I915_TILING_X:
1246         ss->ss2.tiled_surface = 1;
1247         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
1248         break;
1249     case I915_TILING_Y:
1250         ss->ss2.tiled_surface = 1;
1251         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
1252         break;
1253     }
1254 }
1255
1256 static void
1257 ironlake_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
1258 {
1259     struct i965_interface_descriptor *desc;
1260     dri_bo *bo;
1261     int pp_index = pp_context->current_pp;
1262
1263     bo = pp_context->idrt.bo;
1264     dri_bo_map(bo, 1);
1265     assert(bo->virtual);
1266     desc = bo->virtual;
1267     memset(desc, 0, sizeof(*desc));
1268     desc->desc0.grf_reg_blocks = 10;
1269     desc->desc0.kernel_start_pointer = pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
1270     desc->desc1.const_urb_entry_read_offset = 0;
1271     desc->desc1.const_urb_entry_read_len = 4; /* grf 1-4 */
1272     desc->desc2.sampler_state_pointer = pp_context->sampler_state_table.bo->offset >> 5;
1273     desc->desc2.sampler_count = 0;
1274     desc->desc3.binding_table_entry_count = 0;
1275     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
1276
1277     dri_bo_emit_reloc(bo,
1278                       I915_GEM_DOMAIN_INSTRUCTION, 0,
1279                       desc->desc0.grf_reg_blocks,
1280                       offsetof(struct i965_interface_descriptor, desc0),
1281                       pp_context->pp_modules[pp_index].kernel.bo);
1282
1283     dri_bo_emit_reloc(bo,
1284                       I915_GEM_DOMAIN_INSTRUCTION, 0,
1285                       desc->desc2.sampler_count << 2,
1286                       offsetof(struct i965_interface_descriptor, desc2),
1287                       pp_context->sampler_state_table.bo);
1288
1289     dri_bo_unmap(bo);
1290     pp_context->idrt.num_interface_descriptors++;
1291 }
1292
1293 static void
1294 ironlake_pp_vfe_state(struct i965_post_processing_context *pp_context)
1295 {
1296     struct i965_vfe_state *vfe_state;
1297     dri_bo *bo;
1298
1299     bo = pp_context->vfe_state.bo;
1300     dri_bo_map(bo, 1);
1301     assert(bo->virtual);
1302     vfe_state = bo->virtual;
1303     memset(vfe_state, 0, sizeof(*vfe_state));
1304     vfe_state->vfe1.max_threads = pp_context->urb.num_vfe_entries - 1;
1305     vfe_state->vfe1.urb_entry_alloc_size = pp_context->urb.size_vfe_entry - 1;
1306     vfe_state->vfe1.num_urb_entries = pp_context->urb.num_vfe_entries;
1307     vfe_state->vfe1.vfe_mode = VFE_GENERIC_MODE;
1308     vfe_state->vfe1.children_present = 0;
1309     vfe_state->vfe2.interface_descriptor_base = 
1310         pp_context->idrt.bo->offset >> 4; /* reloc */
1311     dri_bo_emit_reloc(bo,
1312                       I915_GEM_DOMAIN_INSTRUCTION, 0,
1313                       0,
1314                       offsetof(struct i965_vfe_state, vfe2),
1315                       pp_context->idrt.bo);
1316     dri_bo_unmap(bo);
1317 }
1318
1319 static void
1320 ironlake_pp_upload_constants(struct i965_post_processing_context *pp_context)
1321 {
1322     unsigned char *constant_buffer;
1323     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1324
1325     assert(sizeof(*pp_static_parameter) == 128);
1326     dri_bo_map(pp_context->curbe.bo, 1);
1327     assert(pp_context->curbe.bo->virtual);
1328     constant_buffer = pp_context->curbe.bo->virtual;
1329     memcpy(constant_buffer, pp_static_parameter, sizeof(*pp_static_parameter));
1330     dri_bo_unmap(pp_context->curbe.bo);
1331 }
1332
1333 static void
1334 ironlake_pp_states_setup(VADriverContextP ctx,
1335                          struct i965_post_processing_context *pp_context)
1336 {
1337     ironlake_pp_interface_descriptor_table(pp_context);
1338     ironlake_pp_vfe_state(pp_context);
1339     ironlake_pp_upload_constants(pp_context);
1340 }
1341
1342 static void
1343 ironlake_pp_pipeline_select(VADriverContextP ctx,
1344                             struct i965_post_processing_context *pp_context)
1345 {
1346     struct intel_batchbuffer *batch = pp_context->batch;
1347
1348     BEGIN_BATCH(batch, 1);
1349     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
1350     ADVANCE_BATCH(batch);
1351 }
1352
1353 static void
1354 ironlake_pp_urb_layout(VADriverContextP ctx,
1355                        struct i965_post_processing_context *pp_context)
1356 {
1357     struct intel_batchbuffer *batch = pp_context->batch;
1358     unsigned int vfe_fence, cs_fence;
1359
1360     vfe_fence = pp_context->urb.cs_start;
1361     cs_fence = pp_context->urb.size;
1362
1363     BEGIN_BATCH(batch, 3);
1364     OUT_BATCH(batch, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
1365     OUT_BATCH(batch, 0);
1366     OUT_BATCH(batch, 
1367               (vfe_fence << UF2_VFE_FENCE_SHIFT) |      /* VFE_SIZE */
1368               (cs_fence << UF2_CS_FENCE_SHIFT));        /* CS_SIZE */
1369     ADVANCE_BATCH(batch);
1370 }
1371
1372 static void
1373 ironlake_pp_state_base_address(VADriverContextP ctx,
1374                                struct i965_post_processing_context *pp_context)
1375 {
1376     struct intel_batchbuffer *batch = pp_context->batch;
1377
1378     BEGIN_BATCH(batch, 8);
1379     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | 6);
1380     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1381     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
1382     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1383     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1384     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1385     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1386     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1387     ADVANCE_BATCH(batch);
1388 }
1389
1390 static void
1391 ironlake_pp_state_pointers(VADriverContextP ctx,
1392                            struct i965_post_processing_context *pp_context)
1393 {
1394     struct intel_batchbuffer *batch = pp_context->batch;
1395
1396     BEGIN_BATCH(batch, 3);
1397     OUT_BATCH(batch, CMD_MEDIA_STATE_POINTERS | 1);
1398     OUT_BATCH(batch, 0);
1399     OUT_RELOC(batch, pp_context->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1400     ADVANCE_BATCH(batch);
1401 }
1402
1403 static void 
1404 ironlake_pp_cs_urb_layout(VADriverContextP ctx,
1405                           struct i965_post_processing_context *pp_context)
1406 {
1407     struct intel_batchbuffer *batch = pp_context->batch;
1408
1409     BEGIN_BATCH(batch, 2);
1410     OUT_BATCH(batch, CMD_CS_URB_STATE | 0);
1411     OUT_BATCH(batch,
1412               ((pp_context->urb.size_cs_entry - 1) << 4) |     /* URB Entry Allocation Size */
1413               (pp_context->urb.num_cs_entries << 0));          /* Number of URB Entries */
1414     ADVANCE_BATCH(batch);
1415 }
1416
1417 static void
1418 ironlake_pp_constant_buffer(VADriverContextP ctx,
1419                             struct i965_post_processing_context *pp_context)
1420 {
1421     struct intel_batchbuffer *batch = pp_context->batch;
1422
1423     BEGIN_BATCH(batch, 2);
1424     OUT_BATCH(batch, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
1425     OUT_RELOC(batch, pp_context->curbe.bo,
1426               I915_GEM_DOMAIN_INSTRUCTION, 0,
1427               pp_context->urb.size_cs_entry - 1);
1428     ADVANCE_BATCH(batch);    
1429 }
1430
1431 static void
1432 ironlake_pp_object_walker(VADriverContextP ctx,
1433                           struct i965_post_processing_context *pp_context)
1434 {
1435     struct intel_batchbuffer *batch = pp_context->batch;
1436     int x, x_steps, y, y_steps;
1437     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1438
1439     x_steps = pp_context->pp_x_steps(pp_context->private_context);
1440     y_steps = pp_context->pp_y_steps(pp_context->private_context);
1441
1442     for (y = 0; y < y_steps; y++) {
1443         for (x = 0; x < x_steps; x++) {
1444             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
1445                 BEGIN_BATCH(batch, 20);
1446                 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 18);
1447                 OUT_BATCH(batch, 0);
1448                 OUT_BATCH(batch, 0); /* no indirect data */
1449                 OUT_BATCH(batch, 0);
1450
1451                 /* inline data grf 5-6 */
1452                 assert(sizeof(*pp_inline_parameter) == 64);
1453                 intel_batchbuffer_data(batch, pp_inline_parameter, sizeof(*pp_inline_parameter));
1454
1455                 ADVANCE_BATCH(batch);
1456             }
1457         }
1458     }
1459 }
1460
1461 static void
1462 ironlake_pp_pipeline_setup(VADriverContextP ctx,
1463                            struct i965_post_processing_context *pp_context)
1464 {
1465     struct intel_batchbuffer *batch = pp_context->batch;
1466
1467     intel_batchbuffer_start_atomic(batch, 0x1000);
1468     intel_batchbuffer_emit_mi_flush(batch);
1469     ironlake_pp_pipeline_select(ctx, pp_context);
1470     ironlake_pp_state_base_address(ctx, pp_context);
1471     ironlake_pp_state_pointers(ctx, pp_context);
1472     ironlake_pp_urb_layout(ctx, pp_context);
1473     ironlake_pp_cs_urb_layout(ctx, pp_context);
1474     ironlake_pp_constant_buffer(ctx, pp_context);
1475     ironlake_pp_object_walker(ctx, pp_context);
1476     intel_batchbuffer_end_atomic(batch);
1477 }
1478
1479 // update u/v offset when the surface format are packed yuv
1480 static void i965_update_src_surface_static_parameter(
1481     VADriverContextP    ctx, 
1482     struct i965_post_processing_context *pp_context,
1483     const struct i965_surface *surface)
1484 {
1485     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1486     int fourcc = pp_get_surface_fourcc(ctx, surface);
1487
1488     switch (fourcc) {
1489     case VA_FOURCC_YUY2:
1490         pp_static_parameter->grf1.source_packed_u_offset = 1;
1491         pp_static_parameter->grf1.source_packed_v_offset = 3;
1492         break;
1493     case VA_FOURCC_UYVY:
1494         pp_static_parameter->grf1.source_packed_y_offset = 1;
1495         pp_static_parameter->grf1.source_packed_v_offset = 2;
1496         break;
1497     case VA_FOURCC_BGRX:
1498     case VA_FOURCC_BGRA:
1499         pp_static_parameter->grf1.source_rgb_layout = 0;
1500         break;
1501     case VA_FOURCC_RGBX:
1502     case VA_FOURCC_RGBA:
1503         pp_static_parameter->grf1.source_rgb_layout = 1;
1504         break;
1505     default:
1506         break;
1507     }
1508     
1509 }
1510
1511 static void i965_update_dst_surface_static_parameter(
1512     VADriverContextP    ctx, 
1513     struct i965_post_processing_context *pp_context,
1514     const struct i965_surface *surface)
1515 {
1516     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1517     int fourcc = pp_get_surface_fourcc(ctx, surface);
1518
1519     switch (fourcc) {
1520     case VA_FOURCC_YUY2:
1521         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_u_offset = 1;
1522         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 3;
1523         break;
1524     case VA_FOURCC_UYVY:
1525         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_y_offset = 1;
1526         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 2;
1527         break;
1528     case VA_FOURCC_BGRX:
1529     case VA_FOURCC_BGRA:
1530         pp_static_parameter->grf1.r1_2.csc.destination_rgb_layout = 0;
1531         break;
1532     case VA_FOURCC_RGBX:
1533     case VA_FOURCC_RGBA:
1534         pp_static_parameter->grf1.r1_2.csc.destination_rgb_layout = 1;
1535         break;
1536     default:
1537         break;
1538     }
1539     
1540 }
1541
1542 static void
1543 i965_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1544                           dri_bo *surf_bo, unsigned long surf_bo_offset,
1545                           int width, int height, int pitch, int format, 
1546                           int index, int is_target)
1547 {
1548     struct i965_surface_state *ss;
1549     dri_bo *ss_bo;
1550     unsigned int tiling;
1551     unsigned int swizzle;
1552
1553     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1554     ss_bo = pp_context->surface_state_binding_table.bo;
1555     assert(ss_bo);
1556
1557     dri_bo_map(ss_bo, True);
1558     assert(ss_bo->virtual);
1559     ss = (struct i965_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1560     memset(ss, 0, sizeof(*ss));
1561     ss->ss0.surface_type = I965_SURFACE_2D;
1562     ss->ss0.surface_format = format;
1563     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1564     ss->ss2.width = width - 1;
1565     ss->ss2.height = height - 1;
1566     ss->ss3.pitch = pitch - 1;
1567     pp_set_surface_tiling(ss, tiling);
1568     dri_bo_emit_reloc(ss_bo,
1569                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1570                       surf_bo_offset,
1571                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state, ss1),
1572                       surf_bo);
1573     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1574     dri_bo_unmap(ss_bo);
1575 }
1576
1577 static void
1578 i965_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1579                            dri_bo *surf_bo, unsigned long surf_bo_offset,
1580                            int width, int height, int wpitch,
1581                            int xoffset, int yoffset,
1582                            int format, int interleave_chroma,
1583                            int index)
1584 {
1585     struct i965_surface_state2 *ss2;
1586     dri_bo *ss2_bo;
1587     unsigned int tiling;
1588     unsigned int swizzle;
1589
1590     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1591     ss2_bo = pp_context->surface_state_binding_table.bo;
1592     assert(ss2_bo);
1593
1594     dri_bo_map(ss2_bo, True);
1595     assert(ss2_bo->virtual);
1596     ss2 = (struct i965_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1597     memset(ss2, 0, sizeof(*ss2));
1598     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1599     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1600     ss2->ss1.width = width - 1;
1601     ss2->ss1.height = height - 1;
1602     ss2->ss2.pitch = wpitch - 1;
1603     ss2->ss2.interleave_chroma = interleave_chroma;
1604     ss2->ss2.surface_format = format;
1605     ss2->ss3.x_offset_for_cb = xoffset;
1606     ss2->ss3.y_offset_for_cb = yoffset;
1607     pp_set_surface2_tiling(ss2, tiling);
1608     dri_bo_emit_reloc(ss2_bo,
1609                       I915_GEM_DOMAIN_RENDER, 0,
1610                       surf_bo_offset,
1611                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state2, ss0),
1612                       surf_bo);
1613     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1614     dri_bo_unmap(ss2_bo);
1615 }
1616
1617 static void
1618 gen7_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1619                           dri_bo *surf_bo, unsigned long surf_bo_offset,
1620                           int width, int height, int pitch, int format, 
1621                           int index, int is_target)
1622 {
1623     struct i965_driver_data * const i965 = i965_driver_data(ctx);  
1624     struct gen7_surface_state *ss;
1625     dri_bo *ss_bo;
1626     unsigned int tiling;
1627     unsigned int swizzle;
1628
1629     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1630     ss_bo = pp_context->surface_state_binding_table.bo;
1631     assert(ss_bo);
1632
1633     dri_bo_map(ss_bo, True);
1634     assert(ss_bo->virtual);
1635     ss = (struct gen7_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1636     memset(ss, 0, sizeof(*ss));
1637     ss->ss0.surface_type = I965_SURFACE_2D;
1638     ss->ss0.surface_format = format;
1639     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1640     ss->ss2.width = width - 1;
1641     ss->ss2.height = height - 1;
1642     ss->ss3.pitch = pitch - 1;
1643     gen7_pp_set_surface_tiling(ss, tiling);
1644     if (IS_HASWELL(i965->intel.device_info))
1645         gen7_render_set_surface_scs(ss);
1646     dri_bo_emit_reloc(ss_bo,
1647                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1648                       surf_bo_offset,
1649                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
1650                       surf_bo);
1651     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1652     dri_bo_unmap(ss_bo);
1653 }
1654
1655 static void
1656 gen7_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1657                            dri_bo *surf_bo, unsigned long surf_bo_offset,
1658                            int width, int height, int wpitch,
1659                            int xoffset, int yoffset,
1660                            int format, int interleave_chroma,
1661                            int index)
1662 {
1663     struct gen7_surface_state2 *ss2;
1664     dri_bo *ss2_bo;
1665     unsigned int tiling;
1666     unsigned int swizzle;
1667
1668     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1669     ss2_bo = pp_context->surface_state_binding_table.bo;
1670     assert(ss2_bo);
1671
1672     dri_bo_map(ss2_bo, True);
1673     assert(ss2_bo->virtual);
1674     ss2 = (struct gen7_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1675     memset(ss2, 0, sizeof(*ss2));
1676     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1677     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1678     ss2->ss1.width = width - 1;
1679     ss2->ss1.height = height - 1;
1680     ss2->ss2.pitch = wpitch - 1;
1681     ss2->ss2.interleave_chroma = interleave_chroma;
1682     ss2->ss2.surface_format = format;
1683     ss2->ss3.x_offset_for_cb = xoffset;
1684     ss2->ss3.y_offset_for_cb = yoffset;
1685     gen7_pp_set_surface2_tiling(ss2, tiling);
1686     dri_bo_emit_reloc(ss2_bo,
1687                       I915_GEM_DOMAIN_RENDER, 0,
1688                       surf_bo_offset,
1689                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state2, ss0),
1690                       surf_bo);
1691     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1692     dri_bo_unmap(ss2_bo);
1693 }
1694
1695 static void 
1696 pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1697                                 const struct i965_surface *surface, 
1698                                 int base_index, int is_target,
1699                                 int *width, int *height, int *pitch, int *offset)
1700 {
1701     struct object_surface *obj_surface;
1702     struct object_image *obj_image;
1703     dri_bo *bo;
1704     int fourcc = pp_get_surface_fourcc(ctx, surface);
1705     const int Y = 0;
1706     const int U = ((fourcc == VA_FOURCC_YV12) ||
1707                    (fourcc == VA_FOURCC_YV16))
1708                    ? 2 : 1;
1709     const int V = ((fourcc == VA_FOURCC_YV12) ||
1710                    (fourcc == VA_FOURCC_YV16))
1711                    ? 1 : 2;
1712     const int UV = 1;
1713     int interleaved_uv = fourcc == VA_FOURCC_NV12;
1714     int packed_yuv = (fourcc == VA_FOURCC_YUY2 || fourcc == VA_FOURCC_UYVY);
1715     int full_packed_format = (fourcc == VA_FOURCC_RGBA ||
1716                               fourcc == VA_FOURCC_RGBX ||
1717                               fourcc == VA_FOURCC_BGRA ||
1718                               fourcc == VA_FOURCC_BGRX);
1719     int scale_factor_of_1st_plane_width_in_byte = 1;
1720                               
1721     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
1722         obj_surface = (struct object_surface *)surface->base;
1723         bo = obj_surface->bo;
1724         width[0] = obj_surface->orig_width;
1725         height[0] = obj_surface->orig_height;
1726         pitch[0] = obj_surface->width;
1727         offset[0] = 0;
1728
1729         if (full_packed_format) {
1730             scale_factor_of_1st_plane_width_in_byte = 4; 
1731         }
1732         else if (packed_yuv ) {
1733             scale_factor_of_1st_plane_width_in_byte =  2; 
1734         }
1735         else if (interleaved_uv) {
1736             width[1] = obj_surface->orig_width;
1737             height[1] = obj_surface->orig_height / 2;
1738             pitch[1] = obj_surface->width;
1739             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
1740         } else {
1741             width[1] = obj_surface->orig_width / 2;
1742             height[1] = obj_surface->orig_height / 2;
1743             pitch[1] = obj_surface->width / 2;
1744             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
1745             width[2] = obj_surface->orig_width / 2;
1746             height[2] = obj_surface->orig_height / 2;
1747             pitch[2] = obj_surface->width / 2;
1748             offset[2] = offset[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
1749         }
1750     } else {
1751         obj_image = (struct object_image *)surface->base;
1752         bo = obj_image->bo;
1753         width[0] = obj_image->image.width;
1754         height[0] = obj_image->image.height;
1755         pitch[0] = obj_image->image.pitches[0];
1756         offset[0] = obj_image->image.offsets[0];
1757
1758         if (full_packed_format) {
1759             scale_factor_of_1st_plane_width_in_byte = 4;
1760         }
1761         else if (packed_yuv ) {
1762             scale_factor_of_1st_plane_width_in_byte = 2;
1763         }
1764         else if (interleaved_uv) {
1765             width[1] = obj_image->image.width;
1766             height[1] = obj_image->image.height / 2;
1767             pitch[1] = obj_image->image.pitches[1];
1768             offset[1] = obj_image->image.offsets[1];
1769         } else {
1770             width[1] = obj_image->image.width / 2;
1771             height[1] = obj_image->image.height / 2;
1772             pitch[1] = obj_image->image.pitches[1];
1773             offset[1] = obj_image->image.offsets[1];
1774             width[2] = obj_image->image.width / 2;
1775             height[2] = obj_image->image.height / 2;
1776             pitch[2] = obj_image->image.pitches[2];
1777             offset[2] = obj_image->image.offsets[2];
1778             if (fourcc == VA_FOURCC_YV16) {
1779                 width[1] = obj_image->image.width / 2;
1780                 height[1] = obj_image->image.height;
1781                 width[2] = obj_image->image.width / 2;
1782                 height[2] = obj_image->image.height;
1783             }
1784         }
1785     }
1786
1787     /* Y surface */
1788     i965_pp_set_surface_state(ctx, pp_context,
1789                               bo, offset[Y],
1790                               width[Y] *scale_factor_of_1st_plane_width_in_byte / 4, height[Y], pitch[Y], I965_SURFACEFORMAT_R8_UNORM,
1791                               base_index, is_target);
1792
1793     if (!packed_yuv && !full_packed_format) {
1794         if (interleaved_uv) {
1795             i965_pp_set_surface_state(ctx, pp_context,
1796                                       bo, offset[UV],
1797                                       width[UV] / 4, height[UV], pitch[UV], I965_SURFACEFORMAT_R8_UNORM,
1798                                       base_index + 1, is_target);
1799         } else {
1800             /* U surface */
1801             i965_pp_set_surface_state(ctx, pp_context,
1802                                       bo, offset[U],
1803                                       width[U] / 4, height[U], pitch[U], I965_SURFACEFORMAT_R8_UNORM,
1804                                       base_index + 1, is_target);
1805
1806             /* V surface */
1807             i965_pp_set_surface_state(ctx, pp_context,
1808                                       bo, offset[V],
1809                                       width[V] / 4, height[V], pitch[V], I965_SURFACEFORMAT_R8_UNORM,
1810                                       base_index + 2, is_target);
1811         }
1812     }
1813
1814 }
1815
1816 static void 
1817 gen7_pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1818                                      const struct i965_surface *surface, 
1819                                      int base_index, int is_target,
1820                                      const VARectangle *rect,
1821                                      int *width, int *height, int *pitch, int *offset)
1822 {
1823     struct object_surface *obj_surface;
1824     struct object_image *obj_image;
1825     dri_bo *bo;
1826     int fourcc = pp_get_surface_fourcc(ctx, surface);
1827     const i965_fourcc_info *fourcc_info = get_fourcc_info(fourcc);
1828
1829     if (fourcc_info == NULL)
1830         return;
1831
1832     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
1833         obj_surface = (struct object_surface *)surface->base;
1834         bo = obj_surface->bo;
1835         width[0] = MIN(rect->x + rect->width, obj_surface->orig_width);
1836         height[0] = MIN(rect->y + rect->height, obj_surface->orig_height);
1837         pitch[0] = obj_surface->width;
1838         offset[0] = 0;
1839
1840         if (fourcc_info->num_planes == 1 && is_target)
1841             width[0] = width[0] * (fourcc_info->bpp[0] / 8); /* surface format is R8 */
1842
1843         width[1] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_surface->cb_cr_width);
1844         height[1] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_surface->cb_cr_height);
1845         pitch[1] = obj_surface->cb_cr_pitch;
1846         offset[1] = obj_surface->y_cb_offset * obj_surface->width;
1847
1848         width[2] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_surface->cb_cr_width);
1849         height[2] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_surface->cb_cr_height);
1850         pitch[2] = obj_surface->cb_cr_pitch;
1851         offset[2] = obj_surface->y_cr_offset * obj_surface->width;
1852     } else {
1853         int U = 0, V = 0;
1854
1855         /* FIXME: add support for ARGB/ABGR image */
1856         obj_image = (struct object_image *)surface->base;
1857         bo = obj_image->bo;
1858         width[0] = MIN(rect->x + rect->width, obj_image->image.width);
1859         height[0] = MIN(rect->y + rect->height, obj_image->image.height);
1860         pitch[0] = obj_image->image.pitches[0];
1861         offset[0] = obj_image->image.offsets[0];
1862
1863         if (fourcc_info->num_planes == 1) {
1864             if (is_target)
1865                 width[0] = width[0] * (fourcc_info->bpp[0] / 8); /* surface format is R8 */
1866         } else if (fourcc_info->num_planes == 2) {
1867             U = 1, V = 1;
1868         } else {
1869             assert(fourcc_info->num_components == 3);
1870
1871             U = fourcc_info->components[1].plane;
1872             V = fourcc_info->components[2].plane;
1873             assert((U == 1 && V == 2) ||
1874                    (U == 2 && V == 1));
1875         }
1876
1877         /* Always set width/height although they aren't used for fourcc_info->num_planes == 1 */
1878         width[1] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_image->image.width / fourcc_info->hfactor);
1879         height[1] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_image->image.height / fourcc_info->vfactor);
1880         pitch[1] = obj_image->image.pitches[U];
1881         offset[1] = obj_image->image.offsets[U];
1882
1883         width[2] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_image->image.width / fourcc_info->hfactor);
1884         height[2] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_image->image.height / fourcc_info->vfactor);
1885         pitch[2] = obj_image->image.pitches[V];
1886         offset[2] = obj_image->image.offsets[V];
1887     }
1888
1889     if (is_target) {
1890         gen7_pp_set_surface_state(ctx, pp_context,
1891                                   bo, 0,
1892                                   width[0] / 4, height[0], pitch[0],
1893                                   I965_SURFACEFORMAT_R8_UINT,
1894                                   base_index, 1);
1895
1896         if (fourcc_info->num_planes == 2) {
1897             gen7_pp_set_surface_state(ctx, pp_context,
1898                                       bo, offset[1],
1899                                       width[1] / 2, height[1], pitch[1],
1900                                       I965_SURFACEFORMAT_R8G8_SINT,
1901                                       base_index + 1, 1);
1902         } else if (fourcc_info->num_planes == 3) {
1903             gen7_pp_set_surface_state(ctx, pp_context,
1904                                       bo, offset[1],
1905                                       width[1] / 4, height[1], pitch[1],
1906                                       I965_SURFACEFORMAT_R8_SINT,
1907                                       base_index + 1, 1);
1908             gen7_pp_set_surface_state(ctx, pp_context,
1909                                       bo, offset[2],
1910                                       width[2] / 4, height[2], pitch[2],
1911                                       I965_SURFACEFORMAT_R8_SINT,
1912                                       base_index + 2, 1);
1913         }
1914
1915         if (fourcc_info->format == I965_COLOR_RGB) {
1916             struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1917             /* the format is MSB: X-B-G-R */
1918             pp_static_parameter->grf2.save_avs_rgb_swap = 0;
1919             if ((fourcc == VA_FOURCC_BGRA) ||
1920                 (fourcc == VA_FOURCC_BGRX)) {
1921                 /* It is stored as MSB: X-R-G-B */
1922                 pp_static_parameter->grf2.save_avs_rgb_swap = 1;
1923             }
1924         }
1925     } else {
1926         int format0 = SURFACE_FORMAT_Y8_UNORM;
1927
1928         switch (fourcc) {
1929         case VA_FOURCC_YUY2:
1930             format0 = SURFACE_FORMAT_YCRCB_NORMAL;
1931             break;
1932
1933         case VA_FOURCC_UYVY:
1934             format0 = SURFACE_FORMAT_YCRCB_SWAPY;
1935             break;
1936
1937         default:
1938             break;
1939         }
1940
1941         if (fourcc_info->format == I965_COLOR_RGB) {
1942             struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1943             /* Only R8G8B8A8_UNORM is supported for BGRX or RGBX */
1944             format0 = SURFACE_FORMAT_R8G8B8A8_UNORM;
1945             pp_static_parameter->grf2.src_avs_rgb_swap = 0;
1946             if ((fourcc == VA_FOURCC_BGRA) ||
1947                 (fourcc == VA_FOURCC_BGRX)) {
1948                 pp_static_parameter->grf2.src_avs_rgb_swap = 1;
1949             }
1950         }
1951
1952         gen7_pp_set_surface2_state(ctx, pp_context,
1953                                    bo, offset[0],
1954                                    width[0], height[0], pitch[0],
1955                                    0, 0,
1956                                    format0, 0,
1957                                    base_index);
1958
1959         if (fourcc_info->num_planes == 2) {
1960             gen7_pp_set_surface2_state(ctx, pp_context,
1961                                        bo, offset[1],
1962                                        width[1], height[1], pitch[1],
1963                                        0, 0,
1964                                        SURFACE_FORMAT_R8B8_UNORM, 0,
1965                                        base_index + 1);
1966         } else if (fourcc_info->num_planes == 3) {
1967             gen7_pp_set_surface2_state(ctx, pp_context,
1968                                        bo, offset[1],
1969                                        width[1], height[1], pitch[1],
1970                                        0, 0,
1971                                        SURFACE_FORMAT_R8_UNORM, 0,
1972                                        base_index + 1);
1973             gen7_pp_set_surface2_state(ctx, pp_context,
1974                                        bo, offset[2],
1975                                        width[2], height[2], pitch[2],
1976                                        0, 0,
1977                                        SURFACE_FORMAT_R8_UNORM, 0,
1978                                        base_index + 2);
1979         }
1980     }
1981 }
1982
1983 static int
1984 pp_null_x_steps(void *private_context)
1985 {
1986     return 1;
1987 }
1988
1989 static int
1990 pp_null_y_steps(void *private_context)
1991 {
1992     return 1;
1993 }
1994
1995 static int
1996 pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1997 {
1998     return 0;
1999 }
2000
2001 static VAStatus
2002 pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2003                    const struct i965_surface *src_surface,
2004                    const VARectangle *src_rect,
2005                    struct i965_surface *dst_surface,
2006                    const VARectangle *dst_rect,
2007                    void *filter_param)
2008 {
2009     /* private function & data */
2010     pp_context->pp_x_steps = pp_null_x_steps;
2011     pp_context->pp_y_steps = pp_null_y_steps;
2012     pp_context->private_context = NULL;
2013     pp_context->pp_set_block_parameter = pp_null_set_block_parameter;
2014
2015     dst_surface->flags = src_surface->flags;
2016
2017     return VA_STATUS_SUCCESS;
2018 }
2019
2020 static int
2021 pp_load_save_x_steps(void *private_context)
2022 {
2023     return 1;
2024 }
2025
2026 static int
2027 pp_load_save_y_steps(void *private_context)
2028 {
2029     struct pp_load_save_context *pp_load_save_context = private_context;
2030
2031     return pp_load_save_context->dest_h / 8;
2032 }
2033
2034 static int
2035 pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2036 {
2037     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2038     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)pp_context->private_context;
2039
2040     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_load_save_context->dest_x;
2041     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_load_save_context->dest_y;
2042
2043     return 0;
2044 }
2045
2046 static void calculate_boundary_block_mask(struct i965_post_processing_context *pp_context, const VARectangle *dst_rect)
2047 {
2048     int i;
2049     /* x offset of dest surface must be dword aligned.
2050      * so we have to extend dst surface on left edge, and mask out pixels not interested
2051      */
2052     if (dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT) {
2053         pp_context->block_horizontal_mask_left = 0;
2054         for (i=dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT; i<GPU_ASM_BLOCK_WIDTH; i++)
2055         {
2056             pp_context->block_horizontal_mask_left |= 1<<i;
2057         }
2058     }
2059     else {
2060         pp_context->block_horizontal_mask_left = 0xffff;
2061     }
2062     
2063     int dst_width_adjust = dst_rect->width + dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT; 
2064     if (dst_width_adjust%GPU_ASM_BLOCK_WIDTH){
2065         pp_context->block_horizontal_mask_right = (1 << (dst_width_adjust%GPU_ASM_BLOCK_WIDTH)) - 1;
2066     }
2067     else {
2068         pp_context->block_horizontal_mask_right = 0xffff;
2069     }
2070     
2071     if (dst_rect->height%GPU_ASM_BLOCK_HEIGHT){
2072         pp_context->block_vertical_mask_bottom = (1 << (dst_rect->height%GPU_ASM_BLOCK_HEIGHT)) - 1;
2073     }
2074     else {
2075         pp_context->block_vertical_mask_bottom = 0xff;
2076     }
2077
2078 }
2079 static VAStatus
2080 pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2081                                 const struct i965_surface *src_surface,
2082                                 const VARectangle *src_rect,
2083                                 struct i965_surface *dst_surface,
2084                                 const VARectangle *dst_rect,
2085                                 void *filter_param)
2086 {
2087     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->pp_load_save_context;
2088     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2089     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2090     int width[3], height[3], pitch[3], offset[3];
2091
2092     /* source surface */
2093     pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 1, 0,
2094                                     width, height, pitch, offset);
2095
2096     /* destination surface */
2097     pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 7, 1,
2098                                     width, height, pitch, offset);
2099
2100     /* private function & data */
2101     pp_context->pp_x_steps = pp_load_save_x_steps;
2102     pp_context->pp_y_steps = pp_load_save_y_steps;
2103     pp_context->private_context = &pp_context->pp_load_save_context;
2104     pp_context->pp_set_block_parameter = pp_load_save_set_block_parameter;
2105
2106     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;;
2107     pp_load_save_context->dest_x = dst_rect->x - dst_left_edge_extend;
2108     pp_load_save_context->dest_y = dst_rect->y;
2109     pp_load_save_context->dest_h = ALIGN(dst_rect->height, 8);
2110     pp_load_save_context->dest_w = ALIGN(dst_rect->width+dst_left_edge_extend, 16);
2111
2112     pp_inline_parameter->grf5.block_count_x = pp_load_save_context->dest_w / 16;   /* 1 x N */
2113     pp_inline_parameter->grf5.number_blocks = pp_load_save_context->dest_w / 16;
2114
2115     pp_static_parameter->grf3.horizontal_origin_offset = src_rect->x;
2116     pp_static_parameter->grf3.vertical_origin_offset = src_rect->y;
2117
2118     // update u/v offset for packed yuv
2119     i965_update_src_surface_static_parameter (ctx, pp_context, src_surface);
2120     i965_update_dst_surface_static_parameter (ctx, pp_context, dst_surface);
2121
2122     dst_surface->flags = src_surface->flags;
2123
2124     return VA_STATUS_SUCCESS;
2125 }
2126
2127 static int
2128 pp_scaling_x_steps(void *private_context)
2129 {
2130     return 1;
2131 }
2132
2133 static int
2134 pp_scaling_y_steps(void *private_context)
2135 {
2136     struct pp_scaling_context *pp_scaling_context = private_context;
2137
2138     return pp_scaling_context->dest_h / 8;
2139 }
2140
2141 static int
2142 pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2143 {
2144     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)pp_context->private_context;
2145     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2146     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2147     float src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2148     float src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
2149
2150     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
2151     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
2152     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
2153     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
2154     
2155     return 0;
2156 }
2157
2158 static VAStatus
2159 pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2160                            const struct i965_surface *src_surface,
2161                            const VARectangle *src_rect,
2162                            struct i965_surface *dst_surface,
2163                            const VARectangle *dst_rect,
2164                            void *filter_param)
2165 {
2166     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->pp_scaling_context;
2167     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2168     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2169     struct object_surface *obj_surface;
2170     struct i965_sampler_state *sampler_state;
2171     int in_w, in_h, in_wpitch, in_hpitch;
2172     int out_w, out_h, out_wpitch, out_hpitch;
2173
2174     /* source surface */
2175     obj_surface = (struct object_surface *)src_surface->base;
2176     in_w = obj_surface->orig_width;
2177     in_h = obj_surface->orig_height;
2178     in_wpitch = obj_surface->width;
2179     in_hpitch = obj_surface->height;
2180
2181     /* source Y surface index 1 */
2182     i965_pp_set_surface_state(ctx, pp_context,
2183                               obj_surface->bo, 0,
2184                               in_w, in_h, in_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2185                               1, 0);
2186
2187     /* source UV surface index 2 */
2188     i965_pp_set_surface_state(ctx, pp_context,
2189                               obj_surface->bo, in_wpitch * in_hpitch,
2190                               in_w / 2, in_h / 2, in_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2191                               2, 0);
2192
2193     /* destination surface */
2194     obj_surface = (struct object_surface *)dst_surface->base;
2195     out_w = obj_surface->orig_width;
2196     out_h = obj_surface->orig_height;
2197     out_wpitch = obj_surface->width;
2198     out_hpitch = obj_surface->height;
2199
2200     /* destination Y surface index 7 */
2201     i965_pp_set_surface_state(ctx, pp_context,
2202                               obj_surface->bo, 0,
2203                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2204                               7, 1);
2205
2206     /* destination UV surface index 8 */
2207     i965_pp_set_surface_state(ctx, pp_context,
2208                               obj_surface->bo, out_wpitch * out_hpitch,
2209                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2210                               8, 1);
2211
2212     /* sampler state */
2213     dri_bo_map(pp_context->sampler_state_table.bo, True);
2214     assert(pp_context->sampler_state_table.bo->virtual);
2215     sampler_state = pp_context->sampler_state_table.bo->virtual;
2216
2217     /* SIMD16 Y index 1 */
2218     sampler_state[1].ss0.min_filter = I965_MAPFILTER_LINEAR;
2219     sampler_state[1].ss0.mag_filter = I965_MAPFILTER_LINEAR;
2220     sampler_state[1].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2221     sampler_state[1].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2222     sampler_state[1].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2223
2224     /* SIMD16 UV index 2 */
2225     sampler_state[2].ss0.min_filter = I965_MAPFILTER_LINEAR;
2226     sampler_state[2].ss0.mag_filter = I965_MAPFILTER_LINEAR;
2227     sampler_state[2].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2228     sampler_state[2].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2229     sampler_state[2].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2230
2231     dri_bo_unmap(pp_context->sampler_state_table.bo);
2232
2233     /* private function & data */
2234     pp_context->pp_x_steps = pp_scaling_x_steps;
2235     pp_context->pp_y_steps = pp_scaling_y_steps;
2236     pp_context->private_context = &pp_context->pp_scaling_context;
2237     pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
2238
2239     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
2240     float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
2241     pp_scaling_context->dest_x = dst_rect->x - dst_left_edge_extend;
2242     pp_scaling_context->dest_y = dst_rect->y;
2243     pp_scaling_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
2244     pp_scaling_context->dest_h = ALIGN(dst_rect->height, 8);
2245     pp_scaling_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
2246     pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h;
2247
2248     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
2249
2250     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) (src_rect->width + src_left_edge_extend)/ in_w / (dst_rect->width + dst_left_edge_extend);
2251     pp_inline_parameter->grf5.block_count_x = pp_scaling_context->dest_w / 16;   /* 1 x N */
2252     pp_inline_parameter->grf5.number_blocks = pp_scaling_context->dest_w / 16;
2253
2254     dst_surface->flags = src_surface->flags;
2255
2256     return VA_STATUS_SUCCESS;
2257 }
2258
2259 static int
2260 pp_avs_x_steps(void *private_context)
2261 {
2262     struct pp_avs_context *pp_avs_context = private_context;
2263
2264     return pp_avs_context->dest_w / 16;
2265 }
2266
2267 static int
2268 pp_avs_y_steps(void *private_context)
2269 {
2270     return 1;
2271 }
2272
2273 static int
2274 pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2275 {
2276     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)pp_context->private_context;
2277     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2278     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2279     float src_x_steping, src_y_steping, video_step_delta;
2280     int tmp_w = ALIGN(pp_avs_context->dest_h * pp_avs_context->src_w / pp_avs_context->src_h, 16);
2281
2282     if (pp_static_parameter->grf4.r4_2.avs.nlas == 0) {
2283         src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2284         pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_avs_context->src_normalized_x;
2285     } else if (tmp_w >= pp_avs_context->dest_w) {
2286         pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
2287         pp_inline_parameter->grf6.video_step_delta = 0;
2288         
2289         if (x == 0) {
2290             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
2291                 pp_avs_context->src_normalized_x;
2292         } else {
2293             src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2294             video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2295             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2296                 16 * 15 * video_step_delta / 2;
2297         }
2298     } else {
2299         int n0, n1, n2, nls_left, nls_right;
2300         int factor_a = 5, factor_b = 4;
2301         float f;
2302
2303         n0 = (pp_avs_context->dest_w - tmp_w) / (16 * 2);
2304         n1 = (pp_avs_context->dest_w - tmp_w) / 16 - n0;
2305         n2 = tmp_w / (16 * factor_a);
2306         nls_left = n0 + n2;
2307         nls_right = n1 + n2;
2308         f = (float) n2 * 16 / tmp_w;
2309         
2310         if (n0 < 5) {
2311             pp_inline_parameter->grf6.video_step_delta = 0.0;
2312
2313             if (x == 0) {
2314                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
2315                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
2316             } else {
2317                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2318                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2319                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2320                     16 * 15 * video_step_delta / 2;
2321             }
2322         } else {
2323             if (x < nls_left) {
2324                 /* f = a * nls_left * 16 + b * nls_left * 16 * (nls_left * 16 - 1) / 2 */
2325                 float a = f / (nls_left * 16 * factor_b);
2326                 float b = (f - nls_left * 16 * a) * 2 / (nls_left * 16 * (nls_left * 16 - 1));
2327                 
2328                 pp_inline_parameter->grf6.video_step_delta = b;
2329
2330                 if (x == 0) {
2331                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
2332                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a;
2333                 } else {
2334                     src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2335                     video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2336                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2337                         16 * 15 * video_step_delta / 2;
2338                     pp_inline_parameter->grf5.normalized_video_x_scaling_step += 16 * b;
2339                 }
2340             } else if (x < (pp_avs_context->dest_w / 16 - nls_right)) {
2341                 /* scale the center linearly */
2342                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2343                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2344                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2345                     16 * 15 * video_step_delta / 2;
2346                 pp_inline_parameter->grf6.video_step_delta = 0.0;
2347                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
2348             } else {
2349                 float a = f / (nls_right * 16 * factor_b);
2350                 float b = (f - nls_right * 16 * a) * 2 / (nls_right * 16 * (nls_right * 16 - 1));
2351
2352                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2353                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2354                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2355                     16 * 15 * video_step_delta / 2;
2356                 pp_inline_parameter->grf6.video_step_delta = -b;
2357
2358                 if (x == (pp_avs_context->dest_w / 16 - nls_right))
2359                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a + (nls_right * 16  - 1) * b;
2360                 else
2361                     pp_inline_parameter->grf5.normalized_video_x_scaling_step -= b * 16;
2362             }
2363         }
2364     }
2365
2366     src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
2367     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
2368     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
2369     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
2370
2371     return 0;
2372 }
2373
2374 static VAStatus
2375 pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2376                        const struct i965_surface *src_surface,
2377                        const VARectangle *src_rect,
2378                        struct i965_surface *dst_surface,
2379                        const VARectangle *dst_rect,
2380                        void *filter_param,
2381                        int nlas)
2382 {
2383     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->pp_avs_context;
2384     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2385     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2386     struct object_surface *obj_surface;
2387     struct i965_sampler_8x8 *sampler_8x8;
2388     struct i965_sampler_8x8_state *sampler_8x8_state;
2389     int index;
2390     int in_w, in_h, in_wpitch, in_hpitch;
2391     int out_w, out_h, out_wpitch, out_hpitch;
2392     int i;
2393
2394     /* surface */
2395     obj_surface = (struct object_surface *)src_surface->base;
2396     in_w = obj_surface->orig_width;
2397     in_h = obj_surface->orig_height;
2398     in_wpitch = obj_surface->width;
2399     in_hpitch = obj_surface->height;
2400
2401     /* source Y surface index 1 */
2402     i965_pp_set_surface2_state(ctx, pp_context,
2403                                obj_surface->bo, 0,
2404                                in_w, in_h, in_wpitch,
2405                                0, 0,
2406                                SURFACE_FORMAT_Y8_UNORM, 0,
2407                                1);
2408
2409     /* source UV surface index 2 */
2410     i965_pp_set_surface2_state(ctx, pp_context,
2411                                obj_surface->bo, in_wpitch * in_hpitch,
2412                                in_w / 2, in_h / 2, in_wpitch,
2413                                0, 0,
2414                                SURFACE_FORMAT_R8B8_UNORM, 0,
2415                                2);
2416
2417     /* destination surface */
2418     obj_surface = (struct object_surface *)dst_surface->base;
2419     out_w = obj_surface->orig_width;
2420     out_h = obj_surface->orig_height;
2421     out_wpitch = obj_surface->width;
2422     out_hpitch = obj_surface->height;
2423     assert(out_w <= out_wpitch && out_h <= out_hpitch);
2424
2425     /* destination Y surface index 7 */
2426     i965_pp_set_surface_state(ctx, pp_context,
2427                               obj_surface->bo, 0,
2428                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2429                               7, 1);
2430
2431     /* destination UV surface index 8 */
2432     i965_pp_set_surface_state(ctx, pp_context,
2433                               obj_surface->bo, out_wpitch * out_hpitch,
2434                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2435                               8, 1);
2436
2437     /* sampler 8x8 state */
2438     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
2439     assert(pp_context->sampler_state_table.bo_8x8->virtual);
2440     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
2441     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
2442     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
2443
2444     for (i = 0; i < 17; i++) {
2445         /* for Y channel, currently ignore */
2446         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x00;
2447         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x00;
2448         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x08;
2449         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x18;
2450         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x18;
2451         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x08;
2452         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x00;
2453         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x00;
2454         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x00;
2455         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x00;
2456         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x10;
2457         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x10;
2458         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x10;
2459         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x10;
2460         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x00;
2461         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x00;
2462         /* for U/V channel, 0.25 */
2463         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
2464         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
2465         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
2466         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
2467         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
2468         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
2469         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
2470         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
2471         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
2472         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
2473         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
2474         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
2475         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
2476         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
2477         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
2478         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
2479     }
2480
2481     sampler_8x8_state->dw136.default_sharpness_level = 0;
2482     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
2483     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
2484     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
2485     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
2486
2487     /* sampler 8x8 */
2488     dri_bo_map(pp_context->sampler_state_table.bo, True);
2489     assert(pp_context->sampler_state_table.bo->virtual);
2490     assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
2491     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
2492
2493     /* sample_8x8 Y index 1 */
2494     index = 1;
2495     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2496     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
2497     sampler_8x8[index].dw0.ief_bypass = 1;
2498     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
2499     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
2500     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2501     sampler_8x8[index].dw2.global_noise_estimation = 22;
2502     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2503     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2504     sampler_8x8[index].dw3.strong_edge_weight = 7;
2505     sampler_8x8[index].dw3.regular_weight = 2;
2506     sampler_8x8[index].dw3.non_edge_weight = 0;
2507     sampler_8x8[index].dw3.gain_factor = 40;
2508     sampler_8x8[index].dw4.steepness_boost = 0;
2509     sampler_8x8[index].dw4.steepness_threshold = 0;
2510     sampler_8x8[index].dw4.mr_boost = 0;
2511     sampler_8x8[index].dw4.mr_threshold = 5;
2512     sampler_8x8[index].dw5.pwl1_point_1 = 4;
2513     sampler_8x8[index].dw5.pwl1_point_2 = 12;
2514     sampler_8x8[index].dw5.pwl1_point_3 = 16;
2515     sampler_8x8[index].dw5.pwl1_point_4 = 26;
2516     sampler_8x8[index].dw6.pwl1_point_5 = 40;
2517     sampler_8x8[index].dw6.pwl1_point_6 = 160;
2518     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
2519     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
2520     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
2521     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
2522     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
2523     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
2524     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
2525     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
2526     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
2527     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
2528     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
2529     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
2530     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
2531     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
2532     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
2533     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
2534     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
2535     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
2536     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
2537     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
2538     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
2539     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
2540     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
2541     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
2542     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
2543     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
2544     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
2545     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
2546     sampler_8x8[index].dw13.limiter_boost = 0;
2547     sampler_8x8[index].dw13.minimum_limiter = 10;
2548     sampler_8x8[index].dw13.maximum_limiter = 11;
2549     sampler_8x8[index].dw14.clip_limiter = 130;
2550     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2551                       I915_GEM_DOMAIN_RENDER, 
2552                       0,
2553                       0,
2554                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2555                       pp_context->sampler_state_table.bo_8x8);
2556
2557     /* sample_8x8 UV index 2 */
2558     index = 2;
2559     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2560     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
2561     sampler_8x8[index].dw0.ief_bypass = 1;
2562     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
2563     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
2564     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2565     sampler_8x8[index].dw2.global_noise_estimation = 22;
2566     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2567     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2568     sampler_8x8[index].dw3.strong_edge_weight = 7;
2569     sampler_8x8[index].dw3.regular_weight = 2;
2570     sampler_8x8[index].dw3.non_edge_weight = 0;
2571     sampler_8x8[index].dw3.gain_factor = 40;
2572     sampler_8x8[index].dw4.steepness_boost = 0;
2573     sampler_8x8[index].dw4.steepness_threshold = 0;
2574     sampler_8x8[index].dw4.mr_boost = 0;
2575     sampler_8x8[index].dw4.mr_threshold = 5;
2576     sampler_8x8[index].dw5.pwl1_point_1 = 4;
2577     sampler_8x8[index].dw5.pwl1_point_2 = 12;
2578     sampler_8x8[index].dw5.pwl1_point_3 = 16;
2579     sampler_8x8[index].dw5.pwl1_point_4 = 26;
2580     sampler_8x8[index].dw6.pwl1_point_5 = 40;
2581     sampler_8x8[index].dw6.pwl1_point_6 = 160;
2582     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
2583     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
2584     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
2585     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
2586     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
2587     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
2588     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
2589     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
2590     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
2591     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
2592     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
2593     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
2594     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
2595     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
2596     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
2597     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
2598     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
2599     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
2600     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
2601     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
2602     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
2603     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
2604     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
2605     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
2606     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
2607     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
2608     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
2609     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
2610     sampler_8x8[index].dw13.limiter_boost = 0;
2611     sampler_8x8[index].dw13.minimum_limiter = 10;
2612     sampler_8x8[index].dw13.maximum_limiter = 11;
2613     sampler_8x8[index].dw14.clip_limiter = 130;
2614     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2615                       I915_GEM_DOMAIN_RENDER, 
2616                       0,
2617                       0,
2618                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2619                       pp_context->sampler_state_table.bo_8x8);
2620
2621     dri_bo_unmap(pp_context->sampler_state_table.bo);
2622
2623     /* private function & data */
2624     pp_context->pp_x_steps = pp_avs_x_steps;
2625     pp_context->pp_y_steps = pp_avs_y_steps;
2626     pp_context->private_context = &pp_context->pp_avs_context;
2627     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
2628
2629     int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
2630     float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
2631     pp_avs_context->dest_x = dst_rect->x - dst_left_edge_extend;
2632     pp_avs_context->dest_y = dst_rect->y;
2633     pp_avs_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
2634     pp_avs_context->dest_h = ALIGN(dst_rect->height, 8);
2635     pp_avs_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
2636     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h;
2637     pp_avs_context->src_w = src_rect->width + src_left_edge_extend;
2638     pp_avs_context->src_h = src_rect->height;
2639
2640     pp_static_parameter->grf4.r4_2.avs.nlas = nlas;
2641     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
2642
2643     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) (src_rect->width + src_left_edge_extend)/ in_w / (dst_rect->width + dst_left_edge_extend);
2644     pp_inline_parameter->grf5.block_count_x = 1;        /* M x 1 */
2645     pp_inline_parameter->grf5.number_blocks = pp_avs_context->dest_h / 8;
2646     pp_inline_parameter->grf6.video_step_delta = 0.0;
2647
2648     dst_surface->flags = src_surface->flags;
2649
2650     return VA_STATUS_SUCCESS;
2651 }
2652
2653 static VAStatus
2654 pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2655                             const struct i965_surface *src_surface,
2656                             const VARectangle *src_rect,
2657                             struct i965_surface *dst_surface,
2658                             const VARectangle *dst_rect,
2659                             void *filter_param)
2660 {
2661     return pp_nv12_avs_initialize(ctx, pp_context,
2662                                   src_surface,
2663                                   src_rect,
2664                                   dst_surface,
2665                                   dst_rect,
2666                                   filter_param,
2667                                   1);
2668 }
2669
2670 static VAStatus
2671 gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2672                              const struct i965_surface *src_surface,
2673                              const VARectangle *src_rect,
2674                              struct i965_surface *dst_surface,
2675                              const VARectangle *dst_rect,
2676                              void *filter_param)
2677 {
2678     return pp_nv12_avs_initialize(ctx, pp_context,
2679                                   src_surface,
2680                                   src_rect,
2681                                   dst_surface,
2682                                   dst_rect,
2683                                   filter_param,
2684                                   0);    
2685 }
2686
2687 static int
2688 gen7_pp_avs_x_steps(void *private_context)
2689 {
2690     struct pp_avs_context *pp_avs_context = private_context;
2691
2692     return pp_avs_context->dest_w / 16;
2693 }
2694
2695 static int
2696 gen7_pp_avs_y_steps(void *private_context)
2697 {
2698     struct pp_avs_context *pp_avs_context = private_context;
2699
2700     return pp_avs_context->dest_h / 16;
2701 }
2702
2703 static int
2704 gen7_pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2705 {
2706     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)pp_context->private_context;
2707     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2708
2709     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
2710     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 16 + pp_avs_context->dest_y;
2711     pp_inline_parameter->grf7.constant_0 = 0xffffffff;
2712     pp_inline_parameter->grf7.sampler_load_main_video_x_scaling_step = pp_avs_context->horiz_range / pp_avs_context->src_w;
2713
2714     return 0;
2715 }
2716
2717 static void gen7_update_src_surface_uv_offset(VADriverContextP    ctx, 
2718                                               struct i965_post_processing_context *pp_context,
2719                                               const struct i965_surface *surface)
2720 {
2721     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2722     int fourcc = pp_get_surface_fourcc(ctx, surface);
2723     
2724     if (fourcc == VA_FOURCC_YUY2) {
2725         pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
2726         pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
2727         pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
2728     } else if (fourcc == VA_FOURCC_UYVY) {
2729         pp_static_parameter->grf2.di_destination_packed_y_component_offset = 1;
2730         pp_static_parameter->grf2.di_destination_packed_u_component_offset = 0;
2731         pp_static_parameter->grf2.di_destination_packed_v_component_offset = 2;
2732     }
2733 }
2734
2735 static VAStatus
2736 gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2737                            const struct i965_surface *src_surface,
2738                            const VARectangle *src_rect,
2739                            struct i965_surface *dst_surface,
2740                            const VARectangle *dst_rect,
2741                            void *filter_param)
2742 {
2743     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->pp_avs_context;
2744     struct i965_driver_data *i965 = i965_driver_data(ctx);
2745     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2746     struct gen7_sampler_8x8 *sampler_8x8;
2747     struct i965_sampler_8x8_state *sampler_8x8_state;
2748     int index, i;
2749     int width[3], height[3], pitch[3], offset[3];
2750     int src_width, src_height;
2751
2752     /* source surface */
2753     gen7_pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 0, 0,
2754                                          src_rect,
2755                                          width, height, pitch, offset);
2756     src_width = width[0];
2757     src_height = height[0];
2758
2759     /* destination surface */
2760     gen7_pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 24, 1,
2761                                          dst_rect,
2762                                          width, height, pitch, offset);
2763
2764     /* sampler 8x8 state */
2765     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
2766     assert(pp_context->sampler_state_table.bo_8x8->virtual);
2767     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
2768     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
2769     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
2770
2771     for (i = 0; i < 17; i++) {
2772         float coff;
2773         coff = i;
2774         coff = coff / 16;
2775         /* for Y channel, currently ignore */
2776         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x0;
2777         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x0;
2778         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x0;
2779         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = intel_format_convert(1 - coff, 1, 6,0);
2780         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = intel_format_convert(coff, 1, 6, 0);
2781         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x0;
2782         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x0;
2783         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x0;
2784         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x0;
2785         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x0;
2786         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x0;
2787         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = intel_format_convert(1 - coff, 1, 6, 0);
2788         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = intel_format_convert(coff, 1, 6, 0);
2789         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x0;
2790         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x0;
2791         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x0;
2792         /* for U/V channel, 0.25 */
2793         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
2794         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
2795         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x0;
2796         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = intel_format_convert(1 - coff, 1, 6, 0);
2797         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = intel_format_convert(coff, 1, 6, 0);
2798         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0;
2799         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
2800         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
2801         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
2802         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
2803         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x0;
2804         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = intel_format_convert(1 - coff, 1, 6, 0);
2805         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = intel_format_convert(coff, 1, 6, 0);
2806         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x0;
2807         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
2808         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
2809     }
2810
2811     sampler_8x8_state->dw136.default_sharpness_level = 0;
2812     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
2813     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
2814     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
2815     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
2816
2817     /* sampler 8x8 */
2818     dri_bo_map(pp_context->sampler_state_table.bo, True);
2819     assert(pp_context->sampler_state_table.bo->virtual);
2820     assert(sizeof(*sampler_8x8) == sizeof(int) * 4);
2821     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
2822
2823     /* sample_8x8 Y index 4 */
2824     index = 4;
2825     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2826     sampler_8x8[index].dw0.global_noise_estimation = 255;
2827     sampler_8x8[index].dw0.ief_bypass = 1;
2828
2829     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2830
2831     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2832     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2833     sampler_8x8[index].dw2.r5x_coefficient = 9;
2834     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2835     sampler_8x8[index].dw2.r5c_coefficient = 3;
2836
2837     sampler_8x8[index].dw3.r3x_coefficient = 27;
2838     sampler_8x8[index].dw3.r3c_coefficient = 5;
2839     sampler_8x8[index].dw3.gain_factor = 40;
2840     sampler_8x8[index].dw3.non_edge_weight = 1;
2841     sampler_8x8[index].dw3.regular_weight = 2;
2842     sampler_8x8[index].dw3.strong_edge_weight = 7;
2843     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2844
2845     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2846                       I915_GEM_DOMAIN_RENDER, 
2847                       0,
2848                       0,
2849                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2850                       pp_context->sampler_state_table.bo_8x8);
2851
2852     /* sample_8x8 UV index 8 */
2853     index = 8;
2854     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2855     sampler_8x8[index].dw0.disable_8x8_filter = 0;
2856     sampler_8x8[index].dw0.global_noise_estimation = 255;
2857     sampler_8x8[index].dw0.ief_bypass = 1;
2858     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2859     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2860     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2861     sampler_8x8[index].dw2.r5x_coefficient = 9;
2862     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2863     sampler_8x8[index].dw2.r5c_coefficient = 3;
2864     sampler_8x8[index].dw3.r3x_coefficient = 27;
2865     sampler_8x8[index].dw3.r3c_coefficient = 5;
2866     sampler_8x8[index].dw3.gain_factor = 40;
2867     sampler_8x8[index].dw3.non_edge_weight = 1;
2868     sampler_8x8[index].dw3.regular_weight = 2;
2869     sampler_8x8[index].dw3.strong_edge_weight = 7;
2870     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2871
2872     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2873                       I915_GEM_DOMAIN_RENDER, 
2874                       0,
2875                       0,
2876                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2877                       pp_context->sampler_state_table.bo_8x8);
2878
2879     /* sampler_8x8 V, index 12 */
2880     index = 12;
2881     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2882     sampler_8x8[index].dw0.disable_8x8_filter = 0;
2883     sampler_8x8[index].dw0.global_noise_estimation = 255;
2884     sampler_8x8[index].dw0.ief_bypass = 1;
2885     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2886     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2887     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2888     sampler_8x8[index].dw2.r5x_coefficient = 9;
2889     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2890     sampler_8x8[index].dw2.r5c_coefficient = 3;
2891     sampler_8x8[index].dw3.r3x_coefficient = 27;
2892     sampler_8x8[index].dw3.r3c_coefficient = 5;
2893     sampler_8x8[index].dw3.gain_factor = 40;
2894     sampler_8x8[index].dw3.non_edge_weight = 1;
2895     sampler_8x8[index].dw3.regular_weight = 2;
2896     sampler_8x8[index].dw3.strong_edge_weight = 7;
2897     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2898
2899     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2900                       I915_GEM_DOMAIN_RENDER, 
2901                       0,
2902                       0,
2903                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2904                       pp_context->sampler_state_table.bo_8x8);
2905
2906     dri_bo_unmap(pp_context->sampler_state_table.bo);
2907
2908     /* private function & data */
2909     pp_context->pp_x_steps = gen7_pp_avs_x_steps;
2910     pp_context->pp_y_steps = gen7_pp_avs_y_steps;
2911     pp_context->private_context = &pp_context->pp_avs_context;
2912     pp_context->pp_set_block_parameter = gen7_pp_avs_set_block_parameter;
2913
2914     pp_avs_context->dest_x = dst_rect->x;
2915     pp_avs_context->dest_y = dst_rect->y;
2916     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
2917     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
2918     pp_avs_context->src_w = src_rect->width;
2919     pp_avs_context->src_h = src_rect->height;
2920     pp_avs_context->horiz_range = (float)src_rect->width / src_width;
2921
2922     int dw = (pp_avs_context->src_w - 1) / 16 + 1;
2923     dw = MAX(dw, dst_rect->width);
2924
2925     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
2926     pp_static_parameter->grf2.avs_wa_enable = 1; /* must be set for GEN7 */
2927     if (IS_HASWELL(i965->intel.device_info))
2928         pp_static_parameter->grf2.avs_wa_enable = 0; /* HSW don't use the WA */
2929
2930     if (pp_static_parameter->grf2.avs_wa_enable) {
2931         int src_fourcc = pp_get_surface_fourcc(ctx, src_surface);
2932         if ((src_fourcc == VA_FOURCC_RGBA) ||
2933             (src_fourcc == VA_FOURCC_RGBX) ||
2934             (src_fourcc == VA_FOURCC_BGRA) ||
2935             (src_fourcc == VA_FOURCC_BGRX)) {
2936             pp_static_parameter->grf2.avs_wa_enable = 0;
2937         }
2938     }
2939         
2940     pp_static_parameter->grf2.avs_wa_width = src_width;
2941     pp_static_parameter->grf2.avs_wa_one_div_256_width = (float) 1.0 / (256 * src_width);
2942     pp_static_parameter->grf2.avs_wa_five_div_256_width = (float) 5.0 / (256 * src_width);
2943     pp_static_parameter->grf2.alpha = 255;
2944
2945     pp_static_parameter->grf3.sampler_load_horizontal_scaling_step_ratio = (float) pp_avs_context->src_w / dw;
2946     pp_static_parameter->grf4.sampler_load_vertical_scaling_step = (float) src_rect->height / src_height / dst_rect->height;
2947     pp_static_parameter->grf5.sampler_load_vertical_frame_origin = (float) src_rect->y / src_height -
2948         (float) pp_avs_context->dest_y * pp_static_parameter->grf4.sampler_load_vertical_scaling_step;
2949     pp_static_parameter->grf6.sampler_load_horizontal_frame_origin = (float) src_rect->x / src_width -
2950         (float) pp_avs_context->dest_x * pp_avs_context->horiz_range / dw;
2951
2952     gen7_update_src_surface_uv_offset(ctx, pp_context, dst_surface);
2953
2954     dst_surface->flags = src_surface->flags;
2955
2956     return VA_STATUS_SUCCESS;
2957 }
2958
2959 static int
2960 pp_dndi_x_steps(void *private_context)
2961 {
2962     return 1;
2963 }
2964
2965 static int
2966 pp_dndi_y_steps(void *private_context)
2967 {
2968     struct pp_dndi_context *pp_dndi_context = private_context;
2969
2970     return pp_dndi_context->dest_h / 4;
2971 }
2972
2973 static int
2974 pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2975 {
2976     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2977
2978     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2979     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
2980
2981     return 0;
2982 }
2983
2984 static VAStatus
2985 pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2986                         const struct i965_surface *src_surface,
2987                         const VARectangle *src_rect,
2988                         struct i965_surface *dst_surface,
2989                         const VARectangle *dst_rect,
2990                         void *filter_param)
2991 {
2992     struct i965_driver_data *i965 = i965_driver_data(ctx);
2993     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->pp_dndi_context;
2994     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2995     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2996     struct object_surface *previous_in_obj_surface, *current_in_obj_surface, *previous_out_obj_surface, *current_out_obj_surface;
2997     struct i965_sampler_dndi *sampler_dndi;
2998     int index;
2999     int w, h;
3000     int orig_w, orig_h;
3001     int dndi_top_first = 1;
3002     VAProcFilterParameterBufferDeinterlacing *di_filter_param = (VAProcFilterParameterBufferDeinterlacing *)filter_param;
3003     int is_first_frame = (pp_dndi_context->frame_order == -1);
3004
3005     if (di_filter_param->flags & VA_DEINTERLACING_BOTTOM_FIELD)
3006         dndi_top_first = 0;
3007     else
3008         dndi_top_first = 1;
3009
3010     /* surface */
3011     current_in_obj_surface = (struct object_surface *)src_surface->base;
3012
3013     if (di_filter_param->algorithm == VAProcDeinterlacingBob) {
3014         previous_in_obj_surface = current_in_obj_surface;
3015         is_first_frame = 1;
3016     } else if (di_filter_param->algorithm == VAProcDeinterlacingMotionAdaptive) {
3017         if (pp_dndi_context->frame_order == 0) {
3018             VAProcPipelineParameterBuffer *pipeline_param = pp_context->pipeline_param;
3019             if (!pipeline_param ||
3020                 !pipeline_param->num_forward_references ||
3021                 pipeline_param->forward_references[0] == VA_INVALID_ID) {
3022                 WARN_ONCE("A forward temporal reference is needed for Motion adaptive deinterlacing !!!\n");
3023
3024                 return VA_STATUS_ERROR_INVALID_PARAMETER;
3025             } else {
3026                 previous_in_obj_surface = SURFACE(pipeline_param->forward_references[0]);
3027                 assert(previous_in_obj_surface && previous_in_obj_surface->bo);
3028
3029                 is_first_frame = 0;
3030             }
3031         } else if (pp_dndi_context->frame_order == 1) {
3032             vpp_surface_convert(ctx,
3033                                 pp_dndi_context->current_out_obj_surface,
3034                                 (struct object_surface *)dst_surface->base);
3035             pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3036             is_first_frame = 0;
3037
3038             return VA_STATUS_SUCCESS_1;
3039         } else {
3040             previous_in_obj_surface = current_in_obj_surface;
3041             is_first_frame = 1;
3042         }
3043     } else {
3044         return VA_STATUS_ERROR_UNIMPLEMENTED;
3045     }
3046
3047     /* source (temporal reference) YUV surface index 5 */
3048     orig_w = previous_in_obj_surface->orig_width;
3049     orig_h = previous_in_obj_surface->orig_height;
3050     w = previous_in_obj_surface->width;
3051     h = previous_in_obj_surface->height;
3052     i965_pp_set_surface2_state(ctx, pp_context,
3053                                previous_in_obj_surface->bo, 0,
3054                                orig_w, orig_h, w,
3055                                0, h,
3056                                SURFACE_FORMAT_PLANAR_420_8, 1,
3057                                5);
3058
3059     /* source surface */
3060     orig_w = current_in_obj_surface->orig_width;
3061     orig_h = current_in_obj_surface->orig_height;
3062     w = current_in_obj_surface->width;
3063     h = current_in_obj_surface->height;
3064
3065     /* source UV surface index 2 */
3066     i965_pp_set_surface_state(ctx, pp_context,
3067                               current_in_obj_surface->bo, w * h,
3068                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3069                               2, 0);
3070
3071     /* source YUV surface index 4 */
3072     i965_pp_set_surface2_state(ctx, pp_context,
3073                                current_in_obj_surface->bo, 0,
3074                                orig_w, orig_h, w,
3075                                0, h,
3076                                SURFACE_FORMAT_PLANAR_420_8, 1,
3077                                4);
3078
3079     /* source STMM surface index 6 */
3080     if (pp_dndi_context->stmm_bo == NULL) {
3081         pp_dndi_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr,
3082                                                 "STMM surface",
3083                                                 w * h,
3084                                                 4096);
3085         assert(pp_dndi_context->stmm_bo);
3086     }
3087
3088     i965_pp_set_surface_state(ctx, pp_context,
3089                               pp_dndi_context->stmm_bo, 0,
3090                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3091                               6, 0);
3092
3093     /* destination (Previous frame) */
3094     previous_out_obj_surface = (struct object_surface *)dst_surface->base;
3095     orig_w = previous_out_obj_surface->orig_width;
3096     orig_h = previous_out_obj_surface->orig_height;
3097     w = previous_out_obj_surface->width;
3098     h = previous_out_obj_surface->height;
3099
3100     if (is_first_frame) {
3101         current_out_obj_surface = previous_out_obj_surface;
3102     } else {
3103         VAStatus va_status;
3104
3105         if (pp_dndi_context->current_out_surface == VA_INVALID_SURFACE) {
3106             unsigned int tiling = 0, swizzle = 0;
3107             dri_bo_get_tiling(previous_out_obj_surface->bo, &tiling, &swizzle);
3108
3109             va_status = i965_CreateSurfaces(ctx,
3110                                             orig_w,
3111                                             orig_h,
3112                                             VA_RT_FORMAT_YUV420,
3113                                             1,
3114                                             &pp_dndi_context->current_out_surface);
3115             assert(va_status == VA_STATUS_SUCCESS);
3116             pp_dndi_context->current_out_obj_surface = SURFACE(pp_dndi_context->current_out_surface);
3117             assert(pp_dndi_context->current_out_obj_surface);
3118             i965_check_alloc_surface_bo(ctx,
3119                                         pp_dndi_context->current_out_obj_surface,
3120                                         tiling != I915_TILING_NONE,
3121                                         VA_FOURCC_NV12,
3122                                         SUBSAMPLE_YUV420);
3123         }
3124
3125         current_out_obj_surface = pp_dndi_context->current_out_obj_surface;
3126     }
3127
3128     /* destination (Previous frame) Y surface index 7 */
3129     i965_pp_set_surface_state(ctx, pp_context,
3130                               previous_out_obj_surface->bo, 0,
3131                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3132                               7, 1);
3133
3134     /* destination (Previous frame) UV surface index 8 */
3135     i965_pp_set_surface_state(ctx, pp_context,
3136                               previous_out_obj_surface->bo, w * h,
3137                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3138                               8, 1);
3139
3140     /* destination(Current frame) */
3141     orig_w = current_out_obj_surface->orig_width;
3142     orig_h = current_out_obj_surface->orig_height;
3143     w = current_out_obj_surface->width;
3144     h = current_out_obj_surface->height;
3145
3146     /* destination (Current frame) Y surface index xxx */
3147     i965_pp_set_surface_state(ctx, pp_context,
3148                               current_out_obj_surface->bo, 0,
3149                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3150                               10, 1);
3151
3152     /* destination (Current frame) UV surface index xxx */
3153     i965_pp_set_surface_state(ctx, pp_context,
3154                               current_out_obj_surface->bo, w * h,
3155                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3156                               11, 1);
3157
3158     /* STMM output surface, index 20 */
3159     i965_pp_set_surface_state(ctx, pp_context,
3160                               pp_dndi_context->stmm_bo, 0,
3161                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3162                               20, 1);
3163
3164     /* sampler dndi */
3165     dri_bo_map(pp_context->sampler_state_table.bo, True);
3166     assert(pp_context->sampler_state_table.bo->virtual);
3167     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3168     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3169
3170     /* sample dndi index 1 */
3171     index = 0;
3172     sampler_dndi[index].dw0.denoise_asd_threshold = 38;
3173     sampler_dndi[index].dw0.denoise_history_delta = 7;          // 0-15, default is 8
3174     sampler_dndi[index].dw0.denoise_maximum_history = 192;      // 128-240
3175     sampler_dndi[index].dw0.denoise_stad_threshold = 140;
3176
3177     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 38;
3178     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 1;
3179     sampler_dndi[index].dw1.stmm_c2 = 1;
3180     sampler_dndi[index].dw1.low_temporal_difference_threshold = 0;
3181     sampler_dndi[index].dw1.temporal_difference_threshold = 0;
3182
3183     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 20;   // 0-31
3184     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 1;    // 0-15
3185     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
3186     sampler_dndi[index].dw2.good_neighbor_threshold = 12;                // 0-63
3187
3188     sampler_dndi[index].dw3.maximum_stmm = 150;
3189     sampler_dndi[index].dw3.multipler_for_vecm = 30;
3190     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 125;
3191     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3192     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3193
3194     sampler_dndi[index].dw4.sdi_delta = 5;
3195     sampler_dndi[index].dw4.sdi_threshold = 100;
3196     sampler_dndi[index].dw4.stmm_output_shift = 5;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
3197     sampler_dndi[index].dw4.stmm_shift_up = 1;
3198     sampler_dndi[index].dw4.stmm_shift_down = 0;
3199     sampler_dndi[index].dw4.minimum_stmm = 118;
3200
3201     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 175;
3202     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 37;
3203     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 100;
3204     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 50;
3205
3206     sampler_dndi[index].dw6.dn_enable = 1;
3207     sampler_dndi[index].dw6.di_enable = 1;
3208     sampler_dndi[index].dw6.di_partial = 0;
3209     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3210     sampler_dndi[index].dw6.dndi_stream_id = 0;
3211     sampler_dndi[index].dw6.dndi_first_frame = is_first_frame;
3212     sampler_dndi[index].dw6.progressive_dn = 0;
3213     sampler_dndi[index].dw6.fmd_tear_threshold = 2;
3214     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100;
3215     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 16;
3216
3217     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
3218     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
3219     sampler_dndi[index].dw7.vdi_walker_enable = 0;
3220     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3221
3222     dri_bo_unmap(pp_context->sampler_state_table.bo);
3223
3224     /* private function & data */
3225     pp_context->pp_x_steps = pp_dndi_x_steps;
3226     pp_context->pp_y_steps = pp_dndi_y_steps;
3227     pp_context->private_context = &pp_context->pp_dndi_context;
3228     pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
3229
3230     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
3231     pp_static_parameter->grf1.r1_6.di.top_field_first = dndi_top_first;
3232     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 0;
3233     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 0;
3234
3235     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
3236     pp_inline_parameter->grf5.number_blocks = w / 16;
3237     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
3238     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
3239
3240     pp_dndi_context->dest_w = w;
3241     pp_dndi_context->dest_h = h;
3242
3243     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3244
3245     pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3246
3247     return VA_STATUS_SUCCESS;
3248 }
3249
3250 static int
3251 pp_dn_x_steps(void *private_context)
3252 {
3253     return 1;
3254 }
3255
3256 static int
3257 pp_dn_y_steps(void *private_context)
3258 {
3259     struct pp_dn_context *pp_dn_context = private_context;
3260
3261     return pp_dn_context->dest_h / 8;
3262 }
3263
3264 static int
3265 pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3266 {
3267     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3268
3269     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
3270     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
3271
3272     return 0;
3273 }
3274
3275 static VAStatus
3276 pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3277                       const struct i965_surface *src_surface,
3278                       const VARectangle *src_rect,
3279                       struct i965_surface *dst_surface,
3280                       const VARectangle *dst_rect,
3281                       void *filter_param)
3282 {
3283     struct i965_driver_data *i965 = i965_driver_data(ctx);
3284     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->pp_dn_context;
3285     struct object_surface *obj_surface;
3286     struct i965_sampler_dndi *sampler_dndi;
3287     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3288     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3289     VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
3290     int index;
3291     int w, h;
3292     int orig_w, orig_h;
3293     int dn_strength = 15;
3294     int dndi_top_first = 1;
3295     int dn_progressive = 0;
3296
3297     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
3298         dndi_top_first = 1;
3299         dn_progressive = 1;
3300     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
3301         dndi_top_first = 1;
3302         dn_progressive = 0;
3303     } else {
3304         dndi_top_first = 0;
3305         dn_progressive = 0;
3306     }
3307
3308     if (dn_filter_param) {
3309         float value = dn_filter_param->value;
3310         
3311         if (value > 1.0)
3312             value = 1.0;
3313         
3314         if (value < 0.0)
3315             value = 0.0;
3316
3317         dn_strength = (int)(value * 31.0F);
3318     }
3319
3320     /* surface */
3321     obj_surface = (struct object_surface *)src_surface->base;
3322     orig_w = obj_surface->orig_width;
3323     orig_h = obj_surface->orig_height;
3324     w = obj_surface->width;
3325     h = obj_surface->height;
3326
3327     if (pp_dn_context->stmm_bo == NULL) {
3328         pp_dn_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr,
3329                                               "STMM surface",
3330                                               w * h,
3331                                               4096);
3332         assert(pp_dn_context->stmm_bo);
3333     }
3334
3335     /* source UV surface index 2 */
3336     i965_pp_set_surface_state(ctx, pp_context,
3337                               obj_surface->bo, w * h,
3338                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3339                               2, 0);
3340
3341     /* source YUV surface index 4 */
3342     i965_pp_set_surface2_state(ctx, pp_context,
3343                                obj_surface->bo, 0,
3344                                orig_w, orig_h, w,
3345                                0, h,
3346                                SURFACE_FORMAT_PLANAR_420_8, 1,
3347                                4);
3348
3349     /* source STMM surface index 20 */
3350     i965_pp_set_surface_state(ctx, pp_context,
3351                               pp_dn_context->stmm_bo, 0,
3352                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3353                               20, 1);
3354
3355     /* destination surface */
3356     obj_surface = (struct object_surface *)dst_surface->base;
3357     orig_w = obj_surface->orig_width;
3358     orig_h = obj_surface->orig_height;
3359     w = obj_surface->width;
3360     h = obj_surface->height;
3361
3362     /* destination Y surface index 7 */
3363     i965_pp_set_surface_state(ctx, pp_context,
3364                               obj_surface->bo, 0,
3365                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3366                               7, 1);
3367
3368     /* destination UV surface index 8 */
3369     i965_pp_set_surface_state(ctx, pp_context,
3370                               obj_surface->bo, w * h,
3371                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3372                               8, 1);
3373     /* sampler dn */
3374     dri_bo_map(pp_context->sampler_state_table.bo, True);
3375     assert(pp_context->sampler_state_table.bo->virtual);
3376     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3377     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3378
3379     /* sample dndi index 1 */
3380     index = 0;
3381     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
3382     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
3383     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
3384     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
3385
3386     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
3387     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
3388     sampler_dndi[index].dw1.stmm_c2 = 0;
3389     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
3390     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
3391
3392     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
3393     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
3394     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
3395     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
3396
3397     sampler_dndi[index].dw3.maximum_stmm = 128;
3398     sampler_dndi[index].dw3.multipler_for_vecm = 2;
3399     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
3400     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3401     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3402
3403     sampler_dndi[index].dw4.sdi_delta = 8;
3404     sampler_dndi[index].dw4.sdi_threshold = 128;
3405     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
3406     sampler_dndi[index].dw4.stmm_shift_up = 0;
3407     sampler_dndi[index].dw4.stmm_shift_down = 0;
3408     sampler_dndi[index].dw4.minimum_stmm = 0;
3409
3410     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
3411     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
3412     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
3413     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
3414
3415     sampler_dndi[index].dw6.dn_enable = 1;
3416     sampler_dndi[index].dw6.di_enable = 0;
3417     sampler_dndi[index].dw6.di_partial = 0;
3418     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3419     sampler_dndi[index].dw6.dndi_stream_id = 1;
3420     sampler_dndi[index].dw6.dndi_first_frame = 1;
3421     sampler_dndi[index].dw6.progressive_dn = dn_progressive;
3422     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
3423     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
3424     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
3425
3426     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
3427     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
3428     sampler_dndi[index].dw7.vdi_walker_enable = 0;
3429     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3430
3431     dri_bo_unmap(pp_context->sampler_state_table.bo);
3432
3433     /* private function & data */
3434     pp_context->pp_x_steps = pp_dn_x_steps;
3435     pp_context->pp_y_steps = pp_dn_y_steps;
3436     pp_context->private_context = &pp_context->pp_dn_context;
3437     pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
3438
3439     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
3440     pp_static_parameter->grf1.r1_6.di.top_field_first = 0;
3441     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 64;
3442     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 192;
3443
3444     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
3445     pp_inline_parameter->grf5.number_blocks = w / 16;
3446     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
3447     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
3448
3449     pp_dn_context->dest_w = w;
3450     pp_dn_context->dest_h = h;
3451
3452     dst_surface->flags = src_surface->flags;
3453     
3454     return VA_STATUS_SUCCESS;
3455 }
3456
3457 static int
3458 gen7_pp_dndi_x_steps(void *private_context)
3459 {
3460     struct pp_dndi_context *pp_dndi_context = private_context;
3461
3462     return pp_dndi_context->dest_w / 16;
3463 }
3464
3465 static int
3466 gen7_pp_dndi_y_steps(void *private_context)
3467 {
3468     struct pp_dndi_context *pp_dndi_context = private_context;
3469
3470     return pp_dndi_context->dest_h / 4;
3471 }
3472
3473 static int
3474 gen7_pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3475 {
3476     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3477
3478     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16;
3479     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 4;
3480
3481     return 0;
3482 }
3483
3484 static VAStatus
3485 gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3486                              const struct i965_surface *src_surface,
3487                              const VARectangle *src_rect,
3488                              struct i965_surface *dst_surface,
3489                              const VARectangle *dst_rect,
3490                              void *filter_param)
3491 {
3492     struct i965_driver_data *i965 = i965_driver_data(ctx);
3493     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->pp_dndi_context;
3494     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3495     struct object_surface *previous_in_obj_surface, *current_in_obj_surface, *previous_out_obj_surface, *current_out_obj_surface;
3496     struct gen7_sampler_dndi *sampler_dndi;
3497     int index;
3498     int w, h;
3499     int orig_w, orig_h;
3500     int dndi_top_first = 1;
3501     VAProcFilterParameterBufferDeinterlacing *di_filter_param = (VAProcFilterParameterBufferDeinterlacing *)filter_param;
3502     int is_first_frame = (pp_dndi_context->frame_order == -1);
3503
3504     if (di_filter_param->flags & VA_DEINTERLACING_BOTTOM_FIELD)
3505         dndi_top_first = 0;
3506     else
3507         dndi_top_first = 1;
3508
3509     /* surface */
3510     current_in_obj_surface = (struct object_surface *)src_surface->base;
3511
3512     if (di_filter_param->algorithm == VAProcDeinterlacingBob) {
3513         previous_in_obj_surface = current_in_obj_surface;
3514         is_first_frame = 1;
3515     } else if (di_filter_param->algorithm == VAProcDeinterlacingMotionAdaptive) {
3516         if (pp_dndi_context->frame_order == 0) {
3517             VAProcPipelineParameterBuffer *pipeline_param = pp_context->pipeline_param;
3518             if (!pipeline_param ||
3519                 !pipeline_param->num_forward_references ||
3520                 pipeline_param->forward_references[0] == VA_INVALID_ID) {
3521                 WARN_ONCE("A forward temporal reference is needed for Motion adaptive deinterlacing !!!\n");
3522
3523                 return VA_STATUS_ERROR_INVALID_PARAMETER;
3524             } else {
3525                 previous_in_obj_surface = SURFACE(pipeline_param->forward_references[0]);
3526                 assert(previous_in_obj_surface && previous_in_obj_surface->bo);
3527
3528                 is_first_frame = 0;
3529             }
3530         } else if (pp_dndi_context->frame_order == 1) {
3531             vpp_surface_convert(ctx,
3532                                 pp_dndi_context->current_out_obj_surface,
3533                                 (struct object_surface *)dst_surface->base);
3534             pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3535             is_first_frame = 0;
3536
3537             return VA_STATUS_SUCCESS_1;
3538         } else {
3539             previous_in_obj_surface = current_in_obj_surface;
3540             is_first_frame = 1;
3541         }
3542     } else {
3543         return VA_STATUS_ERROR_UNIMPLEMENTED;
3544     }
3545
3546     /* source (temporal reference) YUV surface index 4 */
3547     orig_w = previous_in_obj_surface->orig_width;
3548     orig_h = previous_in_obj_surface->orig_height;
3549     w = previous_in_obj_surface->width;
3550     h = previous_in_obj_surface->height;
3551     gen7_pp_set_surface2_state(ctx, pp_context,
3552                                previous_in_obj_surface->bo, 0,
3553                                orig_w, orig_h, w,
3554                                0, h,
3555                                SURFACE_FORMAT_PLANAR_420_8, 1,
3556                                4);
3557
3558     /* source surface */
3559     orig_w = current_in_obj_surface->orig_width;
3560     orig_h = current_in_obj_surface->orig_height;
3561     w = current_in_obj_surface->width;
3562     h = current_in_obj_surface->height;
3563
3564     /* source UV surface index 1 */
3565     gen7_pp_set_surface_state(ctx, pp_context,
3566                               current_in_obj_surface->bo, w * h,
3567                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3568                               1, 0);
3569
3570     /* source YUV surface index 3 */
3571     gen7_pp_set_surface2_state(ctx, pp_context,
3572                                current_in_obj_surface->bo, 0,
3573                                orig_w, orig_h, w,
3574                                0, h,
3575                                SURFACE_FORMAT_PLANAR_420_8, 1,
3576                                3);
3577
3578     /* STMM / History Statistics input surface, index 5 */
3579     if (pp_dndi_context->stmm_bo == NULL) {
3580         pp_dndi_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr,
3581                                                 "STMM surface",
3582                                                 w * h,
3583                                                 4096);
3584         assert(pp_dndi_context->stmm_bo);
3585     }
3586
3587     gen7_pp_set_surface_state(ctx, pp_context,
3588                               pp_dndi_context->stmm_bo, 0,
3589                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3590                               5, 1);
3591
3592     /* destination surface */
3593     previous_out_obj_surface = (struct object_surface *)dst_surface->base;
3594     orig_w = previous_out_obj_surface->orig_width;
3595     orig_h = previous_out_obj_surface->orig_height;
3596     w = previous_out_obj_surface->width;
3597     h = previous_out_obj_surface->height;
3598
3599     if (is_first_frame) {
3600         current_out_obj_surface = previous_out_obj_surface;
3601     } else {
3602         VAStatus va_status;
3603
3604         if (pp_dndi_context->current_out_surface == VA_INVALID_SURFACE) {
3605             unsigned int tiling = 0, swizzle = 0;
3606             dri_bo_get_tiling(previous_out_obj_surface->bo, &tiling, &swizzle);
3607
3608             va_status = i965_CreateSurfaces(ctx,
3609                                             orig_w,
3610                                             orig_h,
3611                                             VA_RT_FORMAT_YUV420,
3612                                             1,
3613                                             &pp_dndi_context->current_out_surface);
3614             assert(va_status == VA_STATUS_SUCCESS);
3615             pp_dndi_context->current_out_obj_surface = SURFACE(pp_dndi_context->current_out_surface);
3616             assert(pp_dndi_context->current_out_obj_surface);
3617             i965_check_alloc_surface_bo(ctx,
3618                                         pp_dndi_context->current_out_obj_surface,
3619                                         tiling != I915_TILING_NONE,
3620                                         VA_FOURCC_NV12,
3621                                         SUBSAMPLE_YUV420);
3622         }
3623
3624         current_out_obj_surface = pp_dndi_context->current_out_obj_surface;
3625     }
3626
3627     /* destination(Previous frame) Y surface index 27 */
3628     gen7_pp_set_surface_state(ctx, pp_context,
3629                               previous_out_obj_surface->bo, 0,
3630                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3631                               27, 1);
3632
3633     /* destination(Previous frame) UV surface index 28 */
3634     gen7_pp_set_surface_state(ctx, pp_context,
3635                               previous_out_obj_surface->bo, w * h,
3636                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3637                               28, 1);
3638
3639     /* destination(Current frame) Y surface index 30 */
3640     gen7_pp_set_surface_state(ctx, pp_context,
3641                               current_out_obj_surface->bo, 0,
3642                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3643                               30, 1);
3644
3645     /* destination(Current frame) UV surface index 31 */
3646     orig_w = current_out_obj_surface->orig_width;
3647     orig_h = current_out_obj_surface->orig_height;
3648     w = current_out_obj_surface->width;
3649     h = current_out_obj_surface->height;
3650
3651     gen7_pp_set_surface_state(ctx, pp_context,
3652                               current_out_obj_surface->bo, w * h,
3653                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3654                               31, 1);
3655
3656     /* STMM output surface, index 33 */
3657     gen7_pp_set_surface_state(ctx, pp_context,
3658                               pp_dndi_context->stmm_bo, 0,
3659                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3660                               33, 1);
3661
3662
3663     /* sampler dndi */
3664     dri_bo_map(pp_context->sampler_state_table.bo, True);
3665     assert(pp_context->sampler_state_table.bo->virtual);
3666     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3667     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3668
3669     /* sample dndi index 0 */
3670     index = 0;
3671     sampler_dndi[index].dw0.denoise_asd_threshold = 38;
3672     sampler_dndi[index].dw0.dnmh_delt = 7;
3673     sampler_dndi[index].dw0.vdi_walker_y_stride = 0;
3674     sampler_dndi[index].dw0.vdi_walker_frame_sharing_enable = 0;
3675     sampler_dndi[index].dw0.denoise_maximum_history = 192;      // 128-240
3676     sampler_dndi[index].dw0.denoise_stad_threshold = 140;
3677
3678     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 38;
3679     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 1;
3680     sampler_dndi[index].dw1.stmm_c2 = 2;
3681     sampler_dndi[index].dw1.low_temporal_difference_threshold = 0;
3682     sampler_dndi[index].dw1.temporal_difference_threshold = 0;
3683
3684     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 20;   // 0-31
3685     sampler_dndi[index].dw2.bne_edge_th = 1;
3686     sampler_dndi[index].dw2.smooth_mv_th = 0;
3687     sampler_dndi[index].dw2.sad_tight_th = 5;
3688     sampler_dndi[index].dw2.cat_slope_minus1 = 9;
3689     sampler_dndi[index].dw2.good_neighbor_th = 12;
3690
3691     sampler_dndi[index].dw3.maximum_stmm = 150;
3692     sampler_dndi[index].dw3.multipler_for_vecm = 30;
3693     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 125;
3694     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3695     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3696
3697     sampler_dndi[index].dw4.sdi_delta = 5;
3698     sampler_dndi[index].dw4.sdi_threshold = 100;
3699     sampler_dndi[index].dw4.stmm_output_shift = 5;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
3700     sampler_dndi[index].dw4.stmm_shift_up = 1;
3701     sampler_dndi[index].dw4.stmm_shift_down = 0;
3702     sampler_dndi[index].dw4.minimum_stmm = 118;
3703
3704     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 175;
3705     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 37;
3706     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 100;
3707     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 50;
3708     sampler_dndi[index].dw6.dn_enable = 0;
3709     sampler_dndi[index].dw6.di_enable = 1;
3710     sampler_dndi[index].dw6.di_partial = 0;
3711     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3712     sampler_dndi[index].dw6.dndi_stream_id = 1;
3713     sampler_dndi[index].dw6.dndi_first_frame = is_first_frame;
3714     sampler_dndi[index].dw6.progressive_dn = 0;
3715     sampler_dndi[index].dw6.mcdi_enable = 0;
3716     sampler_dndi[index].dw6.fmd_tear_threshold = 2;
3717     sampler_dndi[index].dw6.cat_th1 = 0;
3718     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100;
3719     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 16;
3720
3721     sampler_dndi[index].dw7.sad_tha = 5;
3722     sampler_dndi[index].dw7.sad_thb = 10;
3723     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
3724     sampler_dndi[index].dw7.mc_pixel_consistency_th = 25;
3725     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
3726     sampler_dndi[index].dw7.vdi_walker_enable = 0;
3727     sampler_dndi[index].dw7.neighborpixel_th = 10;
3728     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3729
3730     dri_bo_unmap(pp_context->sampler_state_table.bo);
3731
3732     /* private function & data */
3733     pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
3734     pp_context->pp_y_steps = gen7_pp_dndi_y_steps;
3735     pp_context->private_context = &pp_context->pp_dndi_context;
3736     pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
3737
3738     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
3739     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
3740     pp_static_parameter->grf1.di_top_field_first = 0;
3741     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
3742
3743     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
3744     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
3745     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
3746
3747     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
3748     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
3749
3750     pp_dndi_context->dest_w = w;
3751     pp_dndi_context->dest_h = h;
3752
3753     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3754
3755     pp_dndi_context->frame_order = (pp_dndi_context->frame_order + 1) % 2;
3756
3757     return VA_STATUS_SUCCESS;
3758 }
3759
3760 static int
3761 gen7_pp_dn_x_steps(void *private_context)
3762 {
3763     struct pp_dn_context *pp_dn_context = private_context;
3764
3765     return pp_dn_context->dest_w / 16;
3766 }
3767
3768 static int
3769 gen7_pp_dn_y_steps(void *private_context)
3770 {
3771     struct pp_dn_context *pp_dn_context = private_context;
3772
3773     return pp_dn_context->dest_h / 4;
3774 }
3775
3776 static int
3777 gen7_pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3778 {
3779     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3780
3781     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
3782     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
3783
3784     return 0;
3785 }
3786
3787 static VAStatus
3788 gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3789                            const struct i965_surface *src_surface,
3790                            const VARectangle *src_rect,
3791                            struct i965_surface *dst_surface,
3792                            const VARectangle *dst_rect,
3793                            void *filter_param)
3794 {
3795     struct i965_driver_data *i965 = i965_driver_data(ctx);
3796     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->pp_dn_context;
3797     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3798     struct object_surface *obj_surface;
3799     struct gen7_sampler_dndi *sampler_dn;
3800     VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
3801     int index;
3802     int w, h;
3803     int orig_w, orig_h;
3804     int dn_strength = 15;
3805     int dndi_top_first = 1;
3806     int dn_progressive = 0;
3807
3808     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
3809         dndi_top_first = 1;
3810         dn_progressive = 1;
3811     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
3812         dndi_top_first = 1;
3813         dn_progressive = 0;
3814     } else {
3815         dndi_top_first = 0;
3816         dn_progressive = 0;
3817     }
3818
3819     if (dn_filter_param) {
3820         float value = dn_filter_param->value;
3821         
3822         if (value > 1.0)
3823             value = 1.0;
3824         
3825         if (value < 0.0)
3826             value = 0.0;
3827
3828         dn_strength = (int)(value * 31.0F);
3829     }
3830
3831     /* surface */
3832     obj_surface = (struct object_surface *)src_surface->base;
3833     orig_w = obj_surface->orig_width;
3834     orig_h = obj_surface->orig_height;
3835     w = obj_surface->width;
3836     h = obj_surface->height;
3837
3838     if (pp_dn_context->stmm_bo == NULL) {
3839         pp_dn_context->stmm_bo= dri_bo_alloc(i965->intel.bufmgr,
3840                                              "STMM surface",
3841                                              w * h,
3842                                              4096);
3843         assert(pp_dn_context->stmm_bo);
3844     }
3845
3846     /* source UV surface index 1 */
3847     gen7_pp_set_surface_state(ctx, pp_context,
3848                               obj_surface->bo, w * h,
3849                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3850                               1, 0);
3851
3852     /* source YUV surface index 3 */
3853     gen7_pp_set_surface2_state(ctx, pp_context,
3854                                obj_surface->bo, 0,
3855                                orig_w, orig_h, w,
3856                                0, h,
3857                                SURFACE_FORMAT_PLANAR_420_8, 1,
3858                                3);
3859
3860     /* source (temporal reference) YUV surface index 4 */
3861     gen7_pp_set_surface2_state(ctx, pp_context,
3862                                obj_surface->bo, 0,
3863                                orig_w, orig_h, w,
3864                                0, h,
3865                                SURFACE_FORMAT_PLANAR_420_8, 1,
3866                                4);
3867
3868     /* STMM / History Statistics input surface, index 5 */
3869     gen7_pp_set_surface_state(ctx, pp_context,
3870                               pp_dn_context->stmm_bo, 0,
3871                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3872                               33, 1);
3873
3874     /* destination surface */
3875     obj_surface = (struct object_surface *)dst_surface->base;
3876     orig_w = obj_surface->orig_width;
3877     orig_h = obj_surface->orig_height;
3878     w = obj_surface->width;
3879     h = obj_surface->height;
3880
3881     /* destination Y surface index 24 */
3882     gen7_pp_set_surface_state(ctx, pp_context,
3883                               obj_surface->bo, 0,
3884                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3885                               24, 1);
3886
3887     /* destination UV surface index 25 */
3888     gen7_pp_set_surface_state(ctx, pp_context,
3889                               obj_surface->bo, w * h,
3890                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3891                               25, 1);
3892
3893     /* sampler dn */
3894     dri_bo_map(pp_context->sampler_state_table.bo, True);
3895     assert(pp_context->sampler_state_table.bo->virtual);
3896     assert(sizeof(*sampler_dn) == sizeof(int) * 8);
3897     sampler_dn = pp_context->sampler_state_table.bo->virtual;
3898
3899     /* sample dn index 1 */
3900     index = 0;
3901     sampler_dn[index].dw0.denoise_asd_threshold = 0;
3902     sampler_dn[index].dw0.dnmh_delt = 8;
3903     sampler_dn[index].dw0.vdi_walker_y_stride = 0;
3904     sampler_dn[index].dw0.vdi_walker_frame_sharing_enable = 0;
3905     sampler_dn[index].dw0.denoise_maximum_history = 128;      // 128-240
3906     sampler_dn[index].dw0.denoise_stad_threshold = 0;
3907
3908     sampler_dn[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
3909     sampler_dn[index].dw1.denoise_moving_pixel_threshold = 0;
3910     sampler_dn[index].dw1.stmm_c2 = 0;
3911     sampler_dn[index].dw1.low_temporal_difference_threshold = 8;
3912     sampler_dn[index].dw1.temporal_difference_threshold = 16;
3913
3914     sampler_dn[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
3915     sampler_dn[index].dw2.bne_edge_th = 1;
3916     sampler_dn[index].dw2.smooth_mv_th = 0;
3917     sampler_dn[index].dw2.sad_tight_th = 5;
3918     sampler_dn[index].dw2.cat_slope_minus1 = 9;
3919     sampler_dn[index].dw2.good_neighbor_th = 4;
3920
3921     sampler_dn[index].dw3.maximum_stmm = 128;
3922     sampler_dn[index].dw3.multipler_for_vecm = 2;
3923     sampler_dn[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
3924     sampler_dn[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3925     sampler_dn[index].dw3.stmm_blending_constant_select = 0;
3926
3927     sampler_dn[index].dw4.sdi_delta = 8;
3928     sampler_dn[index].dw4.sdi_threshold = 128;
3929     sampler_dn[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
3930     sampler_dn[index].dw4.stmm_shift_up = 0;
3931     sampler_dn[index].dw4.stmm_shift_down = 0;
3932     sampler_dn[index].dw4.minimum_stmm = 0;
3933
3934     sampler_dn[index].dw5.fmd_temporal_difference_threshold = 0;
3935     sampler_dn[index].dw5.sdi_fallback_mode_2_constant = 0;
3936     sampler_dn[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
3937     sampler_dn[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
3938
3939     sampler_dn[index].dw6.dn_enable = 1;
3940     sampler_dn[index].dw6.di_enable = 0;
3941     sampler_dn[index].dw6.di_partial = 0;
3942     sampler_dn[index].dw6.dndi_top_first = dndi_top_first;
3943     sampler_dn[index].dw6.dndi_stream_id = 1;
3944     sampler_dn[index].dw6.dndi_first_frame = 1;
3945     sampler_dn[index].dw6.progressive_dn = dn_progressive;
3946     sampler_dn[index].dw6.mcdi_enable = 0;
3947     sampler_dn[index].dw6.fmd_tear_threshold = 32;
3948     sampler_dn[index].dw6.cat_th1 = 0;
3949     sampler_dn[index].dw6.fmd2_vertical_difference_threshold = 32;
3950     sampler_dn[index].dw6.fmd1_vertical_difference_threshold = 32;
3951
3952     sampler_dn[index].dw7.sad_tha = 5;
3953     sampler_dn[index].dw7.sad_thb = 10;
3954     sampler_dn[index].dw7.fmd_for_1st_field_of_current_frame = 2;
3955     sampler_dn[index].dw7.mc_pixel_consistency_th = 25;
3956     sampler_dn[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
3957     sampler_dn[index].dw7.vdi_walker_enable = 0;
3958     sampler_dn[index].dw7.neighborpixel_th = 10;
3959     sampler_dn[index].dw7.column_width_minus1 = w / 16;
3960
3961     dri_bo_unmap(pp_context->sampler_state_table.bo);
3962
3963     /* private function & data */
3964     pp_context->pp_x_steps = gen7_pp_dn_x_steps;
3965     pp_context->pp_y_steps = gen7_pp_dn_y_steps;
3966     pp_context->private_context = &pp_context->pp_dn_context;
3967     pp_context->pp_set_block_parameter = gen7_pp_dn_set_block_parameter;
3968
3969     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
3970     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
3971     pp_static_parameter->grf1.di_top_field_first = 0;
3972     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
3973
3974     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
3975     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
3976     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
3977
3978     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
3979     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
3980
3981     pp_dn_context->dest_w = w;
3982     pp_dn_context->dest_h = h;
3983
3984     dst_surface->flags = src_surface->flags;
3985
3986     return VA_STATUS_SUCCESS;
3987 }
3988
3989 static VAStatus
3990 ironlake_pp_initialize(
3991     VADriverContextP ctx,
3992     struct i965_post_processing_context *pp_context,
3993     const struct i965_surface *src_surface,
3994     const VARectangle *src_rect,
3995     struct i965_surface *dst_surface,
3996     const VARectangle *dst_rect,
3997     int pp_index,
3998     void *filter_param
3999 )
4000 {
4001     VAStatus va_status;
4002     struct i965_driver_data *i965 = i965_driver_data(ctx);
4003     struct pp_module *pp_module;
4004     dri_bo *bo;
4005     int static_param_size, inline_param_size;
4006
4007     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
4008     bo = dri_bo_alloc(i965->intel.bufmgr,
4009                       "surface state & binding table",
4010                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
4011                       4096);
4012     assert(bo);
4013     pp_context->surface_state_binding_table.bo = bo;
4014
4015     dri_bo_unreference(pp_context->curbe.bo);
4016     bo = dri_bo_alloc(i965->intel.bufmgr,
4017                       "constant buffer",
4018                       4096, 
4019                       4096);
4020     assert(bo);
4021     pp_context->curbe.bo = bo;
4022
4023     dri_bo_unreference(pp_context->idrt.bo);
4024     bo = dri_bo_alloc(i965->intel.bufmgr, 
4025                       "interface discriptor", 
4026                       sizeof(struct i965_interface_descriptor), 
4027                       4096);
4028     assert(bo);
4029     pp_context->idrt.bo = bo;
4030     pp_context->idrt.num_interface_descriptors = 0;
4031
4032     dri_bo_unreference(pp_context->sampler_state_table.bo);
4033     bo = dri_bo_alloc(i965->intel.bufmgr, 
4034                       "sampler state table", 
4035                       4096,
4036                       4096);
4037     assert(bo);
4038     dri_bo_map(bo, True);
4039     memset(bo->virtual, 0, bo->size);
4040     dri_bo_unmap(bo);
4041     pp_context->sampler_state_table.bo = bo;
4042
4043     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
4044     bo = dri_bo_alloc(i965->intel.bufmgr, 
4045                       "sampler 8x8 state ",
4046                       4096,
4047                       4096);
4048     assert(bo);
4049     pp_context->sampler_state_table.bo_8x8 = bo;
4050
4051     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
4052     bo = dri_bo_alloc(i965->intel.bufmgr, 
4053                       "sampler 8x8 state ",
4054                       4096,
4055                       4096);
4056     assert(bo);
4057     pp_context->sampler_state_table.bo_8x8_uv = bo;
4058
4059     dri_bo_unreference(pp_context->vfe_state.bo);
4060     bo = dri_bo_alloc(i965->intel.bufmgr, 
4061                       "vfe state", 
4062                       sizeof(struct i965_vfe_state), 
4063                       4096);
4064     assert(bo);
4065     pp_context->vfe_state.bo = bo;
4066
4067     static_param_size = sizeof(struct pp_static_parameter);
4068     inline_param_size = sizeof(struct pp_inline_parameter);
4069
4070     memset(pp_context->pp_static_parameter, 0, static_param_size);
4071     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
4072     
4073     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
4074     pp_context->current_pp = pp_index;
4075     pp_module = &pp_context->pp_modules[pp_index];
4076     
4077     if (pp_module->initialize)
4078         va_status = pp_module->initialize(ctx, pp_context,
4079                                           src_surface,
4080                                           src_rect,
4081                                           dst_surface,
4082                                           dst_rect,
4083                                           filter_param);
4084     else
4085         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4086
4087     return va_status;
4088 }
4089
4090 static VAStatus
4091 ironlake_post_processing(
4092     VADriverContextP   ctx,
4093     struct i965_post_processing_context *pp_context,
4094     const struct i965_surface *src_surface,
4095     const VARectangle *src_rect,
4096     struct i965_surface *dst_surface,
4097     const VARectangle *dst_rect,
4098     int                pp_index,
4099     void *filter_param
4100 )
4101 {
4102     VAStatus va_status;
4103
4104     va_status = ironlake_pp_initialize(ctx, pp_context,
4105                                        src_surface,
4106                                        src_rect,
4107                                        dst_surface,
4108                                        dst_rect,
4109                                        pp_index,
4110                                        filter_param);
4111
4112     if (va_status == VA_STATUS_SUCCESS) {
4113         ironlake_pp_states_setup(ctx, pp_context);
4114         ironlake_pp_pipeline_setup(ctx, pp_context);
4115     }
4116
4117     return va_status;
4118 }
4119
4120 static VAStatus
4121 gen6_pp_initialize(
4122     VADriverContextP ctx,
4123     struct i965_post_processing_context *pp_context,
4124     const struct i965_surface *src_surface,
4125     const VARectangle *src_rect,
4126     struct i965_surface *dst_surface,
4127     const VARectangle *dst_rect,
4128     int pp_index,
4129     void *filter_param
4130 )
4131 {
4132     VAStatus va_status;
4133     struct i965_driver_data *i965 = i965_driver_data(ctx);
4134     struct pp_module *pp_module;
4135     dri_bo *bo;
4136     int static_param_size, inline_param_size;
4137
4138     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
4139     bo = dri_bo_alloc(i965->intel.bufmgr,
4140                       "surface state & binding table",
4141                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
4142                       4096);
4143     assert(bo);
4144     pp_context->surface_state_binding_table.bo = bo;
4145
4146     dri_bo_unreference(pp_context->curbe.bo);
4147     bo = dri_bo_alloc(i965->intel.bufmgr,
4148                       "constant buffer",
4149                       4096, 
4150                       4096);
4151     assert(bo);
4152     pp_context->curbe.bo = bo;
4153
4154     dri_bo_unreference(pp_context->idrt.bo);
4155     bo = dri_bo_alloc(i965->intel.bufmgr, 
4156                       "interface discriptor", 
4157                       sizeof(struct gen6_interface_descriptor_data), 
4158                       4096);
4159     assert(bo);
4160     pp_context->idrt.bo = bo;
4161     pp_context->idrt.num_interface_descriptors = 0;
4162
4163     dri_bo_unreference(pp_context->sampler_state_table.bo);
4164     bo = dri_bo_alloc(i965->intel.bufmgr, 
4165                       "sampler state table", 
4166                       4096,
4167                       4096);
4168     assert(bo);
4169     dri_bo_map(bo, True);
4170     memset(bo->virtual, 0, bo->size);
4171     dri_bo_unmap(bo);
4172     pp_context->sampler_state_table.bo = bo;
4173
4174     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
4175     bo = dri_bo_alloc(i965->intel.bufmgr, 
4176                       "sampler 8x8 state ",
4177                       4096,
4178                       4096);
4179     assert(bo);
4180     pp_context->sampler_state_table.bo_8x8 = bo;
4181
4182     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
4183     bo = dri_bo_alloc(i965->intel.bufmgr, 
4184                       "sampler 8x8 state ",
4185                       4096,
4186                       4096);
4187     assert(bo);
4188     pp_context->sampler_state_table.bo_8x8_uv = bo;
4189
4190     dri_bo_unreference(pp_context->vfe_state.bo);
4191     bo = dri_bo_alloc(i965->intel.bufmgr, 
4192                       "vfe state", 
4193                       sizeof(struct i965_vfe_state), 
4194                       4096);
4195     assert(bo);
4196     pp_context->vfe_state.bo = bo;
4197     
4198     if (IS_GEN7(i965->intel.device_info)) {
4199         static_param_size = sizeof(struct gen7_pp_static_parameter);
4200         inline_param_size = sizeof(struct gen7_pp_inline_parameter);
4201     } else {
4202         static_param_size = sizeof(struct pp_static_parameter);
4203         inline_param_size = sizeof(struct pp_inline_parameter);
4204     }
4205
4206     memset(pp_context->pp_static_parameter, 0, static_param_size);
4207     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
4208
4209     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
4210     pp_context->current_pp = pp_index;
4211     pp_module = &pp_context->pp_modules[pp_index];
4212     
4213     if (pp_module->initialize)
4214         va_status = pp_module->initialize(ctx, pp_context,
4215                                           src_surface,
4216                                           src_rect,
4217                                           dst_surface,
4218                                           dst_rect,
4219                                           filter_param);
4220     else
4221         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4222
4223     calculate_boundary_block_mask(pp_context, dst_rect);
4224
4225     return va_status;
4226 }
4227
4228
4229 static void
4230 gen6_pp_interface_descriptor_table(VADriverContextP   ctx,
4231                                    struct i965_post_processing_context *pp_context)
4232 {
4233     struct i965_driver_data *i965 = i965_driver_data(ctx);
4234     struct gen6_interface_descriptor_data *desc;
4235     dri_bo *bo;
4236     int pp_index = pp_context->current_pp;
4237
4238     bo = pp_context->idrt.bo;
4239     dri_bo_map(bo, True);
4240     assert(bo->virtual);
4241     desc = bo->virtual;
4242     memset(desc, 0, sizeof(*desc));
4243     desc->desc0.kernel_start_pointer = 
4244         pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
4245     desc->desc1.single_program_flow = 1;
4246     desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
4247     desc->desc2.sampler_count = 1;      /* 1 - 4 samplers used */
4248     desc->desc2.sampler_state_pointer = 
4249         pp_context->sampler_state_table.bo->offset >> 5;
4250     desc->desc3.binding_table_entry_count = 0;
4251     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
4252     desc->desc4.constant_urb_entry_read_offset = 0;
4253
4254     if (IS_GEN7(i965->intel.device_info))
4255         desc->desc4.constant_urb_entry_read_length = 6; /* grf 1-6 */
4256     else
4257         desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
4258
4259     dri_bo_emit_reloc(bo,
4260                       I915_GEM_DOMAIN_INSTRUCTION, 0,
4261                       0,
4262                       offsetof(struct gen6_interface_descriptor_data, desc0),
4263                       pp_context->pp_modules[pp_index].kernel.bo);
4264
4265     dri_bo_emit_reloc(bo,
4266                       I915_GEM_DOMAIN_INSTRUCTION, 0,
4267                       desc->desc2.sampler_count << 2,
4268                       offsetof(struct gen6_interface_descriptor_data, desc2),
4269                       pp_context->sampler_state_table.bo);
4270
4271     dri_bo_unmap(bo);
4272     pp_context->idrt.num_interface_descriptors++;
4273 }
4274
4275 static void
4276 gen6_pp_upload_constants(VADriverContextP ctx,
4277                          struct i965_post_processing_context *pp_context)
4278 {
4279     struct i965_driver_data *i965 = i965_driver_data(ctx);
4280     unsigned char *constant_buffer;
4281     int param_size;
4282
4283     assert(sizeof(struct pp_static_parameter) == 128);
4284     assert(sizeof(struct gen7_pp_static_parameter) == 192);
4285
4286     if (IS_GEN7(i965->intel.device_info))
4287         param_size = sizeof(struct gen7_pp_static_parameter);
4288     else
4289         param_size = sizeof(struct pp_static_parameter);
4290
4291     dri_bo_map(pp_context->curbe.bo, 1);
4292     assert(pp_context->curbe.bo->virtual);
4293     constant_buffer = pp_context->curbe.bo->virtual;
4294     memcpy(constant_buffer, pp_context->pp_static_parameter, param_size);
4295     dri_bo_unmap(pp_context->curbe.bo);
4296 }
4297
4298 static void
4299 gen6_pp_states_setup(VADriverContextP ctx,
4300                      struct i965_post_processing_context *pp_context)
4301 {
4302     gen6_pp_interface_descriptor_table(ctx, pp_context);
4303     gen6_pp_upload_constants(ctx, pp_context);
4304 }
4305
4306 static void
4307 gen6_pp_pipeline_select(VADriverContextP ctx,
4308                         struct i965_post_processing_context *pp_context)
4309 {
4310     struct intel_batchbuffer *batch = pp_context->batch;
4311
4312     BEGIN_BATCH(batch, 1);
4313     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
4314     ADVANCE_BATCH(batch);
4315 }
4316
4317 static void
4318 gen6_pp_state_base_address(VADriverContextP ctx,
4319                            struct i965_post_processing_context *pp_context)
4320 {
4321     struct intel_batchbuffer *batch = pp_context->batch;
4322
4323     BEGIN_BATCH(batch, 10);
4324     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
4325     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4326     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
4327     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4328     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4329     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4330     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4331     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4332     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4333     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4334     ADVANCE_BATCH(batch);
4335 }
4336
4337 static void
4338 gen6_pp_vfe_state(VADriverContextP ctx,
4339                   struct i965_post_processing_context *pp_context)
4340 {
4341     struct intel_batchbuffer *batch = pp_context->batch;
4342
4343     BEGIN_BATCH(batch, 8);
4344     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
4345     OUT_BATCH(batch, 0);
4346     OUT_BATCH(batch,
4347               (pp_context->vfe_gpu_state.max_num_threads - 1) << 16 |
4348               pp_context->vfe_gpu_state.num_urb_entries << 8);
4349     OUT_BATCH(batch, 0);
4350     OUT_BATCH(batch,
4351               (pp_context->vfe_gpu_state.urb_entry_size) << 16 |  
4352                 /* URB Entry Allocation Size, in 256 bits unit */
4353               (pp_context->vfe_gpu_state.curbe_allocation_size));
4354                 /* CURBE Allocation Size, in 256 bits unit */
4355     OUT_BATCH(batch, 0);
4356     OUT_BATCH(batch, 0);
4357     OUT_BATCH(batch, 0);
4358     ADVANCE_BATCH(batch);
4359 }
4360
4361 static void
4362 gen6_pp_curbe_load(VADriverContextP ctx,
4363                    struct i965_post_processing_context *pp_context)
4364 {
4365     struct intel_batchbuffer *batch = pp_context->batch;
4366     struct i965_driver_data *i965 = i965_driver_data(ctx);
4367     int param_size;
4368
4369     if (IS_GEN7(i965->intel.device_info))
4370         param_size = sizeof(struct gen7_pp_static_parameter);
4371     else
4372         param_size = sizeof(struct pp_static_parameter);
4373
4374     BEGIN_BATCH(batch, 4);
4375     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
4376     OUT_BATCH(batch, 0);
4377     OUT_BATCH(batch,
4378               param_size);
4379     OUT_RELOC(batch, 
4380               pp_context->curbe.bo,
4381               I915_GEM_DOMAIN_INSTRUCTION, 0,
4382               0);
4383     ADVANCE_BATCH(batch);
4384 }
4385
4386 static void
4387 gen6_interface_descriptor_load(VADriverContextP ctx,
4388                                struct i965_post_processing_context *pp_context)
4389 {
4390     struct intel_batchbuffer *batch = pp_context->batch;
4391
4392     BEGIN_BATCH(batch, 4);
4393     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
4394     OUT_BATCH(batch, 0);
4395     OUT_BATCH(batch,
4396               pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
4397     OUT_RELOC(batch, 
4398               pp_context->idrt.bo,
4399               I915_GEM_DOMAIN_INSTRUCTION, 0,
4400               0);
4401     ADVANCE_BATCH(batch);
4402 }
4403
4404 static void update_block_mask_parameter(struct i965_post_processing_context *pp_context, int x, int y, int x_steps, int y_steps) 
4405 {
4406     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
4407
4408     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
4409     pp_inline_parameter->grf6.block_vertical_mask_bottom = pp_context->block_vertical_mask_bottom;
4410     // for the first block, it always on the left edge. the second block will reload horizontal_mask from grf6.block_horizontal_mask_middle
4411     pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_left;
4412     pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
4413     pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_right;
4414
4415     /* 1 x N */
4416     if (x_steps == 1) {
4417         if (y == y_steps-1) {
4418             pp_inline_parameter->grf5.block_vertical_mask = pp_context->block_vertical_mask_bottom;
4419         }
4420         else {
4421             pp_inline_parameter->grf6.block_vertical_mask_bottom = 0xff;
4422         }
4423     }
4424
4425     /* M x 1 */
4426     if (y_steps == 1) {
4427         if (x == 0) { // all blocks in this group are on the left edge
4428             pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_left;
4429             pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_left; 
4430         }
4431         else if (x == x_steps-1) {
4432             pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_right;
4433             pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_right;
4434         }
4435         else {
4436             pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
4437             pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
4438             pp_inline_parameter->grf6.block_horizontal_mask_right = 0xffff;
4439         }
4440     }
4441
4442 }
4443
4444 static void
4445 gen6_pp_object_walker(VADriverContextP ctx,
4446                       struct i965_post_processing_context *pp_context)
4447 {
4448     struct i965_driver_data *i965 = i965_driver_data(ctx);
4449     struct intel_batchbuffer *batch = pp_context->batch;
4450     int x, x_steps, y, y_steps;
4451     int param_size, command_length_in_dws;
4452     dri_bo *command_buffer;
4453     unsigned int *command_ptr;
4454
4455     if (IS_GEN7(i965->intel.device_info))
4456         param_size = sizeof(struct gen7_pp_inline_parameter);
4457     else
4458         param_size = sizeof(struct pp_inline_parameter);
4459
4460     x_steps = pp_context->pp_x_steps(pp_context->private_context);
4461     y_steps = pp_context->pp_y_steps(pp_context->private_context);
4462     command_length_in_dws = 6 + (param_size >> 2);
4463     command_buffer = dri_bo_alloc(i965->intel.bufmgr,
4464                                   "command objects buffer",
4465                                   command_length_in_dws * 4 * x_steps * y_steps + 8,
4466                                   4096);
4467
4468     dri_bo_map(command_buffer, 1);
4469     command_ptr = command_buffer->virtual;
4470
4471     for (y = 0; y < y_steps; y++) {
4472         for (x = 0; x < x_steps; x++) {
4473             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
4474                 // some common block parameter update goes here, apply to all pp functions
4475                 if (IS_GEN6(i965->intel.device_info))
4476                     update_block_mask_parameter (pp_context, x, y, x_steps, y_steps);
4477                 
4478                 *command_ptr++ = (CMD_MEDIA_OBJECT | (command_length_in_dws - 2));
4479                 *command_ptr++ = 0;
4480                 *command_ptr++ = 0;
4481                 *command_ptr++ = 0;
4482                 *command_ptr++ = 0;
4483                 *command_ptr++ = 0;
4484                 memcpy(command_ptr, pp_context->pp_inline_parameter, param_size);
4485                 command_ptr += (param_size >> 2);
4486             }
4487         }
4488     }
4489
4490     if (command_length_in_dws * x_steps * y_steps % 2 == 0)
4491         *command_ptr++ = 0;
4492
4493     *command_ptr = MI_BATCH_BUFFER_END;
4494
4495     dri_bo_unmap(command_buffer);
4496
4497     BEGIN_BATCH(batch, 2);
4498     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
4499     OUT_RELOC(batch, command_buffer,
4500               I915_GEM_DOMAIN_COMMAND, 0,
4501               0);
4502     ADVANCE_BATCH(batch);
4503
4504     dri_bo_unreference(command_buffer);
4505
4506     /* Have to execute the batch buffer here becuase MI_BATCH_BUFFER_END
4507      * will cause control to pass back to ring buffer 
4508      */
4509     intel_batchbuffer_end_atomic(batch);
4510     intel_batchbuffer_flush(batch);
4511     intel_batchbuffer_start_atomic(batch, 0x1000);
4512 }
4513
4514 static void
4515 gen6_pp_pipeline_setup(VADriverContextP ctx,
4516                        struct i965_post_processing_context *pp_context)
4517 {
4518     struct intel_batchbuffer *batch = pp_context->batch;
4519
4520     intel_batchbuffer_start_atomic(batch, 0x1000);
4521     intel_batchbuffer_emit_mi_flush(batch);
4522     gen6_pp_pipeline_select(ctx, pp_context);
4523     gen6_pp_state_base_address(ctx, pp_context);
4524     gen6_pp_vfe_state(ctx, pp_context);
4525     gen6_pp_curbe_load(ctx, pp_context);
4526     gen6_interface_descriptor_load(ctx, pp_context);
4527     gen6_pp_object_walker(ctx, pp_context);
4528     intel_batchbuffer_end_atomic(batch);
4529 }
4530
4531 static VAStatus
4532 gen6_post_processing(
4533     VADriverContextP ctx,
4534     struct i965_post_processing_context *pp_context,
4535     const struct i965_surface *src_surface,
4536     const VARectangle *src_rect,
4537     struct i965_surface *dst_surface,
4538     const VARectangle *dst_rect,
4539     int pp_index,
4540     void *filter_param
4541 )
4542 {
4543     VAStatus va_status;
4544     
4545     va_status = gen6_pp_initialize(ctx, pp_context,
4546                                    src_surface,
4547                                    src_rect,
4548                                    dst_surface,
4549                                    dst_rect,
4550                                    pp_index,
4551                                    filter_param);
4552
4553     if (va_status == VA_STATUS_SUCCESS) {
4554         gen6_pp_states_setup(ctx, pp_context);
4555         gen6_pp_pipeline_setup(ctx, pp_context);
4556     }
4557
4558     if (va_status == VA_STATUS_SUCCESS_1)
4559         va_status = VA_STATUS_SUCCESS;
4560
4561     return va_status;
4562 }
4563
4564 static VAStatus
4565 i965_post_processing_internal(
4566     VADriverContextP   ctx,
4567     struct i965_post_processing_context *pp_context,
4568     const struct i965_surface *src_surface,
4569     const VARectangle *src_rect,
4570     struct i965_surface *dst_surface,
4571     const VARectangle *dst_rect,
4572     int                pp_index,
4573     void *filter_param
4574 )
4575 {
4576     VAStatus va_status;
4577     struct i965_driver_data *i965 = i965_driver_data(ctx);
4578
4579     if (pp_context && pp_context->intel_post_processing) {
4580         va_status = (pp_context->intel_post_processing)(ctx, pp_context,
4581                           src_surface, src_rect,
4582                           dst_surface, dst_rect,
4583                           pp_index, filter_param);
4584     } else {
4585         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4586     }
4587
4588     return va_status;
4589 }
4590
4591 static void
4592 rgb_to_yuv(unsigned int argb,
4593            unsigned char *y,
4594            unsigned char *u,
4595            unsigned char *v,
4596            unsigned char *a)
4597 {
4598     int r = ((argb >> 16) & 0xff);
4599     int g = ((argb >> 8) & 0xff);
4600     int b = ((argb >> 0) & 0xff);
4601     
4602     *y = (257 * r + 504 * g + 98 * b) / 1000 + 16;
4603     *v = (439 * r - 368 * g - 71 * b) / 1000 + 128;
4604     *u = (-148 * r - 291 * g + 439 * b) / 1000 + 128;
4605     *a = ((argb >> 24) & 0xff);
4606 }
4607
4608 static void 
4609 i965_vpp_clear_surface(VADriverContextP ctx,
4610                        struct i965_post_processing_context *pp_context,
4611                        struct object_surface *obj_surface,
4612                        unsigned int color)
4613 {
4614     struct i965_driver_data *i965 = i965_driver_data(ctx);
4615     struct intel_batchbuffer *batch = pp_context->batch;
4616     unsigned int blt_cmd, br13;
4617     unsigned int tiling = 0, swizzle = 0;
4618     int pitch;
4619     unsigned char y, u, v, a = 0;
4620     int region_width, region_height;
4621
4622     /* Currently only support NV12 surface */
4623     if (!obj_surface || obj_surface->fourcc != VA_FOURCC_NV12)
4624         return;
4625
4626     rgb_to_yuv(color, &y, &u, &v, &a);
4627
4628     if (a == 0)
4629         return;
4630
4631     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4632     blt_cmd = XY_COLOR_BLT_CMD;
4633     pitch = obj_surface->width;
4634
4635     if (tiling != I915_TILING_NONE) {
4636         assert(tiling == I915_TILING_Y);
4637         // blt_cmd |= XY_COLOR_BLT_DST_TILED;
4638         // pitch >>= 2;
4639     }
4640
4641     br13 = 0xf0 << 16;
4642     br13 |= BR13_8;
4643     br13 |= pitch;
4644
4645     if (IS_IRONLAKE(i965->intel.device_info)) {
4646         intel_batchbuffer_start_atomic(batch, 48);
4647         BEGIN_BATCH(batch, 12);
4648     } else {
4649         /* Will double-check the command if the new chipset is added */
4650         intel_batchbuffer_start_atomic_blt(batch, 48);
4651         BEGIN_BLT_BATCH(batch, 12);
4652     }
4653
4654     region_width = obj_surface->width;
4655     region_height = obj_surface->height;
4656
4657     OUT_BATCH(batch, blt_cmd);
4658     OUT_BATCH(batch, br13);
4659     OUT_BATCH(batch,
4660               0 << 16 |
4661               0);
4662     OUT_BATCH(batch,
4663               region_height << 16 |
4664               region_width);
4665     OUT_RELOC(batch, obj_surface->bo, 
4666               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
4667               0);
4668     OUT_BATCH(batch, y);
4669
4670     br13 = 0xf0 << 16;
4671     br13 |= BR13_565;
4672     br13 |= pitch;
4673
4674     region_width = obj_surface->width / 2;
4675     region_height = obj_surface->height / 2;
4676
4677     if (tiling == I915_TILING_Y) {
4678         region_height = ALIGN(obj_surface->height / 2, 32);
4679     }
4680
4681     OUT_BATCH(batch, blt_cmd);
4682     OUT_BATCH(batch, br13);
4683     OUT_BATCH(batch,
4684               0 << 16 |
4685               0);
4686     OUT_BATCH(batch,
4687               region_height << 16 |
4688               region_width);
4689     OUT_RELOC(batch, obj_surface->bo, 
4690               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
4691               obj_surface->width * obj_surface->y_cb_offset);
4692     OUT_BATCH(batch, v << 8 | u);
4693
4694     ADVANCE_BATCH(batch);
4695     intel_batchbuffer_end_atomic(batch);
4696 }
4697
4698 VAStatus
4699 i965_scaling_processing(
4700     VADriverContextP   ctx,
4701     struct object_surface *src_surface_obj,
4702     const VARectangle *src_rect,
4703     struct object_surface *dst_surface_obj,
4704     const VARectangle *dst_rect,
4705     unsigned int       flags)
4706 {
4707     VAStatus va_status = VA_STATUS_SUCCESS;
4708     struct i965_driver_data *i965 = i965_driver_data(ctx);
4709  
4710     assert(src_surface_obj->fourcc == VA_FOURCC_NV12);
4711     assert(dst_surface_obj->fourcc == VA_FOURCC_NV12);
4712
4713     if (HAS_VPP(i965) && (flags & I965_PP_FLAG_AVS)) {
4714         struct i965_surface src_surface;
4715         struct i965_surface dst_surface;
4716
4717          _i965LockMutex(&i965->pp_mutex);
4718
4719          src_surface.base = (struct object_base *)src_surface_obj;
4720          src_surface.type = I965_SURFACE_TYPE_SURFACE;
4721          src_surface.flags = I965_SURFACE_FLAG_FRAME;
4722          dst_surface.base = (struct object_base *)dst_surface_obj;
4723          dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4724          dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4725
4726          va_status = i965_post_processing_internal(ctx, i965->pp_context,
4727                                                    &src_surface,
4728                                                    src_rect,
4729                                                    &dst_surface,
4730                                                    dst_rect,
4731                                                    PP_NV12_AVS,
4732                                                    NULL);
4733
4734          _i965UnlockMutex(&i965->pp_mutex);
4735     }
4736
4737     return va_status;
4738 }
4739
4740 VASurfaceID
4741 i965_post_processing(
4742     VADriverContextP   ctx,
4743     struct object_surface *obj_surface,
4744     const VARectangle *src_rect,
4745     const VARectangle *dst_rect,
4746     unsigned int       flags,
4747     int               *has_done_scaling  
4748 )
4749 {
4750     struct i965_driver_data *i965 = i965_driver_data(ctx);
4751     VASurfaceID out_surface_id = VA_INVALID_ID;
4752     VASurfaceID tmp_id = VA_INVALID_ID;
4753     
4754     *has_done_scaling = 0;
4755
4756     if (HAS_VPP(i965)) {
4757         VAStatus status;
4758         struct i965_surface src_surface;
4759         struct i965_surface dst_surface;
4760
4761         /* Currently only support post processing for NV12 surface */
4762         if (obj_surface->fourcc != VA_FOURCC_NV12)
4763             return out_surface_id;
4764
4765         _i965LockMutex(&i965->pp_mutex);
4766
4767         if (flags & I965_PP_FLAG_MCDI) {
4768             src_surface.base = (struct object_base *)obj_surface;
4769             src_surface.type = I965_SURFACE_TYPE_SURFACE;
4770             src_surface.flags = (flags & I965_PP_FLAG_TOP_FIELD) ? 
4771                 I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST;
4772
4773             status = i965_CreateSurfaces(ctx,
4774                                          obj_surface->orig_width,
4775                                          obj_surface->orig_height,
4776                                          VA_RT_FORMAT_YUV420,
4777                                          1,
4778                                          &out_surface_id);
4779             assert(status == VA_STATUS_SUCCESS);
4780             obj_surface = SURFACE(out_surface_id);
4781             assert(obj_surface);
4782             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
4783             i965_vpp_clear_surface(ctx, i965->pp_context, obj_surface, 0); 
4784
4785             dst_surface.base = (struct object_base *)obj_surface;
4786             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4787             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4788
4789             i965_post_processing_internal(ctx, i965->pp_context,
4790                                           &src_surface,
4791                                           src_rect,
4792                                           &dst_surface,
4793                                           dst_rect,
4794                                           PP_NV12_DNDI,
4795                                           NULL);
4796         }
4797
4798         if (flags & I965_PP_FLAG_AVS) {
4799             struct i965_render_state *render_state = &i965->render_state;
4800             struct intel_region *dest_region = render_state->draw_region;
4801
4802             if (out_surface_id != VA_INVALID_ID)
4803                 tmp_id = out_surface_id;
4804
4805             src_surface.base = (struct object_base *)obj_surface;
4806             src_surface.type = I965_SURFACE_TYPE_SURFACE;
4807             src_surface.flags = I965_SURFACE_FLAG_FRAME;
4808
4809             status = i965_CreateSurfaces(ctx,
4810                                          dest_region->width,
4811                                          dest_region->height,
4812                                          VA_RT_FORMAT_YUV420,
4813                                          1,
4814                                          &out_surface_id);
4815             assert(status == VA_STATUS_SUCCESS);
4816             obj_surface = SURFACE(out_surface_id);
4817             assert(obj_surface);
4818             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
4819             i965_vpp_clear_surface(ctx, i965->pp_context, obj_surface, 0); 
4820
4821             dst_surface.base = (struct object_base *)obj_surface;
4822             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4823             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4824
4825             i965_post_processing_internal(ctx, i965->pp_context,
4826                                           &src_surface,
4827                                           src_rect,
4828                                           &dst_surface,
4829                                           dst_rect,
4830                                           PP_NV12_AVS,
4831                                           NULL);
4832
4833             if (tmp_id != VA_INVALID_ID)
4834                 i965_DestroySurfaces(ctx, &tmp_id, 1);
4835                 
4836             *has_done_scaling = 1;
4837         }
4838
4839         _i965UnlockMutex(&i965->pp_mutex);
4840     }
4841
4842     return out_surface_id;
4843 }       
4844
4845 static VAStatus
4846 i965_image_pl2_processing(VADriverContextP ctx,
4847                           const struct i965_surface *src_surface,
4848                           const VARectangle *src_rect,
4849                           struct i965_surface *dst_surface,
4850                           const VARectangle *dst_rect);
4851
4852 static VAStatus
4853 i965_image_plx_nv12_plx_processing(VADriverContextP ctx,
4854                                    VAStatus (*i965_image_plx_nv12_processing)(
4855                                        VADriverContextP,
4856                                        const struct i965_surface *,
4857                                        const VARectangle *,
4858                                        struct i965_surface *,
4859                                        const VARectangle *),
4860                                    const struct i965_surface *src_surface,
4861                                    const VARectangle *src_rect,
4862                                    struct i965_surface *dst_surface,
4863                                    const VARectangle *dst_rect)
4864 {
4865     struct i965_driver_data *i965 = i965_driver_data(ctx);
4866     VAStatus status;
4867     VASurfaceID tmp_surface_id = VA_INVALID_SURFACE;
4868     struct object_surface *obj_surface = NULL;
4869     struct i965_surface tmp_surface;
4870     int width, height;
4871
4872     pp_get_surface_size(ctx, dst_surface, &width, &height);
4873     status = i965_CreateSurfaces(ctx,
4874                                  width,
4875                                  height,
4876                                  VA_RT_FORMAT_YUV420,
4877                                  1,
4878                                  &tmp_surface_id);
4879     assert(status == VA_STATUS_SUCCESS);
4880     obj_surface = SURFACE(tmp_surface_id);
4881     assert(obj_surface);
4882     i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
4883
4884     tmp_surface.base = (struct object_base *)obj_surface;
4885     tmp_surface.type = I965_SURFACE_TYPE_SURFACE;
4886     tmp_surface.flags = I965_SURFACE_FLAG_FRAME;
4887
4888     status = i965_image_plx_nv12_processing(ctx,
4889                                             src_surface,
4890                                             src_rect,
4891                                             &tmp_surface,
4892                                             dst_rect);
4893
4894     if (status == VA_STATUS_SUCCESS)
4895         status = i965_image_pl2_processing(ctx,
4896                                            &tmp_surface,
4897                                            dst_rect,
4898                                            dst_surface,
4899                                            dst_rect);
4900
4901     i965_DestroySurfaces(ctx,
4902                          &tmp_surface_id,
4903                          1);
4904
4905     return status;
4906 }
4907
4908
4909 static VAStatus
4910 i965_image_pl1_rgbx_processing(VADriverContextP ctx,
4911                                const struct i965_surface *src_surface,
4912                                const VARectangle *src_rect,
4913                                struct i965_surface *dst_surface,
4914                                const VARectangle *dst_rect)
4915 {
4916     struct i965_driver_data *i965 = i965_driver_data(ctx);
4917     struct i965_post_processing_context *pp_context = i965->pp_context;
4918     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
4919     VAStatus vaStatus;
4920
4921     switch (fourcc) {
4922     case VA_FOURCC_NV12:
4923         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
4924                                                  src_surface,
4925                                                  src_rect,
4926                                                  dst_surface,
4927                                                  dst_rect,
4928                                                  PP_RGBX_LOAD_SAVE_NV12,
4929                                                  NULL);
4930         intel_batchbuffer_flush(pp_context->batch);
4931         break;
4932
4933     default:
4934         vaStatus = i965_image_plx_nv12_plx_processing(ctx,
4935                                                       i965_image_pl1_rgbx_processing,
4936                                                       src_surface,
4937                                                       src_rect,
4938                                                       dst_surface,
4939                                                       dst_rect);
4940         break;
4941     }
4942
4943     return vaStatus;
4944 }
4945
4946 static VAStatus
4947 i965_image_pl3_processing(VADriverContextP ctx,
4948                           const struct i965_surface *src_surface,
4949                           const VARectangle *src_rect,
4950                           struct i965_surface *dst_surface,
4951                           const VARectangle *dst_rect)
4952 {
4953     struct i965_driver_data *i965 = i965_driver_data(ctx);
4954     struct i965_post_processing_context *pp_context = i965->pp_context;
4955     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
4956     VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
4957
4958     switch (fourcc) {
4959     case VA_FOURCC_NV12:
4960         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
4961                                                  src_surface,
4962                                                  src_rect,
4963                                                  dst_surface,
4964                                                  dst_rect,
4965                                                  PP_PL3_LOAD_SAVE_N12,
4966                                                  NULL);
4967         intel_batchbuffer_flush(pp_context->batch);
4968         break;
4969
4970     case VA_FOURCC_IMC1:
4971     case VA_FOURCC_IMC3:
4972     case VA_FOURCC_YV12:
4973     case VA_FOURCC_I420:
4974         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
4975                                                  src_surface,
4976                                                  src_rect,
4977                                                  dst_surface,
4978                                                  dst_rect,
4979                                                  PP_PL3_LOAD_SAVE_PL3,
4980                                                  NULL);
4981         intel_batchbuffer_flush(pp_context->batch);
4982         break;
4983
4984     case VA_FOURCC_YUY2:
4985     case VA_FOURCC_UYVY:
4986         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
4987                                                  src_surface,
4988                                                  src_rect,
4989                                                  dst_surface,
4990                                                  dst_rect,
4991                                                  PP_PL3_LOAD_SAVE_PA,
4992                                                  NULL);
4993         intel_batchbuffer_flush(pp_context->batch);
4994         break;
4995
4996     default:
4997         vaStatus = i965_image_plx_nv12_plx_processing(ctx,
4998                                                       i965_image_pl3_processing,
4999                                                       src_surface,
5000                                                       src_rect,
5001                                                       dst_surface,
5002                                                       dst_rect);
5003         break;
5004     }
5005
5006     return vaStatus;
5007 }
5008
5009 static VAStatus
5010 i965_image_pl2_processing(VADriverContextP ctx,
5011                           const struct i965_surface *src_surface,
5012                           const VARectangle *src_rect,
5013                           struct i965_surface *dst_surface,
5014                           const VARectangle *dst_rect)
5015 {
5016     struct i965_driver_data *i965 = i965_driver_data(ctx);
5017     struct i965_post_processing_context *pp_context = i965->pp_context;
5018     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5019     VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
5020
5021     switch (fourcc) {
5022     case VA_FOURCC_NV12:
5023         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5024                                                  src_surface,
5025                                                  src_rect,
5026                                                  dst_surface,
5027                                                  dst_rect,
5028                                                  PP_NV12_LOAD_SAVE_N12,
5029                                                  NULL);
5030         break;
5031
5032     case VA_FOURCC_IMC1:
5033     case VA_FOURCC_IMC3:
5034     case VA_FOURCC_YV12:
5035     case VA_FOURCC_I420:
5036         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5037                                                  src_surface,
5038                                                  src_rect,
5039                                                  dst_surface,
5040                                                  dst_rect,
5041                                                  PP_NV12_LOAD_SAVE_PL3,
5042                                                  NULL);
5043         break;
5044
5045     case VA_FOURCC_YUY2:
5046     case VA_FOURCC_UYVY:
5047         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5048                                                  src_surface,
5049                                                  src_rect,
5050                                                  dst_surface,
5051                                                  dst_rect,
5052                                                  PP_NV12_LOAD_SAVE_PA,
5053                                                  NULL);
5054         break;
5055
5056     case VA_FOURCC_BGRX:
5057     case VA_FOURCC_BGRA:
5058     case VA_FOURCC_RGBX:
5059     case VA_FOURCC_RGBA:
5060         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5061                                                  src_surface,
5062                                                  src_rect,
5063                                                  dst_surface,
5064                                                  dst_rect,
5065                                                  PP_NV12_LOAD_SAVE_RGBX,
5066                                                  NULL);
5067         break;
5068
5069     default:
5070         return VA_STATUS_ERROR_UNIMPLEMENTED;
5071     }
5072
5073     intel_batchbuffer_flush(pp_context->batch);
5074
5075     return vaStatus;
5076 }
5077
5078 static VAStatus
5079 i965_image_pl1_processing(VADriverContextP ctx,
5080                           const struct i965_surface *src_surface,
5081                           const VARectangle *src_rect,
5082                           struct i965_surface *dst_surface,
5083                           const VARectangle *dst_rect)
5084 {
5085     struct i965_driver_data *i965 = i965_driver_data(ctx);
5086     struct i965_post_processing_context *pp_context = i965->pp_context;
5087     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5088     VAStatus vaStatus;
5089
5090     switch (fourcc) {
5091     case VA_FOURCC_NV12:
5092         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5093                                                  src_surface,
5094                                                  src_rect,
5095                                                  dst_surface,
5096                                                  dst_rect,
5097                                                  PP_PA_LOAD_SAVE_NV12,
5098                                                  NULL);
5099         intel_batchbuffer_flush(pp_context->batch);
5100         break;
5101
5102     case VA_FOURCC_YV12:
5103         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5104                                                  src_surface,
5105                                                  src_rect,
5106                                                  dst_surface,
5107                                                  dst_rect,
5108                                                  PP_PA_LOAD_SAVE_PL3,
5109                                                  NULL);
5110         intel_batchbuffer_flush(pp_context->batch);
5111         break;
5112
5113     case VA_FOURCC_YUY2:
5114     case VA_FOURCC_UYVY:
5115         vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5116                                                  src_surface,
5117                                                  src_rect,
5118                                                  dst_surface,
5119                                                  dst_rect,
5120                                                  PP_PA_LOAD_SAVE_PA,
5121                                                  NULL);
5122         intel_batchbuffer_flush(pp_context->batch);
5123         break;
5124
5125     default:
5126         vaStatus = i965_image_plx_nv12_plx_processing(ctx,
5127                                                       i965_image_pl1_processing,
5128                                                       src_surface,
5129                                                       src_rect,
5130                                                       dst_surface,
5131                                                       dst_rect);
5132         break;
5133     }
5134
5135     return vaStatus;
5136 }
5137
5138 VAStatus
5139 i965_image_processing(VADriverContextP ctx,
5140                       const struct i965_surface *src_surface,
5141                       const VARectangle *src_rect,
5142                       struct i965_surface *dst_surface,
5143                       const VARectangle *dst_rect)
5144 {
5145     struct i965_driver_data *i965 = i965_driver_data(ctx);
5146     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
5147
5148     if (HAS_VPP(i965)) {
5149         int fourcc = pp_get_surface_fourcc(ctx, src_surface);
5150
5151         _i965LockMutex(&i965->pp_mutex);
5152
5153         switch (fourcc) {
5154         case VA_FOURCC_YV12:
5155         case VA_FOURCC_I420:
5156         case VA_FOURCC_IMC1:
5157         case VA_FOURCC_IMC3:
5158         case VA_FOURCC_422H:
5159         case VA_FOURCC_422V:
5160         case VA_FOURCC_411P:
5161         case VA_FOURCC_444P:
5162         case VA_FOURCC_YV16:
5163             status = i965_image_pl3_processing(ctx,
5164                                                src_surface,
5165                                                src_rect,
5166                                                dst_surface,
5167                                                dst_rect);
5168             break;
5169
5170         case  VA_FOURCC_NV12:
5171             status = i965_image_pl2_processing(ctx,
5172                                                src_surface,
5173                                                src_rect,
5174                                                dst_surface,
5175                                                dst_rect);
5176             break;
5177         case VA_FOURCC_YUY2:
5178         case VA_FOURCC_UYVY:
5179             status = i965_image_pl1_processing(ctx,
5180                                                src_surface,
5181                                                src_rect,
5182                                                dst_surface,
5183                                                dst_rect);
5184             break;
5185         case VA_FOURCC_BGRA:
5186         case VA_FOURCC_BGRX:
5187         case VA_FOURCC_RGBA:
5188         case VA_FOURCC_RGBX:
5189             status = i965_image_pl1_rgbx_processing(ctx,
5190                                                src_surface,
5191                                                src_rect,
5192                                                dst_surface,
5193                                                dst_rect);
5194             break;
5195         default:
5196             status = VA_STATUS_ERROR_UNIMPLEMENTED;
5197             break;
5198         }
5199         
5200         _i965UnlockMutex(&i965->pp_mutex);
5201     }
5202
5203     return status;
5204 }       
5205
5206 static void
5207 i965_post_processing_context_finalize(struct i965_post_processing_context *pp_context)
5208 {
5209     int i;
5210
5211     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
5212     pp_context->surface_state_binding_table.bo = NULL;
5213
5214     dri_bo_unreference(pp_context->curbe.bo);
5215     pp_context->curbe.bo = NULL;
5216
5217     dri_bo_unreference(pp_context->sampler_state_table.bo);
5218     pp_context->sampler_state_table.bo = NULL;
5219
5220     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
5221     pp_context->sampler_state_table.bo_8x8 = NULL;
5222
5223     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
5224     pp_context->sampler_state_table.bo_8x8_uv = NULL;
5225
5226     dri_bo_unreference(pp_context->idrt.bo);
5227     pp_context->idrt.bo = NULL;
5228     pp_context->idrt.num_interface_descriptors = 0;
5229
5230     dri_bo_unreference(pp_context->vfe_state.bo);
5231     pp_context->vfe_state.bo = NULL;
5232
5233     dri_bo_unreference(pp_context->pp_dndi_context.stmm_bo);
5234     pp_context->pp_dndi_context.stmm_bo = NULL;
5235
5236     dri_bo_unreference(pp_context->pp_dn_context.stmm_bo);
5237     pp_context->pp_dn_context.stmm_bo = NULL;
5238
5239     for (i = 0; i < NUM_PP_MODULES; i++) {
5240         struct pp_module *pp_module = &pp_context->pp_modules[i];
5241
5242         dri_bo_unreference(pp_module->kernel.bo);
5243         pp_module->kernel.bo = NULL;
5244     }
5245
5246     free(pp_context->pp_static_parameter);
5247     free(pp_context->pp_inline_parameter);
5248     pp_context->pp_static_parameter = NULL;
5249     pp_context->pp_inline_parameter = NULL;
5250 }
5251
5252 void
5253 i965_post_processing_terminate(VADriverContextP ctx)
5254 {
5255     struct i965_driver_data *i965 = i965_driver_data(ctx);
5256     struct i965_post_processing_context *pp_context = i965->pp_context;
5257
5258     if (pp_context) {
5259         pp_context->finalize(pp_context);
5260         free(pp_context);
5261     }
5262
5263     i965->pp_context = NULL;
5264 }
5265
5266 #define VPP_CURBE_ALLOCATION_SIZE       32
5267
5268 void
5269 i965_post_processing_context_init(VADriverContextP ctx,
5270                                   void *data,
5271                                   struct intel_batchbuffer *batch)
5272 {
5273     struct i965_driver_data *i965 = i965_driver_data(ctx);
5274     int i;
5275     struct i965_post_processing_context *pp_context = data;
5276
5277     if (IS_IRONLAKE(i965->intel.device_info)) {
5278         pp_context->urb.size = i965->intel.device_info->urb_size;
5279         pp_context->urb.num_vfe_entries = 32;
5280         pp_context->urb.size_vfe_entry = 1;     /* in 512 bits unit */
5281         pp_context->urb.num_cs_entries = 1;
5282         pp_context->urb.size_cs_entry = 2;
5283         pp_context->urb.vfe_start = 0;
5284         pp_context->urb.cs_start = pp_context->urb.vfe_start + 
5285             pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
5286         assert(pp_context->urb.cs_start +
5287            pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= i965->intel.device_info->urb_size);
5288         pp_context->intel_post_processing = ironlake_post_processing;
5289     } else {
5290         pp_context->vfe_gpu_state.max_num_threads = 60;
5291         pp_context->vfe_gpu_state.num_urb_entries = 59;
5292         pp_context->vfe_gpu_state.gpgpu_mode = 0;
5293         pp_context->vfe_gpu_state.urb_entry_size = 16 - 1;
5294         pp_context->vfe_gpu_state.curbe_allocation_size = VPP_CURBE_ALLOCATION_SIZE;
5295         pp_context->intel_post_processing = gen6_post_processing;
5296     }
5297
5298     pp_context->finalize = i965_post_processing_context_finalize;
5299
5300     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
5301     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
5302     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen7));
5303     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen75));
5304
5305     if (IS_HASWELL(i965->intel.device_info))
5306         memcpy(pp_context->pp_modules, pp_modules_gen75, sizeof(pp_context->pp_modules));
5307     else if (IS_GEN7(i965->intel.device_info))
5308         memcpy(pp_context->pp_modules, pp_modules_gen7, sizeof(pp_context->pp_modules));
5309     else if (IS_GEN6(i965->intel.device_info))
5310         memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
5311     else if (IS_IRONLAKE(i965->intel.device_info))
5312         memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
5313
5314     for (i = 0; i < NUM_PP_MODULES; i++) {
5315         struct pp_module *pp_module = &pp_context->pp_modules[i];
5316         dri_bo_unreference(pp_module->kernel.bo);
5317         if (pp_module->kernel.bin && pp_module->kernel.size) {
5318             pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
5319                                                 pp_module->kernel.name,
5320                                                 pp_module->kernel.size,
5321                                                 4096);
5322             assert(pp_module->kernel.bo);
5323             dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
5324         } else {
5325             pp_module->kernel.bo = NULL;
5326         }
5327     }
5328
5329     /* static & inline parameters */
5330     if (IS_GEN7(i965->intel.device_info)) {
5331         pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
5332         pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
5333     } else {
5334         pp_context->pp_static_parameter = calloc(sizeof(struct pp_static_parameter), 1);
5335         pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
5336     }
5337
5338     pp_context->pp_dndi_context.current_out_surface = VA_INVALID_SURFACE;
5339     pp_context->pp_dndi_context.current_out_obj_surface = NULL;
5340     pp_context->pp_dndi_context.frame_order = -1;
5341     pp_context->batch = batch;
5342 }
5343
5344 bool
5345 i965_post_processing_init(VADriverContextP ctx)
5346 {
5347     struct i965_driver_data *i965 = i965_driver_data(ctx);
5348     struct i965_post_processing_context *pp_context = i965->pp_context;
5349
5350     if (HAS_VPP(i965)) {
5351         if (pp_context == NULL) {
5352             pp_context = calloc(1, sizeof(*pp_context));
5353             i965->codec_info->post_processing_context_init(ctx, pp_context, i965->pp_batch);
5354             i965->pp_context = pp_context;
5355         }
5356     }
5357
5358     return true;
5359 }
5360
5361 static const int procfilter_to_pp_flag[VAProcFilterCount] = {
5362     PP_NULL,    /* VAProcFilterNone */
5363     PP_NV12_DN, /* VAProcFilterNoiseReduction */
5364     PP_NV12_DNDI, /* VAProcFilterDeinterlacing */
5365     PP_NULL,    /* VAProcFilterSharpening */
5366     PP_NULL,    /* VAProcFilterColorBalance */
5367 };
5368
5369 static const int proc_frame_to_pp_frame[3] = {
5370     I965_SURFACE_FLAG_FRAME,
5371     I965_SURFACE_FLAG_TOP_FIELD_FIRST,
5372     I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST
5373 };
5374
5375 VAStatus 
5376 i965_proc_picture(VADriverContextP ctx, 
5377                   VAProfile profile, 
5378                   union codec_state *codec_state,
5379                   struct hw_context *hw_context)
5380 {
5381     struct i965_driver_data *i965 = i965_driver_data(ctx);
5382     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
5383     struct proc_state *proc_state = &codec_state->proc;
5384     VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
5385     struct object_surface *obj_surface;
5386     struct i965_surface src_surface, dst_surface;
5387     VARectangle src_rect, dst_rect;
5388     VAStatus status;
5389     int i;
5390     VASurfaceID tmp_surfaces[VAProcFilterCount + 4];
5391     int num_tmp_surfaces = 0;
5392     unsigned int tiling = 0, swizzle = 0;
5393     int in_width, in_height;
5394
5395     if (pipeline_param->surface == VA_INVALID_ID ||
5396         proc_state->current_render_target == VA_INVALID_ID) {
5397         status = VA_STATUS_ERROR_INVALID_SURFACE;
5398         goto error;
5399     }
5400
5401     obj_surface = SURFACE(pipeline_param->surface);
5402
5403     if (!obj_surface) {
5404         status = VA_STATUS_ERROR_INVALID_SURFACE;
5405         goto error;
5406     }
5407
5408     if (!obj_surface->bo) {
5409         status = VA_STATUS_ERROR_INVALID_VALUE; /* The input surface is created without valid content */
5410         goto error;
5411     }
5412
5413     if (pipeline_param->num_filters && !pipeline_param->filters) {
5414         status = VA_STATUS_ERROR_INVALID_PARAMETER;
5415         goto error;
5416     }
5417
5418     in_width = obj_surface->orig_width;
5419     in_height = obj_surface->orig_height;
5420     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
5421
5422     src_surface.base = (struct object_base *)obj_surface;
5423     src_surface.type = I965_SURFACE_TYPE_SURFACE;
5424     src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
5425
5426     VASurfaceID out_surface_id = VA_INVALID_ID;
5427     if (obj_surface->fourcc != VA_FOURCC_NV12) {
5428         src_surface.base = (struct object_base *)obj_surface;
5429         src_surface.type = I965_SURFACE_TYPE_SURFACE;
5430         src_surface.flags = I965_SURFACE_FLAG_FRAME;
5431         src_rect.x = 0;
5432         src_rect.y = 0;
5433         src_rect.width = in_width;
5434         src_rect.height = in_height;
5435
5436         status = i965_CreateSurfaces(ctx,
5437                                      in_width,
5438                                      in_height,
5439                                      VA_RT_FORMAT_YUV420,
5440                                      1,
5441                                      &out_surface_id);
5442         assert(status == VA_STATUS_SUCCESS);
5443         tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5444         obj_surface = SURFACE(out_surface_id);
5445         assert(obj_surface);
5446         i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5447
5448         dst_surface.base = (struct object_base *)obj_surface;
5449         dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5450         dst_surface.flags = I965_SURFACE_FLAG_FRAME;
5451         dst_rect.x = 0;
5452         dst_rect.y = 0;
5453         dst_rect.width = in_width;
5454         dst_rect.height = in_height;
5455
5456         status = i965_image_processing(ctx,
5457                                        &src_surface,
5458                                        &src_rect,
5459                                        &dst_surface,
5460                                        &dst_rect);
5461         assert(status == VA_STATUS_SUCCESS);
5462
5463         src_surface.base = (struct object_base *)obj_surface;
5464         src_surface.type = I965_SURFACE_TYPE_SURFACE;
5465         src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
5466     }
5467
5468     if (pipeline_param->surface_region) {
5469         src_rect.x = pipeline_param->surface_region->x;
5470         src_rect.y = pipeline_param->surface_region->y;
5471         src_rect.width = pipeline_param->surface_region->width;
5472         src_rect.height = pipeline_param->surface_region->height;
5473     } else {
5474         src_rect.x = 0;
5475         src_rect.y = 0;
5476         src_rect.width = in_width;
5477         src_rect.height = in_height;
5478     }
5479
5480     if (pipeline_param->output_region) {
5481         dst_rect.x = pipeline_param->output_region->x;
5482         dst_rect.y = pipeline_param->output_region->y;
5483         dst_rect.width = pipeline_param->output_region->width;
5484         dst_rect.height = pipeline_param->output_region->height;
5485     } else {
5486         dst_rect.x = 0;
5487         dst_rect.y = 0;
5488         dst_rect.width = in_width;
5489         dst_rect.height = in_height;
5490     }
5491
5492     proc_context->pp_context.pipeline_param = pipeline_param;
5493
5494     for (i = 0; i < pipeline_param->num_filters; i++) {
5495         struct object_buffer *obj_buffer = BUFFER(pipeline_param->filters[i]);
5496         VAProcFilterParameterBufferBase *filter_param = NULL;
5497         VAProcFilterType filter_type;
5498         int kernel_index;
5499
5500         if (!obj_buffer ||
5501             !obj_buffer->buffer_store ||
5502             !obj_buffer->buffer_store->buffer) {
5503             status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
5504             goto error;
5505         }
5506
5507         out_surface_id = VA_INVALID_ID;
5508         filter_param = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5509         filter_type = filter_param->type;
5510         kernel_index = procfilter_to_pp_flag[filter_type];
5511
5512         if (kernel_index != PP_NULL &&
5513             proc_context->pp_context.pp_modules[kernel_index].kernel.bo != NULL) {
5514             status = i965_CreateSurfaces(ctx,
5515                                          in_width,
5516                                          in_height,
5517                                          VA_RT_FORMAT_YUV420,
5518                                          1,
5519                                          &out_surface_id);
5520             assert(status == VA_STATUS_SUCCESS);
5521             tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5522             obj_surface = SURFACE(out_surface_id);
5523             assert(obj_surface);
5524             i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5525             dst_surface.base = (struct object_base *)obj_surface;
5526             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5527             status = i965_post_processing_internal(ctx, &proc_context->pp_context,
5528                                                    &src_surface,
5529                                                    &src_rect,
5530                                                    &dst_surface,
5531                                                    &src_rect,
5532                                                    kernel_index,
5533                                                    filter_param);
5534
5535             if (status == VA_STATUS_SUCCESS) {
5536                 src_surface.base = dst_surface.base;
5537                 src_surface.type = dst_surface.type;
5538                 src_surface.flags = dst_surface.flags;
5539             }
5540         }
5541     }
5542
5543     proc_context->pp_context.pipeline_param = NULL;
5544     obj_surface = SURFACE(proc_state->current_render_target);
5545     
5546     if (!obj_surface) {
5547         status = VA_STATUS_ERROR_INVALID_SURFACE;
5548         goto error;
5549     }
5550
5551     int csc_needed = 0;
5552     if (obj_surface->fourcc && obj_surface->fourcc !=  VA_FOURCC_NV12){
5553         csc_needed = 1;
5554         out_surface_id = VA_INVALID_ID;
5555         status = i965_CreateSurfaces(ctx,
5556                                      obj_surface->orig_width,
5557                                      obj_surface->orig_height,
5558                                      VA_RT_FORMAT_YUV420, 
5559                                      1,
5560                                      &out_surface_id);
5561         assert(status == VA_STATUS_SUCCESS);
5562         tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5563         struct object_surface *csc_surface = SURFACE(out_surface_id);
5564         assert(csc_surface);
5565         i965_check_alloc_surface_bo(ctx, csc_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5566         dst_surface.base = (struct object_base *)csc_surface;
5567     } else {
5568         i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5569         dst_surface.base = (struct object_base *)obj_surface;
5570     }
5571
5572     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5573     i965_vpp_clear_surface(ctx, &proc_context->pp_context, obj_surface, pipeline_param->output_background_color); 
5574
5575     // load/save doesn't support different origin offset for src and dst surface
5576     if (src_rect.width == dst_rect.width &&
5577         src_rect.height == dst_rect.height &&
5578         src_rect.x == dst_rect.x &&
5579         src_rect.y == dst_rect.y) {
5580         i965_post_processing_internal(ctx, &proc_context->pp_context,
5581                                       &src_surface,
5582                                       &src_rect,
5583                                       &dst_surface,
5584                                       &dst_rect,
5585                                       PP_NV12_LOAD_SAVE_N12,
5586                                       NULL);
5587     } else {
5588
5589         i965_post_processing_internal(ctx, &proc_context->pp_context,
5590                                       &src_surface,
5591                                       &src_rect,
5592                                       &dst_surface,
5593                                       &dst_rect,
5594                                       (pipeline_param->filter_flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC ?
5595                                       PP_NV12_AVS : PP_NV12_SCALING,
5596                                       NULL);
5597     }
5598
5599     if (csc_needed) {
5600         src_surface.base = dst_surface.base;
5601         src_surface.type = dst_surface.type;
5602         src_surface.flags = dst_surface.flags;
5603         dst_surface.base = (struct object_base *)obj_surface;
5604         dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5605         i965_image_processing(ctx, &src_surface, &dst_rect, &dst_surface, &dst_rect);
5606     }
5607     
5608     if (num_tmp_surfaces)
5609         i965_DestroySurfaces(ctx,
5610                              tmp_surfaces,
5611                              num_tmp_surfaces);
5612
5613     intel_batchbuffer_flush(hw_context->batch);
5614
5615     return VA_STATUS_SUCCESS;
5616
5617 error:
5618     if (num_tmp_surfaces)
5619         i965_DestroySurfaces(ctx,
5620                              tmp_surfaces,
5621                              num_tmp_surfaces);
5622
5623     return status;
5624 }
5625
5626 static void
5627 i965_proc_context_destroy(void *hw_context)
5628 {
5629     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
5630
5631     i965_post_processing_context_finalize(&proc_context->pp_context);
5632     intel_batchbuffer_free(proc_context->base.batch);
5633     free(proc_context);
5634 }
5635
5636 struct hw_context *
5637 i965_proc_context_init(VADriverContextP ctx, struct object_config *obj_config)
5638 {
5639     struct i965_driver_data *i965 = i965_driver_data(ctx);
5640     struct intel_driver_data *intel = intel_driver_data(ctx);
5641     struct i965_proc_context *proc_context = calloc(1, sizeof(struct i965_proc_context));
5642
5643     proc_context->base.destroy = i965_proc_context_destroy;
5644     proc_context->base.run = i965_proc_picture;
5645     proc_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
5646     i965->codec_info->post_processing_context_init(ctx, &proc_context->pp_context, proc_context->base.batch);
5647
5648     return (struct hw_context *)proc_context;
5649 }
5650
5651