Update DNDI kernel and DNDI states on Sandybridge
[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     int i;
1467
1468     /* surface */
1469     obj_surface = SURFACE(src_surface->id);
1470     in_w = obj_surface->orig_width;
1471     in_h = obj_surface->orig_height;
1472     in_wpitch = obj_surface->width;
1473     in_hpitch = obj_surface->height;
1474
1475     /* source Y surface index 1 */
1476     i965_pp_set_surface2_state(ctx, pp_context,
1477                                obj_surface->bo, 0,
1478                                in_w, in_h, in_wpitch,
1479                                0, 0,
1480                                SURFACE_FORMAT_Y8_UNORM, 0,
1481                                1);
1482
1483     /* source UV surface index 2 */
1484     i965_pp_set_surface2_state(ctx, pp_context,
1485                                obj_surface->bo, in_wpitch * in_hpitch,
1486                                in_w / 2, in_h / 2, in_wpitch,
1487                                0, 0,
1488                                SURFACE_FORMAT_R8B8_UNORM, 0,
1489                                2);
1490
1491     /* destination surface */
1492     obj_surface = SURFACE(dst_surface->id);
1493     out_w = obj_surface->orig_width;
1494     out_h = obj_surface->orig_height;
1495     out_wpitch = obj_surface->width;
1496     out_hpitch = obj_surface->height;
1497     assert(out_w <= out_wpitch && out_h <= out_hpitch);
1498
1499     /* destination Y surface index 7 */
1500     i965_pp_set_surface_state(ctx, pp_context,
1501                               obj_surface->bo, 0,
1502                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1503                               7, 1);
1504
1505     /* destination UV surface index 8 */
1506     i965_pp_set_surface_state(ctx, pp_context,
1507                               obj_surface->bo, out_wpitch * out_hpitch,
1508                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1509                               8, 1);
1510
1511     /* sampler 8x8 state */
1512     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
1513     assert(pp_context->sampler_state_table.bo_8x8->virtual);
1514     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
1515     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
1516     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
1517
1518     for (i = 0; i < 17; i++) {
1519         /* for Y channel, currently ignore */
1520         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x00;
1521         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x00;
1522         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x08;
1523         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x18;
1524         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x18;
1525         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x08;
1526         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x00;
1527         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x00;
1528         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x00;
1529         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x00;
1530         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x10;
1531         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x10;
1532         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x10;
1533         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x10;
1534         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x00;
1535         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x00;
1536         /* for U/V channel, 0.25 */
1537         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
1538         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
1539         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
1540         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
1541         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
1542         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
1543         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
1544         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
1545         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
1546         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
1547         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
1548         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
1549         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
1550         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
1551         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
1552         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
1553     }
1554
1555     sampler_8x8_state->dw136.default_sharpness_level = 0;
1556     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
1557     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
1558     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
1559     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
1560
1561     /* sampler 8x8 */
1562     dri_bo_map(pp_context->sampler_state_table.bo, True);
1563     assert(pp_context->sampler_state_table.bo->virtual);
1564     assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
1565     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
1566
1567     /* sample_8x8 Y index 1 */
1568     index = 1;
1569     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1570     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
1571     sampler_8x8[index].dw0.ief_bypass = 1;
1572     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1573     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1574     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1575     sampler_8x8[index].dw2.global_noise_estimation = 22;
1576     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1577     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1578     sampler_8x8[index].dw3.strong_edge_weight = 7;
1579     sampler_8x8[index].dw3.regular_weight = 2;
1580     sampler_8x8[index].dw3.non_edge_weight = 0;
1581     sampler_8x8[index].dw3.gain_factor = 40;
1582     sampler_8x8[index].dw4.steepness_boost = 0;
1583     sampler_8x8[index].dw4.steepness_threshold = 0;
1584     sampler_8x8[index].dw4.mr_boost = 0;
1585     sampler_8x8[index].dw4.mr_threshold = 5;
1586     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1587     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1588     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1589     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1590     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1591     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1592     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1593     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1594     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1595     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1596     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1597     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1598     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1599     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1600     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1601     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1602     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1603     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1604     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1605     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1606     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1607     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1608     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1609     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1610     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1611     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1612     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1613     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1614     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1615     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1616     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1617     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1618     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1619     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1620     sampler_8x8[index].dw13.limiter_boost = 0;
1621     sampler_8x8[index].dw13.minimum_limiter = 10;
1622     sampler_8x8[index].dw13.maximum_limiter = 11;
1623     sampler_8x8[index].dw14.clip_limiter = 130;
1624     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1625                       I915_GEM_DOMAIN_RENDER, 
1626                       0,
1627                       0,
1628                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1629                       pp_context->sampler_state_table.bo_8x8);
1630
1631     /* sample_8x8 UV index 2 */
1632     index = 2;
1633     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1634     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
1635     sampler_8x8[index].dw0.ief_bypass = 1;
1636     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1637     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1638     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1639     sampler_8x8[index].dw2.global_noise_estimation = 22;
1640     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1641     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1642     sampler_8x8[index].dw3.strong_edge_weight = 7;
1643     sampler_8x8[index].dw3.regular_weight = 2;
1644     sampler_8x8[index].dw3.non_edge_weight = 0;
1645     sampler_8x8[index].dw3.gain_factor = 40;
1646     sampler_8x8[index].dw4.steepness_boost = 0;
1647     sampler_8x8[index].dw4.steepness_threshold = 0;
1648     sampler_8x8[index].dw4.mr_boost = 0;
1649     sampler_8x8[index].dw4.mr_threshold = 5;
1650     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1651     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1652     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1653     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1654     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1655     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1656     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1657     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1658     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1659     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1660     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1661     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1662     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1663     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1664     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1665     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1666     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1667     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1668     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1669     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1670     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1671     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1672     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1673     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1674     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1675     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1676     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1677     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1678     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1679     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1680     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1681     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1682     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1683     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1684     sampler_8x8[index].dw13.limiter_boost = 0;
1685     sampler_8x8[index].dw13.minimum_limiter = 10;
1686     sampler_8x8[index].dw13.maximum_limiter = 11;
1687     sampler_8x8[index].dw14.clip_limiter = 130;
1688     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1689                       I915_GEM_DOMAIN_RENDER, 
1690                       0,
1691                       0,
1692                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1693                       pp_context->sampler_state_table.bo_8x8);
1694
1695     dri_bo_unmap(pp_context->sampler_state_table.bo);
1696
1697     /* private function & data */
1698     pp_context->pp_x_steps = pp_avs_x_steps;
1699     pp_context->pp_y_steps = pp_avs_y_steps;
1700     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
1701
1702     pp_avs_context->dest_x = dst_rect->x;
1703     pp_avs_context->dest_y = dst_rect->y;
1704     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
1705     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
1706     pp_avs_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
1707     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
1708     pp_avs_context->src_w = src_rect->width;
1709     pp_avs_context->src_h = src_rect->height;
1710
1711     pp_static_parameter->grf4.r4_2.avs.nlas = 1;
1712     pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h;
1713
1714     pp_inline_parameter->grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w;
1715     pp_inline_parameter->grf5.block_count_x = 1;        /* M x 1 */
1716     pp_inline_parameter->grf5.number_blocks = pp_avs_context->dest_h / 8;
1717     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
1718     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
1719     pp_inline_parameter->grf6.video_step_delta = 0.0;
1720
1721     dst_surface->flags = src_surface->flags;
1722
1723     return VA_STATUS_SUCCESS;
1724 }
1725
1726 static int
1727 gen7_pp_avs_x_steps(void *private_context)
1728 {
1729     struct pp_avs_context *pp_avs_context = private_context;
1730
1731     return pp_avs_context->dest_w / 16;
1732 }
1733
1734 static int
1735 gen7_pp_avs_y_steps(void *private_context)
1736 {
1737     struct pp_avs_context *pp_avs_context = private_context;
1738
1739     return pp_avs_context->dest_h / 16;
1740 }
1741
1742 static int
1743 gen7_pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1744 {
1745     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1746     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1747
1748     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
1749     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 16 + pp_avs_context->dest_y;
1750     pp_inline_parameter->grf7.constant_0 = 0xffffffff;
1751     pp_inline_parameter->grf7.sampler_load_main_video_x_scaling_step = 1.0 / pp_avs_context->src_w;
1752
1753     return 0;
1754 }
1755
1756 VAStatus
1757 gen7_pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1758                             const struct i965_surface *src_surface,
1759                             const VARectangle *src_rect,
1760                             struct i965_surface *dst_surface,
1761                             const VARectangle *dst_rect,
1762                             void *filter_param)
1763 {
1764     struct i965_driver_data *i965 = i965_driver_data(ctx);
1765     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1766     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1767     struct object_surface *obj_surface;
1768     struct gen7_sampler_8x8 *sampler_8x8;
1769     struct i965_sampler_8x8_state *sampler_8x8_state;
1770     int index, i;
1771     int in_w, in_h, in_wpitch, in_hpitch;
1772     int out_w, out_h, out_wpitch, out_hpitch;
1773
1774     /* surface */
1775     obj_surface = SURFACE(src_surface->id);
1776     in_w = obj_surface->orig_width;
1777     in_h = obj_surface->orig_height;
1778     in_wpitch = obj_surface->width;
1779     in_hpitch = obj_surface->height;
1780
1781     /* source Y surface index 0 */
1782     gen7_pp_set_surface2_state(ctx, pp_context,
1783                                obj_surface->bo, 0,
1784                                in_w, in_h, in_wpitch,
1785                                0, 0,
1786                                SURFACE_FORMAT_Y8_UNORM, 0,
1787                                0);
1788
1789     /* source UV surface index 1 */
1790     gen7_pp_set_surface2_state(ctx, pp_context,
1791                                obj_surface->bo, in_wpitch * in_hpitch,
1792                                in_w / 2, in_h / 2, in_wpitch,
1793                                0, 0,
1794                                SURFACE_FORMAT_R8B8_UNORM, 0,
1795                                1);
1796
1797     /* destination surface */
1798     obj_surface = SURFACE(dst_surface->id);
1799     out_w = obj_surface->orig_width;
1800     out_h = obj_surface->orig_height;
1801     out_wpitch = obj_surface->width;
1802     out_hpitch = obj_surface->height;
1803     assert(out_w <= out_wpitch && out_h <= out_hpitch);
1804
1805     /* destination Y surface index 24 */
1806     gen7_pp_set_surface_state(ctx, pp_context,
1807                               obj_surface->bo, 0,
1808                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_SINT,
1809                               24, 1);
1810
1811     /* destination UV surface index 25 */
1812     gen7_pp_set_surface_state(ctx, pp_context,
1813                               obj_surface->bo, out_wpitch * out_hpitch,
1814                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_SINT,
1815                               25, 1);
1816
1817     /* sampler 8x8 state */
1818     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
1819     assert(pp_context->sampler_state_table.bo_8x8->virtual);
1820     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
1821     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
1822     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
1823
1824     for (i = 0; i < 17; i++) {
1825         /* for Y channel, currently ignore */
1826         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 = 0x0;
1827         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 = 0x0;
1828         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 = 0x0;
1829         sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 = 0x0;
1830         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 = 0x0;
1831         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 = 0x0;
1832         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 = 0x0;
1833         sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 = 0x0;
1834         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 = 0x0;
1835         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 = 0x0;
1836         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 = 0x0;
1837         sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 = 0x0;
1838         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 = 0x0;
1839         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 = 0x0;
1840         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 = 0x0;
1841         sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 = 0x0;
1842         /* for U/V channel, 0.25 */
1843         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c0 = 0x0;
1844         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c1 = 0x0;
1845         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 = 0x10;
1846         sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 = 0x10;
1847         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 = 0x10;
1848         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 = 0x10;
1849         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c6 = 0x0;
1850         sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c7 = 0x0;
1851         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c0 = 0x0;
1852         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c1 = 0x0;
1853         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 = 0x10;
1854         sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 = 0x10;
1855         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 = 0x10;
1856         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 = 0x10;
1857         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c6 = 0x0;
1858         sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c7 = 0x0;
1859     }
1860
1861     sampler_8x8_state->dw136.default_sharpness_level = 0;
1862     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
1863     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
1864     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
1865     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
1866
1867     /* sampler 8x8 */
1868     dri_bo_map(pp_context->sampler_state_table.bo, True);
1869     assert(pp_context->sampler_state_table.bo->virtual);
1870     assert(sizeof(*sampler_8x8) == sizeof(int) * 4);
1871     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
1872
1873     /* sample_8x8 Y index 4 */
1874     index = 4;
1875     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1876     sampler_8x8[index].dw0.global_noise_estimation = 255;
1877     sampler_8x8[index].dw0.ief_bypass = 1;
1878
1879     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1880
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
1887     sampler_8x8[index].dw3.r3x_coefficient = 27;
1888     sampler_8x8[index].dw3.r3c_coefficient = 5;
1889     sampler_8x8[index].dw3.gain_factor = 40;
1890     sampler_8x8[index].dw3.non_edge_weight = 1;
1891     sampler_8x8[index].dw3.regular_weight = 2;
1892     sampler_8x8[index].dw3.strong_edge_weight = 7;
1893     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
1894
1895     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1896                       I915_GEM_DOMAIN_RENDER, 
1897                       0,
1898                       0,
1899                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1900                       pp_context->sampler_state_table.bo_8x8);
1901
1902     /* sample_8x8 UV index 8 */
1903     index = 8;
1904     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1905     sampler_8x8[index].dw0.disable_8x8_filter = 0;
1906     sampler_8x8[index].dw0.global_noise_estimation = 255;
1907     sampler_8x8[index].dw0.ief_bypass = 1;
1908     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1909     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1910     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1911     sampler_8x8[index].dw2.r5x_coefficient = 9;
1912     sampler_8x8[index].dw2.r5cx_coefficient = 8;
1913     sampler_8x8[index].dw2.r5c_coefficient = 3;
1914     sampler_8x8[index].dw3.r3x_coefficient = 27;
1915     sampler_8x8[index].dw3.r3c_coefficient = 5;
1916     sampler_8x8[index].dw3.gain_factor = 40;
1917     sampler_8x8[index].dw3.non_edge_weight = 1;
1918     sampler_8x8[index].dw3.regular_weight = 2;
1919     sampler_8x8[index].dw3.strong_edge_weight = 7;
1920     sampler_8x8[index].dw3.ief4_smooth_enable = 0;
1921
1922     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1923                       I915_GEM_DOMAIN_RENDER, 
1924                       0,
1925                       0,
1926                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1927                       pp_context->sampler_state_table.bo_8x8);
1928
1929     dri_bo_unmap(pp_context->sampler_state_table.bo);
1930
1931     /* private function & data */
1932     pp_context->pp_x_steps = gen7_pp_avs_x_steps;
1933     pp_context->pp_y_steps = gen7_pp_avs_y_steps;
1934     pp_context->pp_set_block_parameter = gen7_pp_avs_set_block_parameter;
1935
1936     pp_avs_context->dest_x = dst_rect->x;
1937     pp_avs_context->dest_y = dst_rect->y;
1938     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
1939     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
1940     pp_avs_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
1941     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
1942     pp_avs_context->src_w = src_rect->width;
1943     pp_avs_context->src_h = src_rect->height;
1944
1945     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
1946     pp_static_parameter->grf3.sampler_load_horizontal_scaling_step_ratio = (float) pp_avs_context->src_w / pp_avs_context->dest_w;
1947     pp_static_parameter->grf4.sampler_load_vertical_scaling_step = (float) 1.0 / out_h;
1948     pp_static_parameter->grf5.sampler_load_vertical_frame_origin = 0.0; /* FIXME */
1949     pp_static_parameter->grf6.sampler_load_horizontal_frame_origin = 0.0;
1950
1951     dst_surface->flags = src_surface->flags;
1952
1953     return VA_STATUS_SUCCESS;
1954 }
1955
1956 static int
1957 pp_dndi_x_steps(void *private_context)
1958 {
1959     return 1;
1960 }
1961
1962 static int
1963 pp_dndi_y_steps(void *private_context)
1964 {
1965     struct pp_dndi_context *pp_dndi_context = private_context;
1966
1967     return pp_dndi_context->dest_h / 4;
1968 }
1969
1970 static int
1971 pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1972 {
1973     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1974
1975     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
1976     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
1977
1978     return 0;
1979 }
1980
1981 static VAStatus
1982 pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1983                         const struct i965_surface *src_surface,
1984                         const VARectangle *src_rect,
1985                         struct i965_surface *dst_surface,
1986                         const VARectangle *dst_rect,
1987                         void *filter_param)
1988 {
1989     struct i965_driver_data *i965 = i965_driver_data(ctx);
1990     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
1991     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1992     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1993     struct object_surface *obj_surface;
1994     struct i965_sampler_dndi *sampler_dndi;
1995     int index;
1996     int w, h;
1997     int orig_w, orig_h;
1998     int dndi_top_first = 1;
1999
2000     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
2001         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
2002
2003     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
2004         dndi_top_first = 1;
2005     else
2006         dndi_top_first = 0;
2007
2008     /* surface */
2009     obj_surface = SURFACE(src_surface->id);
2010     orig_w = obj_surface->orig_width;
2011     orig_h = obj_surface->orig_height;
2012     w = obj_surface->width;
2013     h = obj_surface->height;
2014
2015     if (pp_context->stmm.bo == NULL) {
2016         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2017                                            "STMM surface",
2018                                            w * h,
2019                                            4096);
2020         assert(pp_context->stmm.bo);
2021     }
2022
2023     /* source UV surface index 2 */
2024     i965_pp_set_surface_state(ctx, pp_context,
2025                               obj_surface->bo, w * h,
2026                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2027                               2, 0);
2028
2029     /* source YUV surface index 4 */
2030     i965_pp_set_surface2_state(ctx, pp_context,
2031                                obj_surface->bo, 0,
2032                                orig_w, orig_w, w,
2033                                0, h,
2034                                SURFACE_FORMAT_PLANAR_420_8, 1,
2035                                4);
2036
2037     /* source STMM surface index 20 */
2038     i965_pp_set_surface_state(ctx, pp_context,
2039                               pp_context->stmm.bo, 0,
2040                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2041                               20, 1);
2042
2043     /* destination surface */
2044     obj_surface = SURFACE(dst_surface->id);
2045     orig_w = obj_surface->orig_width;
2046     orig_h = obj_surface->orig_height;
2047     w = obj_surface->width;
2048     h = obj_surface->height;
2049
2050     /* destination Y surface index 7 */
2051     i965_pp_set_surface_state(ctx, pp_context,
2052                               obj_surface->bo, 0,
2053                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2054                               7, 1);
2055
2056     /* destination UV surface index 8 */
2057     i965_pp_set_surface_state(ctx, pp_context,
2058                               obj_surface->bo, w * h,
2059                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2060                               8, 1);
2061     /* sampler dndi */
2062     dri_bo_map(pp_context->sampler_state_table.bo, True);
2063     assert(pp_context->sampler_state_table.bo->virtual);
2064     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2065     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2066
2067     /* sample dndi index 1 */
2068     index = 0;
2069     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2070     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
2071     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2072     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2073
2074     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2075     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 4;
2076     sampler_dndi[index].dw1.stmm_c2 = 1;
2077     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2078     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2079
2080     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
2081     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
2082     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
2083     sampler_dndi[index].dw2.good_neighbor_threshold = 4;                // 0-63
2084
2085     sampler_dndi[index].dw3.maximum_stmm = 128;
2086     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2087     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2088     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2089     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2090
2091     sampler_dndi[index].dw4.sdi_delta = 8;
2092     sampler_dndi[index].dw4.sdi_threshold = 128;
2093     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2094     sampler_dndi[index].dw4.stmm_shift_up = 0;
2095     sampler_dndi[index].dw4.stmm_shift_down = 0;
2096     sampler_dndi[index].dw4.minimum_stmm = 0;
2097
2098     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 8;
2099     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 32;
2100     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 64;
2101     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 32;
2102
2103     sampler_dndi[index].dw6.dn_enable = 1;
2104     sampler_dndi[index].dw6.di_enable = 1;
2105     sampler_dndi[index].dw6.di_partial = 0;
2106     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2107     sampler_dndi[index].dw6.dndi_stream_id = 0;
2108     sampler_dndi[index].dw6.dndi_first_frame = 1;
2109     sampler_dndi[index].dw6.progressive_dn = 0;
2110     sampler_dndi[index].dw6.fmd_tear_threshold = 63;
2111     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2112     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2113
2114     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
2115     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
2116     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2117     sampler_dndi[index].dw7.column_width_minus1 = 0;
2118
2119     dri_bo_unmap(pp_context->sampler_state_table.bo);
2120
2121     /* private function & data */
2122     pp_context->pp_x_steps = pp_dndi_x_steps;
2123     pp_context->pp_y_steps = pp_dndi_y_steps;
2124     pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
2125
2126     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
2127     pp_static_parameter->grf1.r1_6.di.top_field_first = dndi_top_first;
2128     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 0;
2129     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 0;
2130
2131     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
2132     pp_inline_parameter->grf5.number_blocks = w / 16;
2133     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
2134     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
2135
2136     pp_dndi_context->dest_w = w;
2137     pp_dndi_context->dest_h = h;
2138
2139     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
2140
2141     return VA_STATUS_SUCCESS;
2142 }
2143
2144 static int
2145 pp_dn_x_steps(void *private_context)
2146 {
2147     return 1;
2148 }
2149
2150 static int
2151 pp_dn_y_steps(void *private_context)
2152 {
2153     struct pp_dn_context *pp_dn_context = private_context;
2154
2155     return pp_dn_context->dest_h / 8;
2156 }
2157
2158 static int
2159 pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2160 {
2161     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2162
2163     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2164     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
2165
2166     return 0;
2167 }
2168
2169 static VAStatus
2170 pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2171                       const struct i965_surface *src_surface,
2172                       const VARectangle *src_rect,
2173                       struct i965_surface *dst_surface,
2174                       const VARectangle *dst_rect,
2175                       void *filter_param)
2176 {
2177     struct i965_driver_data *i965 = i965_driver_data(ctx);
2178     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
2179     struct object_surface *obj_surface;
2180     struct i965_sampler_dndi *sampler_dndi;
2181     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2182     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2183     VAProcFilterBaseParameterBuffer *dn_filter_param = filter_param;
2184     int index;
2185     int w, h;
2186     int orig_w, orig_h;
2187     int dn_strength = 15;
2188     int dndi_top_first = 1;
2189     int dn_progressive = 0;
2190
2191     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
2192         dndi_top_first = 1;
2193         dn_progressive = 1;
2194     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
2195         dndi_top_first = 1;
2196         dn_progressive = 0;
2197     } else {
2198         dndi_top_first = 0;
2199         dn_progressive = 0;
2200     }
2201
2202     if (dn_filter_param) {
2203         int value = dn_filter_param->value;
2204         
2205         if (value > 1.0)
2206             value = 1.0;
2207         
2208         if (value < 0.0)
2209             value = 0.0;
2210
2211         dn_strength = (int)(value * 31.0F);
2212     }
2213
2214     /* surface */
2215     obj_surface = SURFACE(src_surface->id);
2216     orig_w = obj_surface->orig_width;
2217     orig_h = obj_surface->orig_height;
2218     w = obj_surface->width;
2219     h = obj_surface->height;
2220
2221     if (pp_context->stmm.bo == NULL) {
2222         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2223                                            "STMM surface",
2224                                            w * h,
2225                                            4096);
2226         assert(pp_context->stmm.bo);
2227     }
2228
2229     /* source UV surface index 2 */
2230     i965_pp_set_surface_state(ctx, pp_context,
2231                               obj_surface->bo, w * h,
2232                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2233                               2, 0);
2234
2235     /* source YUV surface index 4 */
2236     i965_pp_set_surface2_state(ctx, pp_context,
2237                                obj_surface->bo, 0,
2238                                orig_w, orig_w, w,
2239                                0, h,
2240                                SURFACE_FORMAT_PLANAR_420_8, 1,
2241                                4);
2242
2243     /* source STMM surface index 20 */
2244     i965_pp_set_surface_state(ctx, pp_context,
2245                               pp_context->stmm.bo, 0,
2246                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2247                               20, 1);
2248
2249     /* destination surface */
2250     obj_surface = SURFACE(dst_surface->id);
2251     orig_w = obj_surface->orig_width;
2252     orig_h = obj_surface->orig_height;
2253     w = obj_surface->width;
2254     h = obj_surface->height;
2255
2256     /* destination Y surface index 7 */
2257     i965_pp_set_surface_state(ctx, pp_context,
2258                               obj_surface->bo, 0,
2259                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2260                               7, 1);
2261
2262     /* destination UV surface index 8 */
2263     i965_pp_set_surface_state(ctx, pp_context,
2264                               obj_surface->bo, w * h,
2265                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2266                               8, 1);
2267     /* sampler dn */
2268     dri_bo_map(pp_context->sampler_state_table.bo, True);
2269     assert(pp_context->sampler_state_table.bo->virtual);
2270     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2271     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2272
2273     /* sample dndi index 1 */
2274     index = 0;
2275     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2276     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
2277     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2278     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2279
2280     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2281     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
2282     sampler_dndi[index].dw1.stmm_c2 = 0;
2283     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2284     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2285
2286     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
2287     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
2288     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
2289     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
2290
2291     sampler_dndi[index].dw3.maximum_stmm = 128;
2292     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2293     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2294     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2295     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2296
2297     sampler_dndi[index].dw4.sdi_delta = 8;
2298     sampler_dndi[index].dw4.sdi_threshold = 128;
2299     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2300     sampler_dndi[index].dw4.stmm_shift_up = 0;
2301     sampler_dndi[index].dw4.stmm_shift_down = 0;
2302     sampler_dndi[index].dw4.minimum_stmm = 0;
2303
2304     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
2305     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
2306     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
2307     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
2308
2309     sampler_dndi[index].dw6.dn_enable = 1;
2310     sampler_dndi[index].dw6.di_enable = 0;
2311     sampler_dndi[index].dw6.di_partial = 0;
2312     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2313     sampler_dndi[index].dw6.dndi_stream_id = 1;
2314     sampler_dndi[index].dw6.dndi_first_frame = 1;
2315     sampler_dndi[index].dw6.progressive_dn = dn_progressive;
2316     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
2317     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2318     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2319
2320     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
2321     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
2322     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2323     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
2324
2325     dri_bo_unmap(pp_context->sampler_state_table.bo);
2326
2327     /* private function & data */
2328     pp_context->pp_x_steps = pp_dn_x_steps;
2329     pp_context->pp_y_steps = pp_dn_y_steps;
2330     pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
2331
2332     pp_static_parameter->grf1.statistics_surface_picth = w / 2;
2333     pp_static_parameter->grf1.r1_6.di.top_field_first = 0;
2334     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 64;
2335     pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 192;
2336
2337     pp_inline_parameter->grf5.block_count_x = w / 16;   /* 1 x N */
2338     pp_inline_parameter->grf5.number_blocks = w / 16;
2339     pp_inline_parameter->grf5.block_vertical_mask = 0xff;
2340     pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
2341
2342     pp_dn_context->dest_w = w;
2343     pp_dn_context->dest_h = h;
2344
2345     dst_surface->flags = src_surface->flags;
2346     
2347     return VA_STATUS_SUCCESS;
2348 }
2349
2350 static int
2351 gen7_pp_dndi_x_steps(void *private_context)
2352 {
2353     struct pp_dndi_context *pp_dndi_context = private_context;
2354
2355     return pp_dndi_context->dest_w / 16;
2356 }
2357
2358 static int
2359 gen7_pp_dndi_y_steps(void *private_context)
2360 {
2361     struct pp_dndi_context *pp_dndi_context = private_context;
2362
2363     return pp_dndi_context->dest_h / 4;
2364 }
2365
2366 static int
2367 gen7_pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2368 {
2369     struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2370
2371     pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16;
2372     pp_inline_parameter->grf7.destination_block_vertical_origin = y * 4;
2373
2374     return 0;
2375 }
2376
2377 static VAStatus
2378 gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2379                              const struct i965_surface *src_surface,
2380                              const VARectangle *src_rect,
2381                              struct i965_surface *dst_surface,
2382                              const VARectangle *dst_rect,
2383                              void *filter_param)
2384 {
2385     struct i965_driver_data *i965 = i965_driver_data(ctx);
2386     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
2387     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2388     struct object_surface *obj_surface;
2389     struct gen7_sampler_dndi *sampler_dndi;
2390     int index;
2391     int w, h;
2392     int orig_w, orig_h;
2393     int dndi_top_first = 1;
2394
2395     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
2396         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
2397
2398     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
2399         dndi_top_first = 1;
2400     else
2401         dndi_top_first = 0;
2402
2403     /* surface */
2404     obj_surface = SURFACE(src_surface->id);
2405     orig_w = obj_surface->orig_width;
2406     orig_h = obj_surface->orig_height;
2407     w = obj_surface->width;
2408     h = obj_surface->height;
2409
2410     if (pp_context->stmm.bo == NULL) {
2411         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2412                                            "STMM surface",
2413                                            w * h,
2414                                            4096);
2415         assert(pp_context->stmm.bo);
2416     }
2417
2418     /* source UV surface index 1 */
2419     gen7_pp_set_surface_state(ctx, pp_context,
2420                               obj_surface->bo, w * h,
2421                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2422                               1, 0);
2423
2424     /* source YUV surface index 3 */
2425     gen7_pp_set_surface2_state(ctx, pp_context,
2426                                obj_surface->bo, 0,
2427                                orig_w, orig_w, w,
2428                                0, h,
2429                                SURFACE_FORMAT_PLANAR_420_8, 1,
2430                                3);
2431
2432     /* source (temporal reference) YUV surface index 4 */
2433     gen7_pp_set_surface2_state(ctx, pp_context,
2434                                obj_surface->bo, 0,
2435                                orig_w, orig_w, w,
2436                                0, h,
2437                                SURFACE_FORMAT_PLANAR_420_8, 1,
2438                                4);
2439
2440     /* STMM / History Statistics input surface, index 5 */
2441     gen7_pp_set_surface_state(ctx, pp_context,
2442                               pp_context->stmm.bo, 0,
2443                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2444                               5, 1);
2445
2446     /* destination surface */
2447     obj_surface = SURFACE(dst_surface->id);
2448     orig_w = obj_surface->orig_width;
2449     orig_h = obj_surface->orig_height;
2450     w = obj_surface->width;
2451     h = obj_surface->height;
2452
2453     /* destination(Previous frame) Y surface index 27 */
2454     gen7_pp_set_surface_state(ctx, pp_context,
2455                               obj_surface->bo, 0,
2456                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2457                               27, 1);
2458
2459     /* destination(Previous frame) UV surface index 28 */
2460     gen7_pp_set_surface_state(ctx, pp_context,
2461                               obj_surface->bo, w * h,
2462                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2463                               28, 1);
2464
2465     /* destination(Current frame) Y surface index 30 */
2466     gen7_pp_set_surface_state(ctx, pp_context,
2467                               obj_surface->bo, 0,
2468                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2469                               30, 1);
2470
2471     /* destination(Current frame) UV surface index 31 */
2472     gen7_pp_set_surface_state(ctx, pp_context,
2473                               obj_surface->bo, w * h,
2474                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2475                               31, 1);
2476
2477     /* STMM output surface, index 33 */
2478     gen7_pp_set_surface_state(ctx, pp_context,
2479                               pp_context->stmm.bo, 0,
2480                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2481                               33, 1);
2482
2483
2484     /* sampler dndi */
2485     dri_bo_map(pp_context->sampler_state_table.bo, True);
2486     assert(pp_context->sampler_state_table.bo->virtual);
2487     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
2488     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
2489
2490     /* sample dndi index 0 */
2491     index = 0;
2492     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
2493     sampler_dndi[index].dw0.dnmh_delt = 8;
2494     sampler_dndi[index].dw0.vdi_walker_y_stride = 0;
2495     sampler_dndi[index].dw0.vdi_walker_frame_sharing_enable = 0;
2496     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
2497     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
2498
2499     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2500     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
2501     sampler_dndi[index].dw1.stmm_c2 = 0;
2502     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
2503     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
2504
2505     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
2506     sampler_dndi[index].dw2.bne_edge_th = 1;
2507     sampler_dndi[index].dw2.smooth_mv_th = 0;
2508     sampler_dndi[index].dw2.sad_tight_th = 5;
2509     sampler_dndi[index].dw2.cat_slope_minus1 = 9;
2510     sampler_dndi[index].dw2.good_neighbor_th = 4;
2511
2512     sampler_dndi[index].dw3.maximum_stmm = 128;
2513     sampler_dndi[index].dw3.multipler_for_vecm = 2;
2514     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2515     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2516     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
2517
2518     sampler_dndi[index].dw4.sdi_delta = 8;
2519     sampler_dndi[index].dw4.sdi_threshold = 128;
2520     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2521     sampler_dndi[index].dw4.stmm_shift_up = 0;
2522     sampler_dndi[index].dw4.stmm_shift_down = 0;
2523     sampler_dndi[index].dw4.minimum_stmm = 0;
2524
2525     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
2526     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
2527     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
2528     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
2529
2530     sampler_dndi[index].dw6.dn_enable = 0;
2531     sampler_dndi[index].dw6.di_enable = 1;
2532     sampler_dndi[index].dw6.di_partial = 0;
2533     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
2534     sampler_dndi[index].dw6.dndi_stream_id = 1;
2535     sampler_dndi[index].dw6.dndi_first_frame = 1;
2536     sampler_dndi[index].dw6.progressive_dn = 0;
2537     sampler_dndi[index].dw6.mcdi_enable = 0;
2538     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
2539     sampler_dndi[index].dw6.cat_th1 = 0;
2540     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
2541     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
2542
2543     sampler_dndi[index].dw7.sad_tha = 5;
2544     sampler_dndi[index].dw7.sad_thb = 10;
2545     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
2546     sampler_dndi[index].dw7.mc_pixel_consistency_th = 25;
2547     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
2548     sampler_dndi[index].dw7.vdi_walker_enable = 0;
2549     sampler_dndi[index].dw7.neighborpixel_th = 10;
2550     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
2551
2552     dri_bo_unmap(pp_context->sampler_state_table.bo);
2553
2554     /* private function & data */
2555     pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
2556     pp_context->pp_y_steps = gen7_pp_dndi_y_steps;
2557     pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
2558
2559     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
2560     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
2561     pp_static_parameter->grf1.di_top_field_first = 0;
2562     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
2563
2564     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
2565     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
2566     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
2567
2568     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
2569     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
2570
2571     pp_dndi_context->dest_w = w;
2572     pp_dndi_context->dest_h = h;
2573
2574     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
2575
2576     return VA_STATUS_SUCCESS;
2577 }
2578
2579 static int
2580 gen7_pp_dn_x_steps(void *private_context)
2581 {
2582     return 1;
2583 }
2584
2585 static int
2586 gen7_pp_dn_y_steps(void *private_context)
2587 {
2588     struct pp_dn_context *pp_dn_context = private_context;
2589
2590     return pp_dn_context->dest_h / 4;
2591 }
2592
2593 static int
2594 gen7_pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2595 {
2596     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2597
2598     pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
2599     pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
2600
2601     return 0;
2602 }
2603
2604 static VAStatus
2605 gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2606                            const struct i965_surface *src_surface,
2607                            const VARectangle *src_rect,
2608                            struct i965_surface *dst_surface,
2609                            const VARectangle *dst_rect,
2610                            void *filter_param)
2611 {
2612     struct i965_driver_data *i965 = i965_driver_data(ctx);
2613     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
2614     struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2615     struct object_surface *obj_surface;
2616     struct gen7_sampler_dndi *sampler_dn;
2617     VAProcFilterBaseParameterBuffer *dn_filter_param = filter_param;
2618     int index;
2619     int w, h;
2620     int orig_w, orig_h;
2621     int dn_strength = 15;
2622     int dndi_top_first = 1;
2623     int dn_progressive = 0;
2624
2625     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
2626         dndi_top_first = 1;
2627         dn_progressive = 1;
2628     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
2629         dndi_top_first = 1;
2630         dn_progressive = 0;
2631     } else {
2632         dndi_top_first = 0;
2633         dn_progressive = 0;
2634     }
2635
2636     if (dn_filter_param) {
2637         int value = dn_filter_param->value;
2638         
2639         if (value > 1.0)
2640             value = 1.0;
2641         
2642         if (value < 0.0)
2643             value = 0.0;
2644
2645         dn_strength = (int)(value * 31.0F);
2646     }
2647
2648     /* surface */
2649     obj_surface = SURFACE(src_surface->id);
2650     orig_w = obj_surface->orig_width;
2651     orig_h = obj_surface->orig_height;
2652     w = obj_surface->width;
2653     h = obj_surface->height;
2654
2655     if (pp_context->stmm.bo == NULL) {
2656         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
2657                                            "STMM surface",
2658                                            w * h,
2659                                            4096);
2660         assert(pp_context->stmm.bo);
2661     }
2662
2663     /* source UV surface index 1 */
2664     gen7_pp_set_surface_state(ctx, pp_context,
2665                               obj_surface->bo, w * h,
2666                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2667                               1, 0);
2668
2669     /* source YUV surface index 3 */
2670     gen7_pp_set_surface2_state(ctx, pp_context,
2671                                obj_surface->bo, 0,
2672                                orig_w, orig_w, w,
2673                                0, h,
2674                                SURFACE_FORMAT_PLANAR_420_8, 1,
2675                                3);
2676
2677     /* source STMM surface index 5 */
2678     gen7_pp_set_surface_state(ctx, pp_context,
2679                               pp_context->stmm.bo, 0,
2680                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2681                               5, 1);
2682
2683     /* destination surface */
2684     obj_surface = SURFACE(dst_surface->id);
2685     orig_w = obj_surface->orig_width;
2686     orig_h = obj_surface->orig_height;
2687     w = obj_surface->width;
2688     h = obj_surface->height;
2689
2690     /* destination Y surface index 7 */
2691     gen7_pp_set_surface_state(ctx, pp_context,
2692                               obj_surface->bo, 0,
2693                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
2694                               7, 1);
2695
2696     /* destination UV surface index 8 */
2697     gen7_pp_set_surface_state(ctx, pp_context,
2698                               obj_surface->bo, w * h,
2699                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
2700                               8, 1);
2701     /* sampler dn */
2702     dri_bo_map(pp_context->sampler_state_table.bo, True);
2703     assert(pp_context->sampler_state_table.bo->virtual);
2704     assert(sizeof(*sampler_dn) == sizeof(int) * 8);
2705     sampler_dn = pp_context->sampler_state_table.bo->virtual;
2706
2707     /* sample dn index 1 */
2708     index = 0;
2709     sampler_dn[index].dw0.denoise_asd_threshold = 0;
2710     sampler_dn[index].dw0.dnmh_delt = 8;
2711     sampler_dn[index].dw0.vdi_walker_y_stride = 0;
2712     sampler_dn[index].dw0.vdi_walker_frame_sharing_enable = 0;
2713     sampler_dn[index].dw0.denoise_maximum_history = 128;      // 128-240
2714     sampler_dn[index].dw0.denoise_stad_threshold = 0;
2715
2716     sampler_dn[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
2717     sampler_dn[index].dw1.denoise_moving_pixel_threshold = 0;
2718     sampler_dn[index].dw1.stmm_c2 = 0;
2719     sampler_dn[index].dw1.low_temporal_difference_threshold = 8;
2720     sampler_dn[index].dw1.temporal_difference_threshold = 16;
2721
2722     sampler_dn[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
2723     sampler_dn[index].dw2.bne_edge_th = 1;
2724     sampler_dn[index].dw2.smooth_mv_th = 0;
2725     sampler_dn[index].dw2.sad_tight_th = 5;
2726     sampler_dn[index].dw2.cat_slope_minus1 = 9;
2727     sampler_dn[index].dw2.good_neighbor_th = 4;
2728
2729     sampler_dn[index].dw3.maximum_stmm = 128;
2730     sampler_dn[index].dw3.multipler_for_vecm = 2;
2731     sampler_dn[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
2732     sampler_dn[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
2733     sampler_dn[index].dw3.stmm_blending_constant_select = 0;
2734
2735     sampler_dn[index].dw4.sdi_delta = 8;
2736     sampler_dn[index].dw4.sdi_threshold = 128;
2737     sampler_dn[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
2738     sampler_dn[index].dw4.stmm_shift_up = 0;
2739     sampler_dn[index].dw4.stmm_shift_down = 0;
2740     sampler_dn[index].dw4.minimum_stmm = 0;
2741
2742     sampler_dn[index].dw5.fmd_temporal_difference_threshold = 0;
2743     sampler_dn[index].dw5.sdi_fallback_mode_2_constant = 0;
2744     sampler_dn[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
2745     sampler_dn[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
2746
2747     sampler_dn[index].dw6.dn_enable = 1;
2748     sampler_dn[index].dw6.di_enable = 0;
2749     sampler_dn[index].dw6.di_partial = 0;
2750     sampler_dn[index].dw6.dndi_top_first = dndi_top_first;
2751     sampler_dn[index].dw6.dndi_stream_id = 1;
2752     sampler_dn[index].dw6.dndi_first_frame = 1;
2753     sampler_dn[index].dw6.progressive_dn = dn_progressive;
2754     sampler_dn[index].dw6.mcdi_enable = 0;
2755     sampler_dn[index].dw6.fmd_tear_threshold = 32;
2756     sampler_dn[index].dw6.cat_th1 = 0;
2757     sampler_dn[index].dw6.fmd2_vertical_difference_threshold = 32;
2758     sampler_dn[index].dw6.fmd1_vertical_difference_threshold = 32;
2759
2760     sampler_dn[index].dw7.sad_tha = 5;
2761     sampler_dn[index].dw7.sad_thb = 10;
2762     sampler_dn[index].dw7.fmd_for_1st_field_of_current_frame = 2;
2763     sampler_dn[index].dw7.mc_pixel_consistency_th = 25;
2764     sampler_dn[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
2765     sampler_dn[index].dw7.vdi_walker_enable = 0;
2766     sampler_dn[index].dw7.neighborpixel_th = 10;
2767     sampler_dn[index].dw7.column_width_minus1 = w / 16;
2768
2769     dri_bo_unmap(pp_context->sampler_state_table.bo);
2770
2771     /* private function & data */
2772     pp_context->pp_x_steps = gen7_pp_dn_x_steps;
2773     pp_context->pp_y_steps = gen7_pp_dn_y_steps;
2774     pp_context->pp_set_block_parameter = gen7_pp_dn_set_block_parameter;
2775
2776     pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
2777     pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
2778     pp_static_parameter->grf1.di_top_field_first = 0;
2779     pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
2780
2781     pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
2782     pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
2783     pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
2784
2785     pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
2786     pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
2787
2788     pp_dn_context->dest_w = w;
2789     pp_dn_context->dest_h = h;
2790
2791     dst_surface->flags = src_surface->flags;
2792
2793     return VA_STATUS_SUCCESS;
2794 }
2795
2796 static VAStatus
2797 ironlake_pp_initialize(
2798     VADriverContextP   ctx,
2799     struct i965_post_processing_context *pp_context,
2800     const struct i965_surface *src_surface,
2801     const VARectangle *src_rect,
2802     struct i965_surface *dst_surface,
2803     const VARectangle *dst_rect,
2804     int                pp_index,
2805     void *filter_param
2806 )
2807 {
2808     VAStatus va_status;
2809     struct i965_driver_data *i965 = i965_driver_data(ctx);
2810     struct pp_module *pp_module;
2811     dri_bo *bo;
2812     int static_param_size, inline_param_size;
2813
2814     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
2815     bo = dri_bo_alloc(i965->intel.bufmgr,
2816                       "surface state & binding table",
2817                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
2818                       4096);
2819     assert(bo);
2820     pp_context->surface_state_binding_table.bo = bo;
2821
2822     dri_bo_unreference(pp_context->curbe.bo);
2823     bo = dri_bo_alloc(i965->intel.bufmgr,
2824                       "constant buffer",
2825                       4096, 
2826                       4096);
2827     assert(bo);
2828     pp_context->curbe.bo = bo;
2829
2830     dri_bo_unreference(pp_context->idrt.bo);
2831     bo = dri_bo_alloc(i965->intel.bufmgr, 
2832                       "interface discriptor", 
2833                       sizeof(struct i965_interface_descriptor), 
2834                       4096);
2835     assert(bo);
2836     pp_context->idrt.bo = bo;
2837     pp_context->idrt.num_interface_descriptors = 0;
2838
2839     dri_bo_unreference(pp_context->sampler_state_table.bo);
2840     bo = dri_bo_alloc(i965->intel.bufmgr, 
2841                       "sampler state table", 
2842                       4096,
2843                       4096);
2844     assert(bo);
2845     dri_bo_map(bo, True);
2846     memset(bo->virtual, 0, bo->size);
2847     dri_bo_unmap(bo);
2848     pp_context->sampler_state_table.bo = bo;
2849
2850     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
2851     bo = dri_bo_alloc(i965->intel.bufmgr, 
2852                       "sampler 8x8 state ",
2853                       4096,
2854                       4096);
2855     assert(bo);
2856     pp_context->sampler_state_table.bo_8x8 = bo;
2857
2858     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
2859     bo = dri_bo_alloc(i965->intel.bufmgr, 
2860                       "sampler 8x8 state ",
2861                       4096,
2862                       4096);
2863     assert(bo);
2864     pp_context->sampler_state_table.bo_8x8_uv = bo;
2865
2866     dri_bo_unreference(pp_context->vfe_state.bo);
2867     bo = dri_bo_alloc(i965->intel.bufmgr, 
2868                       "vfe state", 
2869                       sizeof(struct i965_vfe_state), 
2870                       4096);
2871     assert(bo);
2872     pp_context->vfe_state.bo = bo;
2873
2874     if (IS_GEN7(i965->intel.device_id)) {
2875         static_param_size = sizeof(struct gen7_pp_static_parameter);
2876         inline_param_size = sizeof(struct gen7_pp_inline_parameter);
2877     } else {
2878         static_param_size = sizeof(struct pp_static_parameter);
2879         inline_param_size = sizeof(struct pp_inline_parameter);
2880     }
2881
2882     memset(pp_context->pp_static_parameter, 0, static_param_size);
2883     memset(pp_context->pp_inline_parameter, 0, inline_param_size);
2884     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
2885     pp_context->current_pp = pp_index;
2886     pp_module = &pp_context->pp_modules[pp_index];
2887     
2888     if (pp_module->initialize)
2889         va_status = pp_module->initialize(ctx, pp_context,
2890                                           src_surface,
2891                                           src_rect,
2892                                           dst_surface,
2893                                           dst_rect,
2894                                           filter_param);
2895     else
2896         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
2897
2898     return va_status;
2899 }
2900
2901 static VAStatus
2902 ironlake_post_processing(
2903     VADriverContextP   ctx,
2904     struct i965_post_processing_context *pp_context,
2905     const struct i965_surface *src_surface,
2906     const VARectangle *src_rect,
2907     struct i965_surface *dst_surface,
2908     const VARectangle *dst_rect,
2909     int                pp_index,
2910     void *filter_param
2911 )
2912 {
2913     VAStatus va_status;
2914
2915     va_status = ironlake_pp_initialize(ctx, pp_context,
2916                                        src_surface,
2917                                        src_rect,
2918                                        dst_surface,
2919                                        dst_rect,
2920                                        pp_index,
2921                                        filter_param);
2922
2923     if (va_status == VA_STATUS_SUCCESS) {
2924         ironlake_pp_states_setup(ctx, pp_context);
2925         ironlake_pp_pipeline_setup(ctx, pp_context);
2926     }
2927
2928     return va_status;
2929 }
2930
2931 static VAStatus
2932 gen6_pp_initialize(
2933     VADriverContextP   ctx,
2934     struct i965_post_processing_context *pp_context,
2935     const struct i965_surface *src_surface,
2936     const VARectangle *src_rect,
2937     struct i965_surface *dst_surface,
2938     const VARectangle *dst_rect,
2939     int                pp_index,
2940     void *filter_param
2941 )
2942 {
2943     VAStatus va_status;
2944     struct i965_driver_data *i965 = i965_driver_data(ctx);
2945     struct pp_module *pp_module;
2946     dri_bo *bo;
2947     struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2948     struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2949
2950     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
2951     bo = dri_bo_alloc(i965->intel.bufmgr,
2952                       "surface state & binding table",
2953                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
2954                       4096);
2955     assert(bo);
2956     pp_context->surface_state_binding_table.bo = bo;
2957
2958     dri_bo_unreference(pp_context->curbe.bo);
2959     bo = dri_bo_alloc(i965->intel.bufmgr,
2960                       "constant buffer",
2961                       4096, 
2962                       4096);
2963     assert(bo);
2964     pp_context->curbe.bo = bo;
2965
2966     dri_bo_unreference(pp_context->idrt.bo);
2967     bo = dri_bo_alloc(i965->intel.bufmgr, 
2968                       "interface discriptor", 
2969                       sizeof(struct gen6_interface_descriptor_data), 
2970                       4096);
2971     assert(bo);
2972     pp_context->idrt.bo = bo;
2973     pp_context->idrt.num_interface_descriptors = 0;
2974
2975     dri_bo_unreference(pp_context->sampler_state_table.bo);
2976     bo = dri_bo_alloc(i965->intel.bufmgr, 
2977                       "sampler state table", 
2978                       4096,
2979                       4096);
2980     assert(bo);
2981     dri_bo_map(bo, True);
2982     memset(bo->virtual, 0, bo->size);
2983     dri_bo_unmap(bo);
2984     pp_context->sampler_state_table.bo = bo;
2985
2986     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
2987     bo = dri_bo_alloc(i965->intel.bufmgr, 
2988                       "sampler 8x8 state ",
2989                       4096,
2990                       4096);
2991     assert(bo);
2992     pp_context->sampler_state_table.bo_8x8 = bo;
2993
2994     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
2995     bo = dri_bo_alloc(i965->intel.bufmgr, 
2996                       "sampler 8x8 state ",
2997                       4096,
2998                       4096);
2999     assert(bo);
3000     pp_context->sampler_state_table.bo_8x8_uv = bo;
3001
3002     dri_bo_unreference(pp_context->vfe_state.bo);
3003     bo = dri_bo_alloc(i965->intel.bufmgr, 
3004                       "vfe state", 
3005                       sizeof(struct i965_vfe_state), 
3006                       4096);
3007     assert(bo);
3008     pp_context->vfe_state.bo = bo;
3009     
3010     memset(pp_static_parameter, 0, sizeof(*pp_static_parameter));
3011     memset(pp_inline_parameter, 0, sizeof(*pp_inline_parameter));
3012     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
3013     pp_context->current_pp = pp_index;
3014     pp_module = &pp_context->pp_modules[pp_index];
3015     
3016     if (pp_module->initialize)
3017         va_status = pp_module->initialize(ctx, pp_context,
3018                                           src_surface,
3019                                           src_rect,
3020                                           dst_surface,
3021                                           dst_rect,
3022                                           filter_param);
3023     else
3024         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
3025
3026     return va_status;
3027 }
3028
3029 static void
3030 gen6_pp_interface_descriptor_table(VADriverContextP   ctx,
3031                                    struct i965_post_processing_context *pp_context)
3032 {
3033     struct i965_driver_data *i965 = i965_driver_data(ctx);
3034     struct gen6_interface_descriptor_data *desc;
3035     dri_bo *bo;
3036     int pp_index = pp_context->current_pp;
3037
3038     bo = pp_context->idrt.bo;
3039     dri_bo_map(bo, True);
3040     assert(bo->virtual);
3041     desc = bo->virtual;
3042     memset(desc, 0, sizeof(*desc));
3043     desc->desc0.kernel_start_pointer = 
3044         pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
3045     desc->desc1.single_program_flow = 1;
3046     desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
3047     desc->desc2.sampler_count = 1;      /* 1 - 4 samplers used */
3048     desc->desc2.sampler_state_pointer = 
3049         pp_context->sampler_state_table.bo->offset >> 5;
3050     desc->desc3.binding_table_entry_count = 0;
3051     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
3052     desc->desc4.constant_urb_entry_read_offset = 0;
3053
3054     if (IS_GEN7(i965->intel.device_id))
3055         desc->desc4.constant_urb_entry_read_length = 6; /* grf 1-6 */
3056     else
3057         desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
3058
3059     dri_bo_emit_reloc(bo,
3060                       I915_GEM_DOMAIN_INSTRUCTION, 0,
3061                       0,
3062                       offsetof(struct gen6_interface_descriptor_data, desc0),
3063                       pp_context->pp_modules[pp_index].kernel.bo);
3064
3065     dri_bo_emit_reloc(bo,
3066                       I915_GEM_DOMAIN_INSTRUCTION, 0,
3067                       desc->desc2.sampler_count << 2,
3068                       offsetof(struct gen6_interface_descriptor_data, desc2),
3069                       pp_context->sampler_state_table.bo);
3070
3071     dri_bo_unmap(bo);
3072     pp_context->idrt.num_interface_descriptors++;
3073 }
3074
3075 static void
3076 gen6_pp_upload_constants(VADriverContextP ctx,
3077                          struct i965_post_processing_context *pp_context)
3078 {
3079     struct i965_driver_data *i965 = i965_driver_data(ctx);
3080     unsigned char *constant_buffer;
3081     int param_size;
3082
3083     assert(sizeof(struct pp_static_parameter) == 128);
3084     assert(sizeof(struct gen7_pp_static_parameter) == 192);
3085
3086     if (IS_GEN7(i965->intel.device_id))
3087         param_size = sizeof(struct gen7_pp_static_parameter);
3088     else
3089         param_size = sizeof(struct pp_static_parameter);
3090
3091     dri_bo_map(pp_context->curbe.bo, 1);
3092     assert(pp_context->curbe.bo->virtual);
3093     constant_buffer = pp_context->curbe.bo->virtual;
3094     memcpy(constant_buffer, pp_context->pp_static_parameter, param_size);
3095     dri_bo_unmap(pp_context->curbe.bo);
3096 }
3097
3098 static void
3099 gen6_pp_states_setup(VADriverContextP ctx,
3100                      struct i965_post_processing_context *pp_context)
3101 {
3102     gen6_pp_interface_descriptor_table(ctx, pp_context);
3103     gen6_pp_upload_constants(ctx, pp_context);
3104 }
3105
3106 static void
3107 gen6_pp_pipeline_select(VADriverContextP ctx,
3108                         struct i965_post_processing_context *pp_context)
3109 {
3110     struct intel_batchbuffer *batch = pp_context->batch;
3111
3112     BEGIN_BATCH(batch, 1);
3113     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
3114     ADVANCE_BATCH(batch);
3115 }
3116
3117 static void
3118 gen6_pp_state_base_address(VADriverContextP ctx,
3119                            struct i965_post_processing_context *pp_context)
3120 {
3121     struct intel_batchbuffer *batch = pp_context->batch;
3122
3123     BEGIN_BATCH(batch, 10);
3124     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
3125     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3126     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
3127     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3128     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3129     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3130     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3131     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3132     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3133     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
3134     ADVANCE_BATCH(batch);
3135 }
3136
3137 static void
3138 gen6_pp_vfe_state(VADriverContextP ctx,
3139                   struct i965_post_processing_context *pp_context)
3140 {
3141     struct intel_batchbuffer *batch = pp_context->batch;
3142
3143     BEGIN_BATCH(batch, 8);
3144     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
3145     OUT_BATCH(batch, 0);
3146     OUT_BATCH(batch,
3147               (pp_context->urb.num_vfe_entries - 1) << 16 |
3148               pp_context->urb.num_vfe_entries << 8);
3149     OUT_BATCH(batch, 0);
3150     OUT_BATCH(batch,
3151               (pp_context->urb.size_vfe_entry * 2) << 16 |  /* URB Entry Allocation Size, in 256 bits unit */
3152               (pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2)); /* CURBE Allocation Size, in 256 bits unit */
3153     OUT_BATCH(batch, 0);
3154     OUT_BATCH(batch, 0);
3155     OUT_BATCH(batch, 0);
3156     ADVANCE_BATCH(batch);
3157 }
3158
3159 static void
3160 gen6_pp_curbe_load(VADriverContextP ctx,
3161                    struct i965_post_processing_context *pp_context)
3162 {
3163     struct intel_batchbuffer *batch = pp_context->batch;
3164
3165     assert(pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32 <= pp_context->curbe.bo->size);
3166
3167     BEGIN_BATCH(batch, 4);
3168     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
3169     OUT_BATCH(batch, 0);
3170     OUT_BATCH(batch,
3171               pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 * 32);
3172     OUT_RELOC(batch, 
3173               pp_context->curbe.bo,
3174               I915_GEM_DOMAIN_INSTRUCTION, 0,
3175               0);
3176     ADVANCE_BATCH(batch);
3177 }
3178
3179 static void
3180 gen6_interface_descriptor_load(VADriverContextP ctx,
3181                                struct i965_post_processing_context *pp_context)
3182 {
3183     struct intel_batchbuffer *batch = pp_context->batch;
3184
3185     BEGIN_BATCH(batch, 4);
3186     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
3187     OUT_BATCH(batch, 0);
3188     OUT_BATCH(batch,
3189               pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
3190     OUT_RELOC(batch, 
3191               pp_context->idrt.bo,
3192               I915_GEM_DOMAIN_INSTRUCTION, 0,
3193               0);
3194     ADVANCE_BATCH(batch);
3195 }
3196
3197 static void
3198 gen6_pp_object_walker(VADriverContextP ctx,
3199                       struct i965_post_processing_context *pp_context)
3200 {
3201     struct i965_driver_data *i965 = i965_driver_data(ctx);
3202     struct intel_batchbuffer *batch = pp_context->batch;
3203     int x, x_steps, y, y_steps;
3204     int param_size, command_length_in_dws;
3205     dri_bo *command_buffer;
3206     unsigned int *command_ptr;
3207
3208     if (IS_GEN7(i965->intel.device_id))
3209         param_size = sizeof(struct gen7_pp_inline_parameter);
3210     else
3211         param_size = sizeof(struct pp_inline_parameter);
3212
3213     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
3214     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
3215     command_length_in_dws = 6 + (param_size >> 2);
3216     command_buffer = dri_bo_alloc(i965->intel.bufmgr,
3217                                   "command objects buffer",
3218                                   command_length_in_dws * 4 * x_steps * y_steps + 8,
3219                                   4096);
3220
3221     dri_bo_map(command_buffer, 1);
3222     command_ptr = command_buffer->virtual;
3223
3224     for (y = 0; y < y_steps; y++) {
3225         for (x = 0; x < x_steps; x++) {
3226             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
3227                 *command_ptr++ = (CMD_MEDIA_OBJECT | (command_length_in_dws - 2));
3228                 *command_ptr++ = 0;
3229                 *command_ptr++ = 0;
3230                 *command_ptr++ = 0;
3231                 *command_ptr++ = 0;
3232                 *command_ptr++ = 0;
3233                 memcpy(command_ptr, pp_context->pp_inline_parameter, param_size);
3234                 command_ptr += (param_size >> 2);
3235             }
3236         }
3237     }
3238
3239     if (command_length_in_dws * x_steps * y_steps % 2 == 0)
3240         *command_ptr++ = 0;
3241
3242     *command_ptr = MI_BATCH_BUFFER_END;
3243
3244     dri_bo_unmap(command_buffer);
3245
3246     BEGIN_BATCH(batch, 2);
3247     OUT_BATCH(batch, MI_BATCH_BUFFER_START | (2 << 6));
3248     OUT_RELOC(batch, command_buffer, 
3249               I915_GEM_DOMAIN_COMMAND, 0, 
3250               0);
3251     ADVANCE_BATCH(batch);
3252     
3253     dri_bo_unreference(command_buffer);
3254
3255     /* Have to execute the batch buffer here becuase MI_BATCH_BUFFER_END
3256      * will cause control to pass back to ring buffer 
3257      */
3258     intel_batchbuffer_end_atomic(batch);
3259     intel_batchbuffer_flush(batch);
3260     intel_batchbuffer_start_atomic(batch, 0x1000);
3261 }
3262
3263 static void
3264 gen6_pp_pipeline_setup(VADriverContextP ctx,
3265                        struct i965_post_processing_context *pp_context)
3266 {
3267     struct intel_batchbuffer *batch = pp_context->batch;
3268
3269     intel_batchbuffer_start_atomic(batch, 0x1000);
3270     intel_batchbuffer_emit_mi_flush(batch);
3271     gen6_pp_pipeline_select(ctx, pp_context);
3272     gen6_pp_state_base_address(ctx, pp_context);
3273     gen6_pp_vfe_state(ctx, pp_context);
3274     gen6_pp_curbe_load(ctx, pp_context);
3275     gen6_interface_descriptor_load(ctx, pp_context);
3276     gen6_pp_object_walker(ctx, pp_context);
3277     intel_batchbuffer_end_atomic(batch);
3278 }
3279
3280 static VAStatus
3281 gen6_post_processing(
3282     VADriverContextP   ctx,
3283     struct i965_post_processing_context *pp_context,
3284     const struct i965_surface *src_surface,
3285     const VARectangle *src_rect,
3286     struct i965_surface *dst_surface,
3287     const VARectangle *dst_rect,
3288     int                pp_index,
3289     void * filter_param
3290 )
3291 {
3292     VAStatus va_status;
3293     
3294     va_status = gen6_pp_initialize(ctx, pp_context,
3295                                    src_surface,
3296                                    src_rect,
3297                                    dst_surface,
3298                                    dst_rect,
3299                                    pp_index,
3300                                    filter_param);
3301
3302     if (va_status == VA_STATUS_SUCCESS) {
3303         gen6_pp_states_setup(ctx, pp_context);
3304         gen6_pp_pipeline_setup(ctx, pp_context);
3305     }
3306
3307     return va_status;
3308 }
3309
3310 static VAStatus
3311 i965_post_processing_internal(
3312     VADriverContextP   ctx,
3313     struct i965_post_processing_context *pp_context,
3314     const struct i965_surface *src_surface,
3315     const VARectangle *src_rect,
3316     struct i965_surface *dst_surface,
3317     const VARectangle *dst_rect,
3318     int                pp_index,
3319     void *filter_param
3320 )
3321 {
3322     struct i965_driver_data *i965 = i965_driver_data(ctx);
3323     VAStatus va_status;
3324
3325     if (IS_GEN6(i965->intel.device_id) ||
3326         IS_GEN7(i965->intel.device_id))
3327         va_status = gen6_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
3328     else
3329         va_status = ironlake_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
3330     
3331     return va_status;
3332 }
3333
3334 VAStatus 
3335 i965_DestroySurfaces(VADriverContextP ctx,
3336                      VASurfaceID *surface_list,
3337                      int num_surfaces);
3338 VAStatus 
3339 i965_CreateSurfaces(VADriverContextP ctx,
3340                     int width,
3341                     int height,
3342                     int format,
3343                     int num_surfaces,
3344                     VASurfaceID *surfaces);
3345 VASurfaceID
3346 i965_post_processing(
3347     VADriverContextP   ctx,
3348     VASurfaceID        surface,
3349     const VARectangle *src_rect,
3350     const VARectangle *dst_rect,
3351     unsigned int       flags,
3352     int               *has_done_scaling  
3353 )
3354 {
3355     struct i965_driver_data *i965 = i965_driver_data(ctx);
3356     VASurfaceID in_surface_id = surface;
3357     VASurfaceID out_surface_id = VA_INVALID_ID;
3358     
3359     *has_done_scaling = 0;
3360
3361     if (HAS_PP(i965)) {
3362         struct object_surface *obj_surface;
3363         VAStatus status;
3364         struct i965_surface src_surface;
3365         struct i965_surface dst_surface;
3366
3367         obj_surface = SURFACE(in_surface_id);
3368
3369         /* Currently only support post processing for NV12 surface */
3370         if (obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2'))
3371             return out_surface_id;
3372
3373         if (flags & I965_PP_FLAG_DEINTERLACING) {
3374             status = i965_CreateSurfaces(ctx,
3375                                          obj_surface->orig_width,
3376                                          obj_surface->orig_height,
3377                                          VA_RT_FORMAT_YUV420,
3378                                          1,
3379                                          &out_surface_id);
3380             assert(status == VA_STATUS_SUCCESS);
3381             obj_surface = SURFACE(out_surface_id);
3382             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
3383
3384             src_surface.id = in_surface_id;
3385             src_surface.type = I965_SURFACE_TYPE_SURFACE;
3386             src_surface.flags = (flags & I965_PP_FLAG_DEINTERLACING_TOP_FISRT) ? 
3387                 I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST;
3388             dst_surface.id = out_surface_id;
3389             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3390             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3391
3392             i965_post_processing_internal(ctx, i965->pp_context,
3393                                           &src_surface,
3394                                           src_rect,
3395                                           &dst_surface,
3396                                           dst_rect,
3397                                           PP_NV12_DNDI,
3398                                           NULL);
3399         }
3400
3401         if (flags & I965_PP_FLAG_AVS) {
3402             struct i965_render_state *render_state = &i965->render_state;
3403             struct intel_region *dest_region = render_state->draw_region;
3404
3405             if (out_surface_id != VA_INVALID_ID)
3406                 in_surface_id = out_surface_id;
3407
3408             status = i965_CreateSurfaces(ctx,
3409                                          dest_region->width,
3410                                          dest_region->height,
3411                                          VA_RT_FORMAT_YUV420,
3412                                          1,
3413                                          &out_surface_id);
3414             assert(status == VA_STATUS_SUCCESS);
3415             obj_surface = SURFACE(out_surface_id);
3416             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
3417
3418             src_surface.id = in_surface_id;
3419             src_surface.type = I965_SURFACE_TYPE_SURFACE;
3420             src_surface.flags = I965_SURFACE_FLAG_FRAME;
3421             dst_surface.id = out_surface_id;
3422             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3423             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3424
3425             i965_post_processing_internal(ctx, i965->pp_context,
3426                                           &src_surface,
3427                                           src_rect,
3428                                           &dst_surface,
3429                                           dst_rect,
3430                                           PP_NV12_AVS,
3431                                           NULL);
3432
3433             if (in_surface_id != surface)
3434                 i965_DestroySurfaces(ctx, &in_surface_id, 1);
3435                 
3436             *has_done_scaling = 1;
3437         }
3438     }
3439
3440     return out_surface_id;
3441 }       
3442
3443 static VAStatus
3444 i965_image_i420_processing(VADriverContextP ctx,
3445                            const struct i965_surface *src_surface,
3446                            const VARectangle *src_rect,
3447                            struct i965_surface *dst_surface,
3448                            const VARectangle *dst_rect)
3449 {
3450     struct i965_driver_data *i965 = i965_driver_data(ctx);
3451     struct i965_post_processing_context *pp_context = i965->pp_context;
3452     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
3453
3454     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
3455         i965_post_processing_internal(ctx, i965->pp_context,
3456                                       src_surface,
3457                                       src_rect,
3458                                       dst_surface,
3459                                       dst_rect,
3460                                       PP_PL3_LOAD_SAVE_N12,
3461                                       NULL);
3462     } else {
3463         i965_post_processing_internal(ctx, i965->pp_context,
3464                                       src_surface,
3465                                       src_rect,
3466                                       dst_surface,
3467                                       dst_rect,
3468                                       PP_PL3_LOAD_SAVE_PL3,
3469                                       NULL);
3470     }
3471
3472     intel_batchbuffer_flush(pp_context->batch);
3473
3474     return VA_STATUS_SUCCESS;
3475 }
3476
3477 static VAStatus
3478 i965_image_nv12_processing(VADriverContextP ctx,
3479                            const struct i965_surface *src_surface,
3480                            const VARectangle *src_rect,
3481                            struct i965_surface *dst_surface,
3482                            const VARectangle *dst_rect)
3483 {
3484     struct i965_driver_data *i965 = i965_driver_data(ctx);
3485     struct i965_post_processing_context *pp_context = i965->pp_context;
3486     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
3487
3488     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
3489         i965_post_processing_internal(ctx, i965->pp_context,
3490                                       src_surface,
3491                                       src_rect,
3492                                       dst_surface,
3493                                       dst_rect,
3494                                       PP_NV12_LOAD_SAVE_N12,
3495                                       NULL);
3496     } else {
3497         i965_post_processing_internal(ctx, i965->pp_context,
3498                                       src_surface,
3499                                       src_rect,
3500                                       dst_surface,
3501                                       dst_rect,
3502                                       PP_NV12_LOAD_SAVE_PL3,
3503                                       NULL);
3504     }
3505
3506     intel_batchbuffer_flush(pp_context->batch);
3507
3508     return VA_STATUS_SUCCESS;
3509 }
3510
3511 VAStatus
3512 i965_image_processing(VADriverContextP ctx,
3513                       const struct i965_surface *src_surface,
3514                       const VARectangle *src_rect,
3515                       struct i965_surface *dst_surface,
3516                       const VARectangle *dst_rect)
3517 {
3518     struct i965_driver_data *i965 = i965_driver_data(ctx);
3519     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
3520
3521     if (HAS_PP(i965)) {
3522         int fourcc = pp_get_surface_fourcc(ctx, src_surface);
3523
3524         switch (fourcc) {
3525         case VA_FOURCC('Y', 'V', '1', '2'):
3526         case VA_FOURCC('I', '4', '2', '0'):
3527             status = i965_image_i420_processing(ctx,
3528                                                 src_surface,
3529                                                 src_rect,
3530                                                 dst_surface,
3531                                                 dst_rect);
3532             break;
3533
3534         case  VA_FOURCC('N', 'V', '1', '2'):
3535             status = i965_image_nv12_processing(ctx,
3536                                                 src_surface,
3537                                                 src_rect,
3538                                                 dst_surface,
3539                                                 dst_rect);
3540             break;
3541
3542         default:
3543             status = VA_STATUS_ERROR_UNIMPLEMENTED;
3544             break;
3545         }
3546     }
3547
3548     return status;
3549 }       
3550
3551 static void
3552 i965_post_processing_context_finalize(struct i965_post_processing_context *pp_context)
3553 {
3554     int i;
3555
3556     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
3557     pp_context->surface_state_binding_table.bo = NULL;
3558
3559     dri_bo_unreference(pp_context->curbe.bo);
3560     pp_context->curbe.bo = NULL;
3561
3562     dri_bo_unreference(pp_context->sampler_state_table.bo);
3563     pp_context->sampler_state_table.bo = NULL;
3564
3565     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
3566     pp_context->sampler_state_table.bo_8x8 = NULL;
3567
3568     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
3569     pp_context->sampler_state_table.bo_8x8_uv = NULL;
3570
3571     dri_bo_unreference(pp_context->idrt.bo);
3572     pp_context->idrt.bo = NULL;
3573     pp_context->idrt.num_interface_descriptors = 0;
3574
3575     dri_bo_unreference(pp_context->vfe_state.bo);
3576     pp_context->vfe_state.bo = NULL;
3577
3578     dri_bo_unreference(pp_context->stmm.bo);
3579     pp_context->stmm.bo = NULL;
3580
3581     for (i = 0; i < NUM_PP_MODULES; i++) {
3582         struct pp_module *pp_module = &pp_context->pp_modules[i];
3583
3584         dri_bo_unreference(pp_module->kernel.bo);
3585         pp_module->kernel.bo = NULL;
3586     }
3587
3588     free(pp_context->pp_static_parameter);
3589     free(pp_context->pp_inline_parameter);
3590     pp_context->pp_static_parameter = NULL;
3591     pp_context->pp_inline_parameter = NULL;
3592 }
3593
3594 Bool
3595 i965_post_processing_terminate(VADriverContextP ctx)
3596 {
3597     struct i965_driver_data *i965 = i965_driver_data(ctx);
3598     struct i965_post_processing_context *pp_context = i965->pp_context;
3599
3600     if (pp_context) {
3601         i965_post_processing_context_finalize(pp_context);
3602         free(pp_context);
3603     }
3604
3605     i965->pp_context = NULL;
3606
3607     return True;
3608 }
3609
3610 static void
3611 i965_post_processing_context_init(VADriverContextP ctx,
3612                                   struct i965_post_processing_context *pp_context,
3613                                   struct intel_batchbuffer *batch)
3614 {
3615     struct i965_driver_data *i965 = i965_driver_data(ctx);
3616     int i;
3617
3618     pp_context->urb.size = URB_SIZE((&i965->intel));
3619     pp_context->urb.num_vfe_entries = 32;
3620     pp_context->urb.size_vfe_entry = 1;     /* in 512 bits unit */
3621     pp_context->urb.num_cs_entries = 1;
3622     
3623     if (IS_GEN7(i965->intel.device_id))
3624         pp_context->urb.size_cs_entry = 4;      /* in 512 bits unit */
3625     else
3626         pp_context->urb.size_cs_entry = 2;
3627
3628     pp_context->urb.vfe_start = 0;
3629     pp_context->urb.cs_start = pp_context->urb.vfe_start + 
3630         pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
3631     assert(pp_context->urb.cs_start + 
3632            pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
3633
3634     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
3635     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
3636     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen7));
3637
3638     if (IS_GEN7(i965->intel.device_id))
3639         memcpy(pp_context->pp_modules, pp_modules_gen7, sizeof(pp_context->pp_modules));
3640     else if (IS_GEN6(i965->intel.device_id))
3641         memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
3642     else if (IS_IRONLAKE(i965->intel.device_id))
3643         memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
3644
3645     for (i = 0; i < NUM_PP_MODULES; i++) {
3646         struct pp_module *pp_module = &pp_context->pp_modules[i];
3647         dri_bo_unreference(pp_module->kernel.bo);
3648         if (pp_module->kernel.bin && pp_module->kernel.size) {
3649             pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
3650                                                 pp_module->kernel.name,
3651                                                 pp_module->kernel.size,
3652                                                 4096);
3653             assert(pp_module->kernel.bo);
3654             dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
3655         } else {
3656             pp_module->kernel.bo = NULL;
3657         }
3658     }
3659
3660     /* static & inline parameters */
3661     if (IS_GEN7(i965->intel.device_id)) {
3662         pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
3663         pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
3664     } else {
3665         pp_context->pp_static_parameter = calloc(sizeof(struct pp_static_parameter), 1);
3666         pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
3667     }
3668
3669     pp_context->batch = batch;
3670 }
3671
3672 Bool
3673 i965_post_processing_init(VADriverContextP ctx)
3674 {
3675     struct i965_driver_data *i965 = i965_driver_data(ctx);
3676     struct i965_post_processing_context *pp_context = i965->pp_context;
3677
3678     if (HAS_PP(i965)) {
3679         if (pp_context == NULL) {
3680             pp_context = calloc(1, sizeof(*pp_context));
3681             i965_post_processing_context_init(ctx, pp_context, i965->batch);
3682             i965->pp_context = pp_context;
3683         }
3684     }
3685
3686     return True;
3687 }
3688
3689 static const int procfilter_to_pp_flag[10] = {
3690     PP_NULL,    /* VAProcFilterNone */
3691     PP_NULL,    /* VAProcFilterDering */
3692     PP_NULL,    /* VAProcFilterDeblocking */
3693     PP_NV12_DN, /* VAProcFilterNoiseReduction */
3694     PP_NV12_DNDI, /* VAProcFilterDeinterlacing */
3695     PP_NULL,    /* VAProcFilterSharpening */
3696     PP_NULL,    /* VAProcFilterColorEnhancement */
3697     PP_NULL,    /* VAProcFilterProcAmp */
3698     PP_NULL,    /* VAProcFilterComposition */
3699     PP_NULL,    /* VAProcFilterFrameRateConversion */
3700 };
3701
3702 static const int proc_frame_to_pp_frame[3] = {
3703     I965_SURFACE_FLAG_FRAME,
3704     I965_SURFACE_FLAG_TOP_FIELD_FIRST,
3705     I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST
3706 };
3707
3708 static void 
3709 i965_proc_picture(VADriverContextP ctx, 
3710                   VAProfile profile, 
3711                   union codec_state *codec_state,
3712                   struct hw_context *hw_context)
3713 {
3714     struct i965_driver_data *i965 = i965_driver_data(ctx);
3715     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
3716     struct proc_state *proc_state = &codec_state->proc;
3717     VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
3718     VAProcInputParameterBuffer *input_param = (VAProcInputParameterBuffer *)proc_state->input_param->buffer;
3719     struct object_surface *obj_surface;
3720     struct i965_surface src_surface, dst_surface;
3721     VAStatus status;
3722     int i;
3723     VASurfaceID tmp_surfaces[VA_PROC_PIPELINE_MAX_NUM_FILTERS];
3724     int num_tmp_surfaces = 0;
3725     unsigned int tiling = 0, swizzle = 0;
3726     int in_width, in_height;
3727
3728     assert(input_param->surface != VA_INVALID_ID);
3729     assert(proc_state->current_render_target != VA_INVALID_ID);
3730
3731     obj_surface = SURFACE(input_param->surface);
3732     assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
3733     in_width = obj_surface->orig_width;
3734     in_height = obj_surface->orig_height;
3735     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3736
3737     obj_surface = SURFACE(proc_state->current_render_target);
3738     i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC('N','V','1','2'));
3739
3740     src_surface.id = input_param->surface;
3741     src_surface.type = I965_SURFACE_TYPE_SURFACE;
3742     src_surface.flags = proc_frame_to_pp_frame[input_param->flags];
3743     
3744     for (i = 0; i < VA_PROC_PIPELINE_MAX_NUM_FILTERS; i++) {
3745         VAProcFilterType filter_type = pipeline_param->filter_pipeline[i];
3746         VASurfaceID out_surface_id = VA_INVALID_ID;
3747         void *filter_param = NULL;
3748
3749         if (procfilter_to_pp_flag[filter_type] != PP_NULL) {
3750             if (proc_state->filter_param[filter_type])
3751                 filter_param = proc_state->filter_param[filter_type]->buffer;
3752
3753             status = i965_CreateSurfaces(ctx,
3754                                          in_width,
3755                                          in_height,
3756                                          VA_RT_FORMAT_YUV420,
3757                                          1,
3758                                          &out_surface_id);
3759             assert(status == VA_STATUS_SUCCESS);
3760             tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
3761             obj_surface = SURFACE(out_surface_id);
3762             i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC('N','V','1','2'));
3763             dst_surface.id = out_surface_id;
3764             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3765             status = i965_post_processing_internal(ctx, &proc_context->pp_context,
3766                                                    &src_surface,
3767                                                    &input_param->region,
3768                                                    &dst_surface,
3769                                                    &input_param->region,
3770                                                    procfilter_to_pp_flag[filter_type],
3771                                                    filter_param);
3772
3773             if (status == VA_STATUS_SUCCESS) {
3774                 src_surface.id = dst_surface.id;
3775                 src_surface.type = dst_surface.type;
3776                 src_surface.flags = dst_surface.flags;
3777             }
3778         }
3779     }
3780
3781     dst_surface.id = proc_state->current_render_target;
3782     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3783     i965_post_processing_internal(ctx, &proc_context->pp_context,
3784                                   &src_surface,
3785                                   &input_param->region,
3786                                   &dst_surface,
3787                                   &pipeline_param->output_region,
3788                                   (pipeline_param->flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC ?
3789                                   PP_NV12_AVS : PP_NV12_SCALING,
3790                                   NULL);
3791
3792     if (num_tmp_surfaces)
3793         i965_DestroySurfaces(ctx,
3794                              tmp_surfaces,
3795                              num_tmp_surfaces);
3796
3797     intel_batchbuffer_flush(hw_context->batch);
3798 }
3799
3800 static void
3801 i965_proc_context_destroy(void *hw_context)
3802 {
3803     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
3804
3805     i965_post_processing_context_finalize(&proc_context->pp_context);
3806     intel_batchbuffer_free(proc_context->base.batch);
3807     free(proc_context);
3808 }
3809
3810 struct hw_context *
3811 i965_proc_context_init(VADriverContextP ctx, VAProfile profile)
3812 {
3813     struct intel_driver_data *intel = intel_driver_data(ctx);
3814     struct i965_proc_context *proc_context = calloc(1, sizeof(struct i965_proc_context));
3815
3816     proc_context->base.destroy = i965_proc_context_destroy;
3817     proc_context->base.run = i965_proc_picture;
3818     proc_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER);
3819     i965_post_processing_context_init(ctx, &proc_context->pp_context, proc_context->base.batch);
3820
3821     return (struct hw_context *)proc_context;
3822 }