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