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