VPP: Add support for mixed content(frame & field)
[profile/ivi/vaapi-intel-driver.git] / src / i965_post_processing.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include <va/va_backend.h>
35
36 #include "intel_batchbuffer.h"
37 #include "intel_driver.h"
38 #include "i965_defines.h"
39 #include "i965_structs.h"
40 #include "i965_drv_video.h"
41 #include "i965_post_processing.h"
42 #include "i965_render.h"
43
44 #define HAS_PP(ctx) (IS_IRONLAKE((ctx)->intel.device_id) ||     \
45                      IS_GEN6((ctx)->intel.device_id) ||         \
46                      IS_GEN7((ctx)->intel.device_id))
47
48 #define SURFACE_STATE_PADDED_SIZE_0_I965        ALIGN(sizeof(struct i965_surface_state), 32)
49 #define SURFACE_STATE_PADDED_SIZE_1_I965        ALIGN(sizeof(struct i965_surface_state2), 32)
50 #define SURFACE_STATE_PADDED_SIZE_I965          MAX(SURFACE_STATE_PADDED_SIZE_0_I965, SURFACE_STATE_PADDED_SIZE_1_I965)
51
52 #define SURFACE_STATE_PADDED_SIZE               SURFACE_STATE_PADDED_SIZE_I965
53 #define SURFACE_STATE_OFFSET(index)             (SURFACE_STATE_PADDED_SIZE * index)
54 #define BINDING_TABLE_OFFSET                    SURFACE_STATE_OFFSET(MAX_PP_SURFACES)
55
56 static const uint32_t pp_null_gen5[][4] = {
57 #include "shaders/post_processing/gen5_6/null.g4b.gen5"
58 };
59
60 static const uint32_t pp_nv12_load_save_nv12_gen5[][4] = {
61 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g4b.gen5"
62 };
63
64 static const uint32_t pp_nv12_load_save_pl3_gen5[][4] = {
65 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g4b.gen5"
66 };
67
68 static const uint32_t pp_pl3_load_save_nv12_gen5[][4] = {
69 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g4b.gen5"
70 };
71
72 static const uint32_t pp_pl3_load_save_pl3_gen5[][4] = {
73 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g4b.gen5"
74 };
75
76 static const uint32_t pp_nv12_scaling_gen5[][4] = {
77 #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g4b.gen5"
78 };
79
80 static const uint32_t pp_nv12_avs_gen5[][4] = {
81 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g4b.gen5"
82 };
83
84 static const uint32_t pp_nv12_dndi_gen5[][4] = {
85 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g4b.gen5"
86 };
87
88 static const uint32_t pp_nv12_dn_gen5[][4] = {
89 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g4b.gen5"
90 };
91
92 static VAStatus pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
93                                    const struct i965_surface *src_surface,
94                                    const VARectangle *src_rect,
95                                    struct i965_surface *dst_surface,
96                                    const VARectangle *dst_rect,
97                                    void *filter_param);
98 static VAStatus pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
99                                        const struct i965_surface *src_surface,
100                                        const VARectangle *src_rect,
101                                        struct i965_surface *dst_surface,
102                                        const VARectangle *dst_rect,
103                                        void *filter_param);
104 static VAStatus pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
105                                            const struct i965_surface *src_surface,
106                                            const VARectangle *src_rect,
107                                            struct i965_surface *dst_surface,
108                                            const VARectangle *dst_rect,
109                                            void *filter_param);
110 static VAStatus pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
111                                                 const struct i965_surface *src_surface,
112                                                 const VARectangle *src_rect,
113                                                 struct i965_surface *dst_surface,
114                                                 const VARectangle *dst_rect,
115                                                 void *filter_param);
116 static VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
117                                         const struct i965_surface *src_surface,
118                                         const VARectangle *src_rect,
119                                         struct i965_surface *dst_surface,
120                                         const VARectangle *dst_rect,
121                                         void *filter_param);
122 static VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
123                                       const struct i965_surface *src_surface,
124                                       const VARectangle *src_rect,
125                                       struct i965_surface *dst_surface,
126                                       const VARectangle *dst_rect,
127                                       void *filter_param);
128
129 static struct pp_module pp_modules_gen5[] = {
130     {
131         {
132             "NULL module (for testing)",
133             PP_NULL,
134             pp_null_gen5,
135             sizeof(pp_null_gen5),
136             NULL,
137         },
138
139         pp_null_initialize,
140     },
141
142     {
143         {
144             "NV12_NV12",
145             PP_NV12_LOAD_SAVE_N12,
146             pp_nv12_load_save_nv12_gen5,
147             sizeof(pp_nv12_load_save_nv12_gen5),
148             NULL,
149         },
150
151         pp_plx_load_save_plx_initialize,
152     },
153
154     {
155         {
156             "NV12_PL3",
157             PP_NV12_LOAD_SAVE_PL3,
158             pp_nv12_load_save_pl3_gen5,
159             sizeof(pp_nv12_load_save_pl3_gen5),
160             NULL,
161         },
162
163         pp_plx_load_save_plx_initialize,
164     },
165
166     {
167         {
168             "PL3_NV12",
169             PP_PL3_LOAD_SAVE_N12,
170             pp_pl3_load_save_nv12_gen5,
171             sizeof(pp_pl3_load_save_nv12_gen5),
172             NULL,
173         },
174
175         pp_plx_load_save_plx_initialize,
176     },
177
178     {
179         {
180             "PL3_PL3",
181             PP_PL3_LOAD_SAVE_N12,
182             pp_pl3_load_save_pl3_gen5,
183             sizeof(pp_pl3_load_save_pl3_gen5),
184             NULL,
185         },
186
187         pp_plx_load_save_plx_initialize
188     },
189
190     {
191         {
192             "NV12 Scaling module",
193             PP_NV12_SCALING,
194             pp_nv12_scaling_gen5,
195             sizeof(pp_nv12_scaling_gen5),
196             NULL,
197         },
198
199         pp_nv12_scaling_initialize,
200     },
201
202     {
203         {
204             "NV12 AVS module",
205             PP_NV12_AVS,
206             pp_nv12_avs_gen5,
207             sizeof(pp_nv12_avs_gen5),
208             NULL,
209         },
210
211         pp_nv12_avs_initialize,
212     },
213
214     {
215         {
216             "NV12 DNDI module",
217             PP_NV12_DNDI,
218             pp_nv12_dndi_gen5,
219             sizeof(pp_nv12_dndi_gen5),
220             NULL,
221         },
222
223         pp_nv12_dndi_initialize,
224     },
225
226     {
227         {
228             "NV12 DN module",
229             PP_NV12_DN,
230             pp_nv12_dn_gen5,
231             sizeof(pp_nv12_dn_gen5),
232             NULL,
233         },
234
235         pp_nv12_dn_initialize,
236     },
237 };
238
239 static const uint32_t pp_null_gen6[][4] = {
240 #include "shaders/post_processing/gen5_6/null.g6b"
241 };
242
243 static const uint32_t pp_nv12_load_save_nv12_gen6[][4] = {
244 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g6b"
245 };
246
247 static const uint32_t pp_nv12_load_save_pl3_gen6[][4] = {
248 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g6b"
249 };
250
251 static const uint32_t pp_pl3_load_save_nv12_gen6[][4] = {
252 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g6b"
253 };
254
255 static const uint32_t pp_pl3_load_save_pl3_gen6[][4] = {
256 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g6b"
257 };
258
259 static const uint32_t pp_nv12_scaling_gen6[][4] = {
260 #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g6b"
261 };
262
263 static const uint32_t pp_nv12_avs_gen6[][4] = {
264 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
265 };
266
267 static const uint32_t pp_nv12_dndi_gen6[][4] = {
268 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g6b"
269 };
270
271 static const uint32_t pp_nv12_dn_gen6[][4] = {
272 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g6b"
273 };
274
275 static struct pp_module pp_modules_gen6[] = {
276     {
277         {
278             "NULL module (for testing)",
279             PP_NULL,
280             pp_null_gen6,
281             sizeof(pp_null_gen6),
282             NULL,
283         },
284
285         pp_null_initialize,
286     },
287
288     {
289         {
290             "NV12_NV12",
291             PP_NV12_LOAD_SAVE_N12,
292             pp_nv12_load_save_nv12_gen6,
293             sizeof(pp_nv12_load_save_nv12_gen6),
294             NULL,
295         },
296
297         pp_plx_load_save_plx_initialize,
298     },
299
300     {
301         {
302             "NV12_PL3",
303             PP_NV12_LOAD_SAVE_PL3,
304             pp_nv12_load_save_pl3_gen6,
305             sizeof(pp_nv12_load_save_pl3_gen6),
306             NULL,
307         },
308         
309         pp_plx_load_save_plx_initialize,
310     },
311
312     {
313         {
314             "PL3_NV12",
315             PP_PL3_LOAD_SAVE_N12,
316             pp_pl3_load_save_nv12_gen6,
317             sizeof(pp_pl3_load_save_nv12_gen6),
318             NULL,
319         },
320
321         pp_plx_load_save_plx_initialize,
322     },
323
324     {
325         {
326             "PL3_PL3",
327             PP_PL3_LOAD_SAVE_N12,
328             pp_pl3_load_save_pl3_gen6,
329             sizeof(pp_pl3_load_save_pl3_gen6),
330             NULL,
331         },
332
333         pp_plx_load_save_plx_initialize,
334     },
335
336     {
337         {
338             "NV12 Scaling module",
339             PP_NV12_SCALING,
340             pp_nv12_scaling_gen6,
341             sizeof(pp_nv12_scaling_gen6),
342             NULL,
343         },
344
345         pp_nv12_scaling_initialize,
346     },
347
348     {
349         {
350             "NV12 AVS module",
351             PP_NV12_AVS,
352             pp_nv12_avs_gen6,
353             sizeof(pp_nv12_avs_gen6),
354             NULL,
355         },
356
357         pp_nv12_avs_initialize,
358     },
359
360     {
361         {
362             "NV12 DNDI module",
363             PP_NV12_DNDI,
364             pp_nv12_dndi_gen6,
365             sizeof(pp_nv12_dndi_gen6),
366             NULL,
367         },
368
369         pp_nv12_dndi_initialize,
370     },
371
372     {
373         {
374             "NV12 DN module",
375             PP_NV12_DN,
376             pp_nv12_dn_gen6,
377             sizeof(pp_nv12_dn_gen6),
378             NULL,
379         },
380
381         pp_nv12_dn_initialize,
382     },
383 };
384
385 #define pp_static_parameter     pp_context->pp_static_parameter
386 #define pp_inline_parameter     pp_context->pp_inline_parameter
387
388 static int
389 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
390 {
391     struct i965_driver_data *i965 = i965_driver_data(ctx);
392     int fourcc;
393
394     if (surface->type == I965_SURFACE_TYPE_IMAGE) {
395         struct object_image *obj_image = IMAGE(surface->id);
396         fourcc = obj_image->image.format.fourcc;
397     } else {
398         struct object_surface *obj_surface = SURFACE(surface->id);
399         fourcc = obj_surface->fourcc;
400     }
401
402     return fourcc;
403 }
404
405 static void
406 pp_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
407 {
408     switch (tiling) {
409     case I915_TILING_NONE:
410         ss->ss3.tiled_surface = 0;
411         ss->ss3.tile_walk = 0;
412         break;
413     case I915_TILING_X:
414         ss->ss3.tiled_surface = 1;
415         ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
416         break;
417     case I915_TILING_Y:
418         ss->ss3.tiled_surface = 1;
419         ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
420         break;
421     }
422 }
423
424 static void
425 pp_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
426 {
427     switch (tiling) {
428     case I915_TILING_NONE:
429         ss->ss2.tiled_surface = 0;
430         ss->ss2.tile_walk = 0;
431         break;
432     case I915_TILING_X:
433         ss->ss2.tiled_surface = 1;
434         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
435         break;
436     case I915_TILING_Y:
437         ss->ss2.tiled_surface = 1;
438         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
439         break;
440     }
441 }
442
443 static void
444 ironlake_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
445 {
446     struct i965_interface_descriptor *desc;
447     dri_bo *bo;
448     int pp_index = pp_context->current_pp;
449
450     bo = pp_context->idrt.bo;
451     dri_bo_map(bo, 1);
452     assert(bo->virtual);
453     desc = bo->virtual;
454     memset(desc, 0, sizeof(*desc));
455     desc->desc0.grf_reg_blocks = 10;
456     desc->desc0.kernel_start_pointer = pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
457     desc->desc1.const_urb_entry_read_offset = 0;
458     desc->desc1.const_urb_entry_read_len = 4; /* grf 1-4 */
459     desc->desc2.sampler_state_pointer = pp_context->sampler_state_table.bo->offset >> 5;
460     desc->desc2.sampler_count = 0;
461     desc->desc3.binding_table_entry_count = 0;
462     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
463
464     dri_bo_emit_reloc(bo,
465                       I915_GEM_DOMAIN_INSTRUCTION, 0,
466                       desc->desc0.grf_reg_blocks,
467                       offsetof(struct i965_interface_descriptor, desc0),
468                       pp_context->pp_modules[pp_index].kernel.bo);
469
470     dri_bo_emit_reloc(bo,
471                       I915_GEM_DOMAIN_INSTRUCTION, 0,
472                       desc->desc2.sampler_count << 2,
473                       offsetof(struct i965_interface_descriptor, desc2),
474                       pp_context->sampler_state_table.bo);
475
476     dri_bo_unmap(bo);
477     pp_context->idrt.num_interface_descriptors++;
478 }
479
480 static void
481 ironlake_pp_vfe_state(struct i965_post_processing_context *pp_context)
482 {
483     struct i965_vfe_state *vfe_state;
484     dri_bo *bo;
485
486     bo = pp_context->vfe_state.bo;
487     dri_bo_map(bo, 1);
488     assert(bo->virtual);
489     vfe_state = bo->virtual;
490     memset(vfe_state, 0, sizeof(*vfe_state));
491     vfe_state->vfe1.max_threads = pp_context->urb.num_vfe_entries - 1;
492     vfe_state->vfe1.urb_entry_alloc_size = pp_context->urb.size_vfe_entry - 1;
493     vfe_state->vfe1.num_urb_entries = pp_context->urb.num_vfe_entries;
494     vfe_state->vfe1.vfe_mode = VFE_GENERIC_MODE;
495     vfe_state->vfe1.children_present = 0;
496     vfe_state->vfe2.interface_descriptor_base = 
497         pp_context->idrt.bo->offset >> 4; /* reloc */
498     dri_bo_emit_reloc(bo,
499                       I915_GEM_DOMAIN_INSTRUCTION, 0,
500                       0,
501                       offsetof(struct i965_vfe_state, vfe2),
502                       pp_context->idrt.bo);
503     dri_bo_unmap(bo);
504 }
505
506 static void
507 ironlake_pp_upload_constants(struct i965_post_processing_context *pp_context)
508 {
509     unsigned char *constant_buffer;
510
511     assert(sizeof(pp_static_parameter) == 128);
512     dri_bo_map(pp_context->curbe.bo, 1);
513     assert(pp_context->curbe.bo->virtual);
514     constant_buffer = pp_context->curbe.bo->virtual;
515     memcpy(constant_buffer, &pp_static_parameter, sizeof(pp_static_parameter));
516     dri_bo_unmap(pp_context->curbe.bo);
517 }
518
519 static void
520 ironlake_pp_states_setup(VADriverContextP ctx,
521                          struct i965_post_processing_context *pp_context)
522 {
523     ironlake_pp_interface_descriptor_table(pp_context);
524     ironlake_pp_vfe_state(pp_context);
525     ironlake_pp_upload_constants(pp_context);
526 }
527
528 static void
529 ironlake_pp_pipeline_select(VADriverContextP ctx,
530                             struct i965_post_processing_context *pp_context)
531 {
532     struct intel_batchbuffer *batch = pp_context->batch;
533
534     BEGIN_BATCH(batch, 1);
535     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
536     ADVANCE_BATCH(batch);
537 }
538
539 static void
540 ironlake_pp_urb_layout(VADriverContextP ctx,
541                        struct i965_post_processing_context *pp_context)
542 {
543     struct intel_batchbuffer *batch = pp_context->batch;
544     unsigned int vfe_fence, cs_fence;
545
546     vfe_fence = pp_context->urb.cs_start;
547     cs_fence = pp_context->urb.size;
548
549     BEGIN_BATCH(batch, 3);
550     OUT_BATCH(batch, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
551     OUT_BATCH(batch, 0);
552     OUT_BATCH(batch, 
553               (vfe_fence << UF2_VFE_FENCE_SHIFT) |      /* VFE_SIZE */
554               (cs_fence << UF2_CS_FENCE_SHIFT));        /* CS_SIZE */
555     ADVANCE_BATCH(batch);
556 }
557
558 static void
559 ironlake_pp_state_base_address(VADriverContextP ctx,
560                                struct i965_post_processing_context *pp_context)
561 {
562     struct intel_batchbuffer *batch = pp_context->batch;
563
564     BEGIN_BATCH(batch, 8);
565     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | 6);
566     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
567     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
568     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
569     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
570     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
571     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
572     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
573     ADVANCE_BATCH(batch);
574 }
575
576 static void
577 ironlake_pp_state_pointers(VADriverContextP ctx,
578                            struct i965_post_processing_context *pp_context)
579 {
580     struct intel_batchbuffer *batch = pp_context->batch;
581
582     BEGIN_BATCH(batch, 3);
583     OUT_BATCH(batch, CMD_MEDIA_STATE_POINTERS | 1);
584     OUT_BATCH(batch, 0);
585     OUT_RELOC(batch, pp_context->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
586     ADVANCE_BATCH(batch);
587 }
588
589 static void 
590 ironlake_pp_cs_urb_layout(VADriverContextP ctx,
591                           struct i965_post_processing_context *pp_context)
592 {
593     struct intel_batchbuffer *batch = pp_context->batch;
594
595     BEGIN_BATCH(batch, 2);
596     OUT_BATCH(batch, CMD_CS_URB_STATE | 0);
597     OUT_BATCH(batch,
598               ((pp_context->urb.size_cs_entry - 1) << 4) |     /* URB Entry Allocation Size */
599               (pp_context->urb.num_cs_entries << 0));          /* Number of URB Entries */
600     ADVANCE_BATCH(batch);
601 }
602
603 static void
604 ironlake_pp_constant_buffer(VADriverContextP ctx,
605                             struct i965_post_processing_context *pp_context)
606 {
607     struct intel_batchbuffer *batch = pp_context->batch;
608
609     BEGIN_BATCH(batch, 2);
610     OUT_BATCH(batch, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
611     OUT_RELOC(batch, pp_context->curbe.bo,
612               I915_GEM_DOMAIN_INSTRUCTION, 0,
613               pp_context->urb.size_cs_entry - 1);
614     ADVANCE_BATCH(batch);    
615 }
616
617 static void
618 ironlake_pp_object_walker(VADriverContextP ctx,
619                           struct i965_post_processing_context *pp_context)
620 {
621     struct intel_batchbuffer *batch = pp_context->batch;
622     int x, x_steps, y, y_steps;
623
624     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
625     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
626
627     for (y = 0; y < y_steps; y++) {
628         for (x = 0; x < x_steps; x++) {
629             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
630                 BEGIN_BATCH(batch, 20);
631                 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 18);
632                 OUT_BATCH(batch, 0);
633                 OUT_BATCH(batch, 0); /* no indirect data */
634                 OUT_BATCH(batch, 0);
635
636                 /* inline data grf 5-6 */
637                 assert(sizeof(pp_inline_parameter) == 64);
638                 intel_batchbuffer_data(batch, &pp_inline_parameter, sizeof(pp_inline_parameter));
639
640                 ADVANCE_BATCH(batch);
641             }
642         }
643     }
644 }
645
646 static void
647 ironlake_pp_pipeline_setup(VADriverContextP ctx,
648                            struct i965_post_processing_context *pp_context)
649 {
650     struct intel_batchbuffer *batch = pp_context->batch;
651
652     intel_batchbuffer_start_atomic(batch, 0x1000);
653     intel_batchbuffer_emit_mi_flush(batch);
654     ironlake_pp_pipeline_select(ctx, pp_context);
655     ironlake_pp_state_base_address(ctx, pp_context);
656     ironlake_pp_state_pointers(ctx, pp_context);
657     ironlake_pp_urb_layout(ctx, pp_context);
658     ironlake_pp_cs_urb_layout(ctx, pp_context);
659     ironlake_pp_constant_buffer(ctx, pp_context);
660     ironlake_pp_object_walker(ctx, pp_context);
661     intel_batchbuffer_end_atomic(batch);
662 }
663
664 static void
665 i965_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
666                           dri_bo *surf_bo, unsigned long surf_bo_offset,
667                           int width, int height, int pitch, int format, 
668                           int index, int is_target)
669 {
670     struct i965_surface_state *ss;
671     dri_bo *ss_bo;
672     unsigned int tiling;
673     unsigned int swizzle;
674
675     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
676     ss_bo = pp_context->surface_state_binding_table.bo;
677     assert(ss_bo);
678
679     dri_bo_map(ss_bo, True);
680     assert(ss_bo->virtual);
681     ss = (struct i965_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
682     memset(ss, 0, sizeof(*ss));
683     ss->ss0.surface_type = I965_SURFACE_2D;
684     ss->ss0.surface_format = format;
685     ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
686     ss->ss2.width = width - 1;
687     ss->ss2.height = height - 1;
688     ss->ss3.pitch = pitch - 1;
689     pp_set_surface_tiling(ss, tiling);
690     dri_bo_emit_reloc(ss_bo,
691                       I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
692                       surf_bo_offset,
693                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state, ss1),
694                       surf_bo);
695     ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
696     dri_bo_unmap(ss_bo);
697 }
698
699 static void
700 i965_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
701                            dri_bo *surf_bo, unsigned long surf_bo_offset,
702                            int width, int height, int wpitch,
703                            int xoffset, int yoffset,
704                            int format, int interleave_chroma,
705                            int index)
706 {
707     struct i965_surface_state2 *ss2;
708     dri_bo *ss2_bo;
709     unsigned int tiling;
710     unsigned int swizzle;
711
712     dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
713     ss2_bo = pp_context->surface_state_binding_table.bo;
714     assert(ss2_bo);
715
716     dri_bo_map(ss2_bo, True);
717     assert(ss2_bo->virtual);
718     ss2 = (struct i965_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
719     memset(ss2, 0, sizeof(*ss2));
720     ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
721     ss2->ss1.cbcr_pixel_offset_v_direction = 0;
722     ss2->ss1.width = width - 1;
723     ss2->ss1.height = height - 1;
724     ss2->ss2.pitch = wpitch - 1;
725     ss2->ss2.interleave_chroma = interleave_chroma;
726     ss2->ss2.surface_format = format;
727     ss2->ss3.x_offset_for_cb = xoffset;
728     ss2->ss3.y_offset_for_cb = yoffset;
729     pp_set_surface2_tiling(ss2, tiling);
730     dri_bo_emit_reloc(ss2_bo,
731                       I915_GEM_DOMAIN_RENDER, 0,
732                       surf_bo_offset,
733                       SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state2, ss0),
734                       surf_bo);
735     ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
736     dri_bo_unmap(ss2_bo);
737 }
738
739 static void 
740 pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
741                                 const struct i965_surface *surface, 
742                                 int base_index, int is_target,
743                                 int *width, int *height, int *pitch, int *offset)
744 {
745     struct i965_driver_data *i965 = i965_driver_data(ctx);
746     struct object_surface *obj_surface;
747     struct object_image *obj_image;
748     dri_bo *bo;
749     int fourcc = pp_get_surface_fourcc(ctx, surface);
750     const int Y = 0;
751     const int U = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 2 : 1;
752     const int V = fourcc == VA_FOURCC('Y', 'V', '1', '2') ? 1 : 2;
753     const int UV = 1;
754     int interleaved_uv = fourcc == VA_FOURCC('N', 'V', '1', '2');
755
756     if (surface->type == I965_SURFACE_TYPE_SURFACE) {
757         obj_surface = SURFACE(surface->id);
758         bo = obj_surface->bo;
759         width[0] = obj_surface->orig_width;
760         height[0] = obj_surface->orig_height;
761         pitch[0] = obj_surface->width;
762         offset[0] = 0;
763
764         if (interleaved_uv) {
765             width[1] = obj_surface->orig_width;
766             height[1] = obj_surface->orig_height / 2;
767             pitch[1] = obj_surface->width;
768             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
769         } else {
770             width[1] = obj_surface->orig_width / 2;
771             height[1] = obj_surface->orig_height / 2;
772             pitch[1] = obj_surface->width / 2;
773             offset[1] = offset[0] + obj_surface->width * obj_surface->height;
774             width[2] = obj_surface->orig_width / 2;
775             height[2] = obj_surface->orig_height / 2;
776             pitch[2] = obj_surface->width / 2;
777             offset[2] = offset[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
778         }
779     } else {
780         obj_image = IMAGE(surface->id);
781         bo = obj_image->bo;
782         width[0] = obj_image->image.width;
783         height[0] = obj_image->image.height;
784         pitch[0] = obj_image->image.pitches[0];
785         offset[0] = obj_image->image.offsets[0];
786
787         if (interleaved_uv) {
788             width[1] = obj_image->image.width;
789             height[1] = obj_image->image.height / 2;
790             pitch[1] = obj_image->image.pitches[1];
791             offset[1] = obj_image->image.offsets[1];
792         } else {
793             width[1] = obj_image->image.width / 2;
794             height[1] = obj_image->image.height / 2;
795             pitch[1] = obj_image->image.pitches[1];
796             offset[1] = obj_image->image.offsets[1];
797             width[2] = obj_image->image.width / 2;
798             height[2] = obj_image->image.height / 2;
799             pitch[2] = obj_image->image.pitches[2];
800             offset[2] = obj_image->image.offsets[2];
801         }
802     }
803
804     /* Y surface */
805     i965_pp_set_surface_state(ctx, pp_context,
806                               bo, offset[Y],
807                               width[Y] / 4, height[Y], pitch[Y], I965_SURFACEFORMAT_R8_UNORM,
808                               base_index, is_target);
809
810     if (interleaved_uv) {
811         i965_pp_set_surface_state(ctx, pp_context,
812                                   bo, offset[UV],
813                                   width[UV] / 4, height[UV], pitch[UV], I965_SURFACEFORMAT_R8_UNORM,
814                                   base_index + 1, is_target);
815     } else {
816         /* U surface */
817         i965_pp_set_surface_state(ctx, pp_context,
818                                   bo, offset[U],
819                                   width[U] / 4, height[U], pitch[U], I965_SURFACEFORMAT_R8_UNORM,
820                                   base_index + 1, is_target);
821
822         /* V surface */
823         i965_pp_set_surface_state(ctx, pp_context,
824                                   bo, offset[V],
825                                   width[V] / 4, height[V], pitch[V], I965_SURFACEFORMAT_R8_UNORM,
826                                   base_index + 2, is_target);
827     }
828
829 }
830
831 static int
832 pp_null_x_steps(void *private_context)
833 {
834     return 1;
835 }
836
837 static int
838 pp_null_y_steps(void *private_context)
839 {
840     return 1;
841 }
842
843 static int
844 pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
845 {
846     return 0;
847 }
848
849 static VAStatus
850 pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
851                    const struct i965_surface *src_surface,
852                    const VARectangle *src_rect,
853                    struct i965_surface *dst_surface,
854                    const VARectangle *dst_rect,
855                    void *filter_param)
856 {
857     /* private function & data */
858     pp_context->pp_x_steps = pp_null_x_steps;
859     pp_context->pp_y_steps = pp_null_y_steps;
860     pp_context->pp_set_block_parameter = pp_null_set_block_parameter;
861
862     dst_surface->flags = src_surface->flags;
863
864     return VA_STATUS_SUCCESS;
865 }
866
867 static int
868 pp_load_save_x_steps(void *private_context)
869 {
870     return 1;
871 }
872
873 static int
874 pp_load_save_y_steps(void *private_context)
875 {
876     struct pp_load_save_context *pp_load_save_context = private_context;
877
878     return pp_load_save_context->dest_h / 8;
879 }
880
881 static int
882 pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
883 {
884     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
885     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
886     pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16;
887     pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8;
888
889     return 0;
890 }
891
892 static VAStatus
893 pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
894                                 const struct i965_surface *src_surface,
895                                 const VARectangle *src_rect,
896                                 struct i965_surface *dst_surface,
897                                 const VARectangle *dst_rect,
898                                 void *filter_param)
899 {
900     struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->private_context;
901     int width[3], height[3], pitch[3], offset[3];
902     const int Y = 0;
903
904     /* source surface */
905     pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 1, 0,
906                                     width, height, pitch, offset);
907
908     /* destination surface */
909     pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 7, 1,
910                                     width, height, pitch, offset);
911
912     /* private function & data */
913     pp_context->pp_x_steps = pp_load_save_x_steps;
914     pp_context->pp_y_steps = pp_load_save_y_steps;
915     pp_context->pp_set_block_parameter = pp_load_save_set_block_parameter;
916     pp_load_save_context->dest_h = ALIGN(height[Y], 16);
917     pp_load_save_context->dest_w = ALIGN(width[Y], 16);
918
919     pp_inline_parameter.grf5.block_count_x = ALIGN(width[Y], 16) / 16;   /* 1 x N */
920     pp_inline_parameter.grf5.number_blocks = ALIGN(width[Y], 16) / 16;
921
922     dst_surface->flags = src_surface->flags;
923
924     return VA_STATUS_SUCCESS;
925 }
926
927 static int
928 pp_scaling_x_steps(void *private_context)
929 {
930     return 1;
931 }
932
933 static int
934 pp_scaling_y_steps(void *private_context)
935 {
936     struct pp_scaling_context *pp_scaling_context = private_context;
937
938     return pp_scaling_context->dest_h / 8;
939 }
940
941 static int
942 pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
943 {
944     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
945     float src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
946     float src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step;
947
948     pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
949     pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
950     pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
951     pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
952     
953     return 0;
954 }
955
956 static VAStatus
957 pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
958                            const struct i965_surface *src_surface,
959                            const VARectangle *src_rect,
960                            struct i965_surface *dst_surface,
961                            const VARectangle *dst_rect,
962                            void *filter_param)
963 {
964     struct i965_driver_data *i965 = i965_driver_data(ctx);
965     struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
966     struct object_surface *obj_surface;
967     struct i965_sampler_state *sampler_state;
968     int in_w, in_h, in_wpitch, in_hpitch;
969     int out_w, out_h, out_wpitch, out_hpitch;
970
971     /* source surface */
972     obj_surface = SURFACE(src_surface->id);
973     in_w = obj_surface->orig_width;
974     in_h = obj_surface->orig_height;
975     in_wpitch = obj_surface->width;
976     in_hpitch = obj_surface->height;
977
978     /* source Y surface index 1 */
979     i965_pp_set_surface_state(ctx, pp_context,
980                               obj_surface->bo, 0,
981                               in_w, in_h, in_wpitch, I965_SURFACEFORMAT_R8_UNORM,
982                               1, 0);
983
984     /* source UV surface index 2 */
985     i965_pp_set_surface_state(ctx, pp_context,
986                               obj_surface->bo, in_wpitch * in_hpitch,
987                               in_w / 2, in_h / 2, in_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
988                               2, 0);
989
990     /* destination surface */
991     obj_surface = SURFACE(dst_surface->id);
992     out_w = obj_surface->orig_width;
993     out_h = obj_surface->orig_height;
994     out_wpitch = obj_surface->width;
995     out_hpitch = obj_surface->height;
996
997     /* destination Y surface index 7 */
998     i965_pp_set_surface_state(ctx, pp_context,
999                               obj_surface->bo, 0,
1000                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1001                               7, 1);
1002
1003     /* destination UV surface index 8 */
1004     i965_pp_set_surface_state(ctx, pp_context,
1005                               obj_surface->bo, out_wpitch * out_hpitch,
1006                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1007                               8, 1);
1008
1009     /* sampler state */
1010     dri_bo_map(pp_context->sampler_state_table.bo, True);
1011     assert(pp_context->sampler_state_table.bo->virtual);
1012     sampler_state = pp_context->sampler_state_table.bo->virtual;
1013
1014     /* SIMD16 Y index 1 */
1015     sampler_state[1].ss0.min_filter = I965_MAPFILTER_LINEAR;
1016     sampler_state[1].ss0.mag_filter = I965_MAPFILTER_LINEAR;
1017     sampler_state[1].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1018     sampler_state[1].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1019     sampler_state[1].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1020
1021     /* SIMD16 UV index 2 */
1022     sampler_state[2].ss0.min_filter = I965_MAPFILTER_LINEAR;
1023     sampler_state[2].ss0.mag_filter = I965_MAPFILTER_LINEAR;
1024     sampler_state[2].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1025     sampler_state[2].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1026     sampler_state[2].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
1027
1028     dri_bo_unmap(pp_context->sampler_state_table.bo);
1029
1030     /* private function & data */
1031     pp_context->pp_x_steps = pp_scaling_x_steps;
1032     pp_context->pp_y_steps = pp_scaling_y_steps;
1033     pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
1034
1035     pp_scaling_context->dest_x = dst_rect->x;
1036     pp_scaling_context->dest_y = dst_rect->y;
1037     pp_scaling_context->dest_w = ALIGN(dst_rect->width, 16);
1038     pp_scaling_context->dest_h = ALIGN(dst_rect->height, 16);
1039     pp_scaling_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
1040     pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
1041
1042     pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h;
1043
1044     pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w;
1045     pp_inline_parameter.grf5.block_count_x = pp_scaling_context->dest_w / 16;   /* 1 x N */
1046     pp_inline_parameter.grf5.number_blocks = pp_scaling_context->dest_w / 16;
1047     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
1048     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
1049
1050     dst_surface->flags = src_surface->flags;
1051
1052     return VA_STATUS_SUCCESS;
1053 }
1054
1055 static int
1056 pp_avs_x_steps(void *private_context)
1057 {
1058     struct pp_avs_context *pp_avs_context = private_context;
1059
1060     return pp_avs_context->dest_w / 16;
1061 }
1062
1063 static int
1064 pp_avs_y_steps(void *private_context)
1065 {
1066     return 1;
1067 }
1068
1069 static int
1070 pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1071 {
1072     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1073     float src_x_steping, src_y_steping, video_step_delta;
1074     int tmp_w = ALIGN(pp_avs_context->dest_h * pp_avs_context->src_w / pp_avs_context->src_h, 16);
1075
1076     if (tmp_w >= pp_avs_context->dest_w) {
1077         pp_inline_parameter.grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
1078         pp_inline_parameter.grf6.video_step_delta = 0;
1079         
1080         if (x == 0) {
1081             pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
1082                 pp_avs_context->src_normalized_x;
1083         } else {
1084             src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
1085             video_step_delta = pp_inline_parameter.grf6.video_step_delta;
1086             pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1087                 16 * 15 * video_step_delta / 2;
1088         }
1089     } else {
1090         int n0, n1, n2, nls_left, nls_right;
1091         int factor_a = 5, factor_b = 4;
1092         float f;
1093
1094         n0 = (pp_avs_context->dest_w - tmp_w) / (16 * 2);
1095         n1 = (pp_avs_context->dest_w - tmp_w) / 16 - n0;
1096         n2 = tmp_w / (16 * factor_a);
1097         nls_left = n0 + n2;
1098         nls_right = n1 + n2;
1099         f = (float) n2 * 16 / tmp_w;
1100         
1101         if (n0 < 5) {
1102             pp_inline_parameter.grf6.video_step_delta = 0.0;
1103
1104             if (x == 0) {
1105                 pp_inline_parameter.grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
1106                 pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
1107             } else {
1108                 src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
1109                 video_step_delta = pp_inline_parameter.grf6.video_step_delta;
1110                 pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1111                     16 * 15 * video_step_delta / 2;
1112             }
1113         } else {
1114             if (x < nls_left) {
1115                 /* f = a * nls_left * 16 + b * nls_left * 16 * (nls_left * 16 - 1) / 2 */
1116                 float a = f / (nls_left * 16 * factor_b);
1117                 float b = (f - nls_left * 16 * a) * 2 / (nls_left * 16 * (nls_left * 16 - 1));
1118                 
1119                 pp_inline_parameter.grf6.video_step_delta = b;
1120
1121                 if (x == 0) {
1122                     pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
1123                     pp_inline_parameter.grf5.normalized_video_x_scaling_step = a;
1124                 } else {
1125                     src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
1126                     video_step_delta = pp_inline_parameter.grf6.video_step_delta;
1127                     pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1128                         16 * 15 * video_step_delta / 2;
1129                     pp_inline_parameter.grf5.normalized_video_x_scaling_step += 16 * b;
1130                 }
1131             } else if (x < (pp_avs_context->dest_w / 16 - nls_right)) {
1132                 /* scale the center linearly */
1133                 src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
1134                 video_step_delta = pp_inline_parameter.grf6.video_step_delta;
1135                 pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1136                     16 * 15 * video_step_delta / 2;
1137                 pp_inline_parameter.grf6.video_step_delta = 0.0;
1138                 pp_inline_parameter.grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
1139             } else {
1140                 float a = f / (nls_right * 16 * factor_b);
1141                 float b = (f - nls_right * 16 * a) * 2 / (nls_right * 16 * (nls_right * 16 - 1));
1142
1143                 src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
1144                 video_step_delta = pp_inline_parameter.grf6.video_step_delta;
1145                 pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
1146                     16 * 15 * video_step_delta / 2;
1147                 pp_inline_parameter.grf6.video_step_delta = -b;
1148
1149                 if (x == (pp_avs_context->dest_w / 16 - nls_right))
1150                     pp_inline_parameter.grf5.normalized_video_x_scaling_step = a + (nls_right * 16  - 1) * b;
1151                 else
1152                     pp_inline_parameter.grf5.normalized_video_x_scaling_step -= b * 16;
1153             }
1154         }
1155     }
1156
1157     src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step;
1158     pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
1159     pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
1160     pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
1161
1162     return 0;
1163 }
1164
1165 static VAStatus
1166 pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1167                        const struct i965_surface *src_surface,
1168                        const VARectangle *src_rect,
1169                        struct i965_surface *dst_surface,
1170                        const VARectangle *dst_rect,
1171                        void *filter_param)
1172 {
1173     struct i965_driver_data *i965 = i965_driver_data(ctx);
1174     struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->private_context;
1175     struct object_surface *obj_surface;
1176     struct i965_sampler_8x8 *sampler_8x8;
1177     struct i965_sampler_8x8_state *sampler_8x8_state;
1178     int index;
1179     int in_w, in_h, in_wpitch, in_hpitch;
1180     int out_w, out_h, out_wpitch, out_hpitch;
1181
1182     /* surface */
1183     obj_surface = SURFACE(src_surface->id);
1184     in_w = obj_surface->orig_width;
1185     in_h = obj_surface->orig_height;
1186     in_wpitch = obj_surface->width;
1187     in_hpitch = obj_surface->height;
1188
1189     /* source Y surface index 1 */
1190     i965_pp_set_surface2_state(ctx, pp_context,
1191                                obj_surface->bo, 0,
1192                                in_w, in_h, in_wpitch,
1193                                0, 0,
1194                                SURFACE_FORMAT_Y8_UNORM, 0,
1195                                1);
1196
1197     /* source UV surface index 2 */
1198     i965_pp_set_surface2_state(ctx, pp_context,
1199                                obj_surface->bo, in_wpitch * in_hpitch,
1200                                in_w, in_h, in_wpitch,
1201                                0, 0,
1202                                SURFACE_FORMAT_PLANAR_420_8, 1,
1203                                2);
1204
1205     /* destination surface */
1206     obj_surface = SURFACE(dst_surface->id);
1207     out_w = obj_surface->orig_width;
1208     out_h = obj_surface->orig_height;
1209     out_wpitch = obj_surface->width;
1210     out_hpitch = obj_surface->height;
1211     assert(out_w <= out_wpitch && out_h <= out_hpitch);
1212
1213     /* destination Y surface index 7 */
1214     i965_pp_set_surface_state(ctx, pp_context,
1215                               obj_surface->bo, 0,
1216                               out_w / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
1217                               7, 1);
1218
1219     /* destination UV surface index 8 */
1220     i965_pp_set_surface_state(ctx, pp_context,
1221                               obj_surface->bo, out_wpitch * out_hpitch,
1222                               out_w / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
1223                               8, 1);
1224
1225     /* sampler 8x8 state */
1226     dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
1227     assert(pp_context->sampler_state_table.bo_8x8->virtual);
1228     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
1229     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
1230     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
1231     sampler_8x8_state->dw136.default_sharpness_level = 0;
1232     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 1;
1233     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
1234     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
1235     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
1236
1237     /* sampler 8x8 */
1238     dri_bo_map(pp_context->sampler_state_table.bo, True);
1239     assert(pp_context->sampler_state_table.bo->virtual);
1240     assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
1241     sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
1242
1243     /* sample_8x8 Y index 1 */
1244     index = 1;
1245     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1246     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
1247     sampler_8x8[index].dw0.ief_bypass = 0;
1248     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1249     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1250     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
1251     sampler_8x8[index].dw2.global_noise_estimation = 22;
1252     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1253     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1254     sampler_8x8[index].dw3.strong_edge_weight = 7;
1255     sampler_8x8[index].dw3.regular_weight = 2;
1256     sampler_8x8[index].dw3.non_edge_weight = 0;
1257     sampler_8x8[index].dw3.gain_factor = 40;
1258     sampler_8x8[index].dw4.steepness_boost = 0;
1259     sampler_8x8[index].dw4.steepness_threshold = 0;
1260     sampler_8x8[index].dw4.mr_boost = 0;
1261     sampler_8x8[index].dw4.mr_threshold = 5;
1262     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1263     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1264     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1265     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1266     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1267     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1268     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1269     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1270     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1271     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1272     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1273     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1274     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1275     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1276     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1277     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1278     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1279     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1280     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1281     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1282     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1283     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1284     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1285     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1286     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1287     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1288     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1289     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1290     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1291     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1292     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1293     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1294     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1295     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1296     sampler_8x8[index].dw13.limiter_boost = 0;
1297     sampler_8x8[index].dw13.minimum_limiter = 10;
1298     sampler_8x8[index].dw13.maximum_limiter = 11;
1299     sampler_8x8[index].dw14.clip_limiter = 130;
1300     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1301                       I915_GEM_DOMAIN_RENDER, 
1302                       0,
1303                       0,
1304                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1305                       pp_context->sampler_state_table.bo_8x8);
1306
1307     dri_bo_map(pp_context->sampler_state_table.bo_8x8_uv, True);
1308     assert(pp_context->sampler_state_table.bo_8x8_uv->virtual);
1309     assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
1310     sampler_8x8_state = pp_context->sampler_state_table.bo_8x8_uv->virtual;
1311     memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
1312     sampler_8x8_state->dw136.default_sharpness_level = 0;
1313     sampler_8x8_state->dw137.adaptive_filter_for_all_channel = 0;
1314     sampler_8x8_state->dw137.bypass_y_adaptive_filtering = 1;
1315     sampler_8x8_state->dw137.bypass_x_adaptive_filtering = 1;
1316     dri_bo_unmap(pp_context->sampler_state_table.bo_8x8_uv);
1317
1318     /* sample_8x8 UV index 2 */
1319     index = 2;
1320     memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
1321     sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_NEAREST;
1322     sampler_8x8[index].dw0.ief_bypass = 0;
1323     sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
1324     sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
1325     sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8_uv->offset >> 5;
1326     sampler_8x8[index].dw2.global_noise_estimation = 22;
1327     sampler_8x8[index].dw2.strong_edge_threshold = 8;
1328     sampler_8x8[index].dw2.weak_edge_threshold = 1;
1329     sampler_8x8[index].dw3.strong_edge_weight = 7;
1330     sampler_8x8[index].dw3.regular_weight = 2;
1331     sampler_8x8[index].dw3.non_edge_weight = 0;
1332     sampler_8x8[index].dw3.gain_factor = 40;
1333     sampler_8x8[index].dw4.steepness_boost = 0;
1334     sampler_8x8[index].dw4.steepness_threshold = 0;
1335     sampler_8x8[index].dw4.mr_boost = 0;
1336     sampler_8x8[index].dw4.mr_threshold = 5;
1337     sampler_8x8[index].dw5.pwl1_point_1 = 4;
1338     sampler_8x8[index].dw5.pwl1_point_2 = 12;
1339     sampler_8x8[index].dw5.pwl1_point_3 = 16;
1340     sampler_8x8[index].dw5.pwl1_point_4 = 26;
1341     sampler_8x8[index].dw6.pwl1_point_5 = 40;
1342     sampler_8x8[index].dw6.pwl1_point_6 = 160;
1343     sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
1344     sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
1345     sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
1346     sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
1347     sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
1348     sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
1349     sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
1350     sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
1351     sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
1352     sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
1353     sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
1354     sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
1355     sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
1356     sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
1357     sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
1358     sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
1359     sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
1360     sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
1361     sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
1362     sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
1363     sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
1364     sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
1365     sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
1366     sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
1367     sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
1368     sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
1369     sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
1370     sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
1371     sampler_8x8[index].dw13.limiter_boost = 0;
1372     sampler_8x8[index].dw13.minimum_limiter = 10;
1373     sampler_8x8[index].dw13.maximum_limiter = 11;
1374     sampler_8x8[index].dw14.clip_limiter = 130;
1375     dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
1376                       I915_GEM_DOMAIN_RENDER, 
1377                       0,
1378                       0,
1379                       sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
1380                       pp_context->sampler_state_table.bo_8x8_uv);
1381
1382     dri_bo_unmap(pp_context->sampler_state_table.bo);
1383
1384     /* private function & data */
1385     pp_context->pp_x_steps = pp_avs_x_steps;
1386     pp_context->pp_y_steps = pp_avs_y_steps;
1387     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
1388
1389     pp_avs_context->dest_x = dst_rect->x;
1390     pp_avs_context->dest_y = dst_rect->y;
1391     pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
1392     pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
1393     pp_avs_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
1394     pp_avs_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
1395     pp_avs_context->src_w = src_rect->width;
1396     pp_avs_context->src_h = src_rect->height;
1397
1398     pp_static_parameter.grf4.r4_2.avs.nlas = 1;
1399     pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h;
1400
1401     pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w;
1402     pp_inline_parameter.grf5.block_count_x = 1;        /* M x 1 */
1403     pp_inline_parameter.grf5.number_blocks = pp_avs_context->dest_h / 8;
1404     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
1405     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
1406     pp_inline_parameter.grf6.video_step_delta = 0.0;
1407
1408     dst_surface->flags = src_surface->flags;
1409
1410     return VA_STATUS_SUCCESS;
1411 }
1412
1413 static int
1414 pp_dndi_x_steps(void *private_context)
1415 {
1416     return 1;
1417 }
1418
1419 static int
1420 pp_dndi_y_steps(void *private_context)
1421 {
1422     struct pp_dndi_context *pp_dndi_context = private_context;
1423
1424     return pp_dndi_context->dest_h / 4;
1425 }
1426
1427 static int
1428 pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1429 {
1430     pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16;
1431     pp_inline_parameter.grf5.destination_block_vertical_origin = y * 4;
1432
1433     return 0;
1434 }
1435
1436 static VAStatus
1437 pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1438                         const struct i965_surface *src_surface,
1439                         const VARectangle *src_rect,
1440                         struct i965_surface *dst_surface,
1441                         const VARectangle *dst_rect,
1442                         void *filter_param)
1443 {
1444     struct i965_driver_data *i965 = i965_driver_data(ctx);
1445     struct pp_dndi_context *pp_dndi_context = (struct pp_dndi_context *)&pp_context->private_context;
1446     struct object_surface *obj_surface;
1447     struct i965_sampler_dndi *sampler_dndi;
1448     int index;
1449     int w, h;
1450     int orig_w, orig_h;
1451     int dndi_top_first = 1;
1452
1453     if (src_surface->flags == I965_SURFACE_FLAG_FRAME)
1454         return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
1455
1456     if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST)
1457         dndi_top_first = 1;
1458     else
1459         dndi_top_first = 0;
1460
1461     /* surface */
1462     obj_surface = SURFACE(src_surface->id);
1463     orig_w = obj_surface->orig_width;
1464     orig_h = obj_surface->orig_height;
1465     w = obj_surface->width;
1466     h = obj_surface->height;
1467
1468     if (pp_context->stmm.bo == NULL) {
1469         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
1470                                            "STMM surface",
1471                                            w * h,
1472                                            4096);
1473         assert(pp_context->stmm.bo);
1474     }
1475
1476     /* source UV surface index 2 */
1477     i965_pp_set_surface_state(ctx, pp_context,
1478                               obj_surface->bo, w * h,
1479                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
1480                               2, 0);
1481
1482     /* source YUV surface index 4 */
1483     i965_pp_set_surface2_state(ctx, pp_context,
1484                                obj_surface->bo, 0,
1485                                orig_w, orig_w, w,
1486                                0, h,
1487                                SURFACE_FORMAT_PLANAR_420_8, 1,
1488                                4);
1489
1490     /* source STMM surface index 20 */
1491     i965_pp_set_surface_state(ctx, pp_context,
1492                               pp_context->stmm.bo, 0,
1493                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
1494                               20, 1);
1495
1496     /* destination surface */
1497     obj_surface = SURFACE(dst_surface->id);
1498     orig_w = obj_surface->orig_width;
1499     orig_h = obj_surface->orig_height;
1500     w = obj_surface->width;
1501     h = obj_surface->height;
1502
1503     /* destination Y surface index 7 */
1504     i965_pp_set_surface_state(ctx, pp_context,
1505                               obj_surface->bo, 0,
1506                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
1507                               7, 1);
1508
1509     /* destination UV surface index 8 */
1510     i965_pp_set_surface_state(ctx, pp_context,
1511                               obj_surface->bo, w * h,
1512                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
1513                               8, 1);
1514     /* sampler dndi */
1515     dri_bo_map(pp_context->sampler_state_table.bo, True);
1516     assert(pp_context->sampler_state_table.bo->virtual);
1517     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
1518     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
1519
1520     /* sample dndi index 1 */
1521     index = 0;
1522     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
1523     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
1524     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
1525     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
1526
1527     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
1528     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
1529     sampler_dndi[index].dw1.stmm_c2 = 0;
1530     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
1531     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
1532
1533     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 15;   // 0-31
1534     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
1535     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
1536     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
1537
1538     sampler_dndi[index].dw3.maximum_stmm = 128;
1539     sampler_dndi[index].dw3.multipler_for_vecm = 2;
1540     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
1541     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
1542     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
1543
1544     sampler_dndi[index].dw4.sdi_delta = 8;
1545     sampler_dndi[index].dw4.sdi_threshold = 128;
1546     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
1547     sampler_dndi[index].dw4.stmm_shift_up = 0;
1548     sampler_dndi[index].dw4.stmm_shift_down = 0;
1549     sampler_dndi[index].dw4.minimum_stmm = 0;
1550
1551     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
1552     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
1553     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
1554     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
1555
1556     sampler_dndi[index].dw6.dn_enable = 1;
1557     sampler_dndi[index].dw6.di_enable = 1;
1558     sampler_dndi[index].dw6.di_partial = 0;
1559     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
1560     sampler_dndi[index].dw6.dndi_stream_id = 1;
1561     sampler_dndi[index].dw6.dndi_first_frame = 1;
1562     sampler_dndi[index].dw6.progressive_dn = 0;
1563     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
1564     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
1565     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
1566
1567     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
1568     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
1569     sampler_dndi[index].dw7.vdi_walker_enable = 0;
1570     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
1571
1572     dri_bo_unmap(pp_context->sampler_state_table.bo);
1573
1574     /* private function & data */
1575     pp_context->pp_x_steps = pp_dndi_x_steps;
1576     pp_context->pp_y_steps = pp_dndi_y_steps;
1577     pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
1578
1579     pp_static_parameter.grf1.statistics_surface_picth = w / 2;
1580     pp_static_parameter.grf1.r1_6.di.top_field_first = 0;
1581     pp_static_parameter.grf4.r4_2.di.motion_history_coefficient_m2 = 64;
1582     pp_static_parameter.grf4.r4_2.di.motion_history_coefficient_m1 = 192;
1583
1584     pp_inline_parameter.grf5.block_count_x = w / 16;   /* 1 x N */
1585     pp_inline_parameter.grf5.number_blocks = w / 16;
1586     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
1587     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
1588
1589     pp_dndi_context->dest_w = w;
1590     pp_dndi_context->dest_h = h;
1591
1592     dst_surface->flags = I965_SURFACE_FLAG_FRAME;
1593
1594     return VA_STATUS_SUCCESS;
1595 }
1596
1597 static int
1598 pp_dn_x_steps(void *private_context)
1599 {
1600     return 1;
1601 }
1602
1603 static int
1604 pp_dn_y_steps(void *private_context)
1605 {
1606     struct pp_dn_context *pp_dn_context = private_context;
1607
1608     return pp_dn_context->dest_h / 8;
1609 }
1610
1611 static int
1612 pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
1613 {
1614     pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16;
1615     pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8;
1616
1617     return 0;
1618 }
1619
1620 static VAStatus
1621 pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1622                       const struct i965_surface *src_surface,
1623                       const VARectangle *src_rect,
1624                       struct i965_surface *dst_surface,
1625                       const VARectangle *dst_rect,
1626                       void *filter_param)
1627 {
1628     struct i965_driver_data *i965 = i965_driver_data(ctx);
1629     struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->private_context;
1630     struct object_surface *obj_surface;
1631     struct i965_sampler_dndi *sampler_dndi;
1632     VAProcFilterBaseParameterBuffer *dn_filter_param = filter_param;
1633     int index;
1634     int w, h;
1635     int orig_w, orig_h;
1636     int dn_strength = 15;
1637     int dndi_top_first = 1;
1638     int dn_progressive = 0;
1639
1640     if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
1641         dndi_top_first = 1;
1642         dn_progressive = 1;
1643     } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
1644         dndi_top_first = 1;
1645         dn_progressive = 0;
1646     } else {
1647         dndi_top_first = 0;
1648         dn_progressive = 0;
1649     }
1650
1651     if (dn_filter_param) {
1652         int value = dn_filter_param->value;
1653         
1654         if (value > 1.0)
1655             value = 1.0;
1656         
1657         if (value < 0.0)
1658             value = 0.0;
1659
1660         dn_strength = (int)(value * 31.0F);
1661     }
1662
1663     /* surface */
1664     obj_surface = SURFACE(src_surface->id);
1665     orig_w = obj_surface->orig_width;
1666     orig_h = obj_surface->orig_height;
1667     w = obj_surface->width;
1668     h = obj_surface->height;
1669
1670     if (pp_context->stmm.bo == NULL) {
1671         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
1672                                            "STMM surface",
1673                                            w * h,
1674                                            4096);
1675         assert(pp_context->stmm.bo);
1676     }
1677
1678     /* source UV surface index 2 */
1679     i965_pp_set_surface_state(ctx, pp_context,
1680                               obj_surface->bo, w * h,
1681                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
1682                               2, 0);
1683
1684     /* source YUV surface index 4 */
1685     i965_pp_set_surface2_state(ctx, pp_context,
1686                                obj_surface->bo, 0,
1687                                orig_w, orig_w, w,
1688                                0, h,
1689                                SURFACE_FORMAT_PLANAR_420_8, 1,
1690                                4);
1691
1692     /* source STMM surface index 20 */
1693     i965_pp_set_surface_state(ctx, pp_context,
1694                               pp_context->stmm.bo, 0,
1695                               orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
1696                               20, 1);
1697
1698     /* destination surface */
1699     obj_surface = SURFACE(dst_surface->id);
1700     orig_w = obj_surface->orig_width;
1701     orig_h = obj_surface->orig_height;
1702     w = obj_surface->width;
1703     h = obj_surface->height;
1704
1705     /* destination Y surface index 7 */
1706     i965_pp_set_surface_state(ctx, pp_context,
1707                               obj_surface->bo, 0,
1708                               orig_w / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
1709                               7, 1);
1710
1711     /* destination UV surface index 8 */
1712     i965_pp_set_surface_state(ctx, pp_context,
1713                               obj_surface->bo, w * h,
1714                               orig_w / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
1715                               8, 1);
1716     /* sampler dn */
1717     dri_bo_map(pp_context->sampler_state_table.bo, True);
1718     assert(pp_context->sampler_state_table.bo->virtual);
1719     assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
1720     sampler_dndi = pp_context->sampler_state_table.bo->virtual;
1721
1722     /* sample dndi index 1 */
1723     index = 0;
1724     sampler_dndi[index].dw0.denoise_asd_threshold = 0;
1725     sampler_dndi[index].dw0.denoise_history_delta = 8;          // 0-15, default is 8
1726     sampler_dndi[index].dw0.denoise_maximum_history = 128;      // 128-240
1727     sampler_dndi[index].dw0.denoise_stad_threshold = 0;
1728
1729     sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
1730     sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
1731     sampler_dndi[index].dw1.stmm_c2 = 0;
1732     sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
1733     sampler_dndi[index].dw1.temporal_difference_threshold = 16;
1734
1735     sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength;   // 0-31
1736     sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7;    // 0-15
1737     sampler_dndi[index].dw2.denoise_edge_threshold = 7;                 // 0-15
1738     sampler_dndi[index].dw2.good_neighbor_threshold = 7;                // 0-63
1739
1740     sampler_dndi[index].dw3.maximum_stmm = 128;
1741     sampler_dndi[index].dw3.multipler_for_vecm = 2;
1742     sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
1743     sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
1744     sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
1745
1746     sampler_dndi[index].dw4.sdi_delta = 8;
1747     sampler_dndi[index].dw4.sdi_threshold = 128;
1748     sampler_dndi[index].dw4.stmm_output_shift = 7;                      // stmm_max - stmm_min = 2 ^ stmm_output_shift
1749     sampler_dndi[index].dw4.stmm_shift_up = 0;
1750     sampler_dndi[index].dw4.stmm_shift_down = 0;
1751     sampler_dndi[index].dw4.minimum_stmm = 0;
1752
1753     sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
1754     sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
1755     sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
1756     sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
1757
1758     sampler_dndi[index].dw6.dn_enable = 1;
1759     sampler_dndi[index].dw6.di_enable = 0;
1760     sampler_dndi[index].dw6.di_partial = 0;
1761     sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
1762     sampler_dndi[index].dw6.dndi_stream_id = 1;
1763     sampler_dndi[index].dw6.dndi_first_frame = 1;
1764     sampler_dndi[index].dw6.progressive_dn = dn_progressive;
1765     sampler_dndi[index].dw6.fmd_tear_threshold = 32;
1766     sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
1767     sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
1768
1769     sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
1770     sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
1771     sampler_dndi[index].dw7.vdi_walker_enable = 0;
1772     sampler_dndi[index].dw7.column_width_minus1 = w / 16;
1773
1774     dri_bo_unmap(pp_context->sampler_state_table.bo);
1775
1776     /* private function & data */
1777     pp_context->pp_x_steps = pp_dn_x_steps;
1778     pp_context->pp_y_steps = pp_dn_y_steps;
1779     pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
1780
1781     pp_static_parameter.grf1.statistics_surface_picth = w / 2;
1782     pp_static_parameter.grf1.r1_6.di.top_field_first = 0;
1783     pp_static_parameter.grf4.r4_2.di.motion_history_coefficient_m2 = 64;
1784     pp_static_parameter.grf4.r4_2.di.motion_history_coefficient_m1 = 192;
1785
1786     pp_inline_parameter.grf5.block_count_x = w / 16;   /* 1 x N */
1787     pp_inline_parameter.grf5.number_blocks = w / 16;
1788     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
1789     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
1790
1791     pp_dn_context->dest_w = w;
1792     pp_dn_context->dest_h = h;
1793
1794     dst_surface->flags = src_surface->flags;
1795     
1796     return VA_STATUS_SUCCESS;
1797 }
1798
1799 static VAStatus
1800 ironlake_pp_initialize(
1801     VADriverContextP   ctx,
1802     struct i965_post_processing_context *pp_context,
1803     const struct i965_surface *src_surface,
1804     const VARectangle *src_rect,
1805     struct i965_surface *dst_surface,
1806     const VARectangle *dst_rect,
1807     int                pp_index,
1808     void *filter_param
1809 )
1810 {
1811     VAStatus va_status;
1812     struct i965_driver_data *i965 = i965_driver_data(ctx);
1813     struct pp_module *pp_module;
1814     dri_bo *bo;
1815
1816     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
1817     bo = dri_bo_alloc(i965->intel.bufmgr,
1818                       "surface state & binding table",
1819                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
1820                       4096);
1821     assert(bo);
1822     pp_context->surface_state_binding_table.bo = bo;
1823
1824     dri_bo_unreference(pp_context->curbe.bo);
1825     bo = dri_bo_alloc(i965->intel.bufmgr,
1826                       "constant buffer",
1827                       4096, 
1828                       4096);
1829     assert(bo);
1830     pp_context->curbe.bo = bo;
1831
1832     dri_bo_unreference(pp_context->idrt.bo);
1833     bo = dri_bo_alloc(i965->intel.bufmgr, 
1834                       "interface discriptor", 
1835                       sizeof(struct i965_interface_descriptor), 
1836                       4096);
1837     assert(bo);
1838     pp_context->idrt.bo = bo;
1839     pp_context->idrt.num_interface_descriptors = 0;
1840
1841     dri_bo_unreference(pp_context->sampler_state_table.bo);
1842     bo = dri_bo_alloc(i965->intel.bufmgr, 
1843                       "sampler state table", 
1844                       4096,
1845                       4096);
1846     assert(bo);
1847     dri_bo_map(bo, True);
1848     memset(bo->virtual, 0, bo->size);
1849     dri_bo_unmap(bo);
1850     pp_context->sampler_state_table.bo = bo;
1851
1852     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
1853     bo = dri_bo_alloc(i965->intel.bufmgr, 
1854                       "sampler 8x8 state ",
1855                       4096,
1856                       4096);
1857     assert(bo);
1858     pp_context->sampler_state_table.bo_8x8 = bo;
1859
1860     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
1861     bo = dri_bo_alloc(i965->intel.bufmgr, 
1862                       "sampler 8x8 state ",
1863                       4096,
1864                       4096);
1865     assert(bo);
1866     pp_context->sampler_state_table.bo_8x8_uv = bo;
1867
1868     dri_bo_unreference(pp_context->vfe_state.bo);
1869     bo = dri_bo_alloc(i965->intel.bufmgr, 
1870                       "vfe state", 
1871                       sizeof(struct i965_vfe_state), 
1872                       4096);
1873     assert(bo);
1874     pp_context->vfe_state.bo = bo;
1875     
1876     memset(&pp_static_parameter, 0, sizeof(pp_static_parameter));
1877     memset(&pp_inline_parameter, 0, sizeof(pp_inline_parameter));
1878     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
1879     pp_context->current_pp = pp_index;
1880     pp_module = &pp_context->pp_modules[pp_index];
1881     
1882     if (pp_module->initialize)
1883         va_status = pp_module->initialize(ctx, pp_context,
1884                                           src_surface,
1885                                           src_rect,
1886                                           dst_surface,
1887                                           dst_rect,
1888                                           filter_param);
1889     else
1890         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
1891
1892     return va_status;
1893 }
1894
1895 static VAStatus
1896 ironlake_post_processing(
1897     VADriverContextP   ctx,
1898     struct i965_post_processing_context *pp_context,
1899     const struct i965_surface *src_surface,
1900     const VARectangle *src_rect,
1901     struct i965_surface *dst_surface,
1902     const VARectangle *dst_rect,
1903     int                pp_index,
1904     void *filter_param
1905 )
1906 {
1907     VAStatus va_status;
1908
1909     va_status = ironlake_pp_initialize(ctx, pp_context,
1910                                        src_surface,
1911                                        src_rect,
1912                                        dst_surface,
1913                                        dst_rect,
1914                                        pp_index,
1915                                        filter_param);
1916
1917     if (va_status == VA_STATUS_SUCCESS) {
1918         ironlake_pp_states_setup(ctx, pp_context);
1919         ironlake_pp_pipeline_setup(ctx, pp_context);
1920     }
1921
1922     return va_status;
1923 }
1924
1925 static VAStatus
1926 gen6_pp_initialize(
1927     VADriverContextP   ctx,
1928     struct i965_post_processing_context *pp_context,
1929     const struct i965_surface *src_surface,
1930     const VARectangle *src_rect,
1931     struct i965_surface *dst_surface,
1932     const VARectangle *dst_rect,
1933     int                pp_index,
1934     void *filter_param
1935 )
1936 {
1937     VAStatus va_status;
1938     struct i965_driver_data *i965 = i965_driver_data(ctx);
1939     struct pp_module *pp_module;
1940     dri_bo *bo;
1941
1942     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
1943     bo = dri_bo_alloc(i965->intel.bufmgr,
1944                       "surface state & binding table",
1945                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
1946                       4096);
1947     assert(bo);
1948     pp_context->surface_state_binding_table.bo = bo;
1949
1950     dri_bo_unreference(pp_context->curbe.bo);
1951     bo = dri_bo_alloc(i965->intel.bufmgr,
1952                       "constant buffer",
1953                       4096, 
1954                       4096);
1955     assert(bo);
1956     pp_context->curbe.bo = bo;
1957
1958     dri_bo_unreference(pp_context->idrt.bo);
1959     bo = dri_bo_alloc(i965->intel.bufmgr, 
1960                       "interface discriptor", 
1961                       sizeof(struct gen6_interface_descriptor_data), 
1962                       4096);
1963     assert(bo);
1964     pp_context->idrt.bo = bo;
1965     pp_context->idrt.num_interface_descriptors = 0;
1966
1967     dri_bo_unreference(pp_context->sampler_state_table.bo);
1968     bo = dri_bo_alloc(i965->intel.bufmgr, 
1969                       "sampler state table", 
1970                       4096,
1971                       4096);
1972     assert(bo);
1973     dri_bo_map(bo, True);
1974     memset(bo->virtual, 0, bo->size);
1975     dri_bo_unmap(bo);
1976     pp_context->sampler_state_table.bo = bo;
1977
1978     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
1979     bo = dri_bo_alloc(i965->intel.bufmgr, 
1980                       "sampler 8x8 state ",
1981                       4096,
1982                       4096);
1983     assert(bo);
1984     pp_context->sampler_state_table.bo_8x8 = bo;
1985
1986     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
1987     bo = dri_bo_alloc(i965->intel.bufmgr, 
1988                       "sampler 8x8 state ",
1989                       4096,
1990                       4096);
1991     assert(bo);
1992     pp_context->sampler_state_table.bo_8x8_uv = bo;
1993
1994     dri_bo_unreference(pp_context->vfe_state.bo);
1995     bo = dri_bo_alloc(i965->intel.bufmgr, 
1996                       "vfe state", 
1997                       sizeof(struct i965_vfe_state), 
1998                       4096);
1999     assert(bo);
2000     pp_context->vfe_state.bo = bo;
2001     
2002     memset(&pp_static_parameter, 0, sizeof(pp_static_parameter));
2003     memset(&pp_inline_parameter, 0, sizeof(pp_inline_parameter));
2004     assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
2005     pp_context->current_pp = pp_index;
2006     pp_module = &pp_context->pp_modules[pp_index];
2007     
2008     if (pp_module->initialize)
2009         va_status = pp_module->initialize(ctx, pp_context,
2010                                           src_surface,
2011                                           src_rect,
2012                                           dst_surface,
2013                                           dst_rect,
2014                                           filter_param);
2015     else
2016         va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
2017
2018     return va_status;
2019 }
2020
2021 static void
2022 gen6_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
2023 {
2024     struct gen6_interface_descriptor_data *desc;
2025     dri_bo *bo;
2026     int pp_index = pp_context->current_pp;
2027
2028     bo = pp_context->idrt.bo;
2029     dri_bo_map(bo, True);
2030     assert(bo->virtual);
2031     desc = bo->virtual;
2032     memset(desc, 0, sizeof(*desc));
2033     desc->desc0.kernel_start_pointer = 
2034         pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
2035     desc->desc1.single_program_flow = 1;
2036     desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
2037     desc->desc2.sampler_count = 1;      /* 1 - 4 samplers used */
2038     desc->desc2.sampler_state_pointer = 
2039         pp_context->sampler_state_table.bo->offset >> 5;
2040     desc->desc3.binding_table_entry_count = 0;
2041     desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
2042     desc->desc4.constant_urb_entry_read_offset = 0;
2043     desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
2044
2045     dri_bo_emit_reloc(bo,
2046                       I915_GEM_DOMAIN_INSTRUCTION, 0,
2047                       0,
2048                       offsetof(struct gen6_interface_descriptor_data, desc0),
2049                       pp_context->pp_modules[pp_index].kernel.bo);
2050
2051     dri_bo_emit_reloc(bo,
2052                       I915_GEM_DOMAIN_INSTRUCTION, 0,
2053                       desc->desc2.sampler_count << 2,
2054                       offsetof(struct gen6_interface_descriptor_data, desc2),
2055                       pp_context->sampler_state_table.bo);
2056
2057     dri_bo_unmap(bo);
2058     pp_context->idrt.num_interface_descriptors++;
2059 }
2060
2061 static void
2062 gen6_pp_upload_constants(struct i965_post_processing_context *pp_context)
2063 {
2064     unsigned char *constant_buffer;
2065
2066     assert(sizeof(pp_static_parameter) == 128);
2067     dri_bo_map(pp_context->curbe.bo, 1);
2068     assert(pp_context->curbe.bo->virtual);
2069     constant_buffer = pp_context->curbe.bo->virtual;
2070     memcpy(constant_buffer, &pp_static_parameter, sizeof(pp_static_parameter));
2071     dri_bo_unmap(pp_context->curbe.bo);
2072 }
2073
2074 static void
2075 gen6_pp_states_setup(VADriverContextP ctx,
2076                      struct i965_post_processing_context *pp_context)
2077 {
2078     gen6_pp_interface_descriptor_table(pp_context);
2079     gen6_pp_upload_constants(pp_context);
2080 }
2081
2082 static void
2083 gen6_pp_pipeline_select(VADriverContextP ctx,
2084                         struct i965_post_processing_context *pp_context)
2085 {
2086     struct intel_batchbuffer *batch = pp_context->batch;
2087
2088     BEGIN_BATCH(batch, 1);
2089     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
2090     ADVANCE_BATCH(batch);
2091 }
2092
2093 static void
2094 gen6_pp_state_base_address(VADriverContextP ctx,
2095                            struct i965_post_processing_context *pp_context)
2096 {
2097     struct intel_batchbuffer *batch = pp_context->batch;
2098
2099     BEGIN_BATCH(batch, 10);
2100     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
2101     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2102     OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
2103     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2104     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2105     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2106     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2107     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2108     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2109     OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
2110     ADVANCE_BATCH(batch);
2111 }
2112
2113 static void
2114 gen6_pp_vfe_state(VADriverContextP ctx,
2115                   struct i965_post_processing_context *pp_context)
2116 {
2117     struct intel_batchbuffer *batch = pp_context->batch;
2118
2119     BEGIN_BATCH(batch, 8);
2120     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
2121     OUT_BATCH(batch, 0);
2122     OUT_BATCH(batch,
2123               (pp_context->urb.num_vfe_entries - 1) << 16 |
2124               pp_context->urb.num_vfe_entries << 8);
2125     OUT_BATCH(batch, 0);
2126     OUT_BATCH(batch,
2127               (pp_context->urb.size_vfe_entry * 2) << 16 |  /* in 256 bits unit */
2128               (pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 2 - 1));            /* in 256 bits unit */
2129     OUT_BATCH(batch, 0);
2130     OUT_BATCH(batch, 0);
2131     OUT_BATCH(batch, 0);
2132     ADVANCE_BATCH(batch);
2133 }
2134
2135 static void
2136 gen6_pp_curbe_load(VADriverContextP ctx,
2137                    struct i965_post_processing_context *pp_context)
2138 {
2139     struct intel_batchbuffer *batch = pp_context->batch;
2140
2141     assert(pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 512 <= pp_context->curbe.bo->size);
2142
2143     BEGIN_BATCH(batch, 4);
2144     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
2145     OUT_BATCH(batch, 0);
2146     OUT_BATCH(batch,
2147               pp_context->urb.size_cs_entry * pp_context->urb.num_cs_entries * 512);
2148     OUT_RELOC(batch, 
2149               pp_context->curbe.bo,
2150               I915_GEM_DOMAIN_INSTRUCTION, 0,
2151               0);
2152     ADVANCE_BATCH(batch);
2153 }
2154
2155 static void
2156 gen6_interface_descriptor_load(VADriverContextP ctx,
2157                                struct i965_post_processing_context *pp_context)
2158 {
2159     struct intel_batchbuffer *batch = pp_context->batch;
2160
2161     BEGIN_BATCH(batch, 4);
2162     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
2163     OUT_BATCH(batch, 0);
2164     OUT_BATCH(batch,
2165               pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
2166     OUT_RELOC(batch, 
2167               pp_context->idrt.bo,
2168               I915_GEM_DOMAIN_INSTRUCTION, 0,
2169               0);
2170     ADVANCE_BATCH(batch);
2171 }
2172
2173 static void
2174 gen6_pp_object_walker(VADriverContextP ctx,
2175                       struct i965_post_processing_context *pp_context)
2176 {
2177     struct intel_batchbuffer *batch = pp_context->batch;
2178     int x, x_steps, y, y_steps;
2179
2180     x_steps = pp_context->pp_x_steps(&pp_context->private_context);
2181     y_steps = pp_context->pp_y_steps(&pp_context->private_context);
2182
2183     for (y = 0; y < y_steps; y++) {
2184         for (x = 0; x < x_steps; x++) {
2185             if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
2186                 BEGIN_BATCH(batch, 22);
2187                 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 20);
2188                 OUT_BATCH(batch, 0);
2189                 OUT_BATCH(batch, 0); /* no indirect data */
2190                 OUT_BATCH(batch, 0);
2191                 OUT_BATCH(batch, 0); /* scoreboard */
2192                 OUT_BATCH(batch, 0);
2193
2194                 /* inline data grf 5-6 */
2195                 assert(sizeof(pp_inline_parameter) == 64);
2196                 intel_batchbuffer_data(batch, &pp_inline_parameter, sizeof(pp_inline_parameter));
2197
2198                 ADVANCE_BATCH(batch);
2199             }
2200         }
2201     }
2202 }
2203
2204 static void
2205 gen6_pp_pipeline_setup(VADriverContextP ctx,
2206                        struct i965_post_processing_context *pp_context)
2207 {
2208     struct intel_batchbuffer *batch = pp_context->batch;
2209
2210     intel_batchbuffer_start_atomic(batch, 0x1000);
2211     intel_batchbuffer_emit_mi_flush(batch);
2212     gen6_pp_pipeline_select(ctx, pp_context);
2213     gen6_pp_state_base_address(ctx, pp_context);
2214     gen6_pp_curbe_load(ctx, pp_context);
2215     gen6_interface_descriptor_load(ctx, pp_context);
2216     gen6_pp_vfe_state(ctx, pp_context);
2217     gen6_pp_object_walker(ctx, pp_context);
2218     intel_batchbuffer_end_atomic(batch);
2219 }
2220
2221 static VAStatus
2222 gen6_post_processing(
2223     VADriverContextP   ctx,
2224     struct i965_post_processing_context *pp_context,
2225     const struct i965_surface *src_surface,
2226     const VARectangle *src_rect,
2227     struct i965_surface *dst_surface,
2228     const VARectangle *dst_rect,
2229     int                pp_index,
2230     void * filter_param
2231 )
2232 {
2233     VAStatus va_status;
2234     
2235     va_status = gen6_pp_initialize(ctx, pp_context,
2236                                    src_surface,
2237                                    src_rect,
2238                                    dst_surface,
2239                                    dst_rect,
2240                                    pp_index,
2241                                    filter_param);
2242
2243     if (va_status == VA_STATUS_SUCCESS) {
2244         gen6_pp_states_setup(ctx, pp_context);
2245         gen6_pp_pipeline_setup(ctx, pp_context);
2246     }
2247
2248     return va_status;
2249 }
2250
2251 static VAStatus
2252 i965_post_processing_internal(
2253     VADriverContextP   ctx,
2254     struct i965_post_processing_context *pp_context,
2255     const struct i965_surface *src_surface,
2256     const VARectangle *src_rect,
2257     struct i965_surface *dst_surface,
2258     const VARectangle *dst_rect,
2259     int                pp_index,
2260     void *filter_param
2261 )
2262 {
2263     struct i965_driver_data *i965 = i965_driver_data(ctx);
2264     VAStatus va_status;
2265
2266     if (IS_GEN6(i965->intel.device_id) ||
2267         IS_GEN7(i965->intel.device_id))
2268         va_status = gen6_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
2269     else
2270         va_status = ironlake_post_processing(ctx, pp_context, src_surface, src_rect, dst_surface, dst_rect, pp_index, filter_param);
2271     
2272     return va_status;
2273 }
2274
2275 VAStatus 
2276 i965_DestroySurfaces(VADriverContextP ctx,
2277                      VASurfaceID *surface_list,
2278                      int num_surfaces);
2279 VAStatus 
2280 i965_CreateSurfaces(VADriverContextP ctx,
2281                     int width,
2282                     int height,
2283                     int format,
2284                     int num_surfaces,
2285                     VASurfaceID *surfaces);
2286 VASurfaceID
2287 i965_post_processing(
2288     VADriverContextP   ctx,
2289     VASurfaceID        surface,
2290     const VARectangle *src_rect,
2291     const VARectangle *dst_rect,
2292     unsigned int       flags,
2293     int               *has_done_scaling  
2294 )
2295 {
2296     struct i965_driver_data *i965 = i965_driver_data(ctx);
2297     VASurfaceID in_surface_id = surface;
2298     VASurfaceID out_surface_id = VA_INVALID_ID;
2299     
2300     *has_done_scaling = 0;
2301
2302     if (HAS_PP(i965)) {
2303         struct object_surface *obj_surface;
2304         VAStatus status;
2305         struct i965_surface src_surface;
2306         struct i965_surface dst_surface;
2307
2308         obj_surface = SURFACE(in_surface_id);
2309
2310         /* Currently only support post processing for NV12 surface */
2311         if (obj_surface->fourcc != VA_FOURCC('N', 'V', '1', '2'))
2312             return out_surface_id;
2313
2314         if (flags & I965_PP_FLAG_DEINTERLACING) {
2315             status = i965_CreateSurfaces(ctx,
2316                                          obj_surface->orig_width,
2317                                          obj_surface->orig_height,
2318                                          VA_RT_FORMAT_YUV420,
2319                                          1,
2320                                          &out_surface_id);
2321             assert(status == VA_STATUS_SUCCESS);
2322             obj_surface = SURFACE(out_surface_id);
2323             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
2324
2325             src_surface.id = in_surface_id;
2326             src_surface.type = I965_SURFACE_TYPE_SURFACE;
2327             src_surface.flags = (flags & I965_PP_FLAG_DEINTERLACING_TOP_FISRT) ? 
2328                 I965_SURFACE_FLAG_TOP_FIELD_FIRST : I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST;
2329             dst_surface.id = out_surface_id;
2330             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
2331             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
2332
2333             i965_post_processing_internal(ctx, i965->pp_context,
2334                                           &src_surface,
2335                                           src_rect,
2336                                           &dst_surface,
2337                                           dst_rect,
2338                                           PP_NV12_DNDI,
2339                                           NULL);
2340         }
2341
2342         if (flags & I965_PP_FLAG_AVS) {
2343             struct i965_render_state *render_state = &i965->render_state;
2344             struct intel_region *dest_region = render_state->draw_region;
2345
2346             if (out_surface_id != VA_INVALID_ID)
2347                 in_surface_id = out_surface_id;
2348
2349             status = i965_CreateSurfaces(ctx,
2350                                          dest_region->width,
2351                                          dest_region->height,
2352                                          VA_RT_FORMAT_YUV420,
2353                                          1,
2354                                          &out_surface_id);
2355             assert(status == VA_STATUS_SUCCESS);
2356             obj_surface = SURFACE(out_surface_id);
2357             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
2358
2359             src_surface.id = in_surface_id;
2360             src_surface.type = I965_SURFACE_TYPE_SURFACE;
2361             src_surface.flags = I965_SURFACE_FLAG_FRAME;
2362             dst_surface.id = out_surface_id;
2363             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
2364             dst_surface.flags = I965_SURFACE_FLAG_FRAME;
2365
2366             i965_post_processing_internal(ctx, i965->pp_context,
2367                                           &src_surface,
2368                                           src_rect,
2369                                           &dst_surface,
2370                                           dst_rect,
2371                                           PP_NV12_AVS,
2372                                           NULL);
2373
2374             if (in_surface_id != surface)
2375                 i965_DestroySurfaces(ctx, &in_surface_id, 1);
2376                 
2377             *has_done_scaling = 1;
2378         }
2379     }
2380
2381     return out_surface_id;
2382 }       
2383
2384 static VAStatus
2385 i965_image_i420_processing(VADriverContextP ctx,
2386                            const struct i965_surface *src_surface,
2387                            const VARectangle *src_rect,
2388                            struct i965_surface *dst_surface,
2389                            const VARectangle *dst_rect)
2390 {
2391     struct i965_driver_data *i965 = i965_driver_data(ctx);
2392     struct i965_post_processing_context *pp_context = i965->pp_context;
2393     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
2394
2395     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
2396         i965_post_processing_internal(ctx, i965->pp_context,
2397                                       src_surface,
2398                                       src_rect,
2399                                       dst_surface,
2400                                       dst_rect,
2401                                       PP_PL3_LOAD_SAVE_N12,
2402                                       NULL);
2403     } else {
2404         i965_post_processing_internal(ctx, i965->pp_context,
2405                                       src_surface,
2406                                       src_rect,
2407                                       dst_surface,
2408                                       dst_rect,
2409                                       PP_PL3_LOAD_SAVE_PL3,
2410                                       NULL);
2411     }
2412
2413     intel_batchbuffer_flush(pp_context->batch);
2414
2415     return VA_STATUS_SUCCESS;
2416 }
2417
2418 static VAStatus
2419 i965_image_nv12_processing(VADriverContextP ctx,
2420                            const struct i965_surface *src_surface,
2421                            const VARectangle *src_rect,
2422                            struct i965_surface *dst_surface,
2423                            const VARectangle *dst_rect)
2424 {
2425     struct i965_driver_data *i965 = i965_driver_data(ctx);
2426     struct i965_post_processing_context *pp_context = i965->pp_context;
2427     int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
2428
2429     if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
2430         i965_post_processing_internal(ctx, i965->pp_context,
2431                                       src_surface,
2432                                       src_rect,
2433                                       dst_surface,
2434                                       dst_rect,
2435                                       PP_NV12_LOAD_SAVE_N12,
2436                                       NULL);
2437     } else {
2438         i965_post_processing_internal(ctx, i965->pp_context,
2439                                       src_surface,
2440                                       src_rect,
2441                                       dst_surface,
2442                                       dst_rect,
2443                                       PP_NV12_LOAD_SAVE_PL3,
2444                                       NULL);
2445     }
2446
2447     intel_batchbuffer_flush(pp_context->batch);
2448
2449     return VA_STATUS_SUCCESS;
2450 }
2451
2452 VAStatus
2453 i965_image_processing(VADriverContextP ctx,
2454                       const struct i965_surface *src_surface,
2455                       const VARectangle *src_rect,
2456                       struct i965_surface *dst_surface,
2457                       const VARectangle *dst_rect)
2458 {
2459     struct i965_driver_data *i965 = i965_driver_data(ctx);
2460     VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
2461
2462     if (HAS_PP(i965)) {
2463         int fourcc = pp_get_surface_fourcc(ctx, src_surface);
2464
2465         switch (fourcc) {
2466         case VA_FOURCC('Y', 'V', '1', '2'):
2467         case VA_FOURCC('I', '4', '2', '0'):
2468             status = i965_image_i420_processing(ctx,
2469                                                 src_surface,
2470                                                 src_rect,
2471                                                 dst_surface,
2472                                                 dst_rect);
2473             break;
2474
2475         case  VA_FOURCC('N', 'V', '1', '2'):
2476             status = i965_image_nv12_processing(ctx,
2477                                                 src_surface,
2478                                                 src_rect,
2479                                                 dst_surface,
2480                                                 dst_rect);
2481             break;
2482
2483         default:
2484             status = VA_STATUS_ERROR_UNIMPLEMENTED;
2485             break;
2486         }
2487     }
2488
2489     return status;
2490 }       
2491
2492 static void
2493 i965_post_processing_context_finalize(struct i965_post_processing_context *pp_context)
2494 {
2495     int i;
2496
2497     dri_bo_unreference(pp_context->surface_state_binding_table.bo);
2498     pp_context->surface_state_binding_table.bo = NULL;
2499
2500     dri_bo_unreference(pp_context->curbe.bo);
2501     pp_context->curbe.bo = NULL;
2502
2503     dri_bo_unreference(pp_context->sampler_state_table.bo);
2504     pp_context->sampler_state_table.bo = NULL;
2505
2506     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
2507     pp_context->sampler_state_table.bo_8x8 = NULL;
2508
2509     dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
2510     pp_context->sampler_state_table.bo_8x8_uv = NULL;
2511
2512     dri_bo_unreference(pp_context->idrt.bo);
2513     pp_context->idrt.bo = NULL;
2514     pp_context->idrt.num_interface_descriptors = 0;
2515
2516     dri_bo_unreference(pp_context->vfe_state.bo);
2517     pp_context->vfe_state.bo = NULL;
2518
2519     dri_bo_unreference(pp_context->stmm.bo);
2520     pp_context->stmm.bo = NULL;
2521
2522     for (i = 0; i < NUM_PP_MODULES; i++) {
2523         struct pp_module *pp_module = &pp_context->pp_modules[i];
2524
2525         dri_bo_unreference(pp_module->kernel.bo);
2526         pp_module->kernel.bo = NULL;
2527     }
2528
2529 }
2530
2531 Bool
2532 i965_post_processing_terminate(VADriverContextP ctx)
2533 {
2534     struct i965_driver_data *i965 = i965_driver_data(ctx);
2535     struct i965_post_processing_context *pp_context = i965->pp_context;
2536
2537     if (pp_context) {
2538         i965_post_processing_context_finalize(pp_context);
2539         free(pp_context);
2540     }
2541
2542     i965->pp_context = NULL;
2543
2544     return True;
2545 }
2546
2547 static void
2548 i965_post_processing_context_init(VADriverContextP ctx,
2549                                   struct i965_post_processing_context *pp_context,
2550                                   struct intel_batchbuffer *batch)
2551 {
2552     struct i965_driver_data *i965 = i965_driver_data(ctx);
2553     int i;
2554
2555     pp_context->urb.size = URB_SIZE((&i965->intel));
2556     pp_context->urb.num_vfe_entries = 32;
2557     pp_context->urb.size_vfe_entry = 1;     /* in 512 bits unit */
2558     pp_context->urb.num_cs_entries = 1;
2559     pp_context->urb.size_cs_entry = 2;      /* in 512 bits unit */
2560     pp_context->urb.vfe_start = 0;
2561     pp_context->urb.cs_start = pp_context->urb.vfe_start + 
2562         pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
2563     assert(pp_context->urb.cs_start + 
2564            pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= URB_SIZE((&i965->intel)));
2565
2566     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
2567     assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
2568
2569     if (IS_GEN6(i965->intel.device_id) ||
2570         IS_GEN7(i965->intel.device_id))
2571         memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
2572     else if (IS_IRONLAKE(i965->intel.device_id))
2573         memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
2574
2575     for (i = 0; i < NUM_PP_MODULES; i++) {
2576         struct pp_module *pp_module = &pp_context->pp_modules[i];
2577         dri_bo_unreference(pp_module->kernel.bo);
2578         if (pp_module->kernel.bin) {
2579             pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
2580                                                 pp_module->kernel.name,
2581                                                 pp_module->kernel.size,
2582                                                 4096);
2583             assert(pp_module->kernel.bo);
2584             dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
2585         } else {
2586             pp_module->kernel.bo = NULL;
2587         }
2588     }
2589
2590     pp_context->batch = batch;
2591 }
2592
2593 Bool
2594 i965_post_processing_init(VADriverContextP ctx)
2595 {
2596     struct i965_driver_data *i965 = i965_driver_data(ctx);
2597     struct i965_post_processing_context *pp_context = i965->pp_context;
2598
2599     if (HAS_PP(i965)) {
2600         if (pp_context == NULL) {
2601             pp_context = calloc(1, sizeof(*pp_context));
2602             i965_post_processing_context_init(ctx, pp_context, i965->batch);
2603             i965->pp_context = pp_context;
2604         }
2605     }
2606
2607     return True;
2608 }
2609
2610 static const int procfilter_to_pp_flag[10] = {
2611     PP_NULL,    /* VAProcFilterNone */
2612     PP_NULL,    /* VAProcFilterDering */
2613     PP_NULL,    /* VAProcFilterDeblocking */
2614     PP_NV12_DN, /* VAProcFilterNoiseReduction */
2615     PP_NV12_DNDI, /* VAProcFilterDeinterlacing */
2616     PP_NULL,    /* VAProcFilterSharpening */
2617     PP_NULL,    /* VAProcFilterColorEnhancement */
2618     PP_NULL,    /* VAProcFilterProcAmp */
2619     PP_NULL,    /* VAProcFilterComposition */
2620     PP_NULL,    /* VAProcFilterFrameRateConversion */
2621 };
2622
2623 static const int proc_frame_to_pp_frame[3] = {
2624     I965_SURFACE_FLAG_FRAME,
2625     I965_SURFACE_FLAG_TOP_FIELD_FIRST,
2626     I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST
2627 };
2628
2629 static void 
2630 i965_proc_picture(VADriverContextP ctx, 
2631                   VAProfile profile, 
2632                   union codec_state *codec_state,
2633                   struct hw_context *hw_context)
2634 {
2635     struct i965_driver_data *i965 = i965_driver_data(ctx);
2636     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
2637     struct proc_state *proc_state = &codec_state->proc;
2638     VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
2639     VAProcInputParameterBuffer *input_param = (VAProcInputParameterBuffer *)proc_state->input_param->buffer;
2640     struct object_surface *obj_surface;
2641     struct i965_surface src_surface, dst_surface;
2642     VAStatus status;
2643     int i;
2644     VASurfaceID tmp_surfaces[VA_PROC_PIPELINE_MAX_NUM_FILTERS];
2645     int num_tmp_surfaces = 0;
2646
2647     assert(input_param->surface != VA_INVALID_ID);
2648     assert(proc_state->current_render_target != VA_INVALID_ID);
2649
2650     obj_surface = SURFACE(proc_state->current_render_target);
2651     i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
2652
2653     obj_surface = SURFACE(input_param->surface);
2654     assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
2655
2656     src_surface.id = input_param->surface;
2657     src_surface.type = I965_SURFACE_TYPE_SURFACE;
2658     src_surface.flags = proc_frame_to_pp_frame[input_param->flags];
2659     
2660     for (i = 0; i < VA_PROC_PIPELINE_MAX_NUM_FILTERS; i++) {
2661         VAProcFilterType filter_type = pipeline_param->filter_pipeline[i];
2662         VASurfaceID out_surface_id = VA_INVALID_ID;
2663         void *filter_param = NULL;
2664
2665         if (procfilter_to_pp_flag[filter_type] != PP_NULL) {
2666             if (proc_state->filter_param[filter_type])
2667                 filter_param = proc_state->filter_param[filter_type]->buffer;
2668
2669             status = i965_CreateSurfaces(ctx,
2670                                          obj_surface->orig_width,
2671                                          obj_surface->orig_height,
2672                                          VA_RT_FORMAT_YUV420,
2673                                          1,
2674                                          &out_surface_id);
2675             assert(status == VA_STATUS_SUCCESS);
2676             tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
2677             obj_surface = SURFACE(out_surface_id);
2678             i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
2679             dst_surface.id = out_surface_id;
2680             dst_surface.type = I965_SURFACE_TYPE_SURFACE;
2681             status = i965_post_processing_internal(ctx, &proc_context->pp_context,
2682                                                    &src_surface,
2683                                                    &input_param->region,
2684                                                    &dst_surface,
2685                                                    &input_param->region,
2686                                                    procfilter_to_pp_flag[filter_type],
2687                                                    filter_param);
2688
2689             if (status == VA_STATUS_SUCCESS) {
2690                 src_surface.id = dst_surface.id;
2691                 src_surface.type = dst_surface.type;
2692                 src_surface.flags = dst_surface.flags;
2693             }
2694         }
2695     }
2696
2697     dst_surface.id = proc_state->current_render_target;
2698     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
2699     i965_post_processing_internal(ctx, &proc_context->pp_context,
2700                                   &src_surface,
2701                                   &input_param->region,
2702                                   &dst_surface,
2703                                   &pipeline_param->output_region,
2704                                   PP_NV12_AVS,
2705                                   NULL);
2706
2707     if (num_tmp_surfaces)
2708         i965_DestroySurfaces(ctx,
2709                              tmp_surfaces,
2710                              num_tmp_surfaces);
2711
2712     intel_batchbuffer_flush(hw_context->batch);
2713 }
2714
2715 static void
2716 i965_proc_context_destroy(void *hw_context)
2717 {
2718     struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
2719
2720     i965_post_processing_context_finalize(&proc_context->pp_context);
2721     intel_batchbuffer_free(proc_context->base.batch);
2722     free(proc_context);
2723 }
2724
2725 struct hw_context *
2726 i965_proc_context_init(VADriverContextP ctx, VAProfile profile)
2727 {
2728     struct intel_driver_data *intel = intel_driver_data(ctx);
2729     struct i965_proc_context *proc_context = calloc(1, sizeof(struct i965_proc_context));
2730
2731     proc_context->base.destroy = i965_proc_context_destroy;
2732     proc_context->base.run = i965_proc_picture;
2733     proc_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER);
2734     i965_post_processing_context_init(ctx, &proc_context->pp_context, proc_context->base.batch);
2735
2736     return (struct hw_context *)proc_context;
2737 }