2 * Copyright © 2011 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 * Li Xiaowei <xiaowei.a.li@intel.com>
26 * Li Zhong <zhong.li@intel.com>
35 #include "intel_batchbuffer.h"
36 #include "intel_driver.h"
37 #include "i965_defines.h"
38 #include "i965_structs.h"
39 #include "gen75_vpp_vebox.h"
40 #include "intel_media.h"
45 i965_MapBuffer(VADriverContextP ctx, VABufferID buf_id, void **);
48 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
51 i965_DeriveImage(VADriverContextP ctx, VABufferID surface, VAImage *out_image);
54 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
57 vpp_surface_convert(VADriverContextP ctx, struct object_surface *src_obj_surf,
58 struct object_surface *dst_obj_surf)
60 VAStatus va_status = VA_STATUS_SUCCESS;
62 assert(src_obj_surf->orig_width == dst_obj_surf->orig_width);
63 assert(src_obj_surf->orig_height == dst_obj_surf->orig_height);
65 VARectangle src_rect, dst_rect;
66 src_rect.x = dst_rect.x = 0;
67 src_rect.y = dst_rect.y = 0;
68 src_rect.width = dst_rect.width = src_obj_surf->orig_width;
69 src_rect.height = dst_rect.height = dst_obj_surf->orig_height;
71 struct i965_surface src_surface, dst_surface;
72 src_surface.base = (struct object_base *)src_obj_surf;
73 src_surface.type = I965_SURFACE_TYPE_SURFACE;
74 src_surface.flags = I965_SURFACE_FLAG_FRAME;
76 dst_surface.base = (struct object_base *)dst_obj_surf;
77 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
78 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
80 va_status = i965_image_processing(ctx,
89 vpp_surface_scaling(VADriverContextP ctx, struct object_surface *src_obj_surf,
90 struct object_surface *dst_obj_surf, uint32_t flags)
92 VAStatus va_status = VA_STATUS_SUCCESS;
94 assert(src_obj_surf->fourcc == VA_FOURCC_NV12);
95 assert(dst_obj_surf->fourcc == VA_FOURCC_NV12);
97 VARectangle src_rect, dst_rect;
100 src_rect.width = src_obj_surf->orig_width;
101 src_rect.height = src_obj_surf->orig_height;
105 dst_rect.width = dst_obj_surf->orig_width;
106 dst_rect.height = dst_obj_surf->orig_height;
108 va_status = i965_scaling_processing(ctx,
118 void hsw_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
120 struct i965_driver_data *i965 = i965_driver_data(ctx);
121 unsigned int* p_table ;
122 unsigned int progressive_dn = 1;
123 unsigned int dndi_top_first = 0;
124 unsigned int is_mcdi_enabled = 0;
126 if (proc_ctx->is_di_enabled) {
127 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
132 /* If we are in "First Frame" mode, i.e. past frames are not
133 available for motion measure, then don't use the TFF flag */
134 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
135 VA_DEINTERLACING_BOTTOM_FIELD :
136 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
139 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
143 VAProcFilterParameterBufferDeinterlacing *di_param =
144 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
146 VAProcFilterParameterBuffer * dn_param =
147 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
149 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
151 if (IS_HASWELL(i965->intel.device_info))
152 *p_table ++ = 0; // reserved . w0
154 *p_table ++ = ( 140 << 24 | // denoise STAD threshold . w1
155 192 << 16 | // dnmh_history_max
156 0 << 12 | // reserved
157 7 << 8 | // dnmh_delta[3:0]
158 38 ); // denoise ASD threshold
160 *p_table ++ = ( 0 << 30 | // reserved . w2
161 0 << 24 | // temporal diff th
162 0 << 22 | // reserved.
163 0 << 16 | // low temporal diff th
165 1 << 8 | // denoise moving pixel th
166 38 ); // denoise th for sum of complexity measure
168 *p_table ++ = ( 0 << 30 | // reserved . w3
169 12<< 24 | // good neighbor th[5:0]
170 9 << 20 | // CAT slope minus 1
171 5 << 16 | // SAD Tight in
172 0 << 14 | // smooth mv th
173 0 << 12 | // reserved
174 1 << 8 | // bne_edge_th[3:0]
175 20 ); // block noise estimate noise th
177 *p_table ++ = ( 0 << 31 | // STMM blending constant select. w4
178 64 << 24 | // STMM trc1
179 125<< 16 | // STMM trc2
180 0 << 14 | // reserved
181 30 << 8 | // VECM_mul
182 150 ); // maximum STMM
184 *p_table ++ = ( 118<< 24 | // minumum STMM . W5
185 0 << 22 | // STMM shift down
186 1 << 20 | // STMM shift up
187 5 << 16 | // STMM output shift
188 100 << 8 | // SDI threshold
191 *p_table ++ = ( 50 << 24 | // SDI fallback mode 1 T1 constant . W6
192 100 << 16 | // SDI fallback mode 1 T2 constant
193 37 << 8 | // SDI fallback mode 2 constant(angle2x1)
194 175 ); // FMD temporal difference threshold
196 *p_table ++ = ( 16 << 24 | // FMD #1 vertical difference th . w7
197 100<< 16 | // FMD #2 vertical difference th
199 2 << 8 | // FMD tear threshold
200 is_mcdi_enabled << 7 | // MCDI Enable, use motion compensated deinterlace algorithm
201 progressive_dn << 6 | // progressive DN
203 dndi_top_first << 3 | // DN/DI Top First
206 *p_table ++ = ( 0 << 29 | // reserved . W8
207 32 << 23 | // dnmh_history_init[5:0]
208 10 << 19 | // neighborPixel th
209 0 << 18 | // reserved
210 0 << 16 | // FMD for 2nd field of previous frame
211 25 << 10 | // MC pixel consistency th
212 0 << 8 | // FMD for 1st field for current frame
216 *p_table ++ = ( 0 << 24 | // reserved
217 140<< 16 | // chr_dnmh_stad_th
218 0 << 13 | // reserved
219 1 << 12 | // chrome denoise enable
220 13 << 6 | // chr temp diff th
221 7 ); // chr temp diff low
223 if (IS_GEN8(i965->intel.device_info) ||
224 IS_GEN9(i965->intel.device_info))
225 *p_table ++ = 0; // parameters for hot pixel,
228 //Set default values for STDE
229 void set_std_table_default(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
232 *p_table ++ = ( 0 << 31 | // Reserved
233 0x3F8 << 21 | // SATB1 (10 bits, default 8, optimized value -8)
236 0x7A ); // SATP1 (7 bits, default 6, optimized value -6)
239 *p_table ++ = ( 0 << 31 | // Reserved
245 *p_table ++ = ( 0 << 22 | // Reserved
250 *p_table ++ = ( 14 << 25 | // HUEP3
252 0x7A << 11 | // HUEP1 (7 bits, default value -6 = 7Ah)
256 *p_table ++ = ( 0 << 30 | // Reserved
259 0x3F8 ); // HUEB1 (10 bits, default value 8, optimized value -8)
262 *p_table ++ = ( 0 << 22 | // Reserved
267 *p_table ++ = ( 0 << 22 | // Reserved
272 *p_table ++ = ( 0 << 31 | // Reserved
273 0 << 21 | // SATB1_DARK
274 31 << 14 | // SATP3_DARK
275 31 << 7 | // SATP2_DARK
276 0x7B ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value -5)
279 *p_table ++ = ( 0 << 31 | // Reserved
280 305 << 20 | // SATS0_DARK
281 124 << 10 | // SATB3_DARK
285 *p_table ++ = ( 0 << 22 | // Reserved
286 256 << 11 | // SATS2_DARK
290 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
291 14 << 18 | // HUEP2_DARK
292 14 << 11 | // HUEP1_DARK
296 *p_table ++ = ( 0 << 30 | // Reserved
297 56 << 20 | // HUEB3_DARK
298 56 << 10 | // HUEB2_DARK
302 *p_table ++ = ( 0 << 22 | // Reserved
303 256 << 11 | // HUES1_DARK
307 *p_table ++ = ( 0 << 22 | // Reserved
308 256 << 11 | // HUES3_DARK
312 //Set values for STDE factor 3
313 void set_std_table_3(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
316 *p_table ++ = ( 0 << 31 | // Reserved
317 1016 << 21 | // SATB1 (10 bits, default 8, optimized value 1016)
320 122 ); // SATP1 (7 bits, default 6, optimized value 122)
323 *p_table ++ = ( 0 << 31 | // Reserved
329 *p_table ++ = ( 0 << 22 | // Reserved
334 *p_table ++ = ( 14 << 25 | // HUEP3
336 122 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized 122)
340 *p_table ++ = ( 0 << 30 | // Reserved
341 56 << 20 | // HUEB3 (default 256, optimized 56)
343 1016 ); // HUEB1 (10 bits, default value 8, optimized value 1016)
346 *p_table ++ = ( 0 << 22 | // Reserved
351 *p_table ++ = ( 0 << 22 | // Reserved
356 *p_table ++ = ( 0 << 31 | // Reserved
357 0 << 21 | // SATB1_DARK
358 31 << 14 | // SATP3_DARK
359 31 << 7 | // SATP2_DARK
360 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
363 *p_table ++ = ( 0 << 31 | // Reserved
364 305 << 20 | // SATS0_DARK
365 124 << 10 | // SATB3_DARK
369 *p_table ++ = ( 0 << 22 | // Reserved
370 256 << 11 | // SATS2_DARK
374 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
375 14 << 18 | // HUEP2_DARK
376 14 << 11 | // HUEP1_DARK
380 *p_table ++ = ( 0 << 30 | // Reserved
381 56 << 20 | // HUEB3_DARK
382 56 << 10 | // HUEB2_DARK
386 *p_table ++ = ( 0 << 22 | // Reserved
387 256 << 11 | // HUES1_DARK
391 *p_table ++ = ( 0 << 22 | // Reserved
392 256 << 11 | // HUES3_DARK
396 //Set values for STDE factor 6
397 void set_std_table_6(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
400 *p_table ++ = ( 0 << 31 | // Reserved
401 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
403 31 << 7 | // SATP2 (default 6, optimized 31)
404 114 ); // SATP1 (7 bits, default 6, optimized value 114)
407 *p_table ++ = ( 0 << 31 | // Reserved
408 467 << 20 | // SATS0 (default 297, optimized 467)
413 *p_table ++ = ( 0 << 22 | // Reserved
414 256 << 11 | // SATS2 (default 297, optimized 256)
418 *p_table ++ = ( 14 << 25 | // HUEP3
420 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
424 *p_table ++ = ( 0 << 30 | // Reserved
427 56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
430 *p_table ++ = ( 0 << 22 | // Reserved
435 *p_table ++ = ( 0 << 22 | // Reserved
440 *p_table ++ = ( 0 << 31 | // Reserved
441 0 << 21 | // SATB1_DARK
442 31 << 14 | // SATP3_DARK
443 31 << 7 | // SATP2_DARK
444 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
447 *p_table ++ = ( 0 << 31 | // Reserved
448 305 << 20 | // SATS0_DARK
449 124 << 10 | // SATB3_DARK
453 *p_table ++ = ( 0 << 22 | // Reserved
454 256 << 11 | // SATS2_DARK
458 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
459 14 << 18 | // HUEP2_DARK
460 14 << 11 | // HUEP1_DARK
464 *p_table ++ = ( 0 << 30 | // Reserved
465 56 << 20 | // HUEB3_DARK
466 56 << 10 | // HUEB2_DARK
470 *p_table ++ = ( 0 << 22 | // Reserved
471 256 << 11 | // HUES1_DARK
475 *p_table ++ = ( 0 << 22 | // Reserved
476 256 << 11 | // HUES3_DARK
480 //Set values for STDE factor 9
481 void set_std_table_9(struct intel_vebox_context *proc_ctx, unsigned int *p_table) {
484 *p_table ++ = ( 0 << 31 | // Reserved
485 0 << 21 | // SATB1 (10 bits, default 8, optimized value 0)
487 31 << 7 | // SATP2 (default 6, optimized 31)
488 108 ); // SATP1 (7 bits, default 6, optimized value 108)
491 *p_table ++ = ( 0 << 31 | // Reserved
492 721 << 20 | // SATS0 (default 297, optimized 721)
497 *p_table ++ = ( 0 << 22 | // Reserved
498 256 << 11 | // SATS2 (default 297, optimized 256)
499 156 ); // SATS1 (default 176, optimized 156)
502 *p_table ++ = ( 14 << 25 | // HUEP3
504 14 << 11 | // HUEP1 (7 bits, default value -6 = 7Ah, optimized value 14)
508 *p_table ++ = ( 0 << 30 | // Reserved
511 56 ); // HUEB1 (10 bits, default value 8, optimized value 56)
514 *p_table ++ = ( 0 << 22 | // Reserved
519 *p_table ++ = ( 0 << 22 | // Reserved
524 *p_table ++ = ( 0 << 31 | // Reserved
525 0 << 21 | // SATB1_DARK
526 31 << 14 | // SATP3_DARK
527 31 << 7 | // SATP2_DARK
528 123 ); // SATP1_DARK (7 bits, default value -11 = FF5h, optimized value 123)
531 *p_table ++ = ( 0 << 31 | // Reserved
532 305 << 20 | // SATS0_DARK
533 124 << 10 | // SATB3_DARK
537 *p_table ++ = ( 0 << 22 | // Reserved
538 256 << 11 | // SATS2_DARK
542 *p_table ++ = ( 14 << 25 | // HUEP3_DARK
543 14 << 18 | // HUEP2_DARK
544 14 << 11 | // HUEP1_DARK
548 *p_table ++ = ( 0 << 30 | // Reserved
549 56 << 20 | // HUEB3_DARK
550 56 << 10 | // HUEB2_DARK
554 *p_table ++ = ( 0 << 22 | // Reserved
555 256 << 11 | // HUES1_DARK
559 *p_table ++ = ( 0 << 22 | // Reserved
560 256 << 11 | // HUES3_DARK
565 void hsw_veb_iecp_std_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
567 unsigned int *p_table = proc_ctx->iecp_state_table.ptr + 0 ;
569 if(!(proc_ctx->filters_mask & VPP_IECP_STD_STE)){
570 memset(p_table, 0, 29 * 4);
572 int stde_factor = 0; //default value
573 VAProcFilterParameterBuffer * std_param = (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_std;
574 stde_factor = std_param->value;
577 *p_table ++ = ( 154 << 24 | // V_Mid
579 14 << 10 | // Hue_Max
582 0 << 2 | // Output Control is set to output the 1=STD score /0=Output Pixels
583 1 << 1 | // Set STE Enable
584 1 ); // Set STD Enable
587 *p_table ++ = ( 0 << 31 | // Reserved
588 4 << 28 | // Diamond Margin
589 0 << 21 | // Diamond_du
590 3 << 18 | // HS_Margin
591 79 << 10 | // Cos(alpha)
596 *p_table ++ = ( 0 << 21 | // Reserved
597 100 << 13 | // Diamond_alpha
598 35 << 7 | // Diamond_Th
602 *p_table ++ = ( 254 << 24 | // Y_point_3
603 47 << 16 | // Y_point_2
604 46 << 8 | // Y_point_1
605 1 << 7 | // VY_STD_Enable
609 *p_table ++ = ( 0 << 18 | // Reserved
610 31 << 13 | // Y_slope_2
611 31 << 8 | // Y_slope_1
615 *p_table ++ = ( 400 << 16 | // INV_Skin_types_margin = 20* Skin_Type_margin => 20*20
616 3300 ); // INV_Margin_VYL => 1/Margin_VYL
619 *p_table ++ = ( 216 << 24 | // P1L
621 1600 ); // INV_Margin_VYU
624 *p_table ++ = ( 130 << 24 | // B1L
630 *p_table ++ = ( 0 << 27 | // Reserved
631 0x7FB << 16 | // S0L (11 bits, Default value: -5 = FBh, pad it with 1s to make it 11bits)
636 *p_table ++ = ( 0 << 22 | // Reserved
641 *p_table ++ = ( 0 << 27 | // Reserved
647 *p_table ++ = ( 163 << 24 | // B1U
653 *p_table ++ = ( 0 << 27 | // Reserved
659 *p_table ++ = ( 0 << 22 | // Reserved
660 0x74D << 11 | // S2U (11 bits, Default value -179 = F4Dh)
664 *p_table ++ = ( 0 << 28 | // Reserved
665 20 << 20 | // Skin_types_margin
666 120 << 12 | // Skin_types_thresh
667 1 << 11 | // Skin_Types_Enable
670 //Set DWord 15 through DWord 28 in their respective methods.
671 switch(stde_factor) {
673 set_std_table_3(proc_ctx, p_table);
677 set_std_table_6(proc_ctx, p_table);
681 set_std_table_9(proc_ctx, p_table);
685 set_std_table_default(proc_ctx, p_table);
691 void hsw_veb_iecp_ace_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
693 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 116);
695 if(!(proc_ctx->filters_mask & VPP_IECP_ACE)){
696 memset(p_table, 0, 13 * 4);
698 *p_table ++ = 0x00000068;
699 *p_table ++ = 0x4c382410;
700 *p_table ++ = 0x9c887460;
701 *p_table ++ = 0xebd8c4b0;
702 *p_table ++ = 0x604c3824;
704 *p_table ++ = 0xb09c8874;
705 *p_table ++ = 0x0000d8c4;
706 *p_table ++ = 0x00000000;
707 *p_table ++ = 0x00000000;
708 *p_table ++ = 0x00000000;
710 *p_table ++ = 0x00000000;
711 *p_table ++ = 0x00000000;
712 *p_table ++ = 0x00000000;
716 void hsw_veb_iecp_tcc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
718 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 168);
719 // VAProcFilterParameterBuffer * tcc_param =
720 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
722 if(!(proc_ctx->filters_mask & VPP_IECP_TCC)){
723 memset(p_table, 0, 11 * 4);
725 *p_table ++ = 0x00000000;
726 *p_table ++ = 0x00000000;
727 *p_table ++ = 0x1e34cc91;
728 *p_table ++ = 0x3e3cce91;
729 *p_table ++ = 0x02e80195;
731 *p_table ++ = 0x0197046b;
732 *p_table ++ = 0x01790174;
733 *p_table ++ = 0x00000000;
734 *p_table ++ = 0x00000000;
735 *p_table ++ = 0x03030000;
737 *p_table ++ = 0x009201c0;
741 void hsw_veb_iecp_pro_amp_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
743 unsigned int contrast = 0x80; //default
744 int brightness = 0x00; //default
745 int cos_c_s = 256 ; //default
746 int sin_c_s = 0; //default
747 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 212);
749 if(!(proc_ctx->filters_mask & VPP_IECP_PRO_AMP)){
750 memset(p_table, 0, 2 * 4);
752 float src_saturation = 1.0;
754 float src_contrast = 1.0;
755 float src_brightness = 0.0;
756 float tmp_value = 0.0;
759 VAProcFilterParameterBufferColorBalance * amp_params =
760 (VAProcFilterParameterBufferColorBalance *) proc_ctx->filter_iecp_amp;
762 for (i = 0; i < proc_ctx->filter_iecp_amp_num_elements; i++){
763 VAProcColorBalanceType attrib = amp_params[i].attrib;
765 if(attrib == VAProcColorBalanceHue) {
766 src_hue = amp_params[i].value; //(-180.0, 180.0)
767 }else if(attrib == VAProcColorBalanceSaturation) {
768 src_saturation = amp_params[i].value; //(0.0, 10.0)
769 }else if(attrib == VAProcColorBalanceBrightness) {
770 src_brightness = amp_params[i].value; // (-100.0, 100.0)
771 brightness = intel_format_convert(src_brightness, 7, 4, 1);
772 }else if(attrib == VAProcColorBalanceContrast) {
773 src_contrast = amp_params[i].value; // (0.0, 10.0)
774 contrast = intel_format_convert(src_contrast, 4, 7, 0);
778 tmp_value = cos(src_hue/180*PI) * src_contrast * src_saturation;
779 cos_c_s = intel_format_convert(tmp_value, 7, 8, 1);
781 tmp_value = sin(src_hue/180*PI) * src_contrast * src_saturation;
782 sin_c_s = intel_format_convert(tmp_value, 7, 8, 1);
784 *p_table ++ = ( 0 << 28 | //reserved
785 contrast << 17 | //contrast value (U4.7 format)
787 brightness << 1| // S7.4 format
790 *p_table ++ = ( cos_c_s << 16 | // cos(h) * contrast * saturation
791 sin_c_s); // sin(h) * contrast * saturation
797 void hsw_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
799 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
800 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
801 float v_coef[3] = {0.0, 0.0, 0.0};
802 float u_coef[3] = {0.0, 0.0, 0.0};
803 int is_transform_enabled = 0;
805 if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
806 memset(p_table, 0, 8 * 4);
810 if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
811 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
812 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
813 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
814 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
816 tran_coef[0] = 0.257;
817 tran_coef[1] = 0.504;
818 tran_coef[2] = 0.098;
819 tran_coef[3] = -0.148;
820 tran_coef[4] = -0.291;
821 tran_coef[5] = 0.439;
822 tran_coef[6] = 0.439;
823 tran_coef[7] = -0.368;
824 tran_coef[8] = -0.071;
830 is_transform_enabled = 1;
831 }else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
832 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
833 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
834 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
835 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
836 tran_coef[0] = 1.164;
837 tran_coef[1] = 0.000;
838 tran_coef[2] = 1.569;
839 tran_coef[3] = 1.164;
840 tran_coef[4] = -0.813;
841 tran_coef[5] = -0.392;
842 tran_coef[6] = 1.164;
843 tran_coef[7] = 2.017;
844 tran_coef[8] = 0.000;
847 v_coef[1] = -128 * 4;
848 v_coef[2] = -128 * 4;
850 is_transform_enabled = 1;
851 }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
852 //enable when input and output format are different.
853 is_transform_enabled = 1;
856 if(is_transform_enabled == 0){
857 memset(p_table, 0, 8 * 4);
859 *p_table ++ = ( 0 << 29 | //reserved
860 intel_format_convert(tran_coef[1], 2, 10, 1) << 16 | //c1, s2.10 format
861 intel_format_convert(tran_coef[0], 2, 10, 1) << 3 | //c0, s2.10 format
863 0 << 1 | // yuv_channel swap
864 is_transform_enabled);
866 *p_table ++ = ( 0 << 26 | //reserved
867 intel_format_convert(tran_coef[3], 2, 10, 1) << 13 |
868 intel_format_convert(tran_coef[2], 2, 10, 1));
870 *p_table ++ = ( 0 << 26 | //reserved
871 intel_format_convert(tran_coef[5], 2, 10, 1) << 13 |
872 intel_format_convert(tran_coef[4], 2, 10, 1));
874 *p_table ++ = ( 0 << 26 | //reserved
875 intel_format_convert(tran_coef[7], 2, 10, 1) << 13 |
876 intel_format_convert(tran_coef[6], 2, 10, 1));
878 *p_table ++ = ( 0 << 13 | //reserved
879 intel_format_convert(tran_coef[8], 2, 10, 1));
881 *p_table ++ = ( 0 << 22 | //reserved
882 intel_format_convert(u_coef[0], 10, 0, 1) << 11 |
883 intel_format_convert(v_coef[0], 10, 0, 1));
885 *p_table ++ = ( 0 << 22 | //reserved
886 intel_format_convert(u_coef[1], 10, 0, 1) << 11 |
887 intel_format_convert(v_coef[1], 10, 0, 1));
889 *p_table ++ = ( 0 << 22 | //reserved
890 intel_format_convert(u_coef[2], 10, 0, 1) << 11 |
891 intel_format_convert(v_coef[2], 10, 0, 1));
895 void hsw_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
897 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 252);
898 // VAProcFilterParameterBuffer * tcc_param =
899 // (VAProcFilterParameterBuffer *) proc_ctx->filter_iecp_tcc;
901 if(!(proc_ctx->filters_mask & VPP_IECP_AOI)){
902 memset(p_table, 0, 3 * 4);
904 *p_table ++ = 0x00000000;
905 *p_table ++ = 0x00030000;
906 *p_table ++ = 0x00030000;
910 void hsw_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
912 if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
913 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
914 dri_bo_map(dndi_bo, 1);
915 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
917 hsw_veb_dndi_table(ctx, proc_ctx);
919 dri_bo_unmap(dndi_bo);
922 if(proc_ctx->filters_mask & VPP_IECP_MASK) {
923 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
924 dri_bo_map(iecp_bo, 1);
925 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
927 hsw_veb_iecp_std_table(ctx, proc_ctx);
928 hsw_veb_iecp_ace_table(ctx, proc_ctx);
929 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
930 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
931 hsw_veb_iecp_csc_table(ctx, proc_ctx);
932 hsw_veb_iecp_aoi_table(ctx, proc_ctx);
934 dri_bo_unmap(iecp_bo);
938 void hsw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
940 struct intel_batchbuffer *batch = proc_ctx->batch;
942 BEGIN_VEB_BATCH(batch, 6);
943 OUT_VEB_BATCH(batch, VEB_STATE | (6 - 2));
945 0 << 26 | // state surface control bits
946 0 << 11 | // reserved.
947 0 << 10 | // pipe sync disable
948 proc_ctx->current_output_type << 8 | // DI output frame
949 1 << 7 | // 444->422 downsample method
950 1 << 6 | // 422->420 downsample method
951 proc_ctx->is_first_frame << 5 | // DN/DI first frame
952 proc_ctx->is_di_enabled << 4 | // DI enable
953 proc_ctx->is_dn_enabled << 3 | // DN enable
954 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
955 0 << 1 | // ColorGamutCompressionEnable
956 0 ) ; // ColorGamutExpansionEnable.
959 proc_ctx->dndi_state_table.bo,
960 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
963 proc_ctx->iecp_state_table.bo,
964 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
967 proc_ctx->gamut_state_table.bo,
968 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
971 proc_ctx->vertex_state_table.bo,
972 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
974 ADVANCE_VEB_BATCH(batch);
977 void hsw_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
979 struct intel_batchbuffer *batch = proc_ctx->batch;
980 unsigned int u_offset_y = 0, v_offset_y = 0;
981 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
982 unsigned int surface_format = PLANAR_420_8;
983 struct object_surface* obj_surf = NULL;
984 unsigned int surface_pitch = 0;
985 unsigned int half_pitch_chroma = 0;
988 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
990 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
993 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
994 obj_surf->fourcc == VA_FOURCC_YUY2 ||
995 obj_surf->fourcc == VA_FOURCC_AYUV ||
996 obj_surf->fourcc == VA_FOURCC_RGBA);
998 if (obj_surf->fourcc == VA_FOURCC_NV12) {
999 surface_format = PLANAR_420_8;
1000 surface_pitch = obj_surf->width;
1001 is_uv_interleaved = 1;
1002 half_pitch_chroma = 0;
1003 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
1004 surface_format = YCRCB_NORMAL;
1005 surface_pitch = obj_surf->width * 2;
1006 is_uv_interleaved = 0;
1007 half_pitch_chroma = 0;
1008 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
1009 surface_format = PACKED_444A_8;
1010 surface_pitch = obj_surf->width * 4;
1011 is_uv_interleaved = 0;
1012 half_pitch_chroma = 0;
1013 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
1014 surface_format = R8G8B8A8_UNORM_SRGB;
1015 surface_pitch = obj_surf->width * 4;
1016 is_uv_interleaved = 0;
1017 half_pitch_chroma = 0;
1020 u_offset_y = obj_surf->y_cb_offset;
1021 v_offset_y = obj_surf->y_cr_offset;
1023 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
1025 BEGIN_VEB_BATCH(batch, 6);
1026 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (6 - 2));
1027 OUT_VEB_BATCH(batch,
1028 0 << 1 | // reserved
1029 is_output); // surface indentification.
1031 OUT_VEB_BATCH(batch,
1032 (obj_surf->height - 1) << 18 | // height . w3
1033 (obj_surf->width -1 ) << 4 | // width
1036 OUT_VEB_BATCH(batch,
1037 surface_format << 28 | // surface format, YCbCr420. w4
1038 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
1039 0 << 20 | // reserved
1040 (surface_pitch - 1) << 3 | // surface pitch, 64 align
1041 half_pitch_chroma << 2 | // half pitch for chrome
1042 !!tiling << 1 | // tiled surface, linear surface used
1043 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
1045 OUT_VEB_BATCH(batch,
1046 0 << 29 | // reserved . w5
1047 0 << 16 | // X offset for V(Cb)
1048 0 << 15 | // reserved
1049 u_offset_y); // Y offset for V(Cb)
1051 OUT_VEB_BATCH(batch,
1052 0 << 29 | // reserved . w6
1053 0 << 16 | // X offset for V(Cr)
1054 0 << 15 | // reserved
1055 v_offset_y ); // Y offset for V(Cr)
1057 ADVANCE_VEB_BATCH(batch);
1060 void hsw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1062 struct intel_batchbuffer *batch = proc_ctx->batch;
1063 unsigned char frame_ctrl_bits = 0;
1064 const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1066 /* s1:update the previous and current input */
1067 /* tempFrame = proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1068 proc_ctx->frame_store[FRAME_IN_PREVIOUS] = proc_ctx->frame_store[FRAME_IN_CURRENT]; ;
1069 proc_ctx->frame_store[FRAME_IN_CURRENT] = tempFrame;
1071 if(proc_ctx->surface_input_vebox != -1){
1072 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1073 proc_ctx->surface_input_vebox);
1075 vpp_surface_copy(ctx, proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id,
1076 proc_ctx->surface_input);
1079 /*s2: update the STMM input and output */
1080 /* tempFrame = proc_ctx->frame_store[FRAME_IN_STMM];
1081 proc_ctx->frame_store[FRAME_IN_STMM] = proc_ctx->frame_store[FRAME_OUT_STMM]; ;
1082 proc_ctx->frame_store[FRAME_OUT_STMM] = tempFrame;
1084 /*s3:set reloc buffer address */
1085 BEGIN_VEB_BATCH(batch, 10);
1086 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (10 - 2));
1087 OUT_VEB_BATCH(batch, (width64 - 1));
1089 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1090 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1092 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1093 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1095 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1096 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);
1098 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1099 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1101 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1102 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1104 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1105 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1107 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1108 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1110 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1111 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);
1113 ADVANCE_VEB_BATCH(batch);
1117 frame_store_reset(VEBFrameStore *fs)
1119 fs->obj_surface = NULL;
1120 fs->surface_id = VA_INVALID_ID;
1121 fs->is_internal_surface = 0;
1122 fs->is_scratch_surface = 0;
1126 frame_store_clear(VEBFrameStore *fs, VADriverContextP ctx)
1128 if (fs->obj_surface && fs->is_scratch_surface) {
1129 VASurfaceID surface_id = fs->obj_surface->base.id;
1130 i965_DestroySurfaces(ctx, &surface_id, 1);
1132 frame_store_reset(fs);
1136 gen75_vebox_ensure_surfaces_storage(VADriverContextP ctx,
1137 struct intel_vebox_context *proc_ctx)
1139 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1140 struct object_surface *input_obj_surface, *output_obj_surface;
1141 unsigned int input_fourcc, output_fourcc;
1142 unsigned int input_sampling, output_sampling;
1143 unsigned int input_tiling, output_tiling;
1144 unsigned int i, swizzle;
1148 /* Determine input surface info. Use native VEBOX format whenever
1149 possible. i.e. when the input surface format is not supported
1150 by the VEBOX engine, then allocate a temporary surface (live
1151 during the whole VPP pipeline lifetime)
1153 XXX: derive an actual surface format compatible with the input
1154 surface chroma format */
1155 input_obj_surface = proc_ctx->surface_input_vebox_object ?
1156 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1157 if (input_obj_surface->bo) {
1158 input_fourcc = input_obj_surface->fourcc;
1159 input_sampling = input_obj_surface->subsampling;
1160 dri_bo_get_tiling(input_obj_surface->bo, &input_tiling, &swizzle);
1161 input_tiling = !!input_tiling;
1164 input_fourcc = VA_FOURCC_NV12;
1165 input_sampling = SUBSAMPLE_YUV420;
1167 status = i965_check_alloc_surface_bo(ctx, input_obj_surface,
1168 input_tiling, input_fourcc, input_sampling);
1169 if (status != VA_STATUS_SUCCESS)
1173 /* Determine output surface info.
1175 XXX: derive an actual surface format compatible with the input
1176 surface chroma format */
1177 output_obj_surface = proc_ctx->surface_output_vebox_object ?
1178 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1179 if (output_obj_surface->bo) {
1180 output_fourcc = output_obj_surface->fourcc;
1181 output_sampling = output_obj_surface->subsampling;
1182 dri_bo_get_tiling(output_obj_surface->bo, &output_tiling, &swizzle);
1183 output_tiling = !!output_tiling;
1186 output_fourcc = VA_FOURCC_NV12;
1187 output_sampling = SUBSAMPLE_YUV420;
1189 status = i965_check_alloc_surface_bo(ctx, output_obj_surface,
1190 output_tiling, output_fourcc, output_sampling);
1191 if (status != VA_STATUS_SUCCESS)
1195 /* Update VEBOX pipeline formats */
1196 proc_ctx->fourcc_input = input_fourcc;
1197 proc_ctx->fourcc_output = output_fourcc;
1198 if (input_fourcc != output_fourcc)
1199 proc_ctx->is_iecp_enabled = 1; // IECP needed for format conversion
1201 /* Create pipeline surfaces */
1202 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i ++) {
1203 struct object_surface *obj_surface;
1204 VASurfaceID new_surface;
1206 if (proc_ctx->frame_store[i].obj_surface)
1207 continue; // user allocated surface, not VEBOX internal
1209 status = i965_CreateSurfaces(ctx, proc_ctx->width_input,
1210 proc_ctx->height_input, VA_RT_FORMAT_YUV420, 1, &new_surface);
1211 if (status != VA_STATUS_SUCCESS)
1214 obj_surface = SURFACE(new_surface);
1215 assert(obj_surface != NULL);
1217 if (i <= FRAME_IN_PREVIOUS || i == FRAME_OUT_CURRENT_DN) {
1218 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1219 input_tiling, input_fourcc, input_sampling);
1221 else if (i == FRAME_IN_STMM || i == FRAME_OUT_STMM) {
1222 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1223 1, input_fourcc, input_sampling);
1225 else if (i >= FRAME_OUT_CURRENT) {
1226 status = i965_check_alloc_surface_bo(ctx, obj_surface,
1227 output_tiling, output_fourcc, output_sampling);
1229 if (status != VA_STATUS_SUCCESS)
1232 proc_ctx->frame_store[i].obj_surface = obj_surface;
1233 proc_ctx->frame_store[i].is_internal_surface = 1;
1234 proc_ctx->frame_store[i].is_scratch_surface = 1;
1237 /* Allocate DNDI state table */
1238 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1239 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: dndi state Buffer",
1241 proc_ctx->dndi_state_table.bo = bo;
1243 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1245 /* Allocate IECP state table */
1246 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1247 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: iecp state Buffer",
1249 proc_ctx->iecp_state_table.bo = bo;
1251 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1253 /* Allocate Gamut state table */
1254 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1255 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: gamut state Buffer",
1257 proc_ctx->gamut_state_table.bo = bo;
1259 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1261 /* Allocate vertex state table */
1262 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1263 bo = drm_intel_bo_alloc(i965->intel.bufmgr, "vebox: vertex state Buffer",
1265 proc_ctx->vertex_state_table.bo = bo;
1267 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1269 return VA_STATUS_SUCCESS;
1273 gen75_vebox_ensure_surfaces(VADriverContextP ctx,
1274 struct intel_vebox_context *proc_ctx)
1276 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1277 struct object_surface *obj_surface;
1278 VEBFrameStore *ifs, *ofs;
1279 bool is_new_frame = 0;
1282 /* Update the previous input surface */
1283 obj_surface = proc_ctx->surface_input_object;
1285 is_new_frame = proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id !=
1286 obj_surface->base.id;
1288 ifs = &proc_ctx->frame_store[FRAME_IN_PREVIOUS];
1289 ofs = &proc_ctx->frame_store[proc_ctx->is_dn_enabled ?
1290 FRAME_OUT_CURRENT_DN : FRAME_IN_CURRENT];
1292 const VAProcPipelineParameterBuffer * const pipe =
1293 proc_ctx->pipeline_param;
1295 if (pipe->num_forward_references < 1)
1297 if (pipe->forward_references[0] == VA_INVALID_ID)
1300 obj_surface = SURFACE(pipe->forward_references[0]);
1301 if (!obj_surface || obj_surface->base.id == ifs->surface_id)
1304 frame_store_clear(ifs, ctx);
1305 if (obj_surface->base.id == ofs->surface_id) {
1307 frame_store_reset(ofs);
1310 ifs->obj_surface = obj_surface;
1311 ifs->surface_id = obj_surface->base.id;
1312 ifs->is_internal_surface = 0;
1313 ifs->is_scratch_surface = 0;
1318 /* Update the input surface */
1319 obj_surface = proc_ctx->surface_input_vebox_object ?
1320 proc_ctx->surface_input_vebox_object : proc_ctx->surface_input_object;
1322 ifs = &proc_ctx->frame_store[FRAME_IN_CURRENT];
1323 frame_store_clear(ifs, ctx);
1324 ifs->obj_surface = obj_surface;
1325 ifs->surface_id = proc_ctx->surface_input_object->base.id;
1326 ifs->is_internal_surface = proc_ctx->surface_input_vebox_object != NULL;
1327 ifs->is_scratch_surface = 0;
1329 /* Update the Spatial Temporal Motion Measure (STMM) surfaces */
1331 const VEBFrameStore tmpfs = proc_ctx->frame_store[FRAME_IN_STMM];
1332 proc_ctx->frame_store[FRAME_IN_STMM] =
1333 proc_ctx->frame_store[FRAME_OUT_STMM];
1334 proc_ctx->frame_store[FRAME_OUT_STMM] = tmpfs;
1337 /* Reset the output surfaces to defaults. i.e. clean from user surfaces */
1338 for (i = FRAME_OUT_CURRENT_DN; i <= FRAME_OUT_PREVIOUS; i++) {
1339 ofs = &proc_ctx->frame_store[i];
1340 if (!ofs->is_scratch_surface)
1341 ofs->obj_surface = NULL;
1342 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1345 /* Update the output surfaces */
1346 obj_surface = proc_ctx->surface_output_vebox_object ?
1347 proc_ctx->surface_output_vebox_object : proc_ctx->surface_output_object;
1349 proc_ctx->current_output_type = 2;
1350 if (proc_ctx->filters_mask == VPP_DNDI_DN && !proc_ctx->is_iecp_enabled)
1351 proc_ctx->current_output = FRAME_OUT_CURRENT_DN;
1352 else if (proc_ctx->is_di_adv_enabled && !proc_ctx->is_first_frame) {
1353 proc_ctx->current_output_type = 0;
1354 proc_ctx->current_output = proc_ctx->is_second_field ?
1355 FRAME_OUT_CURRENT : FRAME_OUT_PREVIOUS;
1358 proc_ctx->current_output = FRAME_OUT_CURRENT;
1359 ofs = &proc_ctx->frame_store[proc_ctx->current_output];
1360 frame_store_clear(ofs, ctx);
1361 ofs->obj_surface = obj_surface;
1362 ofs->surface_id = proc_ctx->surface_input_object->base.id;
1363 ofs->is_internal_surface = proc_ctx->surface_output_vebox_object != NULL;
1364 ofs->is_scratch_surface = 0;
1366 return VA_STATUS_SUCCESS;
1369 int hsw_veb_pre_format_convert(VADriverContextP ctx,
1370 struct intel_vebox_context *proc_ctx)
1373 struct i965_driver_data *i965 = i965_driver_data(ctx);
1374 struct object_surface* obj_surf_input = proc_ctx->surface_input_object;
1375 struct object_surface* obj_surf_output = proc_ctx->surface_output_object;
1376 struct object_surface* obj_surf_input_vebox;
1377 struct object_surface* obj_surf_output_vebox;
1379 proc_ctx->format_convert_flags = 0;
1381 proc_ctx->width_input = obj_surf_input->orig_width;
1382 proc_ctx->height_input = obj_surf_input->orig_height;
1383 proc_ctx->width_output = obj_surf_output->orig_width;
1384 proc_ctx->height_output = obj_surf_output->orig_height;
1386 /* only partial frame is not supported to be processed */
1388 assert(proc_ctx->width_input == proc_ctx->pipeline_param->surface_region->width);
1389 assert(proc_ctx->height_input == proc_ctx->pipeline_param->surface_region->height);
1390 assert(proc_ctx->width_output == proc_ctx->pipeline_param->output_region->width);
1391 assert(proc_ctx->height_output == proc_ctx->pipeline_param->output_region->height);
1394 if(proc_ctx->width_output != proc_ctx->width_input ||
1395 proc_ctx->height_output != proc_ctx->height_input){
1396 proc_ctx->format_convert_flags |= POST_SCALING_CONVERT;
1399 /* convert the following format to NV12 format */
1400 if(obj_surf_input->fourcc == VA_FOURCC_YV12 ||
1401 obj_surf_input->fourcc == VA_FOURCC_I420 ||
1402 obj_surf_input->fourcc == VA_FOURCC_IMC1 ||
1403 obj_surf_input->fourcc == VA_FOURCC_IMC3 ||
1404 obj_surf_input->fourcc == VA_FOURCC_RGBA ||
1405 obj_surf_input->fourcc == VA_FOURCC_BGRA){
1407 proc_ctx->format_convert_flags |= PRE_FORMAT_CONVERT;
1409 } else if(obj_surf_input->fourcc == VA_FOURCC_AYUV ||
1410 obj_surf_input->fourcc == VA_FOURCC_YUY2 ||
1411 obj_surf_input->fourcc == VA_FOURCC_NV12){
1412 // nothing to do here
1414 /* not support other format as input */
1418 if (proc_ctx->format_convert_flags & PRE_FORMAT_CONVERT) {
1419 if(proc_ctx->surface_input_vebox_object == NULL){
1420 va_status = i965_CreateSurfaces(ctx,
1421 proc_ctx->width_input,
1422 proc_ctx->height_input,
1423 VA_RT_FORMAT_YUV420,
1425 &(proc_ctx->surface_input_vebox));
1426 assert(va_status == VA_STATUS_SUCCESS);
1427 obj_surf_input_vebox = SURFACE(proc_ctx->surface_input_vebox);
1428 assert(obj_surf_input_vebox);
1430 if (obj_surf_input_vebox) {
1431 proc_ctx->surface_input_vebox_object = obj_surf_input_vebox;
1432 i965_check_alloc_surface_bo(ctx, obj_surf_input_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1436 vpp_surface_convert(ctx, proc_ctx->surface_input_object, proc_ctx->surface_input_vebox_object);
1439 /* create one temporary NV12 surfaces for conversion*/
1440 if(obj_surf_output->fourcc == VA_FOURCC_YV12 ||
1441 obj_surf_output->fourcc == VA_FOURCC_I420 ||
1442 obj_surf_output->fourcc == VA_FOURCC_IMC1 ||
1443 obj_surf_output->fourcc == VA_FOURCC_IMC3 ||
1444 obj_surf_output->fourcc == VA_FOURCC_RGBA ||
1445 obj_surf_output->fourcc == VA_FOURCC_BGRA) {
1447 proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT;
1448 } else if(obj_surf_output->fourcc == VA_FOURCC_AYUV ||
1449 obj_surf_output->fourcc == VA_FOURCC_YUY2 ||
1450 obj_surf_output->fourcc == VA_FOURCC_NV12){
1451 /* Nothing to do here */
1453 /* not support other format as input */
1457 if(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT ||
1458 proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1459 if(proc_ctx->surface_output_vebox_object == NULL){
1460 va_status = i965_CreateSurfaces(ctx,
1461 proc_ctx->width_input,
1462 proc_ctx->height_input,
1463 VA_RT_FORMAT_YUV420,
1465 &(proc_ctx->surface_output_vebox));
1466 assert(va_status == VA_STATUS_SUCCESS);
1467 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_vebox);
1468 assert(obj_surf_output_vebox);
1470 if (obj_surf_output_vebox) {
1471 proc_ctx->surface_output_vebox_object = obj_surf_output_vebox;
1472 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1477 if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT){
1478 if(proc_ctx->surface_output_scaled_object == NULL){
1479 va_status = i965_CreateSurfaces(ctx,
1480 proc_ctx->width_output,
1481 proc_ctx->height_output,
1482 VA_RT_FORMAT_YUV420,
1484 &(proc_ctx->surface_output_scaled));
1485 assert(va_status == VA_STATUS_SUCCESS);
1486 obj_surf_output_vebox = SURFACE(proc_ctx->surface_output_scaled);
1487 assert(obj_surf_output_vebox);
1489 if (obj_surf_output_vebox) {
1490 proc_ctx->surface_output_scaled_object = obj_surf_output_vebox;
1491 i965_check_alloc_surface_bo(ctx, obj_surf_output_vebox, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
1499 int hsw_veb_post_format_convert(VADriverContextP ctx,
1500 struct intel_vebox_context *proc_ctx)
1502 struct object_surface *obj_surface = NULL;
1504 obj_surface = proc_ctx->frame_store[proc_ctx->current_output].obj_surface;
1506 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1507 /* copy the saved frame in the second call */
1508 vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1509 } else if(!(proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1510 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1511 /* Output surface format is covered by vebox pipeline and
1512 * processed picture is already store in output surface
1513 * so nothing will be done here */
1514 } else if ((proc_ctx->format_convert_flags & POST_FORMAT_CONVERT) &&
1515 !(proc_ctx->format_convert_flags & POST_SCALING_CONVERT)){
1516 /* convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1517 vpp_surface_convert(ctx, obj_surface, proc_ctx->surface_output_object);
1519 } else if(proc_ctx->format_convert_flags & POST_SCALING_CONVERT) {
1520 VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1521 /* scaling, convert and copy NV12 to YV12/IMC3/IMC2/RGBA output*/
1522 assert(obj_surface->fourcc == VA_FOURCC_NV12);
1524 /* first step :surface scaling */
1525 vpp_surface_scaling(ctx, obj_surface,
1526 proc_ctx->surface_output_scaled_object, pipe->filter_flags);
1528 /* second step: color format convert and copy to output */
1529 obj_surface = proc_ctx->surface_output_object;
1531 if(obj_surface->fourcc == VA_FOURCC_NV12 ||
1532 obj_surface->fourcc == VA_FOURCC_YV12 ||
1533 obj_surface->fourcc == VA_FOURCC_I420 ||
1534 obj_surface->fourcc == VA_FOURCC_YUY2 ||
1535 obj_surface->fourcc == VA_FOURCC_IMC1 ||
1536 obj_surface->fourcc == VA_FOURCC_IMC3 ||
1537 obj_surface->fourcc == VA_FOURCC_RGBA) {
1538 vpp_surface_convert(ctx, proc_ctx->surface_output_scaled_object, obj_surface);
1548 gen75_vebox_init_pipe_params(VADriverContextP ctx,
1549 struct intel_vebox_context *proc_ctx)
1551 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1552 const VAProcPipelineParameterBuffer * const pipe = proc_ctx->pipeline_param;
1553 VAProcFilterParameterBuffer *filter;
1556 proc_ctx->filters_mask = 0;
1557 for (i = 0; i < pipe->num_filters; i++) {
1558 struct object_buffer * const obj_buffer = BUFFER(pipe->filters[i]);
1560 assert(obj_buffer && obj_buffer->buffer_store);
1561 if (!obj_buffer || !obj_buffer->buffer_store)
1562 return VA_STATUS_ERROR_INVALID_PARAMETER;
1564 filter = (VAProcFilterParameterBuffer *)
1565 obj_buffer->buffer_store->buffer;
1566 switch (filter->type) {
1567 case VAProcFilterNoiseReduction:
1568 proc_ctx->filters_mask |= VPP_DNDI_DN;
1569 proc_ctx->filter_dn = filter;
1571 case VAProcFilterDeinterlacing:
1572 proc_ctx->filters_mask |= VPP_DNDI_DI;
1573 proc_ctx->filter_di = filter;
1575 case VAProcFilterColorBalance:
1576 proc_ctx->filters_mask |= VPP_IECP_PRO_AMP;
1577 proc_ctx->filter_iecp_amp = filter;
1578 proc_ctx->filter_iecp_amp_num_elements = obj_buffer->num_elements;
1580 case VAProcFilterSkinToneEnhancement:
1581 proc_ctx->filters_mask |= VPP_IECP_STD_STE;
1582 proc_ctx->filter_iecp_std = filter;
1585 WARN_ONCE("unsupported filter (type: %d)\n", filter->type);
1586 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1589 return VA_STATUS_SUCCESS;
1593 gen75_vebox_init_filter_params(VADriverContextP ctx,
1594 struct intel_vebox_context *proc_ctx)
1596 proc_ctx->format_convert_flags = 0; /* initialized in hsw_veb_pre_format_convert() */
1598 proc_ctx->is_iecp_enabled = (proc_ctx->filters_mask & VPP_IECP_MASK) != 0;
1599 proc_ctx->is_dn_enabled = (proc_ctx->filters_mask & VPP_DNDI_DN) != 0;
1600 proc_ctx->is_di_enabled = (proc_ctx->filters_mask & VPP_DNDI_DI) != 0;
1601 proc_ctx->is_di_adv_enabled = 0;
1602 proc_ctx->is_first_frame = 0;
1603 proc_ctx->is_second_field = 0;
1605 /* Check whether we are deinterlacing the second field */
1606 if (proc_ctx->is_di_enabled) {
1607 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1608 proc_ctx->filter_di;
1610 const unsigned int tff =
1611 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST);
1612 const unsigned int is_top_field =
1613 !(deint_params->flags & VA_DEINTERLACING_BOTTOM_FIELD);
1615 if ((tff ^ is_top_field) != 0) {
1616 struct object_surface * const obj_surface =
1617 proc_ctx->surface_input_object;
1619 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id != obj_surface->base.id) {
1620 WARN_ONCE("invalid surface provided for second field\n");
1621 return VA_STATUS_ERROR_INVALID_PARAMETER;
1623 proc_ctx->is_second_field = 1;
1627 /* Check whether we are deinterlacing the first frame */
1628 if (proc_ctx->is_di_enabled) {
1629 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1630 proc_ctx->filter_di;
1632 switch (deint_params->algorithm) {
1633 case VAProcDeinterlacingBob:
1634 proc_ctx->is_first_frame = 1;
1636 case VAProcDeinterlacingMotionAdaptive:
1637 case VAProcDeinterlacingMotionCompensated:
1638 if (proc_ctx->frame_store[FRAME_IN_CURRENT].surface_id == VA_INVALID_ID)
1639 proc_ctx->is_first_frame = 1;
1640 else if (proc_ctx->is_second_field) {
1641 /* At this stage, we have already deinterlaced the
1642 first field successfully. So, the first frame flag
1643 is trigerred if the previous field was deinterlaced
1644 without reference frame */
1645 if (proc_ctx->frame_store[FRAME_IN_PREVIOUS].surface_id == VA_INVALID_ID)
1646 proc_ctx->is_first_frame = 1;
1649 const VAProcPipelineParameterBuffer * const pipe =
1650 proc_ctx->pipeline_param;
1652 if (pipe->num_forward_references < 1 ||
1653 pipe->forward_references[0] == VA_INVALID_ID) {
1654 WARN_ONCE("A forward temporal reference is needed for Motion adaptive/compensated deinterlacing !!!\n");
1655 return VA_STATUS_ERROR_INVALID_PARAMETER;
1658 proc_ctx->is_di_adv_enabled = 1;
1661 WARN_ONCE("unsupported deinterlacing algorithm (%d)\n",
1662 deint_params->algorithm);
1663 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
1666 return VA_STATUS_SUCCESS;
1670 gen75_vebox_process_picture(VADriverContextP ctx,
1671 struct intel_vebox_context *proc_ctx)
1675 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1676 if (status != VA_STATUS_SUCCESS)
1679 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1680 if (status != VA_STATUS_SUCCESS)
1683 hsw_veb_pre_format_convert(ctx, proc_ctx);
1685 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1686 if (status != VA_STATUS_SUCCESS)
1689 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1690 if (status != VA_STATUS_SUCCESS)
1693 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1694 assert(proc_ctx->is_second_field);
1695 /* directly copy the saved frame in the second call */
1697 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1698 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1699 hsw_veb_state_table_setup(ctx, proc_ctx);
1700 hsw_veb_state_command(ctx, proc_ctx);
1701 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
1702 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
1703 hsw_veb_dndi_iecp_command(ctx, proc_ctx);
1704 intel_batchbuffer_end_atomic(proc_ctx->batch);
1705 intel_batchbuffer_flush(proc_ctx->batch);
1708 hsw_veb_post_format_convert(ctx, proc_ctx);
1710 return VA_STATUS_SUCCESS;
1713 void gen75_vebox_context_destroy(VADriverContextP ctx,
1714 struct intel_vebox_context *proc_ctx)
1718 if(proc_ctx->surface_input_vebox != VA_INVALID_ID){
1719 i965_DestroySurfaces(ctx, &proc_ctx->surface_input_vebox, 1);
1720 proc_ctx->surface_input_vebox = VA_INVALID_ID;
1721 proc_ctx->surface_input_vebox_object = NULL;
1724 if(proc_ctx->surface_output_vebox != VA_INVALID_ID){
1725 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_vebox, 1);
1726 proc_ctx->surface_output_vebox = VA_INVALID_ID;
1727 proc_ctx->surface_output_vebox_object = NULL;
1730 if(proc_ctx->surface_output_scaled != VA_INVALID_ID){
1731 i965_DestroySurfaces(ctx, &proc_ctx->surface_output_scaled, 1);
1732 proc_ctx->surface_output_scaled = VA_INVALID_ID;
1733 proc_ctx->surface_output_scaled_object = NULL;
1736 for (i = 0; i < ARRAY_ELEMS(proc_ctx->frame_store); i++)
1737 frame_store_clear(&proc_ctx->frame_store[i], ctx);
1739 /* dndi state table */
1740 drm_intel_bo_unreference(proc_ctx->dndi_state_table.bo);
1741 proc_ctx->dndi_state_table.bo = NULL;
1743 /* iecp state table */
1744 drm_intel_bo_unreference(proc_ctx->iecp_state_table.bo);
1745 proc_ctx->iecp_state_table.bo = NULL;
1747 /* gamut statu table */
1748 drm_intel_bo_unreference(proc_ctx->gamut_state_table.bo);
1749 proc_ctx->gamut_state_table.bo = NULL;
1751 /* vertex state table */
1752 drm_intel_bo_unreference(proc_ctx->vertex_state_table.bo);
1753 proc_ctx->vertex_state_table.bo = NULL;
1755 intel_batchbuffer_free(proc_ctx->batch);
1760 struct intel_vebox_context * gen75_vebox_context_init(VADriverContextP ctx)
1762 struct intel_driver_data *intel = intel_driver_data(ctx);
1763 struct intel_vebox_context *proc_context = calloc(1, sizeof(struct intel_vebox_context));
1766 proc_context->batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
1768 for (i = 0; i < ARRAY_ELEMS(proc_context->frame_store); i++)
1769 proc_context->frame_store[i].surface_id = VA_INVALID_ID;
1771 proc_context->filters_mask = 0;
1772 proc_context->surface_output_object = NULL;
1773 proc_context->surface_input_object = NULL;
1774 proc_context->surface_input_vebox = VA_INVALID_ID;
1775 proc_context->surface_input_vebox_object = NULL;
1776 proc_context->surface_output_vebox = VA_INVALID_ID;
1777 proc_context->surface_output_vebox_object = NULL;
1778 proc_context->surface_output_scaled = VA_INVALID_ID;
1779 proc_context->surface_output_scaled_object = NULL;
1780 proc_context->filters_mask = 0;
1781 proc_context->format_convert_flags = 0;
1783 return proc_context;
1786 void bdw_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1788 struct intel_batchbuffer *batch = proc_ctx->batch;
1790 BEGIN_VEB_BATCH(batch, 0xc);
1791 OUT_VEB_BATCH(batch, VEB_STATE | (0xc - 2));
1792 OUT_VEB_BATCH(batch,
1793 0 << 25 | // state surface control bits
1794 0 << 23 | // reserved.
1795 0 << 22 | // gamut expansion position
1796 0 << 15 | // reserved.
1797 0 << 14 | // single slice vebox enable
1798 0 << 13 | // hot pixel filter enable
1799 0 << 12 | // alpha plane enable
1800 0 << 11 | // vignette enable
1801 0 << 10 | // demosaic enable
1802 proc_ctx->current_output_type << 8 | // DI output frame
1803 1 << 7 | // 444->422 downsample method
1804 1 << 6 | // 422->420 downsample method
1805 proc_ctx->is_first_frame << 5 | // DN/DI first frame
1806 proc_ctx->is_di_enabled << 4 | // DI enable
1807 proc_ctx->is_dn_enabled << 3 | // DN enable
1808 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
1809 0 << 1 | // ColorGamutCompressionEnable
1810 0 ) ; // ColorGamutExpansionEnable.
1813 proc_ctx->dndi_state_table.bo,
1814 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1816 OUT_VEB_BATCH(batch, 0);
1819 proc_ctx->iecp_state_table.bo,
1820 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1822 OUT_VEB_BATCH(batch, 0);
1825 proc_ctx->gamut_state_table.bo,
1826 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1828 OUT_VEB_BATCH(batch, 0);
1831 proc_ctx->vertex_state_table.bo,
1832 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1834 OUT_VEB_BATCH(batch, 0);
1836 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
1837 OUT_VEB_BATCH(batch, 0);
1839 ADVANCE_VEB_BATCH(batch);
1842 void bdw_veb_dndi_iecp_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1844 struct intel_batchbuffer *batch = proc_ctx->batch;
1845 unsigned char frame_ctrl_bits = 0;
1846 const unsigned int width64 = ALIGN(proc_ctx->width_input, 64);
1848 BEGIN_VEB_BATCH(batch, 0x14);
1849 OUT_VEB_BATCH(batch, VEB_DNDI_IECP_STATE | (0x14 - 2));//DWord 0
1850 OUT_VEB_BATCH(batch, (width64 - 1));
1853 proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface->bo,
1854 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 2
1855 OUT_VEB_BATCH(batch,0);//DWord 3
1858 proc_ctx->frame_store[FRAME_IN_PREVIOUS].obj_surface->bo,
1859 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 4
1860 OUT_VEB_BATCH(batch,0);//DWord 5
1863 proc_ctx->frame_store[FRAME_IN_STMM].obj_surface->bo,
1864 I915_GEM_DOMAIN_RENDER, 0, frame_ctrl_bits);//DWord 6
1865 OUT_VEB_BATCH(batch,0);//DWord 7
1868 proc_ctx->frame_store[FRAME_OUT_STMM].obj_surface->bo,
1869 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 8
1870 OUT_VEB_BATCH(batch,0);//DWord 9
1873 proc_ctx->frame_store[FRAME_OUT_CURRENT_DN].obj_surface->bo,
1874 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 10
1875 OUT_VEB_BATCH(batch,0);//DWord 11
1878 proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface->bo,
1879 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 12
1880 OUT_VEB_BATCH(batch,0);//DWord 13
1883 proc_ctx->frame_store[FRAME_OUT_PREVIOUS].obj_surface->bo,
1884 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 14
1885 OUT_VEB_BATCH(batch,0);//DWord 15
1888 proc_ctx->frame_store[FRAME_OUT_STATISTIC].obj_surface->bo,
1889 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, frame_ctrl_bits);//DWord 16
1890 OUT_VEB_BATCH(batch,0);//DWord 17
1892 OUT_VEB_BATCH(batch,0);//DWord 18
1893 OUT_VEB_BATCH(batch,0);//DWord 19
1895 ADVANCE_VEB_BATCH(batch);
1899 gen8_vebox_process_picture(VADriverContextP ctx,
1900 struct intel_vebox_context *proc_ctx)
1904 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
1905 if (status != VA_STATUS_SUCCESS)
1908 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
1909 if (status != VA_STATUS_SUCCESS)
1912 hsw_veb_pre_format_convert(ctx, proc_ctx);
1914 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
1915 if (status != VA_STATUS_SUCCESS)
1918 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
1919 if (status != VA_STATUS_SUCCESS)
1922 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
1923 assert(proc_ctx->is_second_field);
1924 /* directly copy the saved frame in the second call */
1926 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
1927 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
1928 hsw_veb_state_table_setup(ctx, proc_ctx);
1929 bdw_veb_state_command(ctx, proc_ctx);
1930 hsw_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
1931 hsw_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
1932 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
1933 intel_batchbuffer_end_atomic(proc_ctx->batch);
1934 intel_batchbuffer_flush(proc_ctx->batch);
1937 hsw_veb_post_format_convert(ctx, proc_ctx);
1939 return VA_STATUS_SUCCESS;
1944 skl_veb_dndi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
1946 unsigned int* p_table ;
1947 unsigned int progressive_dn = 1;
1948 unsigned int dndi_top_first = 0;
1949 unsigned int is_mcdi_enabled = 0;
1951 if (proc_ctx->is_di_enabled) {
1952 const VAProcFilterParameterBufferDeinterlacing * const deint_params =
1953 proc_ctx->filter_di;
1957 /* If we are in "First Frame" mode, i.e. past frames are not
1958 available for motion measure, then don't use the TFF flag */
1959 dndi_top_first = !(deint_params->flags & (proc_ctx->is_first_frame ?
1960 VA_DEINTERLACING_BOTTOM_FIELD :
1961 VA_DEINTERLACING_BOTTOM_FIELD_FIRST));
1964 (deint_params->algorithm == VAProcDeinterlacingMotionCompensated);
1968 VAProcFilterParameterBufferDeinterlacing *di_param =
1969 (VAProcFilterParameterBufferDeinterlacing *) proc_ctx->filter_di;
1971 VAProcFilterParameterBuffer * dn_param =
1972 (VAProcFilterParameterBuffer *) proc_ctx->filter_dn;
1974 p_table = (unsigned int *)proc_ctx->dndi_state_table.ptr;
1976 *p_table ++ = ( 140 << 20 | // denoise stad threshold . w1
1977 192 << 12 | // dnmh_history_max
1978 7 << 8 | // dnmh_delta[3:0]
1979 1 ); // denoise moving pixel threshold
1981 *p_table ++ = ( 38 << 20 | // denoise asd threshold
1982 0 << 10 | // temporal diff th
1983 0 ); // low temporal diff th
1985 *p_table ++ = ( progressive_dn << 28 | // progressive dn
1986 38 << 16 | // denoise th for sum of complexity measure
1987 32 << 10 | // dnmh_history_init[5:0]
1990 *p_table ++ = ( 0 << 28 | // hot pixel count
1991 0 << 20 | // hot pixel threshold
1992 1 << 12 | // block noise estimate edge threshold
1993 20 ); // block noise estimate noise threshold
1995 *p_table ++ = ( 140<< 16 | // chroma denoise stad threshold
1996 0 << 13 | // reserved
1997 1 << 12 | // chrome denoise enable
1998 13 << 6 | // chr temp diff th
1999 7 ); // chr temp diff low
2001 *p_table ++ = 0; // weight
2003 *p_table ++ = ( 0 << 16 | // dn_thmax
2006 *p_table ++ = ( 0 << 16 | // dn_prt5
2007 0 ); // dn_dyn_thmin
2009 *p_table ++ = ( 0 << 16 | // dn_prt4
2012 *p_table ++ = ( 0 << 16 | // dn_prt2
2015 *p_table ++ = ( 0 << 16 | // dn_prt0
2016 0 << 10 | // dn_wd22
2020 *p_table ++ = ( 0 << 25 | // dn_wd12
2021 0 << 20 | // dn_wd11
2022 0 << 15 | // dn_wd10
2023 0 << 10 | // dn_wd02
2027 *p_table ++ = ( 2 << 10 | // stmm c2
2028 9 << 6 | // cat slope minus 1
2029 5 << 2 | // sad tight threshold
2030 0 ); // smooth mv th
2032 *p_table ++ = ( 0 << 31 | // stmm blending constant select
2033 64 << 24 | // stmm trc1
2034 125<< 16 | // stmm trc2
2035 0 << 14 | // reserved
2036 30 << 8 | // multiplier for vecm
2037 150 ); // maximum stmm
2039 *p_table ++ = ( 118<< 24 | // minumum stmm
2040 0 << 22 | // stmm shift down
2041 1 << 20 | // stmm shift up
2042 5 << 16 | // stmm output shift
2043 100 << 8 | // sdi threshold
2046 *p_table ++ = ( 50 << 24 | // sdi fallback mode 1 t1 constant
2047 100 << 16 | // sdi fallback mode 1 t2 constant
2048 37 << 8 | // sdi fallback mode 2 constant(angle2x1)
2049 175 ); // fmd temporal difference threshold
2051 *p_table ++ = ( 16 << 24 | // fmd #1 vertical difference th . w7
2052 100<< 16 | // fmd #2 vertical difference th
2053 0 << 14 | // cat threshold
2054 2 << 8 | // fmd tear threshold
2055 is_mcdi_enabled << 7 | // mcdi enable, use motion compensated deinterlace algorithm
2056 dndi_top_first << 3 | // dn/di top first
2059 *p_table ++ = ( 10 << 19 | // neighbor pixel threshold
2060 0 << 16 | // fmd for 2nd field of previous frame
2061 25 << 10 | // mc pixel consistency threshold
2062 0 << 8 | // fmd for 1st field for current frame
2063 10 << 4 | // sad thb
2067 void skl_veb_iecp_csc_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2069 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 220);
2070 float tran_coef[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
2071 float v_coef[3] = {0.0, 0.0, 0.0};
2072 float u_coef[3] = {0.0, 0.0, 0.0};
2073 int is_transform_enabled = 0;
2075 if(!(proc_ctx->filters_mask & VPP_IECP_CSC)){
2076 memset(p_table, 0, 12 * 4);
2080 if(proc_ctx->fourcc_input == VA_FOURCC_RGBA &&
2081 (proc_ctx->fourcc_output == VA_FOURCC_NV12 ||
2082 proc_ctx->fourcc_output == VA_FOURCC_YV12 ||
2083 proc_ctx->fourcc_output == VA_FOURCC_YVY2 ||
2084 proc_ctx->fourcc_output == VA_FOURCC_AYUV)) {
2086 tran_coef[0] = 0.257;
2087 tran_coef[1] = 0.504;
2088 tran_coef[2] = 0.098;
2089 tran_coef[3] = -0.148;
2090 tran_coef[4] = -0.291;
2091 tran_coef[5] = 0.439;
2092 tran_coef[6] = 0.439;
2093 tran_coef[7] = -0.368;
2094 tran_coef[8] = -0.071;
2097 u_coef[1] = 128 * 4;
2098 u_coef[2] = 128 * 4;
2100 is_transform_enabled = 1;
2101 }else if((proc_ctx->fourcc_input == VA_FOURCC_NV12 ||
2102 proc_ctx->fourcc_input == VA_FOURCC_YV12 ||
2103 proc_ctx->fourcc_input == VA_FOURCC_YUY2 ||
2104 proc_ctx->fourcc_input == VA_FOURCC_AYUV) &&
2105 proc_ctx->fourcc_output == VA_FOURCC_RGBA) {
2106 tran_coef[0] = 1.164;
2107 tran_coef[1] = 0.000;
2108 tran_coef[2] = 1.569;
2109 tran_coef[3] = 1.164;
2110 tran_coef[4] = -0.813;
2111 tran_coef[5] = -0.392;
2112 tran_coef[6] = 1.164;
2113 tran_coef[7] = 2.017;
2114 tran_coef[8] = 0.000;
2116 v_coef[0] = -16 * 4;
2117 v_coef[1] = -128 * 4;
2118 v_coef[2] = -128 * 4;
2120 is_transform_enabled = 1;
2121 }else if(proc_ctx->fourcc_input != proc_ctx->fourcc_output){
2122 //enable when input and output format are different.
2123 is_transform_enabled = 1;
2126 if(is_transform_enabled == 0){
2127 memset(p_table, 0, 12 * 4);
2129 *p_table ++ = ( is_transform_enabled << 31 |
2130 0 << 29 | // yuv_channel swap
2131 intel_format_convert(tran_coef[0], 2, 16, 1)); //c0, s2.16 format
2133 *p_table ++ = ( 0 << 19 | //reserved
2134 intel_format_convert(tran_coef[1], 2, 16, 1)); //c1, s2.16 format
2136 *p_table ++ = ( 0 << 19 | //reserved
2137 intel_format_convert(tran_coef[2], 2, 16, 1)); //c2, s2.16 format
2139 *p_table ++ = ( 0 << 19 | //reserved
2140 intel_format_convert(tran_coef[3], 2, 16, 1)); //c3, s2.16 format
2142 *p_table ++ = ( 0 << 19 | //reserved
2143 intel_format_convert(tran_coef[4], 2, 16, 1)); //c4, s2.16 format
2145 *p_table ++ = ( 0 << 19 | //reserved
2146 intel_format_convert(tran_coef[5], 2, 16, 1)); //c5, s2.16 format
2148 *p_table ++ = ( 0 << 19 | //reserved
2149 intel_format_convert(tran_coef[6], 2, 16, 1)); //c6, s2.16 format
2151 *p_table ++ = ( 0 << 19 | //reserved
2152 intel_format_convert(tran_coef[7], 2, 16, 1)); //c7, s2.16 format
2154 *p_table ++ = ( 0 << 19 | //reserved
2155 intel_format_convert(tran_coef[8], 2, 16, 1)); //c8, s2.16 format
2157 *p_table ++ = ( intel_format_convert(u_coef[0], 16, 0, 1) << 16 |
2158 intel_format_convert(v_coef[0], 16, 0, 1));
2160 *p_table ++ = ( intel_format_convert(u_coef[1], 16, 0, 1) << 16 |
2161 intel_format_convert(v_coef[1], 16, 0, 1));
2163 *p_table ++ = ( intel_format_convert(u_coef[2], 16, 0, 1) << 16 |
2164 intel_format_convert(v_coef[2], 16, 0, 1));
2168 void skl_veb_iecp_aoi_table(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2170 unsigned int *p_table = (unsigned int*)(proc_ctx->iecp_state_table.ptr + 27 * sizeof(unsigned int));
2172 if (!(proc_ctx->filters_mask & VPP_IECP_AOI)) {
2173 memset(p_table, 0, 3 * 4);
2175 *p_table ++ = 0x00000000;
2176 *p_table ++ = 0x00030000;
2177 *p_table ++ = 0x00030000;
2181 void skl_veb_state_table_setup(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2183 if(proc_ctx->filters_mask & VPP_DNDI_MASK) {
2184 dri_bo *dndi_bo = proc_ctx->dndi_state_table.bo;
2185 dri_bo_map(dndi_bo, 1);
2186 proc_ctx->dndi_state_table.ptr = dndi_bo->virtual;
2188 skl_veb_dndi_table(ctx, proc_ctx);
2190 dri_bo_unmap(dndi_bo);
2193 if(proc_ctx->filters_mask & VPP_IECP_MASK) {
2194 dri_bo *iecp_bo = proc_ctx->iecp_state_table.bo;
2195 dri_bo_map(iecp_bo, 1);
2196 proc_ctx->iecp_state_table.ptr = iecp_bo->virtual;
2198 hsw_veb_iecp_std_table(ctx, proc_ctx);
2199 hsw_veb_iecp_ace_table(ctx, proc_ctx);
2200 hsw_veb_iecp_tcc_table(ctx, proc_ctx);
2201 hsw_veb_iecp_pro_amp_table(ctx, proc_ctx);
2202 skl_veb_iecp_csc_table(ctx, proc_ctx);
2203 skl_veb_iecp_aoi_table(ctx, proc_ctx);
2205 dri_bo_unmap(iecp_bo);
2210 skl_veb_state_command(VADriverContextP ctx, struct intel_vebox_context *proc_ctx)
2212 struct intel_batchbuffer *batch = proc_ctx->batch;
2214 BEGIN_VEB_BATCH(batch, 0x10);
2215 OUT_VEB_BATCH(batch, VEB_STATE | (0x10 - 2));
2216 OUT_VEB_BATCH(batch,
2217 0 << 25 | // state surface control bits
2218 0 << 23 | // reserved.
2219 0 << 22 | // gamut expansion position
2220 0 << 15 | // reserved.
2221 0 << 14 | // single slice vebox enable
2222 0 << 13 | // hot pixel filter enable
2223 0 << 12 | // alpha plane enable
2224 0 << 11 | // vignette enable
2225 0 << 10 | // demosaic enable
2226 proc_ctx->current_output_type << 8 | // DI output frame
2227 1 << 7 | // 444->422 downsample method
2228 1 << 6 | // 422->420 downsample method
2229 proc_ctx->is_first_frame << 5 | // DN/DI first frame
2230 proc_ctx->is_di_enabled << 4 | // DI enable
2231 proc_ctx->is_dn_enabled << 3 | // DN enable
2232 proc_ctx->is_iecp_enabled << 2 | // global IECP enabled
2233 0 << 1 | // ColorGamutCompressionEnable
2234 0 ) ; // ColorGamutExpansionEnable.
2237 proc_ctx->dndi_state_table.bo,
2238 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2240 OUT_VEB_BATCH(batch, 0);
2243 proc_ctx->iecp_state_table.bo,
2244 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2246 OUT_VEB_BATCH(batch, 0);
2249 proc_ctx->gamut_state_table.bo,
2250 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2252 OUT_VEB_BATCH(batch, 0);
2255 proc_ctx->vertex_state_table.bo,
2256 I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2258 OUT_VEB_BATCH(batch, 0);
2260 OUT_VEB_BATCH(batch, 0);/*caputre pipe state pointer*/
2261 OUT_VEB_BATCH(batch, 0);
2263 OUT_VEB_BATCH(batch, 0);/*lace lut table state pointer*/
2264 OUT_VEB_BATCH(batch, 0);
2266 OUT_VEB_BATCH(batch, 0);/*gamma correction values address*/
2267 OUT_VEB_BATCH(batch, 0);
2269 ADVANCE_VEB_BATCH(batch);
2272 void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *proc_ctx, unsigned int is_output)
2274 struct intel_batchbuffer *batch = proc_ctx->batch;
2275 unsigned int u_offset_y = 0, v_offset_y = 0;
2276 unsigned int is_uv_interleaved = 0, tiling = 0, swizzle = 0;
2277 unsigned int surface_format = PLANAR_420_8;
2278 struct object_surface* obj_surf = NULL;
2279 unsigned int surface_pitch = 0;
2280 unsigned int half_pitch_chroma = 0;
2281 unsigned int derived_pitch;
2284 obj_surf = proc_ctx->frame_store[FRAME_OUT_CURRENT].obj_surface;
2286 obj_surf = proc_ctx->frame_store[FRAME_IN_CURRENT].obj_surface;
2289 assert(obj_surf->fourcc == VA_FOURCC_NV12 ||
2290 obj_surf->fourcc == VA_FOURCC_YUY2 ||
2291 obj_surf->fourcc == VA_FOURCC_AYUV ||
2292 obj_surf->fourcc == VA_FOURCC_RGBA);
2294 if (obj_surf->fourcc == VA_FOURCC_NV12) {
2295 surface_format = PLANAR_420_8;
2296 surface_pitch = obj_surf->width;
2297 is_uv_interleaved = 1;
2298 half_pitch_chroma = 0;
2299 } else if (obj_surf->fourcc == VA_FOURCC_YUY2) {
2300 surface_format = YCRCB_NORMAL;
2301 surface_pitch = obj_surf->width * 2;
2302 is_uv_interleaved = 0;
2303 half_pitch_chroma = 0;
2304 } else if (obj_surf->fourcc == VA_FOURCC_AYUV) {
2305 surface_format = PACKED_444A_8;
2306 surface_pitch = obj_surf->width * 4;
2307 is_uv_interleaved = 0;
2308 half_pitch_chroma = 0;
2309 } else if (obj_surf->fourcc == VA_FOURCC_RGBA) {
2310 surface_format = R8G8B8A8_UNORM_SRGB;
2311 surface_pitch = obj_surf->width * 4;
2312 is_uv_interleaved = 0;
2313 half_pitch_chroma = 0;
2316 derived_pitch = surface_pitch;
2318 u_offset_y = obj_surf->y_cb_offset;
2319 v_offset_y = obj_surf->y_cr_offset;
2321 dri_bo_get_tiling(obj_surf->bo, &tiling, &swizzle);
2323 BEGIN_VEB_BATCH(batch, 9);
2324 OUT_VEB_BATCH(batch, VEB_SURFACE_STATE | (9 - 2));
2325 OUT_VEB_BATCH(batch,
2326 0 << 1 | // reserved
2327 is_output); // surface indentification.
2329 OUT_VEB_BATCH(batch,
2330 (obj_surf->height - 1) << 18 | // height . w3
2331 (obj_surf->width -1 ) << 4 | // width
2334 OUT_VEB_BATCH(batch,
2335 surface_format << 28 | // surface format, YCbCr420. w4
2336 is_uv_interleaved << 27 | // interleave chrome , two seperate palar
2337 0 << 20 | // reserved
2338 (surface_pitch - 1) << 3 | // surface pitch, 64 align
2339 half_pitch_chroma << 2 | // half pitch for chrome
2340 !!tiling << 1 | // tiled surface, linear surface used
2341 (tiling == I915_TILING_Y)); // tiled walk, ignored when liner surface
2343 OUT_VEB_BATCH(batch,
2344 0 << 16 | // X offset for V(Cb)
2345 u_offset_y); // Y offset for V(Cb)
2347 OUT_VEB_BATCH(batch,
2348 0 << 16 | // X offset for V(Cr)
2349 v_offset_y ); // Y offset for V(Cr)
2351 OUT_VEB_BATCH(batch, 0);
2353 OUT_VEB_BATCH(batch, derived_pitch - 1);
2355 OUT_VEB_BATCH(batch, 0);
2357 ADVANCE_VEB_BATCH(batch);
2361 gen9_vebox_process_picture(VADriverContextP ctx,
2362 struct intel_vebox_context *proc_ctx)
2366 status = gen75_vebox_init_pipe_params(ctx, proc_ctx);
2367 if (status != VA_STATUS_SUCCESS)
2370 status = gen75_vebox_init_filter_params(ctx, proc_ctx);
2371 if (status != VA_STATUS_SUCCESS)
2374 hsw_veb_pre_format_convert(ctx, proc_ctx);
2376 status = gen75_vebox_ensure_surfaces(ctx, proc_ctx);
2377 if (status != VA_STATUS_SUCCESS)
2380 status = gen75_vebox_ensure_surfaces_storage(ctx, proc_ctx);
2381 if (status != VA_STATUS_SUCCESS)
2384 if (proc_ctx->format_convert_flags & POST_COPY_CONVERT) {
2385 assert(proc_ctx->is_second_field);
2386 /* directly copy the saved frame in the second call */
2388 intel_batchbuffer_start_atomic_veb(proc_ctx->batch, 0x1000);
2389 intel_batchbuffer_emit_mi_flush(proc_ctx->batch);
2390 skl_veb_state_table_setup(ctx, proc_ctx);
2391 skl_veb_state_command(ctx, proc_ctx);
2392 skl_veb_surface_state(ctx, proc_ctx, INPUT_SURFACE);
2393 skl_veb_surface_state(ctx, proc_ctx, OUTPUT_SURFACE);
2394 bdw_veb_dndi_iecp_command(ctx, proc_ctx);
2395 intel_batchbuffer_end_atomic(proc_ctx->batch);
2396 intel_batchbuffer_flush(proc_ctx->batch);
2399 hsw_veb_post_format_convert(ctx, proc_ctx);
2401 return VA_STATUS_SUCCESS;