clear background under right context
[profile/ivi/vaapi-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
42 #define HAS_PP(ctx) (IS_IRONLAKE((ctx)->intel.device_id) ||     \
43                      IS_GEN6((ctx)->intel.device_id) ||         \
44                      IS_GEN7((ctx)->intel.device_id))
45
46 #define SURFACE_STATE_PADDED_SIZE_0_I965        ALIGN(sizeof(struct i965_surface_state), 32)
47 #define SURFACE_STATE_PADDED_SIZE_1_I965        ALIGN(sizeof(struct i965_surface_state2), 32)
48 #define SURFACE_STATE_PADDED_SIZE_I965          MAX(SURFACE_STATE_PADDED_SIZE_0_I965, SURFACE_STATE_PADDED_SIZE_1_I965)
49
50 #define SURFACE_STATE_PADDED_SIZE_0_GEN7        ALIGN(sizeof(struct gen7_surface_state), 32)
51 #define SURFACE_STATE_PADDED_SIZE_1_GEN7        ALIGN(sizeof(struct gen7_surface_state2), 32)
52 #define SURFACE_STATE_PADDED_SIZE_GEN7          MAX(SURFACE_STATE_PADDED_SIZE_0_GEN7, SURFACE_STATE_PADDED_SIZE_1_GEN7)
53
54 #define SURFACE_STATE_PADDED_SIZE               MAX(SURFACE_STATE_PADDED_SIZE_I965, SURFACE_STATE_PADDED_SIZE_GEN7)
55 #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
56 #define BINDING_TABLE_OFFSET                    SURFACE_STATE_OFFSET(MAX_PP_SURFACES)
57
58 static const uint32_t pp_null_gen5[][4] = {
59 #include "shaders/post_processing/gen5_6/null.g4b.gen5"
60 };
61
62 static const uint32_t pp_nv12_load_save_nv12_gen5[][4] = {
63 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g4b.gen5"
64 };
65
66 static const uint32_t pp_nv12_load_save_pl3_gen5[][4] = {
67 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g4b.gen5"
68 };
69
70 static const uint32_t pp_pl3_load_save_nv12_gen5[][4] = {
71 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g4b.gen5"
72 };
73
74 static const uint32_t pp_pl3_load_save_pl3_gen5[][4] = {
75 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g4b.gen5"
76 };
77
78 static const uint32_t pp_nv12_scaling_gen5[][4] = {
79 #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g4b.gen5"
80 };
81
82 static const uint32_t pp_nv12_avs_gen5[][4] = {
83 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g4b.gen5"
84 };
85
86 static const uint32_t pp_nv12_dndi_gen5[][4] = {
87 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g4b.gen5"
88 };
89
90 static const uint32_t pp_nv12_dn_gen5[][4] = {
91 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g4b.gen5"
92 };
93
94 static const uint32_t pp_nv12_load_save_pa_gen5[][4] = {
95 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g4b.gen5"
96 };
97
98 static const uint32_t pp_pl3_load_save_pa_gen5[][4] = {
99 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g4b.gen5"
100 };
101
102 static const uint32_t pp_pa_load_save_nv12_gen5[][4] = {
103 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g4b.gen5"
104 };
105
106 static VAStatus pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
107                                    const struct i965_surface *src_surface,
108                                    const VARectangle *src_rect,
109                                    struct i965_surface *dst_surface,
110                                    const VARectangle *dst_rect,
111                                    void *filter_param);
112 static VAStatus pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
113                                             const struct i965_surface *src_surface,
114                                             const VARectangle *src_rect,
115                                             struct i965_surface *dst_surface,
116                                             const VARectangle *dst_rect,
117                                             void *filter_param);
118 static VAStatus pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
119                                            const struct i965_surface *src_surface,
120                                            const VARectangle *src_rect,
121                                            struct i965_surface *dst_surface,
122                                            const VARectangle *dst_rect,
123                                            void *filter_param);
124 static VAStatus gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
125                                              const struct i965_surface *src_surface,
126                                              const VARectangle *src_rect,
127                                              struct i965_surface *dst_surface,
128                                              const VARectangle *dst_rect,
129                                              void *filter_param);
130 static VAStatus pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
131                                                 const struct i965_surface *src_surface,
132                                                 const VARectangle *src_rect,
133                                                 struct i965_surface *dst_surface,
134                                                 const VARectangle *dst_rect,
135                                                 void *filter_param);
136 static VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
137                                         const struct i965_surface *src_surface,
138                                         const VARectangle *src_rect,
139                                         struct i965_surface *dst_surface,
140                                         const VARectangle *dst_rect,
141                                         void *filter_param);
142 static VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
143                                       const struct i965_surface *src_surface,
144                                       const VARectangle *src_rect,
145                                       struct i965_surface *dst_surface,
146                                       const VARectangle *dst_rect,
147                                       void *filter_param);
148
149 static struct pp_module pp_modules_gen5[] = {
150     {
151         {
152             "NULL module (for testing)",
153             PP_NULL,
154             pp_null_gen5,
155             sizeof(pp_null_gen5),
156             NULL,
157         },
158
159         pp_null_initialize,
160     },
161
162     {
163         {
164             "NV12_NV12",
165             PP_NV12_LOAD_SAVE_N12,
166             pp_nv12_load_save_nv12_gen5,
167             sizeof(pp_nv12_load_save_nv12_gen5),
168             NULL,
169         },
170
171         pp_plx_load_save_plx_initialize,
172     },
173
174     {
175         {
176             "NV12_PL3",
177             PP_NV12_LOAD_SAVE_PL3,
178             pp_nv12_load_save_pl3_gen5,
179             sizeof(pp_nv12_load_save_pl3_gen5),
180             NULL,
181         },
182
183         pp_plx_load_save_plx_initialize,
184     },
185
186     {
187         {
188             "PL3_NV12",
189             PP_PL3_LOAD_SAVE_N12,
190             pp_pl3_load_save_nv12_gen5,
191             sizeof(pp_pl3_load_save_nv12_gen5),
192             NULL,
193         },
194
195         pp_plx_load_save_plx_initialize,
196     },
197
198     {
199         {
200             "PL3_PL3",
201             PP_PL3_LOAD_SAVE_N12,
202             pp_pl3_load_save_pl3_gen5,
203             sizeof(pp_pl3_load_save_pl3_gen5),
204             NULL,
205         },
206
207         pp_plx_load_save_plx_initialize
208     },
209
210     {
211         {
212             "NV12 Scaling module",
213             PP_NV12_SCALING,
214             pp_nv12_scaling_gen5,
215             sizeof(pp_nv12_scaling_gen5),
216             NULL,
217         },
218
219         pp_nv12_scaling_initialize,
220     },
221
222     {
223         {
224             "NV12 AVS module",
225             PP_NV12_AVS,
226             pp_nv12_avs_gen5,
227             sizeof(pp_nv12_avs_gen5),
228             NULL,
229         },
230
231         pp_nv12_avs_initialize_nlas,
232     },
233
234     {
235         {
236             "NV12 DNDI module",
237             PP_NV12_DNDI,
238             pp_nv12_dndi_gen5,
239             sizeof(pp_nv12_dndi_gen5),
240             NULL,
241         },
242
243         pp_nv12_dndi_initialize,
244     },
245
246     {
247         {
248             "NV12 DN module",
249             PP_NV12_DN,
250             pp_nv12_dn_gen5,
251             sizeof(pp_nv12_dn_gen5),
252             NULL,
253         },
254
255         pp_nv12_dn_initialize,
256     },
257
258     {
259         {
260             "NV12_PA module",
261             PP_NV12_LOAD_SAVE_PA,
262             pp_nv12_load_save_pa_gen5,
263             sizeof(pp_nv12_load_save_pa_gen5),
264             NULL,
265         },
266     
267         pp_plx_load_save_plx_initialize,
268     },
269
270     {
271         {
272             "PL3_PA module",
273             PP_PL3_LOAD_SAVE_PA,
274             pp_pl3_load_save_pa_gen5,
275             sizeof(pp_pl3_load_save_pa_gen5),
276             NULL,
277         },
278     
279         pp_plx_load_save_plx_initialize,
280     },
281
282     {
283         {
284             "PA_NV12 module",
285             PP_PA_LOAD_SAVE_NV12,
286             pp_pa_load_save_nv12_gen5,
287             sizeof(pp_pa_load_save_nv12_gen5),
288             NULL,
289         },
290     
291         pp_plx_load_save_plx_initialize,
292     },
293
294 };
295
296 static const uint32_t pp_null_gen6[][4] = {
297 #include "shaders/post_processing/gen5_6/null.g6b"
298 };
299
300 static const uint32_t pp_nv12_load_save_nv12_gen6[][4] = {
301 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g6b"
302 };
303
304 static const uint32_t pp_nv12_load_save_pl3_gen6[][4] = {
305 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g6b"
306 };
307
308 static const uint32_t pp_pl3_load_save_nv12_gen6[][4] = {
309 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g6b"
310 };
311
312 static const uint32_t pp_pl3_load_save_pl3_gen6[][4] = {
313 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g6b"
314 };
315
316 static const uint32_t pp_nv12_scaling_gen6[][4] = {
317 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
318 };
319
320 static const uint32_t pp_nv12_avs_gen6[][4] = {
321 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
322 };
323
324 static const uint32_t pp_nv12_dndi_gen6[][4] = {
325 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g6b"
326 };
327
328 static const uint32_t pp_nv12_dn_gen6[][4] = {
329 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g6b"
330 };
331
332 static const uint32_t pp_nv12_load_save_pa_gen6[][4] = {
333 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g6b"
334 };
335
336 static const uint32_t pp_pl3_load_save_pa_gen6[][4] = {
337 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g6b"
338 };
339
340 static const uint32_t pp_pa_load_save_nv12_gen6[][4] = {
341 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g6b"
342 };
343
344 static struct pp_module pp_modules_gen6[] = {
345     {
346         {
347             "NULL module (for testing)",
348             PP_NULL,
349             pp_null_gen6,
350             sizeof(pp_null_gen6),
351             NULL,
352         },
353
354         pp_null_initialize,
355     },
356
357     {
358         {
359             "NV12_NV12",
360             PP_NV12_LOAD_SAVE_N12,
361             pp_nv12_load_save_nv12_gen6,
362             sizeof(pp_nv12_load_save_nv12_gen6),
363             NULL,
364         },
365
366         pp_plx_load_save_plx_initialize,
367     },
368
369     {
370         {
371             "NV12_PL3",
372             PP_NV12_LOAD_SAVE_PL3,
373             pp_nv12_load_save_pl3_gen6,
374             sizeof(pp_nv12_load_save_pl3_gen6),
375             NULL,
376         },
377         
378         pp_plx_load_save_plx_initialize,
379     },
380
381     {
382         {
383             "PL3_NV12",
384             PP_PL3_LOAD_SAVE_N12,
385             pp_pl3_load_save_nv12_gen6,
386             sizeof(pp_pl3_load_save_nv12_gen6),
387             NULL,
388         },
389
390         pp_plx_load_save_plx_initialize,
391     },
392
393     {
394         {
395             "PL3_PL3",
396             PP_PL3_LOAD_SAVE_N12,
397             pp_pl3_load_save_pl3_gen6,
398             sizeof(pp_pl3_load_save_pl3_gen6),
399             NULL,
400         },
401
402         pp_plx_load_save_plx_initialize,
403     },
404
405     {
406         {
407             "NV12 Scaling module",
408             PP_NV12_SCALING,
409             pp_nv12_scaling_gen6,
410             sizeof(pp_nv12_scaling_gen6),
411             NULL,
412         },
413
414         gen6_nv12_scaling_initialize,
415     },
416
417     {
418         {
419             "NV12 AVS module",
420             PP_NV12_AVS,
421             pp_nv12_avs_gen6,
422             sizeof(pp_nv12_avs_gen6),
423             NULL,
424         },
425
426         pp_nv12_avs_initialize_nlas,
427     },
428
429     {
430         {
431             "NV12 DNDI module",
432             PP_NV12_DNDI,
433             pp_nv12_dndi_gen6,
434             sizeof(pp_nv12_dndi_gen6),
435             NULL,
436         },
437
438         pp_nv12_dndi_initialize,
439     },
440
441     {
442         {
443             "NV12 DN module",
444             PP_NV12_DN,
445             pp_nv12_dn_gen6,
446             sizeof(pp_nv12_dn_gen6),
447             NULL,
448         },
449
450         pp_nv12_dn_initialize,
451     },
452     {
453         {
454             "NV12_PA module",
455             PP_NV12_LOAD_SAVE_PA,
456             pp_nv12_load_save_pa_gen6,
457             sizeof(pp_nv12_load_save_pa_gen6),
458             NULL,
459         },
460     
461         pp_plx_load_save_plx_initialize,
462     },
463     
464     {
465         {
466             "PL3_PA module",
467             PP_PL3_LOAD_SAVE_PA,
468             pp_pl3_load_save_pa_gen6,
469             sizeof(pp_pl3_load_save_pa_gen6),
470             NULL,
471         },
472     
473         pp_plx_load_save_plx_initialize,
474     },
475     
476     {
477         {
478             "PA_NV12 module",
479             PP_PA_LOAD_SAVE_NV12,
480             pp_pa_load_save_nv12_gen6,
481             sizeof(pp_pa_load_save_nv12_gen6),
482             NULL,
483         },
484     
485         pp_plx_load_save_plx_initialize,
486     },
487     
488 };
489
490 static const uint32_t pp_null_gen7[][4] = {
491 };
492
493 static const uint32_t pp_nv12_load_save_nv12_gen7[][4] = {
494 #include "shaders/post_processing/gen7/pl2_to_pl2.g7b"
495 };
496
497 static const uint32_t pp_nv12_load_save_pl3_gen7[][4] = {
498 #include "shaders/post_processing/gen7/pl2_to_pl3.g7b"
499 };
500
501 static const uint32_t pp_pl3_load_save_nv12_gen7[][4] = {
502 #include "shaders/post_processing/gen7/pl3_to_pl2.g7b"
503 };
504
505 static const uint32_t pp_pl3_load_save_pl3_gen7[][4] = {
506 #include "shaders/post_processing/gen7/pl3_to_pl3.g7b"
507 };
508
509 static const uint32_t pp_nv12_scaling_gen7[][4] = {
510 #include "shaders/post_processing/gen7/avs.g7b"
511 };
512
513 static const uint32_t pp_nv12_avs_gen7[][4] = {
514 #include "shaders/post_processing/gen7/avs.g7b"
515 };
516
517 static const uint32_t pp_nv12_dndi_gen7[][4] = {
518 // #include "shaders/post_processing/gen7/dndi.g7b"
519 };
520
521 static const uint32_t pp_nv12_dn_gen7[][4] = {
522 };
523 static const uint32_t pp_nv12_load_save_pa_gen7[][4] = {
524 };
525 static const uint32_t pp_pl3_load_save_pa_gen7[][4] = {
526 };
527 static const uint32_t pp_pa_load_save_nv12_gen7[][4] = {
528 };
529
530 static VAStatus gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
531                                            const struct i965_surface *src_surface,
532                                            const VARectangle *src_rect,
533                                            struct i965_surface *dst_surface,
534                                            const VARectangle *dst_rect,
535                                            void *filter_param);
536 static VAStatus gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
537                                              const struct i965_surface *src_surface,
538                                              const VARectangle *src_rect,
539                                              struct i965_surface *dst_surface,
540                                              const VARectangle *dst_rect,
541                                              void *filter_param);
542 static VAStatus gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
543                                            const struct i965_surface *src_surface,
544                                            const VARectangle *src_rect,
545                                            struct i965_surface *dst_surface,
546                                            const VARectangle *dst_rect,
547                                            void *filter_param);
548
549 static struct pp_module pp_modules_gen7[] = {
550     {
551         {
552             "NULL module (for testing)",
553             PP_NULL,
554             pp_null_gen7,
555             sizeof(pp_null_gen7),
556             NULL,
557         },
558
559         pp_null_initialize,
560     },
561
562     {
563         {
564             "NV12_NV12",
565             PP_NV12_LOAD_SAVE_N12,
566             pp_nv12_load_save_nv12_gen7,
567             sizeof(pp_nv12_load_save_nv12_gen7),
568             NULL,
569         },
570
571         gen7_pp_plx_avs_initialize,
572     },
573
574     {
575         {
576             "NV12_PL3",
577             PP_NV12_LOAD_SAVE_PL3,
578             pp_nv12_load_save_pl3_gen7,
579             sizeof(pp_nv12_load_save_pl3_gen7),
580             NULL,
581         },
582         
583         gen7_pp_plx_avs_initialize,
584     },
585
586     {
587         {
588             "PL3_NV12",
589             PP_PL3_LOAD_SAVE_N12,
590             pp_pl3_load_save_nv12_gen7,
591             sizeof(pp_pl3_load_save_nv12_gen7),
592             NULL,
593         },
594
595         gen7_pp_plx_avs_initialize,
596     },
597
598     {
599         {
600             "PL3_PL3",
601             PP_PL3_LOAD_SAVE_N12,
602             pp_pl3_load_save_pl3_gen7,
603             sizeof(pp_pl3_load_save_pl3_gen7),
604             NULL,
605         },
606
607         gen7_pp_plx_avs_initialize,
608     },
609
610     {
611         {
612             "NV12 Scaling module",
613             PP_NV12_SCALING,
614             pp_nv12_scaling_gen7,
615             sizeof(pp_nv12_scaling_gen7),
616             NULL,
617         },
618
619         gen7_pp_plx_avs_initialize,
620     },
621
622     {
623         {
624             "NV12 AVS module",
625             PP_NV12_AVS,
626             pp_nv12_avs_gen7,
627             sizeof(pp_nv12_avs_gen7),
628             NULL,
629         },
630
631         gen7_pp_plx_avs_initialize,
632     },
633
634     {
635         {
636             "NV12 DNDI module",
637             PP_NV12_DNDI,
638             pp_nv12_dndi_gen7,
639             sizeof(pp_nv12_dndi_gen7),
640             NULL,
641         },
642
643         gen7_pp_nv12_dndi_initialize,
644     },
645
646     {
647         {
648             "NV12 DN module",
649             PP_NV12_DN,
650             pp_nv12_dn_gen7,
651             sizeof(pp_nv12_dn_gen7),
652             NULL,
653         },
654
655         gen7_pp_nv12_dn_initialize,
656     },
657     {
658         {
659             "NV12_PA module",
660             PP_NV12_LOAD_SAVE_PA,
661             pp_nv12_load_save_pa_gen7,
662             sizeof(pp_nv12_load_save_pa_gen7),
663             NULL,
664         },
665     
666         pp_plx_load_save_plx_initialize,
667     },
668
669     {
670         {
671             "PL3_PA module",
672             PP_PL3_LOAD_SAVE_PA,
673             pp_pl3_load_save_pa_gen7,
674             sizeof(pp_pl3_load_save_pa_gen7),
675             NULL,
676         },
677     
678         pp_plx_load_save_plx_initialize,
679     },
680
681     {
682         {
683             "PA_NV12 module",
684             PP_PA_LOAD_SAVE_NV12,
685             pp_pa_load_save_nv12_gen7,
686             sizeof(pp_pa_load_save_nv12_gen7),
687             NULL,
688         },
689     
690         pp_plx_load_save_plx_initialize,
691     },
692     
693 };
694
695 static int
696 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
697 {
698     struct i965_driver_data *i965 = i965_driver_data(ctx);
699     int fourcc;
700
701     if (surface->type == I965_SURFACE_TYPE_IMAGE) {
702         struct object_image *obj_image = IMAGE(surface->id);
703         fourcc = obj_image->image.format.fourcc;
704     } else {
705         struct object_surface *obj_surface = SURFACE(surface->id);
706         fourcc = obj_surface->fourcc;
707     }
708
709     return fourcc;
710 }
711
712 static void
713 pp_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
714 {
715     switch (tiling) {
716     case I915_TILING_NONE:
717         ss->ss3.tiled_surface = 0;
718         ss->ss3.tile_walk = 0;
719         break;
720     case I915_TILING_X:
721         ss->ss3.tiled_surface = 1;
722         ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
723         break;
724     case I915_TILING_Y:
725         ss->ss3.tiled_surface = 1;
726         ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
727         break;
728     }
729 }
730
731 static void
732 pp_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
733 {
734     switch (tiling) {
735     case I915_TILING_NONE:
736         ss->ss2.tiled_surface = 0;
737         ss->ss2.tile_walk = 0;
738         break;
739     case I915_TILING_X:
740         ss->ss2.tiled_surface = 1;
741         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
742         break;
743     case I915_TILING_Y:
744         ss->ss2.tiled_surface = 1;
745         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
746         break;
747     }
748 }
749
750 static void
751 gen7_pp_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
752 {
753     switch (tiling) {
754     case I915_TILING_NONE:
755         ss->ss0.tiled_surface = 0;
756         ss->ss0.tile_walk = 0;
757         break;
758     case I915_TILING_X:
759         ss->ss0.tiled_surface = 1;
760         ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
761         break;
762     case I915_TILING_Y:
763         ss->ss0.tiled_surface = 1;
764         ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
765         break;
766     }
767 }
768
769 static void
770 gen7_pp_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
771 {
772     switch (tiling) {
773     case I915_TILING_NONE:
774         ss->ss2.tiled_surface = 0;
775         ss->ss2.tile_walk = 0;
776         break;
777     case I915_TILING_X:
778         ss->ss2.tiled_surface = 1;
779         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
780         break;
781     case I915_TILING_Y:
782         ss->ss2.tiled_surface = 1;
783         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
784         break;
785     }
786 }
787
788 static void
789 ironlake_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
790 {
791     struct i965_interface_descriptor *desc;
792     dri_bo *bo;
793     int pp_index = pp_context->current_pp;
794
795     bo = pp_context->idrt.bo;
796     dri_bo_map(bo, 1);
797     assert(bo->virtual);
798     desc = bo->virtual;
799     memset(desc, 0, sizeof(*desc));
800     desc->desc0.grf_reg_blocks = 10;
801     desc->desc0.kernel_start_pointer = pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
802     desc->desc1.const_urb_entry_read_offset = 0;
803     desc->desc1.const_urb_entry_read_len = 4; /* grf 1-4 */
804     desc->desc2.sampler_state_pointer = pp_context->sampler_state_table.bo->offset >> 5;
805     desc->desc2.sampler_count = 0;
806     desc->desc3.binding_table_entry_count = 0;
807     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
808
809     dri_bo_emit_reloc(bo,
810                       I915_GEM_DOMAIN_INSTRUCTION, 0,
811                       desc->desc0.grf_reg_blocks,
812                       offsetof(struct i965_interface_descriptor, desc0),
813                       pp_context->pp_modules[pp_index].kernel.bo);
814
815     dri_bo_emit_reloc(bo,
816                       I915_GEM_DOMAIN_INSTRUCTION, 0,
817                       desc->desc2.sampler_count << 2,
818                       offsetof(struct i965_interface_descriptor, desc2),
819                       pp_context->sampler_state_table.bo);
820
821     dri_bo_unmap(bo);
822     pp_context->idrt.num_interface_descriptors++;
823 }
824
825 static void
826 ironlake_pp_vfe_state(struct i965_post_processing_context *pp_context)
827 {
828     struct i965_vfe_state *vfe_state;
829     dri_bo *bo;
830
831     bo = pp_context->vfe_state.bo;
832     dri_bo_map(bo, 1);
833     assert(bo->virtual);
834     vfe_state = bo->virtual;
835     memset(vfe_state, 0, sizeof(*vfe_state));
836     vfe_state->vfe1.max_threads = pp_context->urb.num_vfe_entries - 1;
837     vfe_state->vfe1.urb_entry_alloc_size = pp_context->urb.size_vfe_entry - 1;
838     vfe_state->vfe1.num_urb_entries = pp_context->urb.num_vfe_entries;
839     vfe_state->vfe1.vfe_mode = VFE_GENERIC_MODE;
840     vfe_state->vfe1.children_present = 0;
841     vfe_state->vfe2.interface_descriptor_base = 
842         pp_context->idrt.bo->offset >> 4; /* reloc */
843     dri_bo_emit_reloc(bo,
844                       I915_GEM_DOMAIN_INSTRUCTION, 0,
845                       0,
846                       offsetof(struct i965_vfe_state, vfe2),
847                       pp_context->idrt.bo);
848     dri_bo_unmap(bo);
849 }
850
851 static void
852 ironlake_pp_upload_constants(struct i965_post_processing_context *pp_context)
853 {
854     unsigned char *constant_buffer;
855     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
856
857     assert(sizeof(*pp_static_parameter) == 128);
858     dri_bo_map(pp_context->curbe.bo, 1);
859     assert(pp_context->curbe.bo->virtual);
860     constant_buffer = pp_context->curbe.bo->virtual;
861     memcpy(constant_buffer, pp_static_parameter, sizeof(*pp_static_parameter));
862     dri_bo_unmap(pp_context->curbe.bo);
863 }
864
865 static void
866 ironlake_pp_states_setup(VADriverContextP ctx,
867                          struct i965_post_processing_context *pp_context)
868 {
869     ironlake_pp_interface_descriptor_table(pp_context);
870     ironlake_pp_vfe_state(pp_context);
871     ironlake_pp_upload_constants(pp_context);
872 }
873
874 static void
875 ironlake_pp_pipeline_select(VADriverContextP ctx,
876                             struct i965_post_processing_context *pp_context)
877 {
878     struct intel_batchbuffer *batch = pp_context->batch;
879
880     BEGIN_BATCH(batch, 1);
881     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
882     ADVANCE_BATCH(batch);
883 }
884
885 static void
886 ironlake_pp_urb_layout(VADriverContextP ctx,
887                        struct i965_post_processing_context *pp_context)
888 {
889     struct intel_batchbuffer *batch = pp_context->batch;
890     unsigned int vfe_fence, cs_fence;
891
892     vfe_fence = pp_context->urb.cs_start;
893     cs_fence = pp_context->urb.size;
894
895     BEGIN_BATCH(batch, 3);
896     OUT_BATCH(batch, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
897     OUT_BATCH(batch, 0);
898     OUT_BATCH(batch, 
899               (vfe_fence << UF2_VFE_FENCE_SHIFT) |      /* VFE_SIZE */
900               (cs_fence << UF2_CS_FENCE_SHIFT));        /* CS_SIZE */
901     ADVANCE_BATCH(batch);
902 }
903
904 static void
905 ironlake_pp_state_base_address(VADriverContextP ctx,
906                                struct i965_post_processing_context *pp_context)
907 {
908     struct intel_batchbuffer *batch = pp_context->batch;
909
910     BEGIN_BATCH(batch, 8);
911     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | 6);
912     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
913     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
914     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
915     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
916     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
917     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
918     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
919     ADVANCE_BATCH(batch);
920 }
921
922 static void
923 ironlake_pp_state_pointers(VADriverContextP ctx,
924                            struct i965_post_processing_context *pp_context)
925 {
926     struct intel_batchbuffer *batch = pp_context->batch;
927
928     BEGIN_BATCH(batch, 3);
929     OUT_BATCH(batch, CMD_MEDIA_STATE_POINTERS | 1);
930     OUT_BATCH(batch, 0);
931     OUT_RELOC(batch, pp_context->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
932     ADVANCE_BATCH(batch);
933 }
934
935 static void 
936 ironlake_pp_cs_urb_layout(VADriverContextP ctx,
937                           struct i965_post_processing_context *pp_context)
938 {
939     struct intel_batchbuffer *batch = pp_context->batch;
940
941     BEGIN_BATCH(batch, 2);
942     OUT_BATCH(batch, CMD_CS_URB_STATE | 0);
943     OUT_BATCH(batch,
944               ((pp_context->urb.size_cs_entry - 1) << 4) |     /* URB Entry Allocation Size */
945               (pp_context->urb.num_cs_entries << 0));          /* Number of URB Entries */
946     ADVANCE_BATCH(batch);
947 }
948
949 static void
950 ironlake_pp_constant_buffer(VADriverContextP ctx,
951                             struct i965_post_processing_context *pp_context)
952 {
953     struct intel_batchbuffer *batch = pp_context->batch;
954
955     BEGIN_BATCH(batch, 2);
956     OUT_BATCH(batch, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
957     OUT_RELOC(batch, pp_context->curbe.bo,
958               I915_GEM_DOMAIN_INSTRUCTION, 0,
959               pp_context->urb.size_cs_entry - 1);
960     ADVANCE_BATCH(batch);    
961 }
962
963 static void
964 ironlake_pp_object_walker(VADriverContextP ctx,
965                           struct i965_post_processing_context *pp_context)
966 {
967     struct intel_batchbuffer *batch = pp_context->batch;
968     int x, x_steps, y, y_steps;
969     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
970
971     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
972     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
973
974     for (y = 0; y < y_steps; y++) {
975         for (x = 0; x < x_steps; x++) {
976             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
977                 BEGIN_BATCH(batch, 20);
978                 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 18);
979                 OUT_BATCH(batch, 0);
980                 OUT_BATCH(batch, 0); /* no indirect data */
981                 OUT_BATCH(batch, 0);
982
983                 /* inline data grf 5-6 */
984                 assert(sizeof(*pp_inline_parameter) == 64);
985                 intel_batchbuffer_data(batch, pp_inline_parameter, sizeof(*pp_inline_parameter));
986
987                 ADVANCE_BATCH(batch);
988             }
989         }
990     }
991 }
992
993 static void
994 ironlake_pp_pipeline_setup(VADriverContextP ctx,
995                            struct i965_post_processing_context *pp_context)
996 {
997     struct intel_batchbuffer *batch = pp_context->batch;
998
999     intel_batchbuffer_start_atomic(batch, 0x1000);
1000     intel_batchbuffer_emit_mi_flush(batch);
1001     ironlake_pp_pipeline_select(ctx, pp_context);
1002     ironlake_pp_state_base_address(ctx, pp_context);
1003     ironlake_pp_state_pointers(ctx, pp_context);
1004     ironlake_pp_urb_layout(ctx, pp_context);
1005     ironlake_pp_cs_urb_layout(ctx, pp_context);
1006     ironlake_pp_constant_buffer(ctx, pp_context);
1007     ironlake_pp_object_walker(ctx, pp_context);
1008     intel_batchbuffer_end_atomic(batch);
1009 }
1010
1011 static void
1012 i965_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1013                           dri_bo *surf_bo, unsigned long surf_bo_offset,
1014                           int width, int height, int pitch, int format, 
1015                           int index, int is_target)
1016 {
1017     struct i965_surface_state *ss;
1018     dri_bo *ss_bo;
1019     unsigned int tiling;
1020     unsigned int swizzle;
1021
1022     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1023     ss_bo = pp_context->surface_state_binding_table.bo;
1024     assert(ss_bo);
1025
1026     dri_bo_map(ss_bo, True);
1027     assert(ss_bo->virtual);
1028     ss = (struct i965_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1029     memset(ss, 0, sizeof(*ss));
1030     ss->ss0.surface_type = I965_SURFACE_2D;
1031     ss->ss0.surface_format = format;
1032     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1033     ss->ss2.width = width - 1;
1034     ss->ss2.height = height - 1;
1035     ss->ss3.pitch = pitch - 1;
1036     pp_set_surface_tiling(ss, tiling);
1037     dri_bo_emit_reloc(ss_bo,
1038                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1039                       surf_bo_offset,
1040                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state, ss1),
1041                       surf_bo);
1042     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1043     dri_bo_unmap(ss_bo);
1044 }
1045
1046 static void
1047 i965_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1048                            dri_bo *surf_bo, unsigned long surf_bo_offset,
1049                            int width, int height, int wpitch,
1050                            int xoffset, int yoffset,
1051                            int format, int interleave_chroma,
1052                            int index)
1053 {
1054     struct i965_surface_state2 *ss2;
1055     dri_bo *ss2_bo;
1056     unsigned int tiling;
1057     unsigned int swizzle;
1058
1059     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1060     ss2_bo = pp_context->surface_state_binding_table.bo;
1061     assert(ss2_bo);
1062
1063     dri_bo_map(ss2_bo, True);
1064     assert(ss2_bo->virtual);
1065     ss2 = (struct i965_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1066     memset(ss2, 0, sizeof(*ss2));
1067     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1068     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1069     ss2->ss1.width = width - 1;
1070     ss2->ss1.height = height - 1;
1071     ss2->ss2.pitch = wpitch - 1;
1072     ss2->ss2.interleave_chroma = interleave_chroma;
1073     ss2->ss2.surface_format = format;
1074     ss2->ss3.x_offset_for_cb = xoffset;
1075     ss2->ss3.y_offset_for_cb = yoffset;
1076     pp_set_surface2_tiling(ss2, tiling);
1077     dri_bo_emit_reloc(ss2_bo,
1078                       I915_GEM_DOMAIN_RENDER, 0,
1079                       surf_bo_offset,
1080                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state2, ss0),
1081                       surf_bo);
1082     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1083     dri_bo_unmap(ss2_bo);
1084 }
1085
1086 static void
1087 gen7_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1088                           dri_bo *surf_bo, unsigned long surf_bo_offset,
1089                           int width, int height, int pitch, int format, 
1090                           int index, int is_target)
1091 {
1092     struct gen7_surface_state *ss;
1093     dri_bo *ss_bo;
1094     unsigned int tiling;
1095     unsigned int swizzle;
1096
1097     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1098     ss_bo = pp_context->surface_state_binding_table.bo;
1099     assert(ss_bo);
1100
1101     dri_bo_map(ss_bo, True);
1102     assert(ss_bo->virtual);
1103     ss = (struct gen7_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1104     memset(ss, 0, sizeof(*ss));
1105     ss->ss0.surface_type = I965_SURFACE_2D;
1106     ss->ss0.surface_format = format;
1107     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1108     ss->ss2.width = width - 1;
1109     ss->ss2.height = height - 1;
1110     ss->ss3.pitch = pitch - 1;
1111     gen7_pp_set_surface_tiling(ss, tiling);
1112     dri_bo_emit_reloc(ss_bo,
1113                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1114                       surf_bo_offset,
1115                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
1116                       surf_bo);
1117     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1118     dri_bo_unmap(ss_bo);
1119 }
1120
1121 static void
1122 gen7_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1123                            dri_bo *surf_bo, unsigned long surf_bo_offset,
1124                            int width, int height, int wpitch,
1125                            int xoffset, int yoffset,
1126                            int format, int interleave_chroma,
1127                            int index)
1128 {
1129     struct gen7_surface_state2 *ss2;
1130     dri_bo *ss2_bo;
1131     unsigned int tiling;
1132     unsigned int swizzle;
1133
1134     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1135     ss2_bo = pp_context->surface_state_binding_table.bo;
1136     assert(ss2_bo);
1137
1138     dri_bo_map(ss2_bo, True);
1139     assert(ss2_bo->virtual);
1140     ss2 = (struct gen7_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1141     memset(ss2, 0, sizeof(*ss2));
1142     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1143     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1144     ss2->ss1.width = width - 1;
1145     ss2->ss1.height = height - 1;
1146     ss2->ss2.pitch = wpitch - 1;
1147     ss2->ss2.interleave_chroma = interleave_chroma;
1148     ss2->ss2.surface_format = format;
1149     ss2->ss3.x_offset_for_cb = xoffset;
1150     ss2->ss3.y_offset_for_cb = yoffset;
1151     gen7_pp_set_surface2_tiling(ss2, tiling);
1152     dri_bo_emit_reloc(ss2_bo,
1153                       I915_GEM_DOMAIN_RENDER, 0,
1154                       surf_bo_offset,
1155                       SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state2, ss0),
1156                       surf_bo);
1157     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1158     dri_bo_unmap(ss2_bo);
1159 }
1160
1161 static void 
1162 pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1163                                 const struct i965_surface *surface, 
1164                                 int base_index, int is_target,
1165                                 int *width, int *height, int *pitch, int *offset)
1166 {
1167     struct i965_driver_data *i965 = i965_driver_data(ctx);
1168     struct object_surface *obj_surface;
1169     struct object_image *obj_image;
1170     dri_bo *bo;
1171     int fourcc = pp_get_surface_fourcc(ctx, surface);
1172     const int Y = 0;
1173     const int U = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 2 : 1;
1174     const int V = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 1 : 2;
1175     const int UV = 1;
1176     int interleaved_uv = fourcc == VA_FOURCC('N', 'V', '1', '2');
1177     int packed_yuv = (fourcc == VA_FOURCC('Y', 'U', 'Y', '2') || fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')); 
1178
1179     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
1180         obj_surface = SURFACE(surface->id);
1181         bo = obj_surface->bo;
1182         width[0] = obj_surface->orig_width;
1183         height[0] = obj_surface->orig_height;
1184         pitch[0] = obj_surface->width;
1185         offset[0] = 0;
1186
1187         if (packed_yuv ) {
1188             width[0] = obj_surface->orig_width * 2; 
1189             pitch[0] = obj_surface->width * 2;
1190         }
1191         else if (interleaved_uv) {
1192             width[1] = obj_surface->orig_width;
1193             height[1] = obj_surface->orig_height / 2;
1194             pitch[1] = obj_surface->width;
1195             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
1196         } else {
1197             width[1] = obj_surface->orig_width / 2;
1198             height[1] = obj_surface->orig_height / 2;
1199             pitch[1] = obj_surface->width / 2;
1200             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
1201             width[2] = obj_surface->orig_width / 2;
1202             height[2] = obj_surface->orig_height / 2;
1203             pitch[2] = obj_surface->width / 2;
1204             offset[2] = offset[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
1205         }
1206     } else {
1207         obj_image = IMAGE(surface->id);
1208         bo = obj_image->bo;
1209         width[0] = obj_image->image.width;
1210         height[0] = obj_image->image.height;
1211         pitch[0] = obj_image->image.pitches[0];
1212         offset[0] = obj_image->image.offsets[0];
1213
1214         if (interleaved_uv) {
1215             width[1] = obj_image->image.width;
1216             height[1] = obj_image->image.height / 2;
1217             pitch[1] = obj_image->image.pitches[1];
1218             offset[1] = obj_image->image.offsets[1];
1219         } else {
1220             width[1] = obj_image->image.width / 2;
1221             height[1] = obj_image->image.height / 2;
1222             pitch[1] = obj_image->image.pitches[1];
1223             offset[1] = obj_image->image.offsets[1];
1224             width[2] = obj_image->image.width / 2;
1225             height[2] = obj_image->image.height / 2;
1226             pitch[2] = obj_image->image.pitches[2];
1227             offset[2] = obj_image->image.offsets[2];
1228         }
1229     }
1230
1231     /* Y surface */
1232     i965_pp_set_surface_state(ctx, pp_context,
1233                               bo, offset[Y],
1234                               width[Y] / 4, height[Y], pitch[Y], I965_SURFACEFORMAT_R8_UNORM,
1235                               base_index, is_target);
1236
1237     if (!packed_yuv) {
1238         if (interleaved_uv) {
1239             i965_pp_set_surface_state(ctx, pp_context,
1240                                       bo, offset[UV],
1241                                       width[UV] / 4, height[UV], pitch[UV], I965_SURFACEFORMAT_R8_UNORM,
1242                                       base_index + 1, is_target);
1243         } else {
1244             /* U surface */
1245             i965_pp_set_surface_state(ctx, pp_context,
1246                                       bo, offset[U],
1247                                       width[U] / 4, height[U], pitch[U], I965_SURFACEFORMAT_R8_UNORM,
1248                                       base_index + 1, is_target);
1249
1250             /* V surface */
1251             i965_pp_set_surface_state(ctx, pp_context,
1252                                       bo, offset[V],
1253                                       width[V] / 4, height[V], pitch[V], I965_SURFACEFORMAT_R8_UNORM,
1254                                       base_index + 2, is_target);
1255         }
1256     }
1257
1258 }
1259
1260 static void 
1261 gen7_pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1262                                      const struct i965_surface *surface, 
1263                                      int base_index, int is_target,
1264                                      int *width, int *height, int *pitch, int *offset)
1265 {
1266     struct i965_driver_data *i965 = i965_driver_data(ctx);
1267     struct object_surface *obj_surface;
1268     struct object_image *obj_image;
1269     dri_bo *bo;
1270     int fourcc = pp_get_surface_fourcc(ctx, surface);
1271     const int U = (fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
1272                    fourcc == VA_FOURCC('I', 'M', 'C', '1')) ? 2 : 1;
1273     const int V = (fourcc == VA_FOURCC('Y', 'V', '1', '2') ||
1274                    fourcc == VA_FOURCC('I', 'M', 'C', '1')) ? 1 : 2;
1275     int interleaved_uv = fourcc == VA_FOURCC('N', 'V', '1', '2');
1276
1277     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
1278         obj_surface = SURFACE(surface->id);
1279         bo = obj_surface->bo;
1280         width[0] = obj_surface->orig_width;
1281         height[0] = obj_surface->orig_height;
1282         pitch[0] = obj_surface->width;
1283         offset[0] = 0;
1284
1285         width[1] = obj_surface->cb_cr_width;
1286         height[1] = obj_surface->cb_cr_height;
1287         pitch[1] = obj_surface->cb_cr_pitch;
1288         offset[1] = obj_surface->y_cb_offset * obj_surface->width;
1289
1290         width[2] = obj_surface->cb_cr_width;
1291         height[2] = obj_surface->cb_cr_height;
1292         pitch[2] = obj_surface->cb_cr_pitch;
1293         offset[2] = obj_surface->y_cr_offset * obj_surface->width;
1294     } else {
1295         obj_image = IMAGE(surface->id);
1296         bo = obj_image->bo;
1297         width[0] = obj_image->image.width;
1298         height[0] = obj_image->image.height;
1299         pitch[0] = obj_image->image.pitches[0];
1300         offset[0] = obj_image->image.offsets[0];
1301
1302         if (interleaved_uv) {
1303             width[1] = obj_image->image.width;
1304             height[1] = obj_image->image.height / 2;
1305             pitch[1] = obj_image->image.pitches[1];
1306             offset[1] = obj_image->image.offsets[1];
1307         } else {
1308             width[1] = obj_image->image.width / 2;
1309             height[1] = obj_image->image.height / 2;
1310             pitch[1] = obj_image->image.pitches[U];
1311             offset[1] = obj_image->image.offsets[U];
1312             width[2] = obj_image->image.width / 2;
1313             height[2] = obj_image->image.height / 2;
1314             pitch[2] = obj_image->image.pitches[V];
1315             offset[2] = obj_image->image.offsets[V];
1316         }
1317     }
1318
1319     if (is_target) {
1320         gen7_pp_set_surface_state(ctx, pp_context,
1321                                   bo, 0,
1322                                   width[0] / 4, height[0], pitch[0],
1323                                   I965_SURFACEFORMAT_R8_SINT,
1324                                   base_index, 1);
1325
1326         if (interleaved_uv) {
1327             gen7_pp_set_surface_state(ctx, pp_context,
1328                                       bo, offset[1],
1329                                       width[1] / 2, height[1], pitch[1],
1330                                       I965_SURFACEFORMAT_R8G8_SINT,
1331                                       base_index + 1, 1);
1332         } else {
1333             gen7_pp_set_surface_state(ctx, pp_context,
1334                                       bo, offset[1],
1335                                       width[1] / 4, height[1], pitch[1],
1336                                       I965_SURFACEFORMAT_R8_SINT,
1337                                       base_index + 1, 1);
1338             gen7_pp_set_surface_state(ctx, pp_context,
1339                                       bo, offset[2],
1340                                       width[2] / 4, height[2], pitch[2],
1341                                       I965_SURFACEFORMAT_R8_SINT,
1342                                       base_index + 2, 1);
1343         }
1344     } else {
1345         gen7_pp_set_surface2_state(ctx, pp_context,
1346                                    bo, offset[0],
1347                                    width[0], height[0], pitch[0],
1348                                    0, 0,
1349                                    SURFACE_FORMAT_Y8_UNORM, 0,
1350                                    base_index);
1351
1352         if (interleaved_uv) {
1353             gen7_pp_set_surface2_state(ctx, pp_context,
1354                                        bo, offset[1],
1355                                        width[1], height[1], pitch[1],
1356                                        0, 0,
1357                                        SURFACE_FORMAT_R8B8_UNORM, 0,
1358                                        base_index + 1);
1359         } else {
1360             gen7_pp_set_surface2_state(ctx, pp_context,
1361                                        bo, offset[1],
1362                                        width[1], height[1], pitch[1],
1363                                        0, 0,
1364                                        SURFACE_FORMAT_R8_UNORM, 0,
1365                                        base_index + 1);
1366             gen7_pp_set_surface2_state(ctx, pp_context,
1367                                        bo, offset[2],
1368                                        width[2], height[2], pitch[2],
1369                                        0, 0,
1370                                        SURFACE_FORMAT_R8_UNORM, 0,
1371                                        base_index + 2);
1372         }
1373     }
1374 }
1375
1376 static int
1377 pp_null_x_steps(void *private_context)
1378 {
1379     return 1;
1380 }
1381
1382 static int
1383 pp_null_y_steps(void *private_context)
1384 {
1385     return 1;
1386 }
1387
1388 static int
1389 pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1390 {
1391     return 0;
1392 }
1393
1394 static VAStatus
1395 pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1396                    const struct i965_surface *src_surface,
1397                    const VARectangle *src_rect,
1398                    struct i965_surface *dst_surface,
1399                    const VARectangle *dst_rect,
1400                    void *filter_param)
1401 {
1402     /* private function & data */
1403     pp_context->pp_x_steps = pp_null_x_steps;
1404     pp_context->pp_y_steps = pp_null_y_steps;
1405     pp_context->pp_set_block_parameter = pp_null_set_block_parameter;
1406
1407     dst_surface->flags = src_surface->flags;
1408
1409     return VA_STATUS_SUCCESS;
1410 }
1411
1412 static int
1413 pp_load_save_x_steps(void *private_context)
1414 {
1415     return 1;
1416 }
1417
1418 static int
1419 pp_load_save_y_steps(void *private_context)
1420 {
1421     struct pp_load_save_context *pp_load_save_context = private_context;
1422
1423     return pp_load_save_context->dest_h / 8;
1424 }
1425
1426 static int
1427 pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1428 {
1429     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1430
1431     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
1432     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
1433     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
1434     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
1435
1436     return 0;
1437 }
1438
1439 static VAStatus
1440 pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1441                                 const struct i965_surface *src_surface,
1442                                 const VARectangle *src_rect,
1443                                 struct i965_surface *dst_surface,
1444                                 const VARectangle *dst_rect,
1445                                 void *filter_param)
1446 {
1447     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->private_context;
1448     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1449     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1450     int width[3], height[3], pitch[3], offset[3];
1451     const int Y = 0;
1452
1453     /* source surface */
1454     pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 1, 0,
1455                                     width, height, pitch, offset);
1456
1457     /* destination surface */
1458     pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 7, 1,
1459                                     width, height, pitch, offset);
1460
1461     /* private function & data */
1462     pp_context->pp_x_steps = pp_load_save_x_steps;
1463     pp_context->pp_y_steps = pp_load_save_y_steps;
1464     pp_context->pp_set_block_parameter = pp_load_save_set_block_parameter;
1465     pp_load_save_context->dest_h = ALIGN(height[Y], 16);
1466     pp_load_save_context->dest_w = ALIGN(width[Y], 16);
1467
1468     pp_inline_parameter->grf5.block_count_x = ALIGN(width[Y], 16) / 16;   /* 1 x N */
1469     pp_inline_parameter->grf5.number_blocks = ALIGN(width[Y], 16) / 16;
1470
1471     pp_static_parameter->grf3.horizontal_origin_offset = src_rect->x;
1472     pp_static_parameter->grf3.vertical_origin_offset = src_rect->y;
1473
1474     dst_surface->flags = src_surface->flags;
1475
1476     return VA_STATUS_SUCCESS;
1477 }
1478
1479 static int
1480 pp_scaling_x_steps(void *private_context)
1481 {
1482     return 1;
1483 }
1484
1485 static int
1486 pp_scaling_y_steps(void *private_context)
1487 {
1488     struct pp_scaling_context *pp_scaling_context = private_context;
1489
1490     return pp_scaling_context->dest_h / 8;
1491 }
1492
1493 static int
1494 pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1495 {
1496     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
1497     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1498     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1499     float src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1500     float src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
1501
1502     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
1503     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
1504     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
1505     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
1506     
1507     return 0;
1508 }
1509
1510 static VAStatus
1511 pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1512                            const struct i965_surface *src_surface,
1513                            const VARectangle *src_rect,
1514                            struct i965_surface *dst_surface,
1515                            const VARectangle *dst_rect,
1516                            void *filter_param)
1517 {
1518     struct i965_driver_data *i965 = i965_driver_data(ctx);
1519     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
1520     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1521     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1522     struct object_surface *obj_surface;
1523     struct i965_sampler_state *sampler_state;
1524     int in_w, in_h, in_wpitch, in_hpitch;
1525     int out_w, out_h, out_wpitch, out_hpitch;
1526
1527     /* source surface */
1528     obj_surface = SURFACE(src_surface->id);
1529     in_w = obj_surface->orig_width;
1530     in_h = obj_surface->orig_height;
1531     in_wpitch = obj_surface->width;
1532     in_hpitch = obj_surface->height;
1533
1534     /* source Y surface index 1 */
1535     i965_pp_set_surface_state(ctx, pp_context,
1536                               obj_surface->bo, 0,
1537                               in_w, in_h, in_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1538                               1, 0);
1539
1540     /* source UV surface index 2 */
1541     i965_pp_set_surface_state(ctx, pp_context,
1542                               obj_surface->bo, in_wpitch * in_hpitch,
1543                               in_w / 2, in_h / 2, in_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1544                               2, 0);
1545
1546     /* destination surface */
1547     obj_surface = SURFACE(dst_surface->id);
1548     out_w = obj_surface->orig_width;
1549     out_h = obj_surface->orig_height;
1550     out_wpitch = obj_surface->width;
1551     out_hpitch = obj_surface->height;
1552
1553     /* destination Y surface index 7 */
1554     i965_pp_set_surface_state(ctx, pp_context,
1555                               obj_surface->bo, 0,
1556                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1557                               7, 1);
1558
1559     /* destination UV surface index 8 */
1560     i965_pp_set_surface_state(ctx, pp_context,
1561                               obj_surface->bo, out_wpitch * out_hpitch,
1562                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1563                               8, 1);
1564
1565     /* sampler state */
1566     dri_bo_map(pp_context->sampler_state_table.bo, True);
1567     assert(pp_context->sampler_state_table.bo->virtual);
1568     sampler_state = pp_context->sampler_state_table.bo->virtual;
1569
1570     /* SIMD16 Y index 1 */
1571     sampler_state[1].ss0.min_filter = I965_MAPFILTER_LINEAR;
1572     sampler_state[1].ss0.mag_filter = I965_MAPFILTER_LINEAR;
1573     sampler_state[1].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1574     sampler_state[1].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1575     sampler_state[1].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1576
1577     /* SIMD16 UV index 2 */
1578     sampler_state[2].ss0.min_filter = I965_MAPFILTER_LINEAR;
1579     sampler_state[2].ss0.mag_filter = I965_MAPFILTER_LINEAR;
1580     sampler_state[2].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1581     sampler_state[2].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1582     sampler_state[2].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1583
1584     dri_bo_unmap(pp_context->sampler_state_table.bo);
1585
1586     /* private function & data */
1587     pp_context->pp_x_steps = pp_scaling_x_steps;
1588     pp_context->pp_y_steps = pp_scaling_y_steps;
1589     pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
1590
1591     pp_scaling_context->dest_x = dst_rect->x;
1592     pp_scaling_context->dest_y = dst_rect->y;
1593     pp_scaling_context->dest_w = ALIGN(dst_rect->width, 16);
1594     pp_scaling_context->dest_h = ALIGN(dst_rect->height, 16);
1595     pp_scaling_context->src_normalized_x = (float)src_rect->x / in_w;
1596     pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h;
1597
1598     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
1599
1600     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / dst_rect->width;
1601     pp_inline_parameter->grf5.block_count_x = pp_scaling_context->dest_w / 16;   /* 1 x N */
1602     pp_inline_parameter->grf5.number_blocks = pp_scaling_context->dest_w / 16;
1603     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
1604     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
1605
1606     dst_surface->flags = src_surface->flags;
1607
1608     return VA_STATUS_SUCCESS;
1609 }
1610
1611 static int
1612 pp_avs_x_steps(void *private_context)
1613 {
1614     struct pp_avs_context *pp_avs_context = private_context;
1615
1616     return pp_avs_context->dest_w / 16;
1617 }
1618
1619 static int
1620 pp_avs_y_steps(void *private_context)
1621 {
1622     return 1;
1623 }
1624
1625 static int
1626 pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1627 {
1628     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1629     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1630     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1631     float src_x_steping, src_y_steping, video_step_delta;
1632     int tmp_w = ALIGN(pp_avs_context->dest_h * pp_avs_context->src_w / pp_avs_context->src_h, 16);
1633
1634     if (pp_static_parameter->grf4.r4_2.avs.nlas == 0) {
1635         src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1636         pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_avs_context->src_normalized_x;
1637     } else if (tmp_w >= pp_avs_context->dest_w) {
1638         pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
1639         pp_inline_parameter->grf6.video_step_delta = 0;
1640         
1641         if (x == 0) {
1642             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
1643                 pp_avs_context->src_normalized_x;
1644         } else {
1645             src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1646             video_step_delta = pp_inline_parameter->grf6.video_step_delta;
1647             pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1648                 16 * 15 * video_step_delta / 2;
1649         }
1650     } else {
1651         int n0, n1, n2, nls_left, nls_right;
1652         int factor_a = 5, factor_b = 4;
1653         float f;
1654
1655         n0 = (pp_avs_context->dest_w - tmp_w) / (16 * 2);
1656         n1 = (pp_avs_context->dest_w - tmp_w) / 16 - n0;
1657         n2 = tmp_w / (16 * factor_a);
1658         nls_left = n0 + n2;
1659         nls_right = n1 + n2;
1660         f = (float) n2 * 16 / tmp_w;
1661         
1662         if (n0 < 5) {
1663             pp_inline_parameter->grf6.video_step_delta = 0.0;
1664
1665             if (x == 0) {
1666                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
1667                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
1668             } else {
1669                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1670                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
1671                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1672                     16 * 15 * video_step_delta / 2;
1673             }
1674         } else {
1675             if (x < nls_left) {
1676                 /* f = a * nls_left * 16 + b * nls_left * 16 * (nls_left * 16 - 1) / 2 */
1677                 float a = f / (nls_left * 16 * factor_b);
1678                 float b = (f - nls_left * 16 * a) * 2 / (nls_left * 16 * (nls_left * 16 - 1));
1679                 
1680                 pp_inline_parameter->grf6.video_step_delta = b;
1681
1682                 if (x == 0) {
1683                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
1684                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a;
1685                 } else {
1686                     src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1687                     video_step_delta = pp_inline_parameter->grf6.video_step_delta;
1688                     pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1689                         16 * 15 * video_step_delta / 2;
1690                     pp_inline_parameter->grf5.normalized_video_x_scaling_step += 16 * b;
1691                 }
1692             } else if (x < (pp_avs_context->dest_w / 16 - nls_right)) {
1693                 /* scale the center linearly */
1694                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1695                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
1696                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1697                     16 * 15 * video_step_delta / 2;
1698                 pp_inline_parameter->grf6.video_step_delta = 0.0;
1699                 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
1700             } else {
1701                 float a = f / (nls_right * 16 * factor_b);
1702                 float b = (f - nls_right * 16 * a) * 2 / (nls_right * 16 * (nls_right * 16 - 1));
1703
1704                 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
1705                 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
1706                 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1707                     16 * 15 * video_step_delta / 2;
1708                 pp_inline_parameter->grf6.video_step_delta = -b;
1709
1710                 if (x == (pp_avs_context->dest_w / 16 - nls_right))
1711                     pp_inline_parameter->grf5.normalized_video_x_scaling_step = a + (nls_right * 16  - 1) * b;
1712                 else
1713                     pp_inline_parameter->grf5.normalized_video_x_scaling_step -= b * 16;
1714             }
1715         }
1716     }
1717
1718     src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
1719     pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
1720     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
1721     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
1722
1723     return 0;
1724 }
1725
1726 static VAStatus
1727 pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1728                        const struct i965_surface *src_surface,
1729                        const VARectangle *src_rect,
1730                        struct i965_surface *dst_surface,
1731                        const VARectangle *dst_rect,
1732                        void *filter_param,
1733                        int nlas)
1734 {
1735     struct i965_driver_data *i965 = i965_driver_data(ctx);
1736     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1737     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1738     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1739     struct object_surface *obj_surface;
1740     struct i965_sampler_8x8 *sampler_8x8;
1741     struct i965_sampler_8x8_state *sampler_8x8_state;
1742     int index;
1743     int in_w, in_h, in_wpitch, in_hpitch;
1744     int out_w, out_h, out_wpitch, out_hpitch;
1745     int i;
1746
1747     /* surface */
1748     obj_surface = SURFACE(src_surface->id);
1749     in_w = obj_surface->orig_width;
1750     in_h = obj_surface->orig_height;
1751     in_wpitch = obj_surface->width;
1752     in_hpitch = obj_surface->height;
1753
1754     /* source Y surface index 1 */
1755     i965_pp_set_surface2_state(ctx, pp_context,
1756                                obj_surface->bo, 0,
1757                                in_w, in_h, in_wpitch,
1758                                0, 0,
1759                                SURFACE_FORMAT_Y8_UNORM, 0,
1760                                1);
1761
1762     /* source UV surface index 2 */
1763     i965_pp_set_surface2_state(ctx, pp_context,
1764                                obj_surface->bo, in_wpitch * in_hpitch,
1765                                in_w / 2, in_h / 2, in_wpitch,
1766                                0, 0,
1767                                SURFACE_FORMAT_R8B8_UNORM, 0,
1768                                2);
1769
1770     /* destination surface */
1771     obj_surface = SURFACE(dst_surface->id);
1772     out_w = obj_surface->orig_width;
1773     out_h = obj_surface->orig_height;
1774     out_wpitch = obj_surface->width;
1775     out_hpitch = obj_surface->height;
1776     assert(out_w <= out_wpitch && out_h <= out_hpitch);
1777
1778     /* destination Y surface index 7 */
1779     i965_pp_set_surface_state(ctx, pp_context,
1780                               obj_surface->bo, 0,
1781                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1782                               7, 1);
1783
1784     /* destination UV surface index 8 */
1785     i965_pp_set_surface_state(ctx, pp_context,
1786                               obj_surface->bo, out_wpitch * out_hpitch,
1787                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1788                               8, 1);
1789
1790     /* sampler 8x8 state */
1791     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
1792     assert(pp_context->sampler_state_table.bo_8x8->virtual);
1793     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
1794     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
1795     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
1796
1797     for (i = 0; i < 17; i++) {
1798         /* for Y channel, currently ignore */
1799         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x00;
1800         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x00;
1801         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x08;
1802         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x18;
1803         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x18;
1804         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x08;
1805         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x00;
1806         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x00;
1807         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x00;
1808         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x00;
1809         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x10;
1810         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x10;
1811         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x10;
1812         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x10;
1813         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x00;
1814         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x00;
1815         /* for U/V channel, 0.25 */
1816         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
1817         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
1818         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
1819         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
1820         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
1821         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
1822         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
1823         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
1824         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
1825         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
1826         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
1827         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
1828         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
1829         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
1830         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
1831         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
1832     }
1833
1834     sampler_8x8_state->dw136.default_sharpness_level = 0;
1835     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
1836     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
1837     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
1838     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
1839
1840     /* sampler 8x8 */
1841     dri_bo_map(pp_context->sampler_state_table.bo, True);
1842     assert(pp_context->sampler_state_table.bo->virtual);
1843     assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
1844     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
1845
1846     /* sample_8x8 Y index 1 */
1847     index = 1;
1848     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1849     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
1850     sampler_8x8[index].dw0.ief_bypass = 1;
1851     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1852     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1853     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1854     sampler_8x8[index].dw2.global_noise_estimation = 22;
1855     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1856     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1857     sampler_8x8[index].dw3.strong_edge_weight = 7;
1858     sampler_8x8[index].dw3.regular_weight = 2;
1859     sampler_8x8[index].dw3.non_edge_weight = 0;
1860     sampler_8x8[index].dw3.gain_factor = 40;
1861     sampler_8x8[index].dw4.steepness_boost = 0;
1862     sampler_8x8[index].dw4.steepness_threshold = 0;
1863     sampler_8x8[index].dw4.mr_boost = 0;
1864     sampler_8x8[index].dw4.mr_threshold = 5;
1865     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1866     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1867     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1868     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1869     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1870     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1871     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1872     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1873     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1874     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1875     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1876     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1877     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1878     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1879     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1880     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1881     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1882     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1883     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1884     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1885     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1886     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1887     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1888     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1889     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1890     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1891     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1892     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1893     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1894     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1895     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1896     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1897     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1898     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1899     sampler_8x8[index].dw13.limiter_boost = 0;
1900     sampler_8x8[index].dw13.minimum_limiter = 10;
1901     sampler_8x8[index].dw13.maximum_limiter = 11;
1902     sampler_8x8[index].dw14.clip_limiter = 130;
1903     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1904                       I915_GEM_DOMAIN_RENDER, 
1905                       0,
1906                       0,
1907                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1908                       pp_context->sampler_state_table.bo_8x8);
1909
1910     /* sample_8x8 UV index 2 */
1911     index = 2;
1912     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1913     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
1914     sampler_8x8[index].dw0.ief_bypass = 1;
1915     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1916     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1917     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1918     sampler_8x8[index].dw2.global_noise_estimation = 22;
1919     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1920     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1921     sampler_8x8[index].dw3.strong_edge_weight = 7;
1922     sampler_8x8[index].dw3.regular_weight = 2;
1923     sampler_8x8[index].dw3.non_edge_weight = 0;
1924     sampler_8x8[index].dw3.gain_factor = 40;
1925     sampler_8x8[index].dw4.steepness_boost = 0;
1926     sampler_8x8[index].dw4.steepness_threshold = 0;
1927     sampler_8x8[index].dw4.mr_boost = 0;
1928     sampler_8x8[index].dw4.mr_threshold = 5;
1929     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1930     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1931     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1932     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1933     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1934     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1935     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1936     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1937     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1938     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1939     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1940     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1941     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1942     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1943     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1944     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1945     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1946     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1947     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1948     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1949     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1950     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1951     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1952     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1953     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1954     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1955     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1956     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1957     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1958     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1959     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1960     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1961     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1962     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1963     sampler_8x8[index].dw13.limiter_boost = 0;
1964     sampler_8x8[index].dw13.minimum_limiter = 10;
1965     sampler_8x8[index].dw13.maximum_limiter = 11;
1966     sampler_8x8[index].dw14.clip_limiter = 130;
1967     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1968                       I915_GEM_DOMAIN_RENDER, 
1969                       0,
1970                       0,
1971                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1972                       pp_context->sampler_state_table.bo_8x8);
1973
1974     dri_bo_unmap(pp_context->sampler_state_table.bo);
1975
1976     /* private function & data */
1977     pp_context->pp_x_steps = pp_avs_x_steps;
1978     pp_context->pp_y_steps = pp_avs_y_steps;
1979     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
1980
1981     pp_avs_context->dest_x = dst_rect->x;
1982     pp_avs_context->dest_y = dst_rect->y;
1983     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
1984     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
1985     pp_avs_context->src_normalized_x = (float)src_rect->x / in_w;
1986     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h;
1987     pp_avs_context->src_w = src_rect->width;
1988     pp_avs_context->src_h = src_rect->height;
1989
1990     pp_static_parameter->grf4.r4_2.avs.nlas = nlas;
1991     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
1992
1993     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / dst_rect->width;
1994     pp_inline_parameter->grf5.block_count_x = 1;        /* M x 1 */
1995     pp_inline_parameter->grf5.number_blocks = pp_avs_context->dest_h / 8;
1996     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
1997     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
1998     pp_inline_parameter->grf6.video_step_delta = 0.0;
1999
2000     dst_surface->flags = src_surface->flags;
2001
2002     return VA_STATUS_SUCCESS;
2003 }
2004
2005 static VAStatus
2006 pp_nv12_avs_initialize_nlas(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2007                             const struct i965_surface *src_surface,
2008                             const VARectangle *src_rect,
2009                             struct i965_surface *dst_surface,
2010                             const VARectangle *dst_rect,
2011                             void *filter_param)
2012 {
2013     return pp_nv12_avs_initialize(ctx, pp_context,
2014                                   src_surface,
2015                                   src_rect,
2016                                   dst_surface,
2017                                   dst_rect,
2018                                   filter_param,
2019                                   1);
2020 }
2021
2022 static VAStatus
2023 gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2024                              const struct i965_surface *src_surface,
2025                              const VARectangle *src_rect,
2026                              struct i965_surface *dst_surface,
2027                              const VARectangle *dst_rect,
2028                              void *filter_param)
2029 {
2030     return pp_nv12_avs_initialize(ctx, pp_context,
2031                                   src_surface,
2032                                   src_rect,
2033                                   dst_surface,
2034                                   dst_rect,
2035                                   filter_param,
2036                                   0);    
2037 }
2038
2039 static int
2040 gen7_pp_avs_x_steps(void *private_context)
2041 {
2042     struct pp_avs_context *pp_avs_context = private_context;
2043
2044     return pp_avs_context->dest_w / 16;
2045 }
2046
2047 static int
2048 gen7_pp_avs_y_steps(void *private_context)
2049 {
2050     struct pp_avs_context *pp_avs_context = private_context;
2051
2052     return pp_avs_context->dest_h / 16;
2053 }
2054
2055 static int
2056 gen7_pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2057 {
2058     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
2059     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2060
2061     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
2062     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 16 + pp_avs_context->dest_y;
2063     pp_inline_parameter->grf7.constant_0 = 0xffffffff;
2064     pp_inline_parameter->grf7.sampler_load_main_video_x_scaling_step = 1.0 / pp_avs_context->src_w;
2065
2066     return 0;
2067 }
2068
2069 static VAStatus
2070 gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2071                            const struct i965_surface *src_surface,
2072                            const VARectangle *src_rect,
2073                            struct i965_surface *dst_surface,
2074                            const VARectangle *dst_rect,
2075                            void *filter_param)
2076 {
2077     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
2078     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2079     struct gen7_sampler_8x8 *sampler_8x8;
2080     struct i965_sampler_8x8_state *sampler_8x8_state;
2081     int index, i;
2082     int width[3], height[3], pitch[3], offset[3];
2083
2084     /* source surface */
2085     gen7_pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 0, 0,
2086                                          width, height, pitch, offset);
2087
2088     /* destination surface */
2089     gen7_pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 24, 1,
2090                                          width, height, pitch, offset);
2091
2092     /* sampler 8x8 state */
2093     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
2094     assert(pp_context->sampler_state_table.bo_8x8->virtual);
2095     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
2096     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
2097     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
2098
2099     for (i = 0; i < 17; i++) {
2100         /* for Y channel, currently ignore */
2101         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x0;
2102         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x0;
2103         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x0;
2104         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x0;
2105         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x0;
2106         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x0;
2107         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x0;
2108         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x0;
2109         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x0;
2110         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x0;
2111         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x0;
2112         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x0;
2113         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x0;
2114         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x0;
2115         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x0;
2116         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x0;
2117         /* for U/V channel, 0.25 */
2118         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
2119         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
2120         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
2121         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
2122         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
2123         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
2124         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
2125         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
2126         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
2127         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
2128         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
2129         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
2130         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
2131         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
2132         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
2133         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
2134     }
2135
2136     sampler_8x8_state->dw136.default_sharpness_level = 0;
2137     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
2138     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
2139     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
2140     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
2141
2142     /* sampler 8x8 */
2143     dri_bo_map(pp_context->sampler_state_table.bo, True);
2144     assert(pp_context->sampler_state_table.bo->virtual);
2145     assert(sizeof(*sampler_8x8) == sizeof(int) * 4);
2146     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
2147
2148     /* sample_8x8 Y index 4 */
2149     index = 4;
2150     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2151     sampler_8x8[index].dw0.global_noise_estimation = 255;
2152     sampler_8x8[index].dw0.ief_bypass = 1;
2153
2154     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2155
2156     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2157     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2158     sampler_8x8[index].dw2.r5x_coefficient = 9;
2159     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2160     sampler_8x8[index].dw2.r5c_coefficient = 3;
2161
2162     sampler_8x8[index].dw3.r3x_coefficient = 27;
2163     sampler_8x8[index].dw3.r3c_coefficient = 5;
2164     sampler_8x8[index].dw3.gain_factor = 40;
2165     sampler_8x8[index].dw3.non_edge_weight = 1;
2166     sampler_8x8[index].dw3.regular_weight = 2;
2167     sampler_8x8[index].dw3.strong_edge_weight = 7;
2168     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2169
2170     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2171                       I915_GEM_DOMAIN_RENDER, 
2172                       0,
2173                       0,
2174                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2175                       pp_context->sampler_state_table.bo_8x8);
2176
2177     /* sample_8x8 UV index 8 */
2178     index = 8;
2179     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2180     sampler_8x8[index].dw0.disable_8x8_filter = 0;
2181     sampler_8x8[index].dw0.global_noise_estimation = 255;
2182     sampler_8x8[index].dw0.ief_bypass = 1;
2183     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2184     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2185     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2186     sampler_8x8[index].dw2.r5x_coefficient = 9;
2187     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2188     sampler_8x8[index].dw2.r5c_coefficient = 3;
2189     sampler_8x8[index].dw3.r3x_coefficient = 27;
2190     sampler_8x8[index].dw3.r3c_coefficient = 5;
2191     sampler_8x8[index].dw3.gain_factor = 40;
2192     sampler_8x8[index].dw3.non_edge_weight = 1;
2193     sampler_8x8[index].dw3.regular_weight = 2;
2194     sampler_8x8[index].dw3.strong_edge_weight = 7;
2195     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2196
2197     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2198                       I915_GEM_DOMAIN_RENDER, 
2199                       0,
2200                       0,
2201                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2202                       pp_context->sampler_state_table.bo_8x8);
2203
2204     /* sampler_8x8 V, index 12 */
2205     index = 12;
2206     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2207     sampler_8x8[index].dw0.disable_8x8_filter = 0;
2208     sampler_8x8[index].dw0.global_noise_estimation = 255;
2209     sampler_8x8[index].dw0.ief_bypass = 1;
2210     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2211     sampler_8x8[index].dw2.weak_edge_threshold = 1;
2212     sampler_8x8[index].dw2.strong_edge_threshold = 8;
2213     sampler_8x8[index].dw2.r5x_coefficient = 9;
2214     sampler_8x8[index].dw2.r5cx_coefficient = 8;
2215     sampler_8x8[index].dw2.r5c_coefficient = 3;
2216     sampler_8x8[index].dw3.r3x_coefficient = 27;
2217     sampler_8x8[index].dw3.r3c_coefficient = 5;
2218     sampler_8x8[index].dw3.gain_factor = 40;
2219     sampler_8x8[index].dw3.non_edge_weight = 1;
2220     sampler_8x8[index].dw3.regular_weight = 2;
2221     sampler_8x8[index].dw3.strong_edge_weight = 7;
2222     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
2223
2224     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2225                       I915_GEM_DOMAIN_RENDER, 
2226                       0,
2227                       0,
2228                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2229                       pp_context->sampler_state_table.bo_8x8);
2230
2231     dri_bo_unmap(pp_context->sampler_state_table.bo);
2232
2233     /* private function & data */
2234     pp_context->pp_x_steps = gen7_pp_avs_x_steps;
2235     pp_context->pp_y_steps = gen7_pp_avs_y_steps;
2236     pp_context->pp_set_block_parameter = gen7_pp_avs_set_block_parameter;
2237
2238     pp_avs_context->dest_x = dst_rect->x;
2239     pp_avs_context->dest_y = dst_rect->y;
2240     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
2241     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
2242     pp_avs_context->src_w = src_rect->width;
2243     pp_avs_context->src_h = src_rect->height;
2244
2245     int dw = (pp_avs_context->src_w - 1) / 16 + 1;
2246     dw = MAX(dw, pp_avs_context->dest_w);
2247
2248     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
2249     pp_static_parameter->grf3.sampler_load_horizontal_scaling_step_ratio = (float) pp_avs_context->src_w / dw;
2250     pp_static_parameter->grf4.sampler_load_vertical_scaling_step = (float) 1.0 / pp_avs_context->dest_h;
2251     pp_static_parameter->grf5.sampler_load_vertical_frame_origin = -(float)pp_avs_context->dest_y / pp_avs_context->dest_h;
2252     pp_static_parameter->grf6.sampler_load_horizontal_frame_origin = -(float)pp_avs_context->dest_x / dw;
2253
2254     dst_surface->flags = src_surface->flags;
2255
2256     return VA_STATUS_SUCCESS;
2257 }
2258
2259 static int
2260 pp_dndi_x_steps(void *private_context)
2261 {
2262     return 1;
2263 }
2264
2265 static int
2266 pp_dndi_y_steps(void *private_context)
2267 {
2268     struct pp_dndi_context *pp_dndi_context = private_context;
2269
2270     return pp_dndi_context->dest_h / 4;
2271 }
2272
2273 static int
2274 pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2275 {
2276     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2277
2278     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2279     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
2280
2281     return 0;
2282 }
2283
2284 static VAStatus
2285 pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2286                         const struct i965_surface *src_surface,
2287                         const VARectangle *src_rect,
2288                         struct i965_surface *dst_surface,
2289                         const VARectangle *dst_rect,
2290                         void *filter_param)
2291 {
2292     struct i965_driver_data *i965 = i965_driver_data(ctx);
2293     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
2294     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2295     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2296     struct object_surface *obj_surface;
2297     struct i965_sampler_dndi *sampler_dndi;
2298     int index;
2299     int w, h;
2300     int orig_w, orig_h;
2301     int dndi_top_first = 1;
2302
2303     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
2304         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
2305
2306     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
2307         dndi_top_first = 1;
2308     else
2309         dndi_top_first = 0;
2310
2311     /* surface */
2312     obj_surface = SURFACE(src_surface->id);
2313     orig_w = obj_surface->orig_width;
2314     orig_h = obj_surface->orig_height;
2315     w = obj_surface->width;
2316     h = obj_surface->height;
2317
2318     if (pp_context->stmm.bo == NULL) {
2319         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2320                                            "STMM surface",
2321                                            w * h,
2322                                            4096);
2323         assert(pp_context->stmm.bo);
2324     }
2325
2326     /* source UV surface index 2 */
2327     i965_pp_set_surface_state(ctx, pp_context,
2328                               obj_surface->bo, w * h,
2329                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2330                               2, 0);
2331
2332     /* source YUV surface index 4 */
2333     i965_pp_set_surface2_state(ctx, pp_context,
2334                                obj_surface->bo, 0,
2335                                orig_w, orig_h, w,
2336                                0, h,
2337                                SURFACE_FORMAT_PLANAR_420_8, 1,
2338                                4);
2339
2340     /* source STMM surface index 20 */
2341     i965_pp_set_surface_state(ctx, pp_context,
2342                               pp_context->stmm.bo, 0,
2343                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2344                               20, 1);
2345
2346     /* destination surface */
2347     obj_surface = SURFACE(dst_surface->id);
2348     orig_w = obj_surface->orig_width;
2349     orig_h = obj_surface->orig_height;
2350     w = obj_surface->width;
2351     h = obj_surface->height;
2352
2353     /* destination Y surface index 7 */
2354     i965_pp_set_surface_state(ctx, pp_context,
2355                               obj_surface->bo, 0,
2356                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2357                               7, 1);
2358
2359     /* destination UV surface index 8 */
2360     i965_pp_set_surface_state(ctx, pp_context,
2361                               obj_surface->bo, w * h,
2362                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2363                               8, 1);
2364     /* sampler dndi */
2365     dri_bo_map(pp_context->sampler_state_table.bo, True);
2366     assert(pp_context->sampler_state_table.bo->virtual);
2367     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2368     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2369
2370     /* sample dndi index 1 */
2371     index = 0;
2372     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2373     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
2374     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2375     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2376
2377     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2378     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 4;
2379     sampler_dndi[index].dw1.stmm_c2 = 1;
2380     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2381     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2382
2383     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
2384     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
2385     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
2386     sampler_dndi[index].dw2.good_neighbor_threshold = 4;                // 0-63
2387
2388     sampler_dndi[index].dw3.maximum_stmm = 128;
2389     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2390     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2391     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2392     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2393
2394     sampler_dndi[index].dw4.sdi_delta = 8;
2395     sampler_dndi[index].dw4.sdi_threshold = 128;
2396     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2397     sampler_dndi[index].dw4.stmm_shift_up = 0;
2398     sampler_dndi[index].dw4.stmm_shift_down = 0;
2399     sampler_dndi[index].dw4.minimum_stmm = 0;
2400
2401     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 8;
2402     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 32;
2403     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 64;
2404     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 32;
2405
2406     sampler_dndi[index].dw6.dn_enable = 1;
2407     sampler_dndi[index].dw6.di_enable = 1;
2408     sampler_dndi[index].dw6.di_partial = 0;
2409     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2410     sampler_dndi[index].dw6.dndi_stream_id = 0;
2411     sampler_dndi[index].dw6.dndi_first_frame = 1;
2412     sampler_dndi[index].dw6.progressive_dn = 0;
2413     sampler_dndi[index].dw6.fmd_tear_threshold = 63;
2414     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2415     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2416
2417     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
2418     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
2419     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2420     sampler_dndi[index].dw7.column_width_minus1 = 0;
2421
2422     dri_bo_unmap(pp_context->sampler_state_table.bo);
2423
2424     /* private function & data */
2425     pp_context->pp_x_steps = pp_dndi_x_steps;
2426     pp_context->pp_y_steps = pp_dndi_y_steps;
2427     pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
2428
2429     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
2430     pp_static_parameter->grf1.r1_6.di.top_field_first = dndi_top_first;
2431     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 0;
2432     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 0;
2433
2434     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
2435     pp_inline_parameter->grf5.number_blocks = w / 16;
2436     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
2437     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
2438
2439     pp_dndi_context->dest_w = w;
2440     pp_dndi_context->dest_h = h;
2441
2442     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
2443
2444     return VA_STATUS_SUCCESS;
2445 }
2446
2447 static int
2448 pp_dn_x_steps(void *private_context)
2449 {
2450     return 1;
2451 }
2452
2453 static int
2454 pp_dn_y_steps(void *private_context)
2455 {
2456     struct pp_dn_context *pp_dn_context = private_context;
2457
2458     return pp_dn_context->dest_h / 8;
2459 }
2460
2461 static int
2462 pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2463 {
2464     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2465
2466     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2467     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
2468
2469     return 0;
2470 }
2471
2472 static VAStatus
2473 pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2474                       const struct i965_surface *src_surface,
2475                       const VARectangle *src_rect,
2476                       struct i965_surface *dst_surface,
2477                       const VARectangle *dst_rect,
2478                       void *filter_param)
2479 {
2480     struct i965_driver_data *i965 = i965_driver_data(ctx);
2481     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
2482     struct object_surface *obj_surface;
2483     struct i965_sampler_dndi *sampler_dndi;
2484     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2485     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2486     VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
2487     int index;
2488     int w, h;
2489     int orig_w, orig_h;
2490     int dn_strength = 15;
2491     int dndi_top_first = 1;
2492     int dn_progressive = 0;
2493
2494     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
2495         dndi_top_first = 1;
2496         dn_progressive = 1;
2497     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
2498         dndi_top_first = 1;
2499         dn_progressive = 0;
2500     } else {
2501         dndi_top_first = 0;
2502         dn_progressive = 0;
2503     }
2504
2505     if (dn_filter_param) {
2506         float value = dn_filter_param->value;
2507         
2508         if (value > 1.0)
2509             value = 1.0;
2510         
2511         if (value < 0.0)
2512             value = 0.0;
2513
2514         dn_strength = (int)(value * 31.0F);
2515     }
2516
2517     /* surface */
2518     obj_surface = SURFACE(src_surface->id);
2519     orig_w = obj_surface->orig_width;
2520     orig_h = obj_surface->orig_height;
2521     w = obj_surface->width;
2522     h = obj_surface->height;
2523
2524     if (pp_context->stmm.bo == NULL) {
2525         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2526                                            "STMM surface",
2527                                            w * h,
2528                                            4096);
2529         assert(pp_context->stmm.bo);
2530     }
2531
2532     /* source UV surface index 2 */
2533     i965_pp_set_surface_state(ctx, pp_context,
2534                               obj_surface->bo, w * h,
2535                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2536                               2, 0);
2537
2538     /* source YUV surface index 4 */
2539     i965_pp_set_surface2_state(ctx, pp_context,
2540                                obj_surface->bo, 0,
2541                                orig_w, orig_h, w,
2542                                0, h,
2543                                SURFACE_FORMAT_PLANAR_420_8, 1,
2544                                4);
2545
2546     /* source STMM surface index 20 */
2547     i965_pp_set_surface_state(ctx, pp_context,
2548                               pp_context->stmm.bo, 0,
2549                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2550                               20, 1);
2551
2552     /* destination surface */
2553     obj_surface = SURFACE(dst_surface->id);
2554     orig_w = obj_surface->orig_width;
2555     orig_h = obj_surface->orig_height;
2556     w = obj_surface->width;
2557     h = obj_surface->height;
2558
2559     /* destination Y surface index 7 */
2560     i965_pp_set_surface_state(ctx, pp_context,
2561                               obj_surface->bo, 0,
2562                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2563                               7, 1);
2564
2565     /* destination UV surface index 8 */
2566     i965_pp_set_surface_state(ctx, pp_context,
2567                               obj_surface->bo, w * h,
2568                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2569                               8, 1);
2570     /* sampler dn */
2571     dri_bo_map(pp_context->sampler_state_table.bo, True);
2572     assert(pp_context->sampler_state_table.bo->virtual);
2573     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2574     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2575
2576     /* sample dndi index 1 */
2577     index = 0;
2578     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2579     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
2580     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2581     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2582
2583     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2584     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
2585     sampler_dndi[index].dw1.stmm_c2 = 0;
2586     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2587     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2588
2589     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
2590     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
2591     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
2592     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
2593
2594     sampler_dndi[index].dw3.maximum_stmm = 128;
2595     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2596     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2597     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2598     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2599
2600     sampler_dndi[index].dw4.sdi_delta = 8;
2601     sampler_dndi[index].dw4.sdi_threshold = 128;
2602     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2603     sampler_dndi[index].dw4.stmm_shift_up = 0;
2604     sampler_dndi[index].dw4.stmm_shift_down = 0;
2605     sampler_dndi[index].dw4.minimum_stmm = 0;
2606
2607     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
2608     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
2609     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
2610     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
2611
2612     sampler_dndi[index].dw6.dn_enable = 1;
2613     sampler_dndi[index].dw6.di_enable = 0;
2614     sampler_dndi[index].dw6.di_partial = 0;
2615     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2616     sampler_dndi[index].dw6.dndi_stream_id = 1;
2617     sampler_dndi[index].dw6.dndi_first_frame = 1;
2618     sampler_dndi[index].dw6.progressive_dn = dn_progressive;
2619     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
2620     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2621     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2622
2623     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
2624     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
2625     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2626     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
2627
2628     dri_bo_unmap(pp_context->sampler_state_table.bo);
2629
2630     /* private function & data */
2631     pp_context->pp_x_steps = pp_dn_x_steps;
2632     pp_context->pp_y_steps = pp_dn_y_steps;
2633     pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
2634
2635     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
2636     pp_static_parameter->grf1.r1_6.di.top_field_first = 0;
2637     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 64;
2638     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 192;
2639
2640     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
2641     pp_inline_parameter->grf5.number_blocks = w / 16;
2642     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
2643     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
2644
2645     pp_dn_context->dest_w = w;
2646     pp_dn_context->dest_h = h;
2647
2648     dst_surface->flags = src_surface->flags;
2649     
2650     return VA_STATUS_SUCCESS;
2651 }
2652
2653 static int
2654 gen7_pp_dndi_x_steps(void *private_context)
2655 {
2656     struct pp_dndi_context *pp_dndi_context = private_context;
2657
2658     return pp_dndi_context->dest_w / 16;
2659 }
2660
2661 static int
2662 gen7_pp_dndi_y_steps(void *private_context)
2663 {
2664     struct pp_dndi_context *pp_dndi_context = private_context;
2665
2666     return pp_dndi_context->dest_h / 4;
2667 }
2668
2669 static int
2670 gen7_pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2671 {
2672     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2673
2674     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16;
2675     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 4;
2676
2677     return 0;
2678 }
2679
2680 static VAStatus
2681 gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2682                              const struct i965_surface *src_surface,
2683                              const VARectangle *src_rect,
2684                              struct i965_surface *dst_surface,
2685                              const VARectangle *dst_rect,
2686                              void *filter_param)
2687 {
2688     struct i965_driver_data *i965 = i965_driver_data(ctx);
2689     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
2690     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2691     struct object_surface *obj_surface;
2692     struct gen7_sampler_dndi *sampler_dndi;
2693     int index;
2694     int w, h;
2695     int orig_w, orig_h;
2696     int dndi_top_first = 1;
2697
2698     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
2699         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
2700
2701     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
2702         dndi_top_first = 1;
2703     else
2704         dndi_top_first = 0;
2705
2706     /* surface */
2707     obj_surface = SURFACE(src_surface->id);
2708     orig_w = obj_surface->orig_width;
2709     orig_h = obj_surface->orig_height;
2710     w = obj_surface->width;
2711     h = obj_surface->height;
2712
2713     if (pp_context->stmm.bo == NULL) {
2714         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2715                                            "STMM surface",
2716                                            w * h,
2717                                            4096);
2718         assert(pp_context->stmm.bo);
2719     }
2720
2721     /* source UV surface index 1 */
2722     gen7_pp_set_surface_state(ctx, pp_context,
2723                               obj_surface->bo, w * h,
2724                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2725                               1, 0);
2726
2727     /* source YUV surface index 3 */
2728     gen7_pp_set_surface2_state(ctx, pp_context,
2729                                obj_surface->bo, 0,
2730                                orig_w, orig_h, w,
2731                                0, h,
2732                                SURFACE_FORMAT_PLANAR_420_8, 1,
2733                                3);
2734
2735     /* source (temporal reference) YUV surface index 4 */
2736     gen7_pp_set_surface2_state(ctx, pp_context,
2737                                obj_surface->bo, 0,
2738                                orig_w, orig_h, w,
2739                                0, h,
2740                                SURFACE_FORMAT_PLANAR_420_8, 1,
2741                                4);
2742
2743     /* STMM / History Statistics input surface, index 5 */
2744     gen7_pp_set_surface_state(ctx, pp_context,
2745                               pp_context->stmm.bo, 0,
2746                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2747                               5, 1);
2748
2749     /* destination surface */
2750     obj_surface = SURFACE(dst_surface->id);
2751     orig_w = obj_surface->orig_width;
2752     orig_h = obj_surface->orig_height;
2753     w = obj_surface->width;
2754     h = obj_surface->height;
2755
2756     /* destination(Previous frame) Y surface index 27 */
2757     gen7_pp_set_surface_state(ctx, pp_context,
2758                               obj_surface->bo, 0,
2759                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2760                               27, 1);
2761
2762     /* destination(Previous frame) UV surface index 28 */
2763     gen7_pp_set_surface_state(ctx, pp_context,
2764                               obj_surface->bo, w * h,
2765                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2766                               28, 1);
2767
2768     /* destination(Current frame) Y surface index 30 */
2769     gen7_pp_set_surface_state(ctx, pp_context,
2770                               obj_surface->bo, 0,
2771                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2772                               30, 1);
2773
2774     /* destination(Current frame) UV surface index 31 */
2775     gen7_pp_set_surface_state(ctx, pp_context,
2776                               obj_surface->bo, w * h,
2777                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2778                               31, 1);
2779
2780     /* STMM output surface, index 33 */
2781     gen7_pp_set_surface_state(ctx, pp_context,
2782                               pp_context->stmm.bo, 0,
2783                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2784                               33, 1);
2785
2786
2787     /* sampler dndi */
2788     dri_bo_map(pp_context->sampler_state_table.bo, True);
2789     assert(pp_context->sampler_state_table.bo->virtual);
2790     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2791     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2792
2793     /* sample dndi index 0 */
2794     index = 0;
2795     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2796     sampler_dndi[index].dw0.dnmh_delt = 8;
2797     sampler_dndi[index].dw0.vdi_walker_y_stride = 0;
2798     sampler_dndi[index].dw0.vdi_walker_frame_sharing_enable = 0;
2799     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2800     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2801
2802     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2803     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
2804     sampler_dndi[index].dw1.stmm_c2 = 0;
2805     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2806     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2807
2808     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
2809     sampler_dndi[index].dw2.bne_edge_th = 1;
2810     sampler_dndi[index].dw2.smooth_mv_th = 0;
2811     sampler_dndi[index].dw2.sad_tight_th = 5;
2812     sampler_dndi[index].dw2.cat_slope_minus1 = 9;
2813     sampler_dndi[index].dw2.good_neighbor_th = 4;
2814
2815     sampler_dndi[index].dw3.maximum_stmm = 128;
2816     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2817     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2818     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2819     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2820
2821     sampler_dndi[index].dw4.sdi_delta = 8;
2822     sampler_dndi[index].dw4.sdi_threshold = 128;
2823     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2824     sampler_dndi[index].dw4.stmm_shift_up = 0;
2825     sampler_dndi[index].dw4.stmm_shift_down = 0;
2826     sampler_dndi[index].dw4.minimum_stmm = 0;
2827
2828     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
2829     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
2830     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
2831     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
2832
2833     sampler_dndi[index].dw6.dn_enable = 0;
2834     sampler_dndi[index].dw6.di_enable = 1;
2835     sampler_dndi[index].dw6.di_partial = 0;
2836     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2837     sampler_dndi[index].dw6.dndi_stream_id = 1;
2838     sampler_dndi[index].dw6.dndi_first_frame = 1;
2839     sampler_dndi[index].dw6.progressive_dn = 0;
2840     sampler_dndi[index].dw6.mcdi_enable = 0;
2841     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
2842     sampler_dndi[index].dw6.cat_th1 = 0;
2843     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2844     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2845
2846     sampler_dndi[index].dw7.sad_tha = 5;
2847     sampler_dndi[index].dw7.sad_thb = 10;
2848     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
2849     sampler_dndi[index].dw7.mc_pixel_consistency_th = 25;
2850     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
2851     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2852     sampler_dndi[index].dw7.neighborpixel_th = 10;
2853     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
2854
2855     dri_bo_unmap(pp_context->sampler_state_table.bo);
2856
2857     /* private function & data */
2858     pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
2859     pp_context->pp_y_steps = gen7_pp_dndi_y_steps;
2860     pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
2861
2862     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
2863     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
2864     pp_static_parameter->grf1.di_top_field_first = 0;
2865     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
2866
2867     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
2868     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
2869     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
2870
2871     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
2872     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
2873
2874     pp_dndi_context->dest_w = w;
2875     pp_dndi_context->dest_h = h;
2876
2877     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
2878
2879     return VA_STATUS_SUCCESS;
2880 }
2881
2882 static int
2883 gen7_pp_dn_x_steps(void *private_context)
2884 {
2885     return 1;
2886 }
2887
2888 static int
2889 gen7_pp_dn_y_steps(void *private_context)
2890 {
2891     struct pp_dn_context *pp_dn_context = private_context;
2892
2893     return pp_dn_context->dest_h / 4;
2894 }
2895
2896 static int
2897 gen7_pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2898 {
2899     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2900
2901     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2902     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
2903
2904     return 0;
2905 }
2906
2907 static VAStatus
2908 gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2909                            const struct i965_surface *src_surface,
2910                            const VARectangle *src_rect,
2911                            struct i965_surface *dst_surface,
2912                            const VARectangle *dst_rect,
2913                            void *filter_param)
2914 {
2915     struct i965_driver_data *i965 = i965_driver_data(ctx);
2916     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
2917     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2918     struct object_surface *obj_surface;
2919     struct gen7_sampler_dndi *sampler_dn;
2920     VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
2921     int index;
2922     int w, h;
2923     int orig_w, orig_h;
2924     int dn_strength = 15;
2925     int dndi_top_first = 1;
2926     int dn_progressive = 0;
2927
2928     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
2929         dndi_top_first = 1;
2930         dn_progressive = 1;
2931     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
2932         dndi_top_first = 1;
2933         dn_progressive = 0;
2934     } else {
2935         dndi_top_first = 0;
2936         dn_progressive = 0;
2937     }
2938
2939     if (dn_filter_param) {
2940         float value = dn_filter_param->value;
2941         
2942         if (value > 1.0)
2943             value = 1.0;
2944         
2945         if (value < 0.0)
2946             value = 0.0;
2947
2948         dn_strength = (int)(value * 31.0F);
2949     }
2950
2951     /* surface */
2952     obj_surface = SURFACE(src_surface->id);
2953     orig_w = obj_surface->orig_width;
2954     orig_h = obj_surface->orig_height;
2955     w = obj_surface->width;
2956     h = obj_surface->height;
2957
2958     if (pp_context->stmm.bo == NULL) {
2959         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2960                                            "STMM surface",
2961                                            w * h,
2962                                            4096);
2963         assert(pp_context->stmm.bo);
2964     }
2965
2966     /* source UV surface index 1 */
2967     gen7_pp_set_surface_state(ctx, pp_context,
2968                               obj_surface->bo, w * h,
2969                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2970                               1, 0);
2971
2972     /* source YUV surface index 3 */
2973     gen7_pp_set_surface2_state(ctx, pp_context,
2974                                obj_surface->bo, 0,
2975                                orig_w, orig_h, w,
2976                                0, h,
2977                                SURFACE_FORMAT_PLANAR_420_8, 1,
2978                                3);
2979
2980     /* source STMM surface index 5 */
2981     gen7_pp_set_surface_state(ctx, pp_context,
2982                               pp_context->stmm.bo, 0,
2983                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2984                               5, 1);
2985
2986     /* destination surface */
2987     obj_surface = SURFACE(dst_surface->id);
2988     orig_w = obj_surface->orig_width;
2989     orig_h = obj_surface->orig_height;
2990     w = obj_surface->width;
2991     h = obj_surface->height;
2992
2993     /* destination Y surface index 7 */
2994     gen7_pp_set_surface_state(ctx, pp_context,
2995                               obj_surface->bo, 0,
2996                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2997                               7, 1);
2998
2999     /* destination UV surface index 8 */
3000     gen7_pp_set_surface_state(ctx, pp_context,
3001                               obj_surface->bo, w * h,
3002                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3003                               8, 1);
3004     /* sampler dn */
3005     dri_bo_map(pp_context->sampler_state_table.bo, True);
3006     assert(pp_context->sampler_state_table.bo->virtual);
3007     assert(sizeof(*sampler_dn) == sizeof(int) * 8);
3008     sampler_dn = pp_context->sampler_state_table.bo->virtual;
3009
3010     /* sample dn index 1 */
3011     index = 0;
3012     sampler_dn[index].dw0.denoise_asd_threshold = 0;
3013     sampler_dn[index].dw0.dnmh_delt = 8;
3014     sampler_dn[index].dw0.vdi_walker_y_stride = 0;
3015     sampler_dn[index].dw0.vdi_walker_frame_sharing_enable = 0;
3016     sampler_dn[index].dw0.denoise_maximum_history = 128;      // 128-240
3017     sampler_dn[index].dw0.denoise_stad_threshold = 0;
3018
3019     sampler_dn[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
3020     sampler_dn[index].dw1.denoise_moving_pixel_threshold = 0;
3021     sampler_dn[index].dw1.stmm_c2 = 0;
3022     sampler_dn[index].dw1.low_temporal_difference_threshold = 8;
3023     sampler_dn[index].dw1.temporal_difference_threshold = 16;
3024
3025     sampler_dn[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
3026     sampler_dn[index].dw2.bne_edge_th = 1;
3027     sampler_dn[index].dw2.smooth_mv_th = 0;
3028     sampler_dn[index].dw2.sad_tight_th = 5;
3029     sampler_dn[index].dw2.cat_slope_minus1 = 9;
3030     sampler_dn[index].dw2.good_neighbor_th = 4;
3031
3032     sampler_dn[index].dw3.maximum_stmm = 128;
3033     sampler_dn[index].dw3.multipler_for_vecm = 2;
3034     sampler_dn[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
3035     sampler_dn[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3036     sampler_dn[index].dw3.stmm_blending_constant_select = 0;
3037
3038     sampler_dn[index].dw4.sdi_delta = 8;
3039     sampler_dn[index].dw4.sdi_threshold = 128;
3040     sampler_dn[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
3041     sampler_dn[index].dw4.stmm_shift_up = 0;
3042     sampler_dn[index].dw4.stmm_shift_down = 0;
3043     sampler_dn[index].dw4.minimum_stmm = 0;
3044
3045     sampler_dn[index].dw5.fmd_temporal_difference_threshold = 0;
3046     sampler_dn[index].dw5.sdi_fallback_mode_2_constant = 0;
3047     sampler_dn[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
3048     sampler_dn[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
3049
3050     sampler_dn[index].dw6.dn_enable = 1;
3051     sampler_dn[index].dw6.di_enable = 0;
3052     sampler_dn[index].dw6.di_partial = 0;
3053     sampler_dn[index].dw6.dndi_top_first = dndi_top_first;
3054     sampler_dn[index].dw6.dndi_stream_id = 1;
3055     sampler_dn[index].dw6.dndi_first_frame = 1;
3056     sampler_dn[index].dw6.progressive_dn = dn_progressive;
3057     sampler_dn[index].dw6.mcdi_enable = 0;
3058     sampler_dn[index].dw6.fmd_tear_threshold = 32;
3059     sampler_dn[index].dw6.cat_th1 = 0;
3060     sampler_dn[index].dw6.fmd2_vertical_difference_threshold = 32;
3061     sampler_dn[index].dw6.fmd1_vertical_difference_threshold = 32;
3062
3063     sampler_dn[index].dw7.sad_tha = 5;
3064     sampler_dn[index].dw7.sad_thb = 10;
3065     sampler_dn[index].dw7.fmd_for_1st_field_of_current_frame = 2;
3066     sampler_dn[index].dw7.mc_pixel_consistency_th = 25;
3067     sampler_dn[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
3068     sampler_dn[index].dw7.vdi_walker_enable = 0;
3069     sampler_dn[index].dw7.neighborpixel_th = 10;
3070     sampler_dn[index].dw7.column_width_minus1 = w / 16;
3071
3072     dri_bo_unmap(pp_context->sampler_state_table.bo);
3073
3074     /* private function & data */
3075     pp_context->pp_x_steps = gen7_pp_dn_x_steps;
3076     pp_context->pp_y_steps = gen7_pp_dn_y_steps;
3077     pp_context->pp_set_block_parameter = gen7_pp_dn_set_block_parameter;
3078
3079     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
3080     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
3081     pp_static_parameter->grf1.di_top_field_first = 0;
3082     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
3083
3084     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
3085     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
3086     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
3087
3088     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
3089     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
3090
3091     pp_dn_context->dest_w = w;
3092     pp_dn_context->dest_h = h;
3093
3094     dst_surface->flags = src_surface->flags;
3095
3096     return VA_STATUS_SUCCESS;
3097 }
3098
3099 // update u/v offset when the surface format are packed yuv
3100 static void i965_update_src_surface_uv_offset(
3101     VADriverContextP    ctx, 
3102     struct i965_post_processing_context *pp_context,
3103     const struct i965_surface *surface)
3104 {
3105     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3106     int fourcc = pp_get_surface_fourcc(ctx, surface);
3107     
3108     if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
3109         pp_static_parameter->grf1.source_packed_u_offset = 1;
3110         pp_static_parameter->grf1.source_packed_v_offset = 3;
3111     } 
3112     else if (fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
3113         pp_static_parameter->grf1.source_packed_y_offset = 1;
3114         pp_static_parameter->grf1.source_packed_v_offset = 2;
3115     }
3116     
3117 }
3118
3119 static void i965_update_dst_surface_uv_offset(
3120     VADriverContextP    ctx, 
3121     struct i965_post_processing_context *pp_context,
3122     const struct i965_surface *surface)
3123 {
3124     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3125     int fourcc = pp_get_surface_fourcc(ctx, surface);
3126     
3127     if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
3128         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_u_offset = 1;
3129         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 3;
3130     } 
3131     else if (fourcc == VA_FOURCC('U', 'Y', 'V', 'Y')) {
3132         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_y_offset = 1;
3133         pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 2;
3134     }
3135     
3136 }
3137
3138 static VAStatus
3139 ironlake_pp_initialize(
3140     VADriverContextP   ctx,
3141     struct i965_post_processing_context *pp_context,
3142     const struct i965_surface *src_surface,
3143     const VARectangle *src_rect,
3144     struct i965_surface *dst_surface,
3145     const VARectangle *dst_rect,
3146     int                pp_index,
3147     void *filter_param
3148 )
3149 {
3150     VAStatus va_status;
3151     struct i965_driver_data *i965 = i965_driver_data(ctx);
3152     struct pp_module *pp_module;
3153     dri_bo *bo;
3154     int static_param_size, inline_param_size;
3155
3156     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
3157     bo = dri_bo_alloc(i965->intel.bufmgr,
3158                       "surface state & binding table",
3159                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
3160                       4096);
3161     assert(bo);
3162     pp_context->surface_state_binding_table.bo = bo;
3163
3164     dri_bo_unreference(pp_context->curbe.bo);
3165     bo = dri_bo_alloc(i965->intel.bufmgr,
3166                       "constant buffer",
3167                       4096, 
3168                       4096);
3169     assert(bo);
3170     pp_context->curbe.bo = bo;
3171
3172     dri_bo_unreference(pp_context->idrt.bo);
3173     bo = dri_bo_alloc(i965->intel.bufmgr, 
3174                       "interface discriptor", 
3175                       sizeof(struct i965_interface_descriptor), 
3176                       4096);
3177     assert(bo);
3178     pp_context->idrt.bo = bo;
3179     pp_context->idrt.num_interface_descriptors = 0;
3180
3181     dri_bo_unreference(pp_context->sampler_state_table.bo);
3182     bo = dri_bo_alloc(i965->intel.bufmgr, 
3183                       "sampler state table", 
3184                       4096,
3185                       4096);
3186     assert(bo);
3187     dri_bo_map(bo, True);
3188     memset(bo->virtual, 0, bo->size);
3189     dri_bo_unmap(bo);
3190     pp_context->sampler_state_table.bo = bo;
3191
3192     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
3193     bo = dri_bo_alloc(i965->intel.bufmgr, 
3194                       "sampler 8x8 state ",
3195                       4096,
3196                       4096);
3197     assert(bo);
3198     pp_context->sampler_state_table.bo_8x8 = bo;
3199
3200     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
3201     bo = dri_bo_alloc(i965->intel.bufmgr, 
3202                       "sampler 8x8 state ",
3203                       4096,
3204                       4096);
3205     assert(bo);
3206     pp_context->sampler_state_table.bo_8x8_uv = bo;
3207
3208     dri_bo_unreference(pp_context->vfe_state.bo);
3209     bo = dri_bo_alloc(i965->intel.bufmgr, 
3210                       "vfe state", 
3211                       sizeof(struct i965_vfe_state), 
3212                       4096);
3213     assert(bo);
3214     pp_context->vfe_state.bo = bo;
3215
3216     if (IS_GEN7(i965->intel.device_id)) {
3217         static_param_size = sizeof(struct gen7_pp_static_parameter);
3218         inline_param_size = sizeof(struct gen7_pp_inline_parameter);
3219     } else {
3220         static_param_size = sizeof(struct pp_static_parameter);
3221         inline_param_size = sizeof(struct pp_inline_parameter);
3222     }
3223
3224     memset(pp_context->pp_static_parameter, 0, static_param_size);
3225     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
3226     
3227     // update u/v offset for packed yuv
3228     i965_update_src_surface_uv_offset (ctx, pp_context, src_surface);
3229     i965_update_dst_surface_uv_offset (ctx, pp_context, dst_surface);
3230
3231     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
3232     pp_context->current_pp = pp_index;
3233     pp_module = &pp_context->pp_modules[pp_index];
3234     
3235     if (pp_module->initialize)
3236         va_status = pp_module->initialize(ctx, pp_context,
3237                                           src_surface,
3238                                           src_rect,
3239                                           dst_surface,
3240                                           dst_rect,
3241                                           filter_param);
3242     else
3243         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
3244
3245     return va_status;
3246 }
3247
3248 static VAStatus
3249 ironlake_post_processing(
3250     VADriverContextP   ctx,
3251     struct i965_post_processing_context *pp_context,
3252     const struct i965_surface *src_surface,
3253     const VARectangle *src_rect,
3254     struct i965_surface *dst_surface,
3255     const VARectangle *dst_rect,
3256     int                pp_index,
3257     void *filter_param
3258 )
3259 {
3260     VAStatus va_status;
3261
3262     va_status = ironlake_pp_initialize(ctx, pp_context,
3263                                        src_surface,
3264                                        src_rect,
3265                                        dst_surface,
3266                                        dst_rect,
3267                                        pp_index,
3268                                        filter_param);
3269
3270     if (va_status == VA_STATUS_SUCCESS) {
3271         ironlake_pp_states_setup(ctx, pp_context);
3272         ironlake_pp_pipeline_setup(ctx, pp_context);
3273     }
3274
3275     return va_status;
3276 }
3277
3278 static VAStatus
3279 gen6_pp_initialize(
3280     VADriverContextP   ctx,
3281     struct i965_post_processing_context *pp_context,
3282     const struct i965_surface *src_surface,
3283     const VARectangle *src_rect,
3284     struct i965_surface *dst_surface,
3285     const VARectangle *dst_rect,
3286     int                pp_index,
3287     void *filter_param
3288 )
3289 {
3290     VAStatus va_status;
3291     struct i965_driver_data *i965 = i965_driver_data(ctx);
3292     struct pp_module *pp_module;
3293     dri_bo *bo;
3294     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3295     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3296
3297     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
3298     bo = dri_bo_alloc(i965->intel.bufmgr,
3299                       "surface state & binding table",
3300                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
3301                       4096);
3302     assert(bo);
3303     pp_context->surface_state_binding_table.bo = bo;
3304
3305     dri_bo_unreference(pp_context->curbe.bo);
3306     bo = dri_bo_alloc(i965->intel.bufmgr,
3307                       "constant buffer",
3308                       4096, 
3309                       4096);
3310     assert(bo);
3311     pp_context->curbe.bo = bo;
3312
3313     dri_bo_unreference(pp_context->idrt.bo);
3314     bo = dri_bo_alloc(i965->intel.bufmgr, 
3315                       "interface discriptor", 
3316                       sizeof(struct gen6_interface_descriptor_data), 
3317                       4096);
3318     assert(bo);
3319     pp_context->idrt.bo = bo;
3320     pp_context->idrt.num_interface_descriptors = 0;
3321
3322     dri_bo_unreference(pp_context->sampler_state_table.bo);
3323     bo = dri_bo_alloc(i965->intel.bufmgr, 
3324                       "sampler state table", 
3325                       4096,
3326                       4096);
3327     assert(bo);
3328     dri_bo_map(bo, True);
3329     memset(bo->virtual, 0, bo->size);
3330     dri_bo_unmap(bo);
3331     pp_context->sampler_state_table.bo = bo;
3332
3333     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
3334     bo = dri_bo_alloc(i965->intel.bufmgr, 
3335                       "sampler 8x8 state ",
3336                       4096,
3337                       4096);
3338     assert(bo);
3339     pp_context->sampler_state_table.bo_8x8 = bo;
3340
3341     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
3342     bo = dri_bo_alloc(i965->intel.bufmgr, 
3343                       "sampler 8x8 state ",
3344                       4096,
3345                       4096);
3346     assert(bo);
3347     pp_context->sampler_state_table.bo_8x8_uv = bo;
3348
3349     dri_bo_unreference(pp_context->vfe_state.bo);
3350     bo = dri_bo_alloc(i965->intel.bufmgr, 
3351                       "vfe state", 
3352                       sizeof(struct i965_vfe_state), 
3353                       4096);
3354     assert(bo);
3355     pp_context->vfe_state.bo = bo;
3356     
3357     memset(pp_static_parameter, 0, sizeof(*pp_static_parameter));
3358     memset(pp_inline_parameter, 0, sizeof(*pp_inline_parameter));
3359
3360     // update u/v offset for packed yuv
3361     i965_update_src_surface_uv_offset (ctx, pp_context, src_surface);
3362     i965_update_dst_surface_uv_offset (ctx, pp_context, dst_surface);
3363     
3364     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
3365     pp_context->current_pp = pp_index;
3366     pp_module = &pp_context->pp_modules[pp_index];
3367     
3368     if (pp_module->initialize)
3369         va_status = pp_module->initialize(ctx, pp_context,
3370                                           src_surface,
3371                                           src_rect,
3372                                           dst_surface,
3373                                           dst_rect,
3374                                           filter_param);
3375     else
3376         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
3377
3378     return va_status;
3379 }
3380
3381 static void
3382 gen6_pp_interface_descriptor_table(VADriverContextP   ctx,
3383                                    struct i965_post_processing_context *pp_context)
3384 {
3385     struct i965_driver_data *i965 = i965_driver_data(ctx);
3386     struct gen6_interface_descriptor_data *desc;
3387     dri_bo *bo;
3388     int pp_index = pp_context->current_pp;
3389
3390     bo = pp_context->idrt.bo;
3391     dri_bo_map(bo, True);
3392     assert(bo->virtual);
3393     desc = bo->virtual;
3394     memset(desc, 0, sizeof(*desc));
3395     desc->desc0.kernel_start_pointer = 
3396         pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
3397     desc->desc1.single_program_flow = 1;
3398     desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
3399     desc->desc2.sampler_count = 1;      /* 1 - 4 samplers used */
3400     desc->desc2.sampler_state_pointer = 
3401         pp_context->sampler_state_table.bo->offset >> 5;
3402     desc->desc3.binding_table_entry_count = 0;
3403     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
3404     desc->desc4.constant_urb_entry_read_offset = 0;
3405
3406     if (IS_GEN7(i965->intel.device_id))
3407         desc->desc4.constant_urb_entry_read_length = 6; /* grf 1-6 */
3408     else
3409         desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
3410
3411     dri_bo_emit_reloc(bo,
3412                       I915_GEM_DOMAIN_INSTRUCTION, 0,
3413                       0,
3414                       offsetof(struct gen6_interface_descriptor_data, desc0),
3415                       pp_context->pp_modules[pp_index].kernel.bo);
3416
3417     dri_bo_emit_reloc(bo,
3418                       I915_GEM_DOMAIN_INSTRUCTION, 0,
3419                       desc->desc2.sampler_count << 2,
3420                       offsetof(struct gen6_interface_descriptor_data, desc2),
3421                       pp_context->sampler_state_table.bo);
3422
3423     dri_bo_unmap(bo);
3424     pp_context->idrt.num_interface_descriptors++;
3425 }
3426
3427 static void
3428 gen6_pp_upload_constants(VADriverContextP ctx,
3429                          struct i965_post_processing_context *pp_context)
3430 {
3431     struct i965_driver_data *i965 = i965_driver_data(ctx);
3432     unsigned char *constant_buffer;
3433     int param_size;
3434
3435     assert(sizeof(struct pp_static_parameter) == 128);
3436     assert(sizeof(struct gen7_pp_static_parameter) == 192);
3437
3438     if (IS_GEN7(i965->intel.device_id))
3439         param_size = sizeof(struct gen7_pp_static_parameter);
3440     else
3441         param_size = sizeof(struct pp_static_parameter);
3442
3443     dri_bo_map(pp_context->curbe.bo, 1);
3444     assert(pp_context->curbe.bo->virtual);
3445     constant_buffer = pp_context->curbe.bo->virtual;
3446     memcpy(constant_buffer, pp_context->pp_static_parameter, param_size);
3447     dri_bo_unmap(pp_context->curbe.bo);
3448 }
3449
3450 static void
3451 gen6_pp_states_setup(VADriverContextP ctx,
3452                      struct i965_post_processing_context *pp_context)
3453 {
3454     gen6_pp_interface_descriptor_table(ctx, pp_context);
3455     gen6_pp_upload_constants(ctx, pp_context);
3456 }
3457
3458 static void
3459 gen6_pp_pipeline_select(VADriverContextP ctx,
3460                         struct i965_post_processing_context *pp_context)
3461 {
3462     struct intel_batchbuffer *batch = pp_context->batch;
3463
3464     BEGIN_BATCH(batch, 1);
3465     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
3466     ADVANCE_BATCH(batch);
3467 }
3468
3469 static void
3470 gen6_pp_state_base_address(VADriverContextP ctx,
3471                            struct i965_post_processing_context *pp_context)
3472 {
3473     struct intel_batchbuffer *batch = pp_context->batch;
3474
3475     BEGIN_BATCH(batch, 10);
3476     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
3477     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3478     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
3479     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3480     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3481     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3482     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3483     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3484     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3485     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3486     ADVANCE_BATCH(batch);
3487 }
3488
3489 static void
3490 gen6_pp_vfe_state(VADriverContextP ctx,
3491                   struct i965_post_processing_context *pp_context)
3492 {
3493     struct intel_batchbuffer *batch = pp_context->batch;
3494
3495     BEGIN_BATCH(batch, 8);
3496     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
3497     OUT_BATCH(batch, 0);
3498     OUT_BATCH(batch,
3499               (pp_context->urb.num_vfe_entries - 1) << 16 |
3500               pp_context->urb.num_vfe_entries << 8);
3501     OUT_BATCH(batch, 0);
3502     OUT_BATCH(batch,
3503               (pp_context->urb.size_vfe_entry * 2) << 16 |  /* URB Entry Allocation Size, in 256 bits unit */
3504               (pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2)); /* CURBE Allocation Size, in 256 bits unit */
3505     OUT_BATCH(batch, 0);
3506     OUT_BATCH(batch, 0);
3507     OUT_BATCH(batch, 0);
3508     ADVANCE_BATCH(batch);
3509 }
3510
3511 static void
3512 gen6_pp_curbe_load(VADriverContextP ctx,
3513                    struct i965_post_processing_context *pp_context)
3514 {
3515     struct intel_batchbuffer *batch = pp_context->batch;
3516
3517     assert(pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32 <= pp_context->curbe.bo->size);
3518
3519     BEGIN_BATCH(batch, 4);
3520     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
3521     OUT_BATCH(batch, 0);
3522     OUT_BATCH(batch,
3523               pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32);
3524     OUT_RELOC(batch, 
3525               pp_context->curbe.bo,
3526               I915_GEM_DOMAIN_INSTRUCTION, 0,
3527               0);
3528     ADVANCE_BATCH(batch);
3529 }
3530
3531 static void
3532 gen6_interface_descriptor_load(VADriverContextP ctx,
3533                                struct i965_post_processing_context *pp_context)
3534 {
3535     struct intel_batchbuffer *batch = pp_context->batch;
3536
3537     BEGIN_BATCH(batch, 4);
3538     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
3539     OUT_BATCH(batch, 0);
3540     OUT_BATCH(batch,
3541               pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
3542     OUT_RELOC(batch, 
3543               pp_context->idrt.bo,
3544               I915_GEM_DOMAIN_INSTRUCTION, 0,
3545               0);
3546     ADVANCE_BATCH(batch);
3547 }
3548
3549 static void
3550 gen6_pp_object_walker(VADriverContextP ctx,
3551                       struct i965_post_processing_context *pp_context)
3552 {
3553     struct i965_driver_data *i965 = i965_driver_data(ctx);
3554     struct intel_batchbuffer *batch = pp_context->batch;
3555     int x, x_steps, y, y_steps;
3556     int param_size, command_length_in_dws;
3557     dri_bo *command_buffer;
3558     unsigned int *command_ptr;
3559
3560     if (IS_GEN7(i965->intel.device_id))
3561         param_size = sizeof(struct gen7_pp_inline_parameter);
3562     else
3563         param_size = sizeof(struct pp_inline_parameter);
3564
3565     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
3566     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
3567     command_length_in_dws = 6 + (param_size >> 2);
3568     command_buffer = dri_bo_alloc(i965->intel.bufmgr,
3569                                   "command objects buffer",
3570                                   command_length_in_dws * 4 * x_steps * y_steps + 8,
3571                                   4096);
3572
3573     dri_bo_map(command_buffer, 1);
3574     command_ptr = command_buffer->virtual;
3575
3576     for (y = 0; y < y_steps; y++) {
3577         for (x = 0; x < x_steps; x++) {
3578             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
3579                 *command_ptr++ = (CMD_MEDIA_OBJECT | (command_length_in_dws - 2));
3580                 *command_ptr++ = 0;
3581                 *command_ptr++ = 0;
3582                 *command_ptr++ = 0;
3583                 *command_ptr++ = 0;
3584                 *command_ptr++ = 0;
3585                 memcpy(command_ptr, pp_context->pp_inline_parameter, param_size);
3586                 command_ptr += (param_size >> 2);
3587             }
3588         }
3589     }
3590
3591     if (command_length_in_dws * x_steps * y_steps % 2 == 0)
3592         *command_ptr++ = 0;
3593
3594     *command_ptr = MI_BATCH_BUFFER_END;
3595
3596     dri_bo_unmap(command_buffer);
3597
3598     BEGIN_BATCH(batch, 2);
3599     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (2 << 6));
3600     OUT_RELOC(batch, command_buffer, 
3601               I915_GEM_DOMAIN_COMMAND, 0, 
3602               0);
3603     ADVANCE_BATCH(batch);
3604     
3605     dri_bo_unreference(command_buffer);
3606
3607     /* Have to execute the batch buffer here becuase MI_BATCH_BUFFER_END
3608      * will cause control to pass back to ring buffer 
3609      */
3610     intel_batchbuffer_end_atomic(batch);
3611     intel_batchbuffer_flush(batch);
3612     intel_batchbuffer_start_atomic(batch, 0x1000);
3613 }
3614
3615 static void
3616 gen6_pp_pipeline_setup(VADriverContextP ctx,
3617                        struct i965_post_processing_context *pp_context)
3618 {
3619     struct intel_batchbuffer *batch = pp_context->batch;
3620
3621     intel_batchbuffer_start_atomic(batch, 0x1000);
3622     intel_batchbuffer_emit_mi_flush(batch);
3623     gen6_pp_pipeline_select(ctx, pp_context);
3624     gen6_pp_state_base_address(ctx, pp_context);
3625     gen6_pp_vfe_state(ctx, pp_context);
3626     gen6_pp_curbe_load(ctx, pp_context);
3627     gen6_interface_descriptor_load(ctx, pp_context);
3628     gen6_pp_object_walker(ctx, pp_context);
3629     intel_batchbuffer_end_atomic(batch);
3630 }
3631
3632 static VAStatus
3633 gen6_post_processing(
3634     VADriverContextP   ctx,
3635     struct i965_post_processing_context *pp_context,
3636     const struct i965_surface *src_surface,
3637     const VARectangle *src_rect,
3638     struct i965_surface *dst_surface,
3639     const VARectangle *dst_rect,
3640     int                pp_index,
3641     void * filter_param
3642 )
3643 {
3644     VAStatus va_status;
3645     
3646     va_status = gen6_pp_initialize(ctx, pp_context,
3647                                    src_surface,
3648                                    src_rect,
3649                                    dst_surface,
3650                                    dst_rect,
3651                                    pp_index,
3652                                    filter_param);
3653
3654     if (va_status == VA_STATUS_SUCCESS) {
3655         gen6_pp_states_setup(ctx, pp_context);
3656         gen6_pp_pipeline_setup(ctx, pp_context);
3657     }
3658
3659     return va_status;
3660 }
3661
3662 static VAStatus
3663 i965_post_processing_internal(
3664     VADriverContextP   ctx,
3665     struct i965_post_processing_context *pp_context,
3666     const struct i965_surface *src_surface,
3667     const VARectangle *src_rect,
3668     struct i965_surface *dst_surface,
3669     const VARectangle *dst_rect,
3670     int                pp_index,
3671     void *filter_param
3672 )
3673 {
3674     struct i965_driver_data *i965 = i965_driver_data(ctx);
3675     VAStatus va_status;
3676
3677     if (IS_GEN6(i965->intel.device_id) ||
3678         IS_GEN7(i965->intel.device_id))
3679         va_status = gen6_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
3680     else
3681         va_status = ironlake_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
3682     
3683     return va_status;
3684 }
3685
3686 VAStatus 
3687 i965_DestroySurfaces(VADriverContextP ctx,
3688                      VASurfaceID *surface_list,
3689                      int num_surfaces);
3690 VAStatus 
3691 i965_CreateSurfaces(VADriverContextP ctx,
3692                     int width,
3693                     int height,
3694                     int format,
3695                     int num_surfaces,
3696                     VASurfaceID *surfaces);
3697
3698 static void
3699 rgb_to_yuv(unsigned int argb,
3700            unsigned char *y,
3701            unsigned char *u,
3702            unsigned char *v,
3703            unsigned char *a)
3704 {
3705     int r = ((argb >> 16) & 0xff);
3706     int g = ((argb >> 8) & 0xff);
3707     int b = ((argb >> 0) & 0xff);
3708     
3709     *y = (257 * r + 504 * g + 98 * b) / 1000 + 16;
3710     *v = (439 * r - 368 * g - 71 * b) / 1000 + 128;
3711     *u = (-148 * r - 291 * g + 439 * b) / 1000 + 128;
3712     *a = ((argb >> 24) & 0xff);
3713 }
3714
3715 static void 
3716 i965_vpp_clear_surface(VADriverContextP ctx,
3717                        struct i965_post_processing_context *pp_context,
3718                        VASurfaceID surface,
3719                        unsigned int color)
3720 {
3721     struct i965_driver_data *i965 = i965_driver_data(ctx);
3722     struct intel_batchbuffer *batch = pp_context->batch;
3723     struct object_surface *obj_surface = SURFACE(surface);
3724     unsigned int blt_cmd, br13;
3725     unsigned int tiling = 0, swizzle = 0;
3726     int pitch;
3727     unsigned char y, u, v, a;
3728
3729     /* Currently only support NV12 surface */
3730     if (!obj_surface || obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2'))
3731         return;
3732
3733     rgb_to_yuv(color, &y, &u, &v, &a);
3734
3735     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3736     blt_cmd = XY_COLOR_BLT_CMD;
3737     pitch = obj_surface->width;
3738
3739     if (tiling != I915_TILING_NONE) {
3740         blt_cmd |= XY_COLOR_BLT_DST_TILED;
3741         pitch >>= 2;
3742     }
3743
3744     br13 = 0xf0 << 16;
3745     br13 |= BR13_8;
3746     br13 |= pitch;
3747
3748     if (IS_GEN6(i965->intel.device_id) ||
3749         IS_GEN7(i965->intel.device_id)) {
3750         intel_batchbuffer_start_atomic_blt(batch, 48);
3751         BEGIN_BLT_BATCH(batch, 12);
3752     } else {
3753         intel_batchbuffer_start_atomic(batch, 48);
3754         BEGIN_BATCH(batch, 12);
3755     }
3756
3757     OUT_BATCH(batch, blt_cmd);
3758     OUT_BATCH(batch, br13);
3759     OUT_BATCH(batch,
3760               0 << 16 |
3761               0);
3762     OUT_BATCH(batch,
3763               obj_surface->height << 16 |
3764               obj_surface->width);
3765     OUT_RELOC(batch, obj_surface->bo, 
3766               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
3767               0);
3768     OUT_BATCH(batch, y);
3769
3770     br13 = 0xf0 << 16;
3771     br13 |= BR13_565;
3772     br13 |= pitch;
3773
3774     OUT_BATCH(batch, blt_cmd);
3775     OUT_BATCH(batch, br13);
3776     OUT_BATCH(batch,
3777               0 << 16 |
3778               0);
3779     OUT_BATCH(batch,
3780               obj_surface->height / 2 << 16 |
3781               obj_surface->width / 2);
3782     OUT_RELOC(batch, obj_surface->bo, 
3783               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
3784               obj_surface->width * obj_surface->y_cb_offset);
3785     OUT_BATCH(batch, v << 8 | u);
3786
3787     ADVANCE_BATCH(batch);
3788     intel_batchbuffer_end_atomic(batch);
3789 }
3790
3791 VASurfaceID
3792 i965_post_processing(
3793     VADriverContextP   ctx,
3794     VASurfaceID        surface,
3795     const VARectangle *src_rect,
3796     const VARectangle *dst_rect,
3797     unsigned int       flags,
3798     int               *has_done_scaling  
3799 )
3800 {
3801     struct i965_driver_data *i965 = i965_driver_data(ctx);
3802     VASurfaceID in_surface_id = surface;
3803     VASurfaceID out_surface_id = VA_INVALID_ID;
3804     
3805     *has_done_scaling = 0;
3806
3807     if (HAS_PP(i965)) {
3808         struct object_surface *obj_surface;
3809         VAStatus status;
3810         struct i965_surface src_surface;
3811         struct i965_surface dst_surface;
3812
3813         obj_surface = SURFACE(in_surface_id);
3814
3815         /* Currently only support post processing for NV12 surface */
3816         if (obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2'))
3817             return out_surface_id;
3818
3819         _i965LockMutex(&i965->pp_mutex);
3820
3821         if (flags & I965_PP_FLAG_MCDI) {
3822             status = i965_CreateSurfaces(ctx,
3823                                          obj_surface->orig_width,
3824                                          obj_surface->orig_height,
3825                                          VA_RT_FORMAT_YUV420,
3826                                          1,
3827                                          &out_surface_id);
3828             assert(status == VA_STATUS_SUCCESS);
3829             obj_surface = SURFACE(out_surface_id);
3830             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
3831             i965_vpp_clear_surface(ctx, i965->pp_context, out_surface_id, 0); 
3832             src_surface.id = in_surface_id;
3833             src_surface.type = I965_SURFACE_TYPE_SURFACE;
3834             src_surface.flags = (flags & I965_PP_FLAG_TOP_FIELD) ? 
3835                 I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST;
3836             dst_surface.id = out_surface_id;
3837             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3838             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3839
3840             i965_post_processing_internal(ctx, i965->pp_context,
3841                                           &src_surface,
3842                                           src_rect,
3843                                           &dst_surface,
3844                                           dst_rect,
3845                                           PP_NV12_DNDI,
3846                                           NULL);
3847         }
3848
3849         if (flags & I965_PP_FLAG_AVS) {
3850             struct i965_render_state *render_state = &i965->render_state;
3851             struct intel_region *dest_region = render_state->draw_region;
3852
3853             if (out_surface_id != VA_INVALID_ID)
3854                 in_surface_id = out_surface_id;
3855
3856             status = i965_CreateSurfaces(ctx,
3857                                          dest_region->width,
3858                                          dest_region->height,
3859                                          VA_RT_FORMAT_YUV420,
3860                                          1,
3861                                          &out_surface_id);
3862             assert(status == VA_STATUS_SUCCESS);
3863             obj_surface = SURFACE(out_surface_id);
3864             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
3865             i965_vpp_clear_surface(ctx, i965->pp_context, out_surface_id, 0); 
3866             src_surface.id = in_surface_id;
3867             src_surface.type = I965_SURFACE_TYPE_SURFACE;
3868             src_surface.flags = I965_SURFACE_FLAG_FRAME;
3869             dst_surface.id = out_surface_id;
3870             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3871             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3872
3873             i965_post_processing_internal(ctx, i965->pp_context,
3874                                           &src_surface,
3875                                           src_rect,
3876                                           &dst_surface,
3877                                           dst_rect,
3878                                           PP_NV12_AVS,
3879                                           NULL);
3880
3881             if (in_surface_id != surface)
3882                 i965_DestroySurfaces(ctx, &in_surface_id, 1);
3883                 
3884             *has_done_scaling = 1;
3885         }
3886
3887         _i965UnlockMutex(&i965->pp_mutex);
3888     }
3889
3890     return out_surface_id;
3891 }       
3892
3893 static VAStatus
3894 i965_image_pl3_processing(VADriverContextP ctx,
3895                           const struct i965_surface *src_surface,
3896                           const VARectangle *src_rect,
3897                           struct i965_surface *dst_surface,
3898                           const VARectangle *dst_rect)
3899 {
3900     struct i965_driver_data *i965 = i965_driver_data(ctx);
3901     struct i965_post_processing_context *pp_context = i965->pp_context;
3902     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
3903
3904     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
3905         i965_post_processing_internal(ctx, i965->pp_context,
3906                                       src_surface,
3907                                       src_rect,
3908                                       dst_surface,
3909                                       dst_rect,
3910                                       PP_PL3_LOAD_SAVE_N12,
3911                                       NULL);
3912     } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') || 
3913                fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
3914         i965_post_processing_internal(ctx, i965->pp_context,
3915                                       src_surface,
3916                                       src_rect,
3917                                       dst_surface,
3918                                       dst_rect,
3919                                       PP_PL3_LOAD_SAVE_PL3,
3920                                       NULL);
3921     } else if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
3922         i965_post_processing_internal(ctx, i965->pp_context,
3923                                       src_surface,
3924                                       src_rect,
3925                                       dst_surface,
3926                                       dst_rect,
3927                                       PP_PL3_LOAD_SAVE_PA,
3928                                       NULL);
3929
3930     }
3931     else {
3932         assert(0);
3933     }
3934
3935     intel_batchbuffer_flush(pp_context->batch);
3936
3937     return VA_STATUS_SUCCESS;
3938 }
3939
3940 static VAStatus
3941 i965_image_pl2_processing(VADriverContextP ctx,
3942                           const struct i965_surface *src_surface,
3943                           const VARectangle *src_rect,
3944                           struct i965_surface *dst_surface,
3945                           const VARectangle *dst_rect)
3946 {
3947     struct i965_driver_data *i965 = i965_driver_data(ctx);
3948     struct i965_post_processing_context *pp_context = i965->pp_context;
3949     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
3950
3951     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
3952         i965_post_processing_internal(ctx, i965->pp_context,
3953                                       src_surface,
3954                                       src_rect,
3955                                       dst_surface,
3956                                       dst_rect,
3957                                       PP_NV12_LOAD_SAVE_N12,
3958                                       NULL);
3959     } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') || 
3960                fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
3961         i965_post_processing_internal(ctx, i965->pp_context,
3962                                       src_surface,
3963                                       src_rect,
3964                                       dst_surface,
3965                                       dst_rect,
3966                                       PP_NV12_LOAD_SAVE_PL3,
3967                                       NULL);
3968     } else if (fourcc == VA_FOURCC('Y', 'U', 'Y', '2')) {
3969         i965_post_processing_internal(ctx, i965->pp_context,
3970                                       src_surface,
3971                                       src_rect,
3972                                       dst_surface,
3973                                       dst_rect,
3974                                       PP_NV12_LOAD_SAVE_PA,
3975                                       NULL);
3976     }
3977
3978     intel_batchbuffer_flush(pp_context->batch);
3979
3980     return VA_STATUS_SUCCESS;
3981 }
3982
3983 static VAStatus
3984 i965_image_pl1_processing(VADriverContextP ctx,
3985                           const struct i965_surface *src_surface,
3986                           const VARectangle *src_rect,
3987                           struct i965_surface *dst_surface,
3988                           const VARectangle *dst_rect)
3989 {
3990     struct i965_driver_data *i965 = i965_driver_data(ctx);
3991     struct i965_post_processing_context *pp_context = i965->pp_context;
3992     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
3993
3994     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
3995         i965_post_processing_internal(ctx, i965->pp_context,
3996                                       src_surface,
3997                                       src_rect,
3998                                       dst_surface,
3999                                       dst_rect,
4000                                       PP_PA_LOAD_SAVE_NV12,
4001                                       NULL);
4002     }
4003     else {
4004         return VA_STATUS_ERROR_UNKNOWN;
4005     }
4006
4007     intel_batchbuffer_flush(pp_context->batch);
4008
4009     return VA_STATUS_SUCCESS;
4010 }
4011
4012 VAStatus
4013 i965_image_processing(VADriverContextP ctx,
4014                       const struct i965_surface *src_surface,
4015                       const VARectangle *src_rect,
4016                       struct i965_surface *dst_surface,
4017                       const VARectangle *dst_rect)
4018 {
4019     struct i965_driver_data *i965 = i965_driver_data(ctx);
4020     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
4021
4022     if (HAS_PP(i965)) {
4023         int fourcc = pp_get_surface_fourcc(ctx, src_surface);
4024
4025         _i965LockMutex(&i965->pp_mutex);
4026
4027         switch (fourcc) {
4028         case VA_FOURCC('Y', 'V', '1', '2'):
4029         case VA_FOURCC('I', '4', '2', '0'):
4030         case VA_FOURCC('I', 'M', 'C', '1'):
4031         case VA_FOURCC('I', 'M', 'C', '3'):
4032             status = i965_image_pl3_processing(ctx,
4033                                                src_surface,
4034                                                src_rect,
4035                                                dst_surface,
4036                                                dst_rect);
4037             break;
4038
4039         case  VA_FOURCC('N', 'V', '1', '2'):
4040             status = i965_image_pl2_processing(ctx,
4041                                                src_surface,
4042                                                src_rect,
4043                                                dst_surface,
4044                                                dst_rect);
4045             break;
4046         case  VA_FOURCC('Y', 'U', 'Y', '2'):
4047             status = i965_image_pl1_processing(ctx,
4048                                                src_surface,
4049                                                src_rect,
4050                                                dst_surface,
4051                                                dst_rect);
4052             break;
4053
4054         default:
4055             status = VA_STATUS_ERROR_UNIMPLEMENTED;
4056             break;
4057         }
4058         
4059         _i965UnlockMutex(&i965->pp_mutex);
4060     }
4061
4062     return status;
4063 }       
4064
4065 static void
4066 i965_post_processing_context_finalize(struct i965_post_processing_context *pp_context)
4067 {
4068     int i;
4069
4070     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
4071     pp_context->surface_state_binding_table.bo = NULL;
4072
4073     dri_bo_unreference(pp_context->curbe.bo);
4074     pp_context->curbe.bo = NULL;
4075
4076     dri_bo_unreference(pp_context->sampler_state_table.bo);
4077     pp_context->sampler_state_table.bo = NULL;
4078
4079     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
4080     pp_context->sampler_state_table.bo_8x8 = NULL;
4081
4082     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
4083     pp_context->sampler_state_table.bo_8x8_uv = NULL;
4084
4085     dri_bo_unreference(pp_context->idrt.bo);
4086     pp_context->idrt.bo = NULL;
4087     pp_context->idrt.num_interface_descriptors = 0;
4088
4089     dri_bo_unreference(pp_context->vfe_state.bo);
4090     pp_context->vfe_state.bo = NULL;
4091
4092     dri_bo_unreference(pp_context->stmm.bo);
4093     pp_context->stmm.bo = NULL;
4094
4095     for (i = 0; i < NUM_PP_MODULES; i++) {
4096         struct pp_module *pp_module = &pp_context->pp_modules[i];
4097
4098         dri_bo_unreference(pp_module->kernel.bo);
4099         pp_module->kernel.bo = NULL;
4100     }
4101
4102     free(pp_context->pp_static_parameter);
4103     free(pp_context->pp_inline_parameter);
4104     pp_context->pp_static_parameter = NULL;
4105     pp_context->pp_inline_parameter = NULL;
4106 }
4107
4108 Bool
4109 i965_post_processing_terminate(VADriverContextP ctx)
4110 {
4111     struct i965_driver_data *i965 = i965_driver_data(ctx);
4112     struct i965_post_processing_context *pp_context = i965->pp_context;
4113
4114     if (pp_context) {
4115         i965_post_processing_context_finalize(pp_context);
4116         free(pp_context);
4117     }
4118
4119     i965->pp_context = NULL;
4120
4121     return True;
4122 }
4123
4124 static void
4125 i965_post_processing_context_init(VADriverContextP ctx,
4126                                   struct i965_post_processing_context *pp_context,
4127                                   struct intel_batchbuffer *batch)
4128 {
4129     struct i965_driver_data *i965 = i965_driver_data(ctx);
4130     int i;
4131
4132     pp_context->urb.size = URB_SIZE((&i965->intel));
4133     pp_context->urb.num_vfe_entries = 32;
4134     pp_context->urb.size_vfe_entry = 1;     /* in 512 bits unit */
4135     pp_context->urb.num_cs_entries = 1;
4136     
4137     if (IS_GEN7(i965->intel.device_id))
4138         pp_context->urb.size_cs_entry = 4;      /* in 512 bits unit */
4139     else
4140         pp_context->urb.size_cs_entry = 2;
4141
4142     pp_context->urb.vfe_start = 0;
4143     pp_context->urb.cs_start = pp_context->urb.vfe_start + 
4144         pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
4145     assert(pp_context->urb.cs_start + 
4146            pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
4147
4148     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
4149     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
4150     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen7));
4151
4152     if (IS_GEN7(i965->intel.device_id))
4153         memcpy(pp_context->pp_modules, pp_modules_gen7, sizeof(pp_context->pp_modules));
4154     else if (IS_GEN6(i965->intel.device_id))
4155         memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
4156     else if (IS_IRONLAKE(i965->intel.device_id))
4157         memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
4158
4159     for (i = 0; i < NUM_PP_MODULES; i++) {
4160         struct pp_module *pp_module = &pp_context->pp_modules[i];
4161         dri_bo_unreference(pp_module->kernel.bo);
4162         if (pp_module->kernel.bin && pp_module->kernel.size) {
4163             pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
4164                                                 pp_module->kernel.name,
4165                                                 pp_module->kernel.size,
4166                                                 4096);
4167             assert(pp_module->kernel.bo);
4168             dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
4169         } else {
4170             pp_module->kernel.bo = NULL;
4171         }
4172     }
4173
4174     /* static & inline parameters */
4175     if (IS_GEN7(i965->intel.device_id)) {
4176         pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
4177         pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
4178     } else {
4179         pp_context->pp_static_parameter = calloc(sizeof(struct pp_static_parameter), 1);
4180         pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
4181     }
4182
4183     pp_context->batch = batch;
4184 }
4185
4186 Bool
4187 i965_post_processing_init(VADriverContextP ctx)
4188 {
4189     struct i965_driver_data *i965 = i965_driver_data(ctx);
4190     struct i965_post_processing_context *pp_context = i965->pp_context;
4191
4192     if (HAS_PP(i965)) {
4193         if (pp_context == NULL) {
4194             pp_context = calloc(1, sizeof(*pp_context));
4195             i965_post_processing_context_init(ctx, pp_context, i965->batch);
4196             i965->pp_context = pp_context;
4197         }
4198     }
4199
4200     return True;
4201 }
4202
4203 static const int procfilter_to_pp_flag[VAProcFilterCount] = {
4204     PP_NULL,    /* VAProcFilterNone */
4205     PP_NV12_DN, /* VAProcFilterNoiseReduction */
4206     PP_NV12_DNDI, /* VAProcFilterDeinterlacing */
4207     PP_NULL,    /* VAProcFilterSharpening */
4208     PP_NULL,    /* VAProcFilterColorBalance */
4209     PP_NULL,    /* VAProcFilterColorStandard */
4210 };
4211
4212 static const int proc_frame_to_pp_frame[3] = {
4213     I965_SURFACE_FLAG_FRAME,
4214     I965_SURFACE_FLAG_TOP_FIELD_FIRST,
4215     I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST
4216 };
4217
4218 static void 
4219 i965_proc_picture(VADriverContextP ctx, 
4220                   VAProfile profile, 
4221                   union codec_state *codec_state,
4222                   struct hw_context *hw_context)
4223 {
4224     struct i965_driver_data *i965 = i965_driver_data(ctx);
4225     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
4226     struct proc_state *proc_state = &codec_state->proc;
4227     VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
4228     struct object_surface *obj_surface;
4229     struct i965_surface src_surface, dst_surface;
4230     VARectangle src_rect, dst_rect;
4231     VAStatus status;
4232     int i;
4233     VASurfaceID tmp_surfaces[VAProcFilterCount + 4];
4234     int num_tmp_surfaces = 0;
4235     unsigned int tiling = 0, swizzle = 0;
4236     int in_width, in_height;
4237
4238     assert(pipeline_param->surface != VA_INVALID_ID);
4239     assert(proc_state->current_render_target != VA_INVALID_ID);
4240
4241     obj_surface = SURFACE(pipeline_param->surface);
4242     in_width = obj_surface->orig_width;
4243     in_height = obj_surface->orig_height;
4244     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4245
4246     src_surface.id = pipeline_param->surface;
4247     src_surface.type = I965_SURFACE_TYPE_SURFACE;
4248     src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
4249
4250     if (obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2')) {
4251         VASurfaceID out_surface_id = VA_INVALID_ID;
4252
4253         src_surface.id = pipeline_param->surface;
4254         src_surface.type = I965_SURFACE_TYPE_SURFACE;
4255         src_surface.flags = I965_SURFACE_FLAG_FRAME;
4256         src_rect.x = 0;
4257         src_rect.y = 0;
4258         src_rect.width = in_width;
4259         src_rect.height = in_height;
4260
4261         status = i965_CreateSurfaces(ctx,
4262                                      in_width,
4263                                      in_height,
4264                                      VA_RT_FORMAT_YUV420,
4265                                      1,
4266                                      &out_surface_id);
4267         assert(status == VA_STATUS_SUCCESS);
4268         tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
4269         obj_surface = SURFACE(out_surface_id);
4270         i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
4271
4272         dst_surface.id = out_surface_id;
4273         dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4274         dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4275         dst_rect.x = 0;
4276         dst_rect.y = 0;
4277         dst_rect.width = in_width;
4278         dst_rect.height = in_height;
4279
4280         status = i965_image_processing(ctx,
4281                                        &src_surface,
4282                                        &src_rect,
4283                                        &dst_surface,
4284                                        &dst_rect);
4285         assert(status == VA_STATUS_SUCCESS);
4286
4287         src_surface.id = out_surface_id;
4288         src_surface.type = I965_SURFACE_TYPE_SURFACE;
4289         src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
4290     }
4291
4292     if (pipeline_param->surface_region) {
4293         src_rect.x = pipeline_param->surface_region->x;
4294         src_rect.y = pipeline_param->surface_region->y;
4295         src_rect.width = pipeline_param->surface_region->width;
4296         src_rect.height = pipeline_param->surface_region->height;
4297     } else {
4298         src_rect.x = 0;
4299         src_rect.y = 0;
4300         src_rect.width = in_width;
4301         src_rect.height = in_height;
4302     }
4303
4304     if (pipeline_param->output_region) {
4305         dst_rect.x = pipeline_param->output_region->x;
4306         dst_rect.y = pipeline_param->output_region->y;
4307         dst_rect.width = pipeline_param->output_region->width;
4308         dst_rect.height = pipeline_param->output_region->height;
4309     } else {
4310         dst_rect.x = 0;
4311         dst_rect.y = 0;
4312         dst_rect.width = in_width;
4313         dst_rect.height = in_height;
4314     }
4315
4316     obj_surface = SURFACE(proc_state->current_render_target);
4317     i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
4318     i965_vpp_clear_surface(ctx, &proc_context->pp_context, proc_state->current_render_target, pipeline_param->output_background_color); 
4319     
4320     for (i = 0; i < pipeline_param->num_filters; i++) {
4321         struct object_buffer *obj_buffer = BUFFER(pipeline_param->filters[i]);
4322         VAProcFilterParameterBufferBase *filter_param = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
4323         VAProcFilterType filter_type = filter_param->type;
4324         VASurfaceID out_surface_id = VA_INVALID_ID;
4325         int kernel_index = procfilter_to_pp_flag[filter_type];
4326
4327         if (kernel_index != PP_NULL &&
4328             proc_context->pp_context.pp_modules[kernel_index].kernel.bo != NULL) {
4329             status = i965_CreateSurfaces(ctx,
4330                                          in_width,
4331                                          in_height,
4332                                          VA_RT_FORMAT_YUV420,
4333                                          1,
4334                                          &out_surface_id);
4335             assert(status == VA_STATUS_SUCCESS);
4336             tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
4337             obj_surface = SURFACE(out_surface_id);
4338             i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
4339             dst_surface.id = out_surface_id;
4340             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4341             status = i965_post_processing_internal(ctx, &proc_context->pp_context,
4342                                                    &src_surface,
4343                                                    &src_rect,
4344                                                    &dst_surface,
4345                                                    &src_rect,
4346                                                    kernel_index,
4347                                                    filter_param);
4348
4349             if (status == VA_STATUS_SUCCESS) {
4350                 src_surface.id = dst_surface.id;
4351                 src_surface.type = dst_surface.type;
4352                 src_surface.flags = dst_surface.flags;
4353             }
4354         }
4355     }
4356
4357     dst_surface.id = proc_state->current_render_target;
4358     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4359
4360     if (src_rect.width == dst_rect.width &&
4361         src_rect.height == dst_rect.height) {
4362         i965_post_processing_internal(ctx, &proc_context->pp_context,
4363                                       &src_surface,
4364                                       &src_rect,
4365                                       &dst_surface,
4366                                       &dst_rect,
4367                                       PP_NV12_LOAD_SAVE_N12,
4368                                       NULL);
4369     } else {
4370
4371         i965_post_processing_internal(ctx, &proc_context->pp_context,
4372                                       &src_surface,
4373                                       &src_rect,
4374                                       &dst_surface,
4375                                       &dst_rect,
4376                                       (pipeline_param->filter_flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC ?
4377                                       PP_NV12_AVS : PP_NV12_SCALING,
4378                                       NULL);
4379     }
4380
4381     if (num_tmp_surfaces)
4382         i965_DestroySurfaces(ctx,
4383                              tmp_surfaces,
4384                              num_tmp_surfaces);
4385
4386     intel_batchbuffer_flush(hw_context->batch);
4387 }
4388
4389 static void
4390 i965_proc_context_destroy(void *hw_context)
4391 {
4392     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
4393
4394     i965_post_processing_context_finalize(&proc_context->pp_context);
4395     intel_batchbuffer_free(proc_context->base.batch);
4396     free(proc_context);
4397 }
4398
4399 struct hw_context *
4400 i965_proc_context_init(VADriverContextP ctx, struct object_config *obj_config)
4401 {
4402     struct intel_driver_data *intel = intel_driver_data(ctx);
4403     struct i965_proc_context *proc_context = calloc(1, sizeof(struct i965_proc_context));
4404
4405     proc_context->base.destroy = i965_proc_context_destroy;
4406     proc_context->base.run = i965_proc_picture;
4407     proc_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER);
4408     i965_post_processing_context_init(ctx, &proc_context->pp_context, proc_context->base.batch);
4409
4410     return (struct hw_context *)proc_context;
4411 }