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