2 * Copyright © 2010 Intel Corporation
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Xiang Haihao <haihao.xiang@intel.com>
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"
44 vpp_surface_convert(VADriverContextP ctx,
45 struct object_surface *src_obj_surf,
46 struct object_surface *dst_obj_surf);
48 #define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
50 #define SURFACE_STATE_PADDED_SIZE MAX(SURFACE_STATE_PADDED_SIZE_GEN8,\
51 MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7))
53 #define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index)
54 #define BINDING_TABLE_OFFSET SURFACE_STATE_OFFSET(MAX_PP_SURFACES)
56 #define GPU_ASM_BLOCK_WIDTH 16
57 #define GPU_ASM_BLOCK_HEIGHT 8
58 #define GPU_ASM_X_OFFSET_ALIGNMENT 4
60 #define VA_STATUS_SUCCESS_1 0xFFFFFFFE
62 static const uint32_t pp_null_gen5[][4] = {
63 #include "shaders/post_processing/gen5_6/null.g4b.gen5"
66 static const uint32_t pp_nv12_load_save_nv12_gen5[][4] = {
67 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g4b.gen5"
70 static const uint32_t pp_nv12_load_save_pl3_gen5[][4] = {
71 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g4b.gen5"
74 static const uint32_t pp_pl3_load_save_nv12_gen5[][4] = {
75 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g4b.gen5"
78 static const uint32_t pp_pl3_load_save_pl3_gen5[][4] = {
79 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g4b.gen5"
82 static const uint32_t pp_nv12_scaling_gen5[][4] = {
83 #include "shaders/post_processing/gen5_6/nv12_scaling_nv12.g4b.gen5"
86 static const uint32_t pp_nv12_avs_gen5[][4] = {
87 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g4b.gen5"
90 static const uint32_t pp_nv12_dndi_gen5[][4] = {
91 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g4b.gen5"
94 static const uint32_t pp_nv12_dn_gen5[][4] = {
95 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g4b.gen5"
98 static const uint32_t pp_nv12_load_save_pa_gen5[][4] = {
99 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g4b.gen5"
102 static const uint32_t pp_pl3_load_save_pa_gen5[][4] = {
103 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g4b.gen5"
106 static const uint32_t pp_pa_load_save_nv12_gen5[][4] = {
107 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g4b.gen5"
110 static const uint32_t pp_pa_load_save_pl3_gen5[][4] = {
111 #include "shaders/post_processing/gen5_6/pa_load_save_pl3.g4b.gen5"
114 static const uint32_t pp_pa_load_save_pa_gen5[][4] = {
115 #include "shaders/post_processing/gen5_6/pa_load_save_pa.g4b.gen5"
118 static const uint32_t pp_rgbx_load_save_nv12_gen5[][4] = {
119 #include "shaders/post_processing/gen5_6/rgbx_load_save_nv12.g4b.gen5"
122 static const uint32_t pp_nv12_load_save_rgbx_gen5[][4] = {
123 #include "shaders/post_processing/gen5_6/nv12_load_save_rgbx.g4b.gen5"
126 static VAStatus pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
127 const struct i965_surface *src_surface,
128 const VARectangle *src_rect,
129 struct i965_surface *dst_surface,
130 const VARectangle *dst_rect,
133 pp_nv12_avs_initialize(VADriverContextP ctx,
134 struct i965_post_processing_context *pp_context,
135 const struct i965_surface *src_surface, const VARectangle *src_rect,
136 struct i965_surface *dst_surface, const VARectangle *dst_rect,
138 static VAStatus pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
139 const struct i965_surface *src_surface,
140 const VARectangle *src_rect,
141 struct i965_surface *dst_surface,
142 const VARectangle *dst_rect,
144 static VAStatus gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
145 const struct i965_surface *src_surface,
146 const VARectangle *src_rect,
147 struct i965_surface *dst_surface,
148 const VARectangle *dst_rect,
150 static VAStatus pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
151 const struct i965_surface *src_surface,
152 const VARectangle *src_rect,
153 struct i965_surface *dst_surface,
154 const VARectangle *dst_rect,
156 static VAStatus pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
157 const struct i965_surface *src_surface,
158 const VARectangle *src_rect,
159 struct i965_surface *dst_surface,
160 const VARectangle *dst_rect,
162 static VAStatus pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
163 const struct i965_surface *src_surface,
164 const VARectangle *src_rect,
165 struct i965_surface *dst_surface,
166 const VARectangle *dst_rect,
169 static struct pp_module pp_modules_gen5[] = {
172 "NULL module (for testing)",
175 sizeof(pp_null_gen5),
185 PP_NV12_LOAD_SAVE_N12,
186 pp_nv12_load_save_nv12_gen5,
187 sizeof(pp_nv12_load_save_nv12_gen5),
191 pp_plx_load_save_plx_initialize,
197 PP_NV12_LOAD_SAVE_PL3,
198 pp_nv12_load_save_pl3_gen5,
199 sizeof(pp_nv12_load_save_pl3_gen5),
203 pp_plx_load_save_plx_initialize,
209 PP_PL3_LOAD_SAVE_N12,
210 pp_pl3_load_save_nv12_gen5,
211 sizeof(pp_pl3_load_save_nv12_gen5),
215 pp_plx_load_save_plx_initialize,
221 PP_PL3_LOAD_SAVE_PL3,
222 pp_pl3_load_save_pl3_gen5,
223 sizeof(pp_pl3_load_save_pl3_gen5),
227 pp_plx_load_save_plx_initialize
232 "NV12 Scaling module",
234 pp_nv12_scaling_gen5,
235 sizeof(pp_nv12_scaling_gen5),
239 pp_nv12_scaling_initialize,
247 sizeof(pp_nv12_avs_gen5),
251 pp_nv12_avs_initialize,
259 sizeof(pp_nv12_dndi_gen5),
263 pp_nv12_dndi_initialize,
271 sizeof(pp_nv12_dn_gen5),
275 pp_nv12_dn_initialize,
281 PP_NV12_LOAD_SAVE_PA,
282 pp_nv12_load_save_pa_gen5,
283 sizeof(pp_nv12_load_save_pa_gen5),
287 pp_plx_load_save_plx_initialize,
294 pp_pl3_load_save_pa_gen5,
295 sizeof(pp_pl3_load_save_pa_gen5),
299 pp_plx_load_save_plx_initialize,
305 PP_PA_LOAD_SAVE_NV12,
306 pp_pa_load_save_nv12_gen5,
307 sizeof(pp_pa_load_save_nv12_gen5),
311 pp_plx_load_save_plx_initialize,
318 pp_pa_load_save_pl3_gen5,
319 sizeof(pp_pa_load_save_pl3_gen5),
323 pp_plx_load_save_plx_initialize,
330 pp_pa_load_save_pa_gen5,
331 sizeof(pp_pa_load_save_pa_gen5),
335 pp_plx_load_save_plx_initialize,
341 PP_RGBX_LOAD_SAVE_NV12,
342 pp_rgbx_load_save_nv12_gen5,
343 sizeof(pp_rgbx_load_save_nv12_gen5),
347 pp_plx_load_save_plx_initialize,
353 PP_NV12_LOAD_SAVE_RGBX,
354 pp_nv12_load_save_rgbx_gen5,
355 sizeof(pp_nv12_load_save_rgbx_gen5),
359 pp_plx_load_save_plx_initialize,
363 static const uint32_t pp_null_gen6[][4] = {
364 #include "shaders/post_processing/gen5_6/null.g6b"
367 static const uint32_t pp_nv12_load_save_nv12_gen6[][4] = {
368 #include "shaders/post_processing/gen5_6/nv12_load_save_nv12.g6b"
371 static const uint32_t pp_nv12_load_save_pl3_gen6[][4] = {
372 #include "shaders/post_processing/gen5_6/nv12_load_save_pl3.g6b"
375 static const uint32_t pp_pl3_load_save_nv12_gen6[][4] = {
376 #include "shaders/post_processing/gen5_6/pl3_load_save_nv12.g6b"
379 static const uint32_t pp_pl3_load_save_pl3_gen6[][4] = {
380 #include "shaders/post_processing/gen5_6/pl3_load_save_pl3.g6b"
383 static const uint32_t pp_nv12_scaling_gen6[][4] = {
384 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
387 static const uint32_t pp_nv12_avs_gen6[][4] = {
388 #include "shaders/post_processing/gen5_6/nv12_avs_nv12.g6b"
391 static const uint32_t pp_nv12_dndi_gen6[][4] = {
392 #include "shaders/post_processing/gen5_6/nv12_dndi_nv12.g6b"
395 static const uint32_t pp_nv12_dn_gen6[][4] = {
396 #include "shaders/post_processing/gen5_6/nv12_dn_nv12.g6b"
399 static const uint32_t pp_nv12_load_save_pa_gen6[][4] = {
400 #include "shaders/post_processing/gen5_6/nv12_load_save_pa.g6b"
403 static const uint32_t pp_pl3_load_save_pa_gen6[][4] = {
404 #include "shaders/post_processing/gen5_6/pl3_load_save_pa.g6b"
407 static const uint32_t pp_pa_load_save_nv12_gen6[][4] = {
408 #include "shaders/post_processing/gen5_6/pa_load_save_nv12.g6b"
411 static const uint32_t pp_pa_load_save_pl3_gen6[][4] = {
412 #include "shaders/post_processing/gen5_6/pa_load_save_pl3.g6b"
415 static const uint32_t pp_pa_load_save_pa_gen6[][4] = {
416 #include "shaders/post_processing/gen5_6/pa_load_save_pa.g6b"
419 static const uint32_t pp_rgbx_load_save_nv12_gen6[][4] = {
420 #include "shaders/post_processing/gen5_6/rgbx_load_save_nv12.g6b"
423 static const uint32_t pp_nv12_load_save_rgbx_gen6[][4] = {
424 #include "shaders/post_processing/gen5_6/nv12_load_save_rgbx.g6b"
427 static struct pp_module pp_modules_gen6[] = {
430 "NULL module (for testing)",
433 sizeof(pp_null_gen6),
443 PP_NV12_LOAD_SAVE_N12,
444 pp_nv12_load_save_nv12_gen6,
445 sizeof(pp_nv12_load_save_nv12_gen6),
449 pp_plx_load_save_plx_initialize,
455 PP_NV12_LOAD_SAVE_PL3,
456 pp_nv12_load_save_pl3_gen6,
457 sizeof(pp_nv12_load_save_pl3_gen6),
461 pp_plx_load_save_plx_initialize,
467 PP_PL3_LOAD_SAVE_N12,
468 pp_pl3_load_save_nv12_gen6,
469 sizeof(pp_pl3_load_save_nv12_gen6),
473 pp_plx_load_save_plx_initialize,
479 PP_PL3_LOAD_SAVE_PL3,
480 pp_pl3_load_save_pl3_gen6,
481 sizeof(pp_pl3_load_save_pl3_gen6),
485 pp_plx_load_save_plx_initialize,
490 "NV12 Scaling module",
492 pp_nv12_scaling_gen6,
493 sizeof(pp_nv12_scaling_gen6),
497 gen6_nv12_scaling_initialize,
505 sizeof(pp_nv12_avs_gen6),
509 pp_nv12_avs_initialize,
517 sizeof(pp_nv12_dndi_gen6),
521 pp_nv12_dndi_initialize,
529 sizeof(pp_nv12_dn_gen6),
533 pp_nv12_dn_initialize,
538 PP_NV12_LOAD_SAVE_PA,
539 pp_nv12_load_save_pa_gen6,
540 sizeof(pp_nv12_load_save_pa_gen6),
544 pp_plx_load_save_plx_initialize,
551 pp_pl3_load_save_pa_gen6,
552 sizeof(pp_pl3_load_save_pa_gen6),
556 pp_plx_load_save_plx_initialize,
562 PP_PA_LOAD_SAVE_NV12,
563 pp_pa_load_save_nv12_gen6,
564 sizeof(pp_pa_load_save_nv12_gen6),
568 pp_plx_load_save_plx_initialize,
575 pp_pa_load_save_pl3_gen6,
576 sizeof(pp_pa_load_save_pl3_gen6),
580 pp_plx_load_save_plx_initialize,
587 pp_pa_load_save_pa_gen6,
588 sizeof(pp_pa_load_save_pa_gen6),
592 pp_plx_load_save_plx_initialize,
598 PP_RGBX_LOAD_SAVE_NV12,
599 pp_rgbx_load_save_nv12_gen6,
600 sizeof(pp_rgbx_load_save_nv12_gen6),
604 pp_plx_load_save_plx_initialize,
610 PP_NV12_LOAD_SAVE_RGBX,
611 pp_nv12_load_save_rgbx_gen6,
612 sizeof(pp_nv12_load_save_rgbx_gen6),
616 pp_plx_load_save_plx_initialize,
620 static const uint32_t pp_null_gen7[][4] = {
623 static const uint32_t pp_nv12_load_save_nv12_gen7[][4] = {
624 #include "shaders/post_processing/gen7/pl2_to_pl2.g7b"
627 static const uint32_t pp_nv12_load_save_pl3_gen7[][4] = {
628 #include "shaders/post_processing/gen7/pl2_to_pl3.g7b"
631 static const uint32_t pp_pl3_load_save_nv12_gen7[][4] = {
632 #include "shaders/post_processing/gen7/pl3_to_pl2.g7b"
635 static const uint32_t pp_pl3_load_save_pl3_gen7[][4] = {
636 #include "shaders/post_processing/gen7/pl3_to_pl3.g7b"
639 static const uint32_t pp_nv12_scaling_gen7[][4] = {
640 #include "shaders/post_processing/gen7/avs.g7b"
643 static const uint32_t pp_nv12_avs_gen7[][4] = {
644 #include "shaders/post_processing/gen7/avs.g7b"
647 static const uint32_t pp_nv12_dndi_gen7[][4] = {
648 #include "shaders/post_processing/gen7/dndi.g7b"
651 static const uint32_t pp_nv12_dn_gen7[][4] = {
652 #include "shaders/post_processing/gen7/nv12_dn_nv12.g7b"
654 static const uint32_t pp_nv12_load_save_pa_gen7[][4] = {
655 #include "shaders/post_processing/gen7/pl2_to_pa.g7b"
657 static const uint32_t pp_pl3_load_save_pa_gen7[][4] = {
658 #include "shaders/post_processing/gen7/pl3_to_pa.g7b"
660 static const uint32_t pp_pa_load_save_nv12_gen7[][4] = {
661 #include "shaders/post_processing/gen7/pa_to_pl2.g7b"
663 static const uint32_t pp_pa_load_save_pl3_gen7[][4] = {
664 #include "shaders/post_processing/gen7/pa_to_pl3.g7b"
666 static const uint32_t pp_pa_load_save_pa_gen7[][4] = {
667 #include "shaders/post_processing/gen7/pa_to_pa.g7b"
669 static const uint32_t pp_rgbx_load_save_nv12_gen7[][4] = {
670 #include "shaders/post_processing/gen7/rgbx_to_nv12.g7b"
672 static const uint32_t pp_nv12_load_save_rgbx_gen7[][4] = {
673 #include "shaders/post_processing/gen7/pl2_to_rgbx.g7b"
676 static VAStatus gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
677 const struct i965_surface *src_surface,
678 const VARectangle *src_rect,
679 struct i965_surface *dst_surface,
680 const VARectangle *dst_rect,
682 static VAStatus gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
683 const struct i965_surface *src_surface,
684 const VARectangle *src_rect,
685 struct i965_surface *dst_surface,
686 const VARectangle *dst_rect,
688 static VAStatus gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
689 const struct i965_surface *src_surface,
690 const VARectangle *src_rect,
691 struct i965_surface *dst_surface,
692 const VARectangle *dst_rect,
695 static struct pp_module pp_modules_gen7[] = {
698 "NULL module (for testing)",
701 sizeof(pp_null_gen7),
711 PP_NV12_LOAD_SAVE_N12,
712 pp_nv12_load_save_nv12_gen7,
713 sizeof(pp_nv12_load_save_nv12_gen7),
717 gen7_pp_plx_avs_initialize,
723 PP_NV12_LOAD_SAVE_PL3,
724 pp_nv12_load_save_pl3_gen7,
725 sizeof(pp_nv12_load_save_pl3_gen7),
729 gen7_pp_plx_avs_initialize,
735 PP_PL3_LOAD_SAVE_N12,
736 pp_pl3_load_save_nv12_gen7,
737 sizeof(pp_pl3_load_save_nv12_gen7),
741 gen7_pp_plx_avs_initialize,
747 PP_PL3_LOAD_SAVE_PL3,
748 pp_pl3_load_save_pl3_gen7,
749 sizeof(pp_pl3_load_save_pl3_gen7),
753 gen7_pp_plx_avs_initialize,
758 "NV12 Scaling module",
760 pp_nv12_scaling_gen7,
761 sizeof(pp_nv12_scaling_gen7),
765 gen7_pp_plx_avs_initialize,
773 sizeof(pp_nv12_avs_gen7),
777 gen7_pp_plx_avs_initialize,
785 sizeof(pp_nv12_dndi_gen7),
789 gen7_pp_nv12_dndi_initialize,
797 sizeof(pp_nv12_dn_gen7),
801 gen7_pp_nv12_dn_initialize,
806 PP_NV12_LOAD_SAVE_PA,
807 pp_nv12_load_save_pa_gen7,
808 sizeof(pp_nv12_load_save_pa_gen7),
812 gen7_pp_plx_avs_initialize,
819 pp_pl3_load_save_pa_gen7,
820 sizeof(pp_pl3_load_save_pa_gen7),
824 gen7_pp_plx_avs_initialize,
830 PP_PA_LOAD_SAVE_NV12,
831 pp_pa_load_save_nv12_gen7,
832 sizeof(pp_pa_load_save_nv12_gen7),
836 gen7_pp_plx_avs_initialize,
843 pp_pa_load_save_pl3_gen7,
844 sizeof(pp_pa_load_save_pl3_gen7),
848 gen7_pp_plx_avs_initialize,
855 pp_pa_load_save_pa_gen7,
856 sizeof(pp_pa_load_save_pa_gen7),
860 gen7_pp_plx_avs_initialize,
866 PP_RGBX_LOAD_SAVE_NV12,
867 pp_rgbx_load_save_nv12_gen7,
868 sizeof(pp_rgbx_load_save_nv12_gen7),
872 gen7_pp_plx_avs_initialize,
878 PP_NV12_LOAD_SAVE_RGBX,
879 pp_nv12_load_save_rgbx_gen7,
880 sizeof(pp_nv12_load_save_rgbx_gen7),
884 gen7_pp_plx_avs_initialize,
889 static const uint32_t pp_null_gen75[][4] = {
892 static const uint32_t pp_nv12_load_save_nv12_gen75[][4] = {
893 #include "shaders/post_processing/gen7/pl2_to_pl2.g75b"
896 static const uint32_t pp_nv12_load_save_pl3_gen75[][4] = {
897 #include "shaders/post_processing/gen7/pl2_to_pl3.g75b"
900 static const uint32_t pp_pl3_load_save_nv12_gen75[][4] = {
901 #include "shaders/post_processing/gen7/pl3_to_pl2.g75b"
904 static const uint32_t pp_pl3_load_save_pl3_gen75[][4] = {
905 #include "shaders/post_processing/gen7/pl3_to_pl3.g75b"
908 static const uint32_t pp_nv12_scaling_gen75[][4] = {
909 #include "shaders/post_processing/gen7/avs.g75b"
912 static const uint32_t pp_nv12_avs_gen75[][4] = {
913 #include "shaders/post_processing/gen7/avs.g75b"
916 static const uint32_t pp_nv12_dndi_gen75[][4] = {
917 // #include "shaders/post_processing/gen7/dndi.g75b"
920 static const uint32_t pp_nv12_dn_gen75[][4] = {
921 // #include "shaders/post_processing/gen7/nv12_dn_nv12.g75b"
923 static const uint32_t pp_nv12_load_save_pa_gen75[][4] = {
924 #include "shaders/post_processing/gen7/pl2_to_pa.g75b"
926 static const uint32_t pp_pl3_load_save_pa_gen75[][4] = {
927 #include "shaders/post_processing/gen7/pl3_to_pa.g75b"
929 static const uint32_t pp_pa_load_save_nv12_gen75[][4] = {
930 #include "shaders/post_processing/gen7/pa_to_pl2.g75b"
932 static const uint32_t pp_pa_load_save_pl3_gen75[][4] = {
933 #include "shaders/post_processing/gen7/pa_to_pl3.g75b"
935 static const uint32_t pp_pa_load_save_pa_gen75[][4] = {
936 #include "shaders/post_processing/gen7/pa_to_pa.g75b"
938 static const uint32_t pp_rgbx_load_save_nv12_gen75[][4] = {
939 #include "shaders/post_processing/gen7/rgbx_to_nv12.g75b"
941 static const uint32_t pp_nv12_load_save_rgbx_gen75[][4] = {
942 #include "shaders/post_processing/gen7/pl2_to_rgbx.g75b"
945 static struct pp_module pp_modules_gen75[] = {
948 "NULL module (for testing)",
951 sizeof(pp_null_gen75),
961 PP_NV12_LOAD_SAVE_N12,
962 pp_nv12_load_save_nv12_gen75,
963 sizeof(pp_nv12_load_save_nv12_gen75),
967 gen7_pp_plx_avs_initialize,
973 PP_NV12_LOAD_SAVE_PL3,
974 pp_nv12_load_save_pl3_gen75,
975 sizeof(pp_nv12_load_save_pl3_gen75),
979 gen7_pp_plx_avs_initialize,
985 PP_PL3_LOAD_SAVE_N12,
986 pp_pl3_load_save_nv12_gen75,
987 sizeof(pp_pl3_load_save_nv12_gen75),
991 gen7_pp_plx_avs_initialize,
997 PP_PL3_LOAD_SAVE_PL3,
998 pp_pl3_load_save_pl3_gen75,
999 sizeof(pp_pl3_load_save_pl3_gen75),
1003 gen7_pp_plx_avs_initialize,
1008 "NV12 Scaling module",
1010 pp_nv12_scaling_gen75,
1011 sizeof(pp_nv12_scaling_gen75),
1015 gen7_pp_plx_avs_initialize,
1023 sizeof(pp_nv12_avs_gen75),
1027 gen7_pp_plx_avs_initialize,
1035 sizeof(pp_nv12_dndi_gen75),
1039 gen7_pp_nv12_dn_initialize,
1047 sizeof(pp_nv12_dn_gen75),
1051 gen7_pp_nv12_dn_initialize,
1057 PP_NV12_LOAD_SAVE_PA,
1058 pp_nv12_load_save_pa_gen75,
1059 sizeof(pp_nv12_load_save_pa_gen75),
1063 gen7_pp_plx_avs_initialize,
1069 PP_PL3_LOAD_SAVE_PA,
1070 pp_pl3_load_save_pa_gen75,
1071 sizeof(pp_pl3_load_save_pa_gen75),
1075 gen7_pp_plx_avs_initialize,
1081 PP_PA_LOAD_SAVE_NV12,
1082 pp_pa_load_save_nv12_gen75,
1083 sizeof(pp_pa_load_save_nv12_gen75),
1087 gen7_pp_plx_avs_initialize,
1093 PP_PA_LOAD_SAVE_PL3,
1094 pp_pa_load_save_pl3_gen75,
1095 sizeof(pp_pa_load_save_pl3_gen75),
1099 gen7_pp_plx_avs_initialize,
1106 pp_pa_load_save_pa_gen75,
1107 sizeof(pp_pa_load_save_pa_gen75),
1111 gen7_pp_plx_avs_initialize,
1117 PP_RGBX_LOAD_SAVE_NV12,
1118 pp_rgbx_load_save_nv12_gen75,
1119 sizeof(pp_rgbx_load_save_nv12_gen75),
1123 gen7_pp_plx_avs_initialize,
1129 PP_NV12_LOAD_SAVE_RGBX,
1130 pp_nv12_load_save_rgbx_gen75,
1131 sizeof(pp_nv12_load_save_rgbx_gen75),
1135 gen7_pp_plx_avs_initialize,
1141 pp_dndi_frame_store_reset(DNDIFrameStore *fs)
1143 fs->obj_surface = NULL;
1144 fs->surface_id = VA_INVALID_ID;
1145 fs->is_scratch_surface = 0;
1149 pp_dndi_frame_store_swap(DNDIFrameStore *fs1, DNDIFrameStore *fs2)
1151 const DNDIFrameStore tmpfs = *fs1;
1157 pp_dndi_frame_store_clear(DNDIFrameStore *fs, VADriverContextP ctx)
1159 if (fs->obj_surface && fs->is_scratch_surface) {
1160 VASurfaceID va_surface = fs->obj_surface->base.id;
1161 i965_DestroySurfaces(ctx, &va_surface, 1);
1163 pp_dndi_frame_store_reset(fs);
1167 pp_dndi_context_init(struct pp_dndi_context *dndi_ctx)
1171 memset(dndi_ctx, 0, sizeof(*dndi_ctx));
1172 for (i = 0; i < ARRAY_ELEMS(dndi_ctx->frame_store); i++)
1173 pp_dndi_frame_store_reset(&dndi_ctx->frame_store[i]);
1177 pp_dndi_context_init_surface_params(struct pp_dndi_context *dndi_ctx,
1178 struct object_surface *obj_surface,
1179 const VAProcPipelineParameterBuffer *pipe_params,
1180 const VAProcFilterParameterBufferDeinterlacing *deint_params)
1184 dndi_ctx->is_di_enabled = 1;
1185 dndi_ctx->is_di_adv_enabled = 0;
1186 dndi_ctx->is_first_frame = 0;
1187 dndi_ctx->is_second_field = 0;
1189 /* Check whether we are deinterlacing the second field */
1190 if (dndi_ctx->is_di_enabled) {
1191 const unsigned int tff =
1192 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
1193 const unsigned int is_top_field =
1194 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
1196 if ((tff ^ is_top_field) != 0) {
1197 fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT];
1198 if (fs->surface_id != obj_surface->base.id) {
1199 WARN_ONCE("invalid surface provided for second field\n");
1200 return VA_STATUS_ERROR_INVALID_PARAMETER;
1202 dndi_ctx->is_second_field = 1;
1206 /* Check whether we are deinterlacing the first frame */
1207 if (dndi_ctx->is_di_enabled) {
1208 switch (deint_params->algorithm) {
1209 case VAProcDeinterlacingBob:
1210 dndi_ctx->is_first_frame = 1;
1212 case VAProcDeinterlacingMotionAdaptive:
1213 case VAProcDeinterlacingMotionCompensated:
1214 fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT];
1215 if (fs->surface_id == VA_INVALID_ID)
1216 dndi_ctx->is_first_frame = 1;
1217 else if (dndi_ctx->is_second_field) {
1218 /* At this stage, we have already deinterlaced the
1219 first field successfully. So, the first frame flag
1220 is trigerred if the previous field was deinterlaced
1221 without reference frame */
1222 fs = &dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS];
1223 if (fs->surface_id == VA_INVALID_ID)
1224 dndi_ctx->is_first_frame = 1;
1227 if (pipe_params->num_forward_references < 1 ||
1228 pipe_params->forward_references[0] == VA_INVALID_ID) {
1229 WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
1230 return VA_STATUS_ERROR_INVALID_PARAMETER;
1233 dndi_ctx->is_di_adv_enabled = 1;
1236 WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
1237 deint_params->algorithm);
1238 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1241 return VA_STATUS_SUCCESS;
1245 pp_dndi_context_ensure_surfaces_storage(VADriverContextP ctx,
1246 struct i965_post_processing_context *pp_context,
1247 struct object_surface *src_surface, struct object_surface *dst_surface)
1249 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1250 struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context;
1251 unsigned int src_fourcc, dst_fourcc;
1252 unsigned int src_sampling, dst_sampling;
1253 unsigned int src_tiling, dst_tiling;
1254 unsigned int i, swizzle;
1257 /* Determine input surface info. Always use NV12 Y-tiled */
1258 if (src_surface->bo) {
1259 src_fourcc = src_surface->fourcc;
1260 src_sampling = src_surface->subsampling;
1261 dri_bo_get_tiling(src_surface->bo, &src_tiling, &swizzle);
1262 src_tiling = !!src_tiling;
1265 src_fourcc = VA_FOURCC_NV12;
1266 src_sampling = SUBSAMPLE_YUV420;
1268 status = i965_check_alloc_surface_bo(ctx, src_surface,
1269 src_tiling, src_fourcc, src_sampling);
1270 if (status != VA_STATUS_SUCCESS)
1274 /* Determine output surface info. Always use NV12 Y-tiled */
1275 if (dst_surface->bo) {
1276 dst_fourcc = dst_surface->fourcc;
1277 dst_sampling = dst_surface->subsampling;
1278 dri_bo_get_tiling(dst_surface->bo, &dst_tiling, &swizzle);
1279 dst_tiling = !!dst_tiling;
1282 dst_fourcc = VA_FOURCC_NV12;
1283 dst_sampling = SUBSAMPLE_YUV420;
1285 status = i965_check_alloc_surface_bo(ctx, dst_surface,
1286 dst_tiling, dst_fourcc, dst_sampling);
1287 if (status != VA_STATUS_SUCCESS)
1291 /* Create pipeline surfaces */
1292 for (i = 0; i < ARRAY_ELEMS(dndi_ctx->frame_store); i ++) {
1293 struct object_surface *obj_surface;
1294 VASurfaceID new_surface;
1295 unsigned int width, height;
1297 if (dndi_ctx->frame_store[i].obj_surface &&
1298 dndi_ctx->frame_store[i].obj_surface->bo)
1299 continue; // user allocated surface, not VPP internal
1301 if (dndi_ctx->frame_store[i].obj_surface) {
1302 obj_surface = dndi_ctx->frame_store[i].obj_surface;
1303 dndi_ctx->frame_store[i].is_scratch_surface = 0;
1305 if (i <= DNDI_FRAME_IN_STMM) {
1306 width = src_surface->orig_width;
1307 height = src_surface->orig_height;
1310 width = dst_surface->orig_width;
1311 height = dst_surface->orig_height;
1314 status = i965_CreateSurfaces(ctx, width, height, VA_RT_FORMAT_YUV420,
1316 if (status != VA_STATUS_SUCCESS)
1319 obj_surface = SURFACE(new_surface);
1320 assert(obj_surface != NULL);
1321 dndi_ctx->frame_store[i].is_scratch_surface = 1;
1324 if (i <= DNDI_FRAME_IN_PREVIOUS) {
1325 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1326 src_tiling, src_fourcc, src_sampling);
1328 else if (i == DNDI_FRAME_IN_STMM || i == DNDI_FRAME_OUT_STMM) {
1329 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1330 1, VA_FOURCC_Y800, SUBSAMPLE_YUV400);
1332 else if (i >= DNDI_FRAME_OUT_CURRENT) {
1333 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1334 dst_tiling, dst_fourcc, dst_sampling);
1336 if (status != VA_STATUS_SUCCESS)
1339 dndi_ctx->frame_store[i].obj_surface = obj_surface;
1341 return VA_STATUS_SUCCESS;
1345 pp_dndi_context_ensure_surfaces(VADriverContextP ctx,
1346 struct i965_post_processing_context *pp_context,
1347 struct object_surface *src_surface, struct object_surface *dst_surface)
1349 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1350 struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context;
1351 DNDIFrameStore *ifs, *ofs;
1352 bool is_new_frame = false;
1354 /* Update the previous input surface */
1355 is_new_frame = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].surface_id !=
1356 src_surface->base.id;
1358 ifs = &dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS];
1359 ofs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT];
1361 const VAProcPipelineParameterBuffer * const pipe_params =
1362 pp_context->pipeline_param;
1363 struct object_surface *obj_surface;
1365 if (pipe_params->num_forward_references < 1)
1367 if (pipe_params->forward_references[0] == VA_INVALID_ID)
1370 obj_surface = SURFACE(pipe_params->forward_references[0]);
1371 if (!obj_surface || obj_surface->base.id == ifs->surface_id)
1374 pp_dndi_frame_store_clear(ifs, ctx);
1375 if (obj_surface->base.id == ofs->surface_id) {
1377 pp_dndi_frame_store_reset(ofs);
1380 ifs->obj_surface = obj_surface;
1381 ifs->surface_id = obj_surface->base.id;
1386 /* Update the input surface */
1387 ifs = &dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT];
1388 pp_dndi_frame_store_clear(ifs, ctx);
1389 ifs->obj_surface = src_surface;
1390 ifs->surface_id = src_surface->base.id;
1392 /* Update the Spatial Temporal Motion Measure (STMM) surfaces */
1394 pp_dndi_frame_store_swap(&dndi_ctx->frame_store[DNDI_FRAME_IN_STMM],
1395 &dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM]);
1397 /* Update the output surfaces */
1398 ofs = &dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT];
1399 if (dndi_ctx->is_di_adv_enabled && !dndi_ctx->is_first_frame) {
1400 pp_dndi_frame_store_swap(ofs,
1401 &dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS]);
1402 if (!dndi_ctx->is_second_field)
1403 ofs = &dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS];
1405 pp_dndi_frame_store_clear(ofs, ctx);
1406 ofs->obj_surface = dst_surface;
1407 ofs->surface_id = dst_surface->base.id;
1409 return VA_STATUS_SUCCESS;
1413 pp_get_surface_fourcc(VADriverContextP ctx, const struct i965_surface *surface)
1417 if (surface->type == I965_SURFACE_TYPE_IMAGE) {
1418 struct object_image *obj_image = (struct object_image *)surface->base;
1419 fourcc = obj_image->image.format.fourcc;
1421 struct object_surface *obj_surface = (struct object_surface *)surface->base;
1422 fourcc = obj_surface->fourcc;
1429 pp_get_surface_size(VADriverContextP ctx, const struct i965_surface *surface, int *width, int *height)
1431 if (surface->type == I965_SURFACE_TYPE_IMAGE) {
1432 struct object_image *obj_image = (struct object_image *)surface->base;
1434 *width = obj_image->image.width;
1435 *height = obj_image->image.height;
1437 struct object_surface *obj_surface = (struct object_surface *)surface->base;
1439 *width = obj_surface->orig_width;
1440 *height = obj_surface->orig_height;
1445 pp_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
1448 case I915_TILING_NONE:
1449 ss->ss3.tiled_surface = 0;
1450 ss->ss3.tile_walk = 0;
1453 ss->ss3.tiled_surface = 1;
1454 ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
1457 ss->ss3.tiled_surface = 1;
1458 ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
1464 pp_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
1467 case I915_TILING_NONE:
1468 ss->ss2.tiled_surface = 0;
1469 ss->ss2.tile_walk = 0;
1472 ss->ss2.tiled_surface = 1;
1473 ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
1476 ss->ss2.tiled_surface = 1;
1477 ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
1483 gen7_pp_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
1486 case I915_TILING_NONE:
1487 ss->ss0.tiled_surface = 0;
1488 ss->ss0.tile_walk = 0;
1491 ss->ss0.tiled_surface = 1;
1492 ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
1495 ss->ss0.tiled_surface = 1;
1496 ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
1502 gen7_pp_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
1505 case I915_TILING_NONE:
1506 ss->ss2.tiled_surface = 0;
1507 ss->ss2.tile_walk = 0;
1510 ss->ss2.tiled_surface = 1;
1511 ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
1514 ss->ss2.tiled_surface = 1;
1515 ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
1521 ironlake_pp_interface_descriptor_table(struct i965_post_processing_context *pp_context)
1523 struct i965_interface_descriptor *desc;
1525 int pp_index = pp_context->current_pp;
1527 bo = pp_context->idrt.bo;
1529 assert(bo->virtual);
1531 memset(desc, 0, sizeof(*desc));
1532 desc->desc0.grf_reg_blocks = 10;
1533 desc->desc0.kernel_start_pointer = pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
1534 desc->desc1.const_urb_entry_read_offset = 0;
1535 desc->desc1.const_urb_entry_read_len = 4; /* grf 1-4 */
1536 desc->desc2.sampler_state_pointer = pp_context->sampler_state_table.bo->offset >> 5;
1537 desc->desc2.sampler_count = 0;
1538 desc->desc3.binding_table_entry_count = 0;
1539 desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
1541 dri_bo_emit_reloc(bo,
1542 I915_GEM_DOMAIN_INSTRUCTION, 0,
1543 desc->desc0.grf_reg_blocks,
1544 offsetof(struct i965_interface_descriptor, desc0),
1545 pp_context->pp_modules[pp_index].kernel.bo);
1547 dri_bo_emit_reloc(bo,
1548 I915_GEM_DOMAIN_INSTRUCTION, 0,
1549 desc->desc2.sampler_count << 2,
1550 offsetof(struct i965_interface_descriptor, desc2),
1551 pp_context->sampler_state_table.bo);
1554 pp_context->idrt.num_interface_descriptors++;
1558 ironlake_pp_vfe_state(struct i965_post_processing_context *pp_context)
1560 struct i965_vfe_state *vfe_state;
1563 bo = pp_context->vfe_state.bo;
1565 assert(bo->virtual);
1566 vfe_state = bo->virtual;
1567 memset(vfe_state, 0, sizeof(*vfe_state));
1568 vfe_state->vfe1.max_threads = pp_context->urb.num_vfe_entries - 1;
1569 vfe_state->vfe1.urb_entry_alloc_size = pp_context->urb.size_vfe_entry - 1;
1570 vfe_state->vfe1.num_urb_entries = pp_context->urb.num_vfe_entries;
1571 vfe_state->vfe1.vfe_mode = VFE_GENERIC_MODE;
1572 vfe_state->vfe1.children_present = 0;
1573 vfe_state->vfe2.interface_descriptor_base =
1574 pp_context->idrt.bo->offset >> 4; /* reloc */
1575 dri_bo_emit_reloc(bo,
1576 I915_GEM_DOMAIN_INSTRUCTION, 0,
1578 offsetof(struct i965_vfe_state, vfe2),
1579 pp_context->idrt.bo);
1584 ironlake_pp_upload_constants(struct i965_post_processing_context *pp_context)
1586 unsigned char *constant_buffer;
1587 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1589 assert(sizeof(*pp_static_parameter) == 128);
1590 dri_bo_map(pp_context->curbe.bo, 1);
1591 assert(pp_context->curbe.bo->virtual);
1592 constant_buffer = pp_context->curbe.bo->virtual;
1593 memcpy(constant_buffer, pp_static_parameter, sizeof(*pp_static_parameter));
1594 dri_bo_unmap(pp_context->curbe.bo);
1598 ironlake_pp_states_setup(VADriverContextP ctx,
1599 struct i965_post_processing_context *pp_context)
1601 ironlake_pp_interface_descriptor_table(pp_context);
1602 ironlake_pp_vfe_state(pp_context);
1603 ironlake_pp_upload_constants(pp_context);
1607 ironlake_pp_pipeline_select(VADriverContextP ctx,
1608 struct i965_post_processing_context *pp_context)
1610 struct intel_batchbuffer *batch = pp_context->batch;
1612 BEGIN_BATCH(batch, 1);
1613 OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
1614 ADVANCE_BATCH(batch);
1618 ironlake_pp_urb_layout(VADriverContextP ctx,
1619 struct i965_post_processing_context *pp_context)
1621 struct intel_batchbuffer *batch = pp_context->batch;
1622 unsigned int vfe_fence, cs_fence;
1624 vfe_fence = pp_context->urb.cs_start;
1625 cs_fence = pp_context->urb.size;
1627 BEGIN_BATCH(batch, 3);
1628 OUT_BATCH(batch, CMD_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | 1);
1629 OUT_BATCH(batch, 0);
1631 (vfe_fence << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */
1632 (cs_fence << UF2_CS_FENCE_SHIFT)); /* CS_SIZE */
1633 ADVANCE_BATCH(batch);
1637 ironlake_pp_state_base_address(VADriverContextP ctx,
1638 struct i965_post_processing_context *pp_context)
1640 struct intel_batchbuffer *batch = pp_context->batch;
1642 BEGIN_BATCH(batch, 8);
1643 OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | 6);
1644 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1645 OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY);
1646 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1647 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1648 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1649 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1650 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
1651 ADVANCE_BATCH(batch);
1655 ironlake_pp_state_pointers(VADriverContextP ctx,
1656 struct i965_post_processing_context *pp_context)
1658 struct intel_batchbuffer *batch = pp_context->batch;
1660 BEGIN_BATCH(batch, 3);
1661 OUT_BATCH(batch, CMD_MEDIA_STATE_POINTERS | 1);
1662 OUT_BATCH(batch, 0);
1663 OUT_RELOC(batch, pp_context->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1664 ADVANCE_BATCH(batch);
1668 ironlake_pp_cs_urb_layout(VADriverContextP ctx,
1669 struct i965_post_processing_context *pp_context)
1671 struct intel_batchbuffer *batch = pp_context->batch;
1673 BEGIN_BATCH(batch, 2);
1674 OUT_BATCH(batch, CMD_CS_URB_STATE | 0);
1676 ((pp_context->urb.size_cs_entry - 1) << 4) | /* URB Entry Allocation Size */
1677 (pp_context->urb.num_cs_entries << 0)); /* Number of URB Entries */
1678 ADVANCE_BATCH(batch);
1682 ironlake_pp_constant_buffer(VADriverContextP ctx,
1683 struct i965_post_processing_context *pp_context)
1685 struct intel_batchbuffer *batch = pp_context->batch;
1687 BEGIN_BATCH(batch, 2);
1688 OUT_BATCH(batch, CMD_CONSTANT_BUFFER | (1 << 8) | (2 - 2));
1689 OUT_RELOC(batch, pp_context->curbe.bo,
1690 I915_GEM_DOMAIN_INSTRUCTION, 0,
1691 pp_context->urb.size_cs_entry - 1);
1692 ADVANCE_BATCH(batch);
1696 ironlake_pp_object_walker(VADriverContextP ctx,
1697 struct i965_post_processing_context *pp_context)
1699 struct intel_batchbuffer *batch = pp_context->batch;
1700 int x, x_steps, y, y_steps;
1701 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
1703 x_steps = pp_context->pp_x_steps(pp_context->private_context);
1704 y_steps = pp_context->pp_y_steps(pp_context->private_context);
1706 for (y = 0; y < y_steps; y++) {
1707 for (x = 0; x < x_steps; x++) {
1708 if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
1709 BEGIN_BATCH(batch, 20);
1710 OUT_BATCH(batch, CMD_MEDIA_OBJECT | 18);
1711 OUT_BATCH(batch, 0);
1712 OUT_BATCH(batch, 0); /* no indirect data */
1713 OUT_BATCH(batch, 0);
1715 /* inline data grf 5-6 */
1716 assert(sizeof(*pp_inline_parameter) == 64);
1717 intel_batchbuffer_data(batch, pp_inline_parameter, sizeof(*pp_inline_parameter));
1719 ADVANCE_BATCH(batch);
1726 ironlake_pp_pipeline_setup(VADriverContextP ctx,
1727 struct i965_post_processing_context *pp_context)
1729 struct intel_batchbuffer *batch = pp_context->batch;
1731 intel_batchbuffer_start_atomic(batch, 0x1000);
1732 intel_batchbuffer_emit_mi_flush(batch);
1733 ironlake_pp_pipeline_select(ctx, pp_context);
1734 ironlake_pp_state_base_address(ctx, pp_context);
1735 ironlake_pp_state_pointers(ctx, pp_context);
1736 ironlake_pp_urb_layout(ctx, pp_context);
1737 ironlake_pp_cs_urb_layout(ctx, pp_context);
1738 ironlake_pp_constant_buffer(ctx, pp_context);
1739 ironlake_pp_object_walker(ctx, pp_context);
1740 intel_batchbuffer_end_atomic(batch);
1743 // update u/v offset when the surface format are packed yuv
1744 static void i965_update_src_surface_static_parameter(
1745 VADriverContextP ctx,
1746 struct i965_post_processing_context *pp_context,
1747 const struct i965_surface *surface)
1749 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1750 int fourcc = pp_get_surface_fourcc(ctx, surface);
1753 case VA_FOURCC_YUY2:
1754 pp_static_parameter->grf1.source_packed_u_offset = 1;
1755 pp_static_parameter->grf1.source_packed_v_offset = 3;
1757 case VA_FOURCC_UYVY:
1758 pp_static_parameter->grf1.source_packed_y_offset = 1;
1759 pp_static_parameter->grf1.source_packed_v_offset = 2;
1761 case VA_FOURCC_BGRX:
1762 case VA_FOURCC_BGRA:
1763 pp_static_parameter->grf1.source_rgb_layout = 0;
1765 case VA_FOURCC_RGBX:
1766 case VA_FOURCC_RGBA:
1767 pp_static_parameter->grf1.source_rgb_layout = 1;
1775 static void i965_update_dst_surface_static_parameter(
1776 VADriverContextP ctx,
1777 struct i965_post_processing_context *pp_context,
1778 const struct i965_surface *surface)
1780 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
1781 int fourcc = pp_get_surface_fourcc(ctx, surface);
1784 case VA_FOURCC_YUY2:
1785 pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_u_offset = 1;
1786 pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 3;
1788 case VA_FOURCC_UYVY:
1789 pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_y_offset = 1;
1790 pp_static_parameter->grf1.r1_2.load_and_save.destination_packed_v_offset = 2;
1792 case VA_FOURCC_BGRX:
1793 case VA_FOURCC_BGRA:
1794 pp_static_parameter->grf1.r1_2.csc.destination_rgb_layout = 0;
1796 case VA_FOURCC_RGBX:
1797 case VA_FOURCC_RGBA:
1798 pp_static_parameter->grf1.r1_2.csc.destination_rgb_layout = 1;
1807 i965_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1808 dri_bo *surf_bo, unsigned long surf_bo_offset,
1809 int width, int height, int pitch, int format,
1810 int index, int is_target)
1812 struct i965_surface_state *ss;
1814 unsigned int tiling;
1815 unsigned int swizzle;
1817 dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1818 ss_bo = pp_context->surface_state_binding_table.bo;
1821 dri_bo_map(ss_bo, True);
1822 assert(ss_bo->virtual);
1823 ss = (struct i965_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1824 memset(ss, 0, sizeof(*ss));
1825 ss->ss0.surface_type = I965_SURFACE_2D;
1826 ss->ss0.surface_format = format;
1827 ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1828 ss->ss2.width = width - 1;
1829 ss->ss2.height = height - 1;
1830 ss->ss3.pitch = pitch - 1;
1831 pp_set_surface_tiling(ss, tiling);
1832 dri_bo_emit_reloc(ss_bo,
1833 I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1835 SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state, ss1),
1837 ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1838 dri_bo_unmap(ss_bo);
1842 i965_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1843 dri_bo *surf_bo, unsigned long surf_bo_offset,
1844 int width, int height, int wpitch,
1845 int xoffset, int yoffset,
1846 int format, int interleave_chroma,
1849 struct i965_surface_state2 *ss2;
1851 unsigned int tiling;
1852 unsigned int swizzle;
1854 dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1855 ss2_bo = pp_context->surface_state_binding_table.bo;
1858 dri_bo_map(ss2_bo, True);
1859 assert(ss2_bo->virtual);
1860 ss2 = (struct i965_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1861 memset(ss2, 0, sizeof(*ss2));
1862 ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1863 ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1864 ss2->ss1.width = width - 1;
1865 ss2->ss1.height = height - 1;
1866 ss2->ss2.pitch = wpitch - 1;
1867 ss2->ss2.interleave_chroma = interleave_chroma;
1868 ss2->ss2.surface_format = format;
1869 ss2->ss3.x_offset_for_cb = xoffset;
1870 ss2->ss3.y_offset_for_cb = yoffset;
1871 pp_set_surface2_tiling(ss2, tiling);
1872 dri_bo_emit_reloc(ss2_bo,
1873 I915_GEM_DOMAIN_RENDER, 0,
1875 SURFACE_STATE_OFFSET(index) + offsetof(struct i965_surface_state2, ss0),
1877 ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1878 dri_bo_unmap(ss2_bo);
1882 gen7_pp_set_surface_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1883 dri_bo *surf_bo, unsigned long surf_bo_offset,
1884 int width, int height, int pitch, int format,
1885 int index, int is_target)
1887 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1888 struct gen7_surface_state *ss;
1890 unsigned int tiling;
1891 unsigned int swizzle;
1893 dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1894 ss_bo = pp_context->surface_state_binding_table.bo;
1897 dri_bo_map(ss_bo, True);
1898 assert(ss_bo->virtual);
1899 ss = (struct gen7_surface_state *)((char *)ss_bo->virtual + SURFACE_STATE_OFFSET(index));
1900 memset(ss, 0, sizeof(*ss));
1901 ss->ss0.surface_type = I965_SURFACE_2D;
1902 ss->ss0.surface_format = format;
1903 ss->ss1.base_addr = surf_bo->offset + surf_bo_offset;
1904 ss->ss2.width = width - 1;
1905 ss->ss2.height = height - 1;
1906 ss->ss3.pitch = pitch - 1;
1907 gen7_pp_set_surface_tiling(ss, tiling);
1908 if (IS_HASWELL(i965->intel.device_info))
1909 gen7_render_set_surface_scs(ss);
1910 dri_bo_emit_reloc(ss_bo,
1911 I915_GEM_DOMAIN_RENDER, is_target ? I915_GEM_DOMAIN_RENDER : 0,
1913 SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
1915 ((unsigned int *)((char *)ss_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1916 dri_bo_unmap(ss_bo);
1920 gen7_pp_set_surface2_state(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1921 dri_bo *surf_bo, unsigned long surf_bo_offset,
1922 int width, int height, int wpitch,
1923 int xoffset, int yoffset,
1924 int format, int interleave_chroma,
1927 struct gen7_surface_state2 *ss2;
1929 unsigned int tiling;
1930 unsigned int swizzle;
1932 dri_bo_get_tiling(surf_bo, &tiling, &swizzle);
1933 ss2_bo = pp_context->surface_state_binding_table.bo;
1936 dri_bo_map(ss2_bo, True);
1937 assert(ss2_bo->virtual);
1938 ss2 = (struct gen7_surface_state2 *)((char *)ss2_bo->virtual + SURFACE_STATE_OFFSET(index));
1939 memset(ss2, 0, sizeof(*ss2));
1940 ss2->ss0.surface_base_address = surf_bo->offset + surf_bo_offset;
1941 ss2->ss1.cbcr_pixel_offset_v_direction = 0;
1942 ss2->ss1.width = width - 1;
1943 ss2->ss1.height = height - 1;
1944 ss2->ss2.pitch = wpitch - 1;
1945 ss2->ss2.interleave_chroma = interleave_chroma;
1946 ss2->ss2.surface_format = format;
1947 ss2->ss3.x_offset_for_cb = xoffset;
1948 ss2->ss3.y_offset_for_cb = yoffset;
1949 gen7_pp_set_surface2_tiling(ss2, tiling);
1950 dri_bo_emit_reloc(ss2_bo,
1951 I915_GEM_DOMAIN_RENDER, 0,
1953 SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state2, ss0),
1955 ((unsigned int *)((char *)ss2_bo->virtual + BINDING_TABLE_OFFSET))[index] = SURFACE_STATE_OFFSET(index);
1956 dri_bo_unmap(ss2_bo);
1960 pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
1961 const struct i965_surface *surface,
1962 int base_index, int is_target,
1963 int *width, int *height, int *pitch, int *offset)
1965 struct object_surface *obj_surface;
1966 struct object_image *obj_image;
1968 int fourcc = pp_get_surface_fourcc(ctx, surface);
1970 const int U = ((fourcc == VA_FOURCC_YV12) ||
1971 (fourcc == VA_FOURCC_YV16))
1973 const int V = ((fourcc == VA_FOURCC_YV12) ||
1974 (fourcc == VA_FOURCC_YV16))
1977 int interleaved_uv = fourcc == VA_FOURCC_NV12;
1978 int packed_yuv = (fourcc == VA_FOURCC_YUY2 || fourcc == VA_FOURCC_UYVY);
1979 int full_packed_format = (fourcc == VA_FOURCC_RGBA ||
1980 fourcc == VA_FOURCC_RGBX ||
1981 fourcc == VA_FOURCC_BGRA ||
1982 fourcc == VA_FOURCC_BGRX);
1983 int scale_factor_of_1st_plane_width_in_byte = 1;
1985 if (surface->type == I965_SURFACE_TYPE_SURFACE) {
1986 obj_surface = (struct object_surface *)surface->base;
1987 bo = obj_surface->bo;
1988 width[0] = obj_surface->orig_width;
1989 height[0] = obj_surface->orig_height;
1990 pitch[0] = obj_surface->width;
1993 if (full_packed_format) {
1994 scale_factor_of_1st_plane_width_in_byte = 4;
1996 else if (packed_yuv ) {
1997 scale_factor_of_1st_plane_width_in_byte = 2;
1999 else if (interleaved_uv) {
2000 width[1] = obj_surface->orig_width;
2001 height[1] = obj_surface->orig_height / 2;
2002 pitch[1] = obj_surface->width;
2003 offset[1] = offset[0] + obj_surface->width * obj_surface->height;
2005 width[1] = obj_surface->orig_width / 2;
2006 height[1] = obj_surface->orig_height / 2;
2007 pitch[1] = obj_surface->width / 2;
2008 offset[1] = offset[0] + obj_surface->width * obj_surface->height;
2009 width[2] = obj_surface->orig_width / 2;
2010 height[2] = obj_surface->orig_height / 2;
2011 pitch[2] = obj_surface->width / 2;
2012 offset[2] = offset[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
2015 obj_image = (struct object_image *)surface->base;
2017 width[0] = obj_image->image.width;
2018 height[0] = obj_image->image.height;
2019 pitch[0] = obj_image->image.pitches[0];
2020 offset[0] = obj_image->image.offsets[0];
2022 if (full_packed_format) {
2023 scale_factor_of_1st_plane_width_in_byte = 4;
2025 else if (packed_yuv ) {
2026 scale_factor_of_1st_plane_width_in_byte = 2;
2028 else if (interleaved_uv) {
2029 width[1] = obj_image->image.width;
2030 height[1] = obj_image->image.height / 2;
2031 pitch[1] = obj_image->image.pitches[1];
2032 offset[1] = obj_image->image.offsets[1];
2034 width[1] = obj_image->image.width / 2;
2035 height[1] = obj_image->image.height / 2;
2036 pitch[1] = obj_image->image.pitches[1];
2037 offset[1] = obj_image->image.offsets[1];
2038 width[2] = obj_image->image.width / 2;
2039 height[2] = obj_image->image.height / 2;
2040 pitch[2] = obj_image->image.pitches[2];
2041 offset[2] = obj_image->image.offsets[2];
2042 if (fourcc == VA_FOURCC_YV16) {
2043 width[1] = obj_image->image.width / 2;
2044 height[1] = obj_image->image.height;
2045 width[2] = obj_image->image.width / 2;
2046 height[2] = obj_image->image.height;
2052 i965_pp_set_surface_state(ctx, pp_context,
2054 ALIGN(width[Y] *scale_factor_of_1st_plane_width_in_byte, 4) / 4, height[Y], pitch[Y], I965_SURFACEFORMAT_R8_UNORM,
2055 base_index, is_target);
2057 if (!packed_yuv && !full_packed_format) {
2058 if (interleaved_uv) {
2059 i965_pp_set_surface_state(ctx, pp_context,
2061 ALIGN(width[UV], 4) / 4, height[UV], pitch[UV], I965_SURFACEFORMAT_R8_UNORM,
2062 base_index + 1, is_target);
2065 i965_pp_set_surface_state(ctx, pp_context,
2067 ALIGN(width[U], 4) / 4, height[U], pitch[U], I965_SURFACEFORMAT_R8_UNORM,
2068 base_index + 1, is_target);
2071 i965_pp_set_surface_state(ctx, pp_context,
2073 ALIGN(width[V], 4) / 4, height[V], pitch[V], I965_SURFACEFORMAT_R8_UNORM,
2074 base_index + 2, is_target);
2081 gen7_pp_set_media_rw_message_surface(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2082 const struct i965_surface *surface,
2083 int base_index, int is_target,
2084 const VARectangle *rect,
2085 int *width, int *height, int *pitch, int *offset)
2087 struct object_surface *obj_surface;
2088 struct object_image *obj_image;
2090 int fourcc = pp_get_surface_fourcc(ctx, surface);
2091 const i965_fourcc_info *fourcc_info = get_fourcc_info(fourcc);
2093 if (fourcc_info == NULL)
2096 if (surface->type == I965_SURFACE_TYPE_SURFACE) {
2097 obj_surface = (struct object_surface *)surface->base;
2098 bo = obj_surface->bo;
2099 width[0] = MIN(rect->x + rect->width, obj_surface->orig_width);
2100 height[0] = MIN(rect->y + rect->height, obj_surface->orig_height);
2101 pitch[0] = obj_surface->width;
2104 if (fourcc_info->num_planes == 1 && is_target)
2105 width[0] = width[0] * (fourcc_info->bpp[0] / 8); /* surface format is R8 */
2107 width[1] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_surface->cb_cr_width);
2108 height[1] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_surface->cb_cr_height);
2109 pitch[1] = obj_surface->cb_cr_pitch;
2110 offset[1] = obj_surface->y_cb_offset * obj_surface->width;
2112 width[2] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_surface->cb_cr_width);
2113 height[2] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_surface->cb_cr_height);
2114 pitch[2] = obj_surface->cb_cr_pitch;
2115 offset[2] = obj_surface->y_cr_offset * obj_surface->width;
2119 /* FIXME: add support for ARGB/ABGR image */
2120 obj_image = (struct object_image *)surface->base;
2122 width[0] = MIN(rect->x + rect->width, obj_image->image.width);
2123 height[0] = MIN(rect->y + rect->height, obj_image->image.height);
2124 pitch[0] = obj_image->image.pitches[0];
2125 offset[0] = obj_image->image.offsets[0];
2127 if (fourcc_info->num_planes == 1) {
2129 width[0] = width[0] * (fourcc_info->bpp[0] / 8); /* surface format is R8 */
2130 } else if (fourcc_info->num_planes == 2) {
2133 assert(fourcc_info->num_components == 3);
2135 U = fourcc_info->components[1].plane;
2136 V = fourcc_info->components[2].plane;
2137 assert((U == 1 && V == 2) ||
2138 (U == 2 && V == 1));
2141 /* Always set width/height although they aren't used for fourcc_info->num_planes == 1 */
2142 width[1] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_image->image.width / fourcc_info->hfactor);
2143 height[1] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_image->image.height / fourcc_info->vfactor);
2144 pitch[1] = obj_image->image.pitches[U];
2145 offset[1] = obj_image->image.offsets[U];
2147 width[2] = MIN(rect->x / fourcc_info->hfactor + rect->width / fourcc_info->hfactor, obj_image->image.width / fourcc_info->hfactor);
2148 height[2] = MIN(rect->y / fourcc_info->vfactor + rect->height / fourcc_info->vfactor, obj_image->image.height / fourcc_info->vfactor);
2149 pitch[2] = obj_image->image.pitches[V];
2150 offset[2] = obj_image->image.offsets[V];
2154 gen7_pp_set_surface_state(ctx, pp_context,
2156 ALIGN(width[0], 4) / 4, height[0], pitch[0],
2157 I965_SURFACEFORMAT_R8_UINT,
2160 if (fourcc_info->num_planes == 2) {
2161 gen7_pp_set_surface_state(ctx, pp_context,
2163 ALIGN(width[1], 2) / 2, height[1], pitch[1],
2164 I965_SURFACEFORMAT_R8G8_SINT,
2166 } else if (fourcc_info->num_planes == 3) {
2167 gen7_pp_set_surface_state(ctx, pp_context,
2169 ALIGN(width[1], 4) / 4, height[1], pitch[1],
2170 I965_SURFACEFORMAT_R8_SINT,
2172 gen7_pp_set_surface_state(ctx, pp_context,
2174 ALIGN(width[2], 4) / 4, height[2], pitch[2],
2175 I965_SURFACEFORMAT_R8_SINT,
2179 if (fourcc_info->format == I965_COLOR_RGB) {
2180 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2181 /* the format is MSB: X-B-G-R */
2182 pp_static_parameter->grf2.save_avs_rgb_swap = 0;
2183 if ((fourcc == VA_FOURCC_BGRA) ||
2184 (fourcc == VA_FOURCC_BGRX)) {
2185 /* It is stored as MSB: X-R-G-B */
2186 pp_static_parameter->grf2.save_avs_rgb_swap = 1;
2190 int format0 = SURFACE_FORMAT_Y8_UNORM;
2193 case VA_FOURCC_YUY2:
2194 format0 = SURFACE_FORMAT_YCRCB_NORMAL;
2197 case VA_FOURCC_UYVY:
2198 format0 = SURFACE_FORMAT_YCRCB_SWAPY;
2205 if (fourcc_info->format == I965_COLOR_RGB) {
2206 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2207 /* Only R8G8B8A8_UNORM is supported for BGRX or RGBX */
2208 format0 = SURFACE_FORMAT_R8G8B8A8_UNORM;
2209 pp_static_parameter->grf2.src_avs_rgb_swap = 0;
2210 if ((fourcc == VA_FOURCC_BGRA) ||
2211 (fourcc == VA_FOURCC_BGRX)) {
2212 pp_static_parameter->grf2.src_avs_rgb_swap = 1;
2216 gen7_pp_set_surface2_state(ctx, pp_context,
2218 width[0], height[0], pitch[0],
2223 if (fourcc_info->num_planes == 2) {
2224 gen7_pp_set_surface2_state(ctx, pp_context,
2226 width[1], height[1], pitch[1],
2228 SURFACE_FORMAT_R8B8_UNORM, 0,
2230 } else if (fourcc_info->num_planes == 3) {
2231 gen7_pp_set_surface2_state(ctx, pp_context,
2233 width[1], height[1], pitch[1],
2235 SURFACE_FORMAT_R8_UNORM, 0,
2237 gen7_pp_set_surface2_state(ctx, pp_context,
2239 width[2], height[2], pitch[2],
2241 SURFACE_FORMAT_R8_UNORM, 0,
2248 pp_null_x_steps(void *private_context)
2254 pp_null_y_steps(void *private_context)
2260 pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2266 pp_null_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2267 const struct i965_surface *src_surface,
2268 const VARectangle *src_rect,
2269 struct i965_surface *dst_surface,
2270 const VARectangle *dst_rect,
2273 /* private function & data */
2274 pp_context->pp_x_steps = pp_null_x_steps;
2275 pp_context->pp_y_steps = pp_null_y_steps;
2276 pp_context->private_context = NULL;
2277 pp_context->pp_set_block_parameter = pp_null_set_block_parameter;
2279 dst_surface->flags = src_surface->flags;
2281 return VA_STATUS_SUCCESS;
2285 pp_load_save_x_steps(void *private_context)
2291 pp_load_save_y_steps(void *private_context)
2293 struct pp_load_save_context *pp_load_save_context = private_context;
2295 return pp_load_save_context->dest_h / 8;
2299 pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2301 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2302 struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)pp_context->private_context;
2304 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_load_save_context->dest_x;
2305 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_load_save_context->dest_y;
2310 static void calculate_boundary_block_mask(struct i965_post_processing_context *pp_context, const VARectangle *dst_rect)
2313 /* x offset of dest surface must be dword aligned.
2314 * so we have to extend dst surface on left edge, and mask out pixels not interested
2316 if (dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT) {
2317 pp_context->block_horizontal_mask_left = 0;
2318 for (i=dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT; i<GPU_ASM_BLOCK_WIDTH; i++)
2320 pp_context->block_horizontal_mask_left |= 1<<i;
2324 pp_context->block_horizontal_mask_left = 0xffff;
2327 int dst_width_adjust = dst_rect->width + dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
2328 if (dst_width_adjust%GPU_ASM_BLOCK_WIDTH){
2329 pp_context->block_horizontal_mask_right = (1 << (dst_width_adjust%GPU_ASM_BLOCK_WIDTH)) - 1;
2332 pp_context->block_horizontal_mask_right = 0xffff;
2335 if (dst_rect->height%GPU_ASM_BLOCK_HEIGHT){
2336 pp_context->block_vertical_mask_bottom = (1 << (dst_rect->height%GPU_ASM_BLOCK_HEIGHT)) - 1;
2339 pp_context->block_vertical_mask_bottom = 0xff;
2344 pp_plx_load_save_plx_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2345 const struct i965_surface *src_surface,
2346 const VARectangle *src_rect,
2347 struct i965_surface *dst_surface,
2348 const VARectangle *dst_rect,
2351 struct pp_load_save_context *pp_load_save_context = (struct pp_load_save_context *)&pp_context->pp_load_save_context;
2352 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2353 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2354 int width[3], height[3], pitch[3], offset[3];
2356 /* source surface */
2357 pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 1, 0,
2358 width, height, pitch, offset);
2360 /* destination surface */
2361 pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 7, 1,
2362 width, height, pitch, offset);
2364 /* private function & data */
2365 pp_context->pp_x_steps = pp_load_save_x_steps;
2366 pp_context->pp_y_steps = pp_load_save_y_steps;
2367 pp_context->private_context = &pp_context->pp_load_save_context;
2368 pp_context->pp_set_block_parameter = pp_load_save_set_block_parameter;
2370 int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;;
2371 pp_load_save_context->dest_x = dst_rect->x - dst_left_edge_extend;
2372 pp_load_save_context->dest_y = dst_rect->y;
2373 pp_load_save_context->dest_h = ALIGN(dst_rect->height, 8);
2374 pp_load_save_context->dest_w = ALIGN(dst_rect->width+dst_left_edge_extend, 16);
2376 pp_inline_parameter->grf5.block_count_x = pp_load_save_context->dest_w / 16; /* 1 x N */
2377 pp_inline_parameter->grf5.number_blocks = pp_load_save_context->dest_w / 16;
2379 pp_static_parameter->grf3.horizontal_origin_offset = src_rect->x;
2380 pp_static_parameter->grf3.vertical_origin_offset = src_rect->y;
2382 // update u/v offset for packed yuv
2383 i965_update_src_surface_static_parameter (ctx, pp_context, src_surface);
2384 i965_update_dst_surface_static_parameter (ctx, pp_context, dst_surface);
2386 dst_surface->flags = src_surface->flags;
2388 return VA_STATUS_SUCCESS;
2392 pp_scaling_x_steps(void *private_context)
2398 pp_scaling_y_steps(void *private_context)
2400 struct pp_scaling_context *pp_scaling_context = private_context;
2402 return pp_scaling_context->dest_h / 8;
2406 pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2408 struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)pp_context->private_context;
2409 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2410 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2411 float src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2412 float src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
2414 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
2415 pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
2416 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
2417 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
2423 pp_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2424 const struct i965_surface *src_surface,
2425 const VARectangle *src_rect,
2426 struct i965_surface *dst_surface,
2427 const VARectangle *dst_rect,
2430 struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->pp_scaling_context;
2431 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2432 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2433 struct object_surface *obj_surface;
2434 struct i965_sampler_state *sampler_state;
2435 int in_w, in_h, in_wpitch, in_hpitch;
2436 int out_w, out_h, out_wpitch, out_hpitch;
2438 /* source surface */
2439 obj_surface = (struct object_surface *)src_surface->base;
2440 in_w = obj_surface->orig_width;
2441 in_h = obj_surface->orig_height;
2442 in_wpitch = obj_surface->width;
2443 in_hpitch = obj_surface->height;
2445 /* source Y surface index 1 */
2446 i965_pp_set_surface_state(ctx, pp_context,
2448 in_w, in_h, in_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2451 /* source UV surface index 2 */
2452 i965_pp_set_surface_state(ctx, pp_context,
2453 obj_surface->bo, in_wpitch * in_hpitch,
2454 ALIGN(in_w, 2) / 2, in_h / 2, in_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2457 /* destination surface */
2458 obj_surface = (struct object_surface *)dst_surface->base;
2459 out_w = obj_surface->orig_width;
2460 out_h = obj_surface->orig_height;
2461 out_wpitch = obj_surface->width;
2462 out_hpitch = obj_surface->height;
2464 /* destination Y surface index 7 */
2465 i965_pp_set_surface_state(ctx, pp_context,
2467 ALIGN(out_w, 4) / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2470 /* destination UV surface index 8 */
2471 i965_pp_set_surface_state(ctx, pp_context,
2472 obj_surface->bo, out_wpitch * out_hpitch,
2473 ALIGN(out_w, 4) / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2477 dri_bo_map(pp_context->sampler_state_table.bo, True);
2478 assert(pp_context->sampler_state_table.bo->virtual);
2479 sampler_state = pp_context->sampler_state_table.bo->virtual;
2481 /* SIMD16 Y index 1 */
2482 sampler_state[1].ss0.min_filter = I965_MAPFILTER_LINEAR;
2483 sampler_state[1].ss0.mag_filter = I965_MAPFILTER_LINEAR;
2484 sampler_state[1].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2485 sampler_state[1].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2486 sampler_state[1].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2488 /* SIMD16 UV index 2 */
2489 sampler_state[2].ss0.min_filter = I965_MAPFILTER_LINEAR;
2490 sampler_state[2].ss0.mag_filter = I965_MAPFILTER_LINEAR;
2491 sampler_state[2].ss1.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2492 sampler_state[2].ss1.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2493 sampler_state[2].ss1.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
2495 dri_bo_unmap(pp_context->sampler_state_table.bo);
2497 /* private function & data */
2498 pp_context->pp_x_steps = pp_scaling_x_steps;
2499 pp_context->pp_y_steps = pp_scaling_y_steps;
2500 pp_context->private_context = &pp_context->pp_scaling_context;
2501 pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
2503 int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
2504 float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
2505 pp_scaling_context->dest_x = dst_rect->x - dst_left_edge_extend;
2506 pp_scaling_context->dest_y = dst_rect->y;
2507 pp_scaling_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
2508 pp_scaling_context->dest_h = ALIGN(dst_rect->height, 8);
2509 pp_scaling_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
2510 pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h;
2512 pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
2514 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);
2515 pp_inline_parameter->grf5.block_count_x = pp_scaling_context->dest_w / 16; /* 1 x N */
2516 pp_inline_parameter->grf5.number_blocks = pp_scaling_context->dest_w / 16;
2518 dst_surface->flags = src_surface->flags;
2520 return VA_STATUS_SUCCESS;
2524 pp_avs_x_steps(void *private_context)
2526 struct pp_avs_context *pp_avs_context = private_context;
2528 return pp_avs_context->dest_w / 16;
2532 pp_avs_y_steps(void *private_context)
2538 pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
2540 struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)pp_context->private_context;
2541 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2542 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2543 float src_x_steping, src_y_steping, video_step_delta;
2544 int tmp_w = ALIGN(pp_avs_context->dest_h * pp_avs_context->src_w / pp_avs_context->src_h, 16);
2546 if (pp_static_parameter->grf4.r4_2.avs.nlas == 0) {
2547 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2548 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_avs_context->src_normalized_x;
2549 } else if (tmp_w >= pp_avs_context->dest_w) {
2550 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
2551 pp_inline_parameter->grf6.video_step_delta = 0;
2554 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
2555 pp_avs_context->src_normalized_x;
2557 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2558 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2559 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2560 16 * 15 * video_step_delta / 2;
2563 int n0, n1, n2, nls_left, nls_right;
2564 int factor_a = 5, factor_b = 4;
2567 n0 = (pp_avs_context->dest_w - tmp_w) / (16 * 2);
2568 n1 = (pp_avs_context->dest_w - tmp_w) / 16 - n0;
2569 n2 = tmp_w / (16 * factor_a);
2571 nls_right = n1 + n2;
2572 f = (float) n2 * 16 / tmp_w;
2575 pp_inline_parameter->grf6.video_step_delta = 0.0;
2578 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
2579 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
2581 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2582 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2583 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2584 16 * 15 * video_step_delta / 2;
2588 /* f = a * nls_left * 16 + b * nls_left * 16 * (nls_left * 16 - 1) / 2 */
2589 float a = f / (nls_left * 16 * factor_b);
2590 float b = (f - nls_left * 16 * a) * 2 / (nls_left * 16 * (nls_left * 16 - 1));
2592 pp_inline_parameter->grf6.video_step_delta = b;
2595 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
2596 pp_inline_parameter->grf5.normalized_video_x_scaling_step = a;
2598 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2599 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2600 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2601 16 * 15 * video_step_delta / 2;
2602 pp_inline_parameter->grf5.normalized_video_x_scaling_step += 16 * b;
2604 } else if (x < (pp_avs_context->dest_w / 16 - nls_right)) {
2605 /* scale the center linearly */
2606 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2607 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2608 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2609 16 * 15 * video_step_delta / 2;
2610 pp_inline_parameter->grf6.video_step_delta = 0.0;
2611 pp_inline_parameter->grf5.normalized_video_x_scaling_step = 1.0 / tmp_w;
2613 float a = f / (nls_right * 16 * factor_b);
2614 float b = (f - nls_right * 16 * a) * 2 / (nls_right * 16 * (nls_right * 16 - 1));
2616 src_x_steping = pp_inline_parameter->grf5.normalized_video_x_scaling_step;
2617 video_step_delta = pp_inline_parameter->grf6.video_step_delta;
2618 pp_inline_parameter->grf5.r5_1.source_surface_block_normalized_horizontal_origin += src_x_steping * 16 +
2619 16 * 15 * video_step_delta / 2;
2620 pp_inline_parameter->grf6.video_step_delta = -b;
2622 if (x == (pp_avs_context->dest_w / 16 - nls_right))
2623 pp_inline_parameter->grf5.normalized_video_x_scaling_step = a + (nls_right * 16 - 1) * b;
2625 pp_inline_parameter->grf5.normalized_video_x_scaling_step -= b * 16;
2630 src_y_steping = pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step;
2631 pp_inline_parameter->grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
2632 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
2633 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
2638 static const AVSConfig gen5_avs_config = {
2639 .coeff_frac_bits = 6,
2640 .coeff_epsilon = 1.0f / (1U << 6),
2642 .num_luma_coeffs = 8,
2643 .num_chroma_coeffs = 4,
2647 .y_k_h = { -0.25f, -0.5f, -1, 0, 0, -1, -0.5f, -0.25f },
2648 .y_k_v = { -0.25f, -0.5f, -1, 0, 0, -1, -0.5f, -0.25f },
2649 .uv_k_h = { -1, 0, 0, -1 },
2650 .uv_k_v = { -1, 0, 0, -1 },
2653 .y_k_h = { 0.25f, 0.5f, 1, 2, 2, 1, 0.5f, 0.25f },
2654 .y_k_v = { 0.25f, 0.5f, 1, 2, 2, 1, 0.5f, 0.25f },
2655 .uv_k_h = { 1, 2, 2, 1 },
2656 .uv_k_v = { 1, 2, 2, 1 },
2661 static const AVSConfig gen6_avs_config = {
2662 .coeff_frac_bits = 6,
2663 .coeff_epsilon = 1.0f / (1U << 6),
2665 .num_luma_coeffs = 8,
2666 .num_chroma_coeffs = 4,
2670 .y_k_h = { -0.25f, -0.5f, -1, -2, -2, -1, -0.5f, -0.25f },
2671 .y_k_v = { -0.25f, -0.5f, -1, -2, -2, -1, -0.5f, -0.25f },
2672 .uv_k_h = { -1, 0, 0, -1 },
2673 .uv_k_v = { -1, 0, 0, -1 },
2676 .y_k_h = { 0.25f, 0.5f, 1, 2, 2, 1, 0.5f, 0.25f },
2677 .y_k_v = { 0.25f, 0.5f, 1, 2, 2, 1, 0.5f, 0.25f },
2678 .uv_k_h = { 1, 2, 2, 1 },
2679 .uv_k_v = { 1, 2, 2, 1 },
2685 pp_nv12_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2686 const struct i965_surface *src_surface,
2687 const VARectangle *src_rect,
2688 struct i965_surface *dst_surface,
2689 const VARectangle *dst_rect,
2692 struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->pp_avs_context;
2693 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
2694 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
2695 struct object_surface *obj_surface;
2696 struct i965_sampler_8x8 *sampler_8x8;
2697 struct i965_sampler_8x8_state *sampler_8x8_state;
2699 int in_w, in_h, in_wpitch, in_hpitch;
2700 int out_w, out_h, out_wpitch, out_hpitch;
2702 AVSState * const avs = &pp_avs_context->state;
2705 const int nlas = (pp_context->filter_flags & VA_FILTER_SCALING_MASK) ==
2706 VA_FILTER_SCALING_NL_ANAMORPHIC;
2709 obj_surface = (struct object_surface *)src_surface->base;
2710 in_w = obj_surface->orig_width;
2711 in_h = obj_surface->orig_height;
2712 in_wpitch = obj_surface->width;
2713 in_hpitch = obj_surface->height;
2715 /* source Y surface index 1 */
2716 i965_pp_set_surface2_state(ctx, pp_context,
2718 in_w, in_h, in_wpitch,
2720 SURFACE_FORMAT_Y8_UNORM, 0,
2723 /* source UV surface index 2 */
2724 i965_pp_set_surface2_state(ctx, pp_context,
2725 obj_surface->bo, in_wpitch * in_hpitch,
2726 in_w / 2, in_h / 2, in_wpitch,
2728 SURFACE_FORMAT_R8B8_UNORM, 0,
2731 /* destination surface */
2732 obj_surface = (struct object_surface *)dst_surface->base;
2733 out_w = obj_surface->orig_width;
2734 out_h = obj_surface->orig_height;
2735 out_wpitch = obj_surface->width;
2736 out_hpitch = obj_surface->height;
2737 assert(out_w <= out_wpitch && out_h <= out_hpitch);
2739 /* destination Y surface index 7 */
2740 i965_pp_set_surface_state(ctx, pp_context,
2742 ALIGN(out_w, 4) / 4, out_h, out_wpitch, I965_SURFACEFORMAT_R8_UNORM,
2745 /* destination UV surface index 8 */
2746 i965_pp_set_surface_state(ctx, pp_context,
2747 obj_surface->bo, out_wpitch * out_hpitch,
2748 ALIGN(out_w, 4) / 4, out_h / 2, out_wpitch, I965_SURFACEFORMAT_R8G8_UNORM,
2751 /* sampler 8x8 state */
2752 dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
2753 assert(pp_context->sampler_state_table.bo_8x8->virtual);
2754 assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
2755 sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
2756 memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
2758 sx = (float)dst_rect->width / src_rect->width;
2759 sy = (float)dst_rect->height / src_rect->height;
2760 avs_update_coefficients(avs, sx, sy, pp_context->filter_flags);
2762 assert(avs->config->num_phases == 16);
2763 for (i = 0; i <= 16; i++) {
2764 const AVSCoeffs * const coeffs = &avs->coeffs[i];
2766 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 =
2767 intel_format_convert(coeffs->y_k_h[0], 1, 6, 1);
2768 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 =
2769 intel_format_convert(coeffs->y_k_h[1], 1, 6, 1);
2770 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 =
2771 intel_format_convert(coeffs->y_k_h[2], 1, 6, 1);
2772 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 =
2773 intel_format_convert(coeffs->y_k_h[3], 1, 6, 1);
2774 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 =
2775 intel_format_convert(coeffs->y_k_h[4], 1, 6, 1);
2776 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 =
2777 intel_format_convert(coeffs->y_k_h[5], 1, 6, 1);
2778 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 =
2779 intel_format_convert(coeffs->y_k_h[6], 1, 6, 1);
2780 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 =
2781 intel_format_convert(coeffs->y_k_h[7], 1, 6, 1);
2783 sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 =
2784 intel_format_convert(coeffs->uv_k_h[0], 1, 6, 1);
2785 sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 =
2786 intel_format_convert(coeffs->uv_k_h[1], 1, 6, 1);
2787 sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 =
2788 intel_format_convert(coeffs->uv_k_h[2], 1, 6, 1);
2789 sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 =
2790 intel_format_convert(coeffs->uv_k_h[3], 1, 6, 1);
2792 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 =
2793 intel_format_convert(coeffs->y_k_v[0], 1, 6, 1);
2794 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 =
2795 intel_format_convert(coeffs->y_k_v[1], 1, 6, 1);
2796 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 =
2797 intel_format_convert(coeffs->y_k_v[2], 1, 6, 1);
2798 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 =
2799 intel_format_convert(coeffs->y_k_v[3], 1, 6, 1);
2800 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 =
2801 intel_format_convert(coeffs->y_k_v[4], 1, 6, 1);
2802 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 =
2803 intel_format_convert(coeffs->y_k_v[5], 1, 6, 1);
2804 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 =
2805 intel_format_convert(coeffs->y_k_v[6], 1, 6, 1);
2806 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 =
2807 intel_format_convert(coeffs->y_k_v[7], 1, 6, 1);
2809 sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 =
2810 intel_format_convert(coeffs->uv_k_v[0], 1, 6, 1);
2811 sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 =
2812 intel_format_convert(coeffs->uv_k_v[1], 1, 6, 1);
2813 sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 =
2814 intel_format_convert(coeffs->uv_k_v[2], 1, 6, 1);
2815 sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 =
2816 intel_format_convert(coeffs->uv_k_v[3], 1, 6, 1);
2819 /* Adaptive filter for all channels (DW4.15) */
2820 sampler_8x8_state->coefficients[0].dw4.table_1x_filter_c1 = 1U << 7;
2822 sampler_8x8_state->dw136.default_sharpness_level =
2823 -avs_is_needed(pp_context->filter_flags);
2824 sampler_8x8_state->dw137.ilk.bypass_y_adaptive_filtering = 1;
2825 sampler_8x8_state->dw137.ilk.bypass_x_adaptive_filtering = 1;
2826 dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
2829 dri_bo_map(pp_context->sampler_state_table.bo, True);
2830 assert(pp_context->sampler_state_table.bo->virtual);
2831 assert(sizeof(*sampler_8x8) == sizeof(int) * 16);
2832 sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
2834 /* sample_8x8 Y index 1 */
2836 memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2837 sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
2838 sampler_8x8[index].dw0.ief_bypass = 1;
2839 sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
2840 sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
2841 sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2842 sampler_8x8[index].dw2.global_noise_estimation = 22;
2843 sampler_8x8[index].dw2.strong_edge_threshold = 8;
2844 sampler_8x8[index].dw2.weak_edge_threshold = 1;
2845 sampler_8x8[index].dw3.strong_edge_weight = 7;
2846 sampler_8x8[index].dw3.regular_weight = 2;
2847 sampler_8x8[index].dw3.non_edge_weight = 0;
2848 sampler_8x8[index].dw3.gain_factor = 40;
2849 sampler_8x8[index].dw4.steepness_boost = 0;
2850 sampler_8x8[index].dw4.steepness_threshold = 0;
2851 sampler_8x8[index].dw4.mr_boost = 0;
2852 sampler_8x8[index].dw4.mr_threshold = 5;
2853 sampler_8x8[index].dw5.pwl1_point_1 = 4;
2854 sampler_8x8[index].dw5.pwl1_point_2 = 12;
2855 sampler_8x8[index].dw5.pwl1_point_3 = 16;
2856 sampler_8x8[index].dw5.pwl1_point_4 = 26;
2857 sampler_8x8[index].dw6.pwl1_point_5 = 40;
2858 sampler_8x8[index].dw6.pwl1_point_6 = 160;
2859 sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
2860 sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
2861 sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
2862 sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
2863 sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
2864 sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
2865 sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
2866 sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
2867 sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
2868 sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
2869 sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
2870 sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
2871 sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
2872 sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
2873 sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
2874 sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
2875 sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
2876 sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
2877 sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
2878 sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
2879 sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
2880 sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
2881 sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
2882 sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
2883 sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
2884 sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
2885 sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
2886 sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
2887 sampler_8x8[index].dw13.limiter_boost = 0;
2888 sampler_8x8[index].dw13.minimum_limiter = 10;
2889 sampler_8x8[index].dw13.maximum_limiter = 11;
2890 sampler_8x8[index].dw14.clip_limiter = 130;
2891 dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2892 I915_GEM_DOMAIN_RENDER,
2895 sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2896 pp_context->sampler_state_table.bo_8x8);
2898 /* sample_8x8 UV index 2 */
2900 memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
2901 sampler_8x8[index].dw0.avs_filter_type = AVS_FILTER_ADAPTIVE_8_TAP;
2902 sampler_8x8[index].dw0.ief_bypass = 1;
2903 sampler_8x8[index].dw0.ief_filter_type = IEF_FILTER_DETAIL;
2904 sampler_8x8[index].dw0.ief_filter_size = IEF_FILTER_SIZE_5X5;
2905 sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
2906 sampler_8x8[index].dw2.global_noise_estimation = 22;
2907 sampler_8x8[index].dw2.strong_edge_threshold = 8;
2908 sampler_8x8[index].dw2.weak_edge_threshold = 1;
2909 sampler_8x8[index].dw3.strong_edge_weight = 7;
2910 sampler_8x8[index].dw3.regular_weight = 2;
2911 sampler_8x8[index].dw3.non_edge_weight = 0;
2912 sampler_8x8[index].dw3.gain_factor = 40;
2913 sampler_8x8[index].dw4.steepness_boost = 0;
2914 sampler_8x8[index].dw4.steepness_threshold = 0;
2915 sampler_8x8[index].dw4.mr_boost = 0;
2916 sampler_8x8[index].dw4.mr_threshold = 5;
2917 sampler_8x8[index].dw5.pwl1_point_1 = 4;
2918 sampler_8x8[index].dw5.pwl1_point_2 = 12;
2919 sampler_8x8[index].dw5.pwl1_point_3 = 16;
2920 sampler_8x8[index].dw5.pwl1_point_4 = 26;
2921 sampler_8x8[index].dw6.pwl1_point_5 = 40;
2922 sampler_8x8[index].dw6.pwl1_point_6 = 160;
2923 sampler_8x8[index].dw6.pwl1_r3_bias_0 = 127;
2924 sampler_8x8[index].dw6.pwl1_r3_bias_1 = 98;
2925 sampler_8x8[index].dw7.pwl1_r3_bias_2 = 88;
2926 sampler_8x8[index].dw7.pwl1_r3_bias_3 = 64;
2927 sampler_8x8[index].dw7.pwl1_r3_bias_4 = 44;
2928 sampler_8x8[index].dw7.pwl1_r3_bias_5 = 0;
2929 sampler_8x8[index].dw8.pwl1_r3_bias_6 = 0;
2930 sampler_8x8[index].dw8.pwl1_r5_bias_0 = 3;
2931 sampler_8x8[index].dw8.pwl1_r5_bias_1 = 32;
2932 sampler_8x8[index].dw8.pwl1_r5_bias_2 = 32;
2933 sampler_8x8[index].dw9.pwl1_r5_bias_3 = 58;
2934 sampler_8x8[index].dw9.pwl1_r5_bias_4 = 100;
2935 sampler_8x8[index].dw9.pwl1_r5_bias_5 = 108;
2936 sampler_8x8[index].dw9.pwl1_r5_bias_6 = 88;
2937 sampler_8x8[index].dw10.pwl1_r3_slope_0 = -116;
2938 sampler_8x8[index].dw10.pwl1_r3_slope_1 = -20;
2939 sampler_8x8[index].dw10.pwl1_r3_slope_2 = -96;
2940 sampler_8x8[index].dw10.pwl1_r3_slope_3 = -32;
2941 sampler_8x8[index].dw11.pwl1_r3_slope_4 = -50;
2942 sampler_8x8[index].dw11.pwl1_r3_slope_5 = 0;
2943 sampler_8x8[index].dw11.pwl1_r3_slope_6 = 0;
2944 sampler_8x8[index].dw11.pwl1_r5_slope_0 = 116;
2945 sampler_8x8[index].dw12.pwl1_r5_slope_1 = 0;
2946 sampler_8x8[index].dw12.pwl1_r5_slope_2 = 114;
2947 sampler_8x8[index].dw12.pwl1_r5_slope_3 = 67;
2948 sampler_8x8[index].dw12.pwl1_r5_slope_4 = 9;
2949 sampler_8x8[index].dw13.pwl1_r5_slope_5 = -3;
2950 sampler_8x8[index].dw13.pwl1_r5_slope_6 = -15;
2951 sampler_8x8[index].dw13.limiter_boost = 0;
2952 sampler_8x8[index].dw13.minimum_limiter = 10;
2953 sampler_8x8[index].dw13.maximum_limiter = 11;
2954 sampler_8x8[index].dw14.clip_limiter = 130;
2955 dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
2956 I915_GEM_DOMAIN_RENDER,
2959 sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
2960 pp_context->sampler_state_table.bo_8x8);
2962 dri_bo_unmap(pp_context->sampler_state_table.bo);
2964 /* private function & data */
2965 pp_context->pp_x_steps = pp_avs_x_steps;
2966 pp_context->pp_y_steps = pp_avs_y_steps;
2967 pp_context->private_context = &pp_context->pp_avs_context;
2968 pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
2970 int dst_left_edge_extend = dst_rect->x%GPU_ASM_X_OFFSET_ALIGNMENT;
2971 float src_left_edge_extend = (float)dst_left_edge_extend*src_rect->width/dst_rect->width;
2972 pp_avs_context->dest_x = dst_rect->x - dst_left_edge_extend;
2973 pp_avs_context->dest_y = dst_rect->y;
2974 pp_avs_context->dest_w = ALIGN(dst_rect->width + dst_left_edge_extend, 16);
2975 pp_avs_context->dest_h = ALIGN(dst_rect->height, 8);
2976 pp_avs_context->src_normalized_x = (float)(src_rect->x - src_left_edge_extend)/ in_w;
2977 pp_avs_context->src_normalized_y = (float)src_rect->y / in_h;
2978 pp_avs_context->src_w = src_rect->width + src_left_edge_extend;
2979 pp_avs_context->src_h = src_rect->height;
2981 pp_static_parameter->grf4.r4_2.avs.nlas = nlas;
2982 pp_static_parameter->grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / dst_rect->height;
2984 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);
2985 pp_inline_parameter->grf5.block_count_x = 1; /* M x 1 */
2986 pp_inline_parameter->grf5.number_blocks = pp_avs_context->dest_h / 8;
2987 pp_inline_parameter->grf6.video_step_delta = 0.0;
2989 dst_surface->flags = src_surface->flags;
2991 return VA_STATUS_SUCCESS;
2995 gen6_nv12_scaling_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
2996 const struct i965_surface *src_surface,
2997 const VARectangle *src_rect,
2998 struct i965_surface *dst_surface,
2999 const VARectangle *dst_rect,
3002 return pp_nv12_avs_initialize(ctx, pp_context,
3011 gen7_pp_avs_x_steps(void *private_context)
3013 struct pp_avs_context *pp_avs_context = private_context;
3015 return pp_avs_context->dest_w / 16;
3019 gen7_pp_avs_y_steps(void *private_context)
3021 struct pp_avs_context *pp_avs_context = private_context;
3023 return pp_avs_context->dest_h / 16;
3027 gen7_pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3029 struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)pp_context->private_context;
3030 struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3032 pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
3033 pp_inline_parameter->grf7.destination_block_vertical_origin = y * 16 + pp_avs_context->dest_y;
3034 pp_inline_parameter->grf7.constant_0 = 0xffffffff;
3035 pp_inline_parameter->grf7.sampler_load_main_video_x_scaling_step = pp_avs_context->horiz_range / pp_avs_context->src_w;
3040 static void gen7_update_src_surface_uv_offset(VADriverContextP ctx,
3041 struct i965_post_processing_context *pp_context,
3042 const struct i965_surface *surface)
3044 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3045 int fourcc = pp_get_surface_fourcc(ctx, surface);
3047 if (fourcc == VA_FOURCC_YUY2) {
3048 pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
3049 pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
3050 pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
3051 } else if (fourcc == VA_FOURCC_UYVY) {
3052 pp_static_parameter->grf2.di_destination_packed_y_component_offset = 1;
3053 pp_static_parameter->grf2.di_destination_packed_u_component_offset = 0;
3054 pp_static_parameter->grf2.di_destination_packed_v_component_offset = 2;
3059 gen7_pp_plx_avs_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3060 const struct i965_surface *src_surface,
3061 const VARectangle *src_rect,
3062 struct i965_surface *dst_surface,
3063 const VARectangle *dst_rect,
3066 struct pp_avs_context *pp_avs_context = (struct pp_avs_context *)&pp_context->pp_avs_context;
3067 struct i965_driver_data *i965 = i965_driver_data(ctx);
3068 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3069 struct gen7_sampler_8x8 *sampler_8x8;
3070 struct i965_sampler_8x8_state *sampler_8x8_state;
3072 int width[3], height[3], pitch[3], offset[3];
3073 int src_width, src_height;
3074 AVSState * const avs = &pp_avs_context->state;
3077 /* source surface */
3078 gen7_pp_set_media_rw_message_surface(ctx, pp_context, src_surface, 0, 0,
3080 width, height, pitch, offset);
3081 src_width = width[0];
3082 src_height = height[0];
3084 /* destination surface */
3085 gen7_pp_set_media_rw_message_surface(ctx, pp_context, dst_surface, 24, 1,
3087 width, height, pitch, offset);
3089 /* sampler 8x8 state */
3090 dri_bo_map(pp_context->sampler_state_table.bo_8x8, True);
3091 assert(pp_context->sampler_state_table.bo_8x8->virtual);
3092 assert(sizeof(*sampler_8x8_state) == sizeof(int) * 138);
3093 sampler_8x8_state = pp_context->sampler_state_table.bo_8x8->virtual;
3094 memset(sampler_8x8_state, 0, sizeof(*sampler_8x8_state));
3096 sx = (float)dst_rect->width / src_rect->width;
3097 sy = (float)dst_rect->height / src_rect->height;
3098 avs_update_coefficients(avs, sx, sy, pp_context->filter_flags);
3100 assert(avs->config->num_phases == 16);
3101 for (i = 0; i <= 16; i++) {
3102 const AVSCoeffs * const coeffs = &avs->coeffs[i];
3104 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c0 =
3105 intel_format_convert(coeffs->y_k_h[0], 1, 6, 1);
3106 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c1 =
3107 intel_format_convert(coeffs->y_k_h[1], 1, 6, 1);
3108 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c2 =
3109 intel_format_convert(coeffs->y_k_h[2], 1, 6, 1);
3110 sampler_8x8_state->coefficients[i].dw0.table_0x_filter_c3 =
3111 intel_format_convert(coeffs->y_k_h[3], 1, 6, 1);
3112 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c4 =
3113 intel_format_convert(coeffs->y_k_h[4], 1, 6, 1);
3114 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c5 =
3115 intel_format_convert(coeffs->y_k_h[5], 1, 6, 1);
3116 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c6 =
3117 intel_format_convert(coeffs->y_k_h[6], 1, 6, 1);
3118 sampler_8x8_state->coefficients[i].dw1.table_0x_filter_c7 =
3119 intel_format_convert(coeffs->y_k_h[7], 1, 6, 1);
3121 sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c2 =
3122 intel_format_convert(coeffs->uv_k_h[0], 1, 6, 1);
3123 sampler_8x8_state->coefficients[i].dw4.table_1x_filter_c3 =
3124 intel_format_convert(coeffs->uv_k_h[1], 1, 6, 1);
3125 sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c4 =
3126 intel_format_convert(coeffs->uv_k_h[2], 1, 6, 1);
3127 sampler_8x8_state->coefficients[i].dw5.table_1x_filter_c5 =
3128 intel_format_convert(coeffs->uv_k_h[3], 1, 6, 1);
3130 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c0 =
3131 intel_format_convert(coeffs->y_k_v[0], 1, 6, 1);
3132 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c1 =
3133 intel_format_convert(coeffs->y_k_v[1], 1, 6, 1);
3134 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c2 =
3135 intel_format_convert(coeffs->y_k_v[2], 1, 6, 1);
3136 sampler_8x8_state->coefficients[i].dw2.table_0y_filter_c3 =
3137 intel_format_convert(coeffs->y_k_v[3], 1, 6, 1);
3138 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c4 =
3139 intel_format_convert(coeffs->y_k_v[4], 1, 6, 1);
3140 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c5 =
3141 intel_format_convert(coeffs->y_k_v[5], 1, 6, 1);
3142 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c6 =
3143 intel_format_convert(coeffs->y_k_v[6], 1, 6, 1);
3144 sampler_8x8_state->coefficients[i].dw3.table_0y_filter_c7 =
3145 intel_format_convert(coeffs->y_k_v[7], 1, 6, 1);
3147 sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c2 =
3148 intel_format_convert(coeffs->uv_k_v[0], 1, 6, 1);
3149 sampler_8x8_state->coefficients[i].dw6.table_1y_filter_c3 =
3150 intel_format_convert(coeffs->uv_k_v[1], 1, 6, 1);
3151 sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c4 =
3152 intel_format_convert(coeffs->uv_k_v[2], 1, 6, 1);
3153 sampler_8x8_state->coefficients[i].dw7.table_1y_filter_c5 =
3154 intel_format_convert(coeffs->uv_k_v[3], 1, 6, 1);
3157 sampler_8x8_state->dw136.default_sharpness_level =
3158 -avs_is_needed(pp_context->filter_flags);
3159 if (IS_HASWELL(i965->intel.device_info)) {
3160 sampler_8x8_state->dw137.hsw.adaptive_filter_for_all_channel = 1;
3161 sampler_8x8_state->dw137.hsw.bypass_y_adaptive_filtering = 1;
3162 sampler_8x8_state->dw137.hsw.bypass_x_adaptive_filtering = 1;
3165 sampler_8x8_state->coefficients[0].dw4.table_1x_filter_c1 = 1U << 7;
3166 sampler_8x8_state->dw137.ilk.bypass_y_adaptive_filtering = 1;
3167 sampler_8x8_state->dw137.ilk.bypass_x_adaptive_filtering = 1;
3169 dri_bo_unmap(pp_context->sampler_state_table.bo_8x8);
3172 dri_bo_map(pp_context->sampler_state_table.bo, True);
3173 assert(pp_context->sampler_state_table.bo->virtual);
3174 assert(sizeof(*sampler_8x8) == sizeof(int) * 4);
3175 sampler_8x8 = pp_context->sampler_state_table.bo->virtual;
3177 /* sample_8x8 Y index 4 */
3179 memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
3180 sampler_8x8[index].dw0.global_noise_estimation = 255;
3181 sampler_8x8[index].dw0.ief_bypass = 1;
3183 sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
3185 sampler_8x8[index].dw2.weak_edge_threshold = 1;
3186 sampler_8x8[index].dw2.strong_edge_threshold = 8;
3187 sampler_8x8[index].dw2.r5x_coefficient = 9;
3188 sampler_8x8[index].dw2.r5cx_coefficient = 8;
3189 sampler_8x8[index].dw2.r5c_coefficient = 3;
3191 sampler_8x8[index].dw3.r3x_coefficient = 27;
3192 sampler_8x8[index].dw3.r3c_coefficient = 5;
3193 sampler_8x8[index].dw3.gain_factor = 40;
3194 sampler_8x8[index].dw3.non_edge_weight = 1;
3195 sampler_8x8[index].dw3.regular_weight = 2;
3196 sampler_8x8[index].dw3.strong_edge_weight = 7;
3197 sampler_8x8[index].dw3.ief4_smooth_enable = 0;
3199 dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
3200 I915_GEM_DOMAIN_RENDER,
3203 sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
3204 pp_context->sampler_state_table.bo_8x8);
3206 /* sample_8x8 UV index 8 */
3208 memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
3209 sampler_8x8[index].dw0.disable_8x8_filter = 0;
3210 sampler_8x8[index].dw0.global_noise_estimation = 255;
3211 sampler_8x8[index].dw0.ief_bypass = 1;
3212 sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
3213 sampler_8x8[index].dw2.weak_edge_threshold = 1;
3214 sampler_8x8[index].dw2.strong_edge_threshold = 8;
3215 sampler_8x8[index].dw2.r5x_coefficient = 9;
3216 sampler_8x8[index].dw2.r5cx_coefficient = 8;
3217 sampler_8x8[index].dw2.r5c_coefficient = 3;
3218 sampler_8x8[index].dw3.r3x_coefficient = 27;
3219 sampler_8x8[index].dw3.r3c_coefficient = 5;
3220 sampler_8x8[index].dw3.gain_factor = 40;
3221 sampler_8x8[index].dw3.non_edge_weight = 1;
3222 sampler_8x8[index].dw3.regular_weight = 2;
3223 sampler_8x8[index].dw3.strong_edge_weight = 7;
3224 sampler_8x8[index].dw3.ief4_smooth_enable = 0;
3226 dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
3227 I915_GEM_DOMAIN_RENDER,
3230 sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
3231 pp_context->sampler_state_table.bo_8x8);
3233 /* sampler_8x8 V, index 12 */
3235 memset(&sampler_8x8[index], 0, sizeof(*sampler_8x8));
3236 sampler_8x8[index].dw0.disable_8x8_filter = 0;
3237 sampler_8x8[index].dw0.global_noise_estimation = 255;
3238 sampler_8x8[index].dw0.ief_bypass = 1;
3239 sampler_8x8[index].dw1.sampler_8x8_state_pointer = pp_context->sampler_state_table.bo_8x8->offset >> 5;
3240 sampler_8x8[index].dw2.weak_edge_threshold = 1;
3241 sampler_8x8[index].dw2.strong_edge_threshold = 8;
3242 sampler_8x8[index].dw2.r5x_coefficient = 9;
3243 sampler_8x8[index].dw2.r5cx_coefficient = 8;
3244 sampler_8x8[index].dw2.r5c_coefficient = 3;
3245 sampler_8x8[index].dw3.r3x_coefficient = 27;
3246 sampler_8x8[index].dw3.r3c_coefficient = 5;
3247 sampler_8x8[index].dw3.gain_factor = 40;
3248 sampler_8x8[index].dw3.non_edge_weight = 1;
3249 sampler_8x8[index].dw3.regular_weight = 2;
3250 sampler_8x8[index].dw3.strong_edge_weight = 7;
3251 sampler_8x8[index].dw3.ief4_smooth_enable = 0;
3253 dri_bo_emit_reloc(pp_context->sampler_state_table.bo,
3254 I915_GEM_DOMAIN_RENDER,
3257 sizeof(*sampler_8x8) * index + offsetof(struct i965_sampler_8x8, dw1),
3258 pp_context->sampler_state_table.bo_8x8);
3260 dri_bo_unmap(pp_context->sampler_state_table.bo);
3262 /* private function & data */
3263 pp_context->pp_x_steps = gen7_pp_avs_x_steps;
3264 pp_context->pp_y_steps = gen7_pp_avs_y_steps;
3265 pp_context->private_context = &pp_context->pp_avs_context;
3266 pp_context->pp_set_block_parameter = gen7_pp_avs_set_block_parameter;
3268 pp_avs_context->dest_x = dst_rect->x;
3269 pp_avs_context->dest_y = dst_rect->y;
3270 pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
3271 pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
3272 pp_avs_context->src_w = src_rect->width;
3273 pp_avs_context->src_h = src_rect->height;
3274 pp_avs_context->horiz_range = (float)src_rect->width / src_width;
3276 int dw = (pp_avs_context->src_w - 1) / 16 + 1;
3277 dw = MAX(dw, dst_rect->width);
3279 pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
3280 pp_static_parameter->grf2.avs_wa_enable = 1; /* must be set for GEN7 */
3281 if (IS_HASWELL(i965->intel.device_info))
3282 pp_static_parameter->grf2.avs_wa_enable = 0; /* HSW don't use the WA */
3284 if (pp_static_parameter->grf2.avs_wa_enable) {
3285 int src_fourcc = pp_get_surface_fourcc(ctx, src_surface);
3286 if ((src_fourcc == VA_FOURCC_RGBA) ||
3287 (src_fourcc == VA_FOURCC_RGBX) ||
3288 (src_fourcc == VA_FOURCC_BGRA) ||
3289 (src_fourcc == VA_FOURCC_BGRX)) {
3290 pp_static_parameter->grf2.avs_wa_enable = 0;
3294 pp_static_parameter->grf2.avs_wa_width = src_width;
3295 pp_static_parameter->grf2.avs_wa_one_div_256_width = (float) 1.0 / (256 * src_width);
3296 pp_static_parameter->grf2.avs_wa_five_div_256_width = (float) 5.0 / (256 * src_width);
3297 pp_static_parameter->grf2.alpha = 255;
3299 pp_static_parameter->grf3.sampler_load_horizontal_scaling_step_ratio = (float) pp_avs_context->src_w / dw;
3300 pp_static_parameter->grf4.sampler_load_vertical_scaling_step = (float) src_rect->height / src_height / dst_rect->height;
3301 pp_static_parameter->grf5.sampler_load_vertical_frame_origin = (float) src_rect->y / src_height -
3302 (float) pp_avs_context->dest_y * pp_static_parameter->grf4.sampler_load_vertical_scaling_step;
3303 pp_static_parameter->grf6.sampler_load_horizontal_frame_origin = (float) src_rect->x / src_width -
3304 (float) pp_avs_context->dest_x * pp_avs_context->horiz_range / dw;
3306 gen7_update_src_surface_uv_offset(ctx, pp_context, dst_surface);
3308 dst_surface->flags = src_surface->flags;
3310 return VA_STATUS_SUCCESS;
3314 pp_dndi_x_steps(void *private_context)
3320 pp_dndi_y_steps(void *private_context)
3322 struct pp_dndi_context *pp_dndi_context = private_context;
3324 return pp_dndi_context->dest_h / 4;
3328 pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3330 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3332 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
3333 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
3339 pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3340 const struct i965_surface *src_surface,
3341 const VARectangle *src_rect,
3342 struct i965_surface *dst_surface,
3343 const VARectangle *dst_rect,
3346 struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context;
3347 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3348 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3349 const VAProcPipelineParameterBuffer * const pipe_params =
3350 pp_context->pipeline_param;
3351 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
3353 struct object_surface * const src_obj_surface = (struct object_surface *)
3355 struct object_surface * const dst_obj_surface = (struct object_surface *)
3357 struct object_surface *obj_surface;
3358 struct i965_sampler_dndi *sampler_dndi;
3359 int index, dndi_top_first;
3360 int w, h, orig_w, orig_h;
3363 status = pp_dndi_context_init_surface_params(dndi_ctx, src_obj_surface,
3364 pipe_params, deint_params);
3365 if (status != VA_STATUS_SUCCESS)
3368 status = pp_dndi_context_ensure_surfaces(ctx, pp_context,
3369 src_obj_surface, dst_obj_surface);
3370 if (status != VA_STATUS_SUCCESS)
3373 status = pp_dndi_context_ensure_surfaces_storage(ctx, pp_context,
3374 src_obj_surface, dst_obj_surface);
3375 if (status != VA_STATUS_SUCCESS)
3378 /* Current input surface (index = 4) */
3379 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].obj_surface;
3380 i965_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0,
3381 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3382 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 4);
3384 /* Previous input surface (index = 5) */
3385 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS].obj_surface;
3386 i965_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0,
3387 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3388 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 5);
3390 /* STMM input surface (index = 6) */
3391 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_STMM].obj_surface;
3392 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3393 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3394 I965_SURFACEFORMAT_R8_UNORM, 6, 1);
3396 /* Previous output surfaces (index = { 7, 8 }) */
3397 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS].obj_surface;
3398 w = obj_surface->width;
3399 h = obj_surface->height;
3400 orig_w = obj_surface->orig_width;
3401 orig_h = obj_surface->orig_height;
3403 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3404 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 7, 1);
3405 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h,
3406 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 8, 1);
3408 /* Current output surfaces (index = { 10, 11 }) */
3409 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT].obj_surface;
3410 w = obj_surface->width;
3411 h = obj_surface->height;
3412 orig_w = obj_surface->orig_width;
3413 orig_h = obj_surface->orig_height;
3415 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3416 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 10, 1);
3417 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h,
3418 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 11, 1);
3420 /* STMM output surface (index = 20) */
3421 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM].obj_surface;
3422 i965_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3423 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3424 I965_SURFACEFORMAT_R8_UNORM, 20, 1);
3426 dndi_top_first = !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
3429 dri_bo_map(pp_context->sampler_state_table.bo, True);
3430 assert(pp_context->sampler_state_table.bo->virtual);
3431 assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3432 sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3434 /* sample dndi index 1 */
3436 sampler_dndi[index].dw0.denoise_asd_threshold = 38;
3437 sampler_dndi[index].dw0.denoise_history_delta = 7; // 0-15, default is 8
3438 sampler_dndi[index].dw0.denoise_maximum_history = 192; // 128-240
3439 sampler_dndi[index].dw0.denoise_stad_threshold = 140;
3441 sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 38;
3442 sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 1;
3443 sampler_dndi[index].dw1.stmm_c2 = 1;
3444 sampler_dndi[index].dw1.low_temporal_difference_threshold = 0;
3445 sampler_dndi[index].dw1.temporal_difference_threshold = 0;
3447 sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 20; // 0-31
3448 sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 1; // 0-15
3449 sampler_dndi[index].dw2.denoise_edge_threshold = 7; // 0-15
3450 sampler_dndi[index].dw2.good_neighbor_threshold = 12; // 0-63
3452 sampler_dndi[index].dw3.maximum_stmm = 150;
3453 sampler_dndi[index].dw3.multipler_for_vecm = 30;
3454 sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 125;
3455 sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3456 sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3458 sampler_dndi[index].dw4.sdi_delta = 5;
3459 sampler_dndi[index].dw4.sdi_threshold = 100;
3460 sampler_dndi[index].dw4.stmm_output_shift = 5; // stmm_max - stmm_min = 2 ^ stmm_output_shift
3461 sampler_dndi[index].dw4.stmm_shift_up = 1;
3462 sampler_dndi[index].dw4.stmm_shift_down = 3;
3463 sampler_dndi[index].dw4.minimum_stmm = 118;
3465 sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 175;
3466 sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 37;
3467 sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 100;
3468 sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 50;
3470 sampler_dndi[index].dw6.dn_enable = 1;
3471 sampler_dndi[index].dw6.di_enable = 1;
3472 sampler_dndi[index].dw6.di_partial = 0;
3473 sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3474 sampler_dndi[index].dw6.dndi_stream_id = 0;
3475 sampler_dndi[index].dw6.dndi_first_frame = dndi_ctx->is_first_frame;
3476 sampler_dndi[index].dw6.progressive_dn = 0;
3477 sampler_dndi[index].dw6.fmd_tear_threshold = 2;
3478 sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100;
3479 sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 16;
3481 sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
3482 sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
3483 sampler_dndi[index].dw7.vdi_walker_enable = 0;
3484 sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3486 dri_bo_unmap(pp_context->sampler_state_table.bo);
3488 /* private function & data */
3489 pp_context->pp_x_steps = pp_dndi_x_steps;
3490 pp_context->pp_y_steps = pp_dndi_y_steps;
3491 pp_context->private_context = dndi_ctx;
3492 pp_context->pp_set_block_parameter = pp_dndi_set_block_parameter;
3494 pp_static_parameter->grf1.statistics_surface_picth = w / 2;
3495 pp_static_parameter->grf1.r1_6.di.top_field_first = dndi_top_first;
3496 pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 0;
3497 pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 0;
3499 pp_inline_parameter->grf5.block_count_x = w / 16; /* 1 x N */
3500 pp_inline_parameter->grf5.number_blocks = w / 16;
3501 pp_inline_parameter->grf5.block_vertical_mask = 0xff;
3502 pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
3504 dndi_ctx->dest_w = w;
3505 dndi_ctx->dest_h = h;
3507 dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3508 return VA_STATUS_SUCCESS;
3512 pp_dn_x_steps(void *private_context)
3518 pp_dn_y_steps(void *private_context)
3520 struct pp_dn_context *pp_dn_context = private_context;
3522 return pp_dn_context->dest_h / 8;
3526 pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3528 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3530 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
3531 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 8;
3537 pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3538 const struct i965_surface *src_surface,
3539 const VARectangle *src_rect,
3540 struct i965_surface *dst_surface,
3541 const VARectangle *dst_rect,
3544 struct i965_driver_data *i965 = i965_driver_data(ctx);
3545 struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->pp_dn_context;
3546 struct object_surface *obj_surface;
3547 struct i965_sampler_dndi *sampler_dndi;
3548 struct pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3549 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3550 VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
3554 int dn_strength = 15;
3555 int dndi_top_first = 1;
3556 int dn_progressive = 0;
3558 if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
3561 } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
3569 if (dn_filter_param) {
3570 float value = dn_filter_param->value;
3578 dn_strength = (int)(value * 31.0F);
3582 obj_surface = (struct object_surface *)src_surface->base;
3583 orig_w = obj_surface->orig_width;
3584 orig_h = obj_surface->orig_height;
3585 w = obj_surface->width;
3586 h = obj_surface->height;
3588 if (pp_dn_context->stmm_bo == NULL) {
3589 pp_dn_context->stmm_bo = dri_bo_alloc(i965->intel.bufmgr,
3593 assert(pp_dn_context->stmm_bo);
3596 /* source UV surface index 2 */
3597 i965_pp_set_surface_state(ctx, pp_context,
3598 obj_surface->bo, w * h,
3599 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3602 /* source YUV surface index 4 */
3603 i965_pp_set_surface2_state(ctx, pp_context,
3607 SURFACE_FORMAT_PLANAR_420_8, 1,
3610 /* source STMM surface index 20 */
3611 i965_pp_set_surface_state(ctx, pp_context,
3612 pp_dn_context->stmm_bo, 0,
3613 orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3616 /* destination surface */
3617 obj_surface = (struct object_surface *)dst_surface->base;
3618 orig_w = obj_surface->orig_width;
3619 orig_h = obj_surface->orig_height;
3620 w = obj_surface->width;
3621 h = obj_surface->height;
3623 /* destination Y surface index 7 */
3624 i965_pp_set_surface_state(ctx, pp_context,
3626 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
3629 /* destination UV surface index 8 */
3630 i965_pp_set_surface_state(ctx, pp_context,
3631 obj_surface->bo, w * h,
3632 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
3635 dri_bo_map(pp_context->sampler_state_table.bo, True);
3636 assert(pp_context->sampler_state_table.bo->virtual);
3637 assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3638 sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3640 /* sample dndi index 1 */
3642 sampler_dndi[index].dw0.denoise_asd_threshold = 0;
3643 sampler_dndi[index].dw0.denoise_history_delta = 8; // 0-15, default is 8
3644 sampler_dndi[index].dw0.denoise_maximum_history = 128; // 128-240
3645 sampler_dndi[index].dw0.denoise_stad_threshold = 0;
3647 sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
3648 sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 0;
3649 sampler_dndi[index].dw1.stmm_c2 = 0;
3650 sampler_dndi[index].dw1.low_temporal_difference_threshold = 8;
3651 sampler_dndi[index].dw1.temporal_difference_threshold = 16;
3653 sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = dn_strength; // 0-31
3654 sampler_dndi[index].dw2.block_noise_estimate_edge_threshold = 7; // 0-15
3655 sampler_dndi[index].dw2.denoise_edge_threshold = 7; // 0-15
3656 sampler_dndi[index].dw2.good_neighbor_threshold = 7; // 0-63
3658 sampler_dndi[index].dw3.maximum_stmm = 128;
3659 sampler_dndi[index].dw3.multipler_for_vecm = 2;
3660 sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
3661 sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3662 sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3664 sampler_dndi[index].dw4.sdi_delta = 8;
3665 sampler_dndi[index].dw4.sdi_threshold = 128;
3666 sampler_dndi[index].dw4.stmm_output_shift = 7; // stmm_max - stmm_min = 2 ^ stmm_output_shift
3667 sampler_dndi[index].dw4.stmm_shift_up = 0;
3668 sampler_dndi[index].dw4.stmm_shift_down = 0;
3669 sampler_dndi[index].dw4.minimum_stmm = 0;
3671 sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 0;
3672 sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 0;
3673 sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
3674 sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
3676 sampler_dndi[index].dw6.dn_enable = 1;
3677 sampler_dndi[index].dw6.di_enable = 0;
3678 sampler_dndi[index].dw6.di_partial = 0;
3679 sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3680 sampler_dndi[index].dw6.dndi_stream_id = 1;
3681 sampler_dndi[index].dw6.dndi_first_frame = 1;
3682 sampler_dndi[index].dw6.progressive_dn = dn_progressive;
3683 sampler_dndi[index].dw6.fmd_tear_threshold = 32;
3684 sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 32;
3685 sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 32;
3687 sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 2;
3688 sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
3689 sampler_dndi[index].dw7.vdi_walker_enable = 0;
3690 sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3692 dri_bo_unmap(pp_context->sampler_state_table.bo);
3694 /* private function & data */
3695 pp_context->pp_x_steps = pp_dn_x_steps;
3696 pp_context->pp_y_steps = pp_dn_y_steps;
3697 pp_context->private_context = &pp_context->pp_dn_context;
3698 pp_context->pp_set_block_parameter = pp_dn_set_block_parameter;
3700 pp_static_parameter->grf1.statistics_surface_picth = w / 2;
3701 pp_static_parameter->grf1.r1_6.di.top_field_first = 0;
3702 pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m2 = 64;
3703 pp_static_parameter->grf4.r4_2.di.motion_history_coefficient_m1 = 192;
3705 pp_inline_parameter->grf5.block_count_x = w / 16; /* 1 x N */
3706 pp_inline_parameter->grf5.number_blocks = w / 16;
3707 pp_inline_parameter->grf5.block_vertical_mask = 0xff;
3708 pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
3710 pp_dn_context->dest_w = w;
3711 pp_dn_context->dest_h = h;
3713 dst_surface->flags = src_surface->flags;
3715 return VA_STATUS_SUCCESS;
3719 gen7_pp_dndi_x_steps(void *private_context)
3721 struct pp_dndi_context *pp_dndi_context = private_context;
3723 return pp_dndi_context->dest_w / 16;
3727 gen7_pp_dndi_y_steps(void *private_context)
3729 struct pp_dndi_context *pp_dndi_context = private_context;
3731 return pp_dndi_context->dest_h / 4;
3735 gen7_pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3737 struct gen7_pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3739 pp_inline_parameter->grf7.destination_block_horizontal_origin = x * 16;
3740 pp_inline_parameter->grf7.destination_block_vertical_origin = y * 4;
3746 gen7_pp_nv12_dndi_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3747 const struct i965_surface *src_surface,
3748 const VARectangle *src_rect,
3749 struct i965_surface *dst_surface,
3750 const VARectangle *dst_rect,
3753 struct pp_dndi_context * const dndi_ctx = &pp_context->pp_dndi_context;
3754 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3755 const VAProcPipelineParameterBuffer * const pipe_params =
3756 pp_context->pipeline_param;
3757 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
3759 struct object_surface * const src_obj_surface = (struct object_surface *)
3761 struct object_surface * const dst_obj_surface = (struct object_surface *)
3763 struct object_surface *obj_surface;
3764 struct gen7_sampler_dndi *sampler_dndi;
3765 int index, dndi_top_first;
3766 int w, h, orig_w, orig_h;
3769 status = pp_dndi_context_init_surface_params(dndi_ctx, src_obj_surface,
3770 pipe_params, deint_params);
3771 if (status != VA_STATUS_SUCCESS)
3774 status = pp_dndi_context_ensure_surfaces(ctx, pp_context,
3775 src_obj_surface, dst_obj_surface);
3776 if (status != VA_STATUS_SUCCESS)
3779 status = pp_dndi_context_ensure_surfaces_storage(ctx, pp_context,
3780 src_obj_surface, dst_obj_surface);
3781 if (status != VA_STATUS_SUCCESS)
3784 /* Current input surface (index = 3) */
3785 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_CURRENT].obj_surface;
3786 gen7_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0,
3787 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3788 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 3);
3790 /* Previous input surface (index = 4) */
3791 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_PREVIOUS].obj_surface;
3792 gen7_pp_set_surface2_state(ctx, pp_context, obj_surface->bo, 0,
3793 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3794 0, obj_surface->y_cb_offset, SURFACE_FORMAT_PLANAR_420_8, 1, 4);
3796 /* STMM input surface (index = 5) */
3797 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_IN_STMM].obj_surface;
3798 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3799 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3800 I965_SURFACEFORMAT_R8_UNORM, 5, 1);
3802 /* Previous output surfaces (index = { 27, 28 }) */
3803 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_PREVIOUS].obj_surface;
3804 w = obj_surface->width;
3805 h = obj_surface->height;
3806 orig_w = obj_surface->orig_width;
3807 orig_h = obj_surface->orig_height;
3809 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3810 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 27, 1);
3811 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h,
3812 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 28, 1);
3814 /* Current output surfaces (index = { 30, 31 }) */
3815 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_CURRENT].obj_surface;
3816 w = obj_surface->width;
3817 h = obj_surface->height;
3818 orig_w = obj_surface->orig_width;
3819 orig_h = obj_surface->orig_height;
3821 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3822 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM, 30, 1);
3823 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, w * h,
3824 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM, 31, 1);
3826 /* STMM output surface (index = 33) */
3827 obj_surface = dndi_ctx->frame_store[DNDI_FRAME_OUT_STMM].obj_surface;
3828 gen7_pp_set_surface_state(ctx, pp_context, obj_surface->bo, 0,
3829 obj_surface->orig_width, obj_surface->orig_height, obj_surface->width,
3830 I965_SURFACEFORMAT_R8_UNORM, 33, 1);
3832 dndi_top_first = !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
3835 dri_bo_map(pp_context->sampler_state_table.bo, True);
3836 assert(pp_context->sampler_state_table.bo->virtual);
3837 assert(sizeof(*sampler_dndi) == sizeof(int) * 8);
3838 sampler_dndi = pp_context->sampler_state_table.bo->virtual;
3840 /* sample dndi index 0 */
3842 sampler_dndi[index].dw0.denoise_asd_threshold = 38;
3843 sampler_dndi[index].dw0.dnmh_delt = 7;
3844 sampler_dndi[index].dw0.vdi_walker_y_stride = 0;
3845 sampler_dndi[index].dw0.vdi_walker_frame_sharing_enable = 0;
3846 sampler_dndi[index].dw0.denoise_maximum_history = 192; // 128-240
3847 sampler_dndi[index].dw0.denoise_stad_threshold = 140;
3849 sampler_dndi[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 38;
3850 sampler_dndi[index].dw1.denoise_moving_pixel_threshold = 1;
3851 sampler_dndi[index].dw1.stmm_c2 = 2;
3852 sampler_dndi[index].dw1.low_temporal_difference_threshold = 0;
3853 sampler_dndi[index].dw1.temporal_difference_threshold = 0;
3855 sampler_dndi[index].dw2.block_noise_estimate_noise_threshold = 20; // 0-31
3856 sampler_dndi[index].dw2.bne_edge_th = 1;
3857 sampler_dndi[index].dw2.smooth_mv_th = 0;
3858 sampler_dndi[index].dw2.sad_tight_th = 5;
3859 sampler_dndi[index].dw2.cat_slope_minus1 = 9;
3860 sampler_dndi[index].dw2.good_neighbor_th = 12;
3862 sampler_dndi[index].dw3.maximum_stmm = 150;
3863 sampler_dndi[index].dw3.multipler_for_vecm = 30;
3864 sampler_dndi[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 125;
3865 sampler_dndi[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
3866 sampler_dndi[index].dw3.stmm_blending_constant_select = 0;
3868 sampler_dndi[index].dw4.sdi_delta = 5;
3869 sampler_dndi[index].dw4.sdi_threshold = 100;
3870 sampler_dndi[index].dw4.stmm_output_shift = 5; // stmm_max - stmm_min = 2 ^ stmm_output_shift
3871 sampler_dndi[index].dw4.stmm_shift_up = 1;
3872 sampler_dndi[index].dw4.stmm_shift_down = 3;
3873 sampler_dndi[index].dw4.minimum_stmm = 118;
3875 sampler_dndi[index].dw5.fmd_temporal_difference_threshold = 175;
3876 sampler_dndi[index].dw5.sdi_fallback_mode_2_constant = 37;
3877 sampler_dndi[index].dw5.sdi_fallback_mode_1_t2_constant = 100;
3878 sampler_dndi[index].dw5.sdi_fallback_mode_1_t1_constant = 50;
3879 sampler_dndi[index].dw6.dn_enable = 0;
3880 sampler_dndi[index].dw6.di_enable = 1;
3881 sampler_dndi[index].dw6.di_partial = 0;
3882 sampler_dndi[index].dw6.dndi_top_first = dndi_top_first;
3883 sampler_dndi[index].dw6.dndi_stream_id = 1;
3884 sampler_dndi[index].dw6.dndi_first_frame = dndi_ctx->is_first_frame;
3885 sampler_dndi[index].dw6.progressive_dn = 0;
3886 sampler_dndi[index].dw6.mcdi_enable =
3887 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
3888 sampler_dndi[index].dw6.fmd_tear_threshold = 2;
3889 sampler_dndi[index].dw6.cat_th1 = 0;
3890 sampler_dndi[index].dw6.fmd2_vertical_difference_threshold = 100;
3891 sampler_dndi[index].dw6.fmd1_vertical_difference_threshold = 16;
3893 sampler_dndi[index].dw7.sad_tha = 5;
3894 sampler_dndi[index].dw7.sad_thb = 10;
3895 sampler_dndi[index].dw7.fmd_for_1st_field_of_current_frame = 0;
3896 sampler_dndi[index].dw7.mc_pixel_consistency_th = 25;
3897 sampler_dndi[index].dw7.fmd_for_2nd_field_of_previous_frame = 0;
3898 sampler_dndi[index].dw7.vdi_walker_enable = 0;
3899 sampler_dndi[index].dw7.neighborpixel_th = 10;
3900 sampler_dndi[index].dw7.column_width_minus1 = w / 16;
3902 dri_bo_unmap(pp_context->sampler_state_table.bo);
3904 /* private function & data */
3905 pp_context->pp_x_steps = gen7_pp_dndi_x_steps;
3906 pp_context->pp_y_steps = gen7_pp_dndi_y_steps;
3907 pp_context->private_context = dndi_ctx;
3908 pp_context->pp_set_block_parameter = gen7_pp_dndi_set_block_parameter;
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;
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;
3919 pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
3920 pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
3922 dndi_ctx->dest_w = w;
3923 dndi_ctx->dest_h = h;
3925 dst_surface->flags = I965_SURFACE_FLAG_FRAME;
3926 return VA_STATUS_SUCCESS;
3930 gen7_pp_dn_x_steps(void *private_context)
3932 struct pp_dn_context *pp_dn_context = private_context;
3934 return pp_dn_context->dest_w / 16;
3938 gen7_pp_dn_y_steps(void *private_context)
3940 struct pp_dn_context *pp_dn_context = private_context;
3942 return pp_dn_context->dest_h / 4;
3946 gen7_pp_dn_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
3948 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
3950 pp_inline_parameter->grf5.destination_block_horizontal_origin = x * 16;
3951 pp_inline_parameter->grf5.destination_block_vertical_origin = y * 4;
3957 gen7_pp_nv12_dn_initialize(VADriverContextP ctx, struct i965_post_processing_context *pp_context,
3958 const struct i965_surface *src_surface,
3959 const VARectangle *src_rect,
3960 struct i965_surface *dst_surface,
3961 const VARectangle *dst_rect,
3964 struct i965_driver_data *i965 = i965_driver_data(ctx);
3965 struct pp_dn_context *pp_dn_context = (struct pp_dn_context *)&pp_context->pp_dn_context;
3966 struct gen7_pp_static_parameter *pp_static_parameter = pp_context->pp_static_parameter;
3967 struct object_surface *obj_surface;
3968 struct gen7_sampler_dndi *sampler_dn;
3969 VAProcFilterParameterBuffer *dn_filter_param = filter_param; /* FIXME: parameter */
3973 int dn_strength = 15;
3974 int dndi_top_first = 1;
3975 int dn_progressive = 0;
3977 if (src_surface->flags == I965_SURFACE_FLAG_FRAME) {
3980 } else if (src_surface->flags == I965_SURFACE_FLAG_TOP_FIELD_FIRST) {
3988 if (dn_filter_param) {
3989 float value = dn_filter_param->value;
3997 dn_strength = (int)(value * 31.0F);
4001 obj_surface = (struct object_surface *)src_surface->base;
4002 orig_w = obj_surface->orig_width;
4003 orig_h = obj_surface->orig_height;
4004 w = obj_surface->width;
4005 h = obj_surface->height;
4007 if (pp_dn_context->stmm_bo == NULL) {
4008 pp_dn_context->stmm_bo= dri_bo_alloc(i965->intel.bufmgr,
4012 assert(pp_dn_context->stmm_bo);
4015 /* source UV surface index 1 */
4016 gen7_pp_set_surface_state(ctx, pp_context,
4017 obj_surface->bo, w * h,
4018 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
4021 /* source YUV surface index 3 */
4022 gen7_pp_set_surface2_state(ctx, pp_context,
4026 SURFACE_FORMAT_PLANAR_420_8, 1,
4029 /* source (temporal reference) YUV surface index 4 */
4030 gen7_pp_set_surface2_state(ctx, pp_context,
4034 SURFACE_FORMAT_PLANAR_420_8, 1,
4037 /* STMM / History Statistics input surface, index 5 */
4038 gen7_pp_set_surface_state(ctx, pp_context,
4039 pp_dn_context->stmm_bo, 0,
4040 orig_w, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
4043 /* destination surface */
4044 obj_surface = (struct object_surface *)dst_surface->base;
4045 orig_w = obj_surface->orig_width;
4046 orig_h = obj_surface->orig_height;
4047 w = obj_surface->width;
4048 h = obj_surface->height;
4050 /* destination Y surface index 24 */
4051 gen7_pp_set_surface_state(ctx, pp_context,
4053 ALIGN(orig_w, 4) / 4, orig_h, w, I965_SURFACEFORMAT_R8_UNORM,
4056 /* destination UV surface index 25 */
4057 gen7_pp_set_surface_state(ctx, pp_context,
4058 obj_surface->bo, w * h,
4059 ALIGN(orig_w, 4) / 4, orig_h / 2, w, I965_SURFACEFORMAT_R8G8_UNORM,
4063 dri_bo_map(pp_context->sampler_state_table.bo, True);
4064 assert(pp_context->sampler_state_table.bo->virtual);
4065 assert(sizeof(*sampler_dn) == sizeof(int) * 8);
4066 sampler_dn = pp_context->sampler_state_table.bo->virtual;
4068 /* sample dn index 1 */
4070 sampler_dn[index].dw0.denoise_asd_threshold = 0;
4071 sampler_dn[index].dw0.dnmh_delt = 8;
4072 sampler_dn[index].dw0.vdi_walker_y_stride = 0;
4073 sampler_dn[index].dw0.vdi_walker_frame_sharing_enable = 0;
4074 sampler_dn[index].dw0.denoise_maximum_history = 128; // 128-240
4075 sampler_dn[index].dw0.denoise_stad_threshold = 0;
4077 sampler_dn[index].dw1.denoise_threshold_for_sum_of_complexity_measure = 64;
4078 sampler_dn[index].dw1.denoise_moving_pixel_threshold = 0;
4079 sampler_dn[index].dw1.stmm_c2 = 0;
4080 sampler_dn[index].dw1.low_temporal_difference_threshold = 8;
4081 sampler_dn[index].dw1.temporal_difference_threshold = 16;
4083 sampler_dn[index].dw2.block_noise_estimate_noise_threshold = dn_strength; // 0-31
4084 sampler_dn[index].dw2.bne_edge_th = 1;
4085 sampler_dn[index].dw2.smooth_mv_th = 0;
4086 sampler_dn[index].dw2.sad_tight_th = 5;
4087 sampler_dn[index].dw2.cat_slope_minus1 = 9;
4088 sampler_dn[index].dw2.good_neighbor_th = 4;
4090 sampler_dn[index].dw3.maximum_stmm = 128;
4091 sampler_dn[index].dw3.multipler_for_vecm = 2;
4092 sampler_dn[index].dw3.blending_constant_across_time_for_small_values_of_stmm = 0;
4093 sampler_dn[index].dw3.blending_constant_across_time_for_large_values_of_stmm = 64;
4094 sampler_dn[index].dw3.stmm_blending_constant_select = 0;
4096 sampler_dn[index].dw4.sdi_delta = 8;
4097 sampler_dn[index].dw4.sdi_threshold = 128;
4098 sampler_dn[index].dw4.stmm_output_shift = 7; // stmm_max - stmm_min = 2 ^ stmm_output_shift
4099 sampler_dn[index].dw4.stmm_shift_up = 0;
4100 sampler_dn[index].dw4.stmm_shift_down = 0;
4101 sampler_dn[index].dw4.minimum_stmm = 0;
4103 sampler_dn[index].dw5.fmd_temporal_difference_threshold = 0;
4104 sampler_dn[index].dw5.sdi_fallback_mode_2_constant = 0;
4105 sampler_dn[index].dw5.sdi_fallback_mode_1_t2_constant = 0;
4106 sampler_dn[index].dw5.sdi_fallback_mode_1_t1_constant = 0;
4108 sampler_dn[index].dw6.dn_enable = 1;
4109 sampler_dn[index].dw6.di_enable = 0;
4110 sampler_dn[index].dw6.di_partial = 0;
4111 sampler_dn[index].dw6.dndi_top_first = dndi_top_first;
4112 sampler_dn[index].dw6.dndi_stream_id = 1;
4113 sampler_dn[index].dw6.dndi_first_frame = 1;
4114 sampler_dn[index].dw6.progressive_dn = dn_progressive;
4115 sampler_dn[index].dw6.mcdi_enable = 0;
4116 sampler_dn[index].dw6.fmd_tear_threshold = 32;
4117 sampler_dn[index].dw6.cat_th1 = 0;
4118 sampler_dn[index].dw6.fmd2_vertical_difference_threshold = 32;
4119 sampler_dn[index].dw6.fmd1_vertical_difference_threshold = 32;
4121 sampler_dn[index].dw7.sad_tha = 5;
4122 sampler_dn[index].dw7.sad_thb = 10;
4123 sampler_dn[index].dw7.fmd_for_1st_field_of_current_frame = 2;
4124 sampler_dn[index].dw7.mc_pixel_consistency_th = 25;
4125 sampler_dn[index].dw7.fmd_for_2nd_field_of_previous_frame = 1;
4126 sampler_dn[index].dw7.vdi_walker_enable = 0;
4127 sampler_dn[index].dw7.neighborpixel_th = 10;
4128 sampler_dn[index].dw7.column_width_minus1 = w / 16;
4130 dri_bo_unmap(pp_context->sampler_state_table.bo);
4132 /* private function & data */
4133 pp_context->pp_x_steps = gen7_pp_dn_x_steps;
4134 pp_context->pp_y_steps = gen7_pp_dn_y_steps;
4135 pp_context->private_context = &pp_context->pp_dn_context;
4136 pp_context->pp_set_block_parameter = gen7_pp_dn_set_block_parameter;
4138 pp_static_parameter->grf1.di_statistics_surface_pitch_div2 = w / 2;
4139 pp_static_parameter->grf1.di_statistics_surface_height_div4 = h / 4;
4140 pp_static_parameter->grf1.di_top_field_first = 0;
4141 pp_static_parameter->grf1.pointer_to_inline_parameter = 7;
4143 pp_static_parameter->grf2.di_destination_packed_y_component_offset = 0;
4144 pp_static_parameter->grf2.di_destination_packed_u_component_offset = 1;
4145 pp_static_parameter->grf2.di_destination_packed_v_component_offset = 3;
4147 pp_static_parameter->grf4.di_hoffset_svf_from_dvf = 0;
4148 pp_static_parameter->grf4.di_voffset_svf_from_dvf = 0;
4150 pp_dn_context->dest_w = w;
4151 pp_dn_context->dest_h = h;
4153 dst_surface->flags = src_surface->flags;
4155 return VA_STATUS_SUCCESS;
4159 ironlake_pp_initialize(
4160 VADriverContextP ctx,
4161 struct i965_post_processing_context *pp_context,
4162 const struct i965_surface *src_surface,
4163 const VARectangle *src_rect,
4164 struct i965_surface *dst_surface,
4165 const VARectangle *dst_rect,
4171 struct i965_driver_data *i965 = i965_driver_data(ctx);
4172 struct pp_module *pp_module;
4174 int static_param_size, inline_param_size;
4176 dri_bo_unreference(pp_context->surface_state_binding_table.bo);
4177 bo = dri_bo_alloc(i965->intel.bufmgr,
4178 "surface state & binding table",
4179 (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
4182 pp_context->surface_state_binding_table.bo = bo;
4184 dri_bo_unreference(pp_context->curbe.bo);
4185 bo = dri_bo_alloc(i965->intel.bufmgr,
4190 pp_context->curbe.bo = bo;
4192 dri_bo_unreference(pp_context->idrt.bo);
4193 bo = dri_bo_alloc(i965->intel.bufmgr,
4194 "interface discriptor",
4195 sizeof(struct i965_interface_descriptor),
4198 pp_context->idrt.bo = bo;
4199 pp_context->idrt.num_interface_descriptors = 0;
4201 dri_bo_unreference(pp_context->sampler_state_table.bo);
4202 bo = dri_bo_alloc(i965->intel.bufmgr,
4203 "sampler state table",
4207 dri_bo_map(bo, True);
4208 memset(bo->virtual, 0, bo->size);
4210 pp_context->sampler_state_table.bo = bo;
4212 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
4213 bo = dri_bo_alloc(i965->intel.bufmgr,
4214 "sampler 8x8 state ",
4218 pp_context->sampler_state_table.bo_8x8 = bo;
4220 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
4221 bo = dri_bo_alloc(i965->intel.bufmgr,
4222 "sampler 8x8 state ",
4226 pp_context->sampler_state_table.bo_8x8_uv = bo;
4228 dri_bo_unreference(pp_context->vfe_state.bo);
4229 bo = dri_bo_alloc(i965->intel.bufmgr,
4231 sizeof(struct i965_vfe_state),
4234 pp_context->vfe_state.bo = bo;
4236 static_param_size = sizeof(struct pp_static_parameter);
4237 inline_param_size = sizeof(struct pp_inline_parameter);
4239 memset(pp_context->pp_static_parameter, 0, static_param_size);
4240 memset(pp_context->pp_inline_parameter, 0, inline_param_size);
4242 assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
4243 pp_context->current_pp = pp_index;
4244 pp_module = &pp_context->pp_modules[pp_index];
4246 if (pp_module->initialize)
4247 va_status = pp_module->initialize(ctx, pp_context,
4254 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4260 ironlake_post_processing(
4261 VADriverContextP ctx,
4262 struct i965_post_processing_context *pp_context,
4263 const struct i965_surface *src_surface,
4264 const VARectangle *src_rect,
4265 struct i965_surface *dst_surface,
4266 const VARectangle *dst_rect,
4273 va_status = ironlake_pp_initialize(ctx, pp_context,
4281 if (va_status == VA_STATUS_SUCCESS) {
4282 ironlake_pp_states_setup(ctx, pp_context);
4283 ironlake_pp_pipeline_setup(ctx, pp_context);
4291 VADriverContextP ctx,
4292 struct i965_post_processing_context *pp_context,
4293 const struct i965_surface *src_surface,
4294 const VARectangle *src_rect,
4295 struct i965_surface *dst_surface,
4296 const VARectangle *dst_rect,
4302 struct i965_driver_data *i965 = i965_driver_data(ctx);
4303 struct pp_module *pp_module;
4305 int static_param_size, inline_param_size;
4307 dri_bo_unreference(pp_context->surface_state_binding_table.bo);
4308 bo = dri_bo_alloc(i965->intel.bufmgr,
4309 "surface state & binding table",
4310 (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_PP_SURFACES,
4313 pp_context->surface_state_binding_table.bo = bo;
4315 dri_bo_unreference(pp_context->curbe.bo);
4316 bo = dri_bo_alloc(i965->intel.bufmgr,
4321 pp_context->curbe.bo = bo;
4323 dri_bo_unreference(pp_context->idrt.bo);
4324 bo = dri_bo_alloc(i965->intel.bufmgr,
4325 "interface discriptor",
4326 sizeof(struct gen6_interface_descriptor_data),
4329 pp_context->idrt.bo = bo;
4330 pp_context->idrt.num_interface_descriptors = 0;
4332 dri_bo_unreference(pp_context->sampler_state_table.bo);
4333 bo = dri_bo_alloc(i965->intel.bufmgr,
4334 "sampler state table",
4338 dri_bo_map(bo, True);
4339 memset(bo->virtual, 0, bo->size);
4341 pp_context->sampler_state_table.bo = bo;
4343 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
4344 bo = dri_bo_alloc(i965->intel.bufmgr,
4345 "sampler 8x8 state ",
4349 pp_context->sampler_state_table.bo_8x8 = bo;
4351 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
4352 bo = dri_bo_alloc(i965->intel.bufmgr,
4353 "sampler 8x8 state ",
4357 pp_context->sampler_state_table.bo_8x8_uv = bo;
4359 dri_bo_unreference(pp_context->vfe_state.bo);
4360 bo = dri_bo_alloc(i965->intel.bufmgr,
4362 sizeof(struct i965_vfe_state),
4365 pp_context->vfe_state.bo = bo;
4367 if (IS_GEN7(i965->intel.device_info)) {
4368 static_param_size = sizeof(struct gen7_pp_static_parameter);
4369 inline_param_size = sizeof(struct gen7_pp_inline_parameter);
4371 static_param_size = sizeof(struct pp_static_parameter);
4372 inline_param_size = sizeof(struct pp_inline_parameter);
4375 memset(pp_context->pp_static_parameter, 0, static_param_size);
4376 memset(pp_context->pp_inline_parameter, 0, inline_param_size);
4378 assert(pp_index >= PP_NULL && pp_index < NUM_PP_MODULES);
4379 pp_context->current_pp = pp_index;
4380 pp_module = &pp_context->pp_modules[pp_index];
4382 if (pp_module->initialize)
4383 va_status = pp_module->initialize(ctx, pp_context,
4390 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4392 calculate_boundary_block_mask(pp_context, dst_rect);
4399 gen6_pp_interface_descriptor_table(VADriverContextP ctx,
4400 struct i965_post_processing_context *pp_context)
4402 struct i965_driver_data *i965 = i965_driver_data(ctx);
4403 struct gen6_interface_descriptor_data *desc;
4405 int pp_index = pp_context->current_pp;
4407 bo = pp_context->idrt.bo;
4408 dri_bo_map(bo, True);
4409 assert(bo->virtual);
4411 memset(desc, 0, sizeof(*desc));
4412 desc->desc0.kernel_start_pointer =
4413 pp_context->pp_modules[pp_index].kernel.bo->offset >> 6; /* reloc */
4414 desc->desc1.single_program_flow = 1;
4415 desc->desc1.floating_point_mode = FLOATING_POINT_IEEE_754;
4416 desc->desc2.sampler_count = 1; /* 1 - 4 samplers used */
4417 desc->desc2.sampler_state_pointer =
4418 pp_context->sampler_state_table.bo->offset >> 5;
4419 desc->desc3.binding_table_entry_count = 0;
4420 desc->desc3.binding_table_pointer = (BINDING_TABLE_OFFSET >> 5);
4421 desc->desc4.constant_urb_entry_read_offset = 0;
4423 if (IS_GEN7(i965->intel.device_info))
4424 desc->desc4.constant_urb_entry_read_length = 6; /* grf 1-6 */
4426 desc->desc4.constant_urb_entry_read_length = 4; /* grf 1-4 */
4428 dri_bo_emit_reloc(bo,
4429 I915_GEM_DOMAIN_INSTRUCTION, 0,
4431 offsetof(struct gen6_interface_descriptor_data, desc0),
4432 pp_context->pp_modules[pp_index].kernel.bo);
4434 dri_bo_emit_reloc(bo,
4435 I915_GEM_DOMAIN_INSTRUCTION, 0,
4436 desc->desc2.sampler_count << 2,
4437 offsetof(struct gen6_interface_descriptor_data, desc2),
4438 pp_context->sampler_state_table.bo);
4441 pp_context->idrt.num_interface_descriptors++;
4445 gen6_pp_upload_constants(VADriverContextP ctx,
4446 struct i965_post_processing_context *pp_context)
4448 struct i965_driver_data *i965 = i965_driver_data(ctx);
4449 unsigned char *constant_buffer;
4452 assert(sizeof(struct pp_static_parameter) == 128);
4453 assert(sizeof(struct gen7_pp_static_parameter) == 192);
4455 if (IS_GEN7(i965->intel.device_info))
4456 param_size = sizeof(struct gen7_pp_static_parameter);
4458 param_size = sizeof(struct pp_static_parameter);
4460 dri_bo_map(pp_context->curbe.bo, 1);
4461 assert(pp_context->curbe.bo->virtual);
4462 constant_buffer = pp_context->curbe.bo->virtual;
4463 memcpy(constant_buffer, pp_context->pp_static_parameter, param_size);
4464 dri_bo_unmap(pp_context->curbe.bo);
4468 gen6_pp_states_setup(VADriverContextP ctx,
4469 struct i965_post_processing_context *pp_context)
4471 gen6_pp_interface_descriptor_table(ctx, pp_context);
4472 gen6_pp_upload_constants(ctx, pp_context);
4476 gen6_pp_pipeline_select(VADriverContextP ctx,
4477 struct i965_post_processing_context *pp_context)
4479 struct intel_batchbuffer *batch = pp_context->batch;
4481 BEGIN_BATCH(batch, 1);
4482 OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
4483 ADVANCE_BATCH(batch);
4487 gen6_pp_state_base_address(VADriverContextP ctx,
4488 struct i965_post_processing_context *pp_context)
4490 struct intel_batchbuffer *batch = pp_context->batch;
4492 BEGIN_BATCH(batch, 10);
4493 OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
4494 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4495 OUT_RELOC(batch, pp_context->surface_state_binding_table.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
4496 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4497 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4498 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4499 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4500 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4501 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4502 OUT_BATCH(batch, 0 | BASE_ADDRESS_MODIFY);
4503 ADVANCE_BATCH(batch);
4507 gen6_pp_vfe_state(VADriverContextP ctx,
4508 struct i965_post_processing_context *pp_context)
4510 struct intel_batchbuffer *batch = pp_context->batch;
4512 BEGIN_BATCH(batch, 8);
4513 OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
4514 OUT_BATCH(batch, 0);
4516 (pp_context->vfe_gpu_state.max_num_threads - 1) << 16 |
4517 pp_context->vfe_gpu_state.num_urb_entries << 8);
4518 OUT_BATCH(batch, 0);
4520 (pp_context->vfe_gpu_state.urb_entry_size) << 16 |
4521 /* URB Entry Allocation Size, in 256 bits unit */
4522 (pp_context->vfe_gpu_state.curbe_allocation_size));
4523 /* CURBE Allocation Size, in 256 bits unit */
4524 OUT_BATCH(batch, 0);
4525 OUT_BATCH(batch, 0);
4526 OUT_BATCH(batch, 0);
4527 ADVANCE_BATCH(batch);
4531 gen6_pp_curbe_load(VADriverContextP ctx,
4532 struct i965_post_processing_context *pp_context)
4534 struct intel_batchbuffer *batch = pp_context->batch;
4535 struct i965_driver_data *i965 = i965_driver_data(ctx);
4538 if (IS_GEN7(i965->intel.device_info))
4539 param_size = sizeof(struct gen7_pp_static_parameter);
4541 param_size = sizeof(struct pp_static_parameter);
4543 BEGIN_BATCH(batch, 4);
4544 OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
4545 OUT_BATCH(batch, 0);
4549 pp_context->curbe.bo,
4550 I915_GEM_DOMAIN_INSTRUCTION, 0,
4552 ADVANCE_BATCH(batch);
4556 gen6_interface_descriptor_load(VADriverContextP ctx,
4557 struct i965_post_processing_context *pp_context)
4559 struct intel_batchbuffer *batch = pp_context->batch;
4561 BEGIN_BATCH(batch, 4);
4562 OUT_BATCH(batch, CMD_MEDIA_INTERFACE_DESCRIPTOR_LOAD | (4 - 2));
4563 OUT_BATCH(batch, 0);
4565 pp_context->idrt.num_interface_descriptors * sizeof(struct gen6_interface_descriptor_data));
4567 pp_context->idrt.bo,
4568 I915_GEM_DOMAIN_INSTRUCTION, 0,
4570 ADVANCE_BATCH(batch);
4573 static void update_block_mask_parameter(struct i965_post_processing_context *pp_context, int x, int y, int x_steps, int y_steps)
4575 struct pp_inline_parameter *pp_inline_parameter = pp_context->pp_inline_parameter;
4577 pp_inline_parameter->grf5.block_vertical_mask = 0xff;
4578 pp_inline_parameter->grf6.block_vertical_mask_bottom = pp_context->block_vertical_mask_bottom;
4579 // for the first block, it always on the left edge. the second block will reload horizontal_mask from grf6.block_horizontal_mask_middle
4580 pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_left;
4581 pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
4582 pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_right;
4586 if (y == y_steps-1) {
4587 pp_inline_parameter->grf5.block_vertical_mask = pp_context->block_vertical_mask_bottom;
4590 pp_inline_parameter->grf6.block_vertical_mask_bottom = 0xff;
4596 if (x == 0) { // all blocks in this group are on the left edge
4597 pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_left;
4598 pp_inline_parameter->grf6.block_horizontal_mask_right = pp_context->block_horizontal_mask_left;
4600 else if (x == x_steps-1) {
4601 pp_inline_parameter->grf5.block_horizontal_mask = pp_context->block_horizontal_mask_right;
4602 pp_inline_parameter->grf6.block_horizontal_mask_middle = pp_context->block_horizontal_mask_right;
4605 pp_inline_parameter->grf5.block_horizontal_mask = 0xffff;
4606 pp_inline_parameter->grf6.block_horizontal_mask_middle = 0xffff;
4607 pp_inline_parameter->grf6.block_horizontal_mask_right = 0xffff;
4614 gen6_pp_object_walker(VADriverContextP ctx,
4615 struct i965_post_processing_context *pp_context)
4617 struct i965_driver_data *i965 = i965_driver_data(ctx);
4618 struct intel_batchbuffer *batch = pp_context->batch;
4619 int x, x_steps, y, y_steps;
4620 int param_size, command_length_in_dws;
4621 dri_bo *command_buffer;
4622 unsigned int *command_ptr;
4624 if (IS_GEN7(i965->intel.device_info))
4625 param_size = sizeof(struct gen7_pp_inline_parameter);
4627 param_size = sizeof(struct pp_inline_parameter);
4629 x_steps = pp_context->pp_x_steps(pp_context->private_context);
4630 y_steps = pp_context->pp_y_steps(pp_context->private_context);
4631 command_length_in_dws = 6 + (param_size >> 2);
4632 command_buffer = dri_bo_alloc(i965->intel.bufmgr,
4633 "command objects buffer",
4634 command_length_in_dws * 4 * x_steps * y_steps + 8,
4637 dri_bo_map(command_buffer, 1);
4638 command_ptr = command_buffer->virtual;
4640 for (y = 0; y < y_steps; y++) {
4641 for (x = 0; x < x_steps; x++) {
4642 if (!pp_context->pp_set_block_parameter(pp_context, x, y)) {
4643 // some common block parameter update goes here, apply to all pp functions
4644 if (IS_GEN6(i965->intel.device_info))
4645 update_block_mask_parameter (pp_context, x, y, x_steps, y_steps);
4647 *command_ptr++ = (CMD_MEDIA_OBJECT | (command_length_in_dws - 2));
4653 memcpy(command_ptr, pp_context->pp_inline_parameter, param_size);
4654 command_ptr += (param_size >> 2);
4659 if (command_length_in_dws * x_steps * y_steps % 2 == 0)
4662 *command_ptr = MI_BATCH_BUFFER_END;
4664 dri_bo_unmap(command_buffer);
4666 BEGIN_BATCH(batch, 2);
4667 OUT_BATCH(batch, MI_BATCH_BUFFER_START | (1 << 8));
4668 OUT_RELOC(batch, command_buffer,
4669 I915_GEM_DOMAIN_COMMAND, 0,
4671 ADVANCE_BATCH(batch);
4673 dri_bo_unreference(command_buffer);
4675 /* Have to execute the batch buffer here becuase MI_BATCH_BUFFER_END
4676 * will cause control to pass back to ring buffer
4678 intel_batchbuffer_end_atomic(batch);
4679 intel_batchbuffer_flush(batch);
4680 intel_batchbuffer_start_atomic(batch, 0x1000);
4684 gen6_pp_pipeline_setup(VADriverContextP ctx,
4685 struct i965_post_processing_context *pp_context)
4687 struct intel_batchbuffer *batch = pp_context->batch;
4689 intel_batchbuffer_start_atomic(batch, 0x1000);
4690 intel_batchbuffer_emit_mi_flush(batch);
4691 gen6_pp_pipeline_select(ctx, pp_context);
4692 gen6_pp_state_base_address(ctx, pp_context);
4693 gen6_pp_vfe_state(ctx, pp_context);
4694 gen6_pp_curbe_load(ctx, pp_context);
4695 gen6_interface_descriptor_load(ctx, pp_context);
4696 gen6_pp_object_walker(ctx, pp_context);
4697 intel_batchbuffer_end_atomic(batch);
4701 gen6_post_processing(
4702 VADriverContextP ctx,
4703 struct i965_post_processing_context *pp_context,
4704 const struct i965_surface *src_surface,
4705 const VARectangle *src_rect,
4706 struct i965_surface *dst_surface,
4707 const VARectangle *dst_rect,
4714 va_status = gen6_pp_initialize(ctx, pp_context,
4722 if (va_status == VA_STATUS_SUCCESS) {
4723 gen6_pp_states_setup(ctx, pp_context);
4724 gen6_pp_pipeline_setup(ctx, pp_context);
4727 if (va_status == VA_STATUS_SUCCESS_1)
4728 va_status = VA_STATUS_SUCCESS;
4734 i965_post_processing_internal(
4735 VADriverContextP ctx,
4736 struct i965_post_processing_context *pp_context,
4737 const struct i965_surface *src_surface,
4738 const VARectangle *src_rect,
4739 struct i965_surface *dst_surface,
4740 const VARectangle *dst_rect,
4746 struct i965_driver_data *i965 = i965_driver_data(ctx);
4748 if (pp_context && pp_context->intel_post_processing) {
4749 va_status = (pp_context->intel_post_processing)(ctx, pp_context,
4750 src_surface, src_rect,
4751 dst_surface, dst_rect,
4752 pp_index, filter_param);
4754 va_status = VA_STATUS_ERROR_UNIMPLEMENTED;
4761 rgb_to_yuv(unsigned int argb,
4767 int r = ((argb >> 16) & 0xff);
4768 int g = ((argb >> 8) & 0xff);
4769 int b = ((argb >> 0) & 0xff);
4771 *y = (257 * r + 504 * g + 98 * b) / 1000 + 16;
4772 *v = (439 * r - 368 * g - 71 * b) / 1000 + 128;
4773 *u = (-148 * r - 291 * g + 439 * b) / 1000 + 128;
4774 *a = ((argb >> 24) & 0xff);
4778 i965_vpp_clear_surface(VADriverContextP ctx,
4779 struct i965_post_processing_context *pp_context,
4780 struct object_surface *obj_surface,
4783 struct i965_driver_data *i965 = i965_driver_data(ctx);
4784 struct intel_batchbuffer *batch = pp_context->batch;
4785 unsigned int blt_cmd, br13;
4786 unsigned int tiling = 0, swizzle = 0;
4788 unsigned char y, u, v, a = 0;
4789 int region_width, region_height;
4791 /* Currently only support NV12 surface */
4792 if (!obj_surface || obj_surface->fourcc != VA_FOURCC_NV12)
4795 rgb_to_yuv(color, &y, &u, &v, &a);
4800 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4801 blt_cmd = XY_COLOR_BLT_CMD;
4802 pitch = obj_surface->width;
4804 if (tiling != I915_TILING_NONE) {
4805 assert(tiling == I915_TILING_Y);
4806 // blt_cmd |= XY_COLOR_BLT_DST_TILED;
4814 if (IS_IRONLAKE(i965->intel.device_info)) {
4815 intel_batchbuffer_start_atomic(batch, 48);
4816 BEGIN_BATCH(batch, 12);
4818 /* Will double-check the command if the new chipset is added */
4819 intel_batchbuffer_start_atomic_blt(batch, 48);
4820 BEGIN_BLT_BATCH(batch, 12);
4823 region_width = obj_surface->width;
4824 region_height = obj_surface->height;
4826 OUT_BATCH(batch, blt_cmd);
4827 OUT_BATCH(batch, br13);
4832 region_height << 16 |
4834 OUT_RELOC(batch, obj_surface->bo,
4835 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
4837 OUT_BATCH(batch, y);
4843 region_width = obj_surface->width / 2;
4844 region_height = obj_surface->height / 2;
4846 if (tiling == I915_TILING_Y) {
4847 region_height = ALIGN(obj_surface->height / 2, 32);
4850 OUT_BATCH(batch, blt_cmd);
4851 OUT_BATCH(batch, br13);
4856 region_height << 16 |
4858 OUT_RELOC(batch, obj_surface->bo,
4859 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
4860 obj_surface->width * obj_surface->y_cb_offset);
4861 OUT_BATCH(batch, v << 8 | u);
4863 ADVANCE_BATCH(batch);
4864 intel_batchbuffer_end_atomic(batch);
4868 i965_scaling_processing(
4869 VADriverContextP ctx,
4870 struct object_surface *src_surface_obj,
4871 const VARectangle *src_rect,
4872 struct object_surface *dst_surface_obj,
4873 const VARectangle *dst_rect,
4874 unsigned int va_flags)
4876 VAStatus va_status = VA_STATUS_SUCCESS;
4877 struct i965_driver_data *i965 = i965_driver_data(ctx);
4879 assert(src_surface_obj->fourcc == VA_FOURCC_NV12);
4880 assert(dst_surface_obj->fourcc == VA_FOURCC_NV12);
4882 if (HAS_VPP(i965)) {
4883 struct i965_surface src_surface;
4884 struct i965_surface dst_surface;
4885 struct i965_post_processing_context *pp_context;
4886 unsigned int filter_flags;
4888 _i965LockMutex(&i965->pp_mutex);
4890 src_surface.base = (struct object_base *)src_surface_obj;
4891 src_surface.type = I965_SURFACE_TYPE_SURFACE;
4892 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4893 dst_surface.base = (struct object_base *)dst_surface_obj;
4894 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4895 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4897 pp_context = i965->pp_context;
4898 filter_flags = pp_context->filter_flags;
4899 pp_context->filter_flags = va_flags;
4901 va_status = i965_post_processing_internal(ctx, pp_context,
4902 &src_surface, src_rect, &dst_surface, dst_rect,
4903 avs_is_needed(va_flags) ? PP_NV12_AVS : PP_NV12_SCALING, NULL);
4905 pp_context->filter_flags = filter_flags;
4907 _i965UnlockMutex(&i965->pp_mutex);
4914 i965_post_processing(
4915 VADriverContextP ctx,
4916 struct object_surface *obj_surface,
4917 const VARectangle *src_rect,
4918 const VARectangle *dst_rect,
4919 unsigned int va_flags,
4920 int *has_done_scaling,
4921 VARectangle *calibrated_rect
4924 struct i965_driver_data *i965 = i965_driver_data(ctx);
4925 VASurfaceID out_surface_id = VA_INVALID_ID;
4926 VASurfaceID tmp_id = VA_INVALID_ID;
4928 *has_done_scaling = 0;
4930 if (HAS_VPP(i965)) {
4932 struct i965_surface src_surface;
4933 struct i965_surface dst_surface;
4934 struct i965_post_processing_context *pp_context;
4936 /* Currently only support post processing for NV12 surface */
4937 if (obj_surface->fourcc != VA_FOURCC_NV12)
4938 return out_surface_id;
4940 _i965LockMutex(&i965->pp_mutex);
4942 pp_context = i965->pp_context;
4943 pp_context->filter_flags = va_flags;
4944 if (avs_is_needed(va_flags)) {
4945 VARectangle tmp_dst_rect;
4946 struct i965_render_state *render_state = &i965->render_state;
4947 struct intel_region *dest_region = render_state->draw_region;
4949 if (out_surface_id != VA_INVALID_ID)
4950 tmp_id = out_surface_id;
4954 tmp_dst_rect.width = dst_rect->width;
4955 tmp_dst_rect.height = dst_rect->height;
4956 src_surface.base = (struct object_base *)obj_surface;
4957 src_surface.type = I965_SURFACE_TYPE_SURFACE;
4958 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4960 status = i965_CreateSurfaces(ctx,
4963 VA_RT_FORMAT_YUV420,
4966 assert(status == VA_STATUS_SUCCESS);
4967 obj_surface = SURFACE(out_surface_id);
4968 assert(obj_surface);
4969 i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
4970 i965_vpp_clear_surface(ctx, pp_context, obj_surface, 0);
4972 dst_surface.base = (struct object_base *)obj_surface;
4973 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4974 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4976 i965_post_processing_internal(ctx, pp_context,
4984 if (tmp_id != VA_INVALID_ID)
4985 i965_DestroySurfaces(ctx, &tmp_id, 1);
4987 *has_done_scaling = 1;
4988 calibrated_rect->x = 0;
4989 calibrated_rect->y = 0;
4990 calibrated_rect->width = dst_rect->width;
4991 calibrated_rect->height = dst_rect->height;
4994 _i965UnlockMutex(&i965->pp_mutex);
4997 return out_surface_id;
5001 i965_image_pl2_processing(VADriverContextP ctx,
5002 const struct i965_surface *src_surface,
5003 const VARectangle *src_rect,
5004 struct i965_surface *dst_surface,
5005 const VARectangle *dst_rect);
5008 i965_image_plx_nv12_plx_processing(VADriverContextP ctx,
5009 VAStatus (*i965_image_plx_nv12_processing)(
5011 const struct i965_surface *,
5012 const VARectangle *,
5013 struct i965_surface *,
5014 const VARectangle *),
5015 const struct i965_surface *src_surface,
5016 const VARectangle *src_rect,
5017 struct i965_surface *dst_surface,
5018 const VARectangle *dst_rect)
5020 struct i965_driver_data *i965 = i965_driver_data(ctx);
5022 VASurfaceID tmp_surface_id = VA_INVALID_SURFACE;
5023 struct object_surface *obj_surface = NULL;
5024 struct i965_surface tmp_surface;
5027 pp_get_surface_size(ctx, dst_surface, &width, &height);
5028 status = i965_CreateSurfaces(ctx,
5031 VA_RT_FORMAT_YUV420,
5034 assert(status == VA_STATUS_SUCCESS);
5035 obj_surface = SURFACE(tmp_surface_id);
5036 assert(obj_surface);
5037 i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5039 tmp_surface.base = (struct object_base *)obj_surface;
5040 tmp_surface.type = I965_SURFACE_TYPE_SURFACE;
5041 tmp_surface.flags = I965_SURFACE_FLAG_FRAME;
5043 status = i965_image_plx_nv12_processing(ctx,
5049 if (status == VA_STATUS_SUCCESS)
5050 status = i965_image_pl2_processing(ctx,
5056 i965_DestroySurfaces(ctx,
5065 i965_image_pl1_rgbx_processing(VADriverContextP ctx,
5066 const struct i965_surface *src_surface,
5067 const VARectangle *src_rect,
5068 struct i965_surface *dst_surface,
5069 const VARectangle *dst_rect)
5071 struct i965_driver_data *i965 = i965_driver_data(ctx);
5072 struct i965_post_processing_context *pp_context = i965->pp_context;
5073 int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5077 case VA_FOURCC_NV12:
5078 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5083 PP_RGBX_LOAD_SAVE_NV12,
5085 intel_batchbuffer_flush(pp_context->batch);
5089 vaStatus = i965_image_plx_nv12_plx_processing(ctx,
5090 i965_image_pl1_rgbx_processing,
5102 i965_image_pl3_processing(VADriverContextP ctx,
5103 const struct i965_surface *src_surface,
5104 const VARectangle *src_rect,
5105 struct i965_surface *dst_surface,
5106 const VARectangle *dst_rect)
5108 struct i965_driver_data *i965 = i965_driver_data(ctx);
5109 struct i965_post_processing_context *pp_context = i965->pp_context;
5110 int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5111 VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
5114 case VA_FOURCC_NV12:
5115 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5120 PP_PL3_LOAD_SAVE_N12,
5122 intel_batchbuffer_flush(pp_context->batch);
5125 case VA_FOURCC_IMC1:
5126 case VA_FOURCC_IMC3:
5127 case VA_FOURCC_YV12:
5128 case VA_FOURCC_I420:
5129 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5134 PP_PL3_LOAD_SAVE_PL3,
5136 intel_batchbuffer_flush(pp_context->batch);
5139 case VA_FOURCC_YUY2:
5140 case VA_FOURCC_UYVY:
5141 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5146 PP_PL3_LOAD_SAVE_PA,
5148 intel_batchbuffer_flush(pp_context->batch);
5152 vaStatus = i965_image_plx_nv12_plx_processing(ctx,
5153 i965_image_pl3_processing,
5165 i965_image_pl2_processing(VADriverContextP ctx,
5166 const struct i965_surface *src_surface,
5167 const VARectangle *src_rect,
5168 struct i965_surface *dst_surface,
5169 const VARectangle *dst_rect)
5171 struct i965_driver_data *i965 = i965_driver_data(ctx);
5172 struct i965_post_processing_context *pp_context = i965->pp_context;
5173 int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5174 VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED;
5177 case VA_FOURCC_NV12:
5178 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5183 PP_NV12_LOAD_SAVE_N12,
5187 case VA_FOURCC_IMC1:
5188 case VA_FOURCC_IMC3:
5189 case VA_FOURCC_YV12:
5190 case VA_FOURCC_I420:
5191 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5196 PP_NV12_LOAD_SAVE_PL3,
5200 case VA_FOURCC_YUY2:
5201 case VA_FOURCC_UYVY:
5202 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5207 PP_NV12_LOAD_SAVE_PA,
5211 case VA_FOURCC_BGRX:
5212 case VA_FOURCC_BGRA:
5213 case VA_FOURCC_RGBX:
5214 case VA_FOURCC_RGBA:
5215 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5220 PP_NV12_LOAD_SAVE_RGBX,
5225 return VA_STATUS_ERROR_UNIMPLEMENTED;
5228 intel_batchbuffer_flush(pp_context->batch);
5234 i965_image_pl1_processing(VADriverContextP ctx,
5235 const struct i965_surface *src_surface,
5236 const VARectangle *src_rect,
5237 struct i965_surface *dst_surface,
5238 const VARectangle *dst_rect)
5240 struct i965_driver_data *i965 = i965_driver_data(ctx);
5241 struct i965_post_processing_context *pp_context = i965->pp_context;
5242 int fourcc = pp_get_surface_fourcc(ctx, dst_surface);
5246 case VA_FOURCC_NV12:
5247 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5252 PP_PA_LOAD_SAVE_NV12,
5254 intel_batchbuffer_flush(pp_context->batch);
5257 case VA_FOURCC_YV12:
5258 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5263 PP_PA_LOAD_SAVE_PL3,
5265 intel_batchbuffer_flush(pp_context->batch);
5268 case VA_FOURCC_YUY2:
5269 case VA_FOURCC_UYVY:
5270 vaStatus = i965_post_processing_internal(ctx, i965->pp_context,
5277 intel_batchbuffer_flush(pp_context->batch);
5281 vaStatus = i965_image_plx_nv12_plx_processing(ctx,
5282 i965_image_pl1_processing,
5294 i965_image_processing(VADriverContextP ctx,
5295 const struct i965_surface *src_surface,
5296 const VARectangle *src_rect,
5297 struct i965_surface *dst_surface,
5298 const VARectangle *dst_rect)
5300 struct i965_driver_data *i965 = i965_driver_data(ctx);
5301 VAStatus status = VA_STATUS_ERROR_UNIMPLEMENTED;
5303 if (HAS_VPP(i965)) {
5304 int fourcc = pp_get_surface_fourcc(ctx, src_surface);
5306 _i965LockMutex(&i965->pp_mutex);
5309 case VA_FOURCC_YV12:
5310 case VA_FOURCC_I420:
5311 case VA_FOURCC_IMC1:
5312 case VA_FOURCC_IMC3:
5313 case VA_FOURCC_422H:
5314 case VA_FOURCC_422V:
5315 case VA_FOURCC_411P:
5316 case VA_FOURCC_444P:
5317 case VA_FOURCC_YV16:
5318 status = i965_image_pl3_processing(ctx,
5325 case VA_FOURCC_NV12:
5326 status = i965_image_pl2_processing(ctx,
5332 case VA_FOURCC_YUY2:
5333 case VA_FOURCC_UYVY:
5334 status = i965_image_pl1_processing(ctx,
5340 case VA_FOURCC_BGRA:
5341 case VA_FOURCC_BGRX:
5342 case VA_FOURCC_RGBA:
5343 case VA_FOURCC_RGBX:
5344 status = i965_image_pl1_rgbx_processing(ctx,
5351 status = VA_STATUS_ERROR_UNIMPLEMENTED;
5355 _i965UnlockMutex(&i965->pp_mutex);
5362 i965_post_processing_context_finalize(VADriverContextP ctx,
5363 struct i965_post_processing_context *pp_context)
5367 dri_bo_unreference(pp_context->surface_state_binding_table.bo);
5368 pp_context->surface_state_binding_table.bo = NULL;
5370 dri_bo_unreference(pp_context->curbe.bo);
5371 pp_context->curbe.bo = NULL;
5373 dri_bo_unreference(pp_context->sampler_state_table.bo);
5374 pp_context->sampler_state_table.bo = NULL;
5376 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8);
5377 pp_context->sampler_state_table.bo_8x8 = NULL;
5379 dri_bo_unreference(pp_context->sampler_state_table.bo_8x8_uv);
5380 pp_context->sampler_state_table.bo_8x8_uv = NULL;
5382 dri_bo_unreference(pp_context->idrt.bo);
5383 pp_context->idrt.bo = NULL;
5384 pp_context->idrt.num_interface_descriptors = 0;
5386 dri_bo_unreference(pp_context->vfe_state.bo);
5387 pp_context->vfe_state.bo = NULL;
5389 for (i = 0; i < ARRAY_ELEMS(pp_context->pp_dndi_context.frame_store); i++)
5390 pp_dndi_frame_store_clear(&pp_context->pp_dndi_context.frame_store[i],
5393 dri_bo_unreference(pp_context->pp_dn_context.stmm_bo);
5394 pp_context->pp_dn_context.stmm_bo = NULL;
5396 for (i = 0; i < NUM_PP_MODULES; i++) {
5397 struct pp_module *pp_module = &pp_context->pp_modules[i];
5399 dri_bo_unreference(pp_module->kernel.bo);
5400 pp_module->kernel.bo = NULL;
5403 free(pp_context->pp_static_parameter);
5404 free(pp_context->pp_inline_parameter);
5405 pp_context->pp_static_parameter = NULL;
5406 pp_context->pp_inline_parameter = NULL;
5410 i965_post_processing_terminate(VADriverContextP ctx)
5412 struct i965_driver_data *i965 = i965_driver_data(ctx);
5413 struct i965_post_processing_context *pp_context = i965->pp_context;
5416 pp_context->finalize(ctx, pp_context);
5420 i965->pp_context = NULL;
5423 #define VPP_CURBE_ALLOCATION_SIZE 32
5426 i965_post_processing_context_init(VADriverContextP ctx,
5428 struct intel_batchbuffer *batch)
5430 struct i965_driver_data *i965 = i965_driver_data(ctx);
5432 struct i965_post_processing_context *pp_context = data;
5433 const AVSConfig *avs_config;
5435 if (IS_IRONLAKE(i965->intel.device_info)) {
5436 pp_context->urb.size = i965->intel.device_info->urb_size;
5437 pp_context->urb.num_vfe_entries = 32;
5438 pp_context->urb.size_vfe_entry = 1; /* in 512 bits unit */
5439 pp_context->urb.num_cs_entries = 1;
5440 pp_context->urb.size_cs_entry = 2;
5441 pp_context->urb.vfe_start = 0;
5442 pp_context->urb.cs_start = pp_context->urb.vfe_start +
5443 pp_context->urb.num_vfe_entries * pp_context->urb.size_vfe_entry;
5444 assert(pp_context->urb.cs_start +
5445 pp_context->urb.num_cs_entries * pp_context->urb.size_cs_entry <= i965->intel.device_info->urb_size);
5446 pp_context->intel_post_processing = ironlake_post_processing;
5448 pp_context->vfe_gpu_state.max_num_threads = 60;
5449 pp_context->vfe_gpu_state.num_urb_entries = 59;
5450 pp_context->vfe_gpu_state.gpgpu_mode = 0;
5451 pp_context->vfe_gpu_state.urb_entry_size = 16 - 1;
5452 pp_context->vfe_gpu_state.curbe_allocation_size = VPP_CURBE_ALLOCATION_SIZE;
5453 pp_context->intel_post_processing = gen6_post_processing;
5456 pp_context->finalize = i965_post_processing_context_finalize;
5458 assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen5));
5459 assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen6));
5460 assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen7));
5461 assert(NUM_PP_MODULES == ARRAY_ELEMS(pp_modules_gen75));
5463 if (IS_HASWELL(i965->intel.device_info))
5464 memcpy(pp_context->pp_modules, pp_modules_gen75, sizeof(pp_context->pp_modules));
5465 else if (IS_GEN7(i965->intel.device_info))
5466 memcpy(pp_context->pp_modules, pp_modules_gen7, sizeof(pp_context->pp_modules));
5467 else if (IS_GEN6(i965->intel.device_info))
5468 memcpy(pp_context->pp_modules, pp_modules_gen6, sizeof(pp_context->pp_modules));
5469 else if (IS_IRONLAKE(i965->intel.device_info))
5470 memcpy(pp_context->pp_modules, pp_modules_gen5, sizeof(pp_context->pp_modules));
5472 for (i = 0; i < NUM_PP_MODULES; i++) {
5473 struct pp_module *pp_module = &pp_context->pp_modules[i];
5474 dri_bo_unreference(pp_module->kernel.bo);
5475 if (pp_module->kernel.bin && pp_module->kernel.size) {
5476 pp_module->kernel.bo = dri_bo_alloc(i965->intel.bufmgr,
5477 pp_module->kernel.name,
5478 pp_module->kernel.size,
5480 assert(pp_module->kernel.bo);
5481 dri_bo_subdata(pp_module->kernel.bo, 0, pp_module->kernel.size, pp_module->kernel.bin);
5483 pp_module->kernel.bo = NULL;
5487 /* static & inline parameters */
5488 if (IS_GEN7(i965->intel.device_info)) {
5489 pp_context->pp_static_parameter = calloc(sizeof(struct gen7_pp_static_parameter), 1);
5490 pp_context->pp_inline_parameter = calloc(sizeof(struct gen7_pp_inline_parameter), 1);
5492 pp_context->pp_static_parameter = calloc(sizeof(struct pp_static_parameter), 1);
5493 pp_context->pp_inline_parameter = calloc(sizeof(struct pp_inline_parameter), 1);
5496 pp_context->batch = batch;
5497 pp_dndi_context_init(&pp_context->pp_dndi_context);
5499 avs_config = IS_IRONLAKE(i965->intel.device_info) ? &gen5_avs_config :
5501 avs_init_state(&pp_context->pp_avs_context.state, avs_config);
5505 i965_post_processing_init(VADriverContextP ctx)
5507 struct i965_driver_data *i965 = i965_driver_data(ctx);
5508 struct i965_post_processing_context *pp_context = i965->pp_context;
5510 if (HAS_VPP(i965)) {
5511 if (pp_context == NULL) {
5512 pp_context = calloc(1, sizeof(*pp_context));
5513 i965->codec_info->post_processing_context_init(ctx, pp_context, i965->pp_batch);
5514 i965->pp_context = pp_context;
5521 static const int procfilter_to_pp_flag[VAProcFilterCount] = {
5522 PP_NULL, /* VAProcFilterNone */
5523 PP_NV12_DN, /* VAProcFilterNoiseReduction */
5524 PP_NV12_DNDI, /* VAProcFilterDeinterlacing */
5525 PP_NULL, /* VAProcFilterSharpening */
5526 PP_NULL, /* VAProcFilterColorBalance */
5529 static const int proc_frame_to_pp_frame[3] = {
5530 I965_SURFACE_FLAG_FRAME,
5531 I965_SURFACE_FLAG_TOP_FIELD_FIRST,
5532 I965_SURFACE_FLAG_BOTTOME_FIELD_FIRST
5536 PP_OP_CHANGE_FORMAT = 1 << 0,
5537 PP_OP_CHANGE_SIZE = 1 << 1,
5538 PP_OP_DEINTERLACE = 1 << 2,
5539 PP_OP_COMPLEX = 1 << 3,
5543 pp_get_kernel_index(uint32_t src_fourcc, uint32_t dst_fourcc, uint32_t pp_ops,
5544 uint32_t filter_flags)
5549 dst_fourcc = src_fourcc;
5551 switch (src_fourcc) {
5552 case VA_FOURCC_RGBX:
5553 case VA_FOURCC_RGBA:
5554 case VA_FOURCC_BGRX:
5555 case VA_FOURCC_BGRA:
5556 switch (dst_fourcc) {
5557 case VA_FOURCC_NV12:
5558 pp_index = PP_RGBX_LOAD_SAVE_NV12;
5562 case VA_FOURCC_YUY2:
5563 case VA_FOURCC_UYVY:
5564 switch (dst_fourcc) {
5565 case VA_FOURCC_NV12:
5566 pp_index = PP_PA_LOAD_SAVE_NV12;
5568 case VA_FOURCC_I420:
5569 case VA_FOURCC_YV12:
5570 pp_index = PP_PA_LOAD_SAVE_PL3;
5572 case VA_FOURCC_YUY2:
5573 case VA_FOURCC_UYVY:
5574 pp_index = PP_PA_LOAD_SAVE_PA;
5578 case VA_FOURCC_NV12:
5579 switch (dst_fourcc) {
5580 case VA_FOURCC_NV12:
5581 if (pp_ops & PP_OP_CHANGE_SIZE)
5582 pp_index = avs_is_needed(filter_flags) ?
5583 PP_NV12_AVS : PP_NV12_SCALING;
5585 pp_index = PP_NV12_LOAD_SAVE_N12;
5587 case VA_FOURCC_I420:
5588 case VA_FOURCC_YV12:
5589 case VA_FOURCC_IMC1:
5590 case VA_FOURCC_IMC3:
5591 pp_index = PP_NV12_LOAD_SAVE_PL3;
5593 case VA_FOURCC_YUY2:
5594 case VA_FOURCC_UYVY:
5595 pp_index = PP_NV12_LOAD_SAVE_PA;
5597 case VA_FOURCC_RGBX:
5598 case VA_FOURCC_RGBA:
5599 case VA_FOURCC_BGRX:
5600 case VA_FOURCC_BGRA:
5601 pp_index = PP_NV12_LOAD_SAVE_RGBX;
5605 case VA_FOURCC_I420:
5606 case VA_FOURCC_YV12:
5607 case VA_FOURCC_IMC1:
5608 case VA_FOURCC_IMC3:
5609 case VA_FOURCC_YV16:
5610 case VA_FOURCC_411P:
5611 case VA_FOURCC_422H:
5612 case VA_FOURCC_422V:
5613 case VA_FOURCC_444P:
5614 switch (dst_fourcc) {
5615 case VA_FOURCC_NV12:
5616 pp_index = PP_PL3_LOAD_SAVE_N12;
5618 case VA_FOURCC_I420:
5619 case VA_FOURCC_YV12:
5620 case VA_FOURCC_IMC1:
5621 case VA_FOURCC_IMC3:
5622 pp_index = PP_PL3_LOAD_SAVE_PL3;
5624 case VA_FOURCC_YUY2:
5625 case VA_FOURCC_UYVY:
5626 pp_index = PP_PL3_LOAD_SAVE_PA;
5635 i965_proc_picture_fast(VADriverContextP ctx,
5636 struct i965_proc_context *proc_context, struct proc_state *proc_state)
5638 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5639 const VAProcPipelineParameterBuffer * const pipeline_param =
5640 (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
5641 struct object_surface *src_obj_surface, *dst_obj_surface;
5642 struct i965_surface src_surface, dst_surface;
5643 const VAProcFilterParameterBufferDeinterlacing *deint_params = NULL;
5644 VARectangle src_rect, dst_rect;
5646 uint32_t i, filter_flags = 0, pp_ops = 0;
5649 /* Validate pipeline parameters */
5650 if (pipeline_param->num_filters > 0 && !pipeline_param->filters)
5651 return VA_STATUS_ERROR_INVALID_PARAMETER;
5653 for (i = 0; i < pipeline_param->num_filters; i++) {
5654 const VAProcFilterParameterBuffer *filter;
5655 struct object_buffer * const obj_buffer =
5656 BUFFER(pipeline_param->filters[i]);
5658 assert(obj_buffer && obj_buffer->buffer_store);
5659 if (!obj_buffer || !obj_buffer->buffer_store)
5660 return VA_STATUS_ERROR_INVALID_PARAMETER;
5662 filter = (VAProcFilterParameterBuffer *)
5663 obj_buffer->buffer_store->buffer;
5664 switch (filter->type) {
5665 case VAProcFilterDeinterlacing:
5666 pp_ops |= PP_OP_DEINTERLACE;
5667 deint_params = (VAProcFilterParameterBufferDeinterlacing *)filter;
5670 pp_ops |= PP_OP_COMPLEX;
5674 filter_flags |= pipeline_param->filter_flags & VA_FILTER_SCALING_MASK;
5676 /* Validate source surface */
5677 src_obj_surface = SURFACE(pipeline_param->surface);
5678 if (!src_obj_surface)
5679 return VA_STATUS_ERROR_INVALID_SURFACE;
5681 if (!src_obj_surface->fourcc)
5682 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
5684 if (pipeline_param->surface_region) {
5685 src_rect.x = pipeline_param->surface_region->x;
5686 src_rect.y = pipeline_param->surface_region->y;
5687 src_rect.width = pipeline_param->surface_region->width;
5688 src_rect.height = pipeline_param->surface_region->height;
5692 src_rect.width = src_obj_surface->orig_width;
5693 src_rect.height = src_obj_surface->orig_height;
5696 src_surface.base = &src_obj_surface->base;
5697 src_surface.type = I965_SURFACE_TYPE_SURFACE;
5698 src_surface.flags = I965_SURFACE_FLAG_FRAME;
5700 if (pp_ops & PP_OP_DEINTERLACE) {
5701 filter_flags |= !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD) ?
5702 VA_TOP_FIELD : VA_BOTTOM_FIELD;
5703 if (deint_params->algorithm != VAProcDeinterlacingBob)
5704 pp_ops |= PP_OP_COMPLEX;
5706 else if (pipeline_param->filter_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD)) {
5707 filter_flags |= (pipeline_param->filter_flags & VA_TOP_FIELD) ?
5708 VA_TOP_FIELD : VA_BOTTOM_FIELD;
5709 pp_ops |= PP_OP_DEINTERLACE;
5711 if (pp_ops & PP_OP_DEINTERLACE) // XXX: no bob-deinterlacing optimization yet
5712 pp_ops |= PP_OP_COMPLEX;
5714 /* Validate target surface */
5715 dst_obj_surface = SURFACE(proc_state->current_render_target);
5716 if (!dst_obj_surface)
5717 return VA_STATUS_ERROR_INVALID_SURFACE;
5719 if (dst_obj_surface->fourcc &&
5720 dst_obj_surface->fourcc != src_obj_surface->fourcc)
5721 pp_ops |= PP_OP_CHANGE_FORMAT;
5723 if (pipeline_param->output_region) {
5724 dst_rect.x = pipeline_param->output_region->x;
5725 dst_rect.y = pipeline_param->output_region->y;
5726 dst_rect.width = pipeline_param->output_region->width;
5727 dst_rect.height = pipeline_param->output_region->height;
5731 dst_rect.width = dst_obj_surface->orig_width;
5732 dst_rect.height = dst_obj_surface->orig_height;
5735 if (dst_rect.width != src_rect.width || dst_rect.height != src_rect.height)
5736 pp_ops |= PP_OP_CHANGE_SIZE;
5738 dst_surface.base = &dst_obj_surface->base;
5739 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5740 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
5742 /* Validate "fast-path" processing capabilities */
5743 if (!IS_GEN7(i965->intel.device_info)) {
5744 if ((pp_ops & PP_OP_CHANGE_FORMAT) && (pp_ops & PP_OP_CHANGE_SIZE))
5745 return VA_STATUS_ERROR_UNIMPLEMENTED; // temporary surface is needed
5747 if (pipeline_param->pipeline_flags & VA_PROC_PIPELINE_FAST) {
5748 filter_flags &= ~VA_FILTER_SCALING_MASK;
5749 filter_flags |= VA_FILTER_SCALING_FAST;
5752 if (pp_ops & PP_OP_COMPLEX)
5753 return VA_STATUS_ERROR_UNIMPLEMENTED; // full pipeline is needed
5754 if ((filter_flags & VA_FILTER_SCALING_MASK) > VA_FILTER_SCALING_HQ)
5755 return VA_STATUS_ERROR_UNIMPLEMENTED;
5758 pp_index = pp_get_kernel_index(src_obj_surface->fourcc,
5759 dst_obj_surface->fourcc, pp_ops, filter_flags);
5761 return VA_STATUS_ERROR_UNIMPLEMENTED;
5763 proc_context->pp_context.filter_flags = filter_flags;
5764 status = i965_post_processing_internal(ctx, &proc_context->pp_context,
5765 &src_surface, &src_rect, &dst_surface, &dst_rect, pp_index, NULL);
5766 intel_batchbuffer_flush(proc_context->pp_context.batch);
5771 i965_proc_picture(VADriverContextP ctx,
5773 union codec_state *codec_state,
5774 struct hw_context *hw_context)
5776 struct i965_driver_data *i965 = i965_driver_data(ctx);
5777 struct i965_proc_context *proc_context = (struct i965_proc_context *)hw_context;
5778 struct proc_state *proc_state = &codec_state->proc;
5779 VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *)proc_state->pipeline_param->buffer;
5780 struct object_surface *obj_surface;
5781 struct i965_surface src_surface, dst_surface;
5782 VARectangle src_rect, dst_rect;
5785 VASurfaceID tmp_surfaces[VAProcFilterCount + 4];
5786 int num_tmp_surfaces = 0;
5787 unsigned int tiling = 0, swizzle = 0;
5788 int in_width, in_height;
5790 status = i965_proc_picture_fast(ctx, proc_context, proc_state);
5791 if (status != VA_STATUS_ERROR_UNIMPLEMENTED)
5794 if (pipeline_param->surface == VA_INVALID_ID ||
5795 proc_state->current_render_target == VA_INVALID_ID) {
5796 status = VA_STATUS_ERROR_INVALID_SURFACE;
5800 obj_surface = SURFACE(pipeline_param->surface);
5803 status = VA_STATUS_ERROR_INVALID_SURFACE;
5807 if (!obj_surface->bo) {
5808 status = VA_STATUS_ERROR_INVALID_VALUE; /* The input surface is created without valid content */
5812 if (pipeline_param->num_filters && !pipeline_param->filters) {
5813 status = VA_STATUS_ERROR_INVALID_PARAMETER;
5817 in_width = obj_surface->orig_width;
5818 in_height = obj_surface->orig_height;
5819 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
5821 src_surface.base = (struct object_base *)obj_surface;
5822 src_surface.type = I965_SURFACE_TYPE_SURFACE;
5823 src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
5825 VASurfaceID out_surface_id = VA_INVALID_ID;
5826 if (obj_surface->fourcc != VA_FOURCC_NV12) {
5827 src_surface.base = (struct object_base *)obj_surface;
5828 src_surface.type = I965_SURFACE_TYPE_SURFACE;
5829 src_surface.flags = I965_SURFACE_FLAG_FRAME;
5832 src_rect.width = in_width;
5833 src_rect.height = in_height;
5835 status = i965_CreateSurfaces(ctx,
5838 VA_RT_FORMAT_YUV420,
5841 assert(status == VA_STATUS_SUCCESS);
5842 tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5843 obj_surface = SURFACE(out_surface_id);
5844 assert(obj_surface);
5845 i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5847 dst_surface.base = (struct object_base *)obj_surface;
5848 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5849 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
5852 dst_rect.width = in_width;
5853 dst_rect.height = in_height;
5855 status = i965_image_processing(ctx,
5860 assert(status == VA_STATUS_SUCCESS);
5862 src_surface.base = (struct object_base *)obj_surface;
5863 src_surface.type = I965_SURFACE_TYPE_SURFACE;
5864 src_surface.flags = proc_frame_to_pp_frame[pipeline_param->filter_flags & 0x3];
5867 if (pipeline_param->surface_region) {
5868 src_rect.x = pipeline_param->surface_region->x;
5869 src_rect.y = pipeline_param->surface_region->y;
5870 src_rect.width = pipeline_param->surface_region->width;
5871 src_rect.height = pipeline_param->surface_region->height;
5875 src_rect.width = in_width;
5876 src_rect.height = in_height;
5879 proc_context->pp_context.pipeline_param = pipeline_param;
5881 for (i = 0; i < pipeline_param->num_filters; i++) {
5882 struct object_buffer *obj_buffer = BUFFER(pipeline_param->filters[i]);
5883 VAProcFilterParameterBufferBase *filter_param = NULL;
5884 VAProcFilterType filter_type;
5888 !obj_buffer->buffer_store ||
5889 !obj_buffer->buffer_store->buffer) {
5890 status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN;
5894 out_surface_id = VA_INVALID_ID;
5895 filter_param = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5896 filter_type = filter_param->type;
5897 kernel_index = procfilter_to_pp_flag[filter_type];
5899 if (kernel_index != PP_NULL &&
5900 proc_context->pp_context.pp_modules[kernel_index].kernel.bo != NULL) {
5901 status = i965_CreateSurfaces(ctx,
5904 VA_RT_FORMAT_YUV420,
5907 assert(status == VA_STATUS_SUCCESS);
5908 tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5909 obj_surface = SURFACE(out_surface_id);
5910 assert(obj_surface);
5911 i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
5912 dst_surface.base = (struct object_base *)obj_surface;
5913 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5914 status = i965_post_processing_internal(ctx, &proc_context->pp_context,
5922 if (status == VA_STATUS_SUCCESS) {
5923 src_surface.base = dst_surface.base;
5924 src_surface.type = dst_surface.type;
5925 src_surface.flags = dst_surface.flags;
5930 proc_context->pp_context.pipeline_param = NULL;
5931 obj_surface = SURFACE(proc_state->current_render_target);
5934 status = VA_STATUS_ERROR_INVALID_SURFACE;
5938 if (pipeline_param->output_region) {
5939 dst_rect.x = pipeline_param->output_region->x;
5940 dst_rect.y = pipeline_param->output_region->y;
5941 dst_rect.width = pipeline_param->output_region->width;
5942 dst_rect.height = pipeline_param->output_region->height;
5946 dst_rect.width = obj_surface->orig_width;
5947 dst_rect.height = obj_surface->orig_height;
5950 if (IS_GEN7(i965->intel.device_info) ||
5951 IS_GEN8(i965->intel.device_info) ||
5952 IS_GEN9(i965->intel.device_info)) {
5953 unsigned int saved_filter_flag;
5954 struct i965_post_processing_context *i965pp_context = i965->pp_context;
5956 if (obj_surface->fourcc == 0) {
5957 i965_check_alloc_surface_bo(ctx, obj_surface, 1,
5962 i965_vpp_clear_surface(ctx, &proc_context->pp_context,
5964 pipeline_param->output_background_color);
5966 intel_batchbuffer_flush(hw_context->batch);
5968 saved_filter_flag = i965pp_context->filter_flags;
5969 i965pp_context->filter_flags = VA_FILTER_SCALING_HQ;
5971 dst_surface.base = (struct object_base *)obj_surface;
5972 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5973 i965_image_processing(ctx, &src_surface, &src_rect, &dst_surface, &dst_rect);
5975 i965pp_context->filter_flags = saved_filter_flag;
5977 if (num_tmp_surfaces)
5978 i965_DestroySurfaces(ctx,
5982 return VA_STATUS_SUCCESS;
5986 if (obj_surface->fourcc && obj_surface->fourcc != VA_FOURCC_NV12){
5988 out_surface_id = VA_INVALID_ID;
5989 status = i965_CreateSurfaces(ctx,
5990 obj_surface->orig_width,
5991 obj_surface->orig_height,
5992 VA_RT_FORMAT_YUV420,
5995 assert(status == VA_STATUS_SUCCESS);
5996 tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
5997 struct object_surface *csc_surface = SURFACE(out_surface_id);
5998 assert(csc_surface);
5999 i965_check_alloc_surface_bo(ctx, csc_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
6000 dst_surface.base = (struct object_base *)csc_surface;
6002 i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
6003 dst_surface.base = (struct object_base *)obj_surface;
6006 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
6007 i965_vpp_clear_surface(ctx, &proc_context->pp_context, obj_surface, pipeline_param->output_background_color);
6009 // load/save doesn't support different origin offset for src and dst surface
6010 if (src_rect.width == dst_rect.width &&
6011 src_rect.height == dst_rect.height &&
6012 src_rect.x == dst_rect.x &&
6013 src_rect.y == dst_rect.y) {
6014 i965_post_processing_internal(ctx, &proc_context->pp_context,
6019 PP_NV12_LOAD_SAVE_N12,
6023 proc_context->pp_context.filter_flags = pipeline_param->filter_flags;
6024 i965_post_processing_internal(ctx, &proc_context->pp_context,
6029 avs_is_needed(pipeline_param->filter_flags) ? PP_NV12_AVS : PP_NV12_SCALING,
6034 src_surface.base = dst_surface.base;
6035 src_surface.type = dst_surface.type;
6036 src_surface.flags = dst_surface.flags;
6037 dst_surface.base = (struct object_base *)obj_surface;
6038 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
6039 i965_image_processing(ctx, &src_surface, &dst_rect, &dst_surface, &dst_rect);
6042 if (num_tmp_surfaces)
6043 i965_DestroySurfaces(ctx,
6047 intel_batchbuffer_flush(hw_context->batch);
6049 return VA_STATUS_SUCCESS;
6052 if (num_tmp_surfaces)
6053 i965_DestroySurfaces(ctx,
6061 i965_proc_context_destroy(void *hw_context)
6063 struct i965_proc_context * const proc_context = hw_context;
6064 VADriverContextP const ctx = proc_context->driver_context;
6066 i965_post_processing_context_finalize(ctx, &proc_context->pp_context);
6067 intel_batchbuffer_free(proc_context->base.batch);
6072 i965_proc_context_init(VADriverContextP ctx, struct object_config *obj_config)
6074 struct i965_driver_data *i965 = i965_driver_data(ctx);
6075 struct intel_driver_data *intel = intel_driver_data(ctx);
6076 struct i965_proc_context *proc_context = calloc(1, sizeof(struct i965_proc_context));
6078 proc_context->base.destroy = i965_proc_context_destroy;
6079 proc_context->base.run = i965_proc_picture;
6080 proc_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
6081 proc_context->driver_context = ctx;
6082 i965->codec_info->post_processing_context_init(ctx, &proc_context->pp_context, proc_context->base.batch);
6084 return (struct hw_context *)proc_context;